1use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque};
4use iter_index::IndexerIterator;
5use vectree::VecTree;
6use lexigram_core::alt::Alternative;
7use lexigram_core::log::LogMsg;
8use lexigram_core::TokenId;
9use crate::grammar::{grtree_to_str, GrTreeExt, LLParsingTable, NTConversion, ProdRuleSet};
10use crate::{columns_to_str, indent_source, AltId, CharLen, NameFixer, NameTransformer, SourceSpacer, StructLibs, SymbolTable, VarId, LL1};
11use crate::fixed_sym_table::{FixedSymTable, SymInfoTable};
12use crate::alt::ruleflag;
13use crate::build::{BuildError, BuildErrorSource, BuildFrom, HasBuildErrorSource, TryBuildFrom};
14use crate::CollectJoin;
15use crate::grammar::origin::{FromPRS, Origin};
16use crate::lexergen::LexigramCrate;
17use crate::log::{BufLog, LogReader, LogStatus, Logger};
18use crate::parser::{OpCode, Parser, Symbol};
19use crate::segments::Segments;
20use crate::segmap::Seg;
21
22pub(crate) mod tests;
23
24pub(crate) fn symbol_to_code(s: &Symbol) -> String {
27 match s {
28 Symbol::Empty => "Symbol::Empty".to_string(),
29 Symbol::T(t) => format!("Symbol::T({t})"),
30 Symbol::NT(nt) => format!("Symbol::NT({nt})"),
31 Symbol::End => "Symbol::End".to_string(),
32 }
33}
34
35#[derive(Clone, Debug, PartialEq)]
38struct ItemInfo {
39 name: String,
40 sym: Symbol, owner: VarId, index: Option<usize> }
44
45#[allow(unused)]
46impl ItemInfo {
47 fn to_str(&self, symbol_table: Option<&SymbolTable>) -> String {
48 format!("{} ({}{}, ◄{})",
49 self.name,
50 self.sym.to_str(symbol_table),
51 if let Some(n) = self.index { format!(", [{n}]") } else { "".to_string() },
52 Symbol::NT(self.owner).to_str(symbol_table))
53 }
54}
55
56pub struct ParserTables {
66 num_nt: usize,
67 num_t: usize,
68 alt_var: Vec<VarId>,
70 alts: Vec<Alternative>,
71 opcodes: Vec<Vec<OpCode>>,
72 init_opcodes: Vec<OpCode>,
73 table: Vec<AltId>,
74 symbol_table: FixedSymTable,
75 start: VarId,
76 include_alts: bool,
77}
78
79impl ParserTables {
80 pub fn new(
81 parsing_table: LLParsingTable,
82 symbol_table: FixedSymTable,
83 opcodes: Vec<Vec<OpCode>>,
84 init_opcodes: Vec<OpCode>,
85 start: VarId,
86 include_alts: bool
87 ) -> Self {
88 assert!(parsing_table.num_nt > start as usize);
89 let num_nt = parsing_table.num_nt;
90 let num_t = parsing_table.num_t;
91 let table = parsing_table.table;
92 let (factor_var, alts): (Vec<_>, Vec<_>) = parsing_table.alts.into_iter().unzip();
93 ParserTables { num_nt, num_t, alt_var: factor_var, alts, opcodes, init_opcodes, table, symbol_table, start, include_alts }
94 }
95
96 pub fn make_parser(&self) -> Parser<'_> {
97 Parser::new(
98 self.num_nt,
99 self.num_t,
100 self.alt_var.as_slice(),
101 if self.include_alts { self.alts.clone() } else { vec![] },
102 self.opcodes.clone(),
103 self.init_opcodes.clone(),
104 self.table.as_slice(),
105 self.symbol_table.clone(),
106 self.start,
107 )
108 }
109}
110
111impl BuildFrom<ParserGen> for ParserTables {
112 fn build_from(parser_gen: ParserGen) -> Self {
115 ParserTables::new(
116 parser_gen.parsing_table,
117 parser_gen.symbol_table.to_fixed_sym_table(),
118 parser_gen.opcodes,
119 parser_gen.init_opcodes,
120 parser_gen.start,
121 parser_gen.include_alts
122 )
123 }
124}
125
126impl TryBuildFrom<ParserGen> for ParserTables {
128 type Error = BuildError;
129
130 fn try_build_from(source: ParserGen) -> Result<Self, Self::Error> {
131 if source.get_log().has_no_errors() {
132 Ok(ParserTables::build_from(source))
133 } else {
134 Err(BuildError::new(source.give_log(), BuildErrorSource::ParserGen))
135 }
136 }
137}
138
139#[derive(Clone, PartialEq, Debug)]
150pub enum NTValue {
151 None,
153 Parents,
155 Default,
157 SetIds(Vec<VarId>),
159 SetNames(Vec<String>),
161}
162
163impl NTValue {
164 pub const DEFAULT: &str = "<default>";
166 pub const PARENTS: &str = "<parents>";
168
169 pub fn is_none(&self) -> bool {
170 matches!(self, NTValue::None)
171 }
172
173 pub fn is_parents(&self) -> bool {
174 matches!(self, NTValue::Parents)
175 }
176
177 pub fn is_default(&self) -> bool {
178 matches!(self, NTValue::Default)
179 }
180
181 pub fn is_ids(&self) -> bool {
182 matches!(self, NTValue::SetIds(_))
183 }
184
185 pub fn is_names(&self) -> bool {
186 matches!(self, NTValue::SetNames(_))
187 }
188}
189
190pub static DEFAULT_LISTENER_NAME: &str = "Parser";
193
194pub type SpanNbr = u16;
195
196fn count_span_nbr(opcode: &[OpCode]) -> SpanNbr {
197 let count = opcode.iter().filter(|op| op.has_span()).count();
198 count.try_into().unwrap_or_else(|_| panic!("# span = {count} > {}", SpanNbr::MAX))
199}
200
201#[derive(Debug)]
202pub struct ParserGen {
203 parsing_table: LLParsingTable,
204 symbol_table: SymbolTable,
205 terminal_hooks: Vec<TokenId>,
206 name: String,
207 nt_value: Vec<bool>,
208 nt_parent: Vec<Vec<VarId>>,
210 var_alts: Vec<Vec<AltId>>,
211 origin: Origin<VarId, FromPRS>,
212 item_ops: Vec<Vec<Symbol>>,
213 opcodes: Vec<Vec<OpCode>>,
214 init_opcodes: Vec<OpCode>,
215 gen_parser: bool,
217 gen_wrapper: bool,
219 indent: usize,
221 types_indent: usize,
223 listener_indent: usize,
225 gen_span_params: bool,
227 gen_token_enums: bool,
228 span_nbrs: Vec<SpanNbr>,
229 span_nbrs_sep_list: HashMap<AltId, SpanNbr>,
231 start: VarId,
232 nt_conversion: HashMap<VarId, NTConversion>,
233 headers: Vec<String>,
234 used_libs: StructLibs,
235 nt_type: HashMap<VarId, String>,
236 nt_extra_info: HashMap<VarId, (String, Vec<String>)>,
237 log: BufLog,
238 include_alts: bool,
239 lib_crate: LexigramCrate,
240}
241
242impl ParserGen {
243 pub fn build_from_rules<T>(mut rules: ProdRuleSet<T>, name: String) -> Self
249 where
250 ProdRuleSet<LL1>: BuildFrom<ProdRuleSet<T>>,
251 {
252 rules.log.add_note("building parser gen from rules...");
253 let mut ll1_rules = ProdRuleSet::<LL1>::build_from(rules);
254 assert_eq!(ll1_rules.get_log().num_errors(), 0);
255 let parsing_table = ll1_rules.make_parsing_table(true);
256 let num_nt = ll1_rules.get_num_nt();
257 let start = ll1_rules.get_start().unwrap();
258 let mut var_alts = vec![vec![]; num_nt];
259 for (alt_id, (var_id, _)) in parsing_table.alts.iter().index() {
260 var_alts[*var_id as usize].push(alt_id);
261 }
262 let mut nt_parent: Vec<Vec<VarId>> = vec![vec![]; num_nt];
263 for var_id in 0..num_nt {
264 let top_var_id = parsing_table.get_top_parent(var_id as VarId) as usize;
265 nt_parent[top_var_id].push(var_id as VarId);
266 }
267 let ProdRuleSet { symbol_table, nt_conversion, origin, .. } = ll1_rules;
268 let mut builder = ParserGen {
269 parsing_table,
270 symbol_table: symbol_table.expect(stringify!("symbol table is required to create a {}", std::any::type_name::<Self>())),
271 gen_span_params: false,
272 gen_token_enums: false,
273 name,
274 nt_value: vec![false; num_nt],
275 nt_parent,
276 var_alts,
277 origin,
278 terminal_hooks: Vec::new(),
279 item_ops: Vec::new(),
280 opcodes: Vec::new(),
281 init_opcodes: Vec::new(),
282 gen_parser: true,
283 gen_wrapper: true,
284 indent: 0,
285 types_indent: 0,
286 listener_indent: 0,
287 span_nbrs: Vec::new(),
288 span_nbrs_sep_list: HashMap::new(),
289 start,
290 nt_conversion,
291 headers: Vec::new(),
292 used_libs: StructLibs::new(),
293 nt_type: HashMap::new(),
294 nt_extra_info: HashMap::new(),
295 log: ll1_rules.log,
296 include_alts: false,
297 lib_crate: LexigramCrate::Core,
298 };
299 builder.make_opcodes();
300 builder.make_span_nbrs();
301 builder
302 }
303
304 pub fn set_name(&mut self, name: String) {
305 self.name = name;
306 }
307
308 pub fn get_name(&self) -> &str {
309 &self.name
310 }
311
312 #[inline]
313 pub fn get_symbol_table(&self) -> Option<&SymbolTable> {
314 Some(&self.symbol_table)
315 }
316
317 #[inline]
318 pub fn get_parsing_table(&self) -> &LLParsingTable {
319 &self.parsing_table
320 }
321
322 #[inline]
323 pub fn set_terminal_hooks(&mut self, terminal_hooks: Vec<TokenId>) {
324 if !terminal_hooks.is_empty() {
325 self.gen_token_enums = true;
326 }
327 self.terminal_hooks = terminal_hooks;
328 self.add_opcode_hooks();
329 }
330
331 #[inline]
332 pub fn add_header<T: Into<String>>(&mut self, header: T) {
333 self.headers.push(header.into());
334 }
335
336 #[inline]
337 pub fn extend_headers<I: IntoIterator<Item=T>, T: Into<String>>(&mut self, headers: I) {
338 self.headers.extend(headers.into_iter().map(|s| s.into()));
339 }
340
341 #[inline]
342 pub fn add_lib<T: Into<String>>(&mut self, lib:T) {
343 self.used_libs.add(lib);
344 }
345
346 #[inline]
347 pub fn extend_libs<I: IntoIterator<Item=T>, T: Into<String>>(&mut self, libs: I) {
348 self.used_libs.extend(libs);
349 }
350
351 #[inline]
352 pub fn add_nt_type<T: Into<String>>(&mut self, org_var: VarId, var_type: T) {
355 let var = self.conv_nt(org_var).unwrap_or_else(|| panic!("var {org_var} doesn't exist"));
356 self.nt_type.insert(var, var_type.into());
357 }
358
359 #[inline]
360 pub fn get_nt_type(&self, v: VarId) -> &str {
361 self.nt_type.get(&v).unwrap().as_str()
362 }
363
364 #[inline]
365 pub fn get_nt_extra_info(&self, nt: VarId) -> Option<&(String, Vec<String>)> {
379 self.nt_extra_info.get(&nt)
380 }
381
382 pub fn set_nt_value(&mut self, nt_value: &NTValue) {
384 let num_nt = self.get_symbol_table().unwrap().get_num_nt() as VarId;
385 let mut stack = vec![nt_value];
386 let mut neg_stack = vec![];
387 while let Some(nt_value) = stack.pop() {
388 match nt_value {
389 NTValue::None => {}
390 NTValue::Parents => {
391 for v in 0..num_nt {
392 if self.get_nt_parent(v).is_none() {
393 self.nt_value[v as usize] = true;
394 }
395 }
396 }
397 NTValue::Default => {
398 for v in 0..num_nt {
399 if self.get_nt_parent(v).is_none() || self.nt_has_all_flags(v, ruleflag::CHILD_REPEAT | ruleflag::L_FORM) {
400 self.nt_value[v as usize] = true;
401 }
402 }
403 }
404 NTValue::SetIds(ids) => {
405 for v in ids {
406 if *v < num_nt {
407 self.nt_value[*v as usize] = true;
408 } else {
409 self.log.add_error(format!("setting value of NT #{v}, which doesn't exist"));
410 }
411 }
412 }
413 NTValue::SetNames(names) => {
414 let name_to_id = self.symbol_table.get_nonterminals().index::<VarId>()
415 .map(|(v, name)| (name.as_str(), v))
416 .collect::<HashMap<&str, VarId>>();
417 for name in names {
418 match name.as_str() {
419 NTValue::DEFAULT => stack.push(&NTValue::Default),
420 NTValue::PARENTS => stack.push(&NTValue::Parents),
421 mut nt_name => {
422 let add = if !nt_name.starts_with('-') {
423 true
424 } else {
425 nt_name = &nt_name[1..];
426 false
427 };
428 if let Some(v) = name_to_id.get(nt_name) {
429 if add {
430 self.nt_value[*v as usize] = true;
431 } else {
432 neg_stack.push(*v);
433 }
434 } else {
435 self.log.add_error(format!("setting value of NT '{name}', which doesn't exist"));
436 }
437 }
438 }
439 }
440 }
441 }
442 }
443 for v in neg_stack {
444 self.nt_value[v as usize] = false;
445 }
446 }
447
448 #[inline]
449 pub fn set_nt_has_value(&mut self, v: VarId, has_value: bool) {
450 self.nt_value[v as usize] = has_value;
451 }
452
453 pub fn set_gen_parser(&mut self, gen_parser: bool) {
455 self.gen_parser = gen_parser;
456 }
457
458 pub fn set_gen_wrapper(&mut self, gen_wrapper: bool) {
460 self.gen_wrapper = gen_wrapper;
461 }
462
463 pub fn set_indent(&mut self, indent: usize) {
465 self.indent = indent;
466 }
467
468 pub fn set_types_indent(&mut self, indent: usize) {
471 self.types_indent = indent;
472 }
473
474 pub fn set_listener_indent(&mut self, indent: usize) {
477 self.listener_indent = indent;
478 }
479
480 pub fn set_indents(&mut self, wrapper: usize, types: usize, listner: usize) {
483 self.indent = wrapper;
484 self.types_indent = types;
485 self.listener_indent = listner;
486 }
487
488 pub fn set_gen_span_params(&mut self, gen_span_params: bool) {
490 self.gen_span_params = gen_span_params;
491 }
492
493 pub fn set_gen_token_enums(&mut self, gen_token_enums: bool) {
514 self.gen_token_enums = gen_token_enums;
515 }
516
517 #[inline]
518 pub fn get_nt_parent(&self, v: VarId) -> Option<VarId> {
519 self.parsing_table.parent[v as usize]
520 }
521
522 pub fn set_include_alts(&mut self, include_alts: bool) {
525 self.include_alts = include_alts;
526 }
527
528 #[inline]
529 pub fn use_full_lib(&mut self, use_full_lib: bool) {
530 self.lib_crate = if use_full_lib { LexigramCrate::Full } else { LexigramCrate::Core };
531 }
532
533 #[inline]
534 pub fn set_crate(&mut self, lcrate: LexigramCrate) {
535 self.lib_crate = lcrate;
536 }
537
538 #[cfg(test)] fn get_original_alt_str(&self, a_id: AltId, symbol_table: Option<&SymbolTable>) -> Option<String> {
540 let (_var, f) = &self.parsing_table.alts[a_id as usize];
541 f.get_origin().and_then(|(o_v, o_id)| {
542 Some(format!(
543 "{} -> {}",
544 Symbol::NT(o_v).to_str(symbol_table),
545 grtree_to_str(self.origin.get_tree(o_v).unwrap(), Some(o_id), None, Some(o_v), symbol_table, false)
546 ))
547 })
548 }
549
550 fn conv_nt(&self, org_var: VarId) -> Option<VarId> {
556 match self.nt_conversion.get(&org_var) {
557 None => if (org_var as usize) < self.parsing_table.num_nt { Some(org_var) } else { None },
558 Some(NTConversion::MovedTo(new)) => Some(*new),
559 Some(NTConversion::Removed) => None
560 }
561 }
562
563 #[allow(unused)]
564 fn nt_has_all_flags(&self, var: VarId, flags: u32) -> bool {
565 self.parsing_table.flags[var as usize] & flags == flags
566 }
567
568 #[allow(unused)]
569 fn nt_has_any_flags(&self, var: VarId, flags: u32) -> bool {
570 self.parsing_table.flags[var as usize] & flags != 0
571 }
572
573 #[allow(unused)]
574 fn sym_has_flags(&self, s: &Symbol, flags: u32) -> bool {
575 if let Symbol::NT(nt) = s { self.nt_has_all_flags(*nt, flags) } else { false }
576 }
577
578 #[allow(unused)]
579 fn sym_has_value(&self, symbol: &Symbol) -> bool {
580 match symbol {
581 Symbol::T(t) => self.symbol_table.is_token_data(*t),
582 Symbol::NT(nt) => self.nt_value[*nt as usize],
583 _ => false
584 }
585 }
586
587 fn full_alt_components(&self, a_id: AltId, emphasis: Option<VarId>) -> (String, String) {
588 const VERBOSE: bool = false;
589 if VERBOSE { println!("full_alt_components(a_id = {a_id}):"); }
590 let &(mut v_a, ref alt) = &self.parsing_table.alts[a_id as usize];
591 while self.parsing_table.flags[v_a as usize] & ruleflag::CHILD_L_FACT != 0 {
592 v_a = *self.parsing_table.parent[v_a as usize].as_ref().unwrap();
593 }
594 let symtab = self.get_symbol_table();
595 if let Some(v_emph) = emphasis {
596 let parent_nt = self.parsing_table.get_top_parent(v_emph);
597 if let Some((t_emph, id_emph)) = self.origin.get(v_emph) {
598 return ((Symbol::NT(parent_nt).to_str(symtab)), grtree_to_str(t_emph, None, Some(id_emph), Some(parent_nt), symtab, true));
599 } else {
600 return (Symbol::NT(parent_nt).to_str(symtab), format!("<VAR {v_emph} NOT FOUND>"));
601 }
602 }
603 if let Some((vo, id)) = alt.get_origin() {
604 let t = self.origin.get_tree(vo).unwrap();
605 let flags = self.parsing_table.flags[v_a as usize];
606 if v_a != vo && flags & ruleflag::CHILD_REPEAT != 0 {
607 (
609 String::new(),
610 format!("`{}` {} in `{} -> {}`",
611 grtree_to_str(t, Some(id), None, Some(vo), symtab, true),
612 if flags & ruleflag::L_FORM != 0 { "iteration" } else { "item" },
613 Symbol::NT(vo).to_str(symtab),
614 grtree_to_str(t, None, Some(id), Some(vo), symtab, true))
615 )
616 } else {
617 let root = Some(id);
618 (Symbol::NT(vo).to_str(symtab), grtree_to_str(t, root, None, Some(vo), symtab, true))
619 }
620 } else {
621 (Symbol::NT(v_a).to_str(symtab), format!("<alt {a_id} NOT FOUND>"))
622 }
623 }
624
625 fn full_alt_str(&self, a_id: AltId, emphasis: Option<VarId>, quote: bool) -> String {
627 let (left, right) = self.full_alt_components(a_id, emphasis);
628 if left.is_empty() {
629 right
630 } else {
631 format!("{q}{left} -> {right}{q}", q = if quote { "`" } else { "" })
632 }
633 }
634
635 fn make_opcodes(&mut self) {
636 const VERBOSE: bool = false;
637 self.log.add_note("- making opcodes...");
638 self.opcodes.clear();
639 self.init_opcodes = vec![OpCode::End, OpCode::NT(self.start)];
640 for (alt_id, (var_id, alt)) in self.parsing_table.alts.iter().index() {
641 if VERBOSE {
642 println!("{alt_id}: {}", alt.to_rule_str(*var_id, self.get_symbol_table(), 0));
643 }
644 let flags = self.parsing_table.flags[*var_id as usize];
645 let stack_sym = Symbol::NT(*var_id);
646 let mut new = self.parsing_table.alts[alt_id as usize].1.iter().filter(|s| !s.is_empty()).rev().cloned().to_vec();
647 if VERBOSE { println!(" - {}", new.iter().map(|s| s.to_str(self.get_symbol_table())).join(" ")); }
648 let mut opcode = Vec::<OpCode>::new();
649 let mut parent = self.parsing_table.parent[*var_id as usize];
650 if flags & ruleflag::CHILD_L_FACT != 0 {
651 while self.nt_has_all_flags(parent.unwrap(), ruleflag::CHILD_L_FACT) {
652 parent = self.parsing_table.parent[parent.unwrap() as usize];
653 }
654 let parent = parent.unwrap();
655 let parent_r_form_right_rec = self.parsing_table.flags[parent as usize] & ruleflag::R_RECURSION != 0 && flags & ruleflag::L_FORM == 0;
659 if VERBOSE {
660 println!(" - child lfact, parent: {}, !parent_r_form_right_rec = !{parent_r_form_right_rec}, match = {}",
661 Symbol::NT(parent).to_str(self.get_symbol_table()),
662 new.first() == Some(&Symbol::NT(parent)));
663 }
664 if new.first() == Some(&Symbol::NT(parent)) && !parent_r_form_right_rec {
665 opcode.push(OpCode::Loop(parent));
666 new.remove(0);
667 }
668 }
669 let parent_lrec_no_lfact = flags & (ruleflag::PARENT_L_RECURSION | ruleflag::PARENT_L_FACTOR) == ruleflag::PARENT_L_RECURSION;
670 if flags & ruleflag::PARENT_L_FACTOR == 0 ||
671 parent_lrec_no_lfact ||
672 new.iter().all(|s| if let Symbol::NT(ch) = s { !self.nt_has_all_flags(*ch, ruleflag::CHILD_L_FACT) } else { true })
673 {
674 opcode.push(OpCode::Exit(alt_id)); }
683 opcode.extend(new.into_iter().map(OpCode::from));
684 let r_form_right_rec = flags & ruleflag::R_RECURSION != 0 && flags & ruleflag::L_FORM == 0;
685 if VERBOSE { println!(" - r_form_right_rec = {r_form_right_rec} = {} || {}",
686 flags & ruleflag::R_RECURSION != 0 && flags & ruleflag::L_FORM == 0,
687 flags & ruleflag::CHILD_L_FACT != 0 && self.parsing_table.flags[parent.unwrap() as usize] & ruleflag::R_RECURSION != 0 && flags & ruleflag::L_FORM == 0); }
688 if opcode.get(1).map(|op| op.matches(stack_sym)).unwrap_or(false) && !r_form_right_rec {
689 opcode.swap(0, 1);
692 if VERBOSE { println!(" - swap 0, 1: {}", opcode.iter().map(|s| s.to_str(self.get_symbol_table())).join(" ")); }
693 } else if parent_lrec_no_lfact {
694 if let Some(OpCode::NT(x)) = opcode.get(1) {
695 if self.nt_has_all_flags(*x, ruleflag::CHILD_L_RECURSION) {
696 opcode.swap(0, 1);
699 if VERBOSE { println!(" - swap 0, 1: {}", opcode.iter().map(|s| s.to_str(self.get_symbol_table())).join(" ")); }
700 }
701 }
702 } else if flags & ruleflag::CHILD_INDEPENDENT_AMBIGUITY != 0 && opcode.len() > 1 {
703 if let Some(OpCode::NT(var_prime)) = opcode.get(1) {
705 let vp = *var_prime; if self.nt_has_all_flags(vp, ruleflag::CHILD_AMBIGUITY) {
707 opcode.swap(0, 1);
708 opcode[0] = OpCode::Loop(vp);
709 if VERBOSE { println!(" - child indep ambig: {}", opcode.iter().map(|s| s.to_str(self.get_symbol_table())).join(" ")); }
710 }
711 }
712 }
713 if flags & ruleflag::CHILD_L_FACT != 0 && opcode.len() >= 2 {
714 if self.nt_has_all_flags(parent.unwrap(), ruleflag::R_RECURSION | ruleflag::L_FORM)
715 && opcode[1] == OpCode::NT(parent.unwrap())
716 {
717 opcode.swap(0, 1);
718 opcode[0] = OpCode::Loop(parent.unwrap());
719 }
720 let fact_top = self.parsing_table.get_top_parent(*var_id);
721 if VERBOSE {
722 println!(" - check for initial exit swap: opcode = [{}], daddy = {}",
723 opcode.iter().map(|s| s.to_str(self.get_symbol_table())).join(" "),
724 Symbol::NT(fact_top).to_str(self.get_symbol_table()));
725 }
726 if self.parsing_table.flags[fact_top as usize] & ruleflag::PARENT_L_RECURSION != 0 &&
727 matches!(opcode[0], OpCode::Exit(_)) &&
728 matches!(opcode[1], OpCode::NT(v) if self.parsing_table.flags[v as usize] & ruleflag::CHILD_L_RECURSION != 0)
729 {
730 if VERBOSE {
731 println!(" swapping for initial exit_{}: {} <-> {}",
732 Symbol::NT(fact_top).to_str(self.get_symbol_table()).to_lowercase(),
733 opcode[0].to_str(self.get_symbol_table()),
734 opcode[1].to_str(self.get_symbol_table())
735 );
736 }
737 opcode.swap(0, 1);
738 }
739 }
740 opcode.iter_mut().for_each(|o| {
741 if let OpCode::NT(v) = o {
742 if v == var_id && !r_form_right_rec {
745 *o = OpCode::Loop(*v)
746 }
747 }
748 });
749 if VERBOSE { println!(" -> {}", opcode.iter().map(|s| s.to_str(self.get_symbol_table())).join(" ")); }
750 self.opcodes.push(opcode);
751 }
752 }
753
754 fn add_opcode_hooks(&mut self) {
794 const VERBOSE: bool = false;
795 self.log.add_note("- adding hooks into opcodes...");
796 let hooks: HashSet<TokenId> = self.terminal_hooks.iter().cloned().collect();
797 let num_nt = self.parsing_table.num_nt;
798 let num_t = self.parsing_table.num_t;
799 let err = self.parsing_table.alts.len() as AltId;
800 if VERBOSE {
801 self.parsing_table.print(self.get_symbol_table(), 0);
802 println!("num_nt = {num_nt}\nnum_t = {num_t}\ntable: {}", self.parsing_table.table.len());
803 }
804 if VERBOSE { println!("hooks: {}", self.terminal_hooks.iter().map(|t| self.symbol_table.get_t_name(*t)).join(", ")); }
805 let deps: HashSet<VarId> = (0..num_nt as VarId)
806 .filter(|&nt| hooks.iter().any(|&t| self.parsing_table.table[nt as usize * num_t + t as usize] < err))
807 .collect();
808 if VERBOSE { println!("deps = {deps:?} = {}", deps.iter().map(|nt| self.symbol_table.get_nt_name(*nt)).join(", ")); }
809
810 if deps.contains(&self.start) {
812 self.init_opcodes = vec![OpCode::End, OpCode::NT(self.start), OpCode::Hook];
813 }
814 let mut changed = false;
815 for opcodes in self.opcodes.iter_mut() {
816 let mut new = vec![];
817 let n = opcodes.len();
818 for op in &opcodes[..n - 1] {
819 new.push(*op);
820 match op {
821 OpCode::T(t) if hooks.contains(t) => {
822 new.push(OpCode::Hook);
823 }
824 OpCode::NT(nt) | OpCode::Loop(nt) if deps.contains(nt) => {
825 new.push(OpCode::Hook);
826 }
827 _ => {}
828 }
829 }
830 if new.len() + 1 > n {
831 new.push(opcodes[n - 1]);
832 *opcodes = new;
833 changed = true;
834 }
835 }
836 if VERBOSE && changed {
837 println!("new opcodes:");
838 let mut cols = vec![];
839 let tbl = self.get_symbol_table();
840 for (i, (opcodes, (nt, alt))) in self.opcodes.iter().zip(&self.parsing_table.alts).enumerate() {
841 cols.push(vec![
842 i.to_string(),
843 format!("{} -> ", Symbol::NT(*nt).to_str(tbl)),
844 alt.to_str(tbl),
845 opcodes.iter().map(|op| op.to_str(tbl)).join(" "),
846 ]);
847 }
848 println!("{}", indent_source(vec![columns_to_str(cols, None)], 4))
849 }
850 }
851
852 fn make_span_nbrs(&mut self) {
853 self.log.add_note("- making spans...");
854 let mut span_nbrs = vec![0 as SpanNbr; self.parsing_table.alts.len()];
855 for (alt_id, (var_id, _)) in self.parsing_table.alts.iter().enumerate() {
856 let opcode = &self.opcodes[alt_id];
857 let mut span_nbr = span_nbrs[alt_id] + count_span_nbr(opcode);
858 if self.nt_has_any_flags(*var_id, ruleflag::CHILD_REPEAT | ruleflag::CHILD_L_RECURSION) ||
859 self.nt_has_all_flags(*var_id, ruleflag::R_RECURSION | ruleflag::L_FORM) {
860 span_nbr += 1;
862 }
863 if matches!(opcode.first(), Some(OpCode::NT(nt)) if nt != var_id && self.parsing_table.flags[*nt as usize] & ruleflag::CHILD_L_RECURSION != 0) {
864 span_nbr -= 1;
866 }
867 if self.nt_has_all_flags(*var_id, ruleflag::PARENT_L_FACTOR) {
871 if let Some(OpCode::NT(nt)) = opcode.first() {
872 span_nbr -= 1;
873 for a_id in self.var_alts[*nt as usize].iter() {
874 span_nbrs[*a_id as usize] += span_nbr;
875 }
877 span_nbr = 0;
879 }
880 }
881 span_nbrs[alt_id] = span_nbr;
882 }
883 self.span_nbrs = span_nbrs;
884 }
885
886 fn get_group_alts(&self, g: &[VarId]) -> Vec<(VarId, AltId)> {
887 g.iter().flat_map(|c|
888 self.var_alts[*c as usize].iter().map(|a| (*c, *a))
889 ).collect::<Vec<_>>()
890 }
891
892 fn gather_alts(&self, nt: VarId) -> Vec<AltId> {
896 const VERBOSE: bool = false;
897 let mut alt = vec![];
898 let mut explore = VecDeque::<VarId>::new();
899 explore.push_back(nt);
900 while !explore.is_empty() {
901 let var = explore.pop_front().unwrap();
902 if VERBOSE { println!("{var}: alt = {} | explore = {} | alts: {}",
903 alt.iter().join(", "), explore.iter().join(", "),
904 &self.var_alts[var as usize].iter().join(", ")); }
905 for a in &self.var_alts[var as usize] {
906 let (_, alter) = &self.parsing_table.alts[*a as usize];
907 if let Some(Symbol::NT(last)) = alter.symbols().last() {
908 if self.nt_has_all_flags(*last, ruleflag::CHILD_L_FACT) {
909 explore.push_back(*last);
911 continue;
912 }
913 }
914 alt.push(*a);
915 }
916 if VERBOSE { println!(" => alt = {} | explore = {}", alt.iter().join(", "), explore.iter().join(", ")); }
917 }
918 alt
919 }
920
921 fn calc_nt_value(&mut self) {
922 const VERBOSE: bool = false;
923 self.log.add_note("- calculating nonterminals' value...");
924 for g in self.nt_parent.iter().filter(|va| !va.is_empty()) {
926 let group = self.get_group_alts(g);
928 let mut re_evaluate = true;
929 let g_top = g[0];
930 let is_ambig = self.nt_has_all_flags(g_top, ruleflag::PARENT_AMBIGUITY);
931 while re_evaluate {
932 re_evaluate = false;
933 let mut nt_used = HashSet::<VarId>::new();
934 if VERBOSE {
935 let ids = group.iter().map(|(v, _)| *v).collect::<BTreeSet<VarId>>();
936 println!("parent: {}, NT with value: {}",
937 Symbol::NT(g[0]).to_str(self.get_symbol_table()),
938 ids.into_iter().filter_map(|v|
939 if self.nt_value[v as usize] { Some(Symbol::NT(v as VarId).to_str(self.get_symbol_table())) } else { None }
940 ).join(", "));
941 }
942 for (var_id, alt_id) in &group {
943 let mut has_value = false;
945 for s in &self.opcodes[*alt_id as usize] {
946 match s {
947 OpCode::T(t) =>
948 has_value |= self.symbol_table.is_token_data(*t),
949 OpCode::NT(nt) => {
950 let is_ambig_top = is_ambig && self.get_nt_parent(*nt) == Some(g_top)
951 && !self.nt_has_any_flags(*nt, ruleflag::CHILD_L_RECURSION | ruleflag::CHILD_REPEAT);
952 let var = if is_ambig_top { g_top } else { *nt };
953 nt_used.insert(var);
954 has_value |= self.nt_value[var as usize]
955 },
956 _ => {}
957 }
958 }
959 if has_value && self.parsing_table.parent[*var_id as usize].is_some() {
961 let mut child_nt = *var_id as usize;
963 while self.parsing_table.flags[child_nt] & ruleflag::CHILD_REPEAT == 0 {
964 if let Some(parent) = self.parsing_table.parent[child_nt] {
965 child_nt = parent as usize;
966 } else {
967 break;
968 }
969 }
970 if self.parsing_table.flags[child_nt] & (ruleflag::CHILD_REPEAT | ruleflag::L_FORM) == ruleflag::CHILD_REPEAT {
973 if VERBOSE && !self.nt_value[child_nt] {
974 print!(" | {} is now valued {}",
975 Symbol::NT(child_nt as VarId).to_str(self.get_symbol_table()),
976 if nt_used.contains(&(child_nt as VarId)) { "and was used before" } else { "but wasn't used before" }
977 );
978 }
979 re_evaluate |= !self.nt_value[child_nt] && nt_used.contains(&(child_nt as VarId));
980 self.nt_value[child_nt] = true;
981 }
982 }
983 }
984 }
985 }
986 }
987
988 pub(crate) fn make_item_ops(&mut self) {
989 const VERBOSE: bool = false;
990 self.calc_nt_value();
991 self.log.add_note("- making item ops...");
992 let info = &self.parsing_table;
993 let mut items = vec![Vec::<Symbol>::new(); self.parsing_table.alts.len()];
994 if VERBOSE {
995 println!("Groups:");
996 for g in self.nt_parent.iter().filter(|va| !va.is_empty()) {
997 let group = self.get_group_alts(g);
998 let ids = group.iter().map(|(v, _)| *v).collect::<BTreeSet<VarId>>();
999 println!("{}: {}, alts {}",
1000 Symbol::NT(g[0]).to_str(self.get_symbol_table()),
1001 ids.iter().map(|v| Symbol::NT(*v).to_str(self.get_symbol_table())).join(", "),
1002 group.iter().map(|(_, a)| a.to_string()).join(", ")
1003 );
1004 }
1005 }
1006 let mut alts_to_revisit = HashSet::<AltId>::new();
1007 for g in self.nt_parent.iter().filter(|va| !va.is_empty()) {
1009 let group = self.get_group_alts(g);
1011 let g_top = g[0];
1012 let is_ambig = self.nt_has_all_flags(g_top, ruleflag::PARENT_AMBIGUITY);
1013 if VERBOSE {
1014 let ids = group.iter().map(|(v, _)| *v).collect::<BTreeSet<VarId>>();
1015 println!("parent: {}, NT with value: {}",
1016 Symbol::NT(g[0]).to_str(self.get_symbol_table()),
1017 ids.into_iter().filter_map(|v|
1018 if self.nt_value[v as usize] { Some(Symbol::NT(v as VarId).to_str(self.get_symbol_table())) } else { None }
1019 ).join(", "));
1020 }
1021 let g_top_has_value = self.nt_value[g_top as usize];
1022 for (var_id, alt_id) in &group {
1023 let ambig_loop_value = g_top_has_value && is_ambig && self.nt_has_all_flags(*var_id, ruleflag::CHILD_L_RECURSION);
1024 items[*alt_id as usize] = if ambig_loop_value { vec![Symbol::NT(g_top)] } else { vec![] };
1025 }
1026 for (var_id, alt_id) in &group {
1027 let opcode = &self.opcodes[*alt_id as usize];
1028 let (_, alt) = &info.alts[*alt_id as usize];
1029 if VERBOSE {
1030 print!("- {alt_id}: {} -> {} [{}]",
1031 Symbol::NT(*var_id).to_str(self.get_symbol_table()),
1032 alt.to_str(self.get_symbol_table()),
1033 opcode.iter().map(|op| op.to_str(self.get_symbol_table())).join(" "));
1034 }
1035 let flags = info.flags[*var_id as usize];
1036
1037 let mut has_sep_list_child_without_value = false;
1041 let mut values = self.opcodes[*alt_id as usize].iter().rev()
1042 .filter_map(|s| {
1043 let sym_maybe = match s {
1044 OpCode::T(t) => Some(Symbol::T(*t)),
1045 OpCode::NT(nt) => {
1046 let is_ambig_top = is_ambig && self.get_nt_parent(*nt) == Some(g_top)
1047 && !self.nt_has_any_flags(*nt, ruleflag::CHILD_L_RECURSION | ruleflag::CHILD_REPEAT);
1048 let var = if is_ambig_top { g_top } else { *nt };
1049 Some(Symbol::NT(var))
1050 },
1051 _ => {
1052 if VERBOSE { print!(" | {} dropped", s.to_str(self.get_symbol_table())); }
1053 None
1054 }
1055 };
1056 sym_maybe.and_then(|s| {
1057 const REP_MASK: u32 = ruleflag::CHILD_REPEAT | ruleflag::REPEAT_PLUS | ruleflag::L_FORM;
1058 const CHILD_STAR: u32 = ruleflag::CHILD_REPEAT | ruleflag::L_FORM;
1059 let has_value = self.sym_has_value(&s);
1060 if has_value
1061 || matches!(s, Symbol::NT(v) if v != *var_id && self.parsing_table.flags[v as usize] & REP_MASK == CHILD_STAR)
1064 {
1065 if !has_value {
1066 has_sep_list_child_without_value = true;
1067 }
1068 Some(s)
1069 } else {
1070 None
1071 }
1072 })
1073 }).to_vec();
1074 if has_sep_list_child_without_value {
1076 alts_to_revisit.insert(*alt_id);
1078 }
1079 let parent_is_rrec_lfact = !is_ambig && self.nt_has_all_flags(g[0], ruleflag::R_RECURSION | ruleflag::PARENT_L_FACTOR);
1081 if parent_is_rrec_lfact {
1082 if flags & ruleflag::CHILD_L_FACT != 0 && self.nt_has_all_flags(g[0], ruleflag::L_FORM) {
1083 assert!(!self.nt_has_all_flags(*var_id, ruleflag::CHILD_L_FACT | ruleflag::L_FORM), "this was useful after all");
1084 if VERBOSE { print!(" child_rrec_lform_lfact"); }
1085 items[*alt_id as usize].insert(0, Symbol::NT(g[0]));
1086 }
1087 } else {
1088 let sym_maybe = if flags & ruleflag::CHILD_REPEAT != 0 && (self.nt_value[*var_id as usize] || flags & ruleflag::L_FORM != 0) {
1089 Some(Symbol::NT(*var_id))
1090 } else if !is_ambig && flags & ruleflag::CHILD_L_RECURSION != 0 {
1091 let parent = info.parent[*var_id as usize].unwrap();
1092 Some(Symbol::NT(parent))
1093 } else if !is_ambig && flags & (ruleflag::R_RECURSION | ruleflag::L_FORM) == ruleflag::R_RECURSION | ruleflag::L_FORM {
1094 Some(Symbol::NT(*var_id))
1095 } else {
1096 None
1097 };
1098 if let Some(s) = sym_maybe {
1099 if self.sym_has_value(&s) {
1100 if VERBOSE { print!(" | loop => {}", s.to_str(self.get_symbol_table())); }
1101 values.insert(0, s);
1102 }
1103 }
1104 }
1105 if VERBOSE {
1106 println!(" ==> [{}] + [{}]",
1107 items[*alt_id as usize].iter().map(|s| s.to_str(self.get_symbol_table())).join(" "),
1108 values.iter().map(|s| s.to_str(self.get_symbol_table())).join(" "));
1109 }
1110 if let Some(OpCode::NT(nt)) = opcode.first() {
1111 let backup = if matches!(values.last(), Some(Symbol::NT(x)) if x == nt) {
1113 Some(values.pop().unwrap())
1114 } else {
1115 None
1116 };
1117 if nt != var_id && self.nt_has_all_flags(*nt, ruleflag::CHILD_L_RECURSION) {
1118 if VERBOSE { println!(" CHILD_L_RECURSION"); }
1119 items[*alt_id as usize].extend(values);
1121 continue;
1122 }
1123 if flags & ruleflag::PARENT_L_FACTOR != 0 {
1124 if VERBOSE {
1125 println!(" PARENT_L_FACTOR: moving {} to child {}",
1126 values.iter().map(|s| s.to_str(self.get_symbol_table())).join(" "),
1127 Symbol::NT(*nt).to_str(self.get_symbol_table()));
1128 }
1129 let pre = &mut items[*alt_id as usize];
1131 if !pre.is_empty() {
1132 values.splice(0..0, std::mem::take(pre));
1134 }
1135 for a_id in self.var_alts[*nt as usize].iter() {
1136 items[*a_id as usize].extend(values.clone());
1137 }
1143 continue;
1144 }
1145 if let Some(sym) = backup {
1146 values.push(sym);
1147 }
1148 }
1149 items[*alt_id as usize].extend(values);
1150 } }
1152
1153 self.check_sep_list(&mut items);
1156
1157 for alt_id in alts_to_revisit {
1159 items[alt_id as usize].retain(|s| self.sym_has_value(s));
1160 }
1161 self.item_ops = items;
1162
1163 self.log.add_note(
1164 format!(
1165 "NT with value: {}",
1166 self.nt_value.iter().index()
1167 .filter(|&(_, val)| *val)
1168 .map(|(var, _)| Symbol::NT(var).to_str(self.get_symbol_table()))
1169 .join(", ")));
1170 }
1171
1172 fn check_sep_list(&mut self, items: &mut [Vec<Symbol>]) {
1176 const VERBOSE: bool = false;
1214 if VERBOSE {
1215 let log = std::mem::take(&mut self.log);
1216 self.item_ops = items.iter().cloned().to_vec();
1217 self.log_nt_info();
1218 self.log_alt_info();
1219 println!("{}", self.log);
1220 self.item_ops.clear();
1221 self.log = log;
1222 }
1223 self.log.add_note("- determining sep_list nonterminals...");
1224 if VERBOSE { println!("check_sep_list:"); }
1225 for (top_nt, g) in self.nt_parent.iter().enumerate().filter(|va| !va.1.is_empty()) {
1227 let candidate_children = g.iter()
1229 .filter_map(|&var| {
1230 let alts = &self.var_alts[var as usize];
1231 let flags = self.parsing_table.flags[var as usize];
1232 if alts.len() == 2 && flags & (ruleflag::CHILD_REPEAT | ruleflag::REPEAT_PLUS) == ruleflag::CHILD_REPEAT {
1234 Some((var, alts[0] as usize, flags))
1235 } else {
1236 None
1237 }
1238 })
1239 .to_vec(); for &(c_var, c_alt_id, _c_flags) in &candidate_children {
1241 let has_value = self.nt_value[c_var as usize];
1242 let skip_loop_nt = if has_value { 1 } else { 0 }; let mut pattern = items[c_alt_id].iter().skip(skip_loop_nt).cloned().to_vec();
1244 if VERBOSE {
1245 println!(
1246 "? {} {c_alt_id}: pattern = {}",
1247 Symbol::NT(c_var).to_str(self.get_symbol_table()),
1248 pattern.iter().map(|s| s.to_str(self.get_symbol_table())).join(" ")); }
1249 if !pattern.is_empty() {
1250 let pattern_len = pattern.len();
1251 let pattern_copy = pattern.clone();
1252 let c_sym = Symbol::NT(c_var);
1253 let (p_var, _p_alt_id, p_alt, mut p_pos) = self.nt_parent[top_nt].iter()
1255 .flat_map(|&p_var| &self.var_alts[p_var as usize])
1256 .filter_map(|&p_alt_id| {
1257 let (p_var, p_alt) = &self.parsing_table.alts[p_alt_id as usize];
1258 if *p_var != c_var {
1259 p_alt.v.iter().position(|s| s == &c_sym).map(|p_pos| (*p_var, p_alt_id as usize, p_alt, p_pos))
1260 } else {
1261 None
1262 }
1263 })
1264 .next()
1265 .unwrap_or_else(|| panic!("NT {c_var} alt {c_alt_id} should have a parent's alt that includes it"));
1266 if p_pos > 0 {
1267 p_pos -= 1; let c_alt = &self.parsing_table.alts[c_alt_id].1.v;
1270 let mut c_pos = c_alt.len() - 2; let p_pos0 = p_pos;
1272 let mut span_nbr = 0;
1273 while !pattern.is_empty() {
1274 if p_alt[p_pos] == c_alt[c_pos] {
1275 span_nbr += 1;
1276 if self.sym_has_value(&c_alt[c_pos]) {
1277 pattern.pop();
1278 }
1279 if c_pos == 0 || p_pos == 0 {
1280 break;
1281 }
1282 c_pos -= 1;
1283 p_pos -= 1;
1284 } else {
1285 break;
1286 }
1287 }
1288 if pattern.is_empty() {
1289 let exit_alts = self.gather_alts(p_var);
1290 let mut found_pos = vec![];
1296 let all_match = exit_alts.into_iter().all(|a| {
1297 let a_items = &items[a as usize];
1298 if let Some(p) = a_items.iter().position(|s| *s == c_sym) {
1299 if p >= pattern_len && a_items[p - pattern_len..p] == pattern_copy {
1301 found_pos.push((a as usize, p));
1302 true
1303 } else {
1304 false
1306 }
1307 } else {
1308 true
1309 }
1310 });
1311 if all_match {
1312 if VERBOSE {
1313 println!("- match:");
1314 println!(" c[{c_alt_id}]: {} items: {}",
1315 c_alt.iter().map(|s| s.to_str_quote(self.get_symbol_table())).join(" "),
1316 items[c_alt_id].iter().map(|s| s.to_str_quote(self.get_symbol_table())).join(" "));
1317 }
1318 for (p_alt_id, pos) in found_pos {
1319 if VERBOSE {
1320 println!(" p[{p_alt_id}]: {} items: {}",
1321 p_alt.iter().map(|s| s.to_str_quote(self.get_symbol_table())).join(" "),
1322 items[p_alt_id].iter().map(|s| s.to_str_quote(self.get_symbol_table())).join(" "));
1323 println!(
1324 " c_alt_id = {c_alt_id}, p_alt_id = {p_alt_id}, p_pos0 = {p_pos0}, span_nbr = {span_nbr}, pos = {pos} => remove [{}..{}]",
1325 pos - pattern_len, pos);
1326 }
1327 self.span_nbrs[p_alt_id] -= span_nbr as SpanNbr;
1328 self.span_nbrs_sep_list.insert(c_alt_id as AltId, span_nbr as SpanNbr);
1329 items[p_alt_id].drain(pos - pattern_len..pos);
1330 if VERBOSE {
1331 println!(" => p items: {}", items[p_alt_id].iter().map(|s| s.to_str_quote(self.get_symbol_table())).join(" "));
1332 }
1333 self.parsing_table.flags[c_var as usize] |= ruleflag::SEP_LIST;
1334 }
1335 }
1336 }
1337 }
1338 }
1339 }
1340 }
1341 }
1342
1343 fn sort_alt_ids(&self, top_nt: VarId, alts: &[AltId]) -> Vec<AltId> {
1344 const VERBOSE: bool = false;
1345 if VERBOSE {
1346 println!(" sorting {} alts {alts:?}", Symbol::NT(top_nt).to_str(self.get_symbol_table()));
1347 for &a_id in alts {
1348 let &(_nt, ref alt) = &self.parsing_table.alts[a_id as usize];
1349 if let Some((v, id)) = alt.origin {
1350 let tree = &self.origin.trees[v as usize];
1351 println!(" [{a_id}] id = {},{id} -> {} <-> {}",
1352 Symbol::NT(v).to_str(self.get_symbol_table()),
1353 crate::grammar::grtree_to_str_ansi(tree, None, Some(id), Some(v), self.get_symbol_table(), false),
1354 tree.to_str_index(None, self.get_symbol_table())
1355 );
1356 assert_eq!(v, top_nt, "v = {}, top_nt = {}", Symbol::NT(v).to_str(self.get_symbol_table()), Symbol::NT(top_nt).to_str(self.get_symbol_table()));
1357 }
1358 }
1359 }
1360 let mut sorted = vec![];
1361 let mut ids = alts.iter().filter_map(|&alt_id| self.parsing_table.alts[alt_id as usize].1.origin.map(|(_var, id)| (id, alt_id)))
1362 .collect::<HashMap<_, _>>();
1363 let tree = &self.origin.trees[top_nt as usize];
1364 for node in tree.iter_post_depth() {
1365 if let Some((_, alt_id)) = ids.remove_entry(&node.index) {
1366 sorted.push(alt_id);
1367 }
1368 }
1369 if VERBOSE { println!(" -> {sorted:?}"); }
1370 sorted
1371 }
1372
1373 fn get_type_info(&mut self) -> (
1430 Vec<(String, String, String)>,
1431 Vec<Option<(VarId, String)>>,
1432 Vec<Vec<ItemInfo>>,
1433 HashMap<VarId, Vec<AltId>>
1434 ) {
1435 const VERBOSE: bool = false;
1436
1437 self.log.add_note("- determining item_info...");
1438 let pinfo = &self.parsing_table;
1439 let mut nt_upper_fixer = NameFixer::new();
1440 let mut nt_lower_fixer = NameFixer::new();
1441 let mut nt_plower_fixer = NameFixer::new_empty(); let nt_name: Vec<(String, String, String)> = (0..pinfo.num_nt).map(|v| {
1443 let name = self.symbol_table.get_nt_name(v as VarId);
1444 let nu = nt_upper_fixer.get_unique_name(name.to_camelcase());
1445 let nl = nt_lower_fixer.get_unique_name(nu.to_underscore_lowercase());
1446 let npl = nt_plower_fixer.get_unique_name(nu.to_underscore_lowercase());
1447 (nu, nl, npl)
1448 }).to_vec();
1449
1450 let mut alt_info: Vec<Option<(VarId, String)>> = vec![None; pinfo.alts.len()];
1451 let mut nt_repeat = HashMap::<VarId, Vec<ItemInfo>>::new();
1452 let mut item_info: Vec<Vec<ItemInfo>> = vec![vec![]; pinfo.alts.len()];
1453 let mut child_repeat_endpoints = HashMap::<VarId, Vec<AltId>>::new();
1454 for group in self.nt_parent.iter().filter(|vf| !vf.is_empty()) {
1455 let is_ambig = self.nt_has_any_flags(group[0], ruleflag::PARENT_AMBIGUITY);
1456 let mut is_ambig_1st_child = is_ambig;
1457 let mut alt_info_to_sort = HashMap::<VarId, Vec<AltId>>::new();
1458 for var in group {
1459 let nt = *var as usize;
1460 let nt_flags = pinfo.flags[nt];
1461 if is_ambig && (nt_flags & ruleflag::PARENT_L_RECURSION != 0 || (nt_flags & ruleflag::CHILD_L_RECURSION != 0 && !is_ambig_1st_child)) {
1462 continue;
1463 }
1464 if nt_flags & (ruleflag::CHILD_REPEAT | ruleflag::L_FORM) == ruleflag::CHILD_REPEAT {
1465 let is_plus = nt_flags & ruleflag::REPEAT_PLUS != 0;
1468 let mut endpoints = self.gather_alts(*var);
1469 if VERBOSE { println!("** {} endpoints: {endpoints:?} ", Symbol::NT(*var).to_str(self.get_symbol_table())); }
1470 if is_plus {
1471 endpoints = endpoints.chunks(2).map(|slice| slice[0]).to_vec();
1474 } else {
1475 endpoints.retain(|e| !pinfo.alts[*e as usize].1.is_sym_empty());
1478 }
1479 assert!(!endpoints.is_empty());
1480 let endpoints = self.sort_alt_ids(group[0], &endpoints);
1481 child_repeat_endpoints.insert(*var, endpoints);
1482 }
1483 for &alt_id in &self.var_alts[nt] {
1484 let i = alt_id as usize;
1485 if is_ambig_1st_child && pinfo.alts[i].1.is_sym_empty() {
1486 continue;
1487 }
1488 let item_ops = &self.item_ops[alt_id as usize];
1489 let mut indices = HashMap::<Symbol, (String, Option<usize>)>::new();
1494 let mut fixer = NameFixer::new();
1495 let mut owner = pinfo.alts[i].0;
1496 while let Some(parent) = pinfo.parent[owner as usize] {
1497 if pinfo.flags[owner as usize] & ruleflag::CHILD_REPEAT != 0 {
1498 break;
1503 }
1504 owner = parent;
1505 }
1506 let is_nt_child_repeat = pinfo.flags[owner as usize] & ruleflag::CHILD_REPEAT != 0;
1507 for s in item_ops {
1508 if let Some((_, c)) = indices.get_mut(s) {
1509 *c = Some(0);
1510 } else {
1511 let name = if let Symbol::NT(vs) = s {
1512 let flag = pinfo.flags[*vs as usize];
1513 if flag & ruleflag::CHILD_REPEAT != 0 {
1514 let inside_alt_id = self.var_alts[*vs as usize][0];
1515 let inside_alt = &pinfo.alts[inside_alt_id as usize].1;
1516 if false {
1517 let mut plus_name = inside_alt.symbols()[0].to_str(self.get_symbol_table()).to_underscore_lowercase();
1519 plus_name.push_str(if flag & ruleflag::REPEAT_PLUS != 0 { "_plus" } else { "_star" });
1520 plus_name
1521 } else if is_nt_child_repeat && indices.is_empty() {
1522 if flag & ruleflag::REPEAT_PLUS != 0 { "plus_acc".to_string() } else { "star_acc".to_string() }
1524 } else {
1525 if flag & ruleflag::REPEAT_PLUS != 0 { "plus".to_string() } else { "star".to_string() }
1527 }
1528 } else {
1529 nt_name[*vs as usize].clone().1
1530 }
1531 } else {
1532 s.to_str(self.get_symbol_table()).to_lowercase()
1533 };
1534 indices.insert(*s, (fixer.get_unique_name(name), None));
1535 }
1536 }
1537
1538 let has_lfact_child = nt_flags & ruleflag::PARENT_L_FACTOR != 0 &&
1541 pinfo.alts[i].1.symbols().iter().any(|s| matches!(s, &Symbol::NT(c) if pinfo.flags[c as usize] & ruleflag::CHILD_L_FACT != 0));
1542
1543 let is_hidden_repeat_child = pinfo.flags[owner as usize] & (ruleflag::CHILD_REPEAT | ruleflag::L_FORM) == ruleflag::CHILD_REPEAT;
1546
1547 let is_alt_sym_empty = self.is_alt_sym_empty(alt_id);
1549
1550 let is_duplicate = i > 0 && self.nt_has_all_flags(owner, ruleflag::CHILD_REPEAT | ruleflag::REPEAT_PLUS | ruleflag::L_FORM) &&
1553 is_alt_sym_empty;
1554 let is_last_empty_iteration = (nt_flags & ruleflag::CHILD_L_RECURSION != 0
1558 || self.nt_has_all_flags(*var, ruleflag::CHILD_REPEAT | ruleflag::L_FORM)) && is_alt_sym_empty;
1559
1560 let has_context = !has_lfact_child && !is_hidden_repeat_child && !is_duplicate && !is_last_empty_iteration;
1561 if VERBOSE {
1562 println!("NT {nt}, alt {alt_id}: has_lfact_child = {has_lfact_child}, is_hidden_repeat_child = {is_hidden_repeat_child}, \
1563 is_duplicate = {is_duplicate}, is_last_empty_iteration = {is_last_empty_iteration} => has_context = {has_context}");
1564 }
1565 if has_context {
1566 alt_info_to_sort.entry(owner)
1567 .and_modify(|v| v.push(alt_id))
1568 .or_insert_with(|| vec![alt_id]);
1569 }
1570 let has_owner_value = self.nt_value[owner as usize];
1571 item_info[i] = if item_ops.is_empty() && nt_flags & ruleflag::CHILD_L_RECURSION != 0 {
1572 if has_owner_value {
1574 vec![ItemInfo {
1575 name: nt_name[owner as usize].1.clone(),
1576 sym: Symbol::NT(owner),
1577 owner,
1578 index: None,
1579 }]
1580 } else {
1581 vec![]
1582 }
1583 } else {
1584 let is_rrec_lform = self.nt_has_all_flags(owner, ruleflag::R_RECURSION | ruleflag::L_FORM);
1585 let skip = if (is_nt_child_repeat || is_rrec_lform) && has_owner_value { 1 } else { 0 };
1586 let mut infos = item_ops.iter()
1587 .skip(skip)
1588 .map(|s| {
1589 let index = if let Some((_, Some(index))) = indices.get_mut(s) {
1590 let idx = *index;
1591 *index += 1;
1592 Some(idx)
1593 } else {
1594 None
1595 };
1596 ItemInfo {
1597 name: indices[s].0.clone(),
1598 sym: *s,
1599 owner,
1600 index,
1601 }
1602 }).to_vec();
1603 if self.nt_has_all_flags(owner, ruleflag::CHILD_REPEAT | ruleflag::REPEAT_PLUS | ruleflag::L_FORM) {
1604 let last_name = fixer.get_unique_name("last_iteration".to_string());
1606 infos.push(ItemInfo {
1607 name: last_name,
1608 sym: Symbol::Empty, owner,
1610 index: None,
1611 });
1612 };
1613 if is_nt_child_repeat && !infos.is_empty() && !nt_repeat.contains_key(&owner) {
1614 nt_repeat.insert(owner, infos.clone());
1615 }
1616 infos
1617 }
1618 } if is_ambig && nt_flags & ruleflag::CHILD_L_RECURSION != 0 {
1620 is_ambig_1st_child = false;
1621 }
1622 } if VERBOSE { println!("alt_info_to_sort = {alt_info_to_sort:?}"); }
1624 for (owner, alts) in alt_info_to_sort {
1625 for (num, alt) in self.sort_alt_ids(group[0], &alts).into_iter().index_start(1) {
1626 alt_info[alt as usize] = Some((owner, format!("V{num}")));
1627 }
1628 }
1629 } if VERBOSE {
1632 println!("NT names: {}", nt_name.iter()
1633 .map(|(u, l, pl)| format!("{u}/{l}/{pl}"))
1634 .join(", "));
1635 println!("alt info:");
1636 for (alt_id, alt_names) in alt_info.iter().enumerate() {
1637 if let Some((v, name)) = alt_names {
1638 println!("- alt {alt_id}, NT {v} {}, Ctx name: {name}", Symbol::NT(*v).to_str(self.get_symbol_table()));
1639 }
1640 }
1641 println!();
1642 println!("nt_name: {nt_name:?}");
1643 println!("alt_info: {alt_info:?}");
1644 println!("item_info:");
1645 for (i, item) in item_info.iter().enumerate().filter(|(_, item)| !item.is_empty()) {
1646 println!("- {i}: {{ {} }}", item.iter()
1647 .map(|ii| format!("{}{} ({})", ii.name, ii.index.map(|i| format!("[{i}]")).unwrap_or(String::new()), ii.sym.to_str(self.get_symbol_table())))
1648 .join(", "));
1649 }
1650 println!("item_info: {item_info:?}");
1651 println!("child_repeat_endpoints: {child_repeat_endpoints:?}");
1652 }
1653 (nt_name, alt_info, item_info, child_repeat_endpoints)
1654 }
1655
1656 pub fn gen_source_code(&mut self) -> (String, String, String) {
1661 self.log.add_note("generating source code...");
1662 if !self.log.has_no_errors() {
1663 return (String::new(), String::new(), String::new());
1664 }
1665 let mut parts = vec![];
1670 if !self.headers.is_empty() {
1671 parts.push(self.headers.clone());
1672 }
1673 let mut tmp_parts = if self.gen_parser {
1674 vec![self.source_build_parser()]
1675 } else {
1676 vec![]
1677 };
1678 let (src_types, src_listener) = if self.gen_wrapper {
1679 self.make_item_ops();
1680 let (src_wrapper, src_types, src_listener) = self.source_wrapper();
1681 tmp_parts.push(src_wrapper);
1682 (
1683 indent_source(vec![src_types], self.types_indent),
1684 indent_source(vec![src_listener], self.listener_indent)
1685 )
1686 } else {
1687 (String::new(), String::new())
1688 };
1689 self.log_nt_info();
1690 self.log_alt_info();
1691 parts.push(self.source_use());
1692 parts.extend(tmp_parts);
1693 (indent_source(parts, self.indent), src_types, src_listener)
1695 }
1696
1697 pub fn try_gen_source_code(mut self) -> Result<(BufLog, String, String, String), BuildError> {
1698 let (src, src_types, src_listener) = self.gen_source_code();
1699 if self.log.has_no_errors() {
1700 Ok((self.give_log(), src, src_types, src_listener))
1701 } else {
1702 Err(BuildError::new(self.give_log(), BuildErrorSource::ParserGen))
1703 }
1704 }
1705
1706 fn source_use(&self) -> Vec<String> {
1707 self.used_libs.gen_source_code()
1708 }
1709
1710 fn source_build_parser(&mut self) -> Vec<String> {
1711 static BASE_PARSER_LIBS: [&str; 5] = [
1712 "::VarId",
1713 "::AltId",
1714 "::parser::OpCode",
1715 "::parser::Parser",
1716 "::fixed_sym_table::FixedSymTable",
1717 ];
1718 static ALT_PARSER_LIBS: [&str; 2] = [
1719 "::alt::Alternative",
1720 "::parser::Symbol",
1721 ];
1722
1723 self.log.add_note("generating build_parser source...");
1724 let num_nt = self.symbol_table.get_num_nt();
1725 let num_t = self.symbol_table.get_num_t();
1726 self.used_libs.extend(BASE_PARSER_LIBS.into_iter().map(|s| format!("{}{s}", self.lib_crate)));
1727 self.log.add_note(format!("- creating symbol tables: {num_t} terminals, {num_nt} nonterminals"));
1728 let mut src = vec![
1729 format!("const PARSER_NUM_T: usize = {num_t};"),
1730 format!("const PARSER_NUM_NT: usize = {num_nt};"),
1731 format!("static SYMBOLS_T: [(&str, Option<&str>); PARSER_NUM_T] = [{}];",
1732 self.symbol_table.get_terminals().map(|(s, os)|
1733 format!("(\"{s}\", {})", os.as_ref().map(|s| format!("Some({s:?})")).unwrap_or("None".to_string()))).join(", ")),
1734 format!("static SYMBOLS_NT: [&str; PARSER_NUM_NT] = [{}];",
1735 self.symbol_table.get_nonterminals().map(|s| format!("{s:?}")).join(", ")),
1736 format!("static ALT_VAR: [VarId; {}] = [{}];",
1737 self.parsing_table.alts.len(),
1738 self.parsing_table.alts.iter().map(|(v, _)| format!("{v}")).join(", ")),
1739 ];
1740 if self.include_alts {
1741 self.used_libs.extend(ALT_PARSER_LIBS.into_iter().map(|s| format!("{}{s}", self.lib_crate)));
1742 src.push(format!("static ALTERNATIVES: [&[Symbol]; {}] = [{}];",
1743 self.parsing_table.alts.len(),
1744 self.parsing_table.alts.iter().map(|(_, f)| format!("&[{}]", f.iter().map(symbol_to_code).join(", "))).join(", ")));
1745 }
1746 self.log.add_note(format!("- creating parsing tables: {} items, {} opcodes", self.parsing_table.table.len(), self.opcodes.len()));
1747 src.extend(vec![
1748 format!(
1749 "static PARSING_TABLE: [AltId; {}] = [{}];",
1750 self.parsing_table.table.len(),
1751 self.parsing_table.table.iter().map(|v| format!("{v}")).join(", ")),
1752 format!(
1753 "static OPCODES: [&[OpCode]; {}] = [{}];",
1754 self.opcodes.len(),
1755 self.opcodes.iter().map(|strip| format!("&[{}]", strip.iter().map(|op| format!("OpCode::{op:?}")).join(", "))).join(", ")),
1756 format!(
1757 "static INIT_OPCODES: [OpCode; {}] = [{}];",
1758 self.init_opcodes.len(),
1759 self.init_opcodes.iter().map(|op| format!("OpCode::{op:?}")).join(", ")),
1760 format!("static START_SYMBOL: VarId = {};\n", self.start),
1761 ]);
1762 if self.gen_token_enums {
1763 src.add_space();
1764 src.push("#[derive(Clone, Copy, PartialEq, Debug)]".to_string());
1765 src.push("#[repr(u16)]".to_string());
1766 src.push("pub enum Term {".to_string());
1767 let cols = self.symbol_table.get_terminals().enumerate()
1768 .map(|(t, (s, s_opt))| vec![
1769 format!(" #[doc = \"{}\"]", if let Some(so) = s_opt { format!("'{so}'") } else { "(variable)".to_string() }),
1772 format!("{s} = {t},", )])
1773 .to_vec();
1774 src.extend(columns_to_str(cols, Some(vec![16, 0])));
1775 src.push("}\n".to_string());
1776 src.push("#[derive(Clone, Copy, PartialEq, Debug)]".to_string());
1777 src.push("#[repr(u16)]".to_string());
1778 src.push("pub enum NTerm {".to_string());
1779 let cols = self.symbol_table.get_nonterminals().index()
1780 .map(|(t, s)| vec![
1781 format!(
1782 " #[doc = \"`{s}`{}\"]",
1783 if let Some(p) = self.get_nt_parent(t) {
1784 format!(", parent: `{}`", Symbol::NT(p).to_str(self.get_symbol_table()))
1785 } else {
1786 String::new()
1787 }),
1788 format!("{} = {t},", s.to_camelcase())])
1789 .to_vec();
1790 src.extend(columns_to_str(cols, Some(vec![16, 0])));
1791 src.push("}\n".to_string());
1792 src.push("pub fn get_term_name(t: TokenId) -> (&'static str, Option<&'static str>) {".to_string());
1793 src.push(" SYMBOLS_T[t as usize]".to_string());
1794 src.push("}\n".to_string());
1795 }
1796 src.extend(vec![
1797 "pub fn build_parser() -> Parser<'static> {{".to_string(),
1798 " let symbol_table = FixedSymTable::new(".to_string(),
1799 " SYMBOLS_T.into_iter().map(|(s, os)| (s.to_string(), os.map(|s| s.to_string()))).collect(),".to_string(),
1800 " SYMBOLS_NT.into_iter().map(|s| s.to_string()).collect()".to_string(),
1801 " );".to_string(),
1802 " Parser::new(".to_string(),
1803 " PARSER_NUM_NT, PARSER_NUM_T + 1,".to_string(),
1804 " &ALT_VAR,".to_string(),
1805 if self.include_alts {
1806 " ALTERNATIVES.into_iter().map(|s| Alternative::new(s.to_vec())).collect(),".to_string()
1807 } else {
1808 " Vec::new(),".to_string()
1809 },
1810 " OPCODES.into_iter().map(|strip| strip.to_vec()).collect(),".to_string(),
1811 " INIT_OPCODES.to_vec(),".to_string(),
1812 " &PARSING_TABLE,".to_string(),
1813 " symbol_table,".to_string(),
1814 " START_SYMBOL".to_string(),
1815 " )".to_string(),
1816 "}}".to_string(),
1817 ]);
1818 src
1819 }
1820
1821 fn get_info_type(&self, infos: &[ItemInfo], info: &ItemInfo) -> String {
1822 let type_name_base = match info.sym {
1823 Symbol::T(_) => "String".to_string(),
1824 Symbol::NT(vs) => self.get_nt_type(vs).to_string(),
1825 Symbol::Empty => "bool".to_string(),
1826 _ => panic!("unexpected symbol {}", info.sym)
1827 };
1828 if info.index.is_some() {
1829 let nbr = infos.iter()
1830 .map(|nfo| if nfo.sym == info.sym { nfo.index.unwrap() } else { 0 })
1831 .max().unwrap() + 1;
1832 format!("[{type_name_base}; {nbr}]")
1833 } else {
1834 type_name_base
1835 }
1836 }
1837
1838 fn source_infos(&self, infos: &[ItemInfo], add_pub: bool, add_type: bool) -> String {
1840 let pub_str = if add_pub { "pub " } else { "" };
1841 infos.iter()
1842 .filter_map(|info| {
1843 if info.index.is_none() || info.index == Some(0) {
1844 let type_name = if add_type {
1845 format!(": {}", self.get_info_type(infos, info))
1846 } else {
1847 String::new()
1848 };
1849 Some(format!("{pub_str}{}{type_name}", info.name))
1850 } else {
1851 None
1852 }
1853 }).join(", ")
1854 }
1855
1856 fn is_alt_sym_empty(&self, a_id: AltId) -> bool {
1857 self.parsing_table.alts[a_id as usize].1.is_sym_empty()
1858 }
1859
1860 fn make_match_choices(&self, alts: &[AltId], name: &str, flags: u32, no_method: bool, force_id: Option<AltId>) -> (bool, Vec<String>) {
1862 assert!(!alts.is_empty(), "alts cannot be empty");
1863 let discarded = if !no_method && flags & (ruleflag::CHILD_REPEAT | ruleflag::REPEAT_PLUS | ruleflag::L_FORM) == ruleflag::CHILD_REPEAT { 1 } else { 0 };
1868
1869 let is_plus_no_lform = flags & (ruleflag::CHILD_REPEAT | ruleflag::REPEAT_PLUS | ruleflag::L_FORM) == (ruleflag::CHILD_REPEAT | ruleflag::REPEAT_PLUS);
1873 let is_alt_id_threshold = if is_plus_no_lform { 2 } else { 1 };
1874 let is_alt_id = force_id.is_none() && alts.len() - discarded > is_alt_id_threshold;
1875
1876 let mut choices = Vec::<String>::new();
1877 let force_id_str = force_id.map(|f| f.to_string()).unwrap_or_default();
1878 if alts.len() - discarded == 1 {
1879 if no_method {
1880 choices.push(format!(" {} => {{}}", alts[0]));
1881 } else {
1882 choices.push(format!(" {} => self.{name}({force_id_str}),", alts[0]));
1883 }
1884 } else {
1885 let last = alts.len() - 1 - discarded;
1886 choices.extend((0..last).map(|i| format!(" {} |", alts[i])));
1887 if no_method {
1888 choices.push(format!(" {} => {{}}", alts[last]));
1889 } else {
1890 choices.push(format!(" {} => self.{name}({}{force_id_str}),",
1891 alts[last],
1892 if is_alt_id { "alt_id" } else { "" }));
1893 }
1894 }
1895 if discarded == 1 {
1896 choices.push(format!(" {} => {{}}", alts.last().unwrap()));
1897 }
1898 (is_alt_id, choices)
1899 }
1900
1901 fn gen_match_item<F: FnOnce() -> String>(&self, common: String, span_only: F) -> String {
1905 if self.gen_span_params {
1906 let span_code = span_only();
1907 format!("({span_code}, {common})")
1908 } else {
1909 common
1910 }
1911 }
1912
1913 fn get_var_param(item: &ItemInfo, indices: &HashMap<Symbol, Vec<String>>, non_indices: &mut Vec<String>) -> Option<String> {
1914 if let Some(index) = item.index {
1915 if index == 0 {
1916 Some(format!("{}: [{}]", item.name, indices[&item.sym].iter().rev().join(", ")))
1917 } else {
1918 None
1919 }
1920 } else {
1921 let name = non_indices.pop().unwrap();
1922 if name == item.name {
1923 Some(name)
1924 } else {
1925 Some(format!("{}: {name}", item.name))
1926 }
1927 }
1928 }
1929
1930 fn get_var_params(item_info: &[ItemInfo], skip: usize, indices: &HashMap<Symbol, Vec<String>>, non_indices: &mut Vec<String>) -> String {
1931 item_info.iter().skip(skip).filter_map(|item| {
1932 Self::get_var_param(item, indices, non_indices)
1933 }).join(", ")
1934 }
1935
1936 fn source_lets(infos: &[ItemInfo], nt_name: &[(String, String, String)], indent: &str, last_alt_id_maybe: Option<AltId>) -> (Vec<String>, String) {
1937 let mut src_let = vec![];
1938 let mut var_fixer = NameFixer::new();
1939 let mut indices = HashMap::<Symbol, Vec<String>>::new();
1940 let mut non_indices = Vec::<String>::new();
1941 for item in infos.iter().rev() {
1942 let varname = if let Some(index) = item.index {
1943 let name = var_fixer.get_unique_name(format!("{}_{}", item.name, index + 1));
1944 indices.entry(item.sym).and_modify(|v| v.push(name.clone())).or_insert(vec![name.clone()]);
1945 name
1946 } else {
1947 let name = item.name.clone();
1948 non_indices.push(name.clone());
1949 name
1950 };
1951 if item.sym.is_empty() {
1952 src_let.push(format!("{indent}let {varname} = alt_id == {};", last_alt_id_maybe.unwrap()));
1953 } else if let Symbol::NT(v) = item.sym {
1954 src_let.push(format!("{indent}let {varname} = self.stack.pop().unwrap().get_{}();", nt_name[v as usize].2));
1955 } else {
1956 src_let.push(format!("{indent}let {varname} = self.stack_t.pop().unwrap();"));
1957 }
1958 }
1959 let src_struct = Self::get_var_params(infos, 0, &indices, &mut non_indices);
1960 (src_let, src_struct)
1961 }
1962
1963 fn source_update_span(n: &str) -> Vec<String> {
1964 vec![
1965 format!(" let spans = self.stack_span.drain(self.stack_span.len() - {n} ..).collect::<Vec<_>>();"),
1966 " self.stack_span.push(spans.iter().fold(PosSpan::empty(), |acc, sp| acc + sp));".to_string(),
1967 ]
1968 }
1969
1970 fn source_child_repeat_lets(
1975 &self,
1976 endpoints: &[AltId],
1977 item_info: &[Vec<ItemInfo>],
1978 is_plus: bool,
1979 nt_name: &[(String, String, String)],
1980 fn_name: &str,
1981 nu: &str,
1982 is_init: bool,
1983 ) -> (Vec<String>, String)
1984 {
1985 let mut src_val = vec![];
1993 let val_name = if endpoints.len() > 1 {
1994 src_val.push(format!(" let {} = match alt_id {{", self.gen_match_item("val".to_string(), || "n".to_string())));
1996 for (i, &a_id) in endpoints.iter().index_start(1) {
1997 let infos = &item_info[a_id as usize];
1998 src_val.push(format!(" {a_id}{} => {{", if is_plus { format!(" | {}", a_id + 1) } else { String::new() }));
1999 let (src_let, src_struct) = Self::source_lets(infos, nt_name, " ", None);
2000 src_val.extend(src_let);
2001 let return_value = self.gen_match_item(
2002 format!("Syn{nu}Item::V{i} {{ {} }}", src_struct),
2003 || self.span_nbrs[a_id as usize].to_string());
2004 src_val.push(format!(" {return_value}"));
2005 src_val.push(" }".to_string());
2006 }
2007 src_val.push(format!(" _ => panic!(\"unexpected alt id {{alt_id}} in fn {fn_name}\"),"));
2008 src_val.push(" };".to_string());
2009 if self.gen_span_params {
2010 src_val.extend(Self::source_update_span("n"));
2011 }
2012 "val".to_string()
2013 } else {
2014 let a_id = endpoints[0];
2016 if self.gen_span_params {
2017 let span_nbr = if is_init {
2018 *self.span_nbrs_sep_list.get(&a_id).unwrap()
2019 } else {
2020 self.span_nbrs[a_id as usize]
2021 };
2022 src_val.extend(Self::source_update_span(&span_nbr.to_string()));
2023 }
2024 let infos = &item_info[a_id as usize];
2025 let (src_let, src_struct) = Self::source_lets(infos, nt_name, " ", None);
2026 src_val.extend(src_let);
2027 if infos.len() == 1 {
2028 infos[0].name.clone()
2030 } else {
2031 src_val.push(format!(" let val = Syn{nu}Item {{ {} }};", src_struct));
2033 "val".to_string()
2034 }
2035 };
2036 (src_val, val_name)
2037 }
2038
2039 fn source_wrapper(&mut self) -> (Vec<String>, Vec<String>, Vec<String>) {
2044 const VERBOSE: bool = false;
2045 const MATCH_COMMENTS_SHOW_DESCRIPTIVE_ALTS: bool = false;
2046
2047 static TYPE_DERIVE: &str = "#[derive(Debug, PartialEq)]";
2048 static PARSER_LIBS: [&str; 8] = [
2049 "::VarId", "::parser::Call", "::parser::ListenerWrapper",
2050 "::AltId", "::log::Logger", "::TokenId", "::lexer::PosSpan",
2051 "::parser::Terminate"
2052 ];
2053
2054 self.log.add_note("generating wrapper source...");
2057 self.used_libs.extend(PARSER_LIBS.into_iter().map(|s| format!("{}{s}", self.lib_crate)));
2058 if self.gen_span_params {
2059 self.used_libs.add(format!("{}::lexer::PosSpan", self.lib_crate));
2060 }
2061
2062 let (nt_name, alt_info, item_info, child_repeat_endpoints) = self.get_type_info();
2063 let pinfo = &self.parsing_table;
2064
2065 let mut src = vec![];
2066
2067 for (v, name) in nt_name.iter().enumerate().filter(|(v, _)| self.nt_value[*v]) {
2069 let v = v as VarId;
2070 self.nt_type.entry(v).or_insert_with(|| format!("Syn{}", name.0));
2071 }
2072
2073 let mut nt_contexts = vec![None; self.parsing_table.num_nt];
2074 for group in self.nt_parent.iter().filter(|vf| !vf.is_empty()) {
2076 let mut group_names = HashMap::<VarId, Vec<AltId>>::new();
2077 for nt in group {
2079 for &alt_id in &self.var_alts[*nt as usize] {
2080 if let Some((owner, _name)) = &alt_info[alt_id as usize] {
2081 group_names.entry(*owner)
2082 .and_modify(|v| v.push(alt_id))
2083 .or_insert_with(|| vec![alt_id]);
2084 }
2085 }
2086 }
2087 if VERBOSE {
2088 println!("group {}", group.iter().map(|nt| Symbol::NT(*nt).to_str(self.get_symbol_table())).join(" "));
2089 }
2090 for &nt in group {
2091 if let Some(alts) = group_names.get(&nt) {
2092 let flags = self.parsing_table.flags[nt as usize];
2093 if VERBOSE {
2094 print!("- {}: flags {}", Symbol::NT(nt).to_str(self.get_symbol_table()), ruleflag::to_string(flags).join(" "));
2095 if let Some(gn) = group_names.get(&nt) {
2096 println!(", alts = {}", gn.iter().map(|a| a.to_string()).join(", "));
2097 let sorted = self.sort_alt_ids(group[0], gn);
2098 println!(" sorted alts: {sorted:?}");
2099 } else {
2100 println!();
2101 }
2102 }
2103 if flags & (ruleflag::SEP_LIST | ruleflag::L_FORM) == ruleflag::SEP_LIST | ruleflag::L_FORM {
2104 src.push("#[derive(Debug)]".to_string());
2105 src.push(format!("pub enum InitCtx{} {{", nt_name[nt as usize].0));
2106 let a_id = self.var_alts[nt as usize][0];
2107 let comment = format!(
2108 "value of `{}` before {}",
2109 self.item_ops[a_id as usize][1..].iter().map(|s| s.to_str(self.get_symbol_table())).join(" "),
2110 self.full_alt_components(a_id, None).1
2111 );
2112 let ctx_content = self.source_infos(&item_info[a_id as usize], false, true);
2113 src.push(format!(" /// {comment}"));
2114 let a_name = &alt_info[a_id as usize].as_ref().unwrap().1;
2115 let ctx_item = if ctx_content.is_empty() {
2116 if VERBOSE { println!(" {a_name},"); }
2117 format!(" {a_name},", )
2118 } else {
2119 if VERBOSE { println!(" {a_name} {{ {ctx_content} }},"); }
2120 format!(" {a_name} {{ {ctx_content} }},", )
2121 };
2122 src.push(ctx_item);
2123 src.push("}".to_string());
2124 }
2125 src.push("#[derive(Debug)]".to_string());
2126 src.push(format!("pub enum Ctx{} {{", nt_name[nt as usize].0));
2127 if VERBOSE { println!(" context Ctx{}:", nt_name[nt as usize].0); }
2128 let alts = self.sort_alt_ids(group[0], alts);
2129 nt_contexts[nt as usize] = Some(alts.clone());
2130 for a_id in alts {
2131 let comment = self.full_alt_str(a_id, None, true);
2132 src.push(format!(" /// {comment}"));
2133 if VERBOSE { println!(" /// {comment}"); }
2134 let ctx_content = self.source_infos(&item_info[a_id as usize], false, true);
2135 let a_name = &alt_info[a_id as usize].as_ref().unwrap().1;
2136 let ctx_item = if ctx_content.is_empty() {
2137 if VERBOSE { println!(" {a_name},"); }
2138 format!(" {a_name},", )
2139 } else {
2140 if VERBOSE { println!(" {a_name} {{ {ctx_content} }},"); }
2141 format!(" {a_name} {{ {ctx_content} }},", )
2142 };
2143 src.push(ctx_item);
2144 }
2145 src.push("}".to_string());
2146 }
2147 }
2148 }
2149
2150 let mut src_types = vec![
2152 format!("// {:-<80}", ""),
2153 "// Template for the user-defined types:".to_string(),
2154 ];
2155 src.add_space();
2156 let mut syns = Vec::<VarId>::new(); for (v, names) in nt_name.iter().enumerate().filter(|(v, _)| self.nt_value[*v]) {
2158 let v = v as VarId;
2159 let (nu, _nl, _npl) = names;
2160 let nt_type = self.get_nt_type(v);
2161 if self.nt_has_all_flags(v, ruleflag::CHILD_REPEAT) {
2162 let is_lform = self.nt_has_all_flags(v, ruleflag::L_FORM);
2163 let first_alt = self.var_alts[v as usize][0];
2164 let (t, var_oid) = self.origin.get(v).unwrap();
2165 if is_lform {
2166 let astr = format!("/// User-defined type for {}", self.full_alt_str(first_alt, None, true));
2167 src_types.push(String::new());
2168 src_types.push(astr.clone());
2169 src_types.push(TYPE_DERIVE.to_string());
2170 src_types.push(format!("pub struct {}();", self.get_nt_type(v)));
2171 let extra_src = vec![
2172 astr,
2173 TYPE_DERIVE.to_string(),
2174 format!("pub struct {nt_type}();"),
2175 ];
2176 self.nt_extra_info.insert(v, (self.get_nt_type(v).to_string(), extra_src));
2177 } else {
2178 let top_parent = self.parsing_table.get_top_parent(v);
2179 src.push(format!("/// Computed `{}` array in `{} -> {}`",
2180 grtree_to_str(t, Some(var_oid), None, Some(top_parent), self.get_symbol_table(), true),
2181 Symbol::NT(top_parent).to_str(self.get_symbol_table()),
2182 grtree_to_str(t, None, Some(var_oid), Some(top_parent), self.get_symbol_table(), true),
2183 ));
2184 let endpoints = child_repeat_endpoints.get(&v).unwrap();
2185 if endpoints.len() > 1 {
2186 src.push("#[derive(Debug, PartialEq)]".to_string());
2188 src.push(format!("pub struct {nt_type}(pub Vec<Syn{nu}Item>);"));
2189 src.push("#[derive(Debug, PartialEq)]".to_string());
2190 src.push(format!("pub enum Syn{nu}Item {{"));
2191 for (i, &a_id) in endpoints.iter().index_start(1) {
2192 src.push(format!(" /// {}", self.full_alt_str(a_id, None, true)));
2193 src.push(format!(" V{i} {{ {} }},", self.source_infos(&item_info[a_id as usize], false, true)));
2194 }
2195 src.push("}".to_string());
2196 } else {
2197 let a_id = endpoints[0];
2199 let infos = &item_info[a_id as usize];
2200 if infos.len() == 1 {
2201 let type_name = self.get_info_type(infos, &infos[0]);
2203 src.push("#[derive(Debug, PartialEq)]".to_string());
2204 src.push(format!("pub struct {nt_type}(pub Vec<{type_name}>);", ));
2205 } else {
2206 src.push("#[derive(Debug, PartialEq)]".to_string());
2208 src.push(format!("pub struct {nt_type}(pub Vec<Syn{nu}Item>);"));
2209 src.push(format!("/// {}", self.full_alt_str(first_alt, None, false)));
2210 src.push("#[derive(Debug, PartialEq)]".to_string());
2211 src.push(format!("pub struct Syn{nu}Item {{ {} }}", self.source_infos(infos, true, true)));
2212 }
2213 }
2214 }
2215 } else {
2216 src_types.push(String::new());
2217 src_types.push(format!("/// User-defined type for `{}`", Symbol::NT(v).to_str(self.get_symbol_table())));
2218 src_types.push(TYPE_DERIVE.to_string());
2219 src_types.push(format!("pub struct {}();", self.get_nt_type(v)));
2220 let extra_src = vec![
2221 format!("/// User-defined type for `{}`", Symbol::NT(v).to_str(self.get_symbol_table())),
2222 "#[derive(Debug, PartialEq)]".to_string(),
2223 format!("pub struct {}();", self.get_nt_type(v)),
2224 ];
2225 self.nt_extra_info.insert(v, (self.get_nt_type(v).to_string(), extra_src));
2226 }
2227 syns.push(v);
2228 }
2229 if !self.nt_value[self.start as usize] {
2230 let nu = &nt_name[self.start as usize].0;
2231 src.push(format!("/// Top non-terminal {nu} (has no value)"));
2232 src.push("#[derive(Debug, PartialEq)]".to_string());
2233 src.push(format!("pub struct Syn{nu}();"))
2234 }
2235
2236 if VERBOSE { println!("syns = {syns:?}"); }
2238 src.add_space();
2239 src.push("#[derive(Debug)]".to_string());
2241 src.push(format!("enum EnumSynValue {{ {} }}",
2242 syns.iter().map(|v| format!("{}({})", nt_name[*v as usize].0, self.get_nt_type(*v))).join(", ")));
2243 if !syns.is_empty() {
2244 src.add_space();
2246 src.push("impl EnumSynValue {".to_string());
2247 for v in &syns {
2248 let (nu, _, npl) = &nt_name[*v as usize];
2249 let nt_type = self.get_nt_type(*v);
2250 src.push(format!(" fn get_{npl}(self) -> {nt_type} {{"));
2251 if syns.len() == 1 {
2252 src.push(format!(" let EnumSynValue::{nu}(val) = self;"));
2253 src.push(" val".to_string());
2254 } else {
2255 src.push(format!(" if let EnumSynValue::{nu}(val) = self {{ val }} else {{ panic!() }}"));
2256 }
2257 src.push(" }".to_string());
2258 }
2259 src.push("}".to_string());
2260 }
2261
2262 let mut src_init = Vec::<Vec<String>>::new();
2264 let mut src_exit = Vec::<Vec<String>>::new();
2265 let mut src_listener_decl = Vec::<String>::new();
2266 let mut src_wrapper_impl = Vec::<String>::new();
2267 let mut exit_fixer = NameFixer::new();
2268 let mut span_init = HashSet::<VarId>::new();
2269 let mut src_skel = vec![
2270 format!("// {:-<80}", ""),
2271 format!("// Template for the user implementation of {}Listener", self.name),
2272 String::new(),
2273 "struct Listener {".to_string(),
2274 " log: BufLog,".to_string(),
2275 "}".to_string(),
2276 String::new(),
2277 "#[allow(unused)]".to_string(),
2278 format!("impl {}Listener for Listener {{", self.name),
2279 " fn get_log_mut(&mut self) -> &mut impl Logger {".to_string(),
2280 " &mut self.log".to_string(),
2281 " }".to_string(),
2282 String::new(),
2283 ];
2284
2285 for group in self.nt_parent.iter().filter(|vf| !vf.is_empty()) {
2287 let parent_nt = group[0] as usize;
2288 let parent_flags = self.parsing_table.flags[parent_nt];
2289 let parent_has_value = self.nt_value[parent_nt];
2290 let mut exit_alt_done = HashSet::<VarId>::new();
2291 let mut init_nt_done = HashSet::<VarId>::new();
2292 if VERBOSE { println!("- GROUP {}, parent has {}value, parent flags: {}",
2293 group.iter().map(|v| Symbol::NT(*v).to_str(self.get_symbol_table())).join(", "),
2294 if parent_has_value { "" } else { "no " },
2295 ruleflag::to_string(parent_flags).join(" | ")); }
2296 let is_ambig = parent_flags & ruleflag::PARENT_AMBIGUITY != 0;
2297 let ambig_children = if is_ambig {
2298 group.iter().filter(|&v| self.nt_has_any_flags(*v, ruleflag::CHILD_L_RECURSION)).cloned().to_vec()
2299 } else {
2300 Vec::new()
2301 };
2302 let mut ambig_op_alts = BTreeMap::<AltId, Vec<AltId>>::new();
2303 for (id, f) in ambig_children.iter() .flat_map(|v| self.gather_alts(*v))
2305 .filter_map(|f| self.parsing_table.alts[f as usize].1.get_ambig_alt_id().map(|id| (id, f)))
2306 {
2307 ambig_op_alts.entry(id).or_default().push(f);
2308 }
2309 if VERBOSE && is_ambig {
2310 println!("- ambig children vars: {}", ambig_children.iter().map(|v| Symbol::NT(*v).to_str(self.get_symbol_table())).join(", "));
2311 println!(" ambig op alts: {ambig_op_alts:?}");
2312 }
2313 for var in group {
2314 let sym_nt = Symbol::NT(*var);
2315 let nt = *var as usize;
2316 let flags = self.parsing_table.flags[nt];
2317 let is_plus = flags & ruleflag::REPEAT_PLUS != 0;
2318 let is_ambig_1st_child = is_ambig && flags & ruleflag::CHILD_L_RECURSION != 0 && ambig_children.first() == Some(var);
2320 let is_ambig_redundant = is_ambig && flags & ruleflag::L_RECURSION != 0 && !is_ambig_1st_child;
2323 let has_value = self.nt_value[nt];
2324 let nt_comment = format!("// {}", sym_nt.to_str(self.get_symbol_table()));
2325 let is_parent = nt == parent_nt;
2326 let is_child_repeat_lform = self.nt_has_all_flags(*var, ruleflag::CHILD_REPEAT_LFORM);
2327 let is_sep_list = flags & ruleflag::SEP_LIST != 0;
2328 let is_lform = flags & ruleflag::L_FORM != 0;
2329 let is_rrec_lform = is_lform && flags & ruleflag::R_RECURSION != 0;
2330 let (nu, nl, npl) = &nt_name[nt];
2331 if VERBOSE { println!(" - VAR {}, has {}value, flags: {}",
2332 sym_nt.to_str(self.get_symbol_table()),
2333 if has_value { "" } else { "no " },
2334 ruleflag::to_string(flags).join(" | ")); }
2335
2336 let mut has_skel_init = false;
2339 let init_fn_name = format!("init_{npl}");
2340 if self.parsing_table.parent[nt].is_none() {
2341 init_nt_done.insert(*var);
2342 if is_rrec_lform {
2343 span_init.insert(*var);
2344 }
2345 if is_rrec_lform && has_value {
2346 src_wrapper_impl.push(String::new());
2347 src_listener_decl.push(format!(" fn {init_fn_name}(&mut self) -> {};", self.get_nt_type(nt as VarId)));
2348 src_skel.push(format!(" fn {init_fn_name}(&mut self) -> {} {{", self.get_nt_type(nt as VarId)));
2349 has_skel_init = true;
2350 src_init.push(vec![format!(" {nt} => self.init_{nl}(),"), nt_comment]);
2351 src_wrapper_impl.push(format!(" fn {init_fn_name}(&mut self) {{"));
2352 src_wrapper_impl.push(format!(" let val = self.listener.init_{nl}();"));
2353 src_wrapper_impl.push(format!(" self.stack.push(EnumSynValue::{nu}(val));"));
2354 src_wrapper_impl.push(" }".to_string());
2355 } else {
2356 src_listener_decl.push(format!(" fn {init_fn_name}(&mut self) {{}}"));
2357 src_init.push(vec![format!(" {nt} => self.listener.{init_fn_name}(),"), nt_comment]);
2358 }
2359 } else if flags & ruleflag::CHILD_REPEAT != 0 {
2360 if !is_sep_list {
2361 span_init.insert(*var);
2362 }
2363 if has_value || is_sep_list {
2364 init_nt_done.insert(*var);
2365 src_wrapper_impl.push(String::new());
2366 src_init.push(vec![format!(" {nt} => self.{init_fn_name}(),"), nt_comment]);
2367 src_wrapper_impl.push(format!(" fn {init_fn_name}(&mut self) {{"));
2368 if is_lform {
2369 if is_sep_list {
2370 let all_exit_alts = if is_ambig_1st_child {
2371 ambig_op_alts.values().rev().map(|v| v[0]).to_vec()
2372 } else {
2373 self.gather_alts(nt as VarId)
2374 };
2375 let exit_alts = all_exit_alts.into_iter()
2376 .filter(|f|
2377 (flags & ruleflag::CHILD_L_RECURSION == 0
2378 && flags & (ruleflag::CHILD_REPEAT_LFORM | ruleflag::REPEAT_PLUS) != ruleflag::CHILD_REPEAT_LFORM)
2379 || !self.is_alt_sym_empty(*f)
2380 );
2381 let (mut last_alt_ids, exit_info_alts): (Vec<AltId>, Vec<AltId>) = exit_alts.into_iter()
2382 .partition(|i| alt_info[*i as usize].is_none());
2383 let last_alt_id_maybe = if last_alt_ids.is_empty() { None } else { Some(last_alt_ids.remove(0)) };
2384 let a = exit_info_alts[0];
2385 let indent = " ";
2386 let (src_let, ctx_params) = Self::source_lets(&item_info[a as usize], &nt_name, indent, last_alt_id_maybe);
2387 src_wrapper_impl.extend(src_let);
2388 let ctx = if ctx_params.is_empty() {
2389 format!("InitCtx{nu}::{}", alt_info[a as usize].as_ref().unwrap().1)
2390 } else {
2391 format!("InitCtx{nu}::{} {{ {ctx_params} }}", alt_info[a as usize].as_ref().unwrap().1)
2392 };
2393 src_wrapper_impl.push(format!(" let ctx = {ctx};"));
2394 if self.gen_span_params {
2395 src_wrapper_impl.extend(Self::source_update_span(&self.span_nbrs_sep_list[&a].to_string()));
2396 }
2397 src_wrapper_impl.push(format!(
2398 " {}self.listener.{init_fn_name}(ctx{});",
2399 if has_value { "let val = " } else { "" },
2400 if self.gen_span_params { ", spans" } else { "" }));
2401 let ret = if has_value {
2402 format!("-> {};", self.get_nt_type(nt as VarId))
2403 } else {
2404 src_listener_decl.push(" #[allow(unused_variables)]".to_string());
2405 "{}".to_string()
2406 };
2407 src_listener_decl.push(format!(
2408 " fn {init_fn_name}(&mut self, ctx: InitCtx{nu}{}) {ret}",
2409 if self.gen_span_params { ", spans: Vec<PosSpan>" } else { "" }));
2410
2411 let ret = if has_value { format!(" -> {}", self.get_nt_type(nt as VarId)) } else { String::new() };
2413 src_skel.push(format!(
2414 " fn {init_fn_name}(&mut self, ctx: InitCtx{nu}{}){ret} {{",
2415 if self.gen_span_params { ", spans: Vec<PosSpan>" } else { "" }));
2416 let a_id = self.var_alts[nt][0];
2417 let a_info = &item_info[a_id as usize];
2418 if !a_info.is_empty() {
2419 let comment = format!(
2420 "value of `{}` before {}",
2421 self.item_ops[a_id as usize][1..].iter().map(|s| s.to_str(self.get_symbol_table())).join(" "),
2422 self.full_alt_components(a_id, None).1
2423 );
2424 let ctx_content = a_info.iter().map(|i| i.name.clone()).join(", ");
2425 let a_name = &alt_info[a_id as usize].as_ref().unwrap().1;
2426 src_skel.push(format!(" // {comment}"));
2427 src_skel.push(format!(" let InitCtx{nu}::{a_name} {{ {ctx_content} }} = ctx;"));
2428 }
2429 has_skel_init = true;
2430 } else {
2431 src_wrapper_impl.push(format!(" let val = self.listener.{init_fn_name}();"));
2432 src_listener_decl.push(format!(" fn {init_fn_name}(&mut self) -> {};", self.get_nt_type(nt as VarId)));
2433 src_skel.push(format!(" fn {init_fn_name}(&mut self) -> {} {{", self.get_nt_type(nt as VarId)));
2434 has_skel_init = true;
2435 }
2436 if has_value {
2437 src_wrapper_impl.push(format!(" self.stack.push(EnumSynValue::{nu}(val));"));
2438 }
2439 } else if is_sep_list {
2440 let endpoints = child_repeat_endpoints.get(var).unwrap();
2443 let (src_val, val_name) = self.source_child_repeat_lets(endpoints, &item_info, is_plus, &nt_name, &init_fn_name, nu, true);
2444 src_wrapper_impl.extend(src_val);
2445 src_wrapper_impl.push(format!(" self.stack.push(EnumSynValue::{nu}(Syn{nu}(vec![{val_name}])));"));
2446 } else {
2447 src_wrapper_impl.push(format!(" let val = Syn{nu}(Vec::new());"));
2448 src_wrapper_impl.push(format!(" self.stack.push(EnumSynValue::{nu}(val));"));
2449 }
2450 src_wrapper_impl.push(" }".to_string());
2451 } else if is_lform {
2452 init_nt_done.insert(*var);
2453 src_init.push(vec![format!(" {nt} => self.listener.{init_fn_name}(),"), nt_comment]);
2454 src_listener_decl.push(format!(" fn {init_fn_name}(&mut self) {{}}"));
2455 } else {
2456 }
2458 } else {
2459 }
2461 if has_skel_init {
2462 if has_value {
2463 src_skel.push(format!(" {}()", self.get_nt_type(nt as VarId)));
2464 }
2465 src_skel.push(" }".to_string());
2466 src_skel.push(String::new());
2467 }
2468
2469 if !is_ambig_redundant && flags & ruleflag::CHILD_L_FACT == 0 {
2473 let mut has_skel_exit = false;
2474 let mut has_skel_exit_return = false;
2475 let (pnu, _pnl, pnpl) = &nt_name[parent_nt];
2477 if VERBOSE { println!(" {nu} (parent {pnu})"); }
2478 let no_method = !has_value && flags & ruleflag::CHILD_REPEAT_LFORM == ruleflag::CHILD_REPEAT;
2479 let is_rrec_lform = self.nt_has_all_flags(*var, ruleflag::R_RECURSION | ruleflag::L_FORM);
2480 let (fnpl, fnu, fnt, f_valued) = if is_ambig_1st_child {
2481 (pnpl, pnu, parent_nt, parent_has_value) } else {
2483 (npl, nu, nt, has_value)
2484 };
2485 if is_parent || (is_child_repeat_lform && !no_method) || is_ambig_1st_child {
2486 let extra_param = if self.gen_span_params { ", spans: Vec<PosSpan>" } else { "" };
2487 if f_valued {
2488 let nt_type = self.get_nt_type(fnt as VarId);
2489 if is_rrec_lform || (is_child_repeat_lform) {
2490 src_listener_decl.push(format!(" fn exit_{fnpl}(&mut self, acc: &mut {nt_type}, ctx: Ctx{fnu}{extra_param});"));
2491 src_skel.push(format!(" fn exit_{fnpl}(&mut self, acc: &mut {nt_type}, ctx: Ctx{fnu}{extra_param}) {{"));
2492 } else {
2493 src_listener_decl.push(format!(" fn exit_{fnpl}(&mut self, ctx: Ctx{fnu}{extra_param}) -> {nt_type};"));
2494 src_skel.push(format!(" fn exit_{fnpl}(&mut self, ctx: Ctx{fnu}{extra_param}) -> {nt_type} {{"));
2495 has_skel_exit_return = true;
2496 }
2497 } else {
2498 src_listener_decl.push(" #[allow(unused_variables)]".to_string());
2499 src_listener_decl.push(format!(" fn exit_{fnpl}(&mut self, ctx: Ctx{fnu}{extra_param}) {{}}"));
2500 src_skel.push(format!(" fn exit_{fnpl}(&mut self, ctx: Ctx{fnu}{extra_param}) {{"));
2501 }
2502 has_skel_exit = true;
2503 }
2504 let all_exit_alts = if is_ambig_1st_child {
2505 ambig_op_alts.values().rev().map(|v| v[0]).to_vec()
2506 } else {
2507 self.gather_alts(nt as VarId)
2508 };
2509 let (last_it_alts, exit_alts) = all_exit_alts.into_iter()
2510 .partition::<Vec<_>, _>(|f|
2511 (flags & ruleflag::CHILD_L_RECURSION != 0
2512 || flags & (ruleflag::CHILD_REPEAT_LFORM | ruleflag::REPEAT_PLUS) == ruleflag::CHILD_REPEAT_LFORM)
2513 && self.is_alt_sym_empty(*f));
2514 if VERBOSE {
2515 println!(" no_method: {no_method}, exit alts: {}", exit_alts.iter().join(", "));
2516 if !last_it_alts.is_empty() {
2517 println!(" last_it_alts: {}", last_it_alts.iter().join(", "));
2518 }
2519 }
2520
2521 if has_skel_exit {
2523 if let Some(alts) = &nt_contexts[fnt] {
2524 let mut skel_ctx = vec![];
2525 for &a_id in alts {
2526 if let Some((_, variant)) = alt_info[a_id as usize].as_ref() {
2527 let comment = self.full_alt_str(a_id, None, false);
2528 let fields = self.source_infos(&item_info[a_id as usize], false, false);
2529 let ctx_content = if fields.is_empty() {
2530 String::new()
2531 } else {
2532 format!(" {{ {fields} }}")
2533 };
2534 skel_ctx.push((comment, variant, ctx_content));
2535 }
2536 }
2537 match skel_ctx.len() {
2538 0 => {}
2539 1 => {
2540 let (comment, variant, ctx_content) = skel_ctx.pop().unwrap();
2541 src_skel.push(format!(" // {comment}"));
2542 src_skel.push(format!(" let Ctx{fnu}::{variant}{ctx_content} = ctx;"));
2543 }
2544 _ => {
2545 src_skel.push(" match ctx {".to_string());
2546 for (comment, variant, ctx_content) in skel_ctx {
2547 src_skel.push(format!(" // {comment}"));
2548 src_skel.push(format!(" Ctx{fnu}::{variant}{ctx_content} => {{}}"));
2549 }
2550 src_skel.push(" }".to_string());
2551 }
2552 }
2553 if has_skel_exit_return {
2554 src_skel.push(format!(" {}()", self.get_nt_type(fnt as VarId)));
2555 }
2556 src_skel.push(" }".to_string());
2557 src_skel.push(String::new());
2558 } else {
2559 panic!("no alts for NT {fnpl} [{fnt}]");
2560 }
2561 }
2562
2563 for f in &exit_alts {
2564 exit_alt_done.insert(*f);
2565 }
2566 let inter_or_exit_name = if flags & ruleflag::PARENT_L_RECURSION != 0 { format!("inter_{npl}") } else { format!("exit_{npl}") };
2567 let fn_name = exit_fixer.get_unique_name(inter_or_exit_name.clone());
2568 let (is_alt_id, choices) = self.make_match_choices(&exit_alts, &fn_name, flags, no_method, None);
2569 if VERBOSE { println!(" choices: {}", choices.iter().map(|s| s.trim()).join(" ")); }
2570 let comments = exit_alts.iter().map(|f| {
2571 let (v, pf) = &self.parsing_table.alts[*f as usize];
2572 if MATCH_COMMENTS_SHOW_DESCRIPTIVE_ALTS {
2573 format!("// {}", self.full_alt_str(*f, None, false))
2574 } else {
2575 format!("// {}", pf.to_rule_str(*v, self.get_symbol_table(), self.parsing_table.flags[*v as usize]))
2576 }
2577 }).to_vec();
2578 src_exit.extend(choices.into_iter().zip(comments).map(|(a, b)| vec![a, b]));
2579 if is_ambig_1st_child {
2580 for (a_id, dup_alts) in ambig_op_alts.values().rev().filter_map(|v| if v.len() > 1 { v.split_first() } else { None }) {
2581 let (_, choices) = self.make_match_choices(dup_alts, &fn_name, 0, no_method, Some(*a_id));
2584 let comments = dup_alts.iter()
2585 .map(|a| {
2586 let (v, alt) = &pinfo.alts[*a as usize];
2587 format!("// {} (duplicate of {a_id})", alt.to_rule_str(*v, self.get_symbol_table(), 0))
2588 }).to_vec();
2589 src_exit.extend(choices.into_iter().zip(comments).map(|(a, b)| vec![a, b]));
2590 for a in dup_alts {
2591 exit_alt_done.insert(*a);
2592 }
2593 }
2594 }
2595 if !no_method {
2596 src_wrapper_impl.push(String::new());
2597 src_wrapper_impl.push(format!(" fn {fn_name}(&mut self{}) {{", if is_alt_id { ", alt_id: AltId" } else { "" }));
2598 }
2599 if flags & ruleflag::CHILD_REPEAT_LFORM == ruleflag::CHILD_REPEAT {
2600 if has_value {
2601 let endpoints = child_repeat_endpoints.get(var).unwrap();
2602 let (src_val, val_name) = self.source_child_repeat_lets(endpoints, &item_info, is_plus, &nt_name, &fn_name, nu, false);
2603 src_wrapper_impl.extend(src_val);
2604 let vec_name = if is_plus { "plus_acc" } else { "star_acc" };
2605 src_wrapper_impl.push(format!(" let Some(EnumSynValue::{nu}(Syn{nu}({vec_name}))) = self.stack.last_mut() else {{"));
2606 src_wrapper_impl.push(format!(" panic!(\"expected Syn{nu} item on wrapper stack\");"));
2607 src_wrapper_impl.push(" };".to_string());
2608 src_wrapper_impl.push(format!(" {vec_name}.push({val_name});"));
2609 }
2610 } else {
2611 assert!(!no_method, "no_method is not expected here (only used in +* with no lform)");
2612 let (mut last_alt_ids, exit_info_alts): (Vec<AltId>, Vec<AltId>) = exit_alts.into_iter()
2613 .partition(|i| alt_info[*i as usize].is_none());
2614 let fnu = if is_child_repeat_lform { nu } else { pnu }; let fnpl = if is_child_repeat_lform { npl } else { pnpl }; let a_has_value = if is_child_repeat_lform { has_value } else { parent_has_value };
2617 let is_single = exit_info_alts.len() == 1;
2618 let indent = if is_single { " " } else { " " };
2619 if !is_single {
2620 if self.gen_span_params {
2621 src_wrapper_impl.push(" let (n, ctx) = match alt_id {".to_string());
2622 } else {
2623 src_wrapper_impl.push(" let ctx = match alt_id {".to_string());
2624 }
2625 }
2626 if VERBOSE { println!(" exit_alts -> {exit_info_alts:?}, last_alt_id -> {last_alt_ids:?}"); }
2627 let spans_param = if self.gen_span_params { ", spans" } else { "" };
2628 for a in exit_info_alts {
2629 if VERBOSE {
2630 println!(" - ALTERNATIVE {a}: {} -> {}",
2631 Symbol::NT(*var).to_str(self.get_symbol_table()),
2632 self.parsing_table.alts[a as usize].1.to_str(self.get_symbol_table()));
2633 }
2634 let last_alt_id_maybe = if last_alt_ids.is_empty() { None } else { Some(last_alt_ids.remove(0)) };
2635 if !is_single {
2636 let last_alt_choice = if let Some(last_alt_id) = last_alt_id_maybe { format!(" | {last_alt_id}") } else { String::new() };
2637 src_wrapper_impl.push(format!(" {a}{last_alt_choice} => {{", ));
2638 }
2639 let (src_let, ctx_params) = Self::source_lets(&item_info[a as usize], &nt_name, indent, last_alt_id_maybe);
2640 src_wrapper_impl.extend(src_let);
2641 let ctx = if ctx_params.is_empty() {
2642 format!("Ctx{fnu}::{}", alt_info[a as usize].as_ref().unwrap().1)
2643 } else {
2644 format!("Ctx{fnu}::{} {{ {ctx_params} }}", alt_info[a as usize].as_ref().unwrap().1)
2645 };
2646 if is_single {
2647 src_wrapper_impl.push(format!(" let ctx = {ctx};"));
2648 if self.gen_span_params {
2649 src_wrapper_impl.extend(Self::source_update_span(&self.span_nbrs[a as usize].to_string()));
2650
2651 }
2652 } else {
2653 let ctx_value = self.gen_match_item(ctx, || self.span_nbrs[a as usize].to_string());
2654 src_wrapper_impl.push(format!("{indent}{ctx_value}"));
2655 src_wrapper_impl.push(" }".to_string());
2656 }
2657 }
2658 if !is_single {
2659 src_wrapper_impl.push(format!(" _ => panic!(\"unexpected alt id {{alt_id}} in fn {fn_name}\")"));
2660 src_wrapper_impl.push(" };".to_string());
2661 if self.gen_span_params {
2662 src_wrapper_impl.extend(Self::source_update_span("n"));
2663 }
2664 }
2665 if (is_rrec_lform | is_child_repeat_lform) && f_valued {
2666 src_wrapper_impl.push(
2667 format!(" let Some(EnumSynValue::{fnu}(acc)) = self.stack.last_mut() else {{ panic!() }};"));
2668 src_wrapper_impl.push(
2669 format!(" self.listener.exit_{fnpl}(acc, ctx{spans_param});"));
2670 } else {
2671 src_wrapper_impl.push(format!(
2672 " {}self.listener.exit_{fnpl}(ctx{spans_param});",
2673 if a_has_value { "let val = " } else { "" }));
2674 if a_has_value {
2675 src_wrapper_impl.push(format!(" self.stack.push(EnumSynValue::{fnu}(val));"));
2676 }
2677 }
2678 }
2679 if !no_method {
2680 src_wrapper_impl.push(" }".to_string());
2681 }
2682 for a in last_it_alts {
2683 assert_eq!(flags, pinfo.flags[nt]);
2684 let owner_maybe = if flags & ruleflag::CHILD_REPEAT_LFORM == ruleflag::CHILD_REPEAT_LFORM {
2687 Some(*var)
2688 } else if flags & ruleflag::CHILD_L_RECURSION != 0 {
2689 pinfo.parent[nt]
2690 } else {
2691 None
2692 };
2693 if let Some(owner) = owner_maybe {
2694 if self.nt_value[owner as usize] {
2695 let (variant, _, fnname) = &nt_name[owner as usize];
2696 let typ = self.get_nt_type(owner);
2697 let varname = if is_child_repeat_lform { "acc" } else { fnname };
2698 if VERBOSE { println!(" exitloop{fnname}({varname}) owner = {}", Symbol::NT(owner).to_str(self.get_symbol_table())); }
2699 src_listener_decl.push(" #[allow(unused_variables)]".to_string());
2700 src_listener_decl.push(format!(" fn exitloop_{fnname}(&mut self, {varname}: &mut {typ}) {{}}"));
2701 let (v, pf) = &self.parsing_table.alts[a as usize];
2702 let alt_str = if MATCH_COMMENTS_SHOW_DESCRIPTIVE_ALTS {
2703 self.full_alt_str(a, None, false)
2704 } else {
2705 pf.to_rule_str(*v, self.get_symbol_table(), self.parsing_table.flags[*v as usize])
2706 };
2707 src_exit.push(vec![format!(" {a} => self.exitloop_{fnpl}(),"), format!("// {alt_str}")]);
2708 exit_alt_done.insert(a);
2709 src_wrapper_impl.push(String::new());
2710 src_wrapper_impl.push(format!(" fn exitloop_{fnpl}(&mut self) {{"));
2711 src_wrapper_impl.push(format!(" let EnumSynValue::{variant}({varname}) = self.stack.last_mut().unwrap(){};",
2712 if syns.len() > 1 { " else { panic!() }" } else { "" }));
2713 src_wrapper_impl.push(format!(" self.listener.exitloop_{fnname}({varname});"));
2714 src_wrapper_impl.push(" }".to_string());
2715 }
2716 }
2717 }
2718 }
2719 }
2720 for a in group.iter().flat_map(|v| &self.var_alts[*v as usize]).filter(|a| !exit_alt_done.contains(a)) {
2721 let is_called = self.opcodes[*a as usize].contains(&OpCode::Exit(*a));
2722 let (v, alt) = &self.parsing_table.alts[*a as usize];
2723 let alt_str = if MATCH_COMMENTS_SHOW_DESCRIPTIVE_ALTS {
2724 self.full_alt_str(*a, None, false)
2725 } else {
2726 alt.to_rule_str(*v, self.get_symbol_table(), self.parsing_table.flags[*v as usize])
2727 };
2728 let comment = format!("// {alt_str} ({})", if is_called { "not used" } else { "never called" });
2729 if is_called {
2730 src_exit.push(vec![format!(" {a} => {{}}"), comment]);
2731 } else {
2732 src_exit.push(vec![format!(" /* {a} */"), comment]);
2733 }
2734 }
2735 let mut seg_init = Segments::from_iter(
2737 group.iter()
2738 .filter_map(|&v| if !init_nt_done.contains(&v) { Some(Seg(v as u32, v as u32)) } else { None })
2739 );
2740 seg_init.normalize();
2741 for seg in seg_init {
2742 let Seg(a, b) = seg;
2743 if a == b {
2744 src_init.push(vec![format!(" {a} => {{}}"), format!("// {}", Symbol::NT(a as VarId).to_str(self.get_symbol_table()))]);
2745 } else {
2746 src_init.push(vec![
2747 format!(" {a}{}{b} => {{}}", if b == a + 1 { " | " } else { " ..= " }),
2748 format!("// {}", (a..=b).map(|v| Symbol::NT(v as VarId).to_str(self.get_symbol_table())).join(", "))
2749 ]);
2750 }
2751 }
2752 }
2753
2754 src_types.extend(vec![
2756 String::new(),
2757 format!("// {:-<80}", ""),
2758 ]);
2759 self.log.add_info(format!("Template for the user types:\n\n{}\n", src_types.join("\n")));
2760 if let Some(line) = src_skel.last() {
2761 if line.is_empty() {
2762 src_skel.pop();
2763 }
2764 }
2765 src_skel.extend(vec![
2766 "}".to_string(),
2767 String::new(),
2768 format!("// {:-<80}", ""),
2769 ]);
2770 self.log.add_info(format!("Template for the listener implementation:\n\n{}\n", src_skel.join("\n")));
2771
2772 src.add_space();
2774 src.push(format!("pub trait {}Listener {{", self.name));
2775 src.push(" /// Checks if the listener requests an abort. This happens if an error is too difficult to recover from".to_string());
2776 src.push(" /// and may corrupt the stack content. In that case, the parser immediately stops and returns `ParserError::AbortRequest`.".to_string());
2777 src.push(" fn check_abort_request(&self) -> Terminate { Terminate::None }".to_string());
2778 src.push(" fn get_log_mut(&mut self) -> &mut impl Logger;".to_string());
2779 let extra_span = if self.gen_span_params { ", span: PosSpan" } else { "" };
2780 let extra_ref_span = if self.gen_span_params { ", span: &PosSpan" } else { "" };
2781 if !self.terminal_hooks.is_empty() {
2782 src.push(" #[allow(unused_variables)]".to_string());
2783 src.push(format!(" fn hook(&mut self, token: TokenId, text: &str{extra_ref_span}) -> TokenId {{ token }}"));
2784 }
2785 src.push(" #[allow(unused_variables)]".to_string());
2786 src.push(format!(" fn intercept_token(&mut self, token: TokenId, text: &str{extra_ref_span}) -> TokenId {{ token }}"));
2787 if self.nt_value[self.start as usize] || self.gen_span_params {
2788 src.push(" #[allow(unused_variables)]".to_string());
2789 }
2790 if self.nt_value[self.start as usize] {
2791 src.push(format!(" fn exit(&mut self, {}: {}{extra_span}) {{}}", nt_name[self.start as usize].2, self.get_nt_type(self.start)));
2792 } else {
2793 src.push(format!(" fn exit(&mut self{extra_span}) {{}}"));
2794 }
2795 src.push(" #[allow(unused_variables)]".to_string());
2796 src.push(" fn abort(&mut self, terminate: Terminate) {}".to_string());
2797 src.extend(src_listener_decl);
2805 src.push("}".to_string());
2806
2807 src.add_space();
2809 src.push("pub struct Wrapper<T> {".to_string());
2810 src.push(" verbose: bool,".to_string());
2811 src.push(" listener: T,".to_string());
2812 src.push(" stack: Vec<EnumSynValue>,".to_string());
2813 src.push(" max_stack: usize,".to_string());
2814 src.push(" stack_t: Vec<String>,".to_string());
2815 if self.gen_span_params {
2816 src.push(" stack_span: Vec<PosSpan>,".to_string());
2817 }
2818 src.push("}".to_string());
2819 src.push(String::new());
2820 src.push(format!("impl<T: {}Listener> ListenerWrapper for Wrapper<T> {{", self.name));
2821 src.push(" fn switch(&mut self, call: Call, nt: VarId, alt_id: AltId, t_data: Option<Vec<String>>) {".to_string());
2822 src.push(" if self.verbose {".to_string());
2823 src.push(" println!(\"switch: call={call:?}, nt={nt}, alt={alt_id}, t_data={t_data:?}\");".to_string());
2824 src.push(" }".to_string());
2825 src.push(" if let Some(mut t_data) = t_data {".to_string());
2826 src.push(" self.stack_t.append(&mut t_data);".to_string());
2827 src.push(" }".to_string());
2828 src.push(" match call {".to_string());
2829 src.push(" Call::Enter => {".to_string());
2830 if self.gen_span_params {
2831 let mut seg_span = Segments::from_iter(span_init.into_iter().map(|v| Seg(v as u32, v as u32)));
2833 seg_span.normalize();
2834 let pattern = seg_span.into_iter().map(|Seg(a, b)| {
2835 if a == b {
2836 a.to_string()
2837 } else if b == a + 1 {
2838 format!("{a} | {b}")
2839 } else {
2840 format!("{a} ..= {b}")
2841 }
2842 }).join(" | ");
2843 if !pattern.is_empty() {
2844 src.push(format!(" if matches!(nt, {pattern}) {{"));
2845 src.push(" self.stack_span.push(PosSpan::empty());".to_string());
2846 src.push(" }".to_string());
2847 }
2848 }
2849 src.push(" match nt {".to_string());
2850 src.extend(columns_to_str(src_init, Some(vec![64, 0])));
2856 src.push(" _ => panic!(\"unexpected enter nonterminal id: {nt}\")".to_string());
2857 src.push(" }".to_string());
2858 src.push(" }".to_string());
2859 src.push(" Call::Loop => {}".to_string());
2860 src.push(" Call::Exit => {".to_string());
2861 src.push(" match alt_id {".to_string());
2862 src.extend(columns_to_str(src_exit, Some(vec![64, 0])));
2870 src.push(" _ => panic!(\"unexpected exit alternative id: {alt_id}\")".to_string());
2871 src.push(" }".to_string());
2872 src.push(" }".to_string());
2873 src.push(" Call::End(terminate) => {".to_string());
2874 src.push(" match terminate {".to_string());
2875 src.push(" Terminate::None => {".to_string());
2876 let mut args = vec![];
2877 let (_nu, _nl, npl) = &nt_name[self.start as usize];
2878 if self.nt_value[self.start as usize] {
2879 src.push(format!(" let val = self.stack.pop().unwrap().get_{npl}();"));
2880 args.push("val");
2881 }
2882 if self.gen_span_params {
2883 src.push(" let span = self.stack_span.pop().unwrap();".to_string());
2884 args.push("span");
2885 }
2886 src.push(format!(" self.listener.exit({});", args.join(", ")));
2887 src.push(" }".to_string());
2888 src.push(" Terminate::Abort | Terminate::Conclude => self.listener.abort(terminate),".to_string());
2889 src.push(" }".to_string());
2890 src.push(" }".to_string());
2891 src.push(" }".to_string());
2892 src.push(" self.max_stack = std::cmp::max(self.max_stack, self.stack.len());".to_string());
2893 src.push(" if self.verbose {".to_string());
2894 src.push(" println!(\"> stack_t: {}\", self.stack_t.join(\", \"));".to_string());
2895 src.push(" println!(\"> stack: {}\", self.stack.iter().map(|it| format!(\"{it:?}\")).collect::<Vec<_>>().join(\", \"));".to_string());
2896 src.push(" }".to_string());
2897 src.push(" }".to_string());
2898 src.push(String::new());
2899 src.push(" fn check_abort_request(&self) -> Terminate {".to_string());
2900 src.push(" self.listener.check_abort_request()".to_string());
2901 src.push(" }".to_string());
2902 src.push(String::new());
2903 src.push(" fn abort(&mut self) {".to_string());
2904 src.push(" self.stack.clear();".to_string());
2905 if self.gen_span_params {
2906 src.push(" self.stack_span.clear();".to_string());
2907 }
2908 src.push(" self.stack_t.clear();".to_string());
2909 src.push(" }".to_string());
2910 src.push(String::new());
2911 src.push(" fn get_log_mut(&mut self) -> &mut impl Logger {".to_string());
2912 src.push(" self.listener.get_log_mut()".to_string());
2913 src.push(" }".to_string());
2914 if self.gen_span_params {
2915 src.push(String::new());
2916 src.push(" fn push_span(&mut self, span: PosSpan) {".to_string());
2917 src.push(" self.stack_span.push(span);".to_string());
2918 src.push(" }".to_string());
2919 }
2920 src.push(String::new());
2921 src.push(" fn is_stack_empty(&self) -> bool {".to_string());
2922 src.push(" self.stack.is_empty()".to_string());
2923 src.push(" }".to_string());
2924 src.push(String::new());
2925 src.push(" fn is_stack_t_empty(&self) -> bool {".to_string());
2926 src.push(" self.stack_t.is_empty()".to_string());
2927 src.push(" }".to_string());
2928 if self.gen_span_params {
2929 src.add_space();
2930 src.push(" fn is_stack_span_empty(&self) -> bool {".to_string());
2931 src.push(" self.stack_span.is_empty()".to_string());
2932 src.push(" }".to_string());
2933 }
2934 let unused_span = if self.gen_span_params { "" } else { "_" };
2935 let extra_span_arg = if self.gen_span_params { ", span" } else { "" };
2936 if !self.terminal_hooks.is_empty() {
2937 src.add_space();
2938 src.push(format!(" fn hook(&mut self, token: TokenId, text: &str, {unused_span}span: &PosSpan) -> TokenId {{"));
2939 src.push(format!(" self.listener.hook(token, text{extra_span_arg})"));
2940 src.push(" }".to_string());
2941 }
2942 src.add_space();
2943 src.push(format!(" fn intercept_token(&mut self, token: TokenId, text: &str, {unused_span}span: &PosSpan) -> TokenId {{"));
2944 src.push(format!(" self.listener.intercept_token(token, text{extra_span_arg})"));
2945 src.push(" }".to_string());
2946 src.push("}".to_string());
2947
2948 src.add_space();
2949 src.push(format!("impl<T: {}Listener> Wrapper<T> {{", self.name));
2950 src.push(" pub fn new(listener: T, verbose: bool) -> Self {".to_string());
2951 src.push(format!(
2952 " Wrapper {{ verbose, listener, stack: Vec::new(), max_stack: 0, stack_t: Vec::new(){} }}",
2953 if self.gen_span_params { ", stack_span: Vec::new()" } else { "" }
2954 ));
2955 src.push(" }".to_string());
2956 src.push(String::new());
2957 src.push(" pub fn get_listener(&self) -> &T {".to_string());
2958 src.push(" &self.listener".to_string());
2959 src.push(" }".to_string());
2960 src.push(String::new());
2961 src.push(" pub fn get_listener_mut(&mut self) -> &mut T {".to_string());
2962 src.push(" &mut self.listener".to_string());
2963 src.push(" }".to_string());
2964 src.push(String::new());
2965 src.push(" pub fn give_listener(self) -> T {".to_string());
2966 src.push(" self.listener".to_string());
2967 src.push(" }".to_string());
2968 src.push(String::new());
2969 src.push(" pub fn set_verbose(&mut self, verbose: bool) {".to_string());
2970 src.push(" self.verbose = verbose;".to_string());
2971 src.push(" }".to_string());
2972src.extend(src_wrapper_impl);
2992 src.push("}".to_string());
2993
2994 (src, src_types, src_skel)
2995 }
2996}
2997
2998impl LogReader for ParserGen {
2999 type Item = BufLog;
3000
3001 fn get_log(&self) -> &Self::Item {
3002 &self.log
3003 }
3004
3005 fn give_log(self) -> Self::Item {
3006 self.log
3007 }
3008}
3009
3010impl HasBuildErrorSource for ParserGen {
3011 const SOURCE: BuildErrorSource = BuildErrorSource::ParserGen;
3012}
3013
3014impl<T> BuildFrom<ProdRuleSet<T>> for ParserGen where ProdRuleSet<LL1>: BuildFrom<ProdRuleSet<T>> {
3015 fn build_from(mut rules: ProdRuleSet<T>) -> Self {
3021 let name = rules.name.take().unwrap_or(DEFAULT_LISTENER_NAME.to_string());
3022 ParserGen::build_from_rules(rules, name)
3023 }
3024}
3025
3026impl ParserGen {
3030
3031 pub fn get_nt_tree(&self) -> VecTree<VarId> {
3032 let mut tree = VecTree::new();
3033 let root = tree.add_root(0);
3034 let mut idx = HashMap::new();
3035 for group in self.nt_parent.iter().filter(|vf| !vf.is_empty()) {
3036 idx.clear();
3037 let tree_ids = tree.add_iter(None, group.iter().cloned()).to_vec();
3047 idx.extend(group.iter().zip(tree_ids));
3048 for &child in group.iter() {
3049 tree.attach_child(
3050 self.parsing_table.parent[child as usize]
3051 .map(|p| idx[&p])
3052 .unwrap_or(root),
3053 idx[&child]);
3054 }
3055 }
3056 tree
3057 }
3058
3059 pub fn get_indented_nt(&self) -> Vec<(VarId, String)>{
3060 let tree = self.get_nt_tree();
3061 let mut indented = vec![];
3062 let mut indent = vec![];
3063 for node in tree.iter_pre_depth_simple().skip(1) {
3064 let depth = node.depth as usize;
3065 if indent.len() < depth {
3066 indent.push((1..depth).map(|i| if i & 1 == 0 { " " } else { ". " }).join(""));
3067 }
3068 indented.push((*node, format!("{}{}", &indent[depth - 1], Symbol::NT(*node).to_str(self.get_symbol_table()))));
3069 }
3070 indented
3071 }
3072
3073 pub fn nt_info_str(&self) -> Vec<String> {
3074 let indented = self.get_indented_nt();
3075 let mut cols = vec![
3076 vec![" NT".to_string(), " name".to_string(), " val".to_string(), " flags".to_string(), String::new()]];
3077 for (v, line) in indented {
3078 let nt = v as usize;
3079 cols.push(vec![
3081 format!("| {v:3}"),
3082 format!("| {line}"),
3083 if self.nt_value[nt] { "| y".to_string() } else { "|".to_string() },
3084 format!("| {}", ruleflag::to_string(self.parsing_table.flags[nt]).join(", ")),
3086 "|".to_string(),
3087 ]);
3088 }
3089 let mut txt = columns_to_str(cols, Some(vec![3, 5, 0, 0, 0]));
3090 if let Some(max) = txt.get(1).map(|s| s.charlen()) {
3091 let sep = format!("+{:-<1$}+", "", max - 2);
3092 txt.insert(1, sep.clone());
3093 txt.push(sep);
3094 }
3095 txt
3096 }
3097
3098 pub fn log_nt_info(&mut self) {
3099 let mut txt = self.nt_info_str();
3100 txt.push(String::new());
3101 self.log.add_info("nonterminal information:");
3102 self.log.extend_messages(txt.into_iter().map(LogMsg::Info));
3103 }
3104
3105 pub fn alt_info_str(&self) -> Vec<String> {
3106 let indented = self.get_indented_nt();
3107 let mut cols = vec![
3108 vec![" NT".to_string(), " alt".to_string(), " opcodes".to_string(), " spans".to_string(), " item_ops".to_string(), String::new()]];
3109 for (v, line) in indented {
3110 let nt = v as usize;
3111 for &alt_id in &self.var_alts[nt] {
3112 let a_id = alt_id as usize;
3113 let alt = &self.parsing_table.alts[a_id].1;
3114 let opcodes = self.opcodes[a_id].iter().map(|o| o.to_str_quote(self.get_symbol_table())).join(" ");
3115 let item_ops = self.item_ops.get(a_id)
3116 .map(|ops| ops.iter().map(|s| s.to_str(self.get_symbol_table())).join(" "))
3117 .unwrap_or_else(|| "-".to_string());
3118 cols.push(vec![
3119 format!("| {v:3}"),
3120 format!("| {alt_id:4}: {line} -> {}", alt.to_str(self.get_symbol_table())),
3121 format!("| {opcodes}"),
3122 format!("| {}{}",
3123 &self.span_nbrs[a_id],
3124 if let Some(ispan) = self.span_nbrs_sep_list.get(&alt_id) { format!(", {ispan}") } else { String::new() }),
3125 format!("| {item_ops}"),
3126 "|".to_string(),
3127 ]);
3128 }
3129 }
3130 let mut txt = columns_to_str(cols, Some(vec![3, 5, 0, 0, 0, 0]));
3131 if let Some(max) = txt.get(1).map(|s| s.charlen()) {
3132 let sep = format!("+{:-<1$}+", "", max - 2);
3133 txt.insert(1, sep.clone());
3134 txt.push(sep);
3135 }
3136 txt
3137 }
3138
3139 pub fn log_alt_info(&mut self) {
3140 let mut txt = self.alt_info_str();
3141 txt.push("legend: ►nt = enter nonterminal nt, ◄0 = exit alt, ●nt = loop nonterminal, Xyz! = variable terminal, \"…\" = fixed terminal, ▲ = hook".to_string());
3142 txt.push(String::new());
3143 self.log.add_note("rule alternatives:");
3144 self.log.extend_messages(txt.into_iter().map(LogMsg::Info));
3145 }
3146
3147 pub fn print_items(&self, indent: usize, show_symbols: bool, show_span: bool) {
3148 let tbl = self.get_symbol_table();
3149 let fields = (0..self.parsing_table.alts.len())
3150 .map(|a| {
3151 let a_id = a as AltId;
3152 let (v, alt) = &self.parsing_table.alts[a];
3153 let ops = &self.opcodes[a];
3154 let it = &self.item_ops[a_id as usize];
3155 let mut cols = vec![];
3156 if show_symbols {
3157 let symbols = format!("symbols![{}]", it.iter().map(|s| s.to_macro_item()).join(", "));
3158 let value = if show_span {
3159 assert!(self.gen_span_params, "ParserGen is not configured for spans");
3160 format!("({}, {symbols})", self.span_nbrs[a_id as usize])
3161 } else {
3162 symbols
3163 };
3164 cols.push(format!("{a_id} => {value},"));
3165 }
3166 cols.extend([
3167 format!("// {a_id:2}: {} -> {}", Symbol::NT(*v).to_str(tbl), alt.iter().map(|s| s.to_str_quote(tbl)).join(" ")),
3168 format!("| {}", ops.iter().map(|s| s.to_str_quote(tbl)).join(" ")),
3169 format!(
3170 "| {}{}",
3171 &self.span_nbrs[a_id as usize],
3172 if let Some(ispan) = self.span_nbrs_sep_list.get(&a_id) { format!(", {ispan}") } else { String::new() }),
3173 format!("| {}", it.iter().map(|s| s.to_str(tbl)).join(" ")),
3174 ]);
3175 cols
3176 }).to_vec();
3177 let widths = if show_symbols { vec![40, 0, 0, 0, 0] } else { vec![16, 0, 0, 0, 0] };
3178 for l in columns_to_str(fields, Some(widths)) {
3179 println!("{:indent$}{l}", "", indent = indent)
3180 }
3181 }
3182
3183 pub fn print_flags(&self, indent: usize) {
3184 let tbl: Option<&SymbolTable> = self.get_symbol_table();
3185 let prefix = format!("{:width$}//", "", width = indent);
3186 let nt_flags = self.get_parsing_table().flags.iter().index().filter_map(|(nt, &f)|
3187 if f != 0 { Some(format!("{prefix} - {}: {} ({})", Symbol::NT(nt).to_str(tbl), ruleflag::to_string(f).join(" | "), f)) } else { None }
3188 ).join("\n");
3189 let parents = self.get_parsing_table().parent.iter().index().filter_map(|(c, &par)|
3190 par.map(|p| format!("{prefix} - {} -> {}", Symbol::NT(c).to_str(tbl), Symbol::NT(p).to_str(tbl)))
3191 ).join("\n");
3192 if !nt_flags.is_empty() {
3193 println!("{prefix} NT flags:\n{nt_flags}");
3194 }
3195 if !parents.is_empty() {
3196 println!("{prefix} parents:\n{parents}");
3197 }
3198 }
3199}