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::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 intercept_token(&mut self, token: TokenId, text: &str) -> TokenId { token }
920        #[allow(unused_variables)]
921        fn exit(&mut self, file: SynFile) {}
922        #[allow(unused_variables)]
923        fn abort(&mut self, terminate: Terminate) {}
924        fn init_file(&mut self) {}
925        fn exit_file(&mut self, ctx: CtxFile) -> SynFile;
926        fn init_decls(&mut self) {}
927        fn exit_decls(&mut self, ctx: CtxDecls) -> SynDecls;
928        fn init_decl_iter(&mut self) {}
929        #[allow(unused_variables)]
930        fn exit_decl_iter(&mut self, ctx: CtxDeclIter) {}
931        fn init_decl(&mut self) {}
932        fn exit_decl(&mut self, ctx: CtxDecl) -> SynDecl;
933        fn init_decl_terminal(&mut self) {}
934        fn exit_decl_terminal(&mut self, ctx: CtxDeclTerminal) -> SynDeclTerminal;
935        fn init_ruleset(&mut self) {}
936        fn exit_ruleset(&mut self, ctx: CtxRuleset) -> SynRuleset;
937        fn init_rule_iter(&mut self) {}
938        #[allow(unused_variables)]
939        fn exit_rule_iter(&mut self, ctx: CtxRuleIter) {}
940        fn init_rule(&mut self) {}
941        fn exit_rule(&mut self, ctx: CtxRule) -> SynRule;
942        fn init_rule_nt(&mut self) {}
943        fn exit_rule_nt(&mut self, ctx: CtxRuleNt) -> SynRuleNt;
944        fn init_rts_expr(&mut self) {}
945        fn exit_rts_expr(&mut self, ctx: CtxRtsExpr) -> SynRtsExpr;
946        fn init_rts_children(&mut self) {}
947        fn exit_rts_children(&mut self, ctx: CtxRtsChildren) -> SynRtsChildren;
948        fn init_prs_expr(&mut self) {}
949        fn exit_prs_expr(&mut self, ctx: CtxPrsExpr) -> SynPrsExpr;
950        fn init_item(&mut self) {}
951        fn exit_item(&mut self, ctx: CtxItem) -> SynItem;
952    }
953
954    pub struct Wrapper<T> {
955        verbose: bool,
956        listener: T,
957        stack: Vec<EnumSynValue>,
958        max_stack: usize,
959        stack_t: Vec<String>,
960    }
961
962    impl<T: RtsGenListener> ListenerWrapper for Wrapper<T> {
963        fn switch(&mut self, call: Call, nt: VarId, alt_id: AltId, t_data: Option<Vec<String>>) {
964            if self.verbose {
965                println!("switch: call={call:?}, nt={nt}, alt={alt_id}, t_data={t_data:?}");
966            }
967            if let Some(mut t_data) = t_data {
968                self.stack_t.append(&mut t_data);
969            }
970            match call {
971                Call::Enter => {
972                    match nt {
973                        0 => self.listener.init_file(),             // file
974                        1 => self.listener.init_decls(),            // decls
975                        2 => self.listener.init_decl_iter(),        // decl_iter
976                        3 => self.listener.init_decl(),             // decl
977                        13 => self.init_decl1(),                    // decl_1
978                        4 => self.listener.init_decl_terminal(),    // decl_terminal
979                        21 => {}                                    // decl_terminal_1
980                        5 => self.listener.init_ruleset(),          // ruleset
981                        6 => self.listener.init_rule_iter(),        // rule_iter
982                        7 => self.listener.init_rule(),             // rule
983                        22 => {}                                    // rule_1
984                        8 => self.listener.init_rule_nt(),          // rule_nt
985                        9 => self.listener.init_rts_expr(),         // rts_expr
986                        10 => self.listener.init_rts_children(),    // rts_children
987                        14 => self.init_rts_children1(),            // rts_children_1
988                        11 => self.listener.init_prs_expr(),        // prs_expr
989                        15 ..= 20 => {}                             // prs_expr_1, prs_expr_2, prs_expr_3, prs_expr_4, prs_expr_5, prs_expr_6
990                        12 => self.listener.init_item(),            // item
991                        _ => panic!("unexpected enter nonterminal id: {nt}")
992                    }
993                }
994                Call::Loop => {}
995                Call::Exit => {
996                    match alt_id {
997                        0 => self.exit_file(),                      // file -> decls ruleset
998                        1 => self.exit_decls(),                     // decls -> decl_iter
999                        2 => self.exit_decl_iter(),                 // decl_iter -> <L> decl decl_iter
1000                        3 => {}                                     // decl_iter -> <L> ε (not used)
1001                        4 => self.exit_decl(),                      // decl -> "token" decl_terminal decl_1 ";"
1002                        29 => self.exit_decl1(),                    // decl_1 -> "," decl_terminal decl_1
1003                        30 => {}                                    // decl_1 -> ε
1004                        52 |                                        // decl_terminal_1 -> "=" TerminalCst
1005                        53 => self.exit_decl_terminal(alt_id),      // decl_terminal_1 -> ε
1006                     /* 5 */                                        // decl_terminal -> Terminal decl_terminal_1 (never called)
1007                        6 => self.exit_ruleset(),                   // ruleset -> rule_iter
1008                        7 => self.exit_rule_iter(),                 // rule_iter -> <L> rule rule_iter
1009                        8 => {}                                     // rule_iter -> <L> ε (not used)
1010                        54 |                                        // rule_1 -> "->" prs_expr ";"
1011                        55 => self.exit_rule(alt_id),               // rule_1 -> "=>" rts_expr ";"
1012                     /* 9 */                                        // rule -> rule_nt rule_1 (never called)
1013                        10 => self.exit_rule_nt(),                  // rule_nt -> Nonterminal
1014                        11 |                                        // rts_expr -> "&" rts_children
1015                        12 |                                        // rts_expr -> "|" rts_children
1016                        13 |                                        // rts_expr -> "+" rts_children
1017                        14 |                                        // rts_expr -> "*" rts_children
1018                        15 |                                        // rts_expr -> "?" rts_children
1019                        16 => self.exit_rts_expr(alt_id),           // rts_expr -> item
1020                        17 => self.exit_rts_children(),             // rts_children -> "(" rts_children_1 ")"
1021                        31 => self.exit_rts_children1(),            // rts_children_1 -> rts_expr rts_children_1
1022                        32 => {}                                    // rts_children_1 -> ε
1023                        33 |                                        // prs_expr_1 -> "+" prs_expr_1
1024                        34 |                                        // prs_expr_1 -> "*" prs_expr_1
1025                        35 |                                        // prs_expr_1 -> "?" prs_expr_1
1026                        36 |                                        // prs_expr_1 -> prs_expr_4 prs_expr_1
1027                        37 => self.exit_prs_expr1(alt_id),          // prs_expr_1 -> "|" prs_expr_2 prs_expr_1
1028                        40 |                                        // prs_expr_3 -> "+" prs_expr_3 (duplicate of 33)
1029                        46 => self.exit_prs_expr1(33),              // prs_expr_5 -> "+" prs_expr_5 (duplicate of 33)
1030                        41 |                                        // prs_expr_3 -> "*" prs_expr_3 (duplicate of 34)
1031                        47 => self.exit_prs_expr1(34),              // prs_expr_5 -> "*" prs_expr_5 (duplicate of 34)
1032                        42 |                                        // prs_expr_3 -> "?" prs_expr_3 (duplicate of 35)
1033                        48 => self.exit_prs_expr1(35),              // prs_expr_5 -> "?" prs_expr_5 (duplicate of 35)
1034                        43 => self.exit_prs_expr1(36),              // prs_expr_3 -> prs_expr_4 prs_expr_3 (duplicate of 36)
1035                        50 |                                        // prs_expr_6 -> "(" prs_expr ")"
1036                        51 => self.exit_prs_expr6(alt_id),          // prs_expr_6 -> item
1037                        18 => {}                                    // prs_expr -> prs_expr_6 prs_expr_1 (not used)
1038                        38 => {}                                    // prs_expr_1 -> ε (not used)
1039                        39 => {}                                    // prs_expr_2 -> prs_expr_6 prs_expr_3 (not used)
1040                        44 => {}                                    // prs_expr_3 -> ε (not used)
1041                        45 => {}                                    // prs_expr_4 -> prs_expr_6 prs_expr_5 (not used)
1042                        49 => {}                                    // prs_expr_5 -> ε (not used)
1043                        19 |                                        // item -> Nonterminal
1044                        20 |                                        // item -> NTx
1045                        21 |                                        // item -> Terminal
1046                        22 |                                        // item -> TerminalCst
1047                        23 |                                        // item -> Tx
1048                        24 |                                        // item -> Empty
1049                        25 |                                        // item -> LTag
1050                        26 |                                        // item -> "<P>"
1051                        27 |                                        // item -> "<R>"
1052                        28 => self.exit_item(alt_id),               // item -> "<G>"
1053                        _ => panic!("unexpected exit alternative id: {alt_id}")
1054                    }
1055                }
1056                Call::End(terminate) => {
1057                    match terminate {
1058                        Terminate::None => {
1059                            let val = self.stack.pop().unwrap().get_file();
1060                            self.listener.exit(val);
1061                        }
1062                        Terminate::Abort | Terminate::Conclude => self.listener.abort(terminate),
1063                    }
1064                }
1065            }
1066            self.max_stack = std::cmp::max(self.max_stack, self.stack.len());
1067            if self.verbose {
1068                println!("> stack_t:   {}", self.stack_t.join(", "));
1069                println!("> stack:     {}", self.stack.iter().map(|it| format!("{it:?}")).collect::<Vec<_>>().join(", "));
1070            }
1071        }
1072
1073        fn check_abort_request(&self) -> Terminate {
1074            self.listener.check_abort_request()
1075        }
1076
1077        fn abort(&mut self) {
1078            self.stack.clear();
1079            self.stack_t.clear();
1080        }
1081
1082        fn get_log_mut(&mut self) -> &mut impl Logger {
1083            self.listener.get_log_mut()
1084        }
1085
1086        fn is_stack_empty(&self) -> bool {
1087            self.stack.is_empty()
1088        }
1089
1090        fn is_stack_t_empty(&self) -> bool {
1091            self.stack_t.is_empty()
1092        }
1093
1094        fn intercept_token(&mut self, token: TokenId, text: &str, _span: &PosSpan) -> TokenId {
1095            self.listener.intercept_token(token, text)
1096        }
1097    }
1098
1099    impl<T: RtsGenListener> Wrapper<T> {
1100        pub fn new(listener: T, verbose: bool) -> Self {
1101            Wrapper { verbose, listener, stack: Vec::new(), max_stack: 0, stack_t: Vec::new() }
1102        }
1103
1104        pub fn get_listener(&self) -> &T {
1105            &self.listener
1106        }
1107
1108        pub fn get_listener_mut(&mut self) -> &mut T {
1109            &mut self.listener
1110        }
1111
1112        pub fn give_listener(self) -> T {
1113            self.listener
1114        }
1115
1116        pub fn set_verbose(&mut self, verbose: bool) {
1117            self.verbose = verbose;
1118        }
1119
1120        fn exit_file(&mut self) {
1121            let ruleset = self.stack.pop().unwrap().get_ruleset();
1122            let decls = self.stack.pop().unwrap().get_decls();
1123            let ctx = CtxFile::V1 { decls, ruleset };
1124            let val = self.listener.exit_file(ctx);
1125            self.stack.push(EnumSynValue::File(val));
1126        }
1127
1128        fn exit_decls(&mut self) {
1129            let ctx = CtxDecls::V1;
1130            let val = self.listener.exit_decls(ctx);
1131            self.stack.push(EnumSynValue::Decls(val));
1132        }
1133
1134        fn exit_decl_iter(&mut self) {
1135            let decl = self.stack.pop().unwrap().get_decl();
1136            let ctx = CtxDeclIter::V1 { decl };
1137            self.listener.exit_decl_iter(ctx);
1138        }
1139
1140        fn exit_decl(&mut self) {
1141            let star = self.stack.pop().unwrap().get_decl1();
1142            let ctx = CtxDecl::V1 { star };
1143            let val = self.listener.exit_decl(ctx);
1144            self.stack.push(EnumSynValue::Decl(val));
1145        }
1146
1147        fn init_decl1(&mut self) {
1148            let decl_terminal = self.stack.pop().unwrap().get_decl_terminal();
1149            self.stack.push(EnumSynValue::Decl1(SynDecl1(vec![decl_terminal])));
1150        }
1151
1152        fn exit_decl1(&mut self) {
1153            let decl_terminal = self.stack.pop().unwrap().get_decl_terminal();
1154            let Some(EnumSynValue::Decl1(SynDecl1(star_acc))) = self.stack.last_mut() else {
1155                panic!("expected SynDecl1 item on wrapper stack");
1156            };
1157            star_acc.push(decl_terminal);
1158        }
1159
1160        fn exit_decl_terminal(&mut self, alt_id: AltId) {
1161            let ctx = match alt_id {
1162                52 => {
1163                    let terminalcst = self.stack_t.pop().unwrap();
1164                    let terminal = self.stack_t.pop().unwrap();
1165                    CtxDeclTerminal::V1 { terminal, terminalcst }
1166                }
1167                53 => {
1168                    let terminal = self.stack_t.pop().unwrap();
1169                    CtxDeclTerminal::V2 { terminal }
1170                }
1171                _ => panic!("unexpected alt id {alt_id} in fn exit_decl_terminal")
1172            };
1173            let val = self.listener.exit_decl_terminal(ctx);
1174            self.stack.push(EnumSynValue::DeclTerminal(val));
1175        }
1176
1177        fn exit_ruleset(&mut self) {
1178            let ctx = CtxRuleset::V1;
1179            let val = self.listener.exit_ruleset(ctx);
1180            self.stack.push(EnumSynValue::Ruleset(val));
1181        }
1182
1183        fn exit_rule_iter(&mut self) {
1184            let rule = self.stack.pop().unwrap().get_rule();
1185            let ctx = CtxRuleIter::V1 { rule };
1186            self.listener.exit_rule_iter(ctx);
1187        }
1188
1189        fn exit_rule(&mut self, alt_id: AltId) {
1190            let ctx = match alt_id {
1191                54 => {
1192                    let prs_expr = self.stack.pop().unwrap().get_prs_expr();
1193                    let rule_nt = self.stack.pop().unwrap().get_rule_nt();
1194                    CtxRule::V2 { rule_nt, prs_expr }
1195                }
1196                55 => {
1197                    let rts_expr = self.stack.pop().unwrap().get_rts_expr();
1198                    let rule_nt = self.stack.pop().unwrap().get_rule_nt();
1199                    CtxRule::V1 { rule_nt, rts_expr }
1200                }
1201                _ => panic!("unexpected alt id {alt_id} in fn exit_rule")
1202            };
1203            let val = self.listener.exit_rule(ctx);
1204            self.stack.push(EnumSynValue::Rule(val));
1205        }
1206
1207        fn exit_rule_nt(&mut self) {
1208            let nonterminal = self.stack_t.pop().unwrap();
1209            let ctx = CtxRuleNt::V1 { nonterminal };
1210            let val = self.listener.exit_rule_nt(ctx);
1211            self.stack.push(EnumSynValue::RuleNt(val));
1212        }
1213
1214        fn exit_rts_expr(&mut self, alt_id: AltId) {
1215            let ctx = match alt_id {
1216                11 => {
1217                    let rts_children = self.stack.pop().unwrap().get_rts_children();
1218                    CtxRtsExpr::V1 { rts_children }
1219                }
1220                12 => {
1221                    let rts_children = self.stack.pop().unwrap().get_rts_children();
1222                    CtxRtsExpr::V2 { rts_children }
1223                }
1224                13 => {
1225                    let rts_children = self.stack.pop().unwrap().get_rts_children();
1226                    CtxRtsExpr::V3 { rts_children }
1227                }
1228                14 => {
1229                    let rts_children = self.stack.pop().unwrap().get_rts_children();
1230                    CtxRtsExpr::V4 { rts_children }
1231                }
1232                15 => {
1233                    let rts_children = self.stack.pop().unwrap().get_rts_children();
1234                    CtxRtsExpr::V5 { rts_children }
1235                }
1236                16 => {
1237                    let item = self.stack.pop().unwrap().get_item();
1238                    CtxRtsExpr::V6 { item }
1239                }
1240                _ => panic!("unexpected alt id {alt_id} in fn exit_rts_expr")
1241            };
1242            let val = self.listener.exit_rts_expr(ctx);
1243            self.stack.push(EnumSynValue::RtsExpr(val));
1244        }
1245
1246        fn exit_rts_children(&mut self) {
1247            let star = self.stack.pop().unwrap().get_rts_children1();
1248            let ctx = CtxRtsChildren::V1 { star };
1249            let val = self.listener.exit_rts_children(ctx);
1250            self.stack.push(EnumSynValue::RtsChildren(val));
1251        }
1252
1253        fn init_rts_children1(&mut self) {
1254            let val = SynRtsChildren1(Vec::new());
1255            self.stack.push(EnumSynValue::RtsChildren1(val));
1256        }
1257
1258        fn exit_rts_children1(&mut self) {
1259            let rts_expr = self.stack.pop().unwrap().get_rts_expr();
1260            let Some(EnumSynValue::RtsChildren1(SynRtsChildren1(star_acc))) = self.stack.last_mut() else {
1261                panic!("expected SynRtsChildren1 item on wrapper stack");
1262            };
1263            star_acc.push(rts_expr);
1264        }
1265
1266        fn exit_prs_expr1(&mut self, alt_id: AltId) {
1267            let ctx = match alt_id {
1268                33 => {
1269                    let prs_expr = self.stack.pop().unwrap().get_prs_expr();
1270                    CtxPrsExpr::V1 { prs_expr }
1271                }
1272                34 => {
1273                    let prs_expr = self.stack.pop().unwrap().get_prs_expr();
1274                    CtxPrsExpr::V2 { prs_expr }
1275                }
1276                35 => {
1277                    let prs_expr = self.stack.pop().unwrap().get_prs_expr();
1278                    CtxPrsExpr::V3 { prs_expr }
1279                }
1280                36 => {
1281                    let prs_expr_2 = self.stack.pop().unwrap().get_prs_expr();
1282                    let prs_expr_1 = self.stack.pop().unwrap().get_prs_expr();
1283                    CtxPrsExpr::V4 { prs_expr: [prs_expr_1, prs_expr_2] }
1284                }
1285                37 => {
1286                    let prs_expr_2 = self.stack.pop().unwrap().get_prs_expr();
1287                    let prs_expr_1 = self.stack.pop().unwrap().get_prs_expr();
1288                    CtxPrsExpr::V5 { prs_expr: [prs_expr_1, prs_expr_2] }
1289                }
1290                _ => panic!("unexpected alt id {alt_id} in fn exit_prs_expr1")
1291            };
1292            let val = self.listener.exit_prs_expr(ctx);
1293            self.stack.push(EnumSynValue::PrsExpr(val));
1294        }
1295
1296        fn exit_prs_expr6(&mut self, alt_id: AltId) {
1297            let ctx = match alt_id {
1298                50 => {
1299                    let prs_expr = self.stack.pop().unwrap().get_prs_expr();
1300                    CtxPrsExpr::V6 { prs_expr }
1301                }
1302                51 => {
1303                    let item = self.stack.pop().unwrap().get_item();
1304                    CtxPrsExpr::V7 { item }
1305                }
1306                _ => panic!("unexpected alt id {alt_id} in fn exit_prs_expr6")
1307            };
1308            let val = self.listener.exit_prs_expr(ctx);
1309            self.stack.push(EnumSynValue::PrsExpr(val));
1310        }
1311
1312        fn exit_item(&mut self, alt_id: AltId) {
1313            let ctx = match alt_id {
1314                19 => {
1315                    let nonterminal = self.stack_t.pop().unwrap();
1316                    CtxItem::V1 { nonterminal }
1317                }
1318                20 => {
1319                    let ntx = self.stack_t.pop().unwrap();
1320                    CtxItem::V2 { ntx }
1321                }
1322                21 => {
1323                    let terminal = self.stack_t.pop().unwrap();
1324                    CtxItem::V3 { terminal }
1325                }
1326                22 => {
1327                    let terminalcst = self.stack_t.pop().unwrap();
1328                    CtxItem::V4 { terminalcst }
1329                }
1330                23 => {
1331                    let tx = self.stack_t.pop().unwrap();
1332                    CtxItem::V5 { tx }
1333                }
1334                24 => {
1335                    let empty = self.stack_t.pop().unwrap();
1336                    CtxItem::V6 { empty }
1337                }
1338                25 => {
1339                    let ltag = self.stack_t.pop().unwrap();
1340                    CtxItem::V7 { ltag }
1341                }
1342                26 => {
1343                    CtxItem::V8
1344                }
1345                27 => {
1346                    CtxItem::V9
1347                }
1348                28 => {
1349                    CtxItem::V10
1350                }
1351                _ => panic!("unexpected alt id {alt_id} in fn exit_item")
1352            };
1353            let val = self.listener.exit_item(ctx);
1354            self.stack.push(EnumSynValue::Item(val));
1355        }
1356    }
1357
1358    // [rtsgen_parser]
1359}
1360
1361// -------------------------------------------------------------------------