1pub mod tests;
4pub mod origin;
5mod prs;
6
7pub use prs::*;
8
9use std::collections::{HashMap, HashSet};
10use std::fmt::{Display, Formatter};
11use std::marker::PhantomData;
12use std::mem::take;
13use std::ops::{Deref, DerefMut};
14use iter_index::IndexerIterator;
15use vectree::VecTree;
16use lexigram_core::alt::ruleflag;
17use lexigram_core::CollectJoin;
18use crate::cproduct::CProduct;
19use crate::{alt, gnode, hashset, indent_source, prule, sym, vaddi, General, Normalized, TokenId, VarId, LL1, LR};
20use crate::fixed_sym_table::SymInfoTable;
21use crate::grammar::NTConversion::{MovedTo, Removed};
22use crate::grammar::origin::{FromPRS, FromRTS, Origin};
23use lexigram_core::log::{BufLog, LogReader, LogStatus, Logger};
24use crate::build::{BuildErrorSource, BuildFrom, HasBuildErrorSource};
25use crate::parser::Symbol;
26use crate::SymbolTable;
27
28#[derive(Clone, Copy, PartialEq, Debug)]
29pub enum GrNode {
30 Symbol(Symbol),
31 Concat,
32 Or,
33 Maybe,
34 Plus,
35 Star,
36 LForm(VarId), RAssoc, PrecEq, Instance, Greedy, }
69
70impl Display for GrNode {
71 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
72 match self {
73 GrNode::Symbol(s) => write!(f, "{s}"),
74 GrNode::Concat => write!(f, "&"),
75 GrNode::Or => write!(f, "|"),
76 GrNode::Maybe => write!(f, "?"),
77 GrNode::Plus => write!(f, "+"),
78 GrNode::Star => write!(f, "*"),
79 GrNode::LForm(v) => write!(f, "<L={v}>"),
80 GrNode::RAssoc => write!(f, "<R>"),
81 GrNode::PrecEq => write!(f, "<P>"),
82 GrNode::Instance => write!(f, "inst "),
83 GrNode::Greedy => write!(f, "<G>"),
84 }
85 }
86}
87
88impl GrNode {
89 pub fn to_str(&self, symbol_table: Option<&SymbolTable>) -> String {
90 match self {
91 GrNode::Symbol(s) => symbol_table.map(|t| t.get_str(s)).unwrap_or(s.to_string()),
92 GrNode::LForm(v) => format!("<L={}>", symbol_table.map(|t| t.get_str(&Symbol::NT(*v))).unwrap_or(v.to_string())),
93 _ => self.to_string()
94 }
95 }
96
97 pub fn gen_source_code(&self) -> String {
98 match self {
99 GrNode::Symbol(s) => format!("gnode!({})", s.to_macro_item()),
100 GrNode::Concat => "gnode!(&)".to_string(),
101 GrNode::Or => "gnode!(|)".to_string(),
102 GrNode::Maybe => "gnode!(?)".to_string(),
103 GrNode::Plus => "gnode!(+)".to_string(),
104 GrNode::Star => "gnode!(*)".to_string(),
105 GrNode::LForm(v) => format!("gnode!(L {v})"),
106 GrNode::RAssoc => "gnode!(R)".to_string(),
107 GrNode::PrecEq => "gnode!(P)".to_string(),
108 GrNode::Instance => "gnode!(inst)".to_string(),
109 GrNode::Greedy => "gnode!(G)".to_string(),
110 }
111 }
112
113 pub fn is_modifier(&self) -> bool {
114 matches!(self, GrNode::LForm(_) | GrNode::RAssoc | GrNode::PrecEq | GrNode::Greedy)
115 }
116
117 pub fn is_empty(&self) -> bool {
118 matches!(self, GrNode::Symbol(Symbol::Empty))
119 }
120}
121
122#[derive(Clone, Copy)]
128pub struct Dup {
129 index: u32
130}
131
132#[derive(Clone, Copy, Debug)]
133enum DupVal {
134 Original(u32),
135 Copy(u32)
136}
137
138impl Dup {
139 const MASK: u32 = 1 << (u32::BITS - 1);
140
141 fn new(index: usize) -> Self {
142 assert!(index < Self::MASK as usize);
143 Self { index: index as u32 }
144 }
145
146 fn get(&mut self) -> DupVal {
147 let idx = self.index;
148 if idx & Self::MASK == 0 {
149 self.index |= Self::MASK;
150 DupVal::Original(idx)
151 } else {
152 DupVal::Copy(idx & !Self::MASK)
153 }
154 }
155}
156
157impl std::fmt::Debug for Dup {
158 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
159 write!(f, "Dup{{")?;
160 if self.index & Self::MASK == 0 {
161 write!(f, "{}}}", self.index)
162 } else {
163 write!(f, "copy {}}}", self.index & !Dup::MASK)
164 }
165 }
166}
167
168pub type GrTree = VecTree<GrNode>;
171
172pub(crate) const STR_BEFORE: &str = " ►► ";
173pub(crate) const STR_AFTER: &str = " ◄◄ ";
174pub(crate) const STR_BEFORE_ANSI: &str = "\u{1b}[4;1;36m";
175pub(crate) const STR_AFTER_ANSI: &str = "\u{1b}[0m";
176
177pub fn grtree_to_str_custom(tree: &GrTree, node: Option<usize>, emphasis: Option<usize>, nt: Option<VarId>, symbol_table: Option<&SymbolTable>, simplified: bool, ansi: bool)
181 -> String
182{
183 fn pr_join(children: Vec<(u32, String)>, str: &str, pr: u32) -> (u32, String) {
184 (pr, children.into_iter()
185 .map(|(p_ch, ch)| if p_ch >= pr { ch } else { format!("({ch})") })
186 .join(str))
187 }
188
189 fn pr_append(child: (u32, String), str: &str, pr: u32) -> (u32, String) {
190 (pr, if child.0 >= pr { format!("{}{str}", child.1) } else { format!("({}){str}", child.1) })
191 }
192
193 const PR_PROD: u32 = 1;
194 const PR_TERM: u32 = 2;
195 const PR_FACTOR: u32 = 3;
196 const PR_ATOM: u32 = 4;
197
198 let mut children = vec![];
199 if tree.is_empty() {
200 return "<empty>".to_string();
201 }
202 let before = if ansi { STR_BEFORE_ANSI } else { STR_BEFORE };
203 let after = if ansi { STR_AFTER_ANSI } else { STR_AFTER };
204 let top = node.unwrap_or_else(|| tree.get_root().unwrap());
205 for node in tree.iter_post_depth_simple_at(top) {
206 let (pr, mut str) = match node.num_children() {
207 0 => {
208 match node.deref() {
209 GrNode::Symbol(s) => (PR_ATOM, s.to_str_quote(symbol_table)),
210 GrNode::LForm(var) => (PR_ATOM, if simplified || nt == Some(*var) { "<L>".to_string() } else { format!("<L={}>", Symbol::NT(*var).to_str(symbol_table)) }),
211 GrNode::RAssoc => (PR_ATOM, "<R>".to_string()),
212 GrNode::PrecEq => (PR_ATOM, "<P>".to_string()),
213 GrNode::Greedy => (PR_ATOM, "<G>".to_string()),
214 _ => (PR_ATOM, "##ERROR##".to_string()),
215 }
216 }
217 n => {
218 let mut node_children = children.split_off(children.len() - n);
219 match node.deref() {
220 GrNode::Concat => pr_join(node_children, " ", PR_TERM),
221 GrNode::Or => pr_join(node_children, " | ", PR_PROD),
222 GrNode::Maybe => pr_append(node_children.pop().unwrap(), "?", PR_FACTOR),
223 GrNode::Plus => pr_append(node_children.pop().unwrap(), "+", PR_FACTOR),
224 GrNode::Star => pr_append(node_children.pop().unwrap(), "*", PR_FACTOR),
225 GrNode::Instance => pr_join(node_children, " ", PR_FACTOR),
226 _ => (PR_ATOM, "##ERROR##".to_string()),
227 }
228 }
229 };
230 if Some(node.index) == emphasis {
231 str = format!("{before}{str}{after}");
232 }
233 children.push((pr, str));
234 }
235 children.pop().unwrap().1
236}
237
238pub fn grtree_to_str(tree: &GrTree, node: Option<usize>, emphasis: Option<usize>, var: Option<VarId>, symbol_table: Option<&SymbolTable>, simplified: bool) -> String {
239 grtree_to_str_custom(tree, node, emphasis, var, symbol_table, simplified, false)
240}
241
242pub fn grtree_to_str_ansi(tree: &GrTree, node: Option<usize>, emphasis: Option<usize>, var: Option<VarId>, symbol_table: Option<&SymbolTable>, simplified: bool) -> String {
243 grtree_to_str_custom(tree, node, emphasis, var, symbol_table, simplified, true)
244}
245
246fn grtree_cleanup(tree: &mut GrTree, top: Option<usize>, del_empty_term: bool) -> Option<(bool, bool)> {
267 const VERBOSE: bool = false;
268 let root = top.unwrap_or_else(|| tree.get_root().unwrap());
269 let mut had_empty_term = false;
270 let (terms, is_or) = match tree.get(root) {
271 GrNode::Symbol(s) => {
272 let is_empty = *s == Symbol::Empty;
273 return Some((is_empty, is_empty));
274 }
275 GrNode::Concat => (vec![root], false),
276 GrNode::Or => (tree.children(root).to_owned(), true),
277 GrNode::Maybe | GrNode::Plus | GrNode::Star | GrNode::LForm(_)
279 | GrNode::RAssoc | GrNode::PrecEq | GrNode::Instance | GrNode::Greedy => { return None }
280 };
281 let terms_len = terms.len();
282 let mut empty_terms = vec![];
283 for (term_pos, term) in terms.into_iter().enumerate() {
284 match *tree.get(term) {
285 GrNode::Concat => {
286 let children = tree.children(term);
287 let len = children.len();
288 let mut empty_pos = vec![];
289 let n_modifiers = children.iter().enumerate()
290 .fold(0, |n_mod, (pos, &index)| {
291 let n = tree.get(index);
292 if n.is_empty() {
293 empty_pos.push(pos);
294 }
295 n_mod + if n.is_modifier() { 1 } else { 0 }
296 });
297 if VERBOSE { print!("- term {} => {empty_pos:?} empty, {n_modifiers} modifier", tree.to_str_index(Some(term), None)); }
298 if empty_pos.len() + n_modifiers == len {
299 *tree.get_mut(term) = gnode!(e);
300 tree.children_mut(term).clear();
301 empty_terms.push(term_pos);
302 if VERBOSE { println!(" (replacing everything with ε)"); }
303 } else if !empty_pos.is_empty() {
304 if VERBOSE { println!(" => (removing {} ε)", empty_pos.len()); }
305 let new_children = tree.children_mut(term);
306 for i in empty_pos.into_iter().rev() {
307 new_children.remove(i);
308 }
309 } else if VERBOSE {
310 println!(" (nothing to do)");
311 }
312 }
313 GrNode::Symbol(Symbol::Empty) => {
314 empty_terms.push(term_pos);
315 }
316 n if n.is_modifier() => { *tree.get_mut(term) = gnode!(e);
318 empty_terms.push(term_pos);
319 }
320 _ => {}
321 }
322 }
323 if VERBOSE { println!(" {} empty terms: {empty_terms:?}", empty_terms.len()); }
324 if !empty_terms.is_empty() {
325 had_empty_term = true;
326 if is_or {
327 if !del_empty_term && terms_len > 1 || empty_terms.len() == terms_len {
328 empty_terms.pop();
329 }
330 let or_children = tree.children_mut(root);
331 for i in empty_terms.into_iter().rev() {
332 or_children.remove(i);
333 }
334 if VERBOSE { println!("or_children => {or_children:?}"); }
335 }
336 }
337 if is_or && tree.children(root).len() == 1 {
338 let subroot_index = tree.children(root)[0];
340 let subroot = *tree.get(subroot_index);
341 let subroot_children = tree.children(subroot_index).to_owned();
342 *tree.get_mut(root) = subroot;
343 *tree.children_mut(root) = subroot_children;
344 }
345 let is_empty = match tree.get(root) {
346 GrNode::Symbol(s) => s.is_empty(),
347 GrNode::Concat => false, GrNode::Or => false, GrNode::Maybe | GrNode::Plus | GrNode::Star | GrNode::LForm(_) | GrNode::RAssoc | GrNode::PrecEq | GrNode::Instance | GrNode::Greedy => false,
350 };
351 Some((is_empty, had_empty_term))
352}
353
354fn remove_concat_dup_empty(tree: &GrTree, nodes: &mut Vec<usize>) {
361 if nodes.len() > 1 {
362 let mut i = 0;
363 while i < nodes.len() && nodes.len() > 1 {
364 if tree.get(nodes[i]).is_empty() {
365 nodes.remove(i);
366 } else {
367 i += 1;
368 }
369 }
370 }
371}
372
373pub trait GrTreeExt {
378 fn get_dup(&mut self, dup_index: &mut Dup) -> usize;
379 fn to_str(&self, start_node: Option<usize>, symbol_table: Option<&SymbolTable>) -> String;
380 fn to_str_index(&self, start_node: Option<usize>, symbol_table: Option<&SymbolTable>) -> String;
381}
382
383impl GrTreeExt for GrTree {
384 fn get_dup(&mut self, dup_index: &mut Dup) -> usize {
385 match dup_index.get() {
386 DupVal::Original(index) => index as usize,
387 DupVal::Copy(index) => {
388 let node = *self.get(index as usize);
389 self.add(None, node)
390 }
391 }
392 }
393
394 fn to_str(&self, start_node: Option<usize>, symbol_table: Option<&SymbolTable>) -> String {
395 let tfmt = GrTreeFmt {
396 tree: self,
397 show_ids: false,
398 show_depth: false,
399 symbol_table,
400 start_node,
401 };
402 tfmt.to_string()
403 }
404
405 fn to_str_index(&self, start_node: Option<usize>, symbol_table: Option<&SymbolTable>) -> String {
406 let tfmt = GrTreeFmt {
407 tree: self,
408 show_ids: true,
409 show_depth: false,
410 symbol_table,
411 start_node,
412 };
413 tfmt.to_string()
414 }
415}
416
417pub struct GrTreeFmt<'a> {
418 tree: &'a GrTree,
419 show_ids: bool,
420 show_depth: bool,
421 symbol_table: Option<&'a SymbolTable>,
422 start_node: Option<usize>
423}
424
425impl<'a> GrTreeFmt<'a> {
426 fn snode(&self, node: &GrNode, node_id: usize, depth: u32) -> String {
427 let show_ids = self.show_ids;
428 let show_depth = self.show_depth;
429 let mut result = String::new();
430 if show_depth {
431 result.push_str(&depth.to_string());
432 result.push('>');
433 }
434 if show_ids {
435 result.push_str(&node_id.to_string());
436 result.push(':');
437 }
438 let name = if let GrNode::Symbol(sym) = node {
439 if self.symbol_table.is_some() { sym.to_str_quote(self.symbol_table) } else { sym.to_str(self.symbol_table) }
440 } else {
441 node.to_str(self.symbol_table)
442 };
443 result.push_str(name.as_str());
444 result
445 }
446}
447
448impl Display for GrTreeFmt<'_> {
449 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
450 if self.tree.is_empty() {
451 return write!(f, "<empty>");
452 }
453 let start_node = self.start_node.unwrap_or_else(|| self.tree.get_root().expect("the tree must have a defined root"));
454 let mut stack = Vec::<String>::new();
455 for node in self.tree.iter_post_depth_at(start_node) {
456 let n = node.num_children();
457 if n > 0 {
458 let children = stack.drain(stack.len() - n..).join(", ");
459 stack.push(format!("{}({children})", self.snode(&node, node.index, node.depth)));
460 } else {
461 stack.push(self.snode(&node, node.index, node.depth));
462 }
463 }
464 write!(f, "{}", stack.pop().unwrap_or_else(|| "empty".to_string()))
465 }
466}
467
468#[derive(Clone, Copy, PartialEq, Debug)]
471pub enum NTConversion {
472 Removed,
474 MovedTo(VarId)
476}
477
478#[derive(Clone, Debug)]
479pub struct RuleTreeSet<T> {
480 trees: Vec<GrTree>,
481 start: Option<VarId>,
482 symbol_table: Option<SymbolTable>,
483 flags: Vec<u32>, parent: Vec<Option<VarId>>, nt_conversion: HashMap<VarId, NTConversion>,
486 origin: Origin<(VarId, usize), FromRTS>,
487 log: BufLog,
488 _phantom: PhantomData<T>
489}
490
491impl<T> HasBuildErrorSource for RuleTreeSet<T> {
492 const SOURCE: BuildErrorSource = BuildErrorSource::RuleTreeSet;
493}
494
495impl<T> RuleTreeSet<T> {
498 pub fn get_num_nt(&self) -> VarId {
499 self.trees.len() as VarId
500 }
501
502 pub fn get_tree(&self, var: VarId) -> Option<&GrTree> {
503 self.trees.get(var as usize)
504 }
505
506 pub fn get_trees_iter(&self) -> impl Iterator<Item=(VarId, &GrTree)> {
508 self.trees.iter().index().filter_map(|(id, t)| if t.is_empty() { None } else { Some((id, t)) })
509 }
510
511 pub fn get_vars(&self) -> impl Iterator<Item=VarId> + '_ {
513 (0..self.trees.len()).filter_map(|id| if self.trees[id].is_empty() { None } else { Some(id as VarId) })
514 }
515
516 pub fn get_next_available_var(&self) -> VarId {
518 self.trees.len() as VarId
519 }
520
521 pub fn get_terminals(&self) -> HashSet<TokenId> {
523 self.trees.iter()
524 .flat_map(|t| t.iter_post_depth_simple())
525 .filter_map(|x| if let GrNode::Symbol(Symbol::T(t)) = x.deref() { Some(*t) } else { None })
526 .collect::<HashSet<_>>()
527 }
528
529 pub fn set_symbol_table(&mut self, symbol_table: SymbolTable) {
530 self.symbol_table = Some(symbol_table);
531 }
532
533 pub fn get_symbol_table(&self) -> Option<&SymbolTable> {
534 self.symbol_table.as_ref()
535 }
536
537 pub fn set_start(&mut self, start: VarId) {
539 self.start = Some(start);
540 }
541
542 pub fn to_str(&self, var: VarId, node: Option<usize>, emphasis: Option<usize>) -> String {
546 grtree_to_str(&self.trees[var as usize], node, emphasis, Some(var), self.get_symbol_table(), false)
547 }
548
549 pub fn get_log_mut(&mut self) -> &mut BufLog {
550 &mut self.log
551 }
552}
553
554impl<T> LogReader for RuleTreeSet<T> {
555 type Item = BufLog;
556
557 fn get_log(&self) -> &Self::Item {
558 &self.log
559 }
560
561 fn give_log(self) -> Self::Item {
562 self.log
563 }
564}
565
566impl RuleTreeSet<General> {
567 pub fn new() -> Self {
568 Self::with_log(BufLog::new())
569 }
570
571 pub fn with_log(log: BufLog) -> Self {
572 RuleTreeSet {
573 trees: Vec::new(),
574 start: None,
575 symbol_table: None,
576 flags: Vec::new(),
577 parent: Vec::new(),
578 nt_conversion: HashMap::new(),
579 origin: Origin::new(),
580 log,
581 _phantom: PhantomData,
582 }
583 }
584
585 pub fn get_tree_mut(&mut self, var: VarId) -> &mut GrTree {
587 let var = var as usize;
588 if var >= self.trees.len() {
589 self.trees.resize(var + 1, GrTree::new());
590 }
591 &mut self.trees[var]
592 }
593
594 pub fn set_tree(&mut self, var: VarId, tree: GrTree) {
597 let var = var as usize;
598 if var >= self.trees.len() {
599 if var > self.trees.len() {
600 if self.trees.capacity() < var + 1 {
601 self.trees.reserve(var + 1 - self.trees.capacity())
603 }
604 self.trees.resize(var, GrTree::new());
605 }
606 self.trees.push(tree);
607 } else {
608 self.trees[var] = tree;
609 }
610 }
611
612 pub fn normalize(&mut self) {
614 self.log.add_note("original rules:");
615 (0..self.trees.len() as VarId)
616 .for_each(|v| self.log.add_note(format!("- NT[{v:2}] {} -> {}", Symbol::NT(v).to_str(self.get_symbol_table()), self.to_str(v, None, None))));
617 self.log.add_note("normalizing rules...");
618 self.check_num_nt_coherency();
619 self.normalize_vars();
620 self.flags.resize(self.trees.len(), 0);
621 self.parent.resize(self.trees.len(), None);
622 (0..self.trees.len() as VarId)
623 .for_each(|v| self.log.add_note(format!("- NT[{v:2}] {} -> {}", Symbol::NT(v).to_str(self.get_symbol_table()), self.to_str(v, None, None))));
624 }
625
626 fn check_num_nt_coherency(&mut self) {
627 if let Some(n) = self.symbol_table.as_ref().map(|table| table.get_num_nt()) {
628 if n != self.trees.len() {
629 self.log.add_error(format!("there are {} rules but the symbol table has {n} nonterminal symbols: dropping the table", self.trees.len()));
630 self.symbol_table = None;
631 }
632 }
633 }
634
635 fn normalize_vars(&mut self) {
642 const VERBOSE: bool = false;
643 const VERBOSE_CC: bool = false;
644 let mut exclude_nt = HashSet::<VarId>::new();
645 for var in 0..self.get_num_nt() {
646 if exclude_nt.contains(&var) {
647 if VERBOSE { println!("NT[{var}] {} excluded", Symbol::NT(var).to_str(self.get_symbol_table())); }
648 continue
649 }
650 if VERBOSE { println!("normalize_var(NT[{var}] {})", Symbol::NT(var).to_str(self.get_symbol_table())); }
651 let mut new_var = self.get_next_available_var();
652 let orig = take(&mut self.trees[var as usize]);
653 let mut new = GrTree::new();
654 let mut orig_new = GrTree::new();
655 let mut orig_rep_vars = HashMap::<VarId, usize>::new();
656 let mut stack = Vec::<usize>::new(); for sym in orig.iter_post_depth() {
658 let n = sym.num_children();
659 if VERBOSE { println!("- old {}:{}", sym.index, *sym); }
660 if n == 0 {
661 if matches!(*sym, GrNode::Maybe | GrNode::Plus | GrNode::Star) {
662 self.log.add_error(format!(
663 "normalize_var({}): {} must have one child; found none",
664 Symbol::NT(var).to_str(self.get_symbol_table()), *sym));
665 stack.push(new.add(None, GrNode::Symbol(Symbol::Empty)));
667 } else {
668 let new_id = new.add(None, *orig.get(sym.index));
669 stack.push(new_id);
670 if VERBOSE { print!(" leaf: "); }
671 }
672 } else {
673 match *sym {
674 GrNode::Concat | GrNode::Or => {
680 let children = stack.split_off(stack.len() - n);
681 let new_id = if children.iter().all(|&idx| !matches!(new.get(idx), GrNode::Concat|GrNode::Or)) {
682 if VERBOSE { print!(" trivial {}: children={}\n ", *sym, children.iter().map(|s| new.get(*s).to_str(self.get_symbol_table())).join(", ")); }
683 new.addci_iter(None, *sym, children)
685 } else if *sym == GrNode::Or {
686 if VERBOSE {
687 println!(
689 " or: children={}",
690 children.iter().map(|&id| new.to_str_index(Some(id), self.get_symbol_table())).join(", "));
691 }
692 let mut new_children = Vec::new();
700 for id in children {
701 match new.get(id) {
702 GrNode::Symbol(_) | GrNode::Concat | GrNode::Greedy => {
703 if VERBOSE { println!(" - child {id} is {}", new.get(id)); }
704 new_children.push(id);
705 }
706 GrNode::Or => {
707 if VERBOSE { println!(" - child {id} is | with children {:?}", new.children(id)); }
708 new_children.extend(new.children(id));
709 }
710 x => panic!("unexpected node type under | node: {x}"),
711 }
712 }
713 new.addci_iter(None, gnode!(|), new_children)
714 } else { if VERBOSE_CC { println!(" &: children={children:?}"); }
716 let mut dups = Vec::<Vec<Dup>>::new();
728 let concats_children = children.into_iter()
729 .flat_map(|id| {
731 if VERBOSE_CC { print!(" FL {}: ", new.get(id)); }
732 match new.get(id) {
733 GrNode::Concat =>
734 new.children(id).iter().map(|idc| vec![vaddi(&mut dups, [Dup::new(*idc)])]).to_vec(),
735 GrNode::Or => {
736 let children = new.children(id).to_vec();
737 vec![children.into_iter().map(|idc| {
738 if let GrNode::Concat = new.get(idc) {
739 let idc_children = new.children(idc).iter().map(|i| Dup::new(*i)).to_vec();
740 vaddi(&mut dups, idc_children)
741 } else {
742 vaddi(&mut dups, [Dup::new(idc)])
743 }
744 }).to_vec()]
745 }
746 _ => vec![vec![vaddi(&mut dups, [Dup::new(id)])]],
747 }
748 })
749 .cproduct()
752 .map(|dup_ids| {
756 let mut nodes = dup_ids.into_iter()
757 .flat_map(|dup_id| dups.get_mut(dup_id).unwrap().iter_mut()
758 .map(|dup| new.get_dup(dup)).to_vec()).to_vec();
759 remove_concat_dup_empty(&new, &mut nodes);
760 nodes
761 })
762 .to_vec();
764 let concats = concats_children.into_iter()
766 .map(|children_ids| new.addci_iter(None, gnode!(&), children_ids))
767 .to_vec();
768 new.addci_iter(None, gnode!(|), concats)
770 };
771 stack.push(new_id);
772 }
773 GrNode::Maybe => {
774 if n != 1 {
775 self.log.add_error(format!("normalize_var({}): ? must have one child; found {n}: {}",
776 Symbol::NT(var).to_str(self.get_symbol_table()),
777 orig.to_str(Some(sym.index), self.get_symbol_table())));
778 } else {
779 if VERBOSE { print!(" ?: "); }
785 let maybe_child = stack.pop().unwrap();
786 let proceed = match grtree_cleanup(&mut new, Some(maybe_child), true) {
787 None => {
788 self.log.add_error(format!(
789 "unexpected child of ?: {} (should be &, |, or symbol)",
790 grtree_to_str(&new, Some(maybe_child), None, Some(var), self.get_symbol_table(), false)));
791 if VERBOSE { println!("ERROR: unexpected child of ?: {}", grtree_to_str(&new, Some(maybe_child), None, Some(var), self.get_symbol_table(), false)); }
792 return;
793 }
794 Some((true, _)) => {
796 stack.push(maybe_child);
798 if VERBOSE { println!("child of ? simplified to ε"); }
799 false
800 }
801 _ => true,
802 };
803 if proceed {
804 let empty = new.add(None, gnode!(e));
805 let id = match new.get(maybe_child) {
806 GrNode::Or => {
807 new.add(Some(maybe_child), gnode!(e));
808 maybe_child
809 }
810 _ => new.addci_iter(None, gnode!(|), [maybe_child, empty])
811 };
812 stack.push(id);
813 }
814 }
815 }
816 GrNode::Plus | GrNode::Star => {
817 let mut is_plus = *sym == GrNode::Plus;
837 let sym_char = if is_plus { '+' } else { '*' };
838 if VERBOSE { print!(" {sym_char}: "); }
839 if n != 1 {
840 self.log.add_error(format!(
841 "normalize_var({}): {sym_char} must have one child; found {n}: {}",
842 Symbol::NT(var).to_str(self.get_symbol_table()),
843 orig.to_str(Some(sym.index), self.get_symbol_table())));
844 if VERBOSE { println!("ERROR: found {n} children instead of 1"); }
845 return;
846 }
847 let rep_child = stack.pop().unwrap();
848 let proceed = match grtree_cleanup(&mut new, Some(rep_child), true) {
849 None => {
850 self.log.add_error(format!(
851 "unexpected child of {sym_char}: {} (should be &, |, or symbol)",
852 grtree_to_str(&new, Some(rep_child), None, Some(var), self.get_symbol_table(), false)));
853 if VERBOSE { println!("ERROR: unexpected child {}", grtree_to_str(&new, Some(rep_child), None, Some(var), self.get_symbol_table(), false)); }
854 return;
855 }
856 Some((true, _)) => {
858 stack.push(rep_child);
860 if VERBOSE { println!("child simplified to ε"); }
861 false
862 }
863 Some((false, true)) => {
864 if is_plus {
868 is_plus = false;
869 if VERBOSE { print!(" becomes * (child lost ε term), "); }
871 }
872 true
873 }
874 Some((false, false)) => true, };
876 if proceed {
877 if VERBOSE { println!("=> {}", grtree_to_str(&new, Some(rep_child), None, Some(var), self.get_symbol_table(), false)); }
878 let orig_rep = orig_new.add(None, if is_plus { gnode!(+) } else { gnode!(*) });
879 let orig_rep_child = orig_new.add_from_tree(Some(orig_rep), &new, Some(rep_child));
880 let (id, qvar) = self.normalize_plus_or_star(
881 rep_child, orig_rep, orig_rep_child, &mut new, &mut orig_new, var, &mut new_var, is_plus, &mut exclude_nt);
882 stack.push(id);
883 orig_rep_vars.insert(qvar, orig_rep); }
885 }
886 _ => panic!("Unexpected {}", sym.deref())
887 }
888 }
889 if VERBOSE {
890 println!("stack: {}", stack.iter()
891 .map(|id| {
892 let children = new.children(*id);
893 format!("{id}:{}{}", new.get(*id), if children.is_empty() { "".to_string() } else { format!("({})", children.iter().join(",")) })
894 }).join(", ")
895 );
896 }
897 }
898 if stack.len() != 1 {
899 self.log.add_error(format!("normalize_var({}): error while normalizing the rules, {} remaining nodes instead of 1",
900 Symbol::NT(var).to_str(self.get_symbol_table()), stack.len()));
901 return;
902 }
903 if VERBOSE_CC { println!("Final stack id: {}", stack[0]); }
904 let root = stack.pop().unwrap();
905 new.set_root(root);
906 match grtree_cleanup(&mut new, None, false) {
907 None => {
908 self.log.add_error(format!(
909 "unexpected root of {} -> {} (should be &, |, or symbol)",
910 Symbol::NT(var).to_str(self.get_symbol_table()),
911 grtree_to_str(&new, None, None, Some(var), self.get_symbol_table(), false)));
912 if VERBOSE { println!("ERROR: unexpected root {}", grtree_to_str(&new, None, None, Some(var), self.get_symbol_table(), false)); }
913 }
914 Some((true, _)) => {
916 self.log.add_warning(format!("{} is empty", Symbol::NT(var).to_str(self.get_symbol_table())));
917 }
918 _ => {}
919 }
920 let orig_root = orig_new.add_from_tree_callback(None, &new, None, |from, to, _| self.origin.add((var, to), (var, from)));
921 orig_new.set_root(orig_root);
922 while !orig_rep_vars.is_empty() {
923 let mut orig_rep_nodes = Vec::<(usize, usize)>::new();
930 let mut to_remove = Vec::<VarId>::new();
931 for node in orig_new.iter_post_depth() {
932 if let GrNode::Symbol(Symbol::NT(rep_var)) = node.deref() {
933 if let Some(&orig_rep_id) = orig_rep_vars.get(rep_var) {
934 to_remove.push(*rep_var);
935 orig_rep_nodes.push((node.index, orig_rep_id));
936 self.origin.add((*rep_var, self.get_tree(*rep_var).unwrap().get_root().unwrap()), (var, orig_rep_id));
937 }
938 }
939 }
940 for (orig_id, child_id) in orig_rep_nodes {
941 *orig_new.get_mut(orig_id) = gnode!(inst);
942 orig_new.attach_child(orig_id, child_id);
943 }
944 for var in to_remove {
945 orig_rep_vars.remove(&var);
946 }
947 }
948 self.origin.set_tree(var, orig_new);
949 self.set_tree(var, new);
950 }
951 }
952
953 fn normalize_plus_or_star(
954 &mut self, rep_child: usize, orig_rep: usize, orig_rep_child: usize,
955 new: &mut GrTree, orig_new: &mut GrTree, var: VarId, new_var: &mut VarId, is_plus: bool,
956 exclude_nt: &mut HashSet<VarId>
957 ) -> (usize, VarId)
958 {
959 const VERBOSE: bool = false;
960 const OPTIMIZE_SUB_OR: bool = false;
961 if let Some(st) = self.symbol_table.as_ref() {
962 assert_eq!(st.get_num_nt(), self.trees.len(), "number of nt in symbol table doesn't match num_nt");
963 }
964 let (mut qvar, mut rvar) = (*new_var, *new_var + 1);
965 let mut qtree = GrTree::new();
966 let mut rtree = GrTree::new();
967 let mut use_rtree = false;
968
969 let mut lform_nt = None;
971 for node in orig_new.iter_post_depth_at(orig_rep_child) {
972 if let GrNode::LForm(v) = *node {
973 if matches!(lform_nt, Some(v2) if v != v2) {
974 let symtab = self.get_symbol_table();
975 self.log.add_error(
976 format!("in {}, {}: conflicting <L={}> and <L={}>",
977 Symbol::NT(var).to_str(symtab),
978 grtree_to_str(orig_new, Some(orig_rep), None, Some(var), symtab, false),
979 Symbol::NT(lform_nt.unwrap()).to_str(symtab), Symbol::NT(v).to_str(symtab)));
980 } else {
981 lform_nt = Some(v);
982 (qvar, rvar) = (v, *new_var);
983 }
984 }
985 }
986
987 match orig_new.get(orig_rep_child) {
990 GrNode::Symbol(s) => {
991 if VERBOSE { print!("({rep_child}:{s}) "); }
992 let or = qtree.add_root(gnode!(|));
994 let cc = qtree.add(Some(or), gnode!(&));
995 let child = qtree.add(Some(cc), GrNode::Symbol(*s));
996 qtree.add(Some(cc), gnode!(nt qvar));
997 let child2 = qtree.add(Some(or), if is_plus { GrNode::Symbol(*s) } else { gnode!(e) });
998 self.origin.add((qvar, child), (var, orig_rep_child)); self.origin.add((qvar, cc), (var, orig_rep_child));
1000 if is_plus {
1001 self.origin.add((qvar, child2), (var, orig_rep_child));
1002 }
1003 }
1004 GrNode::Concat => {
1005 let id_grchildren = new.children(rep_child);
1006 if VERBOSE { print!("({rep_child}:&({})) ", id_grchildren.iter().join(", ")); }
1007 let or = qtree.add_root(gnode!(|));
1008 let cc1 = qtree.add_from_tree_callback(Some(or), orig_new, Some(orig_rep_child), |to, from, _n| {
1009 self.origin.add((qvar, to), (var, from))
1010 });
1011 let loop_id = qtree.add(Some(cc1), gnode!(nt qvar));
1012 self.origin.add((qvar, loop_id), (var, orig_rep));
1013 if is_plus {
1014 let loop_id2 = qtree.add_from_tree(Some(or), new, Some(rep_child));
1015 self.origin.add((qvar, loop_id2), (var, orig_rep_child));
1016 } else {
1017 qtree.add(Some(or), gnode!(e));
1018 }
1019 }
1020 #[allow(unreachable_patterns)]
1021 GrNode::Or => if !OPTIMIZE_SUB_OR {
1022 let id_grchildren = new.children(rep_child);
1023 if VERBOSE { print!("({rep_child}:|({})) ", id_grchildren.iter().join(", ")); }
1024 let orig_id_grchildren = orig_new.children(orig_rep_child);
1025 let or = qtree.add_root(gnode!(|));
1026 for orig_id_grchild in orig_id_grchildren {
1027 let orig_grchild = orig_new.get(*orig_id_grchild);
1028 match orig_grchild {
1029 GrNode::Symbol(s) => {
1030 let cc = qtree.add(Some(or), gnode!(&));
1031 let child = qtree.add_iter(Some(cc), [GrNode::Symbol(*s), gnode!(nt qvar)])[0];
1032 self.origin.add((qvar, cc), (var, *orig_id_grchild));
1033 self.origin.add((qvar, child), (var, *orig_id_grchild));
1034 if is_plus {
1035 let plus_or = qtree.add(Some(or), GrNode::Symbol(*s));
1036 self.origin.add((qvar, plus_or), (var, *orig_id_grchild));
1037 }
1038 }
1039 GrNode::Concat => {
1040 let cc = qtree.add_from_tree_callback(Some(or), orig_new, Some(*orig_id_grchild), |to, from, _n| {
1041 self.origin.add((qvar, to), (var, from));
1042 });
1043 qtree.add(Some(cc), gnode!(nt qvar));
1044 if is_plus {
1045 qtree.add_from_tree_callback(Some(or), orig_new, Some(*orig_id_grchild), |to, from, _| {
1046 self.origin.add((qvar, to), (var, from));
1047 });
1048 }
1049 }
1050 x => panic!("unexpected node type under a | node: {x}"),
1051 }
1052 }
1053 if !is_plus {
1054 qtree.add(Some(or), gnode!(e));
1055 }
1056 }
1057 #[allow(unreachable_patterns)]
1059 GrNode::Or => if OPTIMIZE_SUB_OR {
1060 let id_grchildren = new.children(rep_child);
1073 if VERBOSE { print!("({rep_child}:|({})) ", id_grchildren.iter().join(", ")); }
1074 let orig_id_grchildren = orig_new.children(orig_rep_child);
1075 let or = qtree.add_root(gnode!(|));
1076 for orig_id_grchild in orig_id_grchildren {
1077 let orig_grchild = new.get(*orig_id_grchild);
1078 match orig_grchild {
1079 GrNode::Symbol(s) => {
1080 if is_plus {
1081 qtree.addc_iter(Some(or), gnode!(&), [GrNode::Symbol(*s), gnode!(nt rvar)]);
1082 use_rtree = true;
1083 } else {
1084 qtree.addc_iter(Some(or), gnode!(&), [GrNode::Symbol(*s), gnode!(nt qvar)]);
1085 }
1086 }
1087 GrNode::Concat => {
1088 let cc = qtree.add_from_tree_callback(Some(or), orig_new, Some(*orig_id_grchild), |to, from, _n| {
1089 self.origin.add((qvar, to), (var, from));
1090 });
1091 if is_plus {
1092 qtree.add(Some(cc), gnode!(nt rvar));
1093 } else {
1094 qtree.add(Some(cc), gnode!(nt qvar));
1095 }
1096 }
1097 x => panic!("unexpected node type under a | node: {x}"),
1098 }
1099 }
1100 if use_rtree {
1101 let or1 = rtree.add_root(gnode!(|));
1102 rtree.add_iter(Some(or1), [gnode!(nt qvar), gnode!(e)]);
1103 } else if !is_plus {
1104 qtree.add(Some(or), gnode!(e));
1105 }
1106 }
1107 _ => panic!("Unexpected node type under a + node: {}", new.get(rep_child))
1108 }
1109 if let Some(v) = lform_nt {
1110 if v == var {
1112 self.log.add_error(
1113 format!("in {}, {}: <L> points to the same nonterminal. It must be a new one, created for the loop.",
1114 Symbol::NT(var).to_str(self.get_symbol_table()),
1115 grtree_to_str(orig_new, Some(orig_rep), None, Some(var), self.get_symbol_table(), false)));
1116 } else {
1117 for mut node in qtree.iter_post_depth_simple_mut() {
1118 if let GrNode::LForm(v2) = node.deref_mut() {
1119 if *v2 == v { *v2 = qvar; }
1120 }
1121 }
1122 for mut node in orig_new.iter_post_depth_simple_at_mut(orig_rep_child) {
1123 if let GrNode::LForm(v2) = node.deref_mut() {
1124 if *v2 == v { *v2 = qvar; }
1125 }
1126 }
1127 }
1128 }
1129 if let Some(st) = self.symbol_table.as_mut() {
1130 if lform_nt.is_none() {
1131 assert_eq!(st.add_child_nonterminal(var), qvar);
1132 }
1133 if use_rtree {
1134 assert_eq!(st.add_child_nonterminal(var), rvar);
1135 }
1136 }
1137 let id = new.add(None, gnode!(nt qvar));
1138 assert!(qvar as usize >= self.trees.len() || self.trees[qvar as usize].is_empty(), "overwriting tree {new_var}");
1139 if VERBOSE { println!("qtree: NT[{qvar}] {} -> {}", Symbol::NT(qvar).to_str(self.get_symbol_table()), grtree_to_str(&qtree, None, None, Some(qvar), self.get_symbol_table(), false) ); }
1140 self.set_tree(qvar, qtree);
1141 exclude_nt.insert(qvar);
1142 self.flags.resize(rvar as usize, 0);
1143 self.parent.resize(rvar as usize, None);
1144 let plus_flag = if is_plus { ruleflag::REPEAT_PLUS } else { 0 };
1145 self.flags[qvar as usize] = ruleflag::CHILD_REPEAT | plus_flag;
1146 self.flags[var as usize] |= ruleflag::PARENT_REPEAT | plus_flag;
1147 self.parent[qvar as usize] = Some(var);
1148 if use_rtree {
1149 if VERBOSE { println!("rtree: NT[{rvar}] {} -> {}", Symbol::NT(rvar).to_str(self.get_symbol_table()), grtree_to_str(&rtree, None, None, Some(rvar), self.get_symbol_table(), false)); }
1150 self.set_tree(rvar, rtree);
1151 exclude_nt.insert(var);
1152 self.flags.resize(rvar as usize + 1, 0);
1153 self.parent.resize(rvar as usize + 1, None);
1154 self.flags[rvar as usize] |= ruleflag::CHILD_L_FACT;
1155 self.parent[rvar as usize] = Some(qvar);
1156 self.flags[qvar as usize] |= ruleflag::PARENT_L_FACTOR;
1157 }
1158 if VERBOSE {
1159 println!("=> new sizes, flags = {}, parent = {}, trees = {} (new_var = {new_var})", self.flags.len(), self.parent.len(), self.trees.len());
1160 println!("=> {}: parent {}, child {}{}",
1161 if is_plus { "+" } else { "*" },
1162 Symbol::NT(var).to_str(self.get_symbol_table()),
1163 Symbol::NT(qvar).to_str(self.get_symbol_table()),
1164 if use_rtree { format!(", child {}", Symbol::NT(rvar).to_str(self.get_symbol_table())) } else { String::new() }
1165 );
1166 }
1167 let mut rectify_maybe = None;
1175 for node in self.get_tree(qvar).unwrap().iter_post_depth_simple() {
1176 if let GrNode::Symbol(Symbol::NT(child)) = node.deref() {
1177 if *child != qvar && self.flags[*child as usize] & ruleflag::CHILD_REPEAT != 0 {
1178 rectify_maybe = Some(*child);
1179 break;
1180 }
1181 }
1182 }
1183 if let Some(child) = rectify_maybe {
1184 self.parent[child as usize] = Some(qvar);
1185 self.flags[qvar as usize] |= ruleflag::PARENT_REPEAT;
1186 if VERBOSE {
1187 println!("=> rectify {}'s parent as {}",
1188 Symbol::NT(child).to_str(self.get_symbol_table()),
1189 Symbol::NT(qvar).to_str(self.get_symbol_table()));
1190 }
1191 }
1192 *new_var = self.get_next_available_var();
1193 (id, qvar)
1194 }
1195}
1196
1197impl Default for RuleTreeSet<General> {
1199 fn default() -> Self {
1200 Self::new()
1201 }
1202}
1203
1204impl BuildFrom<RuleTreeSet<General>> for RuleTreeSet<Normalized> {
1205 fn build_from(mut rules: RuleTreeSet<General>) -> Self {
1210 if rules.log.has_no_errors() {
1214 rules.normalize();
1215 }
1216 RuleTreeSet::<Normalized> {
1217 trees: rules.trees,
1218 start: rules.start,
1219 symbol_table: rules.symbol_table,
1220 flags: rules.flags,
1221 parent: rules.parent,
1222 nt_conversion: rules.nt_conversion,
1223 origin: rules.origin,
1224 log: rules.log,
1225 _phantom: PhantomData
1226 }
1227 }
1228}
1229
1230pub mod macros {
1241 #[macro_export]
1264 macro_rules! gnode {
1265 ([$id:expr]) => { gnode!(t $id) };
1266 (t $id:expr) => { $crate::grammar::GrNode::Symbol($crate::parser::Symbol::T($id as $crate::TokenId)) };
1267 (nt $id:expr) => { $crate::grammar::GrNode::Symbol($crate::parser::Symbol::NT($id as $crate::VarId)) };
1268 (e) => { $crate::grammar::GrNode::Symbol($crate::parser::Symbol::Empty) };
1269 (end) => { $crate::grammar::GrNode::Symbol($crate::parser::Symbol::End) };
1270 (&) => { $crate::grammar::GrNode::Concat };
1272 (|) => { $crate::grammar::GrNode::Or };
1273 (?) => { $crate::grammar::GrNode::Maybe };
1274 (+) => { $crate::grammar::GrNode::Plus };
1275 (*) => { $crate::grammar::GrNode::Star };
1276 (L $id:expr) => { $crate::grammar::GrNode::LForm($id) };
1277 (R) => { $crate::grammar::GrNode::RAssoc };
1278 (P) => { $crate::grammar::GrNode::PrecEq };
1279 (inst) => { $crate::grammar::GrNode::Instance };
1280 (G) => { $crate::grammar::GrNode::Greedy };
1281 }
1282
1283 #[macro_export]
1294 macro_rules! sym {
1295 (t $id:expr) => { $crate::parser::Symbol::T($id as $crate::TokenId) };
1296 (nt $id:expr) => { $crate::parser::Symbol::NT($id as $crate::VarId) };
1297 (e) => { $crate::parser::Symbol::Empty };
1298 (end) => { $crate::parser::Symbol::End };
1299 }
1300
1301 #[macro_export]
1302 macro_rules! altflag {
1303 (L) => { $crate::alt::ruleflag::L_FORM };
1304 (R) => { $crate::alt::ruleflag::R_ASSOC };
1305 (G) => { $crate::alt::ruleflag::GREEDY };
1306 (P) => { $crate::alt::ruleflag::PREC_EQ };
1307 ($f:expr) => { $f };
1308 }
1309
1310 #[macro_export]
1333 macro_rules! alt {
1334 () => { $crate::alt::Alternative::new(std::vec![]) };
1335 ($($a:ident $($b:expr)?,)+) => { alt!($($a $($b)?),+) };
1336 ($($a:ident $($b:expr)?),*) => { $crate::alt::Alternative::new(std::vec![$($crate::sym!($a $($b)?)),*]) };
1337 (#$f:literal, $($a:ident $($b:expr)?,)+) => { alt!(#$f, $($a $($b)?),+) };
1338 (#$f:literal, $($a:ident $($b:expr)?),*) => { $crate::alt::Alternative::new(std::vec![$($crate::sym!($a $($b)?)),*]).with_flags($f) };
1339 ($(#$f:ident,)? $(%($v:expr, $id:expr),)? $($a:ident $($b:expr)?,)+) => { alt!($(#$f,)? $(%($v, $id),)? $($a $($b)?),+) };
1340 ($(#$f:ident,)? $(%($v:expr, $id:expr),)? $($a:ident $($b:expr)?),*)
1341 => { $crate::alt::Alternative::new(std::vec![$($crate::sym!($a $($b)?)),*])$(.with_flags($crate::altflag!($f)))?$(.with_origin($v, $id))? };
1342 (#($f:expr, $o:expr), $(%($v:expr, $id:expr),)? $($a:ident $($b:expr)?,)+)
1343 => { alt!(#($f, $o), $(%($v, $id),)? $($a $($b)?),+) };
1344 (#($f:expr, $o:expr), $(%($v:expr, $id:expr),)? $($a:ident $($b:expr)?),*)
1345 => { $crate::alt::Alternative::new(std::vec![$($crate::sym!($a $($b)?)),*]).with_flags($crate::altflag!($f)).with_ambig_alt_id($o)$(.with_origin($v, $id))? };
1346 (%($v:expr, $id:expr), $($a:ident $($b:expr)?,)+)
1347 => { alt!(%($v, $id), $($a $($b)?),+) };
1348 (%($v:expr, $id:expr), $($a:ident $($b:expr)?),*)
1349 => { $crate::alt::Alternative::new(std::vec![$($crate::sym!($a $($b)?)),*]).with_flags($crate::altflag!($f)).with_origin($v, $id) };
1350 }
1351
1352 #[macro_export]
1353 macro_rules! symbols {
1354 () => { std::vec![] };
1355 ($($a:ident $($b:literal $(: $num:expr)?)?,)+) => { symbols![$($a $($b $(: $num)?)?),+] };
1356 ($($a:ident $($b:literal $(: $num:expr)?)?),*) => { std::vec![$($crate::sym!($a $($b $(: $num)?)?)),*] };
1357 }
1358
1359 #[macro_export]
1380 macro_rules! prule {
1381 () => { std::vec![] };
1382 ($($(#$f:literal,)? $($a:ident $($b:expr)?),*;)+) => { prule![$($(#$f,)? $($a $($b)?),+);+] };
1383 ($($(#$f:literal,)? $($a:ident $($b:expr)?),*);*) => { std::vec![$($crate::alt![$(#$f,)? $($a $($b)?),+]),*]};
1384 ($($(#$f:ident,)? $(%($v:expr, $id:expr),)? $($a:ident $($b:expr)?),*;)+) => { prule![$($(#$f,)? $(%($v, $id),)? $($a $($b)?),+);+] };
1385 ($($(#$f:ident,)? $(%($v:expr, $id:expr),)? $($a:ident $($b:expr)?),*);*) => { std::vec![$($crate::alt![$(#$f,)? $(%($v, $id),)? $($a $($b)?),+]),*]};
1386 ($($(#($f:expr, $o:expr),)? $(%($v:expr, $id:expr),)? $($a:ident $($b:expr)?),*;)+) => { prule![$($(#($f, $o),)? $(%($v, $id),)? $($a $($b)?),+);+] };
1387 ($($(#($f:expr, $o:expr),)? $(%($v:expr, $id:expr),)? $($a:ident $($b:expr)?),*);*) => { std::vec![$($crate::alt![$(#($f,$o),)? $(%($v, $id),)? $($a $($b)?),+]),*]};
1388 }
1389}