1#![allow(dead_code)]
17#![allow(unused_variables)]
18#![allow(non_snake_case)]
19#![allow(non_camel_case_types)]
20#![allow(unused_parens)]
21#![allow(unused_mut)]
22#![allow(unused_assignments)]
23#![allow(unused_doc_comments)]
24#![allow(unused_imports)]
25use std::fmt::Display;
26use std::default::Default;
27use std::collections::{HashMap,HashSet,BTreeSet};
28use std::io::{self,Read,Write,BufReader,BufRead};
29use std::rc::Rc;
30use std::cell::{RefCell,Ref,RefMut};
31use std::hash::{Hash,Hasher};
32use std::any::Any;
33use std::fs::File;
34use std::io::prelude::*;
35use std::path::Path;
36use std::mem;
37use crate::{Stateaction,iserror,TerminalToken,Tokenizer};
39use crate::{LBox,LRc,LC};
40use crate::Stateaction::*;
41use crate::{lbup,lbdown,lbget};
42use crate::{StandardReporter,StackedItem};
43#[cfg(feature = "generator")]
44use crate::{Statemachine};
45
46#[derive(Clone)]
53pub struct ZCRProduction<AT:Default,ET:Default> {
55 pub lhs: &'static str, pub Ruleaction : fn(&mut ZCParser<AT,ET>) -> AT, }
58impl<AT:Default,ET:Default> ZCRProduction<AT,ET>
59{
60 pub fn new_skeleton(lh:&'static str) -> ZCRProduction<AT,ET>
61 {
62 ZCRProduction {
63 lhs : lh,
64 Ruleaction : |p|{ <AT>::default() },
65 }
66 }
67}pub struct ZCParser<AT:Default,ET:Default>
98{
99 pub exstate : ET, pub shared_state : Rc<RefCell<ET>>,
110 pub RSM : Vec<HashMap<&'static str,Stateaction>>, pub Rules : Vec<ZCRProduction<AT,ET>>, stopparsing : bool,
118 pub stack : Vec<StackedItem<AT>>, pub resynch : HashSet<&'static str>,
122 pub Errsym : &'static str,
123 err_occurred : bool,
124 pub linenum : usize,
127 pub column : usize,
128 pub position : usize, pub prev_position : usize,
130 pub src_id : usize,
131 report_line : usize,
132 pub Symset : HashSet<&'static str>,
134 popped : Vec<(usize,usize)>,
136 gindex : RefCell<u32>, err_report : Option<String>, }impl<AT:Default,ET:Default> ZCParser<AT,ET>
142{
143 pub fn new(rlen:usize, slen:usize) -> ZCParser<AT,ET>
147 { let mut p = ZCParser {
149 RSM : Vec::with_capacity(slen),
150 Rules : Vec::with_capacity(rlen),
152 stopparsing : false,
153 exstate : ET::default(),
154 shared_state: Rc::new(RefCell::new(ET::default())),
155 stack : Vec::with_capacity(1024),
156 Errsym : "",
157 err_occurred : false,
158 linenum : 0,
159 column : 0,
160 position : 0,
161 prev_position: 0,
162 src_id : 0,
163 report_line : 0,
164 resynch : HashSet::new(),
165 Symset : HashSet::with_capacity(64),
169 popped: Vec::with_capacity(8),
171 gindex: RefCell::new(0),
172 err_report : None,
173 };
174 for _ in 0..slen {
175 p.RSM.push(HashMap::with_capacity(16));
176 }
178 return p;
179 }pub fn current_line(&self)->usize {self.linenum}
183 pub fn current_column(&self)->usize {self.column}
185 pub fn current_position(&self)->usize {self.position}
187 pub fn previous_position(&self)->usize {self.prev_position}
189
190 pub fn abort(&mut self, msg:&str)
194 {
195 self.err_report.as_mut().map_or_else(
196 ||eprintln!("\n!!!Parsing Aborted: {}",msg),
197 |x|x.push_str(&format!("\n!!!Parsing Aborted: {}\n",msg)));
198
199 self.err_occurred = true;
200 self.stopparsing=true;
201 }
202
203
204 pub fn stop(&mut self) {
207 self.stopparsing = true;
208 }
209
210 pub fn report(&mut self, errmsg:&str) {self.report_error(errmsg,false)}
213 pub fn report_error(&mut self, errmsg:&str, showlc: bool)
215 {
216 if (self.report_line != self.linenum || self.linenum==0) {
218 if showlc {
219 self.err_report.as_mut().map_or_else(
220 ||eprintln!("ERROR on line {}, column {}: {}",self.linenum,self.column,errmsg),
221 |x|x.push_str(&format!("ERROR on line {}, column {}: {}\n",self.linenum,self.column,errmsg)));
222 }
223 else {
224 self.err_report.as_mut().map_or_else(
225 ||eprintln!("PARSER ERROR: {}",errmsg),
226 |x|x.push_str(&format!("PARSER ERROR: {}\n",errmsg)));
227 }
228 self.report_line = self.linenum;
229 }
230 else {
231 if showlc {
232 self.err_report.as_mut().map_or_else(
233 ||eprint!(" ({},{}): {}",self.linenum,self.column,errmsg),
234 |x|x.push_str(&format!(" ({},{}): {}",self.linenum,self.column,errmsg)));
235 }
236 else {
237 self.err_report.as_mut().map_or_else(
238 ||eprint!(" {}",errmsg),
239 |x|{x.push(' '); x.push_str(errmsg)});
240 }
241 }
242 self.err_occurred = true;
244 }pub fn bad_pattern(&mut self,pattern:&str) -> AT
248 {
249 let msg = format!("pattern {} failed to bind to stacked values\n",pattern);
250 self.report(&msg);
251 AT::default()
253 }
254
255fn errshift(&mut self, sym:&str) -> bool
266 {
267 let csi = self.stack[self.stack.len()-1].si; let actionopt = self.RSM[csi].get(sym);
269 if let Some(Shift(ni)) = actionopt {
270 self.stack.push(StackedItem::new(*ni,AT::default(),self.linenum,self.column)); true
271 }
272 else {false}
273 }
274
275 fn shift<'t>(&mut self, nextstate:usize, lookahead:TerminalToken<'t,AT>, tokenizer:&mut dyn Tokenizer<'t,AT>) -> TerminalToken<'t, AT>
279 {
280 self.linenum = lookahead.line; self.column=lookahead.column;
281 self.prev_position = self.position; self.position = tokenizer.position();
282 self.stack.push(StackedItem::new(nextstate,lookahead.value,lookahead.line,lookahead.column));
283 tokenizer.next_tt()
285 }
286
287 pub fn popstack(&mut self) -> StackedItem<AT>
291 {
292 let item = self.stack.pop().expect("PARSER STATE MACHINE/STACK CORRUPTED");
293 self.linenum = item.line; self.column=item.column;
294 self.popped.push((item.line,item.column));
295 item
296 }pub fn popstack_as_lbox(&mut self) -> LBox<AT>
299 {
300 let item = self.stack.pop().expect("PARSER STATE MACHINE/STACK CORRUPTED");
301 self.linenum = item.line; self.column=item.column;
302 self.popped.push((item.line,item.column));
303 let newuid = *self.gindex.borrow();
304 *self.gindex.borrow_mut() += 1;
305 LBox::make(item.value,item.line,item.column,newuid)
306 }fn reduce(&mut self, ri:&usize)
309 {
310 self.popped.clear();
311 let rulei = &self.Rules[*ri];
312 let ruleilhs = rulei.lhs; let val = (rulei.Ruleaction)(self); let newtop = self.stack[self.stack.len()-1].si;
316 let goton = self.RSM[newtop].get(ruleilhs).expect("PARSER STATEMACHINE CORRUPTED");
317 if let Stateaction::Gotonext(nsi) = goton {
318self.stack.push(StackedItem::new(*nsi,val,self.linenum,self.column));
325 }else {
328 self.report("state transition table corrupted: no suitable action after reduce");
329 self.stopparsing=true;
330 }
331 }pub fn error_occurred(&self) -> bool {self.err_occurred}
336
337 pub fn lb<T>(&self,e:T) -> LBox<T> {
346 let newuid = *self.gindex.borrow();
347 *self.gindex.borrow_mut() += 1;
348 LBox::make(e,self.linenum,self.column,newuid)
349 }
350 pub fn lba<T:'static>(&self,e:T) -> LBox<dyn Any> {
353 let newuid = *self.gindex.borrow();
354 *self.gindex.borrow_mut() += 1;
355 LBox::upcast(LBox::make(e,self.linenum,self.column,newuid))
356 }
357 pub fn lrc<T>(&self,e:T) -> LRc<T> { LRc::new(e,self.linenum,self.column ) }
359 pub fn lrca<T:'static>(&self,e:T) -> LRc<dyn Any> { LRc::upcast(LRc::new(e,self.linenum,self.column )) }
361
362 pub fn lbx<T>(&self,i:usize,e:T) -> LBox<T>
365 {
366 let (mut ln,mut cl) = (self.linenum,self.column);
367 if i<self.popped.len() {
368 let index = self.popped.len() - 1 - i;
369 let lc = self.popped[index];
370 ln = lc.0; cl=lc.1;
371 }
372 let newuid = *self.gindex.borrow();
373 *self.gindex.borrow_mut() += 1;
374 LBox::make(e,ln,cl,newuid)
375 }pub fn lbox<T>(&self,i:usize,e:T) -> LBox<T> { self.lbx(i,e) }
379
380 pub fn lc<T>(&self,i:usize,e:T) -> LC<T>
383 {
384 let (mut ln,mut cl) = (self.linenum,self.column);
385 if i<self.popped.len() {
386 let index = self.popped.len() - 1 - i;
387 let lc = self.popped[index];
388 ln = lc.0; cl=lc.1;
389 }
390 let uid = *self.gindex.borrow();
391 *self.gindex.borrow_mut() += 1;
392 LC::make(e,ln,cl,uid)
393 }pub fn lrcn<T>(&self,i:usize,e:T) -> LRc<T>
397 {
398 let (mut ln,mut cl) = (self.linenum,self.column);
399 if i<self.popped.len() {
400 let index = self.popped.len() - 1 - i;
401 let lc = self.popped[index];
402 ln = lc.0; cl=lc.1;
403 }
404 LRc::new(e,ln,cl)
405 }}#[cfg(feature = "generator")]
413impl Statemachine
414{ pub fn writezcparser(&self, filename:&str)->Result<(),std::io::Error>
416 {
417 let ref absyn = self.Gmr.Absyntype;
418 let ref extype = self.Gmr.Externtype;
419 let ref lifetime = self.Gmr.lifetime;
420 let has_lt = lifetime.len()>0 && (absyn.contains(lifetime) || extype.contains(lifetime));
421 let ltopt = if has_lt {format!("<{}>",lifetime)} else {String::from("")};
422
423 let mut fd = File::create(filename)?;
424 write!(fd,"//Parser generated by rustlr for grammar {}",&self.Gmr.name)?;
425 write!(fd,"\n
426#![allow(unused_variables)]
427#![allow(non_snake_case)]
428#![allow(non_camel_case_types)]
429#![allow(unused_parens)]
430#![allow(unused_mut)]
431#![allow(unused_imports)]
432#![allow(unused_assignments)]
433#![allow(dead_code)]
434#![allow(irrefutable_let_patterns)]
435#![allow(unreachable_patterns)]
436use std::rc::Rc;
437use std::cell::RefCell;
438extern crate rustlr;
439use rustlr::{{Tokenizer,TerminalToken,ZCParser,ZCRProduction,Stateaction,decode_action}};\n")?;
440 if self.Gmr.genlex {
441 write!(fd,"use rustlr::{{StrTokenizer,RawToken,LexSource}};
442use std::collections::{{HashMap,HashSet}};\n")?;
443 }
444
445 write!(fd,"{}\n",&self.Gmr.Extras)?; write!(fd,"static SYMBOLS:[&'static str;{}] = [",self.Gmr.Symbols.len())?;
449 for i in 0..self.Gmr.Symbols.len()-1
450 {
451 write!(fd,"\"{}\",",&self.Gmr.Symbols[i].sym)?;
452 }
453 write!(fd,"\"{}\"];\n\n",&self.Gmr.Symbols[self.Gmr.Symbols.len()-1].sym)?;
454 let mut totalsize = 0;
458 for i in 0..self.FSM.len() { totalsize+=self.FSM[i].len(); }
459 write!(fd,"static TABLE:[u64;{}] = [",totalsize)?;
460 let mut encode:u64 = 0;
462 for i in 0..self.FSM.len() {
464 let row = &self.FSM[i]; for key in row.keys()
466 { let k = *key; encode = ((i as u64) << 48) + ((k as u64) << 32);
469 match row.get(key) {
470 Some(Shift(statei)) => { encode += (*statei as u64) << 16; },
471 Some(Gotonext(statei)) => { encode += ((*statei as u64) << 16)+1; },
472 Some(Reduce(rulei)) => { encode += ((*rulei as u64) << 16)+2; },
473 Some(Accept) => {encode += 3; },
474 _ => {encode += 4; }, }write!(fd,"{},",encode)?;
477 } }write!(fd,"];\n\n")?;
480
481 write!(fd,"pub fn make_parser{}() -> ZCParser<{},{}>",<opt,absyn,extype)?;
483 write!(fd,"\n{{\n")?;
484 write!(fd," let mut parser1:ZCParser<{},{}> = ZCParser::new({},{});\n",absyn,extype,self.Gmr.Rules.len(),self.FSM.len())?;
486 write!(fd," let mut rule = ZCRProduction::<{},{}>::new_skeleton(\"{}\");\n",absyn,extype,"start")?;
488 for i in 0..self.Gmr.Rules.len()
489 {
490 write!(fd," rule = ZCRProduction::<{},{}>::new_skeleton(\"{}\");\n",absyn,extype,self.Gmr.Rules[i].lhs.sym)?;
491 write!(fd," rule.Ruleaction = |parser|{{ ")?;
492 let mut k = self.Gmr.Rules[i].rhs.len();
493
494 let mut labels = String::from("(");
496 let mut patterns = String::from("(");
497 while k>0 {
499 let mut boxedlabel = false; let gsym = &self.Gmr.Rules[i].rhs[k-1];
501 let findat = gsym.label.find('@');
502 let mut plab = format!("_item{}_",k-1);
503 match &findat {
504 None if gsym.label.len()>0 && !gsym.label.contains('(') => {
505 let rawlabel = gsym.label.trim();
506 let truelabel = checkboxlabel(rawlabel);
507 boxedlabel = truelabel != rawlabel;
508 plab = String::from(truelabel);
509 },
511 Some(ati) if *ati>0 => {
512 let rawlabel = gsym.label[0..*ati].trim();
513 let truelabel = checkboxlabel(rawlabel);
514 boxedlabel = truelabel != rawlabel;
515 plab = String::from(truelabel);
516 },
517 _ => {},
518 }let poppedlab = plab.as_str();
520 if !boxedlabel {
521 write!(fd,"let mut {} = parser.popstack(); ",poppedlab)?;
522 } else {
523 write!(fd,"let mut {} = parser.popstack_as_lbox(); ",poppedlab)?;
524 }
525
526 if gsym.label.len()>1 && findat.is_some() { let atindex = findat.unwrap();
528 if atindex>0 { labels.push_str("&mut "); if boxedlabel {labels.push('*');}
532 labels.push_str(poppedlab); labels.push_str(".value,");
533 }
535 else { labels.push_str(poppedlab); labels.push_str(".value,");
537 }
538 patterns.push_str(&gsym.label[atindex+1..]); patterns.push(',');
539 } else if gsym.label.len()>0 && gsym.label.contains('(') { labels.push_str(poppedlab); labels.push_str(".value,");
543 patterns.push_str(&gsym.label[..]); patterns.push(',')
545 }k -= 1;
548 }let defaultaction = format!("<{}>::default()}}",absyn);
551 let mut semaction = &self.Gmr.Rules[i].action; if semaction.len()<=1 {semaction = &defaultaction;}
553 if labels.len()<2 { write!(fd,"{};\n",semaction.trim_end())?; } else { labels.push(')'); patterns.push(')');
556 write!(fd,"\n if let {}={} {{ {} else {{parser.bad_pattern(\"{}\")}} }};\n",&patterns,&labels,semaction.trim_end(),&patterns)?;
557 }write!(fd," parser1.Rules.push(rule);\n")?;
560 }write!(fd," parser1.Errsym = \"{}\";\n",&self.Gmr.Errsym)?;
562 for s in &self.Gmr.Resynch {write!(fd," parser1.resynch.insert(\"{}\");\n",s)?;}
564
565 write!(fd,"\n for i in 0..{} {{\n",totalsize)?;
567 write!(fd," let symi = ((TABLE[i] & 0x0000ffff00000000) >> 32) as usize;\n")?;
568 write!(fd," let sti = ((TABLE[i] & 0xffff000000000000) >> 48) as usize;\n")?;
569 write!(fd," parser1.RSM[sti].insert(SYMBOLS[symi],decode_action(TABLE[i]));\n }}\n\n")?;
570write!(fd," for s in SYMBOLS {{ parser1.Symset.insert(s); }}\n\n")?;
573
574 write!(fd," load_extras(&mut parser1);\n")?;
575 write!(fd," return parser1;\n")?;
576 write!(fd,"}} //make_parser\n\n")?;
577
578 let lexerlt = if has_lt {<opt} else {"<'t>"};
580 let traitlt = if has_lt {&self.Gmr.lifetime} else {"'t"};
581 let lexername = format!("{}lexer{}",&self.Gmr.name,lexerlt);
582 let abindex = *self.Gmr.enumhash.get(absyn).unwrap();
583 write!(fd,"pub fn parse_with{}(parser:&mut ZCParser<{},{}>, lexer:&mut dyn Tokenizer<{},{}>) -> Result<{},{}>\n{{\n",lexerlt,absyn,extype,traitlt,absyn,absyn,absyn)?;
584 write!(fd," let _xres_ = parser.parse(lexer); ")?;
585 write!(fd," if !parser.error_occurred() {{Ok(_xres_)}} else {{Err(_xres_)}}\n}}//parse_with public function\n")?;
586 write!(fd,"\npub fn parse_train_with{}(parser:&mut ZCParser<{},{}>, lexer:&mut dyn Tokenizer<{},{}>, parserpath:&str) -> Result<{},{}>\n{{\n",lexerlt,absyn,extype,traitlt,absyn,absyn,absyn)?;
588 write!(fd," let _xres_ = parser.parse_train(lexer,parserpath); ")?;
589 write!(fd," if !parser.error_occurred() {{Ok(_xres_)}} else {{Err(_xres_)}}\n}}//parse_train_with public function\n")?;
590
591
592 if self.Gmr.genlex { self.Gmr.genlexer(&mut fd,"from_raw")?; }
594
595 write!(fd,"fn load_extras{}(parser:&mut ZCParser<{},{}>)\n{{\n",<opt,absyn,extype)?;
597 write!(fd,"}}//end of load_extras: don't change this line as it affects augmentation\n")?;
598 Ok(())
599 }pub fn writelbaparser(&self, filename:&str)->Result<(),std::io::Error>
608 {
609 let ref absyn = self.Gmr.Absyntype;
610
611 if !is_lba(absyn) {
612 return self.writezcparser(filename);
613 }
614
615 let ref extype = self.Gmr.Externtype;
616 let ref lifetime = self.Gmr.lifetime;
617 let has_lt = lifetime.len()>0 && (absyn.contains(lifetime) || extype.contains(lifetime));
618 let ltopt = if has_lt {format!("<{}>",lifetime)} else {String::from("")};
619
620 let rlen = self.Gmr.Rules.len();
621 let mut actions:Vec<String> = Vec::with_capacity(rlen);
623 for ri in 0..rlen
624 {
625 let lhs = &self.Gmr.Rules[ri].lhs.sym;
626 let lhsi = &self.Gmr.Rules[ri].lhs.index;
627 let rettype = &self.Gmr.Symbols[*lhsi].rusttype; let ltoptr = if has_lt || (lifetime.len()>0 && rettype.contains(lifetime))
630 {format!("<{}>",lifetime)} else {String::from("")};
631 let mut fndef = format!("fn _semaction_for_{}_{}(parser:&mut ZCParser<{},{}>) -> {} {{\n",ri,<optr,absyn,extype,rettype);
632
633 let mut k = self.Gmr.Rules[ri].rhs.len();
634 let mut labels = String::from("(");
636 let mut patterns = String::from("(");
637 while k>0 {
639 let gsym = &self.Gmr.Rules[ri].rhs[k-1]; let gsymi = gsym.index; let findat = gsym.label.find('@');
642 let mut plab = format!("_item{}_",k-1);
643 match &findat {
644 None if gsym.label.len()>0 => {plab = format!("{}",&gsym.label);},
645 Some(ati) if *ati>0 => {plab=format!("{}",&gsym.label[0..*ati]);},
646 _ => {},
647 }let poppedlab = plab.as_str();
649 let ref symtype = self.Gmr.Symbols[gsymi].rusttype; let mut stat = format!("let mut {} = lbdown!(parser.popstack().value,{}); ",poppedlab,symtype); if symtype.len()<2 || symtype=="LBox<dyn Any>" || symtype=="LBox<Any>" {
652 stat = format!("let mut {} = parser.popstack().value; ",poppedlab);
653 }
655 fndef.push_str(&stat);
656 if gsym.label.len()>1 && findat.is_some() { labels.push_str("&mut *"); labels.push_str(poppedlab); labels.push(',');
660 let atindex = findat.unwrap();
662 patterns.push_str(&gsym.label[atindex+1..]); patterns.push(',');
663 } k -= 1;
665 }let defaultaction = format!("<{}>::default()}}",rettype);
668 let mut semaction = &self.Gmr.Rules[ri].action; if semaction.len()<=1 {semaction = &defaultaction;}
670 if labels.len()<2 {
671 fndef.push_str(semaction.trim_end()); fndef.push_str("\n");
672 } else { labels.push(')'); patterns.push(')');
675 let pat2= format!("\n if let {}={} {{ {} else {{parser.report(\"{}\"); <{}>::default()}} }}\n",&patterns,&labels,semaction.trim_end(),&patterns,rettype);
676 fndef.push_str(&pat2);
677 }actions.push(fndef);
679 }let mut fd = File::create(filename)?;
684 write!(fd,"//Parser generated by rustlr for grammar {}",&self.Gmr.name)?;
685 write!(fd,"\n
686#![allow(unused_variables)]
687#![allow(non_snake_case)]
688#![allow(non_camel_case_types)]
689#![allow(unused_parens)]
690#![allow(unused_mut)]
691#![allow(unused_imports)]
692#![allow(unused_assignments)]
693#![allow(dead_code)]
694#![allow(irrefutable_let_patterns)]
695use std::any::Any;
696use std::rc::Rc;
697use std::cell::RefCell;
698extern crate rustlr;
699use rustlr::{{Tokenizer,TerminalToken,ZCParser,ZCRProduction,Stateaction,decode_action,LBox,lbdown,lbup,lbget,unbox}};\n")?;
700 if self.Gmr.genlex {
701 write!(fd,"use rustlr::{{StrTokenizer,RawToken,LexSource}};
702use std::collections::{{HashMap,HashSet}};\n")?;
703 }
704
705 write!(fd,"{}\n",&self.Gmr.Extras)?; write!(fd,"static SYMBOLS:[&'static str;{}] = [",self.Gmr.Symbols.len())?;
709 for i in 0..self.Gmr.Symbols.len()-1
710 {
711 write!(fd,"\"{}\",",&self.Gmr.Symbols[i].sym)?;
712 }
713 write!(fd,"\"{}\"];\n\n",&self.Gmr.Symbols[self.Gmr.Symbols.len()-1].sym)?;
714 let mut totalsize = 0;
718 for i in 0..self.FSM.len() { totalsize+=self.FSM[i].len(); }
719 write!(fd,"static TABLE:[u64;{}] = [",totalsize)?;
720 let mut encode:u64 = 0;
722 for i in 0..self.FSM.len() {
724 let row = &self.FSM[i]; for key in row.keys()
726 { let k = *key; encode = ((i as u64) << 48) + ((k as u64) << 32);
729 match row.get(key) {
730 Some(Shift(statei)) => { encode += (*statei as u64) << 16; },
731 Some(Gotonext(statei)) => { encode += ((*statei as u64) << 16)+1; },
732 Some(Reduce(rulei)) => { encode += ((*rulei as u64) << 16)+2; },
733 Some(Accept) => {encode += 3; },
734 _ => {encode += 4; }, }write!(fd,"{},",encode)?;
737 } }write!(fd,"];\n\n")?;
740
741 for deffn in &actions { write!(fd,"{}",deffn)?; }
743
744 write!(fd,"\npub fn make_parser{}() -> ZCParser<{},{}>",<opt,absyn,extype)?;
746 write!(fd,"\n{{\n")?;
747 write!(fd," let mut parser1:ZCParser<{},{}> = ZCParser::new({},{});\n",absyn,extype,self.Gmr.Rules.len(),self.FSM.len())?;
749 write!(fd," let mut rule = ZCRProduction::<{},{}>::new_skeleton(\"{}\");\n",absyn,extype,"start")?; for i in 0..self.Gmr.Rules.len()
752 {
753 write!(fd," rule = ZCRProduction::<{},{}>::new_skeleton(\"{}\");\n",absyn,extype,self.Gmr.Rules[i].lhs.sym)?;
754 write!(fd," rule.Ruleaction = |parser|{{ ")?;
755
756 let lhsi = self.Gmr.Symhash.get(&self.Gmr.Rules[i].lhs.sym).expect("GRAMMAR REPRESENTATION CORRUPTED");
758 let fnname = format!("_semaction_for_{}_",i);
759 let typei = &self.Gmr.Symbols[*lhsi].rusttype;
760 if is_lba(typei) {
761 write!(fd," {}(parser) }};\n",&fnname)?;
762 }
763 else {
764 write!(fd," lbup!( LBox::new({}(parser),parser.linenum,parser.column)) }};\n",&fnname)?;
765 }
766 write!(fd," parser1.Rules.push(rule);\n")?;
767 }write!(fd," parser1.Errsym = \"{}\";\n",&self.Gmr.Errsym)?;
771 for s in &self.Gmr.Resynch {write!(fd," parser1.resynch.insert(\"{}\");\n",s)?;}
773
774 write!(fd,"\n for i in 0..{} {{\n",totalsize)?;
776 write!(fd," let symi = ((TABLE[i] & 0x0000ffff00000000) >> 32) as usize;\n")?;
777 write!(fd," let sti = ((TABLE[i] & 0xffff000000000000) >> 48) as usize;\n")?;
778 write!(fd," parser1.RSM[sti].insert(SYMBOLS[symi],decode_action(TABLE[i]));\n }}\n\n")?;
779write!(fd," for s in SYMBOLS {{ parser1.Symset.insert(s); }}\n\n")?;
782
783 write!(fd," load_extras(&mut parser1);\n")?;
784 write!(fd," return parser1;\n")?;
785 write!(fd,"}} //make_parser\n\n")?;
786
787 if !self.Gmr.sametype { self.Gmr.gen_enum(&mut fd)?; }
789
790 if self.Gmr.genlex { self.Gmr.genlexer(&mut fd,"raw_to_lba")?; }
792
793 write!(fd,"fn load_extras{}(parser:&mut ZCParser<{},{}>)\n{{\n",<opt,absyn,extype)?;
795 write!(fd,"}}//end of load_extras: don't change this line as it affects augmentation\n")?;
796 Ok(())
797 }} #[cfg(feature = "generator")]
815 fn is_lba(t:&str) -> bool {
816 t.trim().starts_with("LBox") && t.contains("Any") && t.contains('<') && t.contains('>')
817
818}impl<AT:Default,ET:Default> ZCParser<AT,ET>
829{
830 pub fn error_recover<'t>(&mut self, lookahead:&mut TerminalToken<'t,AT>, tokenizer:&mut dyn Tokenizer<'t,AT>) -> Option<Stateaction>
835 {
836 let mut erraction = None;
837 if self.Errsym.len()>0 {
839 let errsym = self.Errsym;
840 let mut k = self.stack.len(); let mut spos = k+1;
844 while k>0 && spos>k
845 {
846 let ksi = self.stack[k-1].si;
847 erraction = self.RSM[ksi].get(errsym);
848 if let None = erraction {k-=1;} else {spos=k;}
849 }if spos==k { self.stack.truncate(k); } while let Some(Reduce(ri)) = erraction {
854 self.popped.clear();
856 let rulei = &self.Rules[*ri];
857 let ruleilhs = rulei.lhs; let val = (rulei.Ruleaction)(self);
860 let newtop = self.stack[self.stack.len()-1].si;
861 let gotonopt = self.RSM[newtop].get(ruleilhs);
862 match gotonopt {
863 Some(Gotonext(nsi)) => {
864 self.stack.push(StackedItem::new(*nsi,val,self.linenum,self.column));
866 },_ => {self.abort("recovery failed"); },
868 }let tos=self.stack[self.stack.len()-1].si;
872 erraction = self.RSM[tos].get(self.Errsym).clone();
873 } if let Some(Shift(i)) = erraction { self.stack.push(StackedItem::new(*i,AT::default(),lookahead.line,lookahead.column));
877 while let None = self.RSM[*i].get(lookahead.sym) {
883 if lookahead.sym=="EOF" {break;}
884 *lookahead = tokenizer.next_tt();
885 }erraction = self.RSM[*i].get(lookahead.sym);
888 } }if iserror(&erraction) && self.resynch.len()>0 {
894 while lookahead.sym!="EOF" &&
895 !self.resynch.contains(lookahead.sym) {
896 self.linenum = lookahead.line; self.column = lookahead.column; self.prev_position=self.position; self.position = tokenizer.position();
897 *lookahead = tokenizer.next_tt();
898 }if lookahead.sym!="EOF" {
900 self.linenum = lookahead.line; self.column = lookahead.column; self.prev_position=self.position; self.position=tokenizer.position();
902 *lookahead = tokenizer.next_tt();
903 }
904 let mut k = self.stack.len()-1; let mut position = 0;
906 while k>0 && erraction==None
907 {
908 let ksi = self.stack[k-1].si;
909 erraction = self.RSM[ksi].get(lookahead.sym);
910 if let None=erraction {k-=1;}
911 }match erraction {
913 None => {}, _ => { self.stack.truncate(k);},}}let mut eofcx = 0;
921 while iserror(&erraction) && eofcx<1 { self.linenum = lookahead.line; self.column = lookahead.column; self.prev_position=self.position; self.position=tokenizer.position();
923 *lookahead = tokenizer.next_tt();
924 if lookahead.sym=="EOF" {eofcx+=1;}
926 let csi =self.stack[self.stack.len()-1].si;
927 erraction = self.RSM[csi].get(lookahead.sym);
928 }match erraction {
930 Some(act) if eofcx<1 => Some(*act),
931 _ => None,
932 }}pub fn reset(&mut self) {
937 self.stack.clear();
938 self.err_occurred = false;
939 let mut result = AT::default();
940 self.exstate = ET::default();
941 }pub fn get_err_report(&self) -> &str {
947 self.err_report.as_deref().unwrap_or("")
948 }
949
950 pub fn set_err_report(&mut self, onof:bool) {
958 if onof {self.err_report = Some(String::new());}
959 else {self.err_report = None;}
960 }
961
962
963}pub trait ErrReporter<AT:Default,ET:Default> {
980 fn err_reporter(&mut self, parser:&mut ZCParser<AT,ET>, lookahead:&TerminalToken<AT>, erropt:&Option<Stateaction>, tokenizer:& dyn Tokenizer<'_,AT>);
981 fn report_err(&self, parser:&mut ZCParser<AT,ET>, msg:&str) { parser.report(msg) }
982}impl<AT:Default,ET:Default> ErrReporter<AT,ET> for StandardReporter
995{
996 fn err_reporter(&mut self, parser:&mut ZCParser<AT,ET>, lookahead:&TerminalToken<AT>, erropt:&Option<Stateaction>, tokenizer:& dyn Tokenizer<'_,AT>)
998 {
999 let mut wresult:std::io::Result<()> = Err(std::io::Error::new(std::io::ErrorKind::Other,"")); let cstate = parser.stack[parser.stack.len()-1].si; let mut actionopt = if let Some(act)=erropt {Some(act)} else {None};
1003 let lksym = &lookahead.sym[..];
1004 if parser.Symset.contains(lksym) {
1007 if let None=actionopt {
1008 actionopt = parser.RSM[cstate].get("ANY_ERROR");
1009 }
1010 }else {
1012 actionopt = parser.RSM[cstate].get("ANY_ERROR");
1013 }let mut errmsg = if let Some(Error(em)) = &actionopt {
1015 format!("unexpected symbol '{}' on line {}, column {}: ** {} ** ..",lksym,lookahead.line,lookahead.column,em.trim())
1016 } else {format!("unexpected symbol '{}' on line {}, column {} .. ",lksym,lookahead.line,lookahead.column)};
1017
1018 let srcline = tokenizer.current_line();
1020 if (srcline.len()>0) {
1021 errmsg.push_str("\n >>");
1022 errmsg.push_str(srcline);
1023 errmsg.push_str("\n");
1024 let mut cln = lookahead.column+2;
1025 while cln>0 { errmsg.push(' '); cln-=1; }
1026 let mut tokenlen = lookahead.sym.len();
1028 if is_alphanum(&lookahead.sym) {tokenlen = 3;}
1029 while tokenlen>0 { errmsg.push('^'); tokenlen-=1; }
1030 errmsg.push('\n');
1031 }parser.report(&errmsg);
1034
1035 if self.training { let csym = lookahead.sym.to_owned();
1037 let mut inp = String::from("");
1038 if let None=self.scriptinopt { if let Some(outfd1) = &self.scriptoutopt {
1040 let mut outfd = outfd1;
1041 print!("\n>>>TRAINER: if this message is not adequate (for state {}), enter a replacement (default no change): ",cstate);
1042 let rrrflush = io::stdout().flush();
1043 if let Ok(n) = io::stdin().read_line(&mut inp) {
1044 if inp.len()>5 && parser.Symset.contains(lksym) {
1045 print!(">>>TRAINER: should this message be given for all unexpected symbols in the current state? (default yes) ");
1046 let rrrflush2 = io::stdout().flush();
1047 let mut inp2 = String::new();
1048 if let Ok(n) = io::stdin().read_line(&mut inp2) {
1049 if inp2.trim()=="no" || inp2.trim()=="No" {
1050 wresult = write!(outfd,"{}\t{}\t{} ::: {}\n",lookahead.line,lookahead.column,&csym,inp.trim());
1051 self.trained.insert((cstate,csym),inp);
1052 }
1053 else {wresult = write!(outfd,"{}\t{}\t{} ::: {}\n",lookahead.line,lookahead.column,"ANY_ERROR",inp.trim());
1055 self.trained.insert((cstate,String::from("ANY_ERROR")),inp);
1056 }
1057 }}else if inp.len()>5 && !parser.Symset.contains(lksym) {
1060 wresult = write!(outfd,"{}\t{}\t{} ::: {}\n",lookahead.line,lookahead.column,"ANY_ERROR",inp.trim());
1061 self.trained.insert((cstate,String::from("ANY_ERROR")),inp);
1062 }
1063 }}}else { if let Some(brfd) = &mut self.scriptinopt {
1067 let mut scin = brfd;
1068 let mut readn = 0;
1069 while readn < 1
1070 {
1071 inp = String::new();
1072 match scin.read_line(&mut inp) {
1073 Ok(n) if n>1 && &inp[0..1]!="#" && inp.trim().len()>0 => {readn=n;},
1074 Ok(n) if n>0 => { readn=0; }, _ => {readn = 1; } }if readn>1 { let inpsplit:Vec<&str> = inp.split_whitespace().collect();
1079 if inpsplit.len()>4 && inpsplit[3].trim()==":::" {
1080 let inline = inpsplit[0].trim().parse::<usize>().unwrap();
1081 let incolumn = inpsplit[1].trim().parse::<usize>().unwrap();
1082 let insym = inpsplit[2].trim();
1083 if parser.linenum==inline && parser.column==incolumn {
1084 if &csym==insym || insym=="ANY_ERROR" {
1085 let posc = inp.find(":::").unwrap()+4;
1086 println!("\n>>>Found matching entry from training script for {}, error message: {}",insym,&inp[posc..]);
1087 self.trained.insert((cstate,String::from(insym)),String::from(&inp[posc..]));
1088 } }}}}}}}}}impl<AT:Default,ET:Default> ZCParser<AT,ET>
1103{
1104 pub fn parse_core<'u,'t:'u>(&mut self, tokenizer:&'u mut dyn Tokenizer<'t,AT>, err_handler:&mut dyn ErrReporter<AT,ET>) -> AT
1110 {
1111 self.stack.clear();
1112 self.err_occurred = false;
1113 let mut result = AT::default();
1114 self.stack.push(StackedItem::new(0,AT::default(),0,0));
1116 self.stopparsing = false;
1117 let mut action = Stateaction::Error("");
1118 let mut lookahead = TerminalToken::new("EOF",AT::default(),0,0); if let Some(tok) = tokenizer.nextsym() {lookahead=tok;}
1121 while !self.stopparsing
1124 {
1125 let tos = self.stack.len()-1;
1126 self.linenum = self.stack[tos].line;
1127 self.column=self.stack[tos].column;
1128 let currentstate = self.stack[tos].si;
1131 let mut actionopt = self.RSM[currentstate].get(lookahead.sym);
1132
1133 if actionopt.is_none() && lookahead.sym!="EOF" { actionopt = self.RSM[currentstate].get("_WILDCARD_TOKEN_");
1135 lookahead = tokenizer.transform_wildcard(lookahead);
1137 }
1138
1139 let actclone:Option<Stateaction> = match actionopt {
1140 Some(a) => Some(*a),
1141 None => None,
1142 };
1143 if iserror(&actionopt) { if !self.err_occurred {self.err_occurred = true;}
1145
1146 err_handler.err_reporter(self,&lookahead,&actclone, tokenizer);
1147
1148 match self.error_recover(&mut lookahead,tokenizer) {
1149 None => { self.stopparsing=true; break; }
1150 Some(act) => {action = act;}, }}else { action = actclone.unwrap(); }
1154 match &action {
1155 Shift(nextstate) => {
1156 lookahead = self.shift(*nextstate,lookahead,tokenizer);
1157 },
1158 Reduce(rulei) => { self.reduce(rulei); },
1159 Accept => {
1160 self.stopparsing=true;
1161 if self.stack.len()>0 {result = self.stack.pop().unwrap().value;}
1162 else {self.err_occurred=true;}
1163 },
1164 _ => {}, }}return result;
1168 }pub fn parse<'t>(&mut self, tokenizer:&mut dyn Tokenizer<'t,AT>) -> AT
1172 {
1173 let mut stdeh = StandardReporter::new();
1174 self.parse_core(tokenizer,&mut stdeh)
1175 }pub fn parse_train<'t>(&mut self, tokenizer:&mut dyn Tokenizer<'t,AT>, parserfile:&str) -> AT
1216 {
1217 let mut stdtrainer = StandardReporter::new_interactive_training(parserfile);
1218 let result = self.parse_core(tokenizer,&mut stdtrainer);
1219 if let Err(m) = stdtrainer.augment_training(parserfile) {
1220 eprintln!("Error in augmenting parser: {:?}",m)
1221 }
1222
1223 return result;
1224 }pub fn train_from_script<'t>(&mut self, tokenizer:&mut dyn Tokenizer<'t,AT>,parserfile:&str, scriptfile:&str)
1245 {
1246 let mut stdtrainer = StandardReporter::new_script_training(parserfile,scriptfile);
1247 let result = self.parse_core(tokenizer,&mut stdtrainer);
1248 if let Err(m) = stdtrainer.augment_training(parserfile) {
1249 eprintln!("Error in augmenting parser: {:?}",m)
1250 }
1251 if !self.err_occurred {println!("no errors encountered during parsing");}
1252 }}#[cfg(feature = "generator")]
1256fn checkboxlabel(s:&str) -> &str
1257{
1258 if s.starts_with('[') && s.ends_with(']') {s[1..s.len()-1].trim()} else {s}
1259}fn is_alphanum(x:&str) -> bool
1263{
1264
1265if x.len()<1 {return false};
1269 let mut chars = x.chars();
1270 let first = chars.next().unwrap();
1271 if !(first=='_' || first.is_alphabetic()) {return false;}
1272 for c in chars
1273 {
1274 if !(c=='_' || c.is_alphanumeric()) {return false;}
1275 }
1276 true
1277}