1mod lempar;
205
206use lempar::LemparReader;
207
208use std::mem;
209use std::cmp;
210use std::cmp::Ordering;
211use std::collections::HashMap;
212use std::cell::RefCell;
213use std::io::{self, BufRead, BufReader};
214use std::fmt;
215use std::hash::{Hash, Hasher};
216use std::collections::hash_map::DefaultHasher;
217use std::error::Error;
218use std::iter::Take;
219use std::slice::Iter;
220use std::convert::TryFrom;
221use std::rc::Rc;
222use std::sync::Arc;
223use std::fs::File;
224use std::borrow::Cow;
225
226fn typename_to_string(value: String) -> String
227{ let value_trimmed = value.trim();
228 if value_trimmed.is_empty() || value.starts_with('(') && value.ends_with(')') && value[1 .. value.len()-1].trim().is_empty()
229 { String::new()
230 }
231 else
232 { if value.len() == value_trimmed.len() {value} else {value_trimmed.to_string()}
233 }
234}
235
236fn is_terminal_name(s: &str) -> bool
237{ s.find(|c: char| c.is_ascii_lowercase()).is_none()
238}
239
240#[derive(Debug)]
241pub struct LemonMintError
242{ pub filename: Arc<String>,
243 pub n_line: usize,
244 pub message: String,
245}
246impl LemonMintError
247{ pub fn new(filename: &Arc<String>, n_line: usize, message: String) -> Self
248 { Self {filename: Arc::clone(filename), n_line, message}
249 }
250}
251impl fmt::Display for LemonMintError
252{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
253 { let message: &str = if self.message.is_empty() {"Unspecified error"} else {&self.message};
254 if self.filename.is_empty()
255 { write!(f, "{}", message)
256 }
257 else
258 { write!(f, "{}({}): {}", self.filename, self.n_line, message)
259 }
260 }
261}
262impl Error for LemonMintError {}
263
264type ParserResult<T> = Result<T, LemonMintError>;
265
266#[derive(Copy, Clone, Eq, PartialEq, Debug)]
267enum Directive
268{ Rule,
269 TokenType,
270 Type,
271 DefaultType,
272 StartSymbol,
273 Trace,
274 ExtraArgument,
275 Left,
276 Right,
277 Nonassoc,
278 Fallback,
279 Code,
280}
281
282#[derive(Copy, Clone, Eq, PartialEq, Debug)]
283enum SymbolType
284{ TERMINAL,
285 NONTERMINAL
286}
287
288#[derive(Copy, Clone, Eq, PartialEq, Debug)]
289enum Associativity
290{ LEFT,
291 RIGHT,
292 NONASSOC,
293 UNKNOWN
294}
295
296#[derive(Debug)]
297struct Set
298{ data: Vec<bool>,
299}
300impl Set
301{ pub fn new(size: usize) -> Self
302 { let mut this = Self {data: Vec::new()};
303 if size > 0
304 { this.set_size(size);
305 }
306 this
307 }
308
309 pub fn len(&self) -> usize
310 { self.data.len()
311 }
312
313 pub fn set_size(&mut self, size: usize)
314 { self.data.clear();
315 self.data.resize(size, false);
316 }
317
318 pub fn contains(&self, element: usize) -> bool
319 { *self.data.get(element).unwrap_or(&false)
320 }
321
322 pub fn add(&mut self, element: usize) -> bool
323 { let rv = self.contains(element);
324 if let Some(v) = self.data.get_mut(element)
325 { *v = true;
326 }
327 !rv
328 }
329
330 pub fn intersect(&mut self, other: &Set) -> bool
331 { let mut changed = false;
332 for (i, v) in &mut self.data.iter_mut().enumerate()
333 { if !*v && other.contains(i)
334 { changed = true;
335 *v = true;
336 }
337 }
338 return changed;
339 }
340}
341
342#[derive(Debug)]
344struct Symbol
345{ name: Arc<String>, index: usize, typ: SymbolType, sym_rules_arr: Vec<usize>, fallback_index: usize, prec: i32, assoc: Associativity, firstset: Set, lambda: bool, data_type: String, dtnum: usize, }
357impl Symbol
358{ fn new(name: &str, index: usize) -> Self
359 { let typ = if is_terminal_name(name) || name=="$" {SymbolType::TERMINAL} else {SymbolType::NONTERMINAL};
360 Self
361 { name: Arc::new(String::new()),
362 index,
363 typ,
364 sym_rules_arr: Vec::new(),
365 fallback_index: std::usize::MAX,
366 prec: -1,
367 assoc: Associativity::UNKNOWN,
368 firstset: Set::new(0),
369 lambda: false,
370 data_type: String::new(),
371 dtnum: 0,
372 }
373 }
374}
375impl PartialEq for Symbol
376{ fn eq(&self, other: &Self) -> bool
377 { self.index == other.index
378 }
379}
380
381#[derive(Debug)]
382struct Rhs
383{ name: Arc<String>,
384 index: usize,
385 alias: String,
386}
387
388#[derive(Debug)]
390struct Rule
391{ rule_filename: Arc<String>,
392 rule_n_line: usize, lhs: Arc<String>, lhs_index: usize, lhs_start: bool, rhs: Vec<Rhs>, code: String, precsym_index: usize, index: usize, can_reduce: bool, does_reduce: bool, }
403impl Rule
404{ fn new(rule_filename: &Arc<String>, rule_n_line: usize, lhs: &Arc<String>, lhs_index: usize, index: usize, code: String) -> Self
405 { Self
406 { rule_filename: Arc::clone(rule_filename),
407 rule_n_line,
408 lhs: Arc::clone(lhs),
409 lhs_index,
410 lhs_start: false,
411 rhs: Vec::new(),
412 code,
413 precsym_index: std::usize::MAX,
414 index,
415 can_reduce: false,
416 does_reduce: false,
417 }
418 }
419}
420impl fmt::Display for Rule
421{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
423 { write!(f, "{} ::=", self.lhs)?;
424 for sp in &self.rhs
425 { write!(f, " {}", sp.name)?;
426 }
427 Ok(())
428 }
429}
430
431#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
432struct ConfigKey
433{ n_rule: usize,
434 dot: usize,
435}
436impl ConfigKey
437{ fn new(config: &Config) -> Self
438 { Self
439 { n_rule: config.n_rule,
440 dot: config.dot,
441 }
442 }
443}
444impl cmp::Ord for ConfigKey
445{ fn cmp(&self, other: &Self) -> cmp::Ordering
446 { let mut res = self.n_rule.cmp(&other.n_rule);
447 if res == Ordering::Equal
448 { res = self.dot.cmp(&other.dot);
449 }
450 res
451 }
452}
453impl cmp::PartialOrd for ConfigKey
454{ fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering>
455 { Some(self.cmp(other))
456 }
457}
458
459#[derive(Debug)]
465struct Config
466{ n_rule: usize, dot: usize, fws: Set, fplp: Vec<Rc<RefCell<Config>>>, bplp: Vec<Rc<RefCell<Config>>>, n_state: usize, status_is_complete: bool, }
474impl Config
475{ pub fn new(n_rule: usize, dot: usize, fws_size: usize) -> Self
476 { Self
477 { n_rule,
478 dot,
479 fws: Set::new(fws_size),
480 fplp: Vec::new(),
481 bplp: Vec::new(),
482 n_state: std::usize::MAX,
483 status_is_complete: false,
484 }
485 }
486}
487impl cmp::Ord for Config
488{ fn cmp(&self, other: &Self) -> cmp::Ordering
489 { ConfigKey::new(self).cmp(&ConfigKey::new(other))
490 }
491}
492impl cmp::PartialOrd for Config
493{ fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering>
494 { Some(self.cmp(other))
495 }
496}
497impl cmp::PartialEq for Config
498{ fn eq(&self, other: &Self) -> bool
499 { ConfigKey::new(self).eq(&ConfigKey::new(other))
500 }
501}
502impl Eq for Config {}
503
504#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
505enum ActionType
506{ Shift,
507 Accept,
508 Reduce,
509 Error,
510 SsConflict, SrConflict, RrConflict, ShResolved, RdResolved, NotUsed, ShiftReduce }
518
519#[derive(Debug, PartialEq, Copy, Clone)]
520enum StateOrRule
521{ State(usize), Rule(usize), EmptyRule }
525
526#[derive(Debug)]
528struct Action
529{ id: i32,
530 symbol_index: usize, typ: ActionType,
532 x: StateOrRule,
533 symbol_index_opt: usize, }
535impl Action
536{ fn new_state(id: i32, symbol_index: usize, n_state: usize) -> Action
537 { Action
538 { id,
539 symbol_index,
540 typ: ActionType::Shift,
541 x: StateOrRule::State(n_state),
542 symbol_index_opt: std::usize::MAX,
543 }
544 }
545
546 fn new_rule(id: i32, symbol_index: usize, typ: ActionType, n_rule: usize) -> Action
547 { Action
548 { id,
549 symbol_index,
550 typ,
551 x: StateOrRule::Rule(n_rule),
552 symbol_index_opt: std::usize::MAX,
553 }
554 }
555
556 fn new_empty_rule(id: i32, symbol_index: usize, typ: ActionType) -> Action
557 { Action
558 { id,
559 symbol_index,
560 typ,
561 x: StateOrRule::EmptyRule,
562 symbol_index_opt: std::usize::MAX,
563 }
564 }
565}
566impl cmp::Ord for Action
567{ fn cmp(&self, other: &Self) -> cmp::Ordering
568 { let index = self.symbol_index;
569 let other_index = other.symbol_index;
570 let mut res = index.cmp(&other_index);
571 if res == Ordering::Equal
572 { res = self.typ.cmp(&other.typ);
573 if res == Ordering::Equal
574 { if self.typ==ActionType::Reduce || self.typ==ActionType::ShiftReduce
575 { if let StateOrRule::Rule(n_rule) = self.x
576 { if let StateOrRule::Rule(other_n_rule) = other.x
577 { if n_rule < other_n_rule
578 { return Ordering::Less;
579 }
580 if n_rule > other_n_rule
581 { return Ordering::Greater;
582 }
583 }
584 }
585 }
586 res = self.id.cmp(&other.id);
587 }
588 }
589 res
590 }
591}
592impl cmp::PartialOrd for Action
593{ fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering>
594 { Some(self.cmp(other))
595 }
596}
597impl cmp::PartialEq for Action
598{ fn eq(&self, other: &Self) -> bool
599 { self.cmp(other) == Ordering::Equal
600 }
601}
602impl Eq for Action {}
603
604#[derive(Debug)]
606struct State
607{ basis: Vec<Rc<RefCell<Config>>>, configurations: Vec<Rc<RefCell<Config>>>, n_state: usize, actions: Vec<Rc<RefCell<Action>>>, n_token_act: usize,
612 n_nt_act: usize, token_offset: isize,
614 nt_offset: isize, default_reduce_action: usize, default_reduce_rule: usize, auto_reduce: bool,
618}
619impl State
620{ pub fn new(n_state: usize, basis: Vec<Rc<RefCell<Config>>>, configurations: Vec<Rc<RefCell<Config>>>) -> Self
621 { Self
622 { basis,
623 configurations,
624 n_state,
625 actions: Vec::new(),
626 n_token_act: 0,
627 n_nt_act: 0,
628 token_offset: 0,
629 nt_offset: 0,
630 default_reduce_action: 0,
631 default_reduce_rule: std::usize::MAX,
632 auto_reduce: false,
633 }
634 }
635}
636
637#[derive(Debug)]
642struct AxSet
643{ n_state: usize, is_tkn: bool, n_action: usize, i_order: usize, }
648impl AxSet
649{ fn new(n_state: usize, is_tkn: bool, n_action: usize, i_order: usize) -> Self
650 { Self
651 { n_state,
652 is_tkn,
653 n_action,
654 i_order,
655 }
656 }
657}
658impl cmp::Ord for AxSet
659{ fn cmp(&self, other: &Self) -> cmp::Ordering
660 { let mut res = other.n_action.cmp(&self.n_action); if res == Ordering::Equal
662 { res = self.i_order.cmp(&other.i_order);
663 }
664 res
665 }
666}
667impl cmp::PartialOrd for AxSet
668{ fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering>
669 { Some(self.cmp(other))
670 }
671}
672impl cmp::PartialEq for AxSet
673{ fn eq(&self, other: &Self) -> bool
674 { self.cmp(other) == Ordering::Equal
675 }
676}
677impl Eq for AxSet {}
678
679#[derive(Copy, Clone, Eq, PartialEq, Debug)]
698struct LookaheadAction
699{ lookahead: usize, action: usize, }
702impl LookaheadAction
703{ fn new(lookahead: usize, action: usize) -> Self
704 { Self
705 { lookahead,
706 action,
707 }
708 }
709}
710
711#[derive(Debug)]
712struct ActTab
713{ n_action: usize, a_action: Vec<LookaheadAction>, a_lookahead: Vec<LookaheadAction>, min_lookahead: usize, max_lookahead: usize, min_action: usize, n_terminals: usize, n_symbols: usize, min_token_offset: isize,
724 max_token_offset: isize,
725 min_nt_offset: isize,
726 max_nt_offset: isize,
727
728 n_fallbacks: usize,
729 n_shift_offset: usize,
730 reduce_count: usize,
731}
732impl ActTab
733{ fn new(n_terminals: usize, n_symbols: usize) -> Self
734 { Self
735 { n_action: 0,
736 a_action: Vec::new(),
737 a_lookahead: Vec::new(),
738 min_lookahead: 0,
739 max_lookahead: 0,
740 min_action: 0,
741
742 n_terminals,
743 n_symbols,
744
745 min_token_offset: 0,
746 max_token_offset: 0,
747 min_nt_offset: 0,
748 max_nt_offset: 0,
749
750 n_fallbacks: 0,
751 n_shift_offset: 0,
752 reduce_count: 0,
753 }
754 }
755
756 fn get_n_lookahead(&self) -> usize
757 { self.n_action
758 }
759
760 fn get_n_actions(&self) -> usize
761 { let mut n_action = self.n_action;
762 for rec in self.a_action.iter().take(n_action).rev()
763 { if rec.lookahead == std::usize::MAX
764 { n_action -= 1;
765 }
766 else
767 { break;
768 }
769 }
770 n_action
771 }
772
773 fn iter(&self) -> Take<Iter<'_, LookaheadAction>>
774 { self.a_action.iter().take(self.n_action)
775 }
776
777 fn acttab_action(&mut self, lookahead: usize, action: usize)
780 { if self.a_lookahead.len() == 0
781 { self.max_lookahead = lookahead;
782 self.min_lookahead = lookahead;
783 self.min_action = action;
784 }
785 else
786 { if self.max_lookahead < lookahead
787 { self.max_lookahead = lookahead;
788 }
789 if self.min_lookahead > lookahead
790 { self.min_lookahead = lookahead;
791 self.min_action = action;
792 }
793 }
794 self.a_lookahead.push(LookaheadAction::new(lookahead, action));
795 }
796
797 fn acttab_insert(&mut self, make_it_safe: bool) -> isize
802 { assert!(self.a_lookahead.len() > 0);
803
804 if self.n_action + self.n_symbols + 1 >= self.a_action.len()
807 { self.a_action.resize(self.n_action + self.n_symbols + self.a_action.len() + 21, LookaheadAction::new(std::usize::MAX, std::usize::MAX));
808 }
809
810 let mut found_offset = std::usize::MAX;
815 let end = if make_it_safe {self.min_lookahead} else {0};
816'l: for i in (end .. self.n_action).rev()
817 { if self.a_action[i].lookahead == self.min_lookahead
818 { if self.a_action[i].action == self.min_action
820 { for j in 0..self.a_lookahead.len()
821 { let k = self.a_lookahead[j].lookahead + i - self.min_lookahead;
822 if k>=self.n_action || self.a_lookahead[j].lookahead != self.a_action[k].lookahead || self.a_lookahead[j].action != self.a_action[k].action
823 { continue 'l;
824 }
825 }
826 let mut n = 0;
828 for j in 0..self.n_action
829 { if self.a_action[j].lookahead != std::usize::MAX
830 { if self.a_action[j].lookahead == (j + self.min_lookahead).wrapping_sub(i)
831 { n += 1;
832 }
833 }
834 }
835 if n == self.a_lookahead.len()
836 { found_offset = i; break;
838 }
839 }
840 }
841 }
842
843 if found_offset == std::usize::MAX
845 { found_offset = if make_it_safe {self.min_lookahead} else {0};
848'm: for i in found_offset .. self.a_action.len() - self.max_lookahead
849 { if self.a_action[i].lookahead == std::usize::MAX
850 { for j in 0 .. self.a_lookahead.len()
851 { let k = self.a_lookahead[j].lookahead + i - self.min_lookahead;
852 if k >= self.a_action.len() || self.a_action[k].lookahead != std::usize::MAX
853 { continue 'm;
854 }
855 }
856 for j in 0 .. self.n_action
857 { if self.a_action[j].lookahead == (j + self.min_lookahead).wrapping_sub(i)
858 { continue 'm;
859 }
860 }
861 found_offset = i; break;
863 }
864 }
865 }
866
867 for j in 0 .. self.a_lookahead.len()
869 { let k = self.a_lookahead[j].lookahead - self.min_lookahead + found_offset;
870 self.a_action[k] = self.a_lookahead[j];
871 if k >= self.n_action
872 { self.n_action = k + 1;
873 }
874 }
875 if make_it_safe && found_offset+self.n_terminals >= self.n_action
876 { self.n_action = found_offset+self.n_terminals+1;
877 }
878 self.a_lookahead.clear();
879
880 return found_offset as isize - self.min_lookahead as isize;
882 }
883}
884
885#[derive(Debug)]
886struct SymbolsBuilder
887{ symbols_map: HashMap<Arc<String>, Symbol>,
888 n_terminals: usize,
889 n_nonterminals: usize,
890}
891impl SymbolsBuilder
892{ pub fn new(empty: bool) -> Self
893 { let mut this = Self
894 { symbols_map: HashMap::new(),
895 n_terminals: 0,
896 n_nonterminals: 0,
897 };
898 if !empty
899 { this.add(&Arc::new("$".to_string()));
900 }
901 this
902 }
903
904 pub fn add(&mut self, symbol_name: &Arc<String>) -> usize
906 { if let Some(symbol) = self.symbols_map.get(symbol_name)
907 { symbol.index
908 }
909 else
910 { let index = if is_terminal_name(symbol_name.as_ref()) || symbol_name.as_ref()=="$"
911 { self.n_terminals += 1;
912 self.n_terminals - 1
913 }
914 else
915 { self.n_nonterminals += 1;
916 self.n_nonterminals - 1
917 };
918 let symbol = Symbol::new(symbol_name, index); self.symbols_map.insert(Arc::clone(symbol_name), symbol);
920 index
921 }
922 }
923
924 pub fn get(&self, symbol_name: &Arc<String>) -> &Symbol
925 { &self.symbols_map[symbol_name]
926 }
927
928 pub fn get_mut(&mut self, symbol_name: &Arc<String>) -> &mut Symbol
929 { self.symbols_map.get_mut(symbol_name).unwrap()
930 }
931
932 pub fn into_symbols(mut self, start_name: &String, nonterminal_types: HashMap<String, StringInFile>, precedence: HashMap<String, PrecedenceInFile>, rules: &mut Vec<Rule>) -> ParserResult<Symbols>
933 { for (symbol_name, symbol_type) in nonterminal_types
935 { if let Some(symbol) = self.symbols_map.get_mut(&symbol_name)
936 { symbol.data_type = symbol_type.string;
937 }
938 else
939 { return Err(LemonMintError::new(&symbol_type.filename, symbol_type.n_line, format!("No such nonterminal symbol when defining symbol type: \"{}\"", symbol_name)));
940 }
941 }
942 for (symbol_name, precedence) in precedence
944 { if let Some(symbol) = self.symbols_map.get_mut(&symbol_name)
945 { symbol.prec = precedence.precedence;
946 symbol.assoc = precedence.assoc;
947 }
948 else
949 { return Err(LemonMintError::new(&precedence.filename, precedence.n_line, format!("No such terminal symbol \"{}\" when defining precedence", symbol_name)));
950 }
951 }
952 for rule in rules
954 { rule.lhs_index += self.n_terminals;
955 for rhs in rule.rhs.iter_mut()
956 { if self.symbols_map[&rhs.name].typ == SymbolType::NONTERMINAL
957 { rhs.index += self.n_terminals;
958 }
959 }
960 }
961 let n_symbols = self.symbols_map.len();
963 let default_symbol = self.add(&Arc::new("{default}".to_string()));
964 let default_symbol_index = default_symbol + self.n_terminals;
965 let mut start_symbol_index = std::usize::MAX;
966 let mut error_symbol_index = std::usize::MAX;
967 let mut array = Vec::with_capacity(self.symbols_map.len());
968 for (symbol_name, mut symbol) in self.symbols_map
969 { if symbol.typ == SymbolType::NONTERMINAL
970 { symbol.index += self.n_terminals;
971 if symbol_name.as_ref() == start_name
972 { start_symbol_index = symbol.index;
973 }
974 else if symbol_name.as_ref() == "error"
975 { error_symbol_index = symbol.index;
976 }
977 }
978 else if symbol.index == 0
979 { symbol.typ = SymbolType::NONTERMINAL; }
981 symbol.name = Arc::clone(&symbol_name);
982 array.push(symbol);
983 }
984 array.sort_by(|a, b| a.index.cmp(&b.index));
985 Ok(Symbols {array, n_symbols, n_terminals: self.n_terminals, default_symbol_index, start_symbol_index, error_symbol_index})
986 }
987}
988
989#[derive(Debug)]
990struct Symbols
991{ pub array: Vec<Symbol>, pub n_symbols: usize, pub n_terminals: usize, pub start_symbol_index: usize,
995 pub default_symbol_index: usize,
996 pub error_symbol_index: usize,
997}
998impl Symbols
999{ pub fn get_start_symbol(&self) -> &Symbol
1000 { &self.array[self.start_symbol_index]
1001 }
1002
1003 pub fn get_error_symbol(&self) -> Option<&Symbol>
1004 { self.array.get(self.error_symbol_index)
1005 }
1006}
1007
1008#[derive(Debug)]
1009struct States
1010{ pub array: Vec<State>,
1011 pub n_no_tail: usize, }
1013
1014#[derive(Debug)]
1015struct StatesBuilder;
1016impl StatesBuilder
1017{ pub fn build(symbols: &Symbols, rules: &mut Vec<Rule>, start: &Symbol, n_terminals: usize, actions_enum: &mut i32) -> ParserResult<States>
1019 { let mut configs_basis_keys_arr = Vec::new();
1020 let mut configs_basis_arr = Vec::new();
1021 let mut configs_arr = Vec::new();
1022 let mut configs_map = HashMap::new();
1023 let mut states_map = HashMap::new();
1024
1025 for n_rule in start.sym_rules_arr.iter()
1027 { rules[*n_rule].lhs_start = true;
1028 Self::configlist_add(rules, &mut configs_basis_keys_arr, &mut configs_basis_arr, &mut configs_arr, &mut configs_map, n_terminals, *n_rule, 0, true).borrow_mut().fws.add(0);
1029 }
1030
1031 Self::getstate(symbols, rules, &mut configs_basis_keys_arr, &mut configs_basis_arr, &mut configs_arr, &mut configs_map, &mut states_map, n_terminals, actions_enum)?;
1034
1035 let mut states = States {array: Vec::with_capacity(states_map.len()), n_no_tail: 0}; for (_, elem) in states_map
1037 { states.array.push(Rc::try_unwrap(elem).unwrap().into_inner());
1038 }
1039 states.array.sort_by(|a, b| a.n_state.cmp(&b.n_state));
1040 states.n_no_tail = states.array.len();
1041 Ok(states)
1042 }
1043
1044 fn getstate
1046 ( symbols: &Symbols,
1047 rules: &Vec<Rule>,
1048 configs_basis_keys_arr: &mut Vec<ConfigKey>,
1049 configs_basis_arr: &mut Vec<Rc<RefCell<Config>>>,
1050 configs_arr: &mut Vec<Rc<RefCell<Config>>>,
1051 configs_map: &mut HashMap<ConfigKey, Rc<RefCell<Config>>>,
1052 states_map: &mut HashMap<Vec<ConfigKey>, Rc<RefCell<State>>>,
1053 n_terminals: usize,
1054 actions_enum: &mut i32,
1055 ) -> ParserResult<usize>
1056 { let mut basis_keys = mem::replace(configs_basis_keys_arr, Vec::new());
1058 let mut basis = mem::replace(configs_basis_arr, Vec::new());
1059 basis_keys.sort();
1060 basis.sort();
1061
1062 if let Some(found) = states_map.get(&basis_keys)
1064 { let found = found.borrow();
1065 let n_state = found.n_state;
1066 for (i, x) in basis.iter().enumerate()
1069 { let mut y = found.basis[i].borrow_mut();
1070 if let Ok(mut x) = x.try_borrow_mut()
1071 { mem::swap(&mut x.bplp, &mut y.bplp);
1072 y.bplp.reserve(x.bplp.len());
1073 for config in x.bplp.iter()
1074 { y.bplp.push(Rc::clone(config));
1075 }
1076 }
1077 else
1078 { let len = y.bplp.len();
1080 y.bplp.reserve(len);
1081 for i in 0 .. len
1082 { let o = Rc::clone(&y.bplp[i]);
1083 y.bplp.push(o);
1084 }
1085 }
1086 }
1087 configs_arr.clear();
1088 Ok(n_state)
1089 }
1090 else
1091 { Self::configlist_closure(symbols, rules, configs_basis_keys_arr, configs_basis_arr, configs_arr, configs_map, n_terminals)?; let n_state = states_map.len();
1094 let mut configurations = mem::replace(configs_arr, Vec::new());
1095 configurations.sort(); let stp = State::new ( n_state, basis, configurations );
1101 let stp = Rc::new(RefCell::new(stp));
1102 states_map.insert(basis_keys, Rc::clone(&stp)); let actions = Self::buildshifts(symbols, rules, configs_basis_keys_arr, configs_basis_arr, configs_arr, configs_map, states_map, n_terminals, actions_enum, &stp)?; stp.borrow_mut().actions = actions;
1105 Ok(n_state)
1106 }
1107 }
1108
1109 fn buildshifts
1111 ( symbols: &Symbols,
1112 rules: &Vec<Rule>,
1113 configs_basis_keys_arr: &mut Vec<ConfigKey>,
1114 configs_basis_arr: &mut Vec<Rc<RefCell<Config>>>,
1115 configs_arr: &mut Vec<Rc<RefCell<Config>>>,
1116 configs_map: &mut HashMap<ConfigKey, Rc<RefCell<Config>>>,
1117 states_map: &mut HashMap<Vec<ConfigKey>, Rc<RefCell<State>>>,
1118 n_terminals: usize,
1119 actions_enum: &mut i32,
1120 stp: &Rc<RefCell<State>>
1121 ) -> ParserResult<Vec<Rc<RefCell<Action>>>>
1122 { let mut actions = Vec::new();
1123
1124 for cfp in stp.borrow().configurations.iter()
1126 { cfp.borrow_mut().status_is_complete = false;
1127 }
1128
1129 for (i, cfp) in stp.borrow().configurations.iter().enumerate()
1131 { let (status_is_complete, dot, n_rule) =
1132 { let cfp = cfp.borrow();
1133 (cfp.status_is_complete, cfp.dot, cfp.n_rule)
1134 };
1135 if !status_is_complete && dot<rules[n_rule].rhs.len() { configs_basis_keys_arr.clear();
1137 configs_basis_arr.clear();
1138 configs_arr.clear();
1139 configs_map.clear();
1140 let sp = rules[n_rule].rhs[dot].index; for bcfp in stp.borrow().configurations.iter().skip(i)
1145 { if !bcfp.borrow().status_is_complete && bcfp.borrow().dot<rules[bcfp.borrow().n_rule].rhs.len() { let bsp = rules[bcfp.borrow().n_rule].rhs[bcfp.borrow().dot].index; if bsp == sp { bcfp.borrow_mut().status_is_complete = true; let newcfg = Self::configlist_add(rules, configs_basis_keys_arr, configs_basis_arr, configs_arr, configs_map, n_terminals, bcfp.borrow().n_rule, bcfp.borrow().dot+1, true);
1150 newcfg.borrow_mut().bplp.push(Rc::clone(bcfp));
1151 }
1152 }
1153 }
1154
1155 let n_state = Self::getstate(symbols, rules, configs_basis_keys_arr, configs_basis_arr, configs_arr, configs_map, states_map, n_terminals, actions_enum)?; actions.insert(0, Rc::new(RefCell::new(Action::new_state(*actions_enum, sp, n_state)))); *actions_enum += 1;
1161 }
1162 }
1163 Ok(actions)
1164 }
1165
1166 fn configlist_add
1169 ( rules: &Vec<Rule>,
1170 configs_basis_keys_arr: &mut Vec<ConfigKey>,
1171 configs_basis_arr: &mut Vec<Rc<RefCell<Config>>>,
1172 configs_arr: &mut Vec<Rc<RefCell<Config>>>,
1173 configs_map: &mut HashMap<ConfigKey, Rc<RefCell<Config>>>,
1174 n_terminals: usize,
1175 n_rule: usize,
1176 dot: usize,
1177 is_basis: bool
1178 ) -> Rc<RefCell<Config>>
1179 { let key = ConfigKey {n_rule: rules[n_rule].index, dot};
1180
1181 if let Some(found) = configs_map.get(&key)
1182 { Rc::clone(found)
1183 }
1184 else
1185 { let cfp = Rc::new(RefCell::new(Config::new(n_rule, dot, n_terminals+1)));
1186 configs_arr.push(Rc::clone(&cfp));
1187 let key = ConfigKey::new(&cfp.borrow());
1188 if is_basis
1189 { configs_basis_keys_arr.push(key);
1190 configs_basis_arr.push(Rc::clone(&cfp));
1191 }
1192 configs_map.insert(key, Rc::clone(&cfp));
1193 cfp
1194 }
1195 }
1196
1197 fn configlist_closure
1199 ( symbols: &Symbols,
1200 rules: &Vec<Rule>,
1201 configs_basis_keys_arr: &mut Vec<ConfigKey>,
1202 configs_basis_arr: &mut Vec<Rc<RefCell<Config>>>,
1203 configs_arr: &mut Vec<Rc<RefCell<Config>>>,
1204 configs_map: &mut HashMap<ConfigKey, Rc<RefCell<Config>>>,
1205 n_terminals: usize
1206 ) -> ParserResult<()>
1207 { let mut c = 0;
1208 while c < configs_arr.len() { let (rule, dot) =
1210 { let config = configs_arr[c].borrow();
1211 (&rules[config.n_rule], config.dot)
1212 };
1213 if dot < rule.rhs.len()
1214 { let sp = &symbols.array[rule.rhs[dot].index];
1215 if sp.typ == SymbolType::NONTERMINAL
1216 { if sp.index!=symbols.error_symbol_index && sp.sym_rules_arr.is_empty()
1217 { return Err(LemonMintError::new(&rule.rule_filename, rule.rule_n_line, format!("Nonterminal \"{}\" has no rules.", sp.name)));
1218 }
1219 for new_n_rule in sp.sym_rules_arr.iter()
1220 { let newcfp = Self::configlist_add(rules, configs_basis_keys_arr, configs_basis_arr, configs_arr, configs_map, n_terminals, *new_n_rule, 0, false);
1221 let mut found = false;
1222 for i in dot+1 .. rule.rhs.len()
1223 { let xsp = &symbols.array[rule.rhs[i].index];
1224 if xsp.typ == SymbolType::TERMINAL
1225 { newcfp.borrow_mut().fws.add(xsp.index);
1226 found = true;
1227 break;
1228 }
1229 newcfp.borrow_mut().fws.intersect(&xsp.firstset);
1230 if !xsp.lambda
1231 { found = true;
1232 break;
1233 }
1234 }
1235 if !found
1236 { configs_arr[c].borrow_mut().fplp.insert(0, newcfp); }
1238 }
1239 }
1240 }
1241 c += 1;
1242 }
1243 Ok(())
1244 }
1245}
1246
1247#[derive(Debug)]
1248struct StringInFile
1249{ filename: Arc<String>,
1250 n_line: usize,
1251 string: String,
1252}
1253
1254#[derive(Debug)]
1255struct PrecedenceInFile
1256{ filename: Arc<String>,
1257 n_line: usize,
1258 assoc: Associativity,
1259 precedence: i32,
1260}
1261
1262struct ArrayFormatter
1263{ i: usize,
1264 values_on_line: usize,
1265 endl: &'static str,
1266}
1267impl ArrayFormatter
1268{ pub fn new(values_on_line: usize) -> Self
1269 { Self
1270 { i: 0,
1271 values_on_line,
1272 endl: "\n[\t",
1273 }
1274 }
1275
1276 pub fn separ<W>(&mut self, out: &mut W) -> io::Result<()> where W: io::Write
1277 { if self.i % self.values_on_line == 0
1278 { write!(out, "{}/* {:5} */ ", self.endl, self.i)?;
1279 self.endl = ",\n\t";
1280 }
1281 else
1282 { write!(out, ", ")?;
1283 }
1284 self.i += 1;
1285 Ok(())
1286 }
1287
1288 pub fn end<W>(self, out: &mut W) -> io::Result<()> where W: io::Write
1289 { writeln!(out, "{}];", if self.i==0 {" ["} else {"\n"})
1290 }
1291}
1292
1293#[derive(Debug)]
1320pub struct LemonMintBuilder
1321{ rules: Vec<Rule>, token_type: String, vartype: String, start_name: String, with_trace: bool,
1326 trace_prompt: String, extracode: String, n_conflicts: usize, n_action_table_entries: usize, tables_size: usize, has_fallback: bool, symbols_builder: SymbolsBuilder,
1333 prec_counter: i32,
1334 actions_enum: i32,
1335 nonterminal_types: HashMap<String, StringInFile>,
1336 precedence: HashMap<String, PrecedenceInFile>,
1337 extra_argument_type: String,
1338 min_shift_reduce: usize,
1339 error_action: usize,
1340 accept_action: usize,
1341 no_action: usize,
1342 min_reduce: usize,
1343 max_action: usize,
1344 no_compress: bool, no_resort: bool, }
1347impl LemonMintBuilder
1348{ pub fn new() -> Self
1350 { Self
1351 { rules: Vec::with_capacity(64),
1352 token_type: String::new(),
1353 vartype: String::new(),
1354 start_name: String::new(),
1355 with_trace: false,
1356 trace_prompt: String::new(),
1357 extracode: String::new(),
1358 n_conflicts: 0,
1359 n_action_table_entries: 0,
1360 tables_size: 0,
1361 has_fallback: false,
1362 symbols_builder: SymbolsBuilder::new(false),
1363 prec_counter: 1,
1364 actions_enum: 0,
1365 nonterminal_types: HashMap::new(),
1366 precedence: HashMap::new(),
1367 extra_argument_type: String::new(),
1368 min_shift_reduce: 0,
1369 error_action: 0,
1370 accept_action: 0,
1371 no_action: 0,
1372 min_reduce: 0,
1373 max_action: 0,
1374 no_compress: false,
1375 no_resort: false,
1376 }
1377 }
1378
1379 fn find_rule_precedences(symbols: &mut Symbols, rules: &mut Vec<Rule>)
1385 { for rule in rules.iter_mut()
1386 { if rule.precsym_index == std::usize::MAX
1387 { for sp in &rule.rhs
1388 { if symbols.array[sp.index].prec >= 0
1389 { rule.precsym_index = sp.index;
1390 break;
1391 }
1392 }
1393 }
1394 }
1395 }
1396
1397 fn find_first_sets(&self, symbols: &mut Symbols, rules: &mut Vec<Rule>)
1400 { for (i, symbol) in symbols.array[0 .. symbols.n_symbols].iter_mut().enumerate()
1401 { symbol.lambda = false;
1402 if i >= symbols.n_terminals
1403 { symbol.firstset.set_size(symbols.n_terminals + 1);
1404 }
1405 }
1406
1407 let mut progress = true;
1409 while progress
1410 { progress = false;
1411'l: for rule in rules.iter()
1412 { let rule = rule;
1413 if !symbols.array[rule.lhs_index].lambda
1414 { for sp in &rule.rhs
1415 { let sp = &symbols.array[sp.index];
1416 assert!(sp.typ==SymbolType::NONTERMINAL || !sp.lambda);
1417 if !sp.lambda
1418 { continue 'l;
1419 }
1420 }
1421 symbols.array[rule.lhs_index].lambda = true;
1422 progress = true;
1423 }
1424 }
1425 }
1426
1427 progress = true;
1429 while progress
1430 { progress = false;
1431 for rule in rules.iter()
1432 { for rhs in &rule.rhs
1433 { if symbols.array[rhs.index].typ == SymbolType::TERMINAL
1434 { if symbols.array[rule.lhs_index].firstset.add(rhs.index)
1435 { progress = true;
1436 }
1437 break;
1438 }
1439 else if rule.lhs_index == rhs.index
1440 { if !symbols.array[rule.lhs_index].lambda
1441 { break;
1442 }
1443 }
1444 else
1445 { let set = mem::replace(&mut symbols.array[rhs.index].firstset, Set::new(0));
1446 if symbols.array[rule.lhs_index].firstset.intersect(&set)
1447 { progress = true;
1448 }
1449 symbols.array[rhs.index].firstset = set;
1450 if !symbols.array[rhs.index].lambda
1451 { break;
1452 }
1453 }
1454 }
1455 }
1456 }
1457 }
1458
1459 fn find_links(states: &States)
1461 { for stp in states.array.iter()
1464 { for cfp in stp.configurations.iter()
1465 { cfp.borrow_mut().n_state = stp.n_state;
1466 }
1467 }
1468
1469 for stp in states.array.iter()
1472 { for cfp in stp.configurations.iter()
1473 { for plp in cfp.borrow().bplp.iter()
1474 { plp.borrow_mut().fplp.insert(0, Rc::clone(&cfp)); }
1476 }
1477 }
1478 }
1479
1480 fn find_follow_sets(states: &States)
1484 { for stp in states.array.iter()
1485 { for cfp in stp.configurations.iter()
1486 { cfp.borrow_mut().status_is_complete = false;
1487 }
1488 }
1489
1490 let mut progress = true;
1491 while progress
1492 { progress = false;
1493 for stp in states.array.iter()
1494 { for cfp in stp.configurations.iter()
1495 { if !cfp.borrow().status_is_complete
1496 { for plp in cfp.borrow().fplp.iter()
1497 { let mut plp = plp.borrow_mut();
1498 if plp.fws.intersect(&cfp.borrow().fws) { plp.status_is_complete = false;
1500 progress = true;
1501 }
1502 }
1503 cfp.borrow_mut().status_is_complete = true;
1504 }
1505 }
1506 }
1507 }
1508 }
1509
1510 fn resolve_conflict(symbols: &Symbols, rules: &mut Vec<Rule>, apx: &Rc<RefCell<Action>>, apy: &Rc<RefCell<Action>>) -> usize
1519 { let mut errcnt = 0;
1520 let mut apx = apx.borrow_mut();
1521 let mut apy = apy.borrow_mut();
1522 assert_eq!(apx.symbol_index, apy.symbol_index); let mut apx_typ = apx.typ;
1524 let mut apy_typ = apy.typ;
1525 if apx_typ==ActionType::Shift && apy_typ==ActionType::Shift
1526 { apy_typ = ActionType::SsConflict;
1527 errcnt += 1;
1528 }
1529 if apx_typ==ActionType::Shift && apy_typ==ActionType::Reduce
1530 { let spx = &symbols.array[apx.symbol_index];
1531 if let StateOrRule::Rule(n_rule) = apy.x
1532 { let spy = rules[n_rule].precsym_index;
1533 if spy != std::usize::MAX
1534 { let spy = &symbols.array[spy];
1535 if spx.prec<0 || spy.prec<0
1536 { apy_typ = ActionType::SrConflict;
1538 errcnt += 1;
1539 }
1540 else if spx.prec > spy.prec { apy_typ = ActionType::RdResolved;
1542 }
1543 else if spx.prec < spy.prec
1544 { apx_typ = ActionType::ShResolved;
1545 }
1546 else if spx.prec==spy.prec && spx.assoc== Associativity::RIGHT { apy_typ = ActionType::RdResolved; }
1549 else if spx.prec==spy.prec && spx.assoc== Associativity::LEFT { apx_typ = ActionType::ShResolved;
1551 }
1552 else
1553 { assert!(spx.prec==spy.prec && spx.assoc== Associativity::NONASSOC);
1554 apy_typ = ActionType::Error;
1555 }
1556 }
1557 else
1558 { apy_typ = ActionType::SrConflict;
1560 errcnt += 1;
1561 }
1562 }
1563 }
1564 else if apx_typ==ActionType::Reduce && apy_typ==ActionType::Reduce
1565 { if let StateOrRule::Rule(n_rule_x) = apx.x
1566 { if let StateOrRule::Rule(n_rule_y) = apy.x
1567 { let spx = rules[n_rule_x].precsym_index;
1568 let spy = rules[n_rule_y].precsym_index;
1569 if spx != std::usize::MAX
1570 { if spy != std::usize::MAX
1571 { let spx = &symbols.array[spx];
1572 let spy = &symbols.array[spy];
1573 if spx.prec<0 || spy.prec<0 || spx.prec==spy.prec
1574 { apy_typ = ActionType::RrConflict;
1575 errcnt += 1;
1576 }
1577 else if spx.prec > spy.prec
1578 { apy_typ = ActionType::RdResolved;
1579 }
1580 else if spx.prec < spy.prec
1581 { apx_typ = ActionType::RdResolved;
1582 }
1583 }
1584 else
1585 { apy_typ = ActionType::RrConflict;
1586 errcnt += 1;
1587 }
1588 }
1589 else
1590 { apy_typ = ActionType::RrConflict;
1591 errcnt += 1;
1592 }
1593 }
1594 }
1595 }
1596 else
1597 { assert!
1598 ( apx_typ == ActionType::ShResolved ||
1599 apx_typ == ActionType::RdResolved ||
1600 apx_typ == ActionType::SsConflict ||
1601 apx_typ == ActionType::SrConflict ||
1602 apx_typ == ActionType::RrConflict ||
1603 apy_typ == ActionType::ShResolved ||
1604 apy_typ == ActionType::RdResolved ||
1605 apy_typ == ActionType::SsConflict ||
1606 apy_typ == ActionType::SrConflict ||
1607 apy_typ == ActionType::RrConflict
1608 );
1609 }
1612 apx.typ = apx_typ;
1613 apy.typ = apy_typ;
1614 errcnt
1615 }
1616
1617 fn find_actions(&mut self, symbols: &Symbols, rules: &mut Vec<Rule>, states: &mut States) -> ParserResult<()>
1619 { for stp in states.array.iter_mut() { for cfp in stp.configurations.iter() { if cfp.borrow().dot == rules[cfp.borrow().n_rule].rhs.len() { for (j, symbol) in symbols.array.iter().take(symbols.n_terminals).enumerate()
1625 { if cfp.borrow().fws.contains(j)
1626 { stp.actions.push(Rc::new(RefCell::new(Action::new_rule(self.actions_enum, symbol.index, ActionType::Reduce, cfp.borrow().n_rule))));
1628 self.actions_enum += 1;
1629 }
1630 }
1631 }
1632 }
1633 }
1634
1635 states.array[0].actions.push(Rc::new(RefCell::new(Action::new_empty_rule(self.actions_enum, symbols.start_symbol_index, ActionType::Accept))));
1638 self.actions_enum += 1;
1639
1640 for stp in states.array.iter_mut()
1642 { if stp.actions.len() != 0
1643 { stp.actions.sort();
1644 for action in stp.actions.windows(2)
1645 { if action[0].borrow().symbol_index == action[1].borrow().symbol_index
1646 { self.n_conflicts += Self::resolve_conflict(symbols, rules, &action[0], &action[1]);
1649 }
1650 }
1651 }
1652 }
1653
1654 for stp in states.array.iter_mut()
1656 { for action in stp.actions.iter()
1657 { if action.borrow().typ == ActionType::Reduce
1658 { if let StateOrRule::Rule(n_rule) = action.borrow().x
1659 { rules[n_rule].can_reduce = true;
1660 }
1661 }
1662 }
1663 }
1664 for rule in rules.iter()
1665 { if !rule.can_reduce
1666 { return Err(LemonMintError::new(&rule.rule_filename, rule.rule_n_line, "This rule can not be reduced.\n".to_string()));
1667 }
1668 }
1669 Ok(())
1670 }
1671
1672 fn get_filename_of_first_rule(rules: &Vec<Rule>) -> Arc<String>
1673 { if let Some(rule) = rules.iter().next()
1674 { return Arc::clone(&rule.rule_filename);
1675 }
1676 Arc::new("".to_string())
1677 }
1678
1679 fn compress_tables(&self, symbols: &Symbols, rules: &Vec<Rule>, states: &mut States, default_symbol_index: usize)
1683 { for state in states.array.iter_mut()
1684 { let mut n_best = 0;
1685 let mut r_best = std::usize::MAX;
1686
1687 let mut it = state.actions.iter();
1688 while let Some(action) = it.next()
1689 { if action.borrow().typ == ActionType::Reduce
1690 { if let StateOrRule::Rule(n_rule) = action.borrow().x
1691 { let rule = &rules[n_rule];
1692 if !rule.lhs_start && n_rule != r_best
1693 { let mut n = 1;
1694 let mut it2 = it.clone();
1695 while let Some(ap2) = it2.next()
1696 { if ap2.borrow().typ == ActionType::Reduce
1697 { if let StateOrRule::Rule(n_rule_2) = ap2.borrow().x
1698 { if n_rule_2 != r_best && n_rule_2 == n_rule
1699 { n += 1;
1700 }
1701 }
1702 }
1703 }
1704 if n > n_best
1705 { n_best = n;
1706 r_best = n_rule;
1707 }
1708 }
1709 }
1710 }
1711 }
1712
1713 if n_best < 1
1715 { continue;
1716 }
1717
1718 let mut found = false;
1720 for action in state.actions.iter()
1721 { let mut action = action.borrow_mut();
1722 if action.typ == ActionType::Reduce
1723 { if let StateOrRule::Rule(n_rule) = action.x
1724 { if rules[n_rule].index == r_best
1725 { if !found
1726 { action.symbol_index = default_symbol_index;
1727 found = true;
1728 }
1729 else
1730 { action.typ = ActionType::NotUsed;
1731 }
1732 }
1733 }
1734 }
1735 }
1736 assert!(found);
1737 state.actions.sort();
1738
1739 found = false;
1740 for action in state.actions.iter()
1741 { let action = action.borrow();
1742 if action.typ==ActionType::Shift || action.typ==ActionType::Reduce && match action.x {StateOrRule::Rule(n_rule) => rules[n_rule].index != r_best, _ => false}
1743 { found = true;
1744 break;
1745 }
1746 }
1747 if !found
1748 { state.auto_reduce = true;
1749 state.default_reduce_rule = r_best;
1750 }
1751 }
1752
1753 for stp in states.array.iter()
1755 { for action in stp.actions.iter()
1756 { let mut action = action.borrow_mut();
1757 if action.typ == ActionType::Shift
1758 { if let StateOrRule::State(next_n_state) = action.x
1759 { let next_state = &states.array[next_n_state];
1760 if next_state.auto_reduce && next_state.default_reduce_rule!=std::usize::MAX
1761 { action.typ = ActionType::ShiftReduce;
1762 action.x = StateOrRule::Rule(next_state.default_reduce_rule);
1763 }
1764 }
1765 }
1766 }
1767 }
1768
1769 for stp in states.array.iter()
1773 { for action in stp.actions.iter()
1774 { let mut done = false;
1775 while !done
1776 { done = true;
1777 let mut ap2 = None;
1778 { let action = action.borrow();
1779 if action.typ == ActionType::ShiftReduce
1780 { if let StateOrRule::Rule(n_rule) = action.x
1781 { let rp = &rules[n_rule];
1782 if rp.code.is_empty() && rp.rhs.len()==1
1783 { if action.symbol_index >= symbols.n_terminals
1785 { ap2 = stp.actions.iter().find
1787 ( |a|
1788 { let a = a.borrow();
1789 a.id!= action.id && a.symbol_index==rp.lhs_index
1790 }
1791 );
1792 assert!(ap2.is_some());
1793 done = false;
1794 }
1795 }
1796 }
1797 }
1798 }
1799 if let Some(ap2) = ap2
1800 { let mut action = action.borrow_mut();
1801 let ap2 = ap2.borrow();
1802 action.symbol_index_opt = ap2.symbol_index;
1803 action.typ = ap2.typ;
1804 action.x = ap2.x;
1805 }
1806 }
1807 }
1808 }
1809 }
1810
1811 fn compute_action(&self, symbols: &Symbols, action: &Rc<RefCell<Action>>) -> usize
1814 { let action = action.borrow();
1815 match action.typ
1816 { ActionType::Shift =>
1817 { match action.x
1818 { StateOrRule::State(n_state) => n_state,
1819 _ => std::usize::MAX
1820 }
1821 }
1822 ActionType::ShiftReduce =>
1823 { match action.x
1825 { StateOrRule::Rule(n_rule) =>
1826 { if action.symbol_index >= symbols.n_terminals
1827 { self.min_reduce + n_rule
1828 }
1829 else
1830 { self.min_shift_reduce + n_rule
1831 }
1832 },
1833 _ => std::usize::MAX
1834 }
1835 }
1836 ActionType::Reduce =>
1837 { match action.x
1838 { StateOrRule::Rule(n_rule) => self.min_reduce + n_rule,
1839 _ => std::usize::MAX
1840 }
1841 }
1842 ActionType::Error =>
1843 { self.error_action
1844 }
1845 ActionType::Accept =>
1846 { self.accept_action
1847 }
1848 _ => std::usize::MAX
1849 }
1850 }
1851
1852 fn resort_states(&mut self, symbols: &Symbols, states: &mut States)
1854 { let sorted_len = states.array.len();
1855 for stp in states.array.iter_mut()
1856 { stp.n_token_act = 0;
1857 stp.n_nt_act = 0;
1858 stp.default_reduce_action = std::usize::MAX; stp.token_offset = std::isize::MIN;
1860 stp.nt_offset = std::isize::MIN;
1861 for action in stp.actions.iter()
1862 { let n_action = self.compute_action(symbols, action);
1863 if n_action != std::usize::MAX
1864 { let action = action.borrow();
1865 if action.symbol_index < symbols.n_terminals
1866 { stp.n_token_act += 1;
1867 }
1868 else if action.symbol_index < symbols.n_symbols
1869 { stp.n_nt_act += 1;
1870 }
1871 else
1872 { assert!(!stp.auto_reduce || action.x == StateOrRule::Rule(stp.default_reduce_rule));
1873 stp.default_reduce_action = n_action;
1874 }
1875 }
1876 }
1877 }
1878
1879 if sorted_len > 2
1882 { states.array[1 ..].sort_by
1883 ( |a, b|
1884 { let mut res = b.n_nt_act.cmp(&a.n_nt_act);
1885 if res == Ordering::Equal
1886 { res = b.n_token_act.cmp(&a.n_token_act);
1887 if res == Ordering::Equal
1888 { res = b.n_state.cmp(&a.n_state);
1889 }
1890 }
1891 res
1892 }
1893 );
1894 }
1895
1896 let mut map = Vec::new();
1898 map.resize(states.array.len(), 0);
1899 for (i, stp) in states.array.iter().enumerate()
1900 { map[stp.n_state] = i;
1901 }
1902 for stp in states.array.iter()
1903 { for action in stp.actions.iter()
1904 { if let StateOrRule::State(ref mut state) = action.borrow_mut().x
1905 { *state = map[*state];
1906 }
1907 }
1908 for configuration in stp.configurations.iter()
1909 { let mut configuration = configuration.borrow_mut();
1910 configuration.n_state = map[configuration.n_state];
1911 }
1912 }
1913
1914 for (new_n_state, stp) in states.array.iter_mut().enumerate()
1916 { stp.n_state = new_n_state;
1917 }
1918
1919 while states.n_no_tail>1 && states.array[states.n_no_tail-1].auto_reduce
1920 { states.n_no_tail -= 1;
1921 }
1922 }
1923
1924 fn minimum_size_type(lower: isize, upper: isize) -> isize
1926 { if lower >= 0
1927 { if upper <= 255
1928 { 1
1929 }
1930 else if upper < 65535
1931 { 2
1932 }
1933 else
1934 { 4
1935 }
1936 }
1937 else
1938 { if lower>=-127 && upper<=127
1939 { -1
1940 }
1941 else if lower>=-32767 && upper<32767
1942 { -2
1943 }
1944 else
1945 { -4
1946 }
1947 }
1948 }
1949
1950 fn translate_code(&self, rule: &mut Rule) -> ParserResult<()>
1952 { let mut used = Vec::new(); used.resize(rule.rhs.len(), false);
1954
1955 let mut it = rule.code.chars();
1956 let mut it_prev = it.clone();
1957
1958 while let Some(cp) = it.next()
1959 { if cp.is_ascii_alphabetic()
1960 { let ident: String = it_prev.take_while(|c| c.is_ascii_alphanumeric() || *c=='_').collect();
1961 if ident.len() > 1
1962 { it.nth(ident.chars().count() - 2).unwrap();
1963 }
1964 for (i, rhs) in rule.rhs.iter().enumerate()
1965 { if rhs.alias == ident
1966 { used[i] = true;
1967 break;
1968 }
1969 }
1970 }
1971 it_prev = it.clone();
1972 }
1973
1974 for (i, rhs) in rule.rhs.iter().enumerate()
1976 { if !rhs.alias.is_empty() && !used[i]
1977 { return Err
1978 ( LemonMintError::new
1979 ( &rule.rule_filename,
1980 rule.rule_n_line,
1981 format!("Label {} for \"{}({})\" is never used.", rhs.alias, rhs.name, rhs.alias)
1982 )
1983 );
1984 }
1985 }
1986
1987 Ok(())
1988 }
1989
1990 fn get_minor_type(&self, symbols: &mut Symbols) -> Vec<(String, String)>
1998 { let arraysize = symbols.n_symbols * 2; let mut types = Vec::new(); types.resize(arraysize, String::new());
2002
2003 'l: for (i, sp) in symbols.array[0 .. symbols.n_symbols].iter_mut().enumerate()
2007 { if i == symbols.error_symbol_index
2008 { sp.dtnum = arraysize+1;
2009 continue;
2010 }
2011 if sp.typ==SymbolType::TERMINAL || (sp.data_type.is_empty() && self.vartype.is_empty())
2012 { sp.dtnum = 0;
2013 continue;
2014 }
2015 let stddt = if !sp.data_type.is_empty()
2016 { &sp.data_type
2017 }
2018 else
2019 { &self.vartype
2020 };
2021 if !self.token_type.is_empty() && &self.token_type == stddt
2022 { sp.dtnum = 0;
2023 continue;
2024 }
2025 let mut hash = DefaultHasher::new();
2026 stddt.hash(&mut hash);
2027 let mut hash = hash.finish() as usize % arraysize;
2028 while !types[hash].is_empty()
2029 { if &types[hash] == stddt
2030 { sp.dtnum = hash + 1;
2031 continue 'l;
2032 }
2033 hash += 1;
2034 if hash >= arraysize
2035 { hash = 0;
2036 }
2037 }
2038 sp.dtnum = hash + 1;
2039 types[hash] = stddt.to_string(); }
2041
2042 let mut minor_type = Vec::with_capacity(arraysize+3);
2044 minor_type.push(("None".to_string(), "".to_string()));
2045 minor_type.push(("Symbol0".to_string(), "TokenValue".to_string()));
2046 let mut i = 1;
2047 for name in types
2048 { if !name.is_empty()
2049 { minor_type.push((format!("Symbol{}", i), name));
2050 }
2051 i += 1;
2052 }
2053 if let Some(symbol) = symbols.get_error_symbol()
2054 { minor_type.push((format!("Symbol{}", symbol.dtnum), "i32".to_string()));
2055 }
2056
2057 minor_type
2059 }
2060
2061 fn init_acttab(&mut self, symbols: &Symbols, rules: &mut Vec<Rule>, states: &mut States) -> ActTab
2062 { let mut acttab = ActTab::new(symbols.n_terminals, symbols.n_symbols);
2063
2064 let mut ax = Vec::with_capacity(states.n_no_tail*2);
2066 for stp in states.array[0 .. states.n_no_tail].iter()
2067 { ax.push(AxSet::new(stp.n_state, true, stp.n_token_act, ax.len()));
2068 ax.push(AxSet::new(stp.n_state, false, stp.n_nt_act, ax.len()));
2069 }
2070 ax.sort();
2071
2072 let mut min_token_offset = 0;
2073 let mut max_token_offset = 0;
2074 let mut min_nt_offset = 0;
2075 let mut max_nt_offset = 0;
2076
2077 for ax_i in ax.iter()
2079 { if ax_i.n_action == 0
2080 { break;
2081 }
2082 let stp = &mut states.array[ax_i.n_state];
2083 if ax_i.is_tkn
2084 { for action in stp.actions.iter()
2085 { if action.borrow().symbol_index < symbols.n_terminals
2086 { let n_action = self.compute_action(symbols, action);
2087 if n_action != std::usize::MAX
2088 { acttab.acttab_action(action.borrow().symbol_index, n_action);
2089 }
2090 }
2091 }
2092 stp.token_offset = acttab.acttab_insert(true);
2093 if stp.token_offset < min_token_offset
2094 { min_token_offset = stp.token_offset;
2095 }
2096 if stp.token_offset > max_token_offset
2097 { max_token_offset = stp.token_offset;
2098 }
2099 }
2100 else
2101 { for action in stp.actions.iter()
2102 { if action.borrow().symbol_index >= symbols.n_terminals && action.borrow().symbol_index != symbols.n_symbols
2103 { let n_action = self.compute_action(symbols, action);
2104 if n_action != std::usize::MAX
2105 { acttab.acttab_action(action.borrow().symbol_index, n_action);
2106 }
2107 }
2108 }
2109 stp.nt_offset = acttab.acttab_insert(false);
2110 if stp.nt_offset < min_nt_offset
2111 { min_nt_offset = stp.nt_offset;
2112 }
2113 if stp.nt_offset > max_nt_offset
2114 { max_nt_offset = stp.nt_offset;
2115 }
2116 }
2117 }
2118
2119 for rule in rules.iter_mut()
2121 { rule.does_reduce = false;
2122 }
2123 for state in states.array[0 .. states.n_no_tail].iter()
2124 { for action in state.actions.iter()
2125 { let action = action.borrow_mut();
2126 if action.typ==ActionType::Reduce || action.typ==ActionType::ShiftReduce
2127 { if let StateOrRule::Rule(n_rule) = action.x
2128 { rules[n_rule].does_reduce = true;
2129 }
2130 }
2131 }
2132 }
2133
2134 let mut n_fallbacks = 0;
2135 if self.has_fallback
2136 { n_fallbacks = symbols.n_terminals - 1;
2137 while n_fallbacks>0 && symbols.array[n_fallbacks].fallback_index==std::usize::MAX
2138 { n_fallbacks -= 1;
2139 }
2140 n_fallbacks += 1;
2141 }
2142 self.has_fallback = n_fallbacks != 0;
2143
2144 let mut n_shift_offset = states.n_no_tail;
2145 while n_shift_offset >0 && states.array[n_shift_offset -1].token_offset == std::isize::MIN
2146 { n_shift_offset -= 1;
2147 }
2148
2149 let mut reduce_count = states.n_no_tail;
2150 while reduce_count>0 && states.array[reduce_count-1].nt_offset == std::isize::MIN
2151 { reduce_count -= 1;
2152 }
2153
2154 acttab.min_token_offset = min_token_offset;
2155 acttab.max_token_offset = max_token_offset;
2156 acttab.min_nt_offset = min_nt_offset;
2157 acttab.max_nt_offset = max_nt_offset;
2158 acttab.n_fallbacks = n_fallbacks;
2159 acttab.n_shift_offset = n_shift_offset;
2160 acttab.reduce_count = reduce_count;
2161
2162 acttab
2163 }
2164
2165 fn get_lemon(mut self, mut symbols: Symbols, mut rules: Vec<Rule>, states: States, acttab: ActTab) -> ParserResult<LemonMint>
2167 { let sz_code_type = Self::minimum_size_type(0, symbols.n_symbols as isize+1);
2169 let sz_action_type = Self::minimum_size_type(0, (states.array.len()+rules.len()+5) as isize);
2170 let sz_shift_offset_type = Self::minimum_size_type(acttab.min_token_offset-1, acttab.max_token_offset);
2171 let sz_reduce_offset_type = Self::minimum_size_type(acttab.min_nt_offset-1, acttab.max_nt_offset);
2172
2173 let mut token = Vec::with_capacity(symbols.n_terminals);
2175 for symbol in symbols.array[1 .. symbols.n_terminals].iter()
2176 { token.push(Arc::clone(&symbol.name));
2177 }
2178
2179 self.tables_size += rules.len() * sz_code_type.abs() as usize;
2182
2183 self.n_action_table_entries = acttab.get_n_actions();
2196 let mut n = acttab.get_n_lookahead();
2197 let n_lookahead = std::cmp::max(n, symbols.n_terminals + self.n_action_table_entries);
2198 let mut lookahead_and_action = Vec::with_capacity(n_lookahead);
2199 for (i, LookaheadAction {lookahead, action}) in acttab.iter().enumerate()
2200 { let lookahead = if *lookahead == std::usize::MAX {symbols.n_symbols} else {*lookahead};
2201 let action = if i >= self.n_action_table_entries {0} else if *action == std::usize::MAX {self.no_action} else {*action};
2202 lookahead_and_action.push((lookahead, action));
2203 }
2204 while n < n_lookahead
2207 { lookahead_and_action.push((symbols.n_terminals, 0));
2208 n += 1;
2209 }
2210 self.tables_size += lookahead_and_action.len() * (sz_code_type + sz_action_type).abs() as usize;
2211
2212 let mut shift_offset = Vec::with_capacity(acttab.n_shift_offset);
2214 for stp in states.array.iter().take(acttab.n_shift_offset)
2215 { shift_offset.push(if stp.token_offset==std::isize::MIN {acttab.min_token_offset - 1} else {stp.token_offset});
2216 }
2217 self.tables_size += shift_offset.len() * sz_shift_offset_type.abs() as usize;
2218
2219 let mut reduce_offset = Vec::with_capacity(acttab.reduce_count);
2221 for stp in states.array.iter().take(acttab.reduce_count)
2222 { reduce_offset.push(if stp.nt_offset==std::isize::MIN {acttab.min_nt_offset - 1} else {stp.nt_offset});
2223 }
2224 self.tables_size += reduce_offset.len() * sz_reduce_offset_type.abs() as usize;
2225
2226 let mut default = Vec::with_capacity(states.n_no_tail);
2228 for stp in states.array.iter().take(states.n_no_tail)
2229 { default.push(if stp.default_reduce_action!=std::usize::MAX {stp.default_reduce_action + self.min_reduce} else {self.error_action});
2230 }
2231 self.tables_size += default.len() * sz_action_type.abs() as usize;
2232
2233 let mut fallback = Vec::new();
2235 if self.has_fallback
2236 { fallback.reserve(acttab.n_fallbacks);
2237 for symbol in symbols.array.iter().take(acttab.n_fallbacks)
2238 { if symbol.fallback_index != std::usize::MAX
2239 { let fb = &symbols.array[symbol.fallback_index];
2240 fallback.push((fb.index, Arc::clone(&symbol.name), Arc::clone(&fb.name)));
2241 }
2242 else
2243 { fallback.push((0, Arc::clone(&symbol.name), Arc::new(String::new())));
2244 }
2245 }
2246 }
2247 self.tables_size += fallback.len() * sz_code_type.abs() as usize;
2248
2249 let mut token_names = Vec::new();
2251 if self.with_trace && symbols.n_symbols!=0
2252 { token_names.reserve(symbols.n_symbols);
2253 for symbol in symbols.array.iter().take(symbols.n_symbols)
2254 { token_names.push(Arc::clone(&symbol.name));
2255 }
2256 }
2257
2258 for sym in symbols.array.iter()
2260 { for n_rule in sym.sym_rules_arr.iter()
2261 { self.translate_code(&mut rules[*n_rule])?;
2262 }
2263 }
2264
2265 let start_type = symbols.get_start_symbol().data_type.clone();
2266 let minor_type = self.get_minor_type(&mut symbols);
2267 let n_symbols = symbols.n_symbols;
2268 let n_states = states.array.len();
2269 let n_no_tail = states.n_no_tail;
2270 let error_symbol = if let Some(symbol) = symbols.get_error_symbol() {symbol.index} else {0};
2271 let n_terminals = symbols.n_terminals;
2272 let n_nonterminals = symbols.n_symbols - symbols.n_terminals;
2273
2274 Ok
2275 ( LemonMint
2276 { symbols,
2277 rules,
2278 states,
2279 token_type: self.token_type,
2280 vartype: self.vartype,
2281 start_name: self.start_name,
2282 start_type,
2283 extra_argument_type: self.extra_argument_type,
2284 extracode: self.extracode,
2285 minor_type,
2286 token,
2287
2288 sz_code_type,
2289 sz_action_type,
2290 sz_shift_offset_type,
2291 sz_reduce_offset_type,
2292
2293 n_symbols,
2294 n_states,
2295 n_no_tail,
2296 n_fallbacks: acttab.n_fallbacks,
2297 error_symbol,
2298 with_fallback: self.has_fallback,
2299 shift_count: acttab.n_shift_offset-1,
2300 reduce_count: acttab.reduce_count-1,
2301 with_trace: self.with_trace,
2302 trace_prompt: self.trace_prompt,
2303 shift_min: acttab.min_token_offset,
2304 shift_max: acttab.max_token_offset,
2305 reduce_min: acttab.min_nt_offset,
2306 reduce_max: acttab.max_nt_offset,
2307
2308 n_terminals,
2309 n_nonterminals,
2310 tables_size: self.tables_size,
2311 n_action_table_entries: self.n_action_table_entries,
2312
2313 lookahead_and_action,
2314 shift_offset,
2315 reduce_offset,
2316 default,
2317 fallback,
2318 token_names,
2319 }
2320 )
2321 }
2322
2323 pub fn load_y_file(self, filename: &Arc<String>) -> ParserResult<Self>
2325 { self.load_y(filename, File::open(filename.as_ref()).map_err(|e| LemonMintError::new(filename, 1, e.to_string()))?)
2326 }
2327
2328 pub fn load_y<R>(mut self, filename: &Arc<String>, input: R) -> ParserResult<Self> where R: io::Read
2340 { let input = BufReader::new(input);
2341 let mut n_line = 0;
2342 let mut lines = input.lines();
2343 let mut part_till_comment: Option<String> = None; 'l: while let Some(line) = lines.next()
2345 { n_line += 1;
2346 let mut line = line.map_err(|e| LemonMintError::new(filename, n_line, e.to_string()))?;
2347 if let Some(part) = part_till_comment.take()
2349 { if let Some(pos) = line.find("*/")
2350 { line.replace_range(.. pos+2, &part);
2351 }
2352 else
2353 { part_till_comment = Some(part);
2354 continue;
2355 }
2356 }
2357 loop
2358 { if let Some(pos) = line.find('/')
2359 { match line.bytes().skip(pos+1).next()
2360 { Some(b'/') => { line.truncate(pos);
2362 }
2363 Some(b'*') => { if let Some(len_minus_2) = line[pos+2 ..].find("*/")
2365 { line.replace_range(pos .. pos+len_minus_2+2, "");
2366 continue;
2367 }
2368 else
2369 { line.truncate(pos);
2370 part_till_comment = Some(line);
2371 continue 'l;
2372 }
2373 }
2374 _ => {}
2375 }
2376 }
2377 break;
2378 }
2379 let mut line = line.trim();
2381 if !line.is_empty()
2382 { let mut directive = Directive::Rule;
2383 let mut symbol_name: Cow<str> = "".into();
2384 let mut rule_rhs: Cow<str> = "".into();
2385 if line.as_bytes()[0] == b'%'
2386 { let pos = line.bytes().position(|c| c.is_ascii_whitespace()).unwrap_or(line.len());
2387 let token = &line[1 .. pos];
2388 line = &line[pos ..].trim_start();
2389 directive = match token
2390 { "token_type" => Directive::TokenType,
2391 "type" => Directive::Type,
2392 "default_type" => Directive::DefaultType,
2393 "start_symbol" => Directive::StartSymbol,
2394 "trace" => Directive::Trace,
2395 "extra_argument" => Directive::ExtraArgument,
2396 "left" => Directive::Left,
2397 "right" => Directive::Right,
2398 "nonassoc" => Directive::Nonassoc,
2399 "fallback" => Directive::Fallback,
2400 "code" | "include" => Directive::Code,
2401 _ =>
2402 { return Err(LemonMintError::new(filename, n_line, format!("Directive not supported: %{}", token)));
2403 }
2404 };
2405 }
2406 match directive
2407 { Directive::Type | Directive::Fallback =>
2408 { let pos = line.bytes().position(|c| !c.is_ascii_alphanumeric() && c!=b'_').unwrap_or(line.len());
2410 if pos == 0
2411 { return Err(LemonMintError::new(filename, n_line, "Expected symbol name after %type".to_string()));
2412 }
2413 symbol_name = line[.. pos].to_string().into();
2414 line = &line[pos ..].trim_start();
2415 }
2416 Directive::Rule =>
2417 { let pos = line.find("::=").ok_or_else(|| LemonMintError::new(filename, n_line, "Couldn't interpret this line".to_string()))?;
2418 symbol_name = line[.. pos].trim_end().to_string().into();
2419 line = &line[pos+3 ..].trim_start();
2420 let pos = line.find('.').ok_or_else(|| LemonMintError::new(filename, n_line, "Rules must be terminated with a dot".to_string()))?;
2421 rule_rhs = line[.. pos].trim_end().to_string().into();
2422 line = &line[pos+1 ..].trim_start();
2423 }
2424 _ => {}
2425 }
2426 let mut value: Cow<str> = line.into();
2427 if line.bytes().next() == Some(b'{')
2428 { line = &line[1 ..].trim_start(); let (mut balance, mut last_close) = (1, usize::MAX);
2430 Self::balanced_braces(filename, n_line, line, &mut balance, &mut last_close)?;
2431 if balance == 0
2432 { value = line[.. last_close].into(); }
2434 else
2435 { let mut buffer = String::with_capacity(128);
2437 buffer.push_str(line);
2438 buffer.push('\n');
2439 let from_n_line = n_line;
2440 while let Some(line) = lines.next()
2441 { n_line += 1;
2442 let line = line.map_err(|e| LemonMintError::new(filename, n_line, e.to_string()))?;
2443 Self::balanced_braces(filename, n_line, &line, &mut balance, &mut last_close)?;
2444 if balance == 0
2445 { buffer.push_str(&line[.. last_close]); break;
2447 }
2448 buffer.push_str(&line);
2449 buffer.push('\n');
2450 }
2451 if balance > 0
2452 { return Err(LemonMintError::new(filename, n_line, format!("Braces not closed at the end of file since line {}", from_n_line)));
2453 }
2454 value = buffer.into();
2455 }
2456 }
2457 else if !line.is_empty() && line.as_bytes()[line.len()-1]==b'.'
2458 { value = line[.. line.len()-1].trim_end().into(); }
2460 self = match directive
2461 { Directive::Rule => self.add_rule(filename, n_line, symbol_name.into(), rule_rhs.as_ref(), value.into()),
2462 Directive::TokenType => self.set_token_type(value.into()),
2463 Directive::Type => self.add_type(filename, n_line, symbol_name.into(), value.into()),
2464 Directive::DefaultType => self.set_default_type(value.into()),
2465 Directive::StartSymbol => self.set_start_symbol(filename, n_line, value.into()),
2466 Directive::Trace => self.set_trace_prompt(value.into()),
2467 Directive::ExtraArgument => self.set_extra_argument_type(value.into()),
2468 Directive::Left => self.set_left(filename, n_line, value.as_ref()),
2469 Directive::Right => self.set_right(filename, n_line, value.as_ref()),
2470 Directive::Nonassoc => self.set_nonassoc(filename, n_line, value.as_ref()),
2471 Directive::Fallback => self.add_fallback(filename, n_line, symbol_name.into(), value.as_ref()),
2472 Directive::Code => self.add_code(value.into()),
2473 }?;
2474 }
2475 }
2476 Ok(self)
2477 }
2478
2479 fn balanced_braces(filename: &Arc<String>, n_line: usize, line: &str, balance: &mut i32, last_close: &mut usize) -> ParserResult<()>
2480 { for (i, c) in line.bytes().enumerate()
2481 { match c
2482 { b'{' => *balance += 1,
2483 b'}' => {*balance -= 1; *last_close = i}
2484 _ => {}
2485 }
2486 }
2487 if *balance < 0
2488 { return Err(LemonMintError::new(filename, n_line, "Braces on line not balanced".to_string()));
2489 }
2490 if *balance == 0
2491 { if !line[*last_close+1 ..].trim_end().is_empty()
2492 { return Err(LemonMintError::new(filename, n_line, "Junk after closing brace".to_string()));
2493 }
2494 }
2495 Ok(())
2496 }
2497
2498 pub fn set_start_symbol(mut self, filename: &Arc<String>, n_line: usize, mut value: String) -> ParserResult<Self>
2500 { let trimmed = value.trim();
2501 if trimmed.len() != value.len()
2502 { value = trimmed.to_string();
2503 }
2504 if value.find(|c: char| !c.is_ascii_alphanumeric() && c!='_').is_some()
2505 { return Err(LemonMintError::new(filename, n_line, format!("Invalid start symbol name: {}", value)));
2506 }
2507 if is_terminal_name(&value)
2508 { return Err(LemonMintError::new(filename, n_line, "Start symbol must be nonterminal".to_string()));
2509 }
2510 self.start_name = value;
2511 Ok(self)
2512 }
2513
2514 pub fn set_token_type(mut self, value: String) -> ParserResult<Self>
2516 { self.token_type = typename_to_string(value);
2517 Ok(self)
2518 }
2519
2520 pub fn set_default_type(mut self, value: String) -> ParserResult<Self>
2522 { self.vartype = typename_to_string(value);
2523 Ok(self)
2524 }
2525
2526 pub fn set_trace_prompt(mut self, value: String) -> ParserResult<Self>
2529 { self.with_trace = true;
2530 self.trace_prompt = value;
2531 Ok(self)
2532 }
2533
2534 pub fn set_extra_argument_type(mut self, value: String) -> ParserResult<Self>
2561 { self.extra_argument_type = typename_to_string(value);
2562 Ok(self)
2563 }
2564
2565 pub fn set_left(self, filename: &Arc<String>, n_line: usize, symbol_names: &str) -> ParserResult<Self>
2580 { self.add_associativity(filename, n_line, symbol_names, Associativity::LEFT)
2581 }
2582
2583 pub fn set_right(self, filename: &Arc<String>, n_line: usize, symbol_names: &str) -> ParserResult<Self>
2585 { self.add_associativity(filename, n_line, symbol_names, Associativity::RIGHT)
2586 }
2587
2588 pub fn set_nonassoc(self, filename: &Arc<String>, n_line: usize, symbol_names: &str) -> ParserResult<Self>
2590 { self.add_associativity(filename, n_line, symbol_names, Associativity::NONASSOC)
2591 }
2592
2593 fn add_associativity(mut self, filename: &Arc<String>, n_line: usize, symbol_names: &str, assoc: Associativity) -> ParserResult<Self>
2594 { for symbol_name in symbol_names.trim().split(|c: char| c.is_ascii_whitespace())
2595 { if !symbol_name.is_empty()
2596 { if symbol_name.find(|c: char| !c.is_ascii_alphanumeric() && c!='_').is_some()
2597 { return Err(LemonMintError::new(filename, n_line, format!("Invalid token name: {}", symbol_name)));
2598 }
2599 if !is_terminal_name(symbol_name)
2600 { return Err(LemonMintError::new(filename, n_line, format!("Can only set precedence for terminal symbols, not \"{}\"", symbol_name)));
2601 }
2602 if let Some(prev) = self.precedence.get(symbol_name)
2603 { return Err(LemonMintError::new(filename, n_line, format!("Symbol \"{}\" has already be given a precedence at {}:{}", symbol_name, prev.filename, prev.n_line)));
2604 }
2605 self.precedence.insert
2606 ( symbol_name.to_string(),
2607 PrecedenceInFile
2608 { filename: Arc::clone(filename),
2609 n_line,
2610 assoc,
2611 precedence: self.prec_counter,
2612 }
2613 );
2614 }
2615 }
2616 self.prec_counter += 1;
2617 Ok(self)
2618 }
2619
2620 pub fn add_type(mut self, filename: &Arc<String>, n_line: usize, mut symbol_name: String, type_name: String) -> ParserResult<Self>
2622 { let trimmed = symbol_name.trim();
2623 if trimmed.len() != symbol_name.len()
2624 { symbol_name = trimmed.to_string();
2625 }
2626 if symbol_name.find(|c: char| !c.is_ascii_alphanumeric() && c!='_').is_some()
2627 { return Err(LemonMintError::new(filename, n_line, format!("Invalid symbol name: {}", symbol_name)));
2628 }
2629 if is_terminal_name(&symbol_name)
2630 { return Err(LemonMintError::new(filename, n_line, format!("Can only set type for nonterminal symbols, not \"{}\"", symbol_name)));
2631 }
2632 if let Some(prev) = self.nonterminal_types.get(&symbol_name)
2633 { return Err(LemonMintError::new(filename, n_line, format!("Type for symbol \"{}\" already defined at {}:{}", symbol_name, prev.filename, prev.n_line)));
2634 }
2635 self.nonterminal_types.insert
2636 ( symbol_name,
2637 StringInFile
2638 { filename: Arc::clone(filename),
2639 n_line,
2640 string: typename_to_string(type_name),
2641 }
2642 );
2643 Ok(self)
2644 }
2645
2646 pub fn get_type(&self, mut symbol_name: &str) -> Option<(Arc<String>, usize)>
2648 { symbol_name = symbol_name.trim();
2649 self.nonterminal_types.get(symbol_name).map(|v| (Arc::clone(&v.filename), v.n_line))
2650 }
2651
2652 pub fn add_fallback(mut self, filename: &Arc<String>, n_line: usize, mut fallback_to_symbol_name: String, symbol_names: &str) -> ParserResult<Self>
2654 { let trimmed = fallback_to_symbol_name.trim();
2655 if trimmed.len() != fallback_to_symbol_name.len()
2656 { fallback_to_symbol_name = trimmed.to_string();
2657 }
2658 if fallback_to_symbol_name.find(|c: char| !c.is_ascii_alphanumeric() && c!='_').is_some()
2659 { return Err(LemonMintError::new(filename, n_line, format!("Invalid token name: {}", fallback_to_symbol_name)));
2660 }
2661 let fallback_to_symbol_name = Arc::new(fallback_to_symbol_name);
2662 for symbol_name in symbol_names.trim().split(|c: char| c.is_ascii_whitespace())
2663 { if !symbol_name.is_empty()
2664 { if symbol_name.find(|c: char| !c.is_ascii_alphanumeric() && c!='_').is_some()
2665 { return Err(LemonMintError::new(filename, n_line, format!("Invalid token name: {}", symbol_name)));
2666 }
2667 if !is_terminal_name(symbol_name)
2668 { return Err(LemonMintError::new(filename, n_line, format!("Can only set fallback to terminal symbols, not \"{}\"", symbol_name)));
2669 }
2670 let symbol_name = Arc::new(symbol_name.to_string());
2671 self.symbols_builder.add(&symbol_name);
2672 self.symbols_builder.add(&fallback_to_symbol_name);
2673 let sp = self.symbols_builder.get(&symbol_name);
2674 if sp.fallback_index != std::usize::MAX
2675 { return Err(LemonMintError::new(filename, n_line, format!("More than one fallback assigned to token \"{}\"", symbol_name)));
2676 }
2677 let fsp = self.symbols_builder.get(&fallback_to_symbol_name);
2678 if *fsp == *sp
2679 { return Err(LemonMintError::new(filename, n_line, format!("Symbol \"{}\" is asked fallback to self // {}, {}", symbol_name, fallback_to_symbol_name, symbol_name)));
2680 }
2681 self.symbols_builder.get_mut(&symbol_name).fallback_index = fsp.index;
2682 self.has_fallback = true;
2683 }
2684 }
2685 Ok(self)
2686 }
2687
2688 pub fn add_rule(mut self, filename: &Arc<String>, n_line: usize, mut lhs_name: String, rhs_names_aliases: &str, code: String) -> ParserResult<Self>
2709 { let trimmed = lhs_name.trim();
2710 if trimmed.len() != lhs_name.len()
2711 { lhs_name = trimmed.to_string();
2712 }
2713 if is_terminal_name(&lhs_name)
2714 { return Err(LemonMintError::new(filename, n_line, format!("Invalid LHS symbol: \"{}\"", lhs_name)));
2715 }
2716 let mut code = code;
2717 if code.trim().is_empty()
2718 { code = String::new();
2719 }
2720 if self.start_name.is_empty()
2721 { self.start_name = lhs_name.clone();
2722 }
2723 let lhs_name = Arc::new(lhs_name);
2724 let lhs_index = self.symbols_builder.add(&lhs_name);
2725 let mut rule = Rule::new(filename, n_line, &lhs_name, lhs_index, self.rules.len(), code);
2726 let mut s = rhs_names_aliases.trim_start();
2728 while s.len() != 0
2729 { let name_len = s.chars().position(|c| !c.is_ascii_alphanumeric() && c!='_').unwrap_or(s.len());
2730 if name_len == 0
2731 { return Err(LemonMintError::new(filename, n_line, format!("Invalid RHS expression: \"{}\"", rhs_names_aliases)));
2732 }
2733 let rhs_name = Arc::new(s[.. name_len].to_string());
2734 let rhs_index = self.symbols_builder.add(&rhs_name);
2735 s = s[name_len ..].trim_start();
2736 let mut alias = String::new();
2737 if s.bytes().next() == Some(b'(')
2738 { s = s[1 ..].trim_start();
2739 let alias_len = s.chars().position(|c| !c.is_ascii_alphanumeric() && c!='_').unwrap_or(s.len());
2740 alias = s[.. alias_len].to_string();
2741 s = s[alias_len ..].trim_start();
2742 if alias_len==0 || s.bytes().next() != Some(b')')
2743 { return Err(LemonMintError::new(filename, n_line, format!("Invalid alias in RHS expression: \"{}\"", rhs_names_aliases)));
2744 }
2745 s = s[1 ..].trim_start();
2746 }
2747 rule.rhs.push(Rhs{name: rhs_name, index: rhs_index, alias});
2748 }
2749 self.symbols_builder.get_mut(&lhs_name).sym_rules_arr.insert(0, self.rules.len()); self.rules.push(rule);
2751 Ok(self)
2752 }
2753
2754 pub fn add_code(mut self, code: String) -> ParserResult<Self>
2756 { if self.extracode.is_empty()
2757 { self.extracode = code;
2758 }
2759 else
2760 { self.extracode.push_str("\n\n");
2761 self.extracode.push_str(&code);
2762 }
2763 Ok(self)
2764 }
2765
2766 pub fn set_no_compress(mut self, new_no_compress: bool) -> ParserResult<Self>
2768 { self.no_compress = new_no_compress;
2769 Ok(self)
2770 }
2771
2772 pub fn set_no_resort(mut self, new_no_resort: bool) -> ParserResult<Self>
2774 { self.no_resort = new_no_resort;
2775 Ok(self)
2776 }
2777
2778 pub fn try_into_lemon(mut self) -> ParserResult<LemonMint>
2782 { let mut rules = mem::replace(&mut self.rules, Vec::new());
2784 if rules.len() == 0
2785 { return Err(LemonMintError::new(&Arc::new(String::new()), 1, "Empty grammar".to_string()));
2786 }
2787
2788 let mut symbols =
2790 { let symbols_builder = mem::replace(&mut self.symbols_builder, SymbolsBuilder::new(true));
2791 let nonterminal_types = mem::replace(&mut self.nonterminal_types, HashMap::new());
2792 let precedence = mem::replace(&mut self.precedence, HashMap::new());
2793
2794 symbols_builder.into_symbols(&self.start_name, nonterminal_types, precedence, &mut rules)? };
2796
2797 rules.sort_by
2799 ( |a, b|
2800 { if a.code.is_empty() == b.code.is_empty()
2801 { a.index.cmp(&b.index)
2802 }
2803 else if a.code.is_empty()
2804 { Ordering::Greater
2805 }
2806 else
2807 { Ordering::Less
2808 }
2809 }
2810 );
2811 for (i, rule) in rules.iter_mut().enumerate()
2812 { rule.index = i;
2813 }
2814
2815 Self::find_rule_precedences(&mut symbols, &mut rules);
2817
2818 self.find_first_sets(&mut symbols, &mut rules);
2820
2821 if !self.start_name.is_empty()
2823 { if symbols.start_symbol_index == std::usize::MAX
2824 { return Err(LemonMintError::new(&Self::get_filename_of_first_rule(&rules), 1, format!("The specified start symbol \"{}\" is not in a nonterminal of the grammar", self.start_name)));
2825 }
2826 }
2827 else
2828 { return Err(LemonMintError::new(&Self::get_filename_of_first_rule(&rules), 1, "Please, specify a start symbol".to_string()));
2829 }
2830
2831 for rule in rules.iter()
2834 { for rhs in &rule.rhs
2835 { if rhs.index == symbols.start_symbol_index
2836 { return Err(LemonMintError::new(&Self::get_filename_of_first_rule(&rules), 1, format!("The start symbol \"{}\" occurs on the right-hand side of a rule", rhs.name)));
2837 }
2838 }
2839 }
2840
2841 dump_symbols(&symbols, &rules);
2842
2843 let mut states = StatesBuilder::build(&symbols, &mut rules, symbols.get_start_symbol(), symbols.n_terminals, &mut self.actions_enum)?;
2845
2846 dump_states(&states, &rules, &symbols, 1);
2847
2848 Self::find_links(&states);
2850
2851 dump_states(&states, &rules, &symbols, 2);
2852
2853 Self::find_follow_sets(&states);
2855
2856 dump_states(&states, &rules, &symbols, 3);
2857
2858 self.find_actions(&symbols, &mut rules, &mut states)?;
2860
2861 dump_states(&states, &rules, &symbols, 4);
2862
2863 if !self.no_compress
2865 { self.compress_tables(&symbols, &rules, &mut states, symbols.default_symbol_index);
2866 }
2867
2868 dump_states(&states, &rules, &symbols, 5);
2869
2870 if !self.no_resort
2873 { self.resort_states(&symbols, &mut states);
2874 }
2875
2876 dump_states(&states, &rules, &symbols, 6);
2877
2878 self.min_shift_reduce = states.array.len();
2880 self.error_action = self.min_shift_reduce + rules.len();
2881 self.accept_action = self.error_action + 1;
2882 self.no_action = self.accept_action + 1;
2883 self.min_reduce = self.no_action + 1;
2884 self.max_action = self.min_reduce + rules.len();
2885 let acttab = self.init_acttab(&symbols, &mut rules, &mut states);
2886
2887 dump_states(&states, &rules, &symbols, 7);
2888
2889 if self.n_conflicts > 0
2891 { Err(LemonMintError::new(&Self::get_filename_of_first_rule(&rules), 1, format!("{} parsing conflicts", self.n_conflicts)))
2892 }
2893 else
2894 { self.get_lemon(symbols, rules, states, acttab)
2895 }
2896 }
2897}
2898
2899#[derive(Debug, Copy, Clone, PartialEq)]
2900enum Lang
2901{ Rust
2902}
2903
2904fn size_type_to_str(lang: Lang, n_bytes: isize) -> &'static str
2905{ match (lang, n_bytes)
2906 { (Lang::Rust, -1) => "i8",
2907 (Lang::Rust, -2) => "i16",
2908 (Lang::Rust, -4) => "i32",
2909 (Lang::Rust, 1) => "u8",
2910 (Lang::Rust, 2) => "u16",
2911 (Lang::Rust, 4) => "u32",
2912 (Lang::Rust, _) => "isize",
2913 }
2914}
2915
2916#[derive(Debug)]
2918pub struct LemonMint
2919{ symbols: Symbols,
2920 rules: Vec<Rule>, states: States,
2922 token_type: String, vartype: String, start_name: String, start_type: String,
2926 extra_argument_type: String,
2927 extracode: String,
2928 minor_type: Vec<(String, String)>,
2929 token: Vec<Arc<String>>,
2930
2931 sz_code_type: isize,
2932 sz_action_type: isize,
2933 sz_shift_offset_type: isize,
2934 sz_reduce_offset_type: isize,
2935
2936 n_symbols: usize,
2937 n_states: usize,
2938 n_no_tail: usize,
2939 n_fallbacks: usize,
2940 error_symbol: usize,
2941 #[allow(dead_code)] with_fallback: bool,
2942 shift_count: usize,
2943 reduce_count: usize,
2944 with_trace: bool,
2945 trace_prompt: String, shift_min: isize,
2947 shift_max: isize,
2948 reduce_min: isize,
2949 reduce_max: isize,
2950
2951 n_terminals: usize,
2952 #[allow(dead_code)] n_nonterminals: usize,
2953 #[allow(dead_code)] tables_size: usize, n_action_table_entries: usize, lookahead_and_action: Vec<(usize, usize)>,
2957 shift_offset: Vec<isize>,
2958 reduce_offset: Vec<isize>,
2959 default: Vec<usize>,
2960 fallback: Vec<(usize, Arc<String>, Arc<String>)>,
2961 token_names: Vec<Arc<String>>,
2962}
2963impl LemonMint
2964{ pub fn gen_rust<W>(&self, out: &mut W) -> io::Result<()> where W: io::Write
2970 { writeln!(out, "pub mod code {{")?;
2971
2972 let mut lempar_reader = LemparReader::new();
2973 lempar_reader.copy_part(out)?; writeln!(out, "pub type TokenValue = {};", if !self.token_type.is_empty() {&self.token_type} else {"String"})?;
2977 writeln!(out, "pub type ExtraArgumentType = {};", if !self.extra_argument_type.is_empty() {&self.extra_argument_type} else {"()"})?;
2978 writeln!(out, "pub type StartType = {};", if !self.start_type.is_empty() {&self.start_type} else {"()"})?;
2979 writeln!(out, "type CodeType = {};", size_type_to_str(Lang::Rust, self.sz_code_type))?;
2980 writeln!(out, "type ActionType = {};", size_type_to_str(Lang::Rust, self.sz_action_type))?;
2981 writeln!(out, "type ShiftOffsetType = {};", size_type_to_str(Lang::Rust, self.sz_shift_offset_type))?;
2982 writeln!(out, "type ReduceOffsetType = {};", size_type_to_str(Lang::Rust, self.sz_reduce_offset_type))?;
2983
2984 write!(out, "enum MinorType\n{{")?;
2985 for (variant, typ) in self.minor_type.iter()
2986 { if typ.is_empty()
2987 { writeln!(out, "\t{},", variant)?;
2988 }
2989 else
2990 { writeln!(out, "\t{}({}),", variant, typ)?;
2991 }
2992 }
2993 writeln!(out, "}}")?;
2994
2995 writeln!(out, "#[repr(u32)]\n#[derive(Copy, Clone, PartialEq)]\n#[allow(non_camel_case_types)]")?;
2997 write!(out, "pub enum Token\n{{")?;
2998 for (i, name) in self.token.iter().enumerate()
2999 { if self.token_type.is_empty()
3000 { writeln!(out, "\t{:<30} = {:2},", name, i+1)?;
3001 }
3002 else
3003 { writeln!(out, "\t{:<30} = {:2},", name, i+1)?;
3004 }
3005 }
3006 writeln!(out, "}}\n")?;
3007
3008 writeln!(out, "const NO_CODE: CodeType = {}; // YYNOCODE", self.n_symbols)?;
3010 writeln!(out, "const N_STATES: usize = {}; // YYNSTATE", self.n_no_tail)?;
3011 writeln!(out, "const N_RULES: usize = {}; // YYNRULE", self.rules.len())?;
3012 writeln!(out, "const N_TERMINALS: usize = {}; // YYNTOKEN", self.n_terminals)?;
3013 writeln!(out, "const MAX_SHIFT: usize = N_STATES-1; // YY_MAX_SHIFT")?;
3014 writeln!(out, "const MIN_SHIFTREDUCE: usize = {}; // YY_MIN_SHIFTREDUCE", self.n_states)?;
3015 writeln!(out, "const MAX_SHIFTREDUCE: usize = MIN_SHIFTREDUCE + N_RULES - 1; // YY_MAX_SHIFTREDUCE")?;
3016 writeln!(out, "const ERROR_ACTION: usize = MAX_SHIFTREDUCE + 1; // YY_ERROR_ACTION")?;
3017 writeln!(out, "const ACCEPT_ACTION: usize = ERROR_ACTION + 1; // YY_ACCEPT_ACTION")?;
3018 writeln!(out, "const NO_ACTION: usize = ACCEPT_ACTION + 1; // YY_NO_ACTION")?;
3019 writeln!(out, "const MIN_REDUCE: usize = NO_ACTION + 1; // YY_MIN_REDUCE")?;
3020 writeln!(out, "//const MAX_REDUCE: usize = MIN_REDUCE + N_RULES - 1; // YY_MAX_REDUCE")?;
3021 writeln!(out, "const ERROR_SYMBOL: CodeType = {}; // YYERRORSYMBOL", self.error_symbol)?;
3022 writeln!(out, "const WITH_FALLBACK: bool = {}; // YYFALLBACK", if self.n_fallbacks>0 {"true"} else {"false"})?;
3023 writeln!(out, "const SHIFT_COUNT: usize = {}; // YY_SHIFT_COUNT", self.shift_count)?;
3024 writeln!(out, "const REDUCE_COUNT: usize = {}; // YY_REDUCE_COUNT", self.reduce_count)?;
3025 writeln!(out, "//const SHIFT_MIN: i32 = {}; // YY_SHIFT_MIN", self.shift_min)?;
3026 writeln!(out, "//const SHIFT_MAX: i32 = {}; // YY_SHIFT_MAX", self.shift_max)?;
3027 writeln!(out, "//const REDUCE_MIN: i32 = {}; // YY_REDUCE_MIN", self.reduce_min)?;
3028 writeln!(out, "//const REDUCE_MAX: i32 = {}; // YY_REDUCE_MAX", self.reduce_max)?;
3029 writeln!(out, "const ACTTAB_COUNT: usize = {}; // YY_ACTTAB_COUNT", self.n_action_table_entries)?;
3030 writeln!(out, "const TRACE: bool = {};", if self.with_trace {"true"} else {"false"})?;
3031
3032 if self.trace_prompt.chars().position(|c| c=='\\' || c=='"').is_none()
3034 { writeln!(out, "const TRACE_PROMPT: &str = \"{}\";", self.trace_prompt)?;
3035 }
3036 else
3037 { let mut tag = String::with_capacity(self.trace_prompt.len()+1);
3038 for _i in 0 .. self.trace_prompt.len()+1
3039 { tag.push('#');
3040 if !self.trace_prompt.contains(&tag)
3041 { break;
3042 }
3043 }
3044 writeln!(out, "const TRACE_PROMPT: &str = r{tag}\"{}\"{tag};", self.trace_prompt, tag=tag)?;
3045 }
3046
3047 write!(out, "const LOOKAHEAD_AND_ACTION: [LookaheadAndAction; {}] =", self.lookahead_and_action.len())?;
3060 let mut formatter = ArrayFormatter::new(2);
3061 for (lookahead, action) in self.lookahead_and_action.iter()
3062 { formatter.separ(out)?;
3063 write!(out, "LookaheadAndAction {{lookahead: {:4}, action: {:4}}}", lookahead, action)?;
3064 }
3065 formatter.end(out)?;
3066
3067 write!(out, "const SHIFT_OFFSET: [ShiftOffsetType; {}] =", self.shift_offset.len())?;
3069 let mut formatter = ArrayFormatter::new(16);
3070 for offset in self.shift_offset.iter()
3071 { formatter.separ(out)?;
3072 write!(out, "{:4}", offset)?;
3073 }
3074 formatter.end(out)?;
3075
3076 write!(out, "const REDUCE_OFFSET: [ReduceOffsetType; {}] =", self.reduce_offset.len())?;
3078 let mut formatter = ArrayFormatter::new(16);
3079 for offset in self.reduce_offset.iter()
3080 { formatter.separ(out)?;
3081 write!(out, "{:4}", offset)?;
3082 }
3083 formatter.end(out)?;
3084
3085 write!(out, "const DEFAULT: [ActionType; {}] =", self.default.len())?;
3087 let mut formatter = ArrayFormatter::new(16);
3088 for action in self.default.iter()
3089 { formatter.separ(out)?;
3090 write!(out, "{:4}", action)?;
3091 }
3092 formatter.end(out)?;
3093
3094 lempar_reader.copy_part(out)?; write!(out, "const FALLBACK: [CodeType; {}] =", self.fallback.len())?;
3099 let mut formatter = ArrayFormatter::new(1);
3100 for (index, name, to_name) in self.fallback.iter()
3101 { formatter.separ(out)?;
3102 write!(out, "{:3} /* {:10} => {} */", index, name, to_name)?;
3103 }
3104 formatter.end(out)?;
3105
3106 lempar_reader.copy_part(out)?; write!(out, "const TOKEN_NAMES: [&str; {}] =", self.token_names.len())?;
3111 let mut formatter = ArrayFormatter::new(1);
3112 for name in self.token_names.iter()
3113 { formatter.separ(out)?;
3114 write!(out, "{:<15}", format!("\"{}\"", name))?;
3115 }
3116 formatter.end(out)?;
3117
3118 lempar_reader.copy_part(out)?; write!(out, "const RULE_NAMES: [&str; {}] =", self.rules.len())?;
3124 let mut formatter = ArrayFormatter::new(1);
3125 for rule in self.rules.iter()
3126 { formatter.separ(out)?;
3127 write!(out, "\"{}\"", rule)?;
3128 }
3129 formatter.end(out)?;
3130
3131 lempar_reader.copy_part(out)?; write!(out, "const RULES_INFO: [CodeType; {}] =", self.rules.len())?;
3137 let mut formatter = ArrayFormatter::new(16);
3138 for rule in &self.rules
3139 { formatter.separ(out)?;
3140 write!(out, "{:4}", rule.lhs_index)?;
3141 }
3142 formatter.end(out)?;
3143
3144 lempar_reader.copy_part(out)?; for rule in self.rules.iter()
3149 { if !rule.code.is_empty() { write!(out, "\t\t\t{} =>", rule.index)?;
3151 let has_data_type = !self.symbols.array[rule.lhs_index].data_type.is_empty();
3152 let mut next_indent = "\t\t\t\t";
3153 if has_data_type && !rule.lhs_start
3154 { write!(out, " MinorType::Symbol{}\n\t\t\t(\t{{", self.symbols.array[rule.lhs_index].dtnum)?;
3155 next_indent = "\t\t\t\t\t";
3156 }
3157 else
3158 { write!(out, "\n\t\t\t{{")?;
3159 }
3160 let mut indent = "\t";
3161 let mut n_aliases = 0;
3162 let n_args = rule.rhs.len();
3163 for i in (0 .. n_args).rev()
3164 { let has_alias = !rule.rhs[i].alias.is_empty();
3165 if has_alias
3166 { n_aliases += 1;
3167 writeln!(out, "{}let arg{} = self.stack.pop().unwrap();", indent, i+1)?;
3168 }
3169 else
3170 { writeln!(out, "{}self.stack.pop();", indent)?;
3171 }
3172 indent = next_indent;
3173 }
3174 if n_aliases > 0
3175 { write!(out, "{}{}match {}", indent, if rule.lhs_start {"let result = "} else {""}, if n_aliases>1 {"("} else {""})?;
3176 let mut comma = "";
3177 for i in 0 .. n_args
3178 { if !rule.rhs[i].alias.is_empty()
3179 { write!(out, "{}arg{}.minor", comma, i+1)?;
3180 comma = ", ";
3181 }
3182 }
3183 write!(out, "{}\n{}{{\t{}", if n_aliases>1 {")"} else {""}, indent, if n_aliases>1 {"("} else {""})?;
3184 comma = "";
3185 for (i, rhs) in rule.rhs.iter().enumerate()
3186 { if !rhs.alias.is_empty()
3187 { write!(out, "{}MinorType::Symbol{}(arg{})", comma, self.symbols.array[rhs.index].dtnum, i+1)?;
3188 comma = ", ";
3189 }
3190 }
3191 write!(out, "{} => super::rules::do_rule_{}(&mut self.extra", if n_aliases>1 {")"} else {""}, rule.index)?;
3192 for i in 0 .. n_args
3193 { if !rule.rhs[i].alias.is_empty()
3194 { write!(out, ", arg{}", i+1)?;
3195 }
3196 }
3197 if rule.lhs_start
3198 { writeln!(out, "),\n{}\t_ => unreachable!()\n{}}};\n\t\t\t\tself.result = Some(result);\n\t\t\t\tMinorType::None\n\t\t\t}},", indent, indent)?;
3199 }
3200 else if has_data_type
3201 { writeln!(out, "),\n{}\t_ => unreachable!()\n{}}}\n\t\t\t\t}}\n\t\t\t),", indent, indent)?;
3202 }
3203 else
3204 { writeln!(out, "),\n{}\t_ => unreachable!()\n{}}};\n\t\t\t\tMinorType::None\n\t\t\t}},", indent, indent)?;
3205 }
3206 }
3207 else
3208 { if rule.lhs_start
3209 { writeln!(out, "{}self.result = Some(super::rules::do_rule_{}(&mut self.extra));\n\t\t\t\tMinorType::None\n\t\t\t}},", indent, rule.index)?;
3210 }
3211 else if has_data_type
3212 { writeln!(out, "{}super::rules::do_rule_{}(&mut self.extra)\n\t\t\t}}),", indent, rule.index)?;
3213 }
3214 else
3215 { writeln!(out, "{}super::rules::do_rule_{}(&mut self.extra);\n\t\t\t\tMinorType::None\n\t\t\t}},", indent, rule.index)?;
3216 }
3217 }
3218 }
3219 }
3220 writeln!(out, "\t\t\t_ =>\n\t\t\t{{\tself.stack.pop(); MinorType::None\n\t\t\t}}")?;
3222
3223 lempar_reader.copy_part(out)?; writeln!(out, "\n}}\n\n\nmod rules\n{{\tuse super::code::{{TokenValue, ExtraArgumentType}};")?;
3227 for rule in self.rules.iter()
3228 { let rule = rule;
3229 if !rule.code.is_empty()
3230 { write!(out, "\n\t/// {}\n", rule)?;
3231 write!(out, "\t#[inline]\n\t#[allow(non_snake_case, unused_variables)]\n")?;
3232 write!(out, "\tpub fn do_rule_{}(extra: &mut ExtraArgumentType", rule.index)?;
3233 for rhs in &rule.rhs
3234 { if !rhs.alias.is_empty()
3235 { let data_type = if rhs.index < self.n_terminals
3236 { "TokenValue"
3237 }
3238 else
3239 { &self.symbols.array[rhs.index].data_type
3240 };
3241 write!(out, ", {}: {}", rhs.alias, if data_type.is_empty() {"()"} else {data_type})?;
3242 }
3243 }
3244 write!(out, ")")?;
3245 let lhs = &self.symbols.array[rule.lhs_index];
3246 if !lhs.data_type.is_empty()
3247 { write!(out, " -> {}", lhs.data_type)?;
3248 }
3249 write!(out, "\n\t{{\t")?;
3250 let mut it = rule.code.chars();
3251'l: while let Some(mut c) = it.next()
3252 { 'm:while c == '\n'
3253 { write!(out, "\n\t\t")?;
3254 while let Some(c2) = it.next()
3255 { if c2=='\n' || !c2.is_ascii_whitespace()
3256 { c = c2;
3257 continue 'm;
3258 }
3259 }
3260 break 'l;
3261 }
3262 write!(out, "{}", c)?;
3263 }
3264 writeln!(out, "\n\t}}")?;
3265 }
3266 }
3267 writeln!(out, "}}\n")?;
3268
3269 lempar_reader.copy_part(out)?;
3271 if !self.extracode.is_empty()
3272 { writeln!(out, "\n\n{}", self.extracode)?;
3273 }
3274
3275 Ok(())
3276 }
3277
3278 pub fn gen_log<W>(&self, out: &mut W, basisflag: bool, show_precedence_conflict: bool) -> io::Result<()> where W: io::Write
3285 { for stp in self.states.array[0 .. self.states.n_no_tail].iter()
3286 { writeln!(out, "State {}:", stp.n_state)?;
3287
3288 for cfp in stp.configurations.iter()
3289 { if basisflag
3290 { let mut is_basis = false;
3291 for bp in stp.basis.iter()
3292 { if *cfp.borrow() == *bp.borrow()
3293 { is_basis = true;
3294 break;
3295 }
3296 }
3297 if !is_basis
3298 { continue;
3299 }
3300 }
3301 if cfp.borrow().dot == self.rules[cfp.borrow().n_rule].rhs.len()
3302 { let buf = format!("({})", self.rules[cfp.borrow().n_rule].index);
3303 write!(out, " {:>5} ", buf)?;
3304 }
3305 else
3306 { write!(out, " ")?;
3307 }
3308 Self::config_print(&self.rules, out, cfp)?;
3309 writeln!(out, "")?;
3310 }
3311
3312 writeln!(out, "")?;
3313 for action in stp.actions.iter()
3314 { if Self::print_action(&self.symbols, &self.rules, action, out, 30, show_precedence_conflict)?
3315 { writeln!(out, "")?;
3316 }
3317 }
3318 writeln!(out, "")?;
3319 }
3320 writeln!(out, "----------------------------------------------------")?;
3321 writeln!(out, "Symbols:")?;
3322 for i in 0 .. self.symbols.n_symbols
3323 { let sp = &self.symbols.array[i];
3324 write!(out, " {:>3}: {}", i, sp.name)?;
3325 if sp.typ == SymbolType::NONTERMINAL
3326 { write!(out, ":")?;
3327 if sp.lambda
3328 { write!(out, " <lambda>")?;
3329 }
3330 for j in 0 .. self.symbols.n_terminals
3331 { if sp.firstset.len()>0 && sp.firstset.contains(j)
3332 { write!(out, " {}", self.symbols.array[j].name)?;
3333 }
3334 }
3335 }
3336 writeln!(out, "")?;
3337 }
3338 Ok(())
3339 }
3340
3341 fn config_print<W>(rules: &Vec<Rule>, out: &mut W, cfp: &Rc<RefCell<Config>>) -> io::Result<()> where W: io::Write
3342 { write!(out, "{} ::=", rules[cfp.borrow().n_rule].lhs)?;
3343 for i in 0 ..= rules[cfp.borrow().n_rule].rhs.len()
3344 { if i == cfp.borrow().dot
3345 { write!(out, " *")?;
3346 }
3347 if i == rules[cfp.borrow().n_rule].rhs.len()
3348 { break;
3349 }
3350 write!(out, " {}", rules[cfp.borrow().n_rule].rhs[i].name)?;
3351 }
3352 Ok(())
3353 }
3354
3355 fn print_action<W>(symbols: &Symbols, rules: &[Rule], action: &Rc<RefCell<Action>>, out: &mut W, indent: usize, show_precedence_conflict: bool) -> io::Result<bool> where W: io::Write
3357 { let mut result = false;
3358 match action.borrow().typ
3359 { ActionType::Shift =>
3360 { if let StateOrRule::State(n_state) = action.borrow().x
3361 { write!(out, "{:>w$} shift {:<7}", symbols.array[action.borrow().symbol_index].name, n_state, w=indent)?;
3362 result = true;
3363 }
3364 }
3365 ActionType::Reduce =>
3366 { if let StateOrRule::Rule(n_rule) = action.borrow().x
3367 { write!(out, "{:>w$} reduce {:<7}", symbols.array[action.borrow().symbol_index].name, rules[n_rule].index, w=indent)?;
3368 Self::rule_print(out, &rules[n_rule], std::usize::MAX)?;
3369 result = true;
3370 }
3371 }
3372 ActionType::ShiftReduce =>
3373 { if let StateOrRule::Rule(n_rule) = action.borrow().x
3374 { write!(out, "{:>w$} shift-reduce {:<7}", symbols.array[action.borrow().symbol_index].name, rules[n_rule].index, w=indent)?;
3375 Self::rule_print(out, &rules[n_rule], std::usize::MAX)?;
3376 result = true;
3377 }
3378 }
3379 ActionType::Accept =>
3380 { write!(out, "{:>w$} accept", symbols.array[action.borrow().symbol_index].name, w=indent)?;
3381 result = true;
3382 }
3383 ActionType::Error =>
3384 { write!(out, "{:>w$} error", symbols.array[action.borrow().symbol_index].name, w=indent)?;
3385 result = true;
3386 }
3387 ActionType::SrConflict | ActionType::RrConflict =>
3388 { if let StateOrRule::Rule(n_rule) = action.borrow().x
3389 { write!(out, "{:>w$} reduce {:<7} ** Parsing conflict **", symbols.array[action.borrow().symbol_index].name, rules[n_rule].index, w=indent)?;
3390 result = true;
3391 }
3392 }
3393 ActionType::SsConflict =>
3394 { if let StateOrRule::State(n_state) = action.borrow().x
3395 { write!(out, "{:>w$} shift {:<7} ** Parsing conflict **", symbols.array[action.borrow().symbol_index].name, n_state, w=indent)?;
3396 result = true;
3397 }
3398 }
3399 ActionType::ShResolved =>
3400 { if show_precedence_conflict
3401 { if let StateOrRule::State(n_state) = action.borrow().x
3402 { write!(out, "{:>w$} shift {:<7} -- dropped by precedence", symbols.array[action.borrow().symbol_index].name, n_state, w=indent)?;
3403 result = true;
3404 }
3405 }
3406 }
3407 ActionType::RdResolved =>
3408 { if show_precedence_conflict
3409 { if let StateOrRule::Rule(n_rule) = action.borrow().x
3410 { write!(out, "{:>w$} reduce {:<7} -- dropped by precedence", symbols.array[action.borrow().symbol_index].name, rules[n_rule].index, w=indent)?;
3411 result = true;
3412 }
3413 }
3414 }
3415 ActionType::NotUsed => {}
3416 }
3417 Ok(result)
3418 }
3419
3420 fn rule_print<W>(out: &mut W, rule: &Rule, cursor: usize) -> io::Result<()> where W: io::Write
3422 { write!(out, "{} ::=", rule.lhs)?;
3423 for (i, symbol) in rule.rhs.iter().enumerate()
3424 { if i == cursor
3425 { write!(out, " *")?;
3426 }
3427 write!(out, " {}", symbol.name)?;
3428 }
3429 if cursor == rule.rhs.len()
3430 { write!(out, " *")?;
3431 }
3432 Ok(())
3433 }
3434
3435 pub fn gen_y<W>(&self, out: &mut W) -> io::Result<()> where W: io::Write
3439 { writeln!(out, "// Symbols:")?;
3440 let mut maxlen = 10;
3441 for sp in self.symbols.array[0 .. self.symbols.n_symbols].iter()
3442 { if sp.name.len() > maxlen
3443 { maxlen = sp.name.len();
3444 }
3445 }
3446 let mut ncolumns = 76 / (maxlen+5);
3447 if ncolumns < 1
3448 { ncolumns = 1;
3449 }
3450 let skip = (self.symbols.n_symbols+ncolumns-1) / ncolumns;
3451 for i in 0 .. skip
3452 { write!(out, "//")?;
3453 for j in (i .. self.symbols.n_symbols).step_by(skip)
3454 { let sp = &self.symbols.array[j];
3455 assert_eq!(sp.index, j);
3456 write!(out, " {:3} {:<w$}", maxlen, sp.name, w=maxlen)?;
3457 }
3458 writeln!(out, "")?;
3459 }
3460 writeln!(out, "")?;
3461 if !self.start_name.is_empty()
3463 { writeln!(out, "%start_symbol {{{}}}", self.start_name)?;
3464 }
3465 if !self.token_type.is_empty()
3467 { writeln!(out, "%token_type {{{}}}", self.token_type)?;
3468 }
3469 if !self.vartype.is_empty()
3471 { writeln!(out, "%default_type {{{}}}", self.vartype)?;
3472 }
3473 if !self.extra_argument_type.is_empty()
3475 { writeln!(out, "%extra_argument {{{}}}", self.extra_argument_type)?;
3476 }
3477 let mut prec = 0;
3479 loop
3480 { let mut has_greater_prec = false;
3481 let mut started = false;
3482 for symbol in self.symbols.array[1 .. self.symbols.n_terminals].iter()
3483 { if symbol.prec >= prec
3484 { if symbol.prec > prec
3485 { has_greater_prec = true;
3486 }
3487 else
3488 { if !started
3489 { write!(out, "{}", if symbol.assoc== Associativity::LEFT {"%left"} else if symbol.assoc== Associativity::RIGHT {"%right"} else {"%nonassoc"})?;
3490 started = true;
3491 }
3492 write!(out, " {}", symbol.name)?;
3493 }
3494 }
3495 }
3496 if started
3497 { writeln!(out, ".")?;
3498 }
3499 if !has_greater_prec
3500 { break;
3501 }
3502 prec += 1;
3503 }
3504 for symbol in self.symbols.array[self.symbols.n_terminals+1 .. self.symbols.n_symbols].iter()
3506 { let symbol = symbol;
3507 writeln!(out, "%type {} {{{}}}", symbol.name, symbol.data_type)?;
3508 }
3509 for rule in self.rules.iter()
3511 { write!(out, "{}", rule.lhs)?;
3512 if self.symbols.array[rule.lhs_index].dtnum != 0
3513 { write!(out, "(RESULT)")?;
3514 }
3515 write!(out, " ::=")?;
3516 for sp in &rule.rhs
3517 { write!(out, " {}", sp.name)?;
3518 if !sp.alias.is_empty()
3519 { write!(out, "({})", sp.alias)?;
3520 }
3521 }
3522 write!(out, ".")?;
3523 if rule.precsym_index != std::usize::MAX
3524 { write!(out, " [{}]", self.symbols.array[rule.precsym_index].name)?;
3525 }
3526 if !rule.code.is_empty()
3527 { writeln!(out, " {{\n{}\n}}", rule.code)?;
3528 }
3529 writeln!(out, "")?;
3530 }
3531 Ok(())
3532 }
3533}
3534impl TryFrom<LemonMintBuilder> for LemonMint
3535{ type Error = LemonMintError;
3536
3537 fn try_from(builder: LemonMintBuilder) -> ParserResult<Self>
3538 { builder.try_into_lemon()
3539 }
3540}
3541
3542#[cfg(not(feature = "with-debug"))]
3543fn dump_symbols(_symbols: &Symbols, _rules: &Vec<Rule>)
3544{
3545}
3546
3547#[cfg(not(feature = "with-debug"))]
3548fn dump_states(_states: &States, _rules: &Vec<Rule>, _symbols: &Symbols, _n: i32)
3549{
3550}
3551
3552#[cfg(feature = "with-debug")]
3553fn dump_symbols(symbols: &Symbols, rules: &Vec<Rule>)
3554{ use std::io::prelude::*;
3555 let mut out = File::create("/tmp/symbols-rust.js").unwrap();
3556 for s in symbols.array.iter()
3557 { writeln!(out, "{} ({}) {:?} #{} {:?} {} {}LAM:", s.name, s.index, s.typ, s.dtnum, s.assoc, s.prec, if s.lambda {""} else {"!"}).unwrap();
3558 if s.firstset.len() > 0
3559 { write!(out, " ").unwrap();
3560 for (j, v) in s.firstset.data.iter().enumerate()
3561 { write!(out, "{}{}", if j%4==0&&j>0 {" "} else {""}, if *v {'y'} else {'n'}).unwrap();
3562 }
3563 writeln!(out).unwrap();
3564 }
3565 for n_rule in s.sym_rules_arr.iter()
3566 { let rule = &rules[*n_rule];
3567 writeln!(out, " {} = {}", rule.index, rule.code).unwrap();
3568 }
3569 }
3570 }
3597
3598#[cfg(feature = "with-debug")]
3599fn dump_states(states: &States, rules: &Vec<Rule>, symbols: &Symbols, n: i32)
3600{ use std::io::prelude::*;
3601 let mut out = File::create(format!("/tmp/states-{}-rust.js", n)).unwrap();
3602 for s in states.array.iter()
3603 { writeln!
3604 ( out,
3605 "{}. nTknAct={}, nNtAct={}, iTknOfst={}, iNtOfst={}, iDfltReduce={}, {} dfR{}[{}]",
3606 s.n_state,
3607 s.n_token_act,
3608 s.n_nt_act,
3609 if s.token_offset==std::isize::MIN {-1000} else {s.token_offset},
3610 if s.nt_offset==std::isize::MIN {-1000} else {s.nt_offset},
3611 if s.default_reduce_action==std::usize::MAX {-1} else {s.default_reduce_action as isize},
3612 if s.auto_reduce {"A"} else {"!A"},
3613 if s.default_reduce_rule==std::usize::MAX {-1} else {s.default_reduce_rule as isize},
3614 if s.default_reduce_rule==std::usize::MAX {"".to_string()} else {rules[s.default_reduce_rule].lhs.to_string()}
3615 ).unwrap();
3616 for cfp in s.basis.iter()
3617 { let cfp = cfp.borrow();
3618 writeln!(out, " bs{} R{}[{}] .{}", cfp.n_state as isize, cfp.n_rule, rules[cfp.n_rule].lhs, cfp.dot).unwrap();
3619 }
3620 for cfp in s.configurations.iter()
3621 { let cfp = cfp.borrow();
3622 writeln!(out, " cf{} R{}[{}] .{}", cfp.n_state as isize, cfp.n_rule, rules[cfp.n_rule].lhs, cfp.dot).unwrap();
3624 let mut delim = "";
3626 write!(out, "{:<12}[", "").unwrap();
3627 for (j, v) in cfp.fws.data.iter().enumerate()
3628 { if *v
3629 { write!(out, "{}{}", delim, symbols.array[j].name).unwrap();
3630 delim = " ";
3631 }
3632 }
3633 writeln!(out, "]").unwrap();
3634 for cfp in cfp.fplp.iter()
3636 { write!(out, "{:<12}{} (state {:2}) ", "", "To ", cfp.borrow().n_state as isize).unwrap();
3637 LemonMint::config_print(rules, &mut out, cfp).unwrap();
3638 writeln!(out).unwrap();
3639 }
3640 for cfp in cfp.bplp.iter()
3642 { write!(out, "{:<12}{} (state {:2}) ", "", "From", cfp.borrow().n_state as isize).unwrap();
3643 LemonMint::config_print(rules, &mut out, cfp).unwrap();
3644 writeln!(out).unwrap();
3645 }
3646 }
3647 for action in s.actions.iter()
3648 { if LemonMint::print_action(symbols, rules, action, &mut out, 30, true).unwrap()
3649 { writeln!(out).unwrap();
3650 }
3651 }
3652 }
3653 }