1#![allow(dead_code)]
65#![allow(unused_variables)]
66#![allow(non_snake_case)]
67#![allow(non_camel_case_types)]
68#![allow(unused_parens)]
69#![allow(unused_assignments)]
70#![allow(unused_doc_comments)]
71#![allow(unused_imports)]
72
73mod shared_defs;
74pub use shared_defs::*;
75#[cfg(feature = "generator")]
76mod grammar_processor;
77#[cfg(feature = "generator")]
78use grammar_processor::*;
79#[cfg(feature = "generator")]
80mod lr_statemachine;
81#[cfg(feature = "generator")]
82use lr_statemachine::*;
83pub mod lexer_interface;
84pub use lexer_interface::*;
85pub mod runtime_parser;
86pub use runtime_parser::*;
87mod augmenter;
88use augmenter::*;
89pub mod generic_absyn;
90pub use generic_absyn::*;
91pub mod zc_parser;
92#[cfg(feature = "generator")]
93mod parser_writer;
94#[cfg(feature = "generator")]
95mod sd_parserwriter;
96#[cfg(feature = "generator")]
97mod fs_parserwriter;
98#[cfg(feature = "generator")]
99mod ast_writer;
100#[cfg(feature = "generator")]
101mod fs_astwriter;
102#[cfg(feature = "generator")]
103mod bumpast_writer;
104#[cfg(feature = "generator")]
105mod lalr_statemachine;
106#[cfg(feature = "generator")]
107mod selmlk; pub mod base_parser; pub use base_parser::{BaseParser,BaseProduction};
111
112#[cfg(feature = "generator")]
115mod yacc_ast;
116#[cfg(feature = "generator")]
117mod yaccparser;
118#[cfg(feature = "generator")]
119use lalr_statemachine::LALRMachine;
120#[cfg(feature = "generator")]
121use selmlk::{MLStatemachine};
122pub use zc_parser::{ZCParser,ZCRProduction};
123#[cfg(feature = "legacy-parser")]
124pub use runtime_parser::{RuntimeParser,RProduction,StackedItem};
125
126pub const RUSTLRVERSION:&'static str = "0.6.1";
127
128#[cfg(feature = "generator")]
139pub fn generate(argv:&str) -> Result<String,String> {
140 let asplit:Vec<_> = argv.split_whitespace().collect();
141 rustle1(&asplit)
142}
143
144
145#[cfg(feature = "generator")]
148pub fn rustle(args:&Vec<String>) -> Result<String,String> {
150 let mut args2 = Vec::new();
151 for s in args { args2.push(&s[..]); }
152 rustle1(&args2[..])
153}
154#[cfg(feature = "generator")]
155fn rustle1(args:&[&str]) -> Result<String,String> {
157 let argc = args.len();
158 if argc<2 {
159 return Err("Must give path of .grammar file".to_owned());
161 }
162 let mut filepath = "";
163 let mut parserfile = String::from(""); let mut lalr = false; let mut newlalr = true;
166 let mut tracelev:usize = 1; let mut verbose = false;
168 let mut zc = false;
169 let mut newbase = true;
170 let mut genlex = false;
171 let mut genabsyn = false;
172 let mut lrsd = false;
173 let mut lrsdmaxk:usize = selmlk::MAXK;
174 let mut regenerate = false;
175 let mut mode = 0;
176 let mut conv_yacc = false;
177 let mut inlinetable = true;
178 let mut argi = 1; while argi<argc
180 {
181 match args[argi] {
182 filen if filen.ends_with(".grammar") => {filepath = args[argi];},
183 filen if filen.ends_with(".y") => {
184 filepath=args[argi];
185 conv_yacc=true;
186 break;
187 },
188 "lr1" | "LR1" | "-lr1" => { lalr=false; newlalr=false; },
189 "lalr" | "LALR" | "-lalr" => {newlalr=true; },
190 "lalr1" | "LALR1" | "-lalr1" => {newlalr=true; },
191 "oldlalr" | "-oldlalr" | "-selML" => {newlalr=false; lalr=true;}
192 "-lrsd" | "lrsd" => {
193 newlalr=false; lalr=false; lrsd=true;
194 if argi+1<argc {
195 if let Ok(mk)=args[argi+1].parse::<usize>() {
196 lrsdmaxk=mk; argi+=1;
197 } }},
200 "-regenerate" => { regenerate=true; },
201 "-fsharp" => {mode=1;},
202 "-trace" => {
203 argi+=1;
204 if argi<argc {
205 if let Ok(lv) = args[argi].parse::<usize>() {tracelev=lv; }
206 if tracelev>0 {println!("trace-level set to {}",tracelev);}
207 }
208 },
209 "-table" => { inlinetable = false; },
210 "verbose" | "-verbose" => { verbose=true; },
211 "-zc" | "zero_copy" => {zc=true; newbase=false;},
212 "-newbase" | "-base" => {newbase = true; zc=false; genabsyn=true; genlex=true;},
213 "genlex" | "-genlex" => {genlex=true; },
214 "-genabsyn" | "-ast" | "-auto" => {genabsyn = true; },
215 "-nozc" => {zc=false;},
216 "binary" | "-binary" => { verbose=false; },
217 "-o" => {
218 argi+=1;
219 if argi<argc {parserfile = String::from(args[argi]);}
220 },
221 _ => {},
222 }argi+=1;
224 }if filepath.len()==0 {
227 return Err("Must give path of .grammar file or .y file to convert from".to_owned());
229 }
230 if conv_yacc {
231 yaccparser::convert_from_yacc(filepath);
232 return Ok(String::new());
233 }
235
236 if zc && verbose {
237 return Err("verbose mode not compatible with -zc option".to_owned());
239 }
240 if tracelev>0 && verbose {println!("verbose parsers should be used for diagnositic purposes and cannot be trained/augmented");}
241 if tracelev>1 {println!("parsing grammar from {}",&filepath);}
242 let mut grammar1 = Grammar::new();
243 grammar1.genlex = genlex;
244 grammar1.genabsyn = genabsyn;
245 grammar1.tracelev = tracelev;
246 grammar1.mode = mode; let parsedok = grammar1.parse_grammar(filepath); if !parsedok {
250 return Err(format!("\nFailed to process grammar at {}",filepath));
252 }
253 if grammar1.name.len()<2 { let doti = if let Some(p)= filepath.rfind('.') {p} else {filepath.len()};
256 let mut slashi = if let Some(p) = filepath.rfind('/') {p+1} else {0};
257 if slashi==0 {
258 slashi = if let Some(p) = filepath.rfind('\\') {p+1} else {0};
259 }
260 grammar1.name = filepath[slashi..doti].to_string();
261 }let gramname = grammar1.name.clone();
263
264 let pfsuffix = if mode==1 {"fs"} else {"rs"};
265
266 let slashpos = parserfile.rfind('/').or(parserfile.rfind('\\'));
267 if grammar1.genabsyn {
269 let mut astpath = format!("{}_ast.{}",&gramname,pfsuffix);
270 if let Some(pos) = slashpos { astpath=format!("{}{}",&parserfile[..pos+1],&astpath); }
271 let wres;
272 if mode==1 {wres = grammar1.write_fsast(&astpath); }
273 else if !grammar1.bumpast { wres = grammar1.writeabsyn(&astpath); }
274 else {wres = grammar1.write_bumpast(&astpath); }
275 if !wres.is_ok() {
276 return Err("Failed to generate abstract syntax".to_owned());
278 }
279 }
280 if !inlinetable {
281 let mut fsmpath = format!("{}_table.fsm",&gramname);
282 if let Some(pos) = slashpos { fsmpath=format!("{}{}",&parserfile[..pos+1],&fsmpath); }
283 grammar1.tablefile = fsmpath;
284 }
285
286 grammar1.delay_transform(); if tracelev>2 {println!("computing Nullable set");}
290 grammar1.compute_NullableRf();
291 if tracelev>2 {println!("computing First sets");}
292 grammar1.compute_First();
294
295 let mut fsm0;
296 if lrsd {
297 grammar1.logprint(&format!("Generating Experimental LR-Selective Delay State Machine with Max Delay = {}",lrsdmaxk));
298 let mut lrsdfsm = MLStatemachine::new(grammar1);
299 lrsdfsm.regenerate = regenerate;
300 lrsdfsm.selml(lrsdmaxk);
301 if lrsdfsm.failed {
303 return Err("LR SELECTIVE DELAY FAILURE. NO PARSER GENERATED".to_owned());
305 }
306 if !lrsdfsm.failed && lrsdfsm.regenerate {
307 lrsdfsm.Gmr.logprint("Re-Generating LR(1) machine for transformed grammar...");
308 lrsd = false;
309 fsm0 = Statemachine::new(lrsdfsm.Gmr);
310 fsm0.lalr = false;
311 fsm0.generatefsm(); } else { fsm0 = lrsdfsm.to_statemachine(); }
313 } else if newlalr { grammar1.logprint("Generating LALR(1) state machine");
320 let mut lalrfsm = LALRMachine::new(grammar1);
321 lalrfsm.generatefsm();
322 fsm0 = lalrfsm.to_statemachine();
323 }
324 else {
325 grammar1.logprint(&format!("Generating {} state machine for grammar {}...",if lalr {"older LALR"} else {"LR1"},&gramname));
326 fsm0 = Statemachine::new(grammar1);
327 fsm0.lalr = lalr;
328 if lalr {fsm0.Open = Vec::with_capacity(1024); } fsm0.generatefsm(); } if tracelev>2 && !newlalr && !lrsd { for state in &fsm0.States {printstate(state,&fsm0.Gmr);} }
332 else if tracelev>1 && !newlalr && !lrsd { printstate(&fsm0.States[0],&fsm0.Gmr); }if parserfile.len()<1 || parserfile.ends_with('/') || parserfile.ends_with('\\') {parserfile.push_str(&format!("{}parser.{}",&gramname,pfsuffix));}
334 if fsm0.States.len()>65536 {
335 return Err(format!("too many states: {} execeeds limit of 65536",fsm0.States.len()));
336 }
337 let write_result =
338 if mode==1 { fsm0.writefsparser(&parserfile) }
339 else if newbase && !lrsd {
340 fsm0.writebaseenumparser(&parserfile)
341 }
342 else if newbase && lrsd {
343 fsm0.writelrsdbaseparser(&parserfile)
344 }
345 else if zc { if !lrsd {fsm0.writeenumparser(&parserfile)}
349 else {fsm0.writelrsdparser(&parserfile)}
350 }
351 else { if verbose {fsm0.write_verbose(&parserfile)}
353 else {fsm0.writeparser(&parserfile)}
354 }; fsm0.Gmr.logprint(&format!("{} total states",fsm0.FSM.len()));
357 if let Ok(_) = write_result {
358 fsm0.Gmr.logprint(&format!("Parser saved in {}",&parserfile));
359 }
360 else if let Err(err) = write_result {
361 return Err(format!("failed to write parser, likely due to invalid -o destination\n{:?}",err));
362 }
363 let mut savedlog = String::new();
364 if tracelev==0 {fsm0.Gmr.swap_log(&mut savedlog);}
365 Ok(savedlog)
366}