// Copyright (c) 2025 Redglyph (@gmail.com). All Rights Reserved.
// =============================================================================================
// Parser for the simplified grammars used in unit tests
// (lexer/parser generated by the build-rtsgen crate)
mod tests;
use std::collections::HashMap;
use std::io::Cursor;
use std::str::FromStr;
use iter_index::IndexerIterator;
use vectree::VecTree;
use lexigram_core::CollectJoin;
use crate::{General, NameFixer, NameTransformer, SymbolTable};
use crate::{TokenId, VarId};
use crate::grammar::{GrNode, GrTree, RuleTreeSet};
use crate::char_reader::CharReader;
use crate::lexer::{Lexer, TokenSpliterator};
use lexigram_core::log::{BufLog, LogStatus, Logger};
use crate::parser::{Parser, Symbol};
use crate::rtsgen::listener_types::*;
use crate::rtsgen::rtsgen_lexer::build_lexer;
use crate::rtsgen::rtsgen_parser::*;
static T_NAME_DICTIONARY: &[(&str, &str)] = &[
("+", "Add"), ("-", "Sub"), ("*", "Mul"), ("/", "Div"), ("%", "Percent"), ("++", "Inc"), ("--", "Dec"),
("<<", "Shl"), (">>", "Shr"), ("!", "Not"), ("^", "Exp"), ("~", "Tilde"),
("&", "And"), ("|", "Or"), ("&&", "And2"), ("||", "Or2"),
("=", "Eq"), ("==", "Eq2"), ("<", "Lt"), (">", "Gt"), ("<=", "LtEq"), (">=", "GtEq"), ("!=", "Neq"),
(":=", "ColonEq"), ("+=", "AddEq"), ("-=", "SubEq"), ("*=", "MulEq"), ("/=", "DivEq"),
("(", "LPar"), (")", "RPar"), ("[", "LSBracket"), ("]", "RSBracker"), ("{", "LBracket"), ("}", "RBracket"),
("\"", "DQuote"), ("'", "Quote"), ("$", "Dollar"), ("?", "Question"), ("\\", "Backslash"),
(":", "Colon"), (";", "SemiColon"), (".", "Dot"), (",", "Comma"), ("#", "Sharp"), ("@", "At"), ("´", "Tick"), ("`", "BTick"),
("\n", "EOL"), ("\r\n", "WinEOL"), ("\r", "CR"), ("\t", "Tab"), (" ", "Space"), ("\\", "Backslash"), ("\0", "Null"),
("->", "Arrow"), ("=>", "DArrow"),
];
pub struct RtsGen<'l, 'p> {
lexer: Lexer<'l, Cursor<String>>,
parser: Parser<'p>,
t_name_dictionary: Option<HashMap<String, String>>,
}
impl RtsGen<'_, '_> {
pub fn new() -> Self {
let t_name_dictionary = Some(HashMap::from_iter(T_NAME_DICTIONARY.iter().map(|(a, b)| (a.to_string(), b.to_string()))));
RtsGen::with_guess_names(t_name_dictionary)
}
pub fn with_guess_names(t_name_dictionary: Option<HashMap<String, String>>) -> Self {
let lexer = build_lexer();
let parser = build_parser();
RtsGen { lexer, parser, t_name_dictionary }
}
pub fn parse(&mut self, text: String) -> Result<RuleTreeSet<General>, BufLog> {
const VERBOSE_WRAPPER: bool = false;
let mut wrapper = Wrapper::new(RGListener::new(self.t_name_dictionary.as_ref()), VERBOSE_WRAPPER);
let stream = CharReader::new(Cursor::new(text));
self.lexer.attach_stream(stream);
let tokens = self.lexer.tokens().split_channel0(|(_tok, ch, text, pos_span)|
panic!("unexpected channel {ch} while parsing a file at {pos_span}, \"{text}\"")
);
let _ = self.parser.parse_stream(&mut wrapper, tokens); // errors are written in the log, so we can dismiss the error here
let listener = wrapper.give_listener();
listener.make_rts()
}
}
impl Default for RtsGen<'_, '_> {
fn default() -> Self {
Self::new()
}
}
// listener implementation
struct RGListener<'a> {
log: BufLog,
nt: HashMap<String, VarId>,
nt_def_order: Vec<VarId>,
rules: Vec<GrTree>,
reserved_nt: Vec<VarId>,
symbol_table: Option<SymbolTable>,
t: HashMap<String, TokenId>,
num_t: usize,
/// terminal information; `(String, Option<String>)` = (token name, optional string if not variable)
tokens: Vec<(String, Option<String>)>,
curr: Option<GrTree>,
curr_name: Option<String>,
curr_nt: Option<VarId>,
t_name_dictionary: Option<&'a HashMap<String, String>>,
}
#[derive(Clone, Copy, PartialEq)]
enum IsNew { No, Yes }
trait ToVarId {
fn to_var_id(self, panic_message: &str) -> VarId;
}
impl ToVarId for usize {
fn to_var_id(self, panic_message: &str) -> VarId {
if self < (VarId::MAX as usize) {
self as VarId
} else {
panic!("{panic_message}")
}
}
}
impl<'a> RGListener<'a> {
fn new(t_name_dictionary: Option<&'a HashMap<String, String>>) -> Self {
RGListener {
log: BufLog::new(),
nt: HashMap::new(),
nt_def_order: Vec::new(),
rules: Vec::new(),
reserved_nt: Vec::new(),
symbol_table: None,
t: HashMap::new(),
num_t: 0,
tokens: Vec::new(),
curr: None,
curr_name: None,
curr_nt: None,
t_name_dictionary,
}
}
pub fn make_rts(self) -> Result<RuleTreeSet<General>, BufLog> {
let RGListener { log, rules, symbol_table, .. } = self;
if log.has_no_errors() {
let mut rts = RuleTreeSet::<General>::with_log(log);
rts.set_symbol_table(symbol_table.unwrap());
rts.set_start(0);
for (var, rule) in rules.into_iter().index::<VarId>() {
rts.set_tree(var, rule);
}
Ok(rts)
} else {
Err(log)
}
}
/// Gets the nonterminal ID corresponding to the name, creating it if
/// it doesn't exist.
fn get_or_create_nt(&mut self, name: String) -> VarId {
let size = self.nt.len();
*self.nt.entry(name).or_insert_with(|| {
self.rules.push(GrTree::new());
size.to_var_id("too many nonterminals")
})
}
/// Gets the terminal ID corresponding to the name or value, creating it if
/// it doesn't exist.
///
/// Returns
/// * `IsNew` = `Yes` if the terminal had to be created, `No` otherwise
/// * `TokenId` = the terminal ID
fn get_or_create_t(&mut self, name: String) -> (IsNew, TokenId) {
let mut is_new = IsNew::No;
let tok = *self.t.entry(name).or_insert_with(|| {
is_new = IsNew::Yes;
let tok = self.num_t.to_var_id("too many terminals"); // VarId = TokenId
self.num_t += 1;
tok
});
(is_new, tok)
}
fn invent_t_name(&self, tok: TokenId, value: &str) -> String {
self.t_name_dictionary
.and_then(|g| g.get(value).cloned())
.unwrap_or_else(|| {
if value.chars().any(|c| c.is_ascii_alphanumeric()) &&
value.chars().all(|c| c.is_ascii_alphanumeric() || c.is_whitespace() || c == '_')
{
let name = value.chars().map(|c| if c.is_whitespace() { '_' } else { c }).collect::<String>();
if !value.as_bytes()[0].is_ascii_alphabetic() {
format!("Tok{}", name.to_camelcase())
} else {
name.to_camelcase()
}
} else {
format!("Token{tok}")
}
})
}
/// Finalizes the rules and creates the symbol table.
fn finalize_ruleset(&mut self) {
let mut nt_name = vec![String::new(); self.nt.len()];
let mut dest = vec![0; self.nt.len()];
self.nt_def_order.iter().enumerate().for_each(|(i, &nt)| dest[nt as usize] = i);
for (name, var) in &self.nt {
nt_name[dest[*var as usize]] = name.clone();
}
// detects undefined nonterminals
let mut undefined = self.nt.iter()
.filter_map(|(name, &var)| if self.rules[var as usize].is_empty() { Some(name.to_string()) } else { None })
.to_vec();
if !undefined.is_empty() {
undefined.sort(); // comes from hashmap
self.log.add_error(format!("undefined nonterminals: {}", undefined.into_iter().map(|s| format!("'{s}'")).join(", ")));
return;
}
// builds symbol table
assert_eq!(self.tokens.len(), self.num_t);
let mut symtab = SymbolTable::new();
symtab.extend_nonterminals(nt_name);
let mut t_name = vec![(String::new(), None); self.tokens.len()];
let mut namefixer = NameFixer::new_empty();
for (tok, (name, value_maybe)) in self.tokens.iter().enumerate().filter(|(_, (name, _))| !name.is_empty()) {
namefixer.add(name.clone());
t_name[tok] = (name.clone(), value_maybe.clone());
}
// puts names to constant terminals
for (tok, (_, cst_maybe)) in self.tokens.iter().enumerate().filter(|(_, (name, _))| name.is_empty()) {
let new_name = namefixer.get_unique_name(self.invent_t_name(tok as TokenId, cst_maybe.as_ref().unwrap()));
t_name[tok] = (new_name, cst_maybe.clone());
}
symtab.extend_terminals(t_name);
self.symbol_table = Some(symtab);
// remove reserved nonterminals
for v in &self.reserved_nt {
self.rules[*v as usize].clear();
}
// reorders nonterminal IDs by order of definition rather than order of appearance
self.rules = self.nt_def_order.iter()
.map(|nt| std::mem::take(self.rules.get_mut(*nt as usize).unwrap()))
.collect();
for rule in &mut self.rules {
for mut node in rule.iter_post_depth_simple_mut() {
match *node {
GrNode::Symbol(Symbol::NT(ref mut old))
| GrNode::LForm(ref mut old) => *old = *dest.get(*old as usize).unwrap_or(&(*old as usize)) as VarId,
_ => {}
}
}
}
}
}
impl RtsGenListener for RGListener<'_> {
fn get_log_mut(&mut self) -> &mut impl Logger {
&mut self.log
}
fn exit(&mut self, _ruleset: SynFile) {
self.finalize_ruleset();
}
fn exit_file(&mut self, _ctx: CtxFile) -> SynFile {
SynFile()
}
fn exit_decls(&mut self, _ctx: CtxDecls) -> SynDecls {
SynDecls()
}
fn exit_decl(&mut self, _ctx: CtxDecl) -> SynDecl {
SynDecl()
}
fn exit_decl_terminal(&mut self, ctx: CtxDeclTerminal) -> SynDeclTerminal {
match ctx {
// decl_terminal -> Terminal "=" TerminalCst
CtxDeclTerminal::V1 { terminal, terminalcst } => {
if self.t.contains_key(&terminal) {
self.log.add_error(format!("token '{terminal}' already declared"));
} else if self.t.contains_key(&terminalcst) {
self.log.add_error(format!("token value {terminalcst} already used"));
} else {
let token = self.num_t.to_var_id("too many terminals");
self.num_t += 1;
self.tokens.push((terminal.clone(), Some(terminalcst[1..terminalcst.len() - 1].to_string())));
self.t.insert(terminal, token);
self.t.insert(terminalcst, token);
}
}
// decl_terminal -> Terminal
CtxDeclTerminal::V2 { terminal } => {
if self.t.contains_key(&terminal) {
self.log.add_error(format!("token '{terminal}' already declared"));
} else {
let token = self.num_t.to_var_id("too many terminals");
self.num_t += 1;
self.tokens.push((terminal.clone(), None));
self.t.insert(terminal, token);
}
}
};
SynDeclTerminal()
}
fn exit_ruleset(&mut self, _ctx: CtxRuleset) -> SynRuleset {
SynRuleset()
}
fn init_rule(&mut self) {
self.curr_name = None;
self.curr = Some(VecTree::new());
self.curr_nt = None;
}
fn exit_rule(&mut self, ctx: CtxRule) -> SynRule {
let (var, id) = match ctx {
// rule -> rule_nt "->" prs_expr ";"
CtxRule::V1 { rule_nt: SynRuleNt(var), rts_expr: SynRtsExpr(id_expr) }
// rule -> rule_nt "=>" rts_expr ";"
| CtxRule::V2 { rule_nt: SynRuleNt(var), prs_expr: SynPrsExpr(id_expr) } => (var, id_expr),
};
let mut tree = self.curr.take().unwrap();
tree.set_root(id);
self.rules[var as usize] = tree;
SynRule()
}
fn exit_rule_nt(&mut self, ctx: CtxRuleNt) -> SynRuleNt {
let CtxRuleNt::V1 { nonterminal } = ctx;
let mut error = false;
assert_eq!(self.curr_nt, None);
let var = if let Some(&var) = self.nt.get(&nonterminal) {
if !self.rules[var as usize].is_empty() {
error = true;
self.log.add_error(format!("nonterminal '{nonterminal}' is defined multiple times"));
}
var
} else {
self.get_or_create_nt(nonterminal.clone())
};
if !error { self.nt_def_order.push(var); }
self.curr_nt = Some(var);
self.curr_name = Some(nonterminal);
SynRuleNt(var)
}
fn exit_rts_expr(&mut self, ctx: CtxRtsExpr) -> SynRtsExpr {
let tree = self.curr.as_mut().unwrap();
let id = match ctx {
// rts_expr -> "&" rts_children
CtxRtsExpr::V1 { rts_children: SynRtsChildren(v) } =>
tree.addci_iter(None, GrNode::Concat, v.into_iter().map(|SynRtsExpr(id)| id)),
// rts_expr -> "|" rts_children
CtxRtsExpr::V2 { rts_children: SynRtsChildren(v) } =>
tree.addci_iter(None, GrNode::Or, v.into_iter().map(|SynRtsExpr(id)| id)),
// rts_expr -> "+" rts_children
CtxRtsExpr::V3 { rts_children: SynRtsChildren(v) } =>
tree.addci_iter(None, GrNode::Plus, v.into_iter().map(|SynRtsExpr(id)| id)),
// rts_expr -> "*" rts_children
CtxRtsExpr::V4 { rts_children: SynRtsChildren(v) } =>
tree.addci_iter(None, GrNode::Star, v.into_iter().map(|SynRtsExpr(id)| id)),
// rts_expr -> "?" rts_children
CtxRtsExpr::V5 { rts_children: SynRtsChildren(v) } =>
tree.addci_iter(None, GrNode::Maybe, v.into_iter().map(|SynRtsExpr(id)| id)),
// rts_expr -> item
CtxRtsExpr::V6 { item: SynItem(id_item) } =>
id_item,
};
SynRtsExpr(id)
}
fn exit_rts_children(&mut self, ctx: CtxRtsChildren) -> SynRtsChildren {
// rts_children -> "(" rts_expr* ")"
let CtxRtsChildren::V1 { star: SynRtsChildren1(v) } = ctx;
SynRtsChildren(v)
}
fn exit_prs_expr(&mut self, ctx: CtxPrsExpr) -> SynPrsExpr {
let tree = self.curr.as_mut().unwrap();
let id = match ctx {
// prs_expr -> prs_expr "+"
CtxPrsExpr::V1 { prs_expr: SynPrsExpr(id) } =>
tree.addci(None, GrNode::Plus, id),
// prs_expr -> prs_expr "*"
CtxPrsExpr::V2 { prs_expr: SynPrsExpr(id) } =>
tree.addci(None, GrNode::Star, id),
// prs_expr -> prs_expr "?"
CtxPrsExpr::V3 { prs_expr: SynPrsExpr(id) } =>
tree.addci(None, GrNode::Maybe, id),
// prs_expr -> prs_expr prs_expr
CtxPrsExpr::V4 { prs_expr: [SynPrsExpr(mut left), SynPrsExpr(right)] } => {
if *tree.get(left) != GrNode::Concat {
left = tree.addci(None, GrNode::Concat, left);
}
tree.attach_child(left, right);
left
}
// prs_expr -> prs_expr "|" prs_expr
CtxPrsExpr::V5 { prs_expr: [SynPrsExpr(mut left), SynPrsExpr(right)] } => {
if *tree.get(left) != GrNode::Or {
left = tree.addci(None, GrNode::Or, left);
}
tree.attach_child(left, right);
left
}
// prs_expr -> "(" prs_expr ")"
CtxPrsExpr::V6 { prs_expr: SynPrsExpr(id) } => id,
// prs_expr -> item
CtxPrsExpr::V7 { item: SynItem(id) } => id,
};
SynPrsExpr(id)
}
fn exit_item(&mut self, ctx: CtxItem) -> SynItem {
let id = match ctx {
// item -> Nonterminal
CtxItem::V1 { nonterminal } => {
let var = self.get_or_create_nt(nonterminal);
self.curr.as_mut().unwrap().add(None, GrNode::Symbol(Symbol::NT(var)))
}
// item -> NTx (NT symbol without any check or creation process)
CtxItem::V2 { ntx } => {
let x = match VarId::from_str(&ntx[3..ntx.len() - 1]) {
Ok(x) => x,
Err(e) => {
self.log.add_error(format!("in {}, integer literal {ntx} can't be parsed: {e}", self.curr_name.as_ref().unwrap()));
VarId::MAX
}
};
self.curr.as_mut().unwrap().add(None, GrNode::Symbol(Symbol::NT(x)))
}
// item -> Terminal
CtxItem::V3 { terminal } => {
let (is_new, tok) = self.get_or_create_t(terminal.clone());
if let IsNew::Yes = is_new {
self.tokens.push((terminal, None));
}
self.curr.as_mut().unwrap().add(None, GrNode::Symbol(Symbol::T(tok)))
}
// item -> TerminalCst
CtxItem::V4 { terminalcst } => {
let (is_new, tok) = self.get_or_create_t(terminalcst.clone());
if let IsNew::Yes = is_new {
// the names will be set later, to give priority to variable terminal names in case of conflict
match decode_str(&terminalcst[1..terminalcst.len() - 1]) {
Ok(text) => {
self.tokens.push((String::new(), Some(text)));
}
Err(msg) => {
self.log.add_error(format!("in {}, string literal {terminalcst}: {msg}", self.curr_name.as_ref().unwrap()));
self.tokens.push((String::new(), Some("???".to_string())));
}
}
}
self.curr.as_mut().unwrap().add(None, GrNode::Symbol(Symbol::T(tok)))
}
// item -> Tx (T symbol without any check or creation process)
CtxItem::V5 { tx } => {
let x = match VarId::from_str(&tx[2..tx.len() - 1]) {
Ok(x) => x,
Err(e) => {
self.log.add_error(format!("in {}, integer literal {tx} can't be parsed: {e}", self.curr_name.as_ref().unwrap()));
VarId::MAX
}
};
self.curr.as_mut().unwrap().add(None, GrNode::Symbol(Symbol::T(x)))
}
// item -> Empty
CtxItem::V6 { .. } =>
self.curr.as_mut().unwrap().add(None, GrNode::Symbol(Symbol::Empty)),
// item -> LTag
CtxItem::V7 { ltag } => {
// `ltag` contains "<L=name>" or "<L>"
let var = if ltag.len() > 3 {
let name = <ag[3..ltag.len()-1];
let var = self.get_or_create_nt(name.to_string());
self.nt_def_order.push(var);
self.rules[var as usize].add_root(GrNode::Symbol(Symbol::Empty));
self.reserved_nt.push(var);
var
} else {
self.curr_nt.unwrap()
};
self.curr.as_mut().unwrap().add(None, GrNode::LForm(var))
}
// item -> "<P>"
CtxItem::V8 => self.curr.as_mut().unwrap().add(None, GrNode::PrecEq),
// item -> "<R>"
CtxItem::V9 => self.curr.as_mut().unwrap().add(None, GrNode::RAssoc),
// `item -> "<G>"`
CtxItem::V10 => self.curr.as_mut().unwrap().add(None, GrNode::Greedy),
};
SynItem(id)
}
}
/// Decodes a string literal (without its surrounding quotes). There must be at least two characters in `strlit`.
fn decode_str(strlit: &str) -> Result<String, String> {
let mut result = String::new();
let mut chars = strlit.chars();
while let Some(c) = chars.next() {
match c {
'\\' => {
result.push(match chars.next().ok_or(format!("'\\' incomplete escape code in string literal '{strlit}'"))? {
'n' => '\n',
'r' => '\r',
't' => '\t',
'\"' => '\"',
'\\' => '\\',
'u' => {
if !matches!(chars.next(), Some('{')) { return Err(format!("malformed unicode literal in string literal '{strlit}' (missing '{{')")); }
let mut hex = String::new();
loop {
let Some(h) = chars.next() else { return Err(format!("malformed unicode literal in string literal '{strlit}' (missing '}}')")); };
if h == '}' { break; }
hex.push(h);
};
let code = u32::from_str_radix(&hex, 16).map_err(|_| format!("'{hex}' isn't a valid hexadecimal value"))?;
char::from_u32(code).ok_or_else(|| format!("'{hex}' isn't a valid unicode hexadecimal value"))?
}
unknown => return Err(format!("unknown escape code '\\{unknown}' in string literal '{strlit}'"))
});
}
_ => result.push(c)
}
}
Ok(result)
}
// -------------------------------------------------------------------------
// User types used in the listener interface:
// (initially copied/uncommented from the generated parser code)
pub mod listener_types {
use crate::VarId;
/// User-defined type for `file`
#[derive(Debug, PartialEq)] pub struct SynFile();
/// User-defined type for `decls`
#[derive(Debug, PartialEq)] pub struct SynDecls();
/// User-defined type for `decl`
#[derive(Debug, PartialEq)] pub struct SynDecl();
/// User-defined type for `decl_terminal`
#[derive(Debug, PartialEq)] pub struct SynDeclTerminal();
/// User-defined type for `ruleset`
#[derive(Debug, PartialEq)] pub struct SynRuleset();
/// User-defined type for `rule`
#[derive(Debug, PartialEq)] pub struct SynRule();
/// User-defined type for `rule_nt`
#[derive(Debug, PartialEq)] pub struct SynRuleNt(pub VarId);
/// User-defined type for `rts_expr`
#[derive(Debug, PartialEq)] pub struct SynRtsExpr(pub usize);
/// User-defined type for `rts_children`
#[derive(Debug, PartialEq)] pub struct SynRtsChildren(pub Vec<SynRtsExpr>);
/// User-defined type for `prs_expr`
#[derive(Debug, PartialEq)] pub struct SynPrsExpr(pub usize);
/// User-defined type for `item`
#[derive(Debug, PartialEq)] pub struct SynItem(pub usize);
}
// -------------------------------------------------------------------------
pub mod rtsgen_lexer {
// Generated code, don't modify manually anything between the tags below
use crate as lexigram_lib;
// [rtsgen_lexer]
use std::collections::HashMap;
use std::io::Read;
use lexigram_lib::lexer::{ActionOption, Lexer, ModeOption, StateId, Terminal};
use lexigram_lib::segmap::{GroupId, Seg, SegMap};
const NBR_GROUPS: u32 = 43;
const INITIAL_STATE: StateId = 0;
const FIRST_END_STATE: StateId = 23;
const NBR_STATES: StateId = 56;
static ASCII_TO_GROUP: [GroupId; 128] = [
31, 31, 31, 31, 31, 31, 31, 31, 31, 22, 39, 31, 31, 39, 31, 31, // 0-15
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, // 16-31
0, 31, 1, 31, 31, 31, 2, 31, 3, 4, 5, 6, 7, 8, 31, 9, // 32-47
37, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, 10, 11, 12, 23, 13, // 48-63
31, 29, 29, 29, 29, 29, 29, 14, 34, 34, 34, 34, 26, 34, 15, 34, // 64-79
27, 34, 28, 34, 16, 34, 34, 34, 34, 34, 34, 31, 24, 31, 31, 35, // 80-95
31, 33, 33, 33, 33, 41, 33, 36, 36, 36, 36, 40, 36, 36, 42, 38, // 96-111
36, 36, 17, 36, 18, 32, 36, 36, 36, 36, 36, 19, 20, 25, 31, 31, // 112-127
];
static UTF8_TO_GROUP: [(char, GroupId); 2] = [
('ε', 21),
('€', 21),
];
static SEG_TO_GROUP: [(Seg, GroupId); 4] = [
(Seg(128, 948), 31),
(Seg(950, 8363), 31),
(Seg(8365, 55295), 31),
(Seg(57344, 1114111), 31),
];
static TERMINAL_TABLE: [Terminal;33] = [
Terminal { action: ActionOption::Skip, channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(2), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(10), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(11), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(5), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(4), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(9), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(12), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(8), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(6), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(19), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(19), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(19), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(20), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(20), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(3), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(7), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Skip, channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Skip, channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(0), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(1), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(13), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(14), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(15), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(16), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(20), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(20), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(20), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(17), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(18), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(19), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(21), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
Terminal { action: ActionOption::Token(22), channel: 0, mode: ModeOption::None, mode_state: None, pop: false },
];
static STATE_TABLE: [StateId; 2409] = [
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
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
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
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
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
56, 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
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
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
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
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
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
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
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
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
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
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
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
56, 56, 56, 56, 56, 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
56, 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
56, 56, 56, 56, 56, 56, 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
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
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
56, 56, 56, 56, 56, 56, 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
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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
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>
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>
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>
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>
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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
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>
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>
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>
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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 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>
56 // error group in [nbr_state * nbr_group + nbr_group]
];
pub fn build_lexer<R: Read>() -> Lexer<'static, R> {
Lexer::new(
// parameters
NBR_GROUPS,
INITIAL_STATE,
FIRST_END_STATE,
NBR_STATES,
// tables
&ASCII_TO_GROUP,
HashMap::<char, GroupId>::from(UTF8_TO_GROUP),
SegMap::<GroupId>::from(SEG_TO_GROUP),
&STATE_TABLE,
&TERMINAL_TABLE,
)
}
// [rtsgen_lexer]
}
// -------------------------------------------------------------------------
pub mod rtsgen_parser {
// Generated code, don't modify manually anything between the tags below
use crate as lexigram_lib;
// [rtsgen_parser]
use lexigram_lib::{AltId, TokenId, VarId, fixed_sym_table::FixedSymTable, lexer::PosSpan, log::{LogMsg, Logger}, parser::{Call, ListenerWrapper, OpCode, Parser, Terminate}};
use super::listener_types::*;
const PARSER_NUM_T: usize = 23;
const PARSER_NUM_NT: usize = 23;
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)];
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"];
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];
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];
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)]];
static INIT_OPCODES: [OpCode; 2] = [OpCode::End, OpCode::NT(0)];
static START_SYMBOL: VarId = 0;
pub fn build_parser() -> Parser<'static> {{
let symbol_table = FixedSymTable::new(
SYMBOLS_T.into_iter().map(|(s, os)| (s.to_string(), os.map(|s| s.to_string()))).collect(),
SYMBOLS_NT.into_iter().map(|s| s.to_string()).collect()
);
Parser::new(
PARSER_NUM_NT, PARSER_NUM_T + 1,
&ALT_VAR,
Vec::new(),
OPCODES.into_iter().map(|strip| strip.to_vec()).collect(),
INIT_OPCODES.to_vec(),
&PARSING_TABLE,
symbol_table,
START_SYMBOL
)
}}
#[derive(Debug)]
pub enum CtxFile {
/// `file -> decls ruleset`
V1 { decls: SynDecls, ruleset: SynRuleset },
}
#[derive(Debug)]
pub enum CtxDecls {
/// `decls -> (<L> decl)*`
V1,
}
#[derive(Debug)]
pub enum CtxDeclIter {
/// `<L> decl` iteration in `decls -> ( ►► <L> decl ◄◄ )*`
V1 { decl: SynDecl },
}
#[derive(Debug)]
pub enum CtxDecl {
/// `decl -> "token" decl_terminal ("," decl_terminal)* ";"`
V1 { star: SynDecl1 },
}
#[derive(Debug)]
pub enum CtxDeclTerminal {
/// `decl_terminal -> Terminal "=" TerminalCst`
V1 { terminal: String, terminalcst: String },
/// `decl_terminal -> Terminal`
V2 { terminal: String },
}
#[derive(Debug)]
pub enum CtxRuleset {
/// `ruleset -> (<L> rule)*`
V1,
}
#[derive(Debug)]
pub enum CtxRuleIter {
/// `<L> rule` iteration in `ruleset -> ( ►► <L> rule ◄◄ )*`
V1 { rule: SynRule },
}
#[derive(Debug)]
pub enum CtxRule {
/// `rule -> rule_nt "=>" rts_expr ";"`
V1 { rule_nt: SynRuleNt, rts_expr: SynRtsExpr },
/// `rule -> rule_nt "->" prs_expr ";"`
V2 { rule_nt: SynRuleNt, prs_expr: SynPrsExpr },
}
#[derive(Debug)]
pub enum CtxRuleNt {
/// `rule_nt -> Nonterminal`
V1 { nonterminal: String },
}
#[derive(Debug)]
pub enum CtxRtsExpr {
/// `rts_expr -> "&" rts_children`
V1 { rts_children: SynRtsChildren },
/// `rts_expr -> "|" rts_children`
V2 { rts_children: SynRtsChildren },
/// `rts_expr -> "+" rts_children`
V3 { rts_children: SynRtsChildren },
/// `rts_expr -> "*" rts_children`
V4 { rts_children: SynRtsChildren },
/// `rts_expr -> "?" rts_children`
V5 { rts_children: SynRtsChildren },
/// `rts_expr -> item`
V6 { item: SynItem },
}
#[derive(Debug)]
pub enum CtxRtsChildren {
/// `rts_children -> "(" rts_expr* ")"`
V1 { star: SynRtsChildren1 },
}
#[derive(Debug)]
pub enum CtxPrsExpr {
/// `prs_expr -> prs_expr "+"`
V1 { prs_expr: SynPrsExpr },
/// `prs_expr -> prs_expr "*"`
V2 { prs_expr: SynPrsExpr },
/// `prs_expr -> prs_expr "?"`
V3 { prs_expr: SynPrsExpr },
/// `prs_expr -> prs_expr prs_expr`
V4 { prs_expr: [SynPrsExpr; 2] },
/// `prs_expr -> prs_expr "|" prs_expr`
V5 { prs_expr: [SynPrsExpr; 2] },
/// `prs_expr -> "(" prs_expr ")"`
V6 { prs_expr: SynPrsExpr },
/// `prs_expr -> item`
V7 { item: SynItem },
}
#[derive(Debug)]
pub enum CtxItem {
/// `item -> Nonterminal`
V1 { nonterminal: String },
/// `item -> NTx`
V2 { ntx: String },
/// `item -> Terminal`
V3 { terminal: String },
/// `item -> TerminalCst`
V4 { terminalcst: String },
/// `item -> Tx`
V5 { tx: String },
/// `item -> Empty`
V6 { empty: String },
/// `item -> LTag`
V7 { ltag: String },
/// `item -> "<P>"`
V8,
/// `item -> "<R>"`
V9,
/// `item -> "<G>"`
V10,
}
/// Computed `("," decl_terminal)*` array in `decl -> "token" decl_terminal ►► ("," decl_terminal)* ◄◄ ";"`
#[derive(Debug, PartialEq)]
pub struct SynDecl1(pub Vec<SynDeclTerminal>);
/// Computed `rts_expr*` array in `rts_children -> "(" ►► rts_expr* ◄◄ ")"`
#[derive(Debug, PartialEq)]
pub struct SynRtsChildren1(pub Vec<SynRtsExpr>);
#[derive(Debug)]
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) }
impl EnumSynValue {
fn get_file(self) -> SynFile {
if let EnumSynValue::File(val) = self { val } else { panic!() }
}
fn get_decls(self) -> SynDecls {
if let EnumSynValue::Decls(val) = self { val } else { panic!() }
}
fn get_decl(self) -> SynDecl {
if let EnumSynValue::Decl(val) = self { val } else { panic!() }
}
fn get_decl_terminal(self) -> SynDeclTerminal {
if let EnumSynValue::DeclTerminal(val) = self { val } else { panic!() }
}
fn get_ruleset(self) -> SynRuleset {
if let EnumSynValue::Ruleset(val) = self { val } else { panic!() }
}
fn get_rule(self) -> SynRule {
if let EnumSynValue::Rule(val) = self { val } else { panic!() }
}
fn get_rule_nt(self) -> SynRuleNt {
if let EnumSynValue::RuleNt(val) = self { val } else { panic!() }
}
fn get_rts_expr(self) -> SynRtsExpr {
if let EnumSynValue::RtsExpr(val) = self { val } else { panic!() }
}
fn get_rts_children(self) -> SynRtsChildren {
if let EnumSynValue::RtsChildren(val) = self { val } else { panic!() }
}
fn get_prs_expr(self) -> SynPrsExpr {
if let EnumSynValue::PrsExpr(val) = self { val } else { panic!() }
}
fn get_item(self) -> SynItem {
if let EnumSynValue::Item(val) = self { val } else { panic!() }
}
fn get_decl1(self) -> SynDecl1 {
if let EnumSynValue::Decl1(val) = self { val } else { panic!() }
}
fn get_rts_children1(self) -> SynRtsChildren1 {
if let EnumSynValue::RtsChildren1(val) = self { val } else { panic!() }
}
}
pub trait RtsGenListener {
/// Checks if the listener requests an abort. This happens if an error is too difficult to recover from
/// and may corrupt the stack content. In that case, the parser immediately stops and returns `ParserError::AbortRequest`.
fn check_abort_request(&self) -> Terminate { Terminate::None }
fn get_log_mut(&mut self) -> &mut impl Logger;
#[allow(unused_variables)]
fn handle_msg(&mut self, span_opt: Option<&PosSpan>, msg: LogMsg) {
self.get_log_mut().add(msg);
}
#[allow(unused_variables)]
fn intercept_token(&mut self, token: TokenId, text: &str) -> TokenId { token }
#[allow(unused_variables)]
fn exit(&mut self, file: SynFile) {}
#[allow(unused_variables)]
fn abort(&mut self, terminate: Terminate) {}
fn init_file(&mut self) {}
fn exit_file(&mut self, ctx: CtxFile) -> SynFile;
fn init_decls(&mut self) {}
fn exit_decls(&mut self, ctx: CtxDecls) -> SynDecls;
fn init_decl_iter(&mut self) {}
#[allow(unused_variables)]
fn exit_decl_iter(&mut self, ctx: CtxDeclIter) {}
fn init_decl(&mut self) {}
fn exit_decl(&mut self, ctx: CtxDecl) -> SynDecl;
fn init_decl_terminal(&mut self) {}
fn exit_decl_terminal(&mut self, ctx: CtxDeclTerminal) -> SynDeclTerminal;
fn init_ruleset(&mut self) {}
fn exit_ruleset(&mut self, ctx: CtxRuleset) -> SynRuleset;
fn init_rule_iter(&mut self) {}
#[allow(unused_variables)]
fn exit_rule_iter(&mut self, ctx: CtxRuleIter) {}
fn init_rule(&mut self) {}
fn exit_rule(&mut self, ctx: CtxRule) -> SynRule;
fn init_rule_nt(&mut self) {}
fn exit_rule_nt(&mut self, ctx: CtxRuleNt) -> SynRuleNt;
fn init_rts_expr(&mut self) {}
fn exit_rts_expr(&mut self, ctx: CtxRtsExpr) -> SynRtsExpr;
fn init_rts_children(&mut self) {}
fn exit_rts_children(&mut self, ctx: CtxRtsChildren) -> SynRtsChildren;
fn init_prs_expr(&mut self) {}
fn exit_prs_expr(&mut self, ctx: CtxPrsExpr) -> SynPrsExpr;
fn init_item(&mut self) {}
fn exit_item(&mut self, ctx: CtxItem) -> SynItem;
}
pub struct Wrapper<T> {
verbose: bool,
listener: T,
stack: Vec<EnumSynValue>,
max_stack: usize,
stack_t: Vec<String>,
}
impl<T: RtsGenListener> ListenerWrapper for Wrapper<T> {
fn switch(&mut self, call: Call, nt: VarId, alt_id: AltId, t_data: Option<Vec<String>>) {
if self.verbose {
println!("switch: call={call:?}, nt={nt}, alt={alt_id}, t_data={t_data:?}");
}
if let Some(mut t_data) = t_data {
self.stack_t.append(&mut t_data);
}
match call {
Call::Enter => {
match nt {
0 => self.listener.init_file(), // file
1 => self.listener.init_decls(), // decls
2 => self.listener.init_decl_iter(), // decl_iter
3 => self.listener.init_decl(), // decl
13 => self.init_decl1(), // decl_1
4 => self.listener.init_decl_terminal(), // decl_terminal
21 => {} // decl_terminal_1
5 => self.listener.init_ruleset(), // ruleset
6 => self.listener.init_rule_iter(), // rule_iter
7 => self.listener.init_rule(), // rule
22 => {} // rule_1
8 => self.listener.init_rule_nt(), // rule_nt
9 => self.listener.init_rts_expr(), // rts_expr
10 => self.listener.init_rts_children(), // rts_children
14 => self.init_rts_children1(), // rts_children_1
11 => self.listener.init_prs_expr(), // prs_expr
15 ..= 20 => {} // prs_expr_1, prs_expr_2, prs_expr_3, prs_expr_4, prs_expr_5, prs_expr_6
12 => self.listener.init_item(), // item
_ => panic!("unexpected enter nonterminal id: {nt}")
}
}
Call::Loop => {}
Call::Exit => {
match alt_id {
0 => self.exit_file(), // file -> decls ruleset
1 => self.exit_decls(), // decls -> decl_iter
2 => self.exit_decl_iter(), // decl_iter -> <L> decl decl_iter
3 => {} // decl_iter -> <L> ε (not used)
4 => self.exit_decl(), // decl -> "token" decl_terminal decl_1 ";"
29 => self.exit_decl1(), // decl_1 -> "," decl_terminal decl_1
30 => {} // decl_1 -> ε
52 | // decl_terminal_1 -> "=" TerminalCst
53 => self.exit_decl_terminal(alt_id), // decl_terminal_1 -> ε
/* 5 */ // decl_terminal -> Terminal decl_terminal_1 (never called)
6 => self.exit_ruleset(), // ruleset -> rule_iter
7 => self.exit_rule_iter(), // rule_iter -> <L> rule rule_iter
8 => {} // rule_iter -> <L> ε (not used)
54 | // rule_1 -> "->" prs_expr ";"
55 => self.exit_rule(alt_id), // rule_1 -> "=>" rts_expr ";"
/* 9 */ // rule -> rule_nt rule_1 (never called)
10 => self.exit_rule_nt(), // rule_nt -> Nonterminal
11 | // rts_expr -> "&" rts_children
12 | // rts_expr -> "|" rts_children
13 | // rts_expr -> "+" rts_children
14 | // rts_expr -> "*" rts_children
15 | // rts_expr -> "?" rts_children
16 => self.exit_rts_expr(alt_id), // rts_expr -> item
17 => self.exit_rts_children(), // rts_children -> "(" rts_children_1 ")"
31 => self.exit_rts_children1(), // rts_children_1 -> rts_expr rts_children_1
32 => {} // rts_children_1 -> ε
33 | // prs_expr_1 -> "+" prs_expr_1
34 | // prs_expr_1 -> "*" prs_expr_1
35 | // prs_expr_1 -> "?" prs_expr_1
36 | // prs_expr_1 -> prs_expr_4 prs_expr_1
37 => self.exit_prs_expr1(alt_id), // prs_expr_1 -> "|" prs_expr_2 prs_expr_1
40 | // prs_expr_3 -> "+" prs_expr_3 (duplicate of 33)
46 => self.exit_prs_expr1(33), // prs_expr_5 -> "+" prs_expr_5 (duplicate of 33)
41 | // prs_expr_3 -> "*" prs_expr_3 (duplicate of 34)
47 => self.exit_prs_expr1(34), // prs_expr_5 -> "*" prs_expr_5 (duplicate of 34)
42 | // prs_expr_3 -> "?" prs_expr_3 (duplicate of 35)
48 => self.exit_prs_expr1(35), // prs_expr_5 -> "?" prs_expr_5 (duplicate of 35)
43 => self.exit_prs_expr1(36), // prs_expr_3 -> prs_expr_4 prs_expr_3 (duplicate of 36)
50 | // prs_expr_6 -> "(" prs_expr ")"
51 => self.exit_prs_expr6(alt_id), // prs_expr_6 -> item
18 => {} // prs_expr -> prs_expr_6 prs_expr_1 (not used)
38 => {} // prs_expr_1 -> ε (not used)
39 => {} // prs_expr_2 -> prs_expr_6 prs_expr_3 (not used)
44 => {} // prs_expr_3 -> ε (not used)
45 => {} // prs_expr_4 -> prs_expr_6 prs_expr_5 (not used)
49 => {} // prs_expr_5 -> ε (not used)
19 | // item -> Nonterminal
20 | // item -> NTx
21 | // item -> Terminal
22 | // item -> TerminalCst
23 | // item -> Tx
24 | // item -> Empty
25 | // item -> LTag
26 | // item -> "<P>"
27 | // item -> "<R>"
28 => self.exit_item(alt_id), // item -> "<G>"
_ => panic!("unexpected exit alternative id: {alt_id}")
}
}
Call::End(terminate) => {
match terminate {
Terminate::None => {
let val = self.stack.pop().unwrap().get_file();
self.listener.exit(val);
}
Terminate::Abort | Terminate::Conclude => self.listener.abort(terminate),
}
}
}
self.max_stack = std::cmp::max(self.max_stack, self.stack.len());
if self.verbose {
println!("> stack_t: {}", self.stack_t.join(", "));
println!("> stack: {}", self.stack.iter().map(|it| format!("{it:?}")).collect::<Vec<_>>().join(", "));
}
}
fn check_abort_request(&self) -> Terminate {
self.listener.check_abort_request()
}
fn abort(&mut self) {
self.stack.clear();
self.stack_t.clear();
}
fn get_log_mut(&mut self) -> &mut impl Logger {
self.listener.get_log_mut()
}
fn report(&mut self, span_opt: Option<&PosSpan>, msg: LogMsg) {
self.listener.handle_msg(span_opt, msg);
}
fn is_stack_empty(&self) -> bool {
self.stack.is_empty()
}
fn is_stack_t_empty(&self) -> bool {
self.stack_t.is_empty()
}
fn intercept_token(&mut self, token: TokenId, text: &str, _span: &PosSpan) -> TokenId {
self.listener.intercept_token(token, text)
}
}
impl<T: RtsGenListener> Wrapper<T> {
pub fn new(listener: T, verbose: bool) -> Self {
Wrapper { verbose, listener, stack: Vec::new(), max_stack: 0, stack_t: Vec::new() }
}
pub fn get_listener(&self) -> &T {
&self.listener
}
pub fn get_listener_mut(&mut self) -> &mut T {
&mut self.listener
}
pub fn give_listener(self) -> T {
self.listener
}
pub fn set_verbose(&mut self, verbose: bool) {
self.verbose = verbose;
}
fn exit_file(&mut self) {
let ruleset = self.stack.pop().unwrap().get_ruleset();
let decls = self.stack.pop().unwrap().get_decls();
let ctx = CtxFile::V1 { decls, ruleset };
let val = self.listener.exit_file(ctx);
self.stack.push(EnumSynValue::File(val));
}
fn exit_decls(&mut self) {
let ctx = CtxDecls::V1;
let val = self.listener.exit_decls(ctx);
self.stack.push(EnumSynValue::Decls(val));
}
fn exit_decl_iter(&mut self) {
let decl = self.stack.pop().unwrap().get_decl();
let ctx = CtxDeclIter::V1 { decl };
self.listener.exit_decl_iter(ctx);
}
fn exit_decl(&mut self) {
let star = self.stack.pop().unwrap().get_decl1();
let ctx = CtxDecl::V1 { star };
let val = self.listener.exit_decl(ctx);
self.stack.push(EnumSynValue::Decl(val));
}
fn init_decl1(&mut self) {
let decl_terminal = self.stack.pop().unwrap().get_decl_terminal();
self.stack.push(EnumSynValue::Decl1(SynDecl1(vec![decl_terminal])));
}
fn exit_decl1(&mut self) {
let decl_terminal = self.stack.pop().unwrap().get_decl_terminal();
let Some(EnumSynValue::Decl1(SynDecl1(star_acc))) = self.stack.last_mut() else {
panic!("expected SynDecl1 item on wrapper stack");
};
star_acc.push(decl_terminal);
}
fn exit_decl_terminal(&mut self, alt_id: AltId) {
let ctx = match alt_id {
52 => {
let terminalcst = self.stack_t.pop().unwrap();
let terminal = self.stack_t.pop().unwrap();
CtxDeclTerminal::V1 { terminal, terminalcst }
}
53 => {
let terminal = self.stack_t.pop().unwrap();
CtxDeclTerminal::V2 { terminal }
}
_ => panic!("unexpected alt id {alt_id} in fn exit_decl_terminal")
};
let val = self.listener.exit_decl_terminal(ctx);
self.stack.push(EnumSynValue::DeclTerminal(val));
}
fn exit_ruleset(&mut self) {
let ctx = CtxRuleset::V1;
let val = self.listener.exit_ruleset(ctx);
self.stack.push(EnumSynValue::Ruleset(val));
}
fn exit_rule_iter(&mut self) {
let rule = self.stack.pop().unwrap().get_rule();
let ctx = CtxRuleIter::V1 { rule };
self.listener.exit_rule_iter(ctx);
}
fn exit_rule(&mut self, alt_id: AltId) {
let ctx = match alt_id {
54 => {
let prs_expr = self.stack.pop().unwrap().get_prs_expr();
let rule_nt = self.stack.pop().unwrap().get_rule_nt();
CtxRule::V2 { rule_nt, prs_expr }
}
55 => {
let rts_expr = self.stack.pop().unwrap().get_rts_expr();
let rule_nt = self.stack.pop().unwrap().get_rule_nt();
CtxRule::V1 { rule_nt, rts_expr }
}
_ => panic!("unexpected alt id {alt_id} in fn exit_rule")
};
let val = self.listener.exit_rule(ctx);
self.stack.push(EnumSynValue::Rule(val));
}
fn exit_rule_nt(&mut self) {
let nonterminal = self.stack_t.pop().unwrap();
let ctx = CtxRuleNt::V1 { nonterminal };
let val = self.listener.exit_rule_nt(ctx);
self.stack.push(EnumSynValue::RuleNt(val));
}
fn exit_rts_expr(&mut self, alt_id: AltId) {
let ctx = match alt_id {
11 => {
let rts_children = self.stack.pop().unwrap().get_rts_children();
CtxRtsExpr::V1 { rts_children }
}
12 => {
let rts_children = self.stack.pop().unwrap().get_rts_children();
CtxRtsExpr::V2 { rts_children }
}
13 => {
let rts_children = self.stack.pop().unwrap().get_rts_children();
CtxRtsExpr::V3 { rts_children }
}
14 => {
let rts_children = self.stack.pop().unwrap().get_rts_children();
CtxRtsExpr::V4 { rts_children }
}
15 => {
let rts_children = self.stack.pop().unwrap().get_rts_children();
CtxRtsExpr::V5 { rts_children }
}
16 => {
let item = self.stack.pop().unwrap().get_item();
CtxRtsExpr::V6 { item }
}
_ => panic!("unexpected alt id {alt_id} in fn exit_rts_expr")
};
let val = self.listener.exit_rts_expr(ctx);
self.stack.push(EnumSynValue::RtsExpr(val));
}
fn exit_rts_children(&mut self) {
let star = self.stack.pop().unwrap().get_rts_children1();
let ctx = CtxRtsChildren::V1 { star };
let val = self.listener.exit_rts_children(ctx);
self.stack.push(EnumSynValue::RtsChildren(val));
}
fn init_rts_children1(&mut self) {
let val = SynRtsChildren1(Vec::new());
self.stack.push(EnumSynValue::RtsChildren1(val));
}
fn exit_rts_children1(&mut self) {
let rts_expr = self.stack.pop().unwrap().get_rts_expr();
let Some(EnumSynValue::RtsChildren1(SynRtsChildren1(star_acc))) = self.stack.last_mut() else {
panic!("expected SynRtsChildren1 item on wrapper stack");
};
star_acc.push(rts_expr);
}
fn exit_prs_expr1(&mut self, alt_id: AltId) {
let ctx = match alt_id {
33 => {
let prs_expr = self.stack.pop().unwrap().get_prs_expr();
CtxPrsExpr::V1 { prs_expr }
}
34 => {
let prs_expr = self.stack.pop().unwrap().get_prs_expr();
CtxPrsExpr::V2 { prs_expr }
}
35 => {
let prs_expr = self.stack.pop().unwrap().get_prs_expr();
CtxPrsExpr::V3 { prs_expr }
}
36 => {
let prs_expr_2 = self.stack.pop().unwrap().get_prs_expr();
let prs_expr_1 = self.stack.pop().unwrap().get_prs_expr();
CtxPrsExpr::V4 { prs_expr: [prs_expr_1, prs_expr_2] }
}
37 => {
let prs_expr_2 = self.stack.pop().unwrap().get_prs_expr();
let prs_expr_1 = self.stack.pop().unwrap().get_prs_expr();
CtxPrsExpr::V5 { prs_expr: [prs_expr_1, prs_expr_2] }
}
_ => panic!("unexpected alt id {alt_id} in fn exit_prs_expr1")
};
let val = self.listener.exit_prs_expr(ctx);
self.stack.push(EnumSynValue::PrsExpr(val));
}
fn exit_prs_expr6(&mut self, alt_id: AltId) {
let ctx = match alt_id {
50 => {
let prs_expr = self.stack.pop().unwrap().get_prs_expr();
CtxPrsExpr::V6 { prs_expr }
}
51 => {
let item = self.stack.pop().unwrap().get_item();
CtxPrsExpr::V7 { item }
}
_ => panic!("unexpected alt id {alt_id} in fn exit_prs_expr6")
};
let val = self.listener.exit_prs_expr(ctx);
self.stack.push(EnumSynValue::PrsExpr(val));
}
fn exit_item(&mut self, alt_id: AltId) {
let ctx = match alt_id {
19 => {
let nonterminal = self.stack_t.pop().unwrap();
CtxItem::V1 { nonterminal }
}
20 => {
let ntx = self.stack_t.pop().unwrap();
CtxItem::V2 { ntx }
}
21 => {
let terminal = self.stack_t.pop().unwrap();
CtxItem::V3 { terminal }
}
22 => {
let terminalcst = self.stack_t.pop().unwrap();
CtxItem::V4 { terminalcst }
}
23 => {
let tx = self.stack_t.pop().unwrap();
CtxItem::V5 { tx }
}
24 => {
let empty = self.stack_t.pop().unwrap();
CtxItem::V6 { empty }
}
25 => {
let ltag = self.stack_t.pop().unwrap();
CtxItem::V7 { ltag }
}
26 => {
CtxItem::V8
}
27 => {
CtxItem::V9
}
28 => {
CtxItem::V10
}
_ => panic!("unexpected alt id {alt_id} in fn exit_item")
};
let val = self.listener.exit_item(ctx);
self.stack.push(EnumSynValue::Item(val));
}
}
// [rtsgen_parser]
}
// -------------------------------------------------------------------------