Skip to main content

lexigram_lib/rtsgen/
mod.rs

1// Copyright (c) 2025 Redglyph (@gmail.com). All Rights Reserved.
2
3// =============================================================================================
4// Parser for the simplified grammars used in unit tests
5// (lexer/parser generated by the build-rtsgen crate)
6
7mod tests;
8
9use std::collections::HashMap;
10use std::io::Cursor;
11use std::str::FromStr;
12use iter_index::IndexerIterator;
13use vectree::VecTree;
14use lexigram_core::CollectJoin;
15use crate::{General, NameFixer, NameTransformer, SymbolTable};
16use crate::{TokenId, VarId};
17use crate::grammar::{GrNode, GrTree, RuleTreeSet};
18use crate::char_reader::CharReader;
19use crate::lexer::{Lexer, TokenSpliterator};
20use lexigram_core::log::{BufLog, LogStatus, Logger};
21use crate::parser::{Parser, Symbol};
22use crate::rtsgen::listener_types::*;
23use crate::rtsgen::rtsgen_lexer::build_lexer;
24use crate::rtsgen::rtsgen_parser::*;
25
26static T_NAME_DICTIONARY: &[(&str, &str)] = &[
27    ("+", "Add"), ("-", "Sub"), ("*", "Mul"), ("/", "Div"), ("%", "Percent"), ("++", "Inc"), ("--", "Dec"),
28    ("<<", "Shl"), (">>", "Shr"), ("!", "Not"), ("^", "Exp"), ("~", "Tilde"),
29    ("&", "And"), ("|", "Or"), ("&&", "And2"), ("||", "Or2"),
30    ("=", "Eq"), ("==", "Eq2"), ("<", "Lt"), (">", "Gt"), ("<=", "LtEq"), (">=", "GtEq"), ("!=", "Neq"),
31    (":=", "ColonEq"), ("+=", "AddEq"), ("-=", "SubEq"), ("*=", "MulEq"), ("/=", "DivEq"),
32    ("(", "LPar"), (")", "RPar"), ("[", "LSBracket"), ("]", "RSBracker"), ("{", "LBracket"), ("}", "RBracket"),
33    ("\"", "DQuote"), ("'", "Quote"), ("$", "Dollar"), ("?", "Question"), ("\\", "Backslash"),
34    (":", "Colon"), (";", "SemiColon"), (".", "Dot"), (",", "Comma"), ("#", "Sharp"), ("@", "At"), ("´", "Tick"), ("`", "BTick"),
35    ("\n", "EOL"), ("\r\n", "WinEOL"), ("\r", "CR"), ("\t", "Tab"), (" ", "Space"), ("\\", "Backslash"), ("\0", "Null"),
36    ("->", "Arrow"), ("=>", "DArrow"),
37];
38
39pub struct RtsGen<'l, 'p> {
40    lexer: Lexer<'l, Cursor<String>>,
41    parser: Parser<'p>,
42    t_name_dictionary: Option<HashMap<String, String>>,
43}
44
45impl RtsGen<'_, '_> {
46    pub fn new() -> Self {
47        let t_name_dictionary = Some(HashMap::from_iter(T_NAME_DICTIONARY.iter().map(|(a, b)| (a.to_string(), b.to_string()))));
48        RtsGen::with_guess_names(t_name_dictionary)
49    }
50
51    pub fn with_guess_names(t_name_dictionary: Option<HashMap<String, String>>) -> Self {
52        let lexer = build_lexer();
53        let parser = build_parser();
54        RtsGen { lexer, parser, t_name_dictionary }
55    }
56
57    pub fn parse(&mut self, text: String) -> Result<RuleTreeSet<General>, BufLog> {
58        const VERBOSE_WRAPPER: bool = false;
59
60        let mut wrapper = Wrapper::new(RGListener::new(self.t_name_dictionary.as_ref()), VERBOSE_WRAPPER);
61        let stream = CharReader::new(Cursor::new(text));
62        self.lexer.attach_stream(stream);
63        let tokens = self.lexer.tokens().split_channel0(|(_tok, ch, text, pos_span)|
64            panic!("unexpected channel {ch} while parsing a file at {pos_span}, \"{text}\"")
65        );
66        let _ = self.parser.parse_stream(&mut wrapper, tokens); // errors are written in the log, so we can dismiss the error here
67        let listener = wrapper.give_listener();
68        listener.make_rts()
69    }
70}
71
72impl Default for RtsGen<'_, '_> {
73    fn default() -> Self {
74        Self::new()
75    }
76}
77
78// listener implementation
79
80struct RGListener<'a> {
81    log: BufLog,
82    nt: HashMap<String, VarId>,
83    nt_def_order: Vec<VarId>,
84    rules: Vec<GrTree>,
85    reserved_nt: Vec<VarId>,
86    symbol_table: Option<SymbolTable>,
87    t: HashMap<String, TokenId>,
88    num_t: usize,
89    /// terminal information; `(String, Option<String>)` = (token name, optional string if not variable)
90    tokens: Vec<(String, Option<String>)>,
91    curr: Option<GrTree>,
92    curr_name: Option<String>,
93    curr_nt: Option<VarId>,
94    t_name_dictionary: Option<&'a HashMap<String, String>>,
95}
96
97#[derive(Clone, Copy, PartialEq)]
98enum IsNew { No, Yes }
99
100trait ToVarId {
101    fn to_var_id(self, panic_message: &str) -> VarId;
102}
103
104impl ToVarId for usize {
105    fn to_var_id(self, panic_message: &str) -> VarId {
106        if self < (VarId::MAX as usize) {
107            self as VarId
108        } else {
109            panic!("{panic_message}")
110        }
111    }
112}
113
114impl<'a> RGListener<'a> {
115    fn new(t_name_dictionary: Option<&'a HashMap<String, String>>) -> Self {
116        RGListener {
117            log: BufLog::new(),
118            nt: HashMap::new(),
119            nt_def_order: Vec::new(),
120            rules: Vec::new(),
121            reserved_nt: Vec::new(),
122            symbol_table: None,
123            t: HashMap::new(),
124            num_t: 0,
125            tokens: Vec::new(),
126            curr: None,
127            curr_name: None,
128            curr_nt: None,
129            t_name_dictionary,
130        }
131    }
132
133    pub fn make_rts(self) -> Result<RuleTreeSet<General>, BufLog> {
134        let RGListener { log, rules, symbol_table, .. } = self;
135        if log.has_no_errors() {
136            let mut rts = RuleTreeSet::<General>::with_log(log);
137            rts.set_symbol_table(symbol_table.unwrap());
138            rts.set_start(0);
139            for (var, rule) in rules.into_iter().index::<VarId>() {
140                rts.set_tree(var, rule);
141            }
142            Ok(rts)
143        } else {
144            Err(log)
145        }
146    }
147
148    /// Gets the nonterminal ID corresponding to the name, creating it if
149    /// it doesn't exist.
150    fn get_or_create_nt(&mut self, name: String) -> VarId {
151        let size = self.nt.len();
152        *self.nt.entry(name).or_insert_with(|| {
153            self.rules.push(GrTree::new());
154            size.to_var_id("too many nonterminals")
155        })
156    }
157
158    /// Gets the terminal ID corresponding to the name or value, creating it if
159    /// it doesn't exist.
160    ///
161    /// Returns
162    /// * `IsNew` = `Yes` if the terminal had to be created, `No` otherwise
163    /// * `TokenId` = the terminal ID
164    fn get_or_create_t(&mut self, name: String) -> (IsNew, TokenId) {
165        let mut is_new = IsNew::No;
166        let tok = *self.t.entry(name).or_insert_with(|| {
167            is_new = IsNew::Yes;
168            let tok = self.num_t.to_var_id("too many terminals"); // VarId = TokenId
169            self.num_t += 1;
170            tok
171        });
172        (is_new, tok)
173    }
174
175    fn invent_t_name(&self, tok: TokenId, value: &str) -> String {
176        self.t_name_dictionary
177            .and_then(|g| g.get(value).cloned())
178            .unwrap_or_else(|| {
179                if value.chars().any(|c| c.is_ascii_alphanumeric()) &&
180                    value.chars().all(|c| c.is_ascii_alphanumeric() || c.is_whitespace() || c == '_')
181                {
182                    let name = value.chars().map(|c| if c.is_whitespace() { '_' } else { c }).collect::<String>();
183                    if !value.as_bytes()[0].is_ascii_alphabetic() {
184                        format!("Tok{}", name.to_camelcase())
185                    } else {
186                        name.to_camelcase()
187                    }
188                } else {
189                    format!("Token{tok}")
190                }
191            })
192    }
193
194    /// Finalizes the rules and creates the symbol table.
195    fn finalize_ruleset(&mut self) {
196        let mut nt_name = vec![String::new(); self.nt.len()];
197        let mut dest = vec![0; self.nt.len()];
198        self.nt_def_order.iter().enumerate().for_each(|(i, &nt)| dest[nt as usize] = i);
199        for (name, var) in &self.nt {
200            nt_name[dest[*var as usize]] = name.clone();
201        }
202
203        // detects undefined nonterminals
204        let mut undefined = self.nt.iter()
205            .filter_map(|(name, &var)| if self.rules[var as usize].is_empty() { Some(name.to_string()) } else { None })
206            .to_vec();
207        if !undefined.is_empty() {
208            undefined.sort(); // comes from hashmap
209            self.log.add_error(format!("undefined nonterminals: {}", undefined.into_iter().map(|s| format!("'{s}'")).join(", ")));
210            return;
211        }
212
213        // builds symbol table
214        assert_eq!(self.tokens.len(), self.num_t);
215        let mut symtab = SymbolTable::new();
216        symtab.extend_nonterminals(nt_name);
217        let mut t_name = vec![(String::new(), None); self.tokens.len()];
218        let mut namefixer = NameFixer::new_empty();
219        for (tok, (name, value_maybe)) in self.tokens.iter().enumerate().filter(|(_, (name, _))| !name.is_empty()) {
220            namefixer.add(name.clone());
221            t_name[tok] = (name.clone(), value_maybe.clone());
222        }
223
224        // puts names to constant terminals
225        for (tok, (_, cst_maybe)) in self.tokens.iter().enumerate().filter(|(_, (name, _))| name.is_empty()) {
226            let new_name = namefixer.get_unique_name(self.invent_t_name(tok as TokenId, cst_maybe.as_ref().unwrap()));
227            t_name[tok] = (new_name, cst_maybe.clone());
228        }
229        symtab.extend_terminals(t_name);
230        self.symbol_table = Some(symtab);
231
232        // remove reserved nonterminals
233        for v in &self.reserved_nt {
234            self.rules[*v as usize].clear();
235        }
236
237        // reorders nonterminal IDs by order of definition rather than order of appearance
238        self.rules = self.nt_def_order.iter()
239            .map(|nt| std::mem::take(self.rules.get_mut(*nt as usize).unwrap()))
240            .collect();
241        for rule in &mut self.rules {
242            for mut node in rule.iter_post_depth_simple_mut() {
243                match *node {
244                    GrNode::Symbol(Symbol::NT(ref mut old))
245                    | GrNode::LForm(ref mut old) => *old = *dest.get(*old as usize).unwrap_or(&(*old as usize)) as VarId,
246                    _ => {}
247                }
248            }
249        }
250    }
251}
252
253impl RtsGenListener for RGListener<'_> {
254    fn get_log_mut(&mut self) -> &mut impl Logger {
255        &mut self.log
256    }
257
258    fn exit(&mut self, _ruleset: SynFile) {
259        self.finalize_ruleset();
260    }
261
262    fn exit_file(&mut self, _ctx: CtxFile) -> SynFile {
263        SynFile()
264    }
265
266    fn exit_decls(&mut self, _ctx: CtxDecls) -> SynDecls {
267        SynDecls()
268    }
269
270    fn exit_decl(&mut self, _ctx: CtxDecl) -> SynDecl {
271        SynDecl()
272    }
273
274    fn exit_decl_terminal(&mut self, ctx: CtxDeclTerminal) -> SynDeclTerminal {
275        match ctx {
276            // decl_terminal -> Terminal "=" TerminalCst
277            CtxDeclTerminal::V1 { terminal, terminalcst } => {
278                if self.t.contains_key(&terminal) {
279                    self.log.add_error(format!("token '{terminal}' already declared"));
280                } else if self.t.contains_key(&terminalcst) {
281                    self.log.add_error(format!("token value {terminalcst} already used"));
282                } else {
283                    let token = self.num_t.to_var_id("too many terminals");
284                    self.num_t += 1;
285                    self.tokens.push((terminal.clone(), Some(terminalcst[1..terminalcst.len() - 1].to_string())));
286                    self.t.insert(terminal, token);
287                    self.t.insert(terminalcst, token);
288                }
289
290            }
291            // decl_terminal -> Terminal
292            CtxDeclTerminal::V2 { terminal } => {
293                if self.t.contains_key(&terminal) {
294                    self.log.add_error(format!("token '{terminal}' already declared"));
295                } else {
296                    let token = self.num_t.to_var_id("too many terminals");
297                    self.num_t += 1;
298                    self.tokens.push((terminal.clone(), None));
299                    self.t.insert(terminal, token);
300                }
301            }
302        };
303        SynDeclTerminal()
304    }
305
306    fn exit_ruleset(&mut self, _ctx: CtxRuleset) -> SynRuleset {
307        SynRuleset()
308    }
309
310    fn init_rule(&mut self) {
311        self.curr_name = None;
312        self.curr = Some(VecTree::new());
313        self.curr_nt = None;
314    }
315
316    fn exit_rule(&mut self, ctx: CtxRule) -> SynRule {
317        let (var, id) = match ctx {
318            // rule -> rule_nt "->" prs_expr ";"
319            CtxRule::V1 { rule_nt: SynRuleNt(var), rts_expr: SynRtsExpr(id_expr) }
320            // rule -> rule_nt "=>" rts_expr ";"
321            | CtxRule::V2 { rule_nt: SynRuleNt(var), prs_expr: SynPrsExpr(id_expr) } => (var, id_expr),
322        };
323        let mut tree = self.curr.take().unwrap();
324        tree.set_root(id);
325        self.rules[var as usize] = tree;
326        SynRule()
327    }
328
329    fn exit_rule_nt(&mut self, ctx: CtxRuleNt) -> SynRuleNt {
330        let CtxRuleNt::V1 { nonterminal } = ctx;
331        let mut error = false;
332        assert_eq!(self.curr_nt, None);
333        let var = if let Some(&var) = self.nt.get(&nonterminal) {
334            if !self.rules[var as usize].is_empty() {
335                error = true;
336                self.log.add_error(format!("nonterminal '{nonterminal}' is defined multiple times"));
337            }
338            var
339        } else {
340            self.get_or_create_nt(nonterminal.clone())
341        };
342        if !error { self.nt_def_order.push(var); }
343        self.curr_nt = Some(var);
344        self.curr_name = Some(nonterminal);
345        SynRuleNt(var)
346    }
347
348    fn exit_rts_expr(&mut self, ctx: CtxRtsExpr) -> SynRtsExpr {
349        let tree = self.curr.as_mut().unwrap();
350        let id = match ctx {
351            // rts_expr -> "&" rts_children
352            CtxRtsExpr::V1 { rts_children: SynRtsChildren(v) } =>
353                tree.addci_iter(None, GrNode::Concat, v.into_iter().map(|SynRtsExpr(id)| id)),
354            // rts_expr -> "|" rts_children
355            CtxRtsExpr::V2 { rts_children: SynRtsChildren(v) } =>
356                tree.addci_iter(None, GrNode::Or, v.into_iter().map(|SynRtsExpr(id)| id)),
357            // rts_expr -> "+" rts_children
358            CtxRtsExpr::V3 { rts_children: SynRtsChildren(v) } =>
359                tree.addci_iter(None, GrNode::Plus, v.into_iter().map(|SynRtsExpr(id)| id)),
360            // rts_expr -> "*" rts_children
361            CtxRtsExpr::V4 { rts_children: SynRtsChildren(v) } =>
362                tree.addci_iter(None, GrNode::Star, v.into_iter().map(|SynRtsExpr(id)| id)),
363            // rts_expr -> "?" rts_children
364            CtxRtsExpr::V5 { rts_children: SynRtsChildren(v) } =>
365                tree.addci_iter(None, GrNode::Maybe, v.into_iter().map(|SynRtsExpr(id)| id)),
366            // rts_expr -> item
367            CtxRtsExpr::V6 { item: SynItem(id_item) } =>
368                id_item,
369        };
370        SynRtsExpr(id)
371    }
372
373    fn exit_rts_children(&mut self, ctx: CtxRtsChildren) -> SynRtsChildren {
374        // rts_children -> "(" rts_expr* ")"
375        let CtxRtsChildren::V1 { star: SynRtsChildren1(v) } = ctx;
376        SynRtsChildren(v)
377    }
378
379    fn exit_prs_expr(&mut self, ctx: CtxPrsExpr) -> SynPrsExpr {
380        let tree = self.curr.as_mut().unwrap();
381        let id = match ctx {
382            // prs_expr -> prs_expr "+"
383            CtxPrsExpr::V1 { prs_expr: SynPrsExpr(id) } =>
384                tree.addci(None, GrNode::Plus, id),
385            // prs_expr -> prs_expr "*"
386            CtxPrsExpr::V2 { prs_expr: SynPrsExpr(id) } =>
387                tree.addci(None, GrNode::Star, id),
388            // prs_expr -> prs_expr "?"
389            CtxPrsExpr::V3 { prs_expr: SynPrsExpr(id) } =>
390                tree.addci(None, GrNode::Maybe, id),
391            // prs_expr -> prs_expr prs_expr
392            CtxPrsExpr::V4 { prs_expr: [SynPrsExpr(mut left), SynPrsExpr(right)] } => {
393                if *tree.get(left) != GrNode::Concat {
394                    left = tree.addci(None, GrNode::Concat, left);
395                }
396                tree.attach_child(left, right);
397                left
398            }
399            // prs_expr -> prs_expr "|" prs_expr
400            CtxPrsExpr::V5 { prs_expr: [SynPrsExpr(mut left), SynPrsExpr(right)] } => {
401                if *tree.get(left) != GrNode::Or {
402                    left = tree.addci(None, GrNode::Or, left);
403                }
404                tree.attach_child(left, right);
405                left
406            }
407            // prs_expr -> "(" prs_expr ")"
408            CtxPrsExpr::V6 { prs_expr: SynPrsExpr(id) } => id,
409            // prs_expr -> item
410            CtxPrsExpr::V7 { item: SynItem(id) } => id,
411        };
412        SynPrsExpr(id)
413    }
414
415    fn exit_item(&mut self, ctx: CtxItem) -> SynItem {
416        let id = match ctx {
417            // item -> Nonterminal
418            CtxItem::V1 { nonterminal } => {
419                let var = self.get_or_create_nt(nonterminal);
420                self.curr.as_mut().unwrap().add(None, GrNode::Symbol(Symbol::NT(var)))
421            }
422            // item -> NTx (NT symbol without any check or creation process)
423            CtxItem::V2 { ntx } => {
424                let x = match VarId::from_str(&ntx[3..ntx.len() - 1]) {
425                    Ok(x) => x,
426                    Err(e) => {
427                        self.log.add_error(format!("in {}, integer literal {ntx} can't be parsed: {e}", self.curr_name.as_ref().unwrap()));
428                        VarId::MAX
429                    }
430                };
431                self.curr.as_mut().unwrap().add(None, GrNode::Symbol(Symbol::NT(x)))
432            }
433            // item -> Terminal
434            CtxItem::V3 { terminal } => {
435                let (is_new, tok) = self.get_or_create_t(terminal.clone());
436                if let IsNew::Yes = is_new {
437                    self.tokens.push((terminal, None));
438                }
439                self.curr.as_mut().unwrap().add(None, GrNode::Symbol(Symbol::T(tok)))
440            }
441            // item -> TerminalCst
442            CtxItem::V4 { terminalcst } => {
443                let (is_new, tok) = self.get_or_create_t(terminalcst.clone());
444                if let IsNew::Yes = is_new {
445                    // the names will be set later, to give priority to variable terminal names in case of conflict
446                    match decode_str(&terminalcst[1..terminalcst.len() - 1]) {
447                        Ok(text) => {
448                            self.tokens.push((String::new(), Some(text)));
449                        }
450                        Err(msg) => {
451                            self.log.add_error(format!("in {}, string literal {terminalcst}: {msg}", self.curr_name.as_ref().unwrap()));
452                            self.tokens.push((String::new(), Some("???".to_string())));
453                        }
454                    }
455                }
456                self.curr.as_mut().unwrap().add(None, GrNode::Symbol(Symbol::T(tok)))
457            }
458            // item -> Tx (T symbol without any check or creation process)
459            CtxItem::V5 { tx } => {
460                let x = match VarId::from_str(&tx[2..tx.len() - 1]) {
461                    Ok(x) => x,
462                    Err(e) => {
463                        self.log.add_error(format!("in {}, integer literal {tx} can't be parsed: {e}", self.curr_name.as_ref().unwrap()));
464                        VarId::MAX
465                    }
466                };
467                self.curr.as_mut().unwrap().add(None, GrNode::Symbol(Symbol::T(x)))
468            }
469            // item -> Empty
470            CtxItem::V6 { .. } =>
471                self.curr.as_mut().unwrap().add(None, GrNode::Symbol(Symbol::Empty)),
472            // item -> LTag
473            CtxItem::V7 { ltag } => {
474                // `ltag` contains "<L=name>" or "<L>"
475                let var = if ltag.len() > 3 {
476                    let name = &ltag[3..ltag.len()-1];
477                    let var = self.get_or_create_nt(name.to_string());
478                    self.nt_def_order.push(var);
479                    self.rules[var as usize].add_root(GrNode::Symbol(Symbol::Empty));
480                    self.reserved_nt.push(var);
481                    var
482                } else {
483                    self.curr_nt.unwrap()
484                };
485                self.curr.as_mut().unwrap().add(None, GrNode::LForm(var))
486            }
487            // item -> "<P>"
488            CtxItem::V8 => self.curr.as_mut().unwrap().add(None, GrNode::PrecEq),
489            // item -> "<R>"
490            CtxItem::V9 => self.curr.as_mut().unwrap().add(None, GrNode::RAssoc),
491            // `item -> "<G>"`
492            CtxItem::V10 => self.curr.as_mut().unwrap().add(None, GrNode::Greedy),
493        };
494        SynItem(id)
495    }
496}
497
498/// Decodes a string literal (without its surrounding quotes). There must be at least two characters in `strlit`.
499fn decode_str(strlit: &str) -> Result<String, String> {
500    let mut result = String::new();
501    let mut chars = strlit.chars();
502    while let Some(c) = chars.next() {
503        match c {
504            '\\' => {
505                result.push(match chars.next().ok_or(format!("'\\' incomplete escape code in string literal '{strlit}'"))? {
506                    'n' => '\n',
507                    'r' => '\r',
508                    't' => '\t',
509                    '\"' => '\"',
510                    '\\' => '\\',
511                    'u' => {
512                        if !matches!(chars.next(), Some('{')) { return Err(format!("malformed unicode literal in string literal '{strlit}' (missing '{{')")); }
513                        let mut hex = String::new();
514                        loop {
515                            let Some(h) = chars.next() else { return Err(format!("malformed unicode literal in string literal '{strlit}' (missing '}}')")); };
516                            if h == '}' { break; }
517                            hex.push(h);
518                        };
519                        let code = u32::from_str_radix(&hex, 16).map_err(|_| format!("'{hex}' isn't a valid hexadecimal value"))?;
520                        char::from_u32(code).ok_or_else(|| format!("'{hex}' isn't a valid unicode hexadecimal value"))?
521                    }
522                    unknown => return Err(format!("unknown escape code '\\{unknown}' in string literal '{strlit}'"))
523                });
524            }
525            _ => result.push(c)
526        }
527    }
528    Ok(result)
529}
530
531// -------------------------------------------------------------------------
532// User types used in the listener interface:
533// (initially copied/uncommented from the generated parser code)
534
535pub mod listener_types {
536    use crate::VarId;
537
538    /// User-defined type for `file`
539    #[derive(Debug, PartialEq)] pub struct SynFile();
540    /// User-defined type for `decls`
541    #[derive(Debug, PartialEq)] pub struct SynDecls();
542    /// User-defined type for `decl`
543    #[derive(Debug, PartialEq)] pub struct SynDecl();
544    /// User-defined type for `decl_terminal`
545    #[derive(Debug, PartialEq)] pub struct SynDeclTerminal();
546    /// User-defined type for `ruleset`
547    #[derive(Debug, PartialEq)] pub struct SynRuleset();
548    /// User-defined type for `rule`
549    #[derive(Debug, PartialEq)] pub struct SynRule();
550    /// User-defined type for `rule_nt`
551    #[derive(Debug, PartialEq)] pub struct SynRuleNt(pub VarId);
552    /// User-defined type for `rts_expr`
553    #[derive(Debug, PartialEq)] pub struct SynRtsExpr(pub usize);
554    /// User-defined type for `rts_children`
555    #[derive(Debug, PartialEq)] pub struct SynRtsChildren(pub Vec<SynRtsExpr>);
556    /// User-defined type for `prs_expr`
557    #[derive(Debug, PartialEq)] pub struct SynPrsExpr(pub usize);
558    /// User-defined type for `item`
559    #[derive(Debug, PartialEq)] pub struct SynItem(pub usize);
560}
561
562// -------------------------------------------------------------------------
563
564pub mod rtsgen_lexer {
565    // Generated code, don't modify manually anything between the tags below
566    use crate as lexigram_lib;
567
568    // [rtsgen_lexer]
569
570    use std::collections::HashMap;
571    use std::io::Read;
572    use lexigram_lib::lexer::{ActionOption, Lexer, ModeOption, StateId, Terminal};
573    use lexigram_lib::segmap::{GroupId, Seg, SegMap};
574
575    const NBR_GROUPS: u32 = 43;
576    const INITIAL_STATE: StateId = 0;
577    const FIRST_END_STATE: StateId = 23;
578    const NBR_STATES: StateId = 56;
579    static ASCII_TO_GROUP: [GroupId; 128] = [
580         31,  31,  31,  31,  31,  31,  31,  31,  31,  22,  39,  31,  31,  39,  31,  31,   // 0-15
581         31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,   // 16-31
582          0,  31,   1,  31,  31,  31,   2,  31,   3,   4,   5,   6,   7,   8,  31,   9,   // 32-47
583         37,  30,  30,  30,  30,  30,  30,  30,  30,  30,  31,  10,  11,  12,  23,  13,   // 48-63
584         31,  29,  29,  29,  29,  29,  29,  14,  34,  34,  34,  34,  26,  34,  15,  34,   // 64-79
585         27,  34,  28,  34,  16,  34,  34,  34,  34,  34,  34,  31,  24,  31,  31,  35,   // 80-95
586         31,  33,  33,  33,  33,  41,  33,  36,  36,  36,  36,  40,  36,  36,  42,  38,   // 96-111
587         36,  36,  17,  36,  18,  32,  36,  36,  36,  36,  36,  19,  20,  25,  31,  31,   // 112-127
588    ];
589    static UTF8_TO_GROUP: [(char, GroupId); 2] = [
590        ('ε', 21),
591        ('€', 21),
592    ];
593    static SEG_TO_GROUP: [(Seg, GroupId); 4] = [
594        (Seg(128, 948), 31),
595        (Seg(950, 8363), 31),
596        (Seg(8365, 55295), 31),
597        (Seg(57344, 1114111), 31),
598    ];
599    static TERMINAL_TABLE: [Terminal;33] = [
600        Terminal { action: ActionOption::Skip, channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
601        Terminal { action: ActionOption::Token(2), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
602        Terminal { action: ActionOption::Token(10), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
603        Terminal { action: ActionOption::Token(11), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
604        Terminal { action: ActionOption::Token(5), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
605        Terminal { action: ActionOption::Token(4), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
606        Terminal { action: ActionOption::Token(9), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
607        Terminal { action: ActionOption::Token(12), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
608        Terminal { action: ActionOption::Token(8), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
609        Terminal { action: ActionOption::Token(6), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
610        Terminal { action: ActionOption::Token(19), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
611        Terminal { action: ActionOption::Token(19), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
612        Terminal { action: ActionOption::Token(19), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
613        Terminal { action: ActionOption::Token(20), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
614        Terminal { action: ActionOption::Token(20), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
615        Terminal { action: ActionOption::Token(3), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
616        Terminal { action: ActionOption::Token(7), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
617        Terminal { action: ActionOption::Skip, channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
618        Terminal { action: ActionOption::Skip, channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
619        Terminal { action: ActionOption::Token(0), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
620        Terminal { action: ActionOption::Token(1), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
621        Terminal { action: ActionOption::Token(13), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
622        Terminal { action: ActionOption::Token(14), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
623        Terminal { action: ActionOption::Token(15), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
624        Terminal { action: ActionOption::Token(16), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
625        Terminal { action: ActionOption::Token(20), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
626        Terminal { action: ActionOption::Token(20), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
627        Terminal { action: ActionOption::Token(20), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
628        Terminal { action: ActionOption::Token(17), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
629        Terminal { action: ActionOption::Token(18), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
630        Terminal { action: ActionOption::Token(19), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
631        Terminal { action: ActionOption::Token(21), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
632        Terminal { action: ActionOption::Token(22), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
633    ];
634    static STATE_TABLE: [StateId; 2409] = [
635         23,   1,  24,  25,  26,  27,  28,  29,   2,   3,  30,   4,  31,  32,  33,  34,  35,  36,  37,   5,  38,  39,  23,  56,  56,  56,  33,  33,  33,  33,  56,  56,  36,  36,  33,  56,  36,  56,  36,  23,  36,  36,  36, // state 0
636         14,  56,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  56,  14,  15,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  56,  14,  14,  14, // state 1
637         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  42,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 2
638         56,  56,  56,  56,  56,   6,  56,  56,  56,  40,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 3
639         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,   8,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,   9,  10,  11,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 4
640         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  39,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 5
641          6,   6,   6,   6,   6,   7,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, // state 6
642          6,   6,   6,   6,   6,   7,   6,   6,   6,  41,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6,   6, // state 7
643         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  47,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 8
644         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  12,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  44,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 9
645         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  45,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 10
646         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  46,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 11
647         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  13,  13,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  13,  13,  56,  56,  13,  56,  13,  56,  13,  13,  13, // state 12
648         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  13,  13,  56,  56,  56,  56,  44,  56,  56,  56,  56,  56,  56,  13,  56,  13,  13,  56,  13,  13,  13,  13,  56,  13,  13,  13, // state 13
649         14,  52,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  56,  14,  15,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  56,  14,  14,  14, // state 14
650         56,  14,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  14,  14,  56,  56,  56,  56,  56,  14,  56,  56,  56,  56,  56,  56,  56,  16,  56,  56,  56,  56,  56,  56,  56,  56,  56,  14, // state 15
651         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  17,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 16
652         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  18,  18,  56,  56,  18,  56,  56,  56,  18,  56,  56,  56,  18,  56, // state 17
653         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  14,  56,  56,  56,  18,  18,  56,  56,  18,  56,  56,  56,  18,  56,  56,  56,  18,  56, // state 18
654         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  20,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 19
655         56,  56,  56,  56,  54,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  20,  56,  56,  56,  56,  56,  56,  20,  56,  56,  56,  56,  56, // state 20
656         56,  56,  56,  56,  55,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  21,  56,  56,  56,  56,  56,  56,  21,  56,  56,  56,  56,  56, // state 21
657         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  21,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 22
658         23,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  23,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  23,  56,  56,  56, // state 23 <skip>
659         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 24 <end:2>
660         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 25 <end:10>
661         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 26 <end:11>
662         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 27 <end:5>
663         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 28 <end:4>
664         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 29 <end:9>
665         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 30 <end:12>
666         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  43,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 31 <end:8>
667         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 32 <end:6>
668         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  33,  33,  33,  33,  33,  56,  56,  56,  56,  56,  56,  56,  33,  33,  33,  33,  33,  56,  33,  33,  33,  33,  33,  33,  33,  56,  33,  33,  33, // state 33 <end:19>
669         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  33,  33,  53,  33,  33,  56,  56,  56,  56,  56,  56,  56,  33,  33,  33,  33,  33,  56,  33,  33,  33,  33,  33,  33,  33,  56,  33,  33,  33, // state 34 <end:19>
670         56,  56,  56,  19,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  33,  33,  33,  33,  33,  56,  56,  56,  56,  56,  56,  56,  33,  33,  33,  33,  33,  56,  33,  33,  33,  33,  33,  33,  33,  56,  33,  33,  33, // state 35 <end:19>
671         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  36,  36,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  36,  56,  36,  36,  56,  36,  36,  36,  36,  56,  36,  36,  36, // state 36 <end:20>
672         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  36,  36,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  36,  56,  36,  36,  56,  36,  36,  36,  48,  56,  36,  36,  36, // state 37 <end:20>
673         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 38 <end:3>
674         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 39 <end:7>
675         40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  40,  56,  40,  40,  40, // state 40 <skip>
676         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 41 <skip>
677         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 42 <end:0>
678         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 43 <end:1>
679         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 44 <end:13>
680         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 45 <end:14>
681         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 46 <end:15>
682         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 47 <end:16>
683         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  36,  36,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  36,  56,  36,  36,  56,  36,  36,  36,  36,  56,  49,  36,  36, // state 48 <end:20>
684         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  36,  36,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  36,  56,  36,  36,  56,  36,  36,  36,  36,  56,  36,  50,  36, // state 49 <end:20>
685         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  36,  36,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  36,  56,  36,  36,  56,  36,  36,  36,  36,  56,  36,  36,  51, // state 50 <end:20>
686         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  36,  36,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  36,  56,  36,  36,  56,  36,  36,  36,  36,  56,  36,  36,  36, // state 51 <end:17>
687         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 52 <end:18>
688         56,  56,  56,  22,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  33,  33,  33,  33,  33,  56,  56,  56,  56,  56,  56,  56,  33,  33,  33,  33,  33,  56,  33,  33,  33,  33,  33,  33,  33,  56,  33,  33,  33, // state 53 <end:19>
689         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 54 <end:21>
690         56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56, // state 55 <end:22>
691         56 // error group in [nbr_state * nbr_group + nbr_group]
692    ];
693
694    pub fn build_lexer<R: Read>() -> Lexer<'static, R> {
695        Lexer::new(
696            // parameters
697            NBR_GROUPS,
698            INITIAL_STATE,
699            FIRST_END_STATE,
700            NBR_STATES,
701            // tables
702            &ASCII_TO_GROUP,
703            HashMap::<char, GroupId>::from(UTF8_TO_GROUP),
704            SegMap::<GroupId>::from(SEG_TO_GROUP),
705            &STATE_TABLE,
706            &TERMINAL_TABLE,
707        )
708    }
709
710    // [rtsgen_lexer]
711}
712
713// -------------------------------------------------------------------------
714
715pub mod rtsgen_parser {
716    // Generated code, don't modify manually anything between the tags below
717    use crate as lexigram_lib;
718
719    // [rtsgen_parser]
720
721    use lexigram_lib::{AltId, TokenId, VarId, fixed_sym_table::FixedSymTable, lexer::PosSpan, log::{LogMsg, Logger}, parser::{Call, ListenerWrapper, OpCode, Parser, Terminate}};
722    use super::listener_types::*;
723
724    const PARSER_NUM_T: usize = 23;
725    const PARSER_NUM_NT: usize = 23;
726    static SYMBOLS_T: [(&str, Option<&str>); PARSER_NUM_T] = [("Arrow", Some("->")), ("DArrow", Some("=>")), ("Concat", Some("&")), ("Or", Some("|")), ("Plus", Some("+")), ("Star", Some("*")), ("Question", Some("?")), ("Empty", None), ("Equal", Some("=")), ("Comma", Some(",")), ("LPar", Some("(")), ("RPar", Some(")")), ("Semicolon", Some(";")), ("LTag", None), ("PTag", Some("<P>")), ("RTag", Some("<R>")), ("GTag", Some("<G>")), ("Token", Some("token")), ("TerminalCst", None), ("Terminal", None), ("Nonterminal", None), ("Tx", None), ("NTx", None)];
727    static SYMBOLS_NT: [&str; PARSER_NUM_NT] = ["file", "decls", "decl_iter", "decl", "decl_terminal", "ruleset", "rule_iter", "rule", "rule_nt", "rts_expr", "rts_children", "prs_expr", "item", "decl_1", "rts_children_1", "prs_expr_1", "prs_expr_2", "prs_expr_3", "prs_expr_4", "prs_expr_5", "prs_expr_6", "decl_terminal_1", "rule_1"];
728    static ALT_VAR: [VarId; 56] = [0, 1, 2, 2, 3, 4, 5, 6, 6, 7, 8, 9, 9, 9, 9, 9, 9, 10, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 15, 15, 16, 17, 17, 17, 17, 17, 18, 19, 19, 19, 19, 20, 20, 21, 21, 22, 22];
729    static PARSING_TABLE: [AltId; 552] = [56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 0, 56, 56, 0, 56, 56, 0, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 1, 56, 56, 1, 56, 56, 1, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 2, 56, 56, 3, 56, 56, 3, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 4, 56, 56, 57, 56, 56, 57, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 56, 56, 57, 56, 56, 56, 56, 56, 56, 5, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 6, 56, 56, 6, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 7, 56, 56, 8, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 9, 56, 56, 57, 57, 57, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 10, 56, 56, 56, 56, 56, 11, 12, 13, 14, 15, 16, 56, 56, 56, 57, 57, 16, 16, 16, 16, 56, 16, 16, 16, 16, 16, 56, 56, 56, 57, 57, 57, 57, 57, 57, 56, 56, 17, 57, 57, 57, 57, 57, 57, 56, 57, 57, 57, 57, 57, 56, 56, 56, 56, 56, 56, 56, 56, 18, 56, 56, 18, 57, 57, 18, 18, 18, 18, 56, 18, 18, 18, 18, 18, 56, 56, 56, 57, 57, 57, 57, 57, 24, 56, 56, 57, 57, 57, 25, 26, 27, 28, 56, 22, 21, 19, 23, 20, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 29, 56, 56, 30, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 31, 31, 31, 31, 31, 31, 56, 56, 56, 32, 56, 31, 31, 31, 31, 56, 31, 31, 31, 31, 31, 56, 56, 56, 56, 37, 33, 34, 35, 36, 56, 56, 36, 38, 38, 36, 36, 36, 36, 56, 36, 36, 36, 36, 36, 56, 56, 56, 56, 57, 57, 57, 57, 39, 56, 56, 39, 57, 57, 39, 39, 39, 39, 56, 39, 39, 39, 39, 39, 56, 56, 56, 56, 44, 40, 41, 42, 43, 56, 56, 43, 44, 44, 43, 43, 43, 43, 56, 43, 43, 43, 43, 43, 56, 56, 56, 56, 57, 57, 57, 57, 45, 56, 56, 45, 57, 57, 45, 45, 45, 45, 56, 45, 45, 45, 45, 45, 56, 56, 56, 56, 49, 46, 47, 48, 49, 56, 56, 49, 49, 49, 49, 49, 49, 49, 56, 49, 49, 49, 49, 49, 56, 56, 56, 56, 57, 57, 57, 57, 51, 56, 56, 50, 57, 57, 51, 51, 51, 51, 56, 51, 51, 51, 51, 51, 56, 56, 56, 56, 56, 56, 56, 56, 56, 52, 53, 56, 56, 53, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 54, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 56, 56, 57];
730    static OPCODES: [&[OpCode]; 56] = [&[OpCode::Exit(0), OpCode::NT(5), OpCode::NT(1)], &[OpCode::Exit(1), OpCode::NT(2)], &[OpCode::Loop(2), OpCode::Exit(2), OpCode::NT(3)], &[OpCode::Exit(3)], &[OpCode::Exit(4), OpCode::T(12), OpCode::NT(13), OpCode::NT(4), OpCode::T(17)], &[OpCode::NT(21), OpCode::T(19)], &[OpCode::Exit(6), OpCode::NT(6)], &[OpCode::Loop(6), OpCode::Exit(7), OpCode::NT(7)], &[OpCode::Exit(8)], &[OpCode::NT(22), OpCode::NT(8)], &[OpCode::Exit(10), OpCode::T(20)], &[OpCode::Exit(11), OpCode::NT(10), OpCode::T(2)], &[OpCode::Exit(12), OpCode::NT(10), OpCode::T(3)], &[OpCode::Exit(13), OpCode::NT(10), OpCode::T(4)], &[OpCode::Exit(14), OpCode::NT(10), OpCode::T(5)], &[OpCode::Exit(15), OpCode::NT(10), OpCode::T(6)], &[OpCode::Exit(16), OpCode::NT(12)], &[OpCode::Exit(17), OpCode::T(11), OpCode::NT(14), OpCode::T(10)], &[OpCode::NT(15), OpCode::Exit(18), OpCode::NT(20)], &[OpCode::Exit(19), OpCode::T(20)], &[OpCode::Exit(20), OpCode::T(22)], &[OpCode::Exit(21), OpCode::T(19)], &[OpCode::Exit(22), OpCode::T(18)], &[OpCode::Exit(23), OpCode::T(21)], &[OpCode::Exit(24), OpCode::T(7)], &[OpCode::Exit(25), OpCode::T(13)], &[OpCode::Exit(26), OpCode::T(14)], &[OpCode::Exit(27), OpCode::T(15)], &[OpCode::Exit(28), OpCode::T(16)], &[OpCode::Loop(13), OpCode::Exit(29), OpCode::NT(4), OpCode::T(9)], &[OpCode::Exit(30)], &[OpCode::Loop(14), OpCode::Exit(31), OpCode::NT(9)], &[OpCode::Exit(32)], &[OpCode::Loop(15), OpCode::Exit(33), OpCode::T(4)], &[OpCode::Loop(15), OpCode::Exit(34), OpCode::T(5)], &[OpCode::Loop(15), OpCode::Exit(35), OpCode::T(6)], &[OpCode::Loop(15), OpCode::Exit(36), OpCode::NT(18)], &[OpCode::Loop(15), OpCode::Exit(37), OpCode::NT(16), OpCode::T(3)], &[OpCode::Exit(38)], &[OpCode::NT(17), OpCode::Exit(39), OpCode::NT(20)], &[OpCode::Loop(17), OpCode::Exit(40), OpCode::T(4)], &[OpCode::Loop(17), OpCode::Exit(41), OpCode::T(5)], &[OpCode::Loop(17), OpCode::Exit(42), OpCode::T(6)], &[OpCode::Loop(17), OpCode::Exit(43), OpCode::NT(18)], &[OpCode::Exit(44)], &[OpCode::NT(19), OpCode::Exit(45), OpCode::NT(20)], &[OpCode::Loop(19), OpCode::Exit(46), OpCode::T(4)], &[OpCode::Loop(19), OpCode::Exit(47), OpCode::T(5)], &[OpCode::Loop(19), OpCode::Exit(48), OpCode::T(6)], &[OpCode::Exit(49)], &[OpCode::Exit(50), OpCode::T(11), OpCode::NT(11), OpCode::T(10)], &[OpCode::Exit(51), OpCode::NT(12)], &[OpCode::Exit(52), OpCode::T(18), OpCode::T(8)], &[OpCode::Exit(53)], &[OpCode::Exit(54), OpCode::T(12), OpCode::NT(11), OpCode::T(0)], &[OpCode::Exit(55), OpCode::T(12), OpCode::NT(9), OpCode::T(1)]];
731    static INIT_OPCODES: [OpCode; 2] = [OpCode::End, OpCode::NT(0)];
732    static START_SYMBOL: VarId = 0;
733
734    pub fn build_parser() -> Parser<'static> {{
735        let symbol_table = FixedSymTable::new(
736            SYMBOLS_T.into_iter().map(|(s, os)| (s.to_string(), os.map(|s| s.to_string()))).collect(),
737            SYMBOLS_NT.into_iter().map(|s| s.to_string()).collect()
738        );
739        Parser::new(
740            PARSER_NUM_NT, PARSER_NUM_T + 1,
741            &ALT_VAR,
742            Vec::new(),
743            OPCODES.into_iter().map(|strip| strip.to_vec()).collect(),
744            INIT_OPCODES.to_vec(),
745            &PARSING_TABLE,
746            symbol_table,
747            START_SYMBOL
748        )
749    }}
750
751    #[derive(Debug)]
752    pub enum CtxFile {
753        /// `file -> decls ruleset`
754        V1 { decls: SynDecls, ruleset: SynRuleset },
755    }
756    #[derive(Debug)]
757    pub enum CtxDecls {
758        /// `decls -> (<L> decl)*`
759        V1,
760    }
761    #[derive(Debug)]
762    pub enum CtxDeclIter {
763        /// `<L> decl` iteration in `decls -> ( ►► <L> decl ◄◄ )*`
764        V1 { decl: SynDecl },
765    }
766    #[derive(Debug)]
767    pub enum CtxDecl {
768        /// `decl -> "token" decl_terminal ("," decl_terminal)* ";"`
769        V1 { star: SynDecl1 },
770    }
771    #[derive(Debug)]
772    pub enum CtxDeclTerminal {
773        /// `decl_terminal -> Terminal "=" TerminalCst`
774        V1 { terminal: String, terminalcst: String },
775        /// `decl_terminal -> Terminal`
776        V2 { terminal: String },
777    }
778    #[derive(Debug)]
779    pub enum CtxRuleset {
780        /// `ruleset -> (<L> rule)*`
781        V1,
782    }
783    #[derive(Debug)]
784    pub enum CtxRuleIter {
785        /// `<L> rule` iteration in `ruleset -> ( ►► <L> rule ◄◄ )*`
786        V1 { rule: SynRule },
787    }
788    #[derive(Debug)]
789    pub enum CtxRule {
790        /// `rule -> rule_nt "=>" rts_expr ";"`
791        V1 { rule_nt: SynRuleNt, rts_expr: SynRtsExpr },
792        /// `rule -> rule_nt "->" prs_expr ";"`
793        V2 { rule_nt: SynRuleNt, prs_expr: SynPrsExpr },
794    }
795    #[derive(Debug)]
796    pub enum CtxRuleNt {
797        /// `rule_nt -> Nonterminal`
798        V1 { nonterminal: String },
799    }
800    #[derive(Debug)]
801    pub enum CtxRtsExpr {
802        /// `rts_expr -> "&" rts_children`
803        V1 { rts_children: SynRtsChildren },
804        /// `rts_expr -> "|" rts_children`
805        V2 { rts_children: SynRtsChildren },
806        /// `rts_expr -> "+" rts_children`
807        V3 { rts_children: SynRtsChildren },
808        /// `rts_expr -> "*" rts_children`
809        V4 { rts_children: SynRtsChildren },
810        /// `rts_expr -> "?" rts_children`
811        V5 { rts_children: SynRtsChildren },
812        /// `rts_expr -> item`
813        V6 { item: SynItem },
814    }
815    #[derive(Debug)]
816    pub enum CtxRtsChildren {
817        /// `rts_children -> "(" rts_expr* ")"`
818        V1 { star: SynRtsChildren1 },
819    }
820    #[derive(Debug)]
821    pub enum CtxPrsExpr {
822        /// `prs_expr -> prs_expr "+"`
823        V1 { prs_expr: SynPrsExpr },
824        /// `prs_expr -> prs_expr "*"`
825        V2 { prs_expr: SynPrsExpr },
826        /// `prs_expr -> prs_expr "?"`
827        V3 { prs_expr: SynPrsExpr },
828        /// `prs_expr -> prs_expr prs_expr`
829        V4 { prs_expr: [SynPrsExpr; 2] },
830        /// `prs_expr -> prs_expr "|" prs_expr`
831        V5 { prs_expr: [SynPrsExpr; 2] },
832        /// `prs_expr -> "(" prs_expr ")"`
833        V6 { prs_expr: SynPrsExpr },
834        /// `prs_expr -> item`
835        V7 { item: SynItem },
836    }
837    #[derive(Debug)]
838    pub enum CtxItem {
839        /// `item -> Nonterminal`
840        V1 { nonterminal: String },
841        /// `item -> NTx`
842        V2 { ntx: String },
843        /// `item -> Terminal`
844        V3 { terminal: String },
845        /// `item -> TerminalCst`
846        V4 { terminalcst: String },
847        /// `item -> Tx`
848        V5 { tx: String },
849        /// `item -> Empty`
850        V6 { empty: String },
851        /// `item -> LTag`
852        V7 { ltag: String },
853        /// `item -> "<P>"`
854        V8,
855        /// `item -> "<R>"`
856        V9,
857        /// `item -> "<G>"`
858        V10,
859    }
860
861    /// Computed `("," decl_terminal)*` array in `decl -> "token" decl_terminal  ►► ("," decl_terminal)* ◄◄  ";"`
862    #[derive(Debug, PartialEq)]
863    pub struct SynDecl1(pub Vec<SynDeclTerminal>);
864    /// Computed `rts_expr*` array in `rts_children -> "("  ►► rts_expr* ◄◄  ")"`
865    #[derive(Debug, PartialEq)]
866    pub struct SynRtsChildren1(pub Vec<SynRtsExpr>);
867
868    #[derive(Debug)]
869    enum EnumSynValue { File(SynFile), Decls(SynDecls), Decl(SynDecl), DeclTerminal(SynDeclTerminal), Ruleset(SynRuleset), Rule(SynRule), RuleNt(SynRuleNt), RtsExpr(SynRtsExpr), RtsChildren(SynRtsChildren), PrsExpr(SynPrsExpr), Item(SynItem), Decl1(SynDecl1), RtsChildren1(SynRtsChildren1) }
870
871    impl EnumSynValue {
872        fn get_file(self) -> SynFile {
873            if let EnumSynValue::File(val) = self { val } else { panic!() }
874        }
875        fn get_decls(self) -> SynDecls {
876            if let EnumSynValue::Decls(val) = self { val } else { panic!() }
877        }
878        fn get_decl(self) -> SynDecl {
879            if let EnumSynValue::Decl(val) = self { val } else { panic!() }
880        }
881        fn get_decl_terminal(self) -> SynDeclTerminal {
882            if let EnumSynValue::DeclTerminal(val) = self { val } else { panic!() }
883        }
884        fn get_ruleset(self) -> SynRuleset {
885            if let EnumSynValue::Ruleset(val) = self { val } else { panic!() }
886        }
887        fn get_rule(self) -> SynRule {
888            if let EnumSynValue::Rule(val) = self { val } else { panic!() }
889        }
890        fn get_rule_nt(self) -> SynRuleNt {
891            if let EnumSynValue::RuleNt(val) = self { val } else { panic!() }
892        }
893        fn get_rts_expr(self) -> SynRtsExpr {
894            if let EnumSynValue::RtsExpr(val) = self { val } else { panic!() }
895        }
896        fn get_rts_children(self) -> SynRtsChildren {
897            if let EnumSynValue::RtsChildren(val) = self { val } else { panic!() }
898        }
899        fn get_prs_expr(self) -> SynPrsExpr {
900            if let EnumSynValue::PrsExpr(val) = self { val } else { panic!() }
901        }
902        fn get_item(self) -> SynItem {
903            if let EnumSynValue::Item(val) = self { val } else { panic!() }
904        }
905        fn get_decl1(self) -> SynDecl1 {
906            if let EnumSynValue::Decl1(val) = self { val } else { panic!() }
907        }
908        fn get_rts_children1(self) -> SynRtsChildren1 {
909            if let EnumSynValue::RtsChildren1(val) = self { val } else { panic!() }
910        }
911    }
912
913    pub trait RtsGenListener {
914        /// Checks if the listener requests an abort. This happens if an error is too difficult to recover from
915        /// and may corrupt the stack content. In that case, the parser immediately stops and returns `ParserError::AbortRequest`.
916        fn check_abort_request(&self) -> Terminate { Terminate::None }
917        fn get_log_mut(&mut self) -> &mut impl Logger;
918        #[allow(unused_variables)]
919        fn handle_msg(&mut self, span_opt: Option<&PosSpan>, msg: LogMsg) {
920            self.get_log_mut().add(msg);
921        }
922        #[allow(unused_variables)]
923        fn intercept_token(&mut self, token: TokenId, text: &str) -> TokenId { token }
924        #[allow(unused_variables)]
925        fn exit(&mut self, file: SynFile) {}
926        #[allow(unused_variables)]
927        fn abort(&mut self, terminate: Terminate) {}
928        fn init_file(&mut self) {}
929        fn exit_file(&mut self, ctx: CtxFile) -> SynFile;
930        fn init_decls(&mut self) {}
931        fn exit_decls(&mut self, ctx: CtxDecls) -> SynDecls;
932        fn init_decl_iter(&mut self) {}
933        #[allow(unused_variables)]
934        fn exit_decl_iter(&mut self, ctx: CtxDeclIter) {}
935        fn init_decl(&mut self) {}
936        fn exit_decl(&mut self, ctx: CtxDecl) -> SynDecl;
937        fn init_decl_terminal(&mut self) {}
938        fn exit_decl_terminal(&mut self, ctx: CtxDeclTerminal) -> SynDeclTerminal;
939        fn init_ruleset(&mut self) {}
940        fn exit_ruleset(&mut self, ctx: CtxRuleset) -> SynRuleset;
941        fn init_rule_iter(&mut self) {}
942        #[allow(unused_variables)]
943        fn exit_rule_iter(&mut self, ctx: CtxRuleIter) {}
944        fn init_rule(&mut self) {}
945        fn exit_rule(&mut self, ctx: CtxRule) -> SynRule;
946        fn init_rule_nt(&mut self) {}
947        fn exit_rule_nt(&mut self, ctx: CtxRuleNt) -> SynRuleNt;
948        fn init_rts_expr(&mut self) {}
949        fn exit_rts_expr(&mut self, ctx: CtxRtsExpr) -> SynRtsExpr;
950        fn init_rts_children(&mut self) {}
951        fn exit_rts_children(&mut self, ctx: CtxRtsChildren) -> SynRtsChildren;
952        fn init_prs_expr(&mut self) {}
953        fn exit_prs_expr(&mut self, ctx: CtxPrsExpr) -> SynPrsExpr;
954        fn init_item(&mut self) {}
955        fn exit_item(&mut self, ctx: CtxItem) -> SynItem;
956    }
957
958    pub struct Wrapper<T> {
959        verbose: bool,
960        listener: T,
961        stack: Vec<EnumSynValue>,
962        max_stack: usize,
963        stack_t: Vec<String>,
964    }
965
966    impl<T: RtsGenListener> ListenerWrapper for Wrapper<T> {
967        fn switch(&mut self, call: Call, nt: VarId, alt_id: AltId, t_data: Option<Vec<String>>) {
968            if self.verbose {
969                println!("switch: call={call:?}, nt={nt}, alt={alt_id}, t_data={t_data:?}");
970            }
971            if let Some(mut t_data) = t_data {
972                self.stack_t.append(&mut t_data);
973            }
974            match call {
975                Call::Enter => {
976                    match nt {
977                        0 => self.listener.init_file(),             // file
978                        1 => self.listener.init_decls(),            // decls
979                        2 => self.listener.init_decl_iter(),        // decl_iter
980                        3 => self.listener.init_decl(),             // decl
981                        13 => self.init_decl1(),                    // decl_1
982                        4 => self.listener.init_decl_terminal(),    // decl_terminal
983                        21 => {}                                    // decl_terminal_1
984                        5 => self.listener.init_ruleset(),          // ruleset
985                        6 => self.listener.init_rule_iter(),        // rule_iter
986                        7 => self.listener.init_rule(),             // rule
987                        22 => {}                                    // rule_1
988                        8 => self.listener.init_rule_nt(),          // rule_nt
989                        9 => self.listener.init_rts_expr(),         // rts_expr
990                        10 => self.listener.init_rts_children(),    // rts_children
991                        14 => self.init_rts_children1(),            // rts_children_1
992                        11 => self.listener.init_prs_expr(),        // prs_expr
993                        15 ..= 20 => {}                             // prs_expr_1, prs_expr_2, prs_expr_3, prs_expr_4, prs_expr_5, prs_expr_6
994                        12 => self.listener.init_item(),            // item
995                        _ => panic!("unexpected enter nonterminal id: {nt}")
996                    }
997                }
998                Call::Loop => {}
999                Call::Exit => {
1000                    match alt_id {
1001                        0 => self.exit_file(),                      // file -> decls ruleset
1002                        1 => self.exit_decls(),                     // decls -> decl_iter
1003                        2 => self.exit_decl_iter(),                 // decl_iter -> <L> decl decl_iter
1004                        3 => {}                                     // decl_iter -> <L> ε (not used)
1005                        4 => self.exit_decl(),                      // decl -> "token" decl_terminal decl_1 ";"
1006                        29 => self.exit_decl1(),                    // decl_1 -> "," decl_terminal decl_1
1007                        30 => {}                                    // decl_1 -> ε
1008                        52 |                                        // decl_terminal_1 -> "=" TerminalCst
1009                        53 => self.exit_decl_terminal(alt_id),      // decl_terminal_1 -> ε
1010                     /* 5 */                                        // decl_terminal -> Terminal decl_terminal_1 (never called)
1011                        6 => self.exit_ruleset(),                   // ruleset -> rule_iter
1012                        7 => self.exit_rule_iter(),                 // rule_iter -> <L> rule rule_iter
1013                        8 => {}                                     // rule_iter -> <L> ε (not used)
1014                        54 |                                        // rule_1 -> "->" prs_expr ";"
1015                        55 => self.exit_rule(alt_id),               // rule_1 -> "=>" rts_expr ";"
1016                     /* 9 */                                        // rule -> rule_nt rule_1 (never called)
1017                        10 => self.exit_rule_nt(),                  // rule_nt -> Nonterminal
1018                        11 |                                        // rts_expr -> "&" rts_children
1019                        12 |                                        // rts_expr -> "|" rts_children
1020                        13 |                                        // rts_expr -> "+" rts_children
1021                        14 |                                        // rts_expr -> "*" rts_children
1022                        15 |                                        // rts_expr -> "?" rts_children
1023                        16 => self.exit_rts_expr(alt_id),           // rts_expr -> item
1024                        17 => self.exit_rts_children(),             // rts_children -> "(" rts_children_1 ")"
1025                        31 => self.exit_rts_children1(),            // rts_children_1 -> rts_expr rts_children_1
1026                        32 => {}                                    // rts_children_1 -> ε
1027                        33 |                                        // prs_expr_1 -> "+" prs_expr_1
1028                        34 |                                        // prs_expr_1 -> "*" prs_expr_1
1029                        35 |                                        // prs_expr_1 -> "?" prs_expr_1
1030                        36 |                                        // prs_expr_1 -> prs_expr_4 prs_expr_1
1031                        37 => self.exit_prs_expr1(alt_id),          // prs_expr_1 -> "|" prs_expr_2 prs_expr_1
1032                        40 |                                        // prs_expr_3 -> "+" prs_expr_3 (duplicate of 33)
1033                        46 => self.exit_prs_expr1(33),              // prs_expr_5 -> "+" prs_expr_5 (duplicate of 33)
1034                        41 |                                        // prs_expr_3 -> "*" prs_expr_3 (duplicate of 34)
1035                        47 => self.exit_prs_expr1(34),              // prs_expr_5 -> "*" prs_expr_5 (duplicate of 34)
1036                        42 |                                        // prs_expr_3 -> "?" prs_expr_3 (duplicate of 35)
1037                        48 => self.exit_prs_expr1(35),              // prs_expr_5 -> "?" prs_expr_5 (duplicate of 35)
1038                        43 => self.exit_prs_expr1(36),              // prs_expr_3 -> prs_expr_4 prs_expr_3 (duplicate of 36)
1039                        50 |                                        // prs_expr_6 -> "(" prs_expr ")"
1040                        51 => self.exit_prs_expr6(alt_id),          // prs_expr_6 -> item
1041                        18 => {}                                    // prs_expr -> prs_expr_6 prs_expr_1 (not used)
1042                        38 => {}                                    // prs_expr_1 -> ε (not used)
1043                        39 => {}                                    // prs_expr_2 -> prs_expr_6 prs_expr_3 (not used)
1044                        44 => {}                                    // prs_expr_3 -> ε (not used)
1045                        45 => {}                                    // prs_expr_4 -> prs_expr_6 prs_expr_5 (not used)
1046                        49 => {}                                    // prs_expr_5 -> ε (not used)
1047                        19 |                                        // item -> Nonterminal
1048                        20 |                                        // item -> NTx
1049                        21 |                                        // item -> Terminal
1050                        22 |                                        // item -> TerminalCst
1051                        23 |                                        // item -> Tx
1052                        24 |                                        // item -> Empty
1053                        25 |                                        // item -> LTag
1054                        26 |                                        // item -> "<P>"
1055                        27 |                                        // item -> "<R>"
1056                        28 => self.exit_item(alt_id),               // item -> "<G>"
1057                        _ => panic!("unexpected exit alternative id: {alt_id}")
1058                    }
1059                }
1060                Call::End(terminate) => {
1061                    match terminate {
1062                        Terminate::None => {
1063                            let val = self.stack.pop().unwrap().get_file();
1064                            self.listener.exit(val);
1065                        }
1066                        Terminate::Abort | Terminate::Conclude => self.listener.abort(terminate),
1067                    }
1068                }
1069            }
1070            self.max_stack = std::cmp::max(self.max_stack, self.stack.len());
1071            if self.verbose {
1072                println!("> stack_t:   {}", self.stack_t.join(", "));
1073                println!("> stack:     {}", self.stack.iter().map(|it| format!("{it:?}")).collect::<Vec<_>>().join(", "));
1074            }
1075        }
1076
1077        fn check_abort_request(&self) -> Terminate {
1078            self.listener.check_abort_request()
1079        }
1080
1081        fn abort(&mut self) {
1082            self.stack.clear();
1083            self.stack_t.clear();
1084        }
1085
1086        fn get_log_mut(&mut self) -> &mut impl Logger {
1087            self.listener.get_log_mut()
1088        }
1089
1090        fn report(&mut self, span_opt: Option<&PosSpan>, msg: LogMsg) {
1091            self.listener.handle_msg(span_opt, msg);
1092        }
1093
1094        fn is_stack_empty(&self) -> bool {
1095            self.stack.is_empty()
1096        }
1097
1098        fn is_stack_t_empty(&self) -> bool {
1099            self.stack_t.is_empty()
1100        }
1101
1102        fn intercept_token(&mut self, token: TokenId, text: &str, _span: &PosSpan) -> TokenId {
1103            self.listener.intercept_token(token, text)
1104        }
1105    }
1106
1107    impl<T: RtsGenListener> Wrapper<T> {
1108        pub fn new(listener: T, verbose: bool) -> Self {
1109            Wrapper { verbose, listener, stack: Vec::new(), max_stack: 0, stack_t: Vec::new() }
1110        }
1111
1112        pub fn get_listener(&self) -> &T {
1113            &self.listener
1114        }
1115
1116        pub fn get_listener_mut(&mut self) -> &mut T {
1117            &mut self.listener
1118        }
1119
1120        pub fn give_listener(self) -> T {
1121            self.listener
1122        }
1123
1124        pub fn set_verbose(&mut self, verbose: bool) {
1125            self.verbose = verbose;
1126        }
1127
1128        fn exit_file(&mut self) {
1129            let ruleset = self.stack.pop().unwrap().get_ruleset();
1130            let decls = self.stack.pop().unwrap().get_decls();
1131            let ctx = CtxFile::V1 { decls, ruleset };
1132            let val = self.listener.exit_file(ctx);
1133            self.stack.push(EnumSynValue::File(val));
1134        }
1135
1136        fn exit_decls(&mut self) {
1137            let ctx = CtxDecls::V1;
1138            let val = self.listener.exit_decls(ctx);
1139            self.stack.push(EnumSynValue::Decls(val));
1140        }
1141
1142        fn exit_decl_iter(&mut self) {
1143            let decl = self.stack.pop().unwrap().get_decl();
1144            let ctx = CtxDeclIter::V1 { decl };
1145            self.listener.exit_decl_iter(ctx);
1146        }
1147
1148        fn exit_decl(&mut self) {
1149            let star = self.stack.pop().unwrap().get_decl1();
1150            let ctx = CtxDecl::V1 { star };
1151            let val = self.listener.exit_decl(ctx);
1152            self.stack.push(EnumSynValue::Decl(val));
1153        }
1154
1155        fn init_decl1(&mut self) {
1156            let decl_terminal = self.stack.pop().unwrap().get_decl_terminal();
1157            self.stack.push(EnumSynValue::Decl1(SynDecl1(vec![decl_terminal])));
1158        }
1159
1160        fn exit_decl1(&mut self) {
1161            let decl_terminal = self.stack.pop().unwrap().get_decl_terminal();
1162            let Some(EnumSynValue::Decl1(SynDecl1(star_acc))) = self.stack.last_mut() else {
1163                panic!("expected SynDecl1 item on wrapper stack");
1164            };
1165            star_acc.push(decl_terminal);
1166        }
1167
1168        fn exit_decl_terminal(&mut self, alt_id: AltId) {
1169            let ctx = match alt_id {
1170                52 => {
1171                    let terminalcst = self.stack_t.pop().unwrap();
1172                    let terminal = self.stack_t.pop().unwrap();
1173                    CtxDeclTerminal::V1 { terminal, terminalcst }
1174                }
1175                53 => {
1176                    let terminal = self.stack_t.pop().unwrap();
1177                    CtxDeclTerminal::V2 { terminal }
1178                }
1179                _ => panic!("unexpected alt id {alt_id} in fn exit_decl_terminal")
1180            };
1181            let val = self.listener.exit_decl_terminal(ctx);
1182            self.stack.push(EnumSynValue::DeclTerminal(val));
1183        }
1184
1185        fn exit_ruleset(&mut self) {
1186            let ctx = CtxRuleset::V1;
1187            let val = self.listener.exit_ruleset(ctx);
1188            self.stack.push(EnumSynValue::Ruleset(val));
1189        }
1190
1191        fn exit_rule_iter(&mut self) {
1192            let rule = self.stack.pop().unwrap().get_rule();
1193            let ctx = CtxRuleIter::V1 { rule };
1194            self.listener.exit_rule_iter(ctx);
1195        }
1196
1197        fn exit_rule(&mut self, alt_id: AltId) {
1198            let ctx = match alt_id {
1199                54 => {
1200                    let prs_expr = self.stack.pop().unwrap().get_prs_expr();
1201                    let rule_nt = self.stack.pop().unwrap().get_rule_nt();
1202                    CtxRule::V2 { rule_nt, prs_expr }
1203                }
1204                55 => {
1205                    let rts_expr = self.stack.pop().unwrap().get_rts_expr();
1206                    let rule_nt = self.stack.pop().unwrap().get_rule_nt();
1207                    CtxRule::V1 { rule_nt, rts_expr }
1208                }
1209                _ => panic!("unexpected alt id {alt_id} in fn exit_rule")
1210            };
1211            let val = self.listener.exit_rule(ctx);
1212            self.stack.push(EnumSynValue::Rule(val));
1213        }
1214
1215        fn exit_rule_nt(&mut self) {
1216            let nonterminal = self.stack_t.pop().unwrap();
1217            let ctx = CtxRuleNt::V1 { nonterminal };
1218            let val = self.listener.exit_rule_nt(ctx);
1219            self.stack.push(EnumSynValue::RuleNt(val));
1220        }
1221
1222        fn exit_rts_expr(&mut self, alt_id: AltId) {
1223            let ctx = match alt_id {
1224                11 => {
1225                    let rts_children = self.stack.pop().unwrap().get_rts_children();
1226                    CtxRtsExpr::V1 { rts_children }
1227                }
1228                12 => {
1229                    let rts_children = self.stack.pop().unwrap().get_rts_children();
1230                    CtxRtsExpr::V2 { rts_children }
1231                }
1232                13 => {
1233                    let rts_children = self.stack.pop().unwrap().get_rts_children();
1234                    CtxRtsExpr::V3 { rts_children }
1235                }
1236                14 => {
1237                    let rts_children = self.stack.pop().unwrap().get_rts_children();
1238                    CtxRtsExpr::V4 { rts_children }
1239                }
1240                15 => {
1241                    let rts_children = self.stack.pop().unwrap().get_rts_children();
1242                    CtxRtsExpr::V5 { rts_children }
1243                }
1244                16 => {
1245                    let item = self.stack.pop().unwrap().get_item();
1246                    CtxRtsExpr::V6 { item }
1247                }
1248                _ => panic!("unexpected alt id {alt_id} in fn exit_rts_expr")
1249            };
1250            let val = self.listener.exit_rts_expr(ctx);
1251            self.stack.push(EnumSynValue::RtsExpr(val));
1252        }
1253
1254        fn exit_rts_children(&mut self) {
1255            let star = self.stack.pop().unwrap().get_rts_children1();
1256            let ctx = CtxRtsChildren::V1 { star };
1257            let val = self.listener.exit_rts_children(ctx);
1258            self.stack.push(EnumSynValue::RtsChildren(val));
1259        }
1260
1261        fn init_rts_children1(&mut self) {
1262            let val = SynRtsChildren1(Vec::new());
1263            self.stack.push(EnumSynValue::RtsChildren1(val));
1264        }
1265
1266        fn exit_rts_children1(&mut self) {
1267            let rts_expr = self.stack.pop().unwrap().get_rts_expr();
1268            let Some(EnumSynValue::RtsChildren1(SynRtsChildren1(star_acc))) = self.stack.last_mut() else {
1269                panic!("expected SynRtsChildren1 item on wrapper stack");
1270            };
1271            star_acc.push(rts_expr);
1272        }
1273
1274        fn exit_prs_expr1(&mut self, alt_id: AltId) {
1275            let ctx = match alt_id {
1276                33 => {
1277                    let prs_expr = self.stack.pop().unwrap().get_prs_expr();
1278                    CtxPrsExpr::V1 { prs_expr }
1279                }
1280                34 => {
1281                    let prs_expr = self.stack.pop().unwrap().get_prs_expr();
1282                    CtxPrsExpr::V2 { prs_expr }
1283                }
1284                35 => {
1285                    let prs_expr = self.stack.pop().unwrap().get_prs_expr();
1286                    CtxPrsExpr::V3 { prs_expr }
1287                }
1288                36 => {
1289                    let prs_expr_2 = self.stack.pop().unwrap().get_prs_expr();
1290                    let prs_expr_1 = self.stack.pop().unwrap().get_prs_expr();
1291                    CtxPrsExpr::V4 { prs_expr: [prs_expr_1, prs_expr_2] }
1292                }
1293                37 => {
1294                    let prs_expr_2 = self.stack.pop().unwrap().get_prs_expr();
1295                    let prs_expr_1 = self.stack.pop().unwrap().get_prs_expr();
1296                    CtxPrsExpr::V5 { prs_expr: [prs_expr_1, prs_expr_2] }
1297                }
1298                _ => panic!("unexpected alt id {alt_id} in fn exit_prs_expr1")
1299            };
1300            let val = self.listener.exit_prs_expr(ctx);
1301            self.stack.push(EnumSynValue::PrsExpr(val));
1302        }
1303
1304        fn exit_prs_expr6(&mut self, alt_id: AltId) {
1305            let ctx = match alt_id {
1306                50 => {
1307                    let prs_expr = self.stack.pop().unwrap().get_prs_expr();
1308                    CtxPrsExpr::V6 { prs_expr }
1309                }
1310                51 => {
1311                    let item = self.stack.pop().unwrap().get_item();
1312                    CtxPrsExpr::V7 { item }
1313                }
1314                _ => panic!("unexpected alt id {alt_id} in fn exit_prs_expr6")
1315            };
1316            let val = self.listener.exit_prs_expr(ctx);
1317            self.stack.push(EnumSynValue::PrsExpr(val));
1318        }
1319
1320        fn exit_item(&mut self, alt_id: AltId) {
1321            let ctx = match alt_id {
1322                19 => {
1323                    let nonterminal = self.stack_t.pop().unwrap();
1324                    CtxItem::V1 { nonterminal }
1325                }
1326                20 => {
1327                    let ntx = self.stack_t.pop().unwrap();
1328                    CtxItem::V2 { ntx }
1329                }
1330                21 => {
1331                    let terminal = self.stack_t.pop().unwrap();
1332                    CtxItem::V3 { terminal }
1333                }
1334                22 => {
1335                    let terminalcst = self.stack_t.pop().unwrap();
1336                    CtxItem::V4 { terminalcst }
1337                }
1338                23 => {
1339                    let tx = self.stack_t.pop().unwrap();
1340                    CtxItem::V5 { tx }
1341                }
1342                24 => {
1343                    let empty = self.stack_t.pop().unwrap();
1344                    CtxItem::V6 { empty }
1345                }
1346                25 => {
1347                    let ltag = self.stack_t.pop().unwrap();
1348                    CtxItem::V7 { ltag }
1349                }
1350                26 => {
1351                    CtxItem::V8
1352                }
1353                27 => {
1354                    CtxItem::V9
1355                }
1356                28 => {
1357                    CtxItem::V10
1358                }
1359                _ => panic!("unexpected alt id {alt_id} in fn exit_item")
1360            };
1361            let val = self.listener.exit_item(ctx);
1362            self.stack.push(EnumSynValue::Item(val));
1363        }
1364    }
1365
1366    // [rtsgen_parser]
1367}
1368
1369// -------------------------------------------------------------------------