1mod lempar;
113
114use lempar::LemparReader;
115
116use std::mem;
117use std::cmp;
118use std::cmp::Ordering;
119use std::collections::HashMap;
120use std::cell::RefCell;
121use std::io::{self, BufRead, BufReader};
122use std::fmt;
123use std::hash::{Hash, Hasher};
124use std::collections::hash_map::DefaultHasher;
125use std::error::Error;
126use std::iter::Take;
127use std::slice::Iter;
128use std::convert::TryFrom;
129use std::rc::Rc;
130use std::sync::Arc;
131use std::fs::File;
132use std::borrow::Cow;
133
134fn typename_to_string(value: String) -> String
135{ let value_trimmed = value.trim();
136 if value_trimmed.is_empty() || value.starts_with('(') && value.ends_with(')') && value[1 .. value.len()-1].trim().is_empty()
137 { String::new()
138 }
139 else
140 { if value.len() == value_trimmed.len() {value} else {value_trimmed.to_string()}
141 }
142}
143
144fn is_terminal_name(s: &str) -> bool
145{ s.find(|c: char| c.is_ascii_lowercase()).is_none()
146}
147
148#[derive(Debug)]
149pub struct LemonMintError
150{ pub filename: Arc<String>,
151 pub n_line: usize,
152 pub message: String,
153}
154impl LemonMintError
155{ pub fn new(filename: &Arc<String>, n_line: usize, message: String) -> Self
156 { Self {filename: Arc::clone(filename), n_line, message}
157 }
158}
159impl fmt::Display for LemonMintError
160{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
161 { let message: &str = if self.message.is_empty() {"Unspecified error"} else {&self.message};
162 if self.filename.is_empty()
163 { write!(f, "{}", message)
164 }
165 else
166 { write!(f, "{}({}): {}", self.filename, self.n_line, message)
167 }
168 }
169}
170impl Error for LemonMintError {}
171
172type ParserResult<T> = Result<T, LemonMintError>;
173
174#[derive(Copy, Clone, Eq, PartialEq, Debug)]
175enum Directive
176{ Rule,
177 TokenType,
178 Type,
179 DefaultType,
180 StartSymbol,
181 Trace,
182 ExtraArgument,
183 Left,
184 Right,
185 Nonassoc,
186 Fallback,
187 Code,
188}
189
190#[derive(Copy, Clone, Eq, PartialEq, Debug)]
191enum SymbolType
192{ TERMINAL,
193 NONTERMINAL
194}
195
196#[derive(Copy, Clone, Eq, PartialEq, Debug)]
197enum Associativity
198{ LEFT,
199 RIGHT,
200 NONASSOC,
201 UNKNOWN
202}
203
204#[derive(Debug)]
205struct Set
206{ data: Vec<bool>,
207}
208impl Set
209{ pub fn new(size: usize) -> Self
210 { let mut this = Self {data: Vec::new()};
211 if size > 0
212 { this.set_size(size);
213 }
214 this
215 }
216
217 pub fn len(&self) -> usize
218 { self.data.len()
219 }
220
221 pub fn set_size(&mut self, size: usize)
222 { self.data.clear();
223 self.data.resize(size, false);
224 }
225
226 pub fn contains(&self, element: usize) -> bool
227 { *self.data.get(element).unwrap_or(&false)
228 }
229
230 pub fn add(&mut self, element: usize) -> bool
231 { let rv = self.contains(element);
232 if let Some(v) = self.data.get_mut(element)
233 { *v = true;
234 }
235 !rv
236 }
237
238 pub fn intersect(&mut self, other: &Set) -> bool
239 { let mut changed = false;
240 for (i, v) in &mut self.data.iter_mut().enumerate()
241 { if !*v && other.contains(i)
242 { changed = true;
243 *v = true;
244 }
245 }
246 return changed;
247 }
248}
249
250#[derive(Debug)]
252struct Symbol
253{ 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, }
265impl Symbol
266{ fn new(name: &str, index: usize) -> Self
267 { let typ = if is_terminal_name(name) || name=="$" {SymbolType::TERMINAL} else {SymbolType::NONTERMINAL};
268 Self
269 { name: Arc::new(String::new()),
270 index,
271 typ,
272 sym_rules_arr: Vec::new(),
273 fallback_index: std::usize::MAX,
274 prec: -1,
275 assoc: Associativity::UNKNOWN,
276 firstset: Set::new(0),
277 lambda: false,
278 data_type: String::new(),
279 dtnum: 0,
280 }
281 }
282}
283impl PartialEq for Symbol
284{ fn eq(&self, other: &Self) -> bool
285 { self.index == other.index
286 }
287}
288
289#[derive(Debug)]
290struct Rhs
291{ name: Arc<String>,
292 index: usize,
293 alias: String,
294}
295
296#[derive(Debug)]
298struct Rule
299{ rule_filename: Arc<String>,
300 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, }
311impl Rule
312{ fn new(rule_filename: &Arc<String>, rule_n_line: usize, lhs: &Arc<String>, lhs_index: usize, index: usize, code: String) -> Self
313 { Self
314 { rule_filename: Arc::clone(rule_filename),
315 rule_n_line,
316 lhs: Arc::clone(lhs),
317 lhs_index,
318 lhs_start: false,
319 rhs: Vec::new(),
320 code,
321 precsym_index: std::usize::MAX,
322 index,
323 can_reduce: false,
324 does_reduce: false,
325 }
326 }
327}
328impl fmt::Display for Rule
329{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
331 { write!(f, "{} ::=", self.lhs)?;
332 for sp in &self.rhs
333 { write!(f, " {}", sp.name)?;
334 }
335 Ok(())
336 }
337}
338
339#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
340struct ConfigKey
341{ n_rule: usize,
342 dot: usize,
343}
344impl ConfigKey
345{ fn new(config: &Config) -> Self
346 { Self
347 { n_rule: config.n_rule,
348 dot: config.dot,
349 }
350 }
351}
352impl cmp::Ord for ConfigKey
353{ fn cmp(&self, other: &Self) -> cmp::Ordering
354 { let mut res = self.n_rule.cmp(&other.n_rule);
355 if res == Ordering::Equal
356 { res = self.dot.cmp(&other.dot);
357 }
358 res
359 }
360}
361impl cmp::PartialOrd for ConfigKey
362{ fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering>
363 { Some(self.cmp(other))
364 }
365}
366
367#[derive(Debug)]
373struct Config
374{ n_rule: usize, dot: usize, fws: Set, fplp: Vec<Rc<RefCell<Config>>>, bplp: Vec<Rc<RefCell<Config>>>, n_state: usize, status_is_complete: bool, }
382impl Config
383{ pub fn new(n_rule: usize, dot: usize, fws_size: usize) -> Self
384 { Self
385 { n_rule,
386 dot,
387 fws: Set::new(fws_size),
388 fplp: Vec::new(),
389 bplp: Vec::new(),
390 n_state: std::usize::MAX,
391 status_is_complete: false,
392 }
393 }
394}
395impl cmp::Ord for Config
396{ fn cmp(&self, other: &Self) -> cmp::Ordering
397 { ConfigKey::new(self).cmp(&ConfigKey::new(other))
398 }
399}
400impl cmp::PartialOrd for Config
401{ fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering>
402 { Some(self.cmp(other))
403 }
404}
405impl cmp::PartialEq for Config
406{ fn eq(&self, other: &Self) -> bool
407 { ConfigKey::new(self).eq(&ConfigKey::new(other))
408 }
409}
410impl Eq for Config {}
411
412#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
413enum ActionType
414{ Shift,
415 Accept,
416 Reduce,
417 Error,
418 SsConflict, SrConflict, RrConflict, ShResolved, RdResolved, NotUsed, ShiftReduce }
426
427#[derive(Debug, PartialEq, Copy, Clone)]
428enum StateOrRule
429{ State(usize), Rule(usize), EmptyRule }
433
434#[derive(Debug)]
436struct Action
437{ id: i32,
438 symbol_index: usize, typ: ActionType,
440 x: StateOrRule,
441 symbol_index_opt: usize, }
443impl Action
444{ fn new_state(id: i32, symbol_index: usize, n_state: usize) -> Action
445 { Action
446 { id,
447 symbol_index,
448 typ: ActionType::Shift,
449 x: StateOrRule::State(n_state),
450 symbol_index_opt: std::usize::MAX,
451 }
452 }
453
454 fn new_rule(id: i32, symbol_index: usize, typ: ActionType, n_rule: usize) -> Action
455 { Action
456 { id,
457 symbol_index,
458 typ,
459 x: StateOrRule::Rule(n_rule),
460 symbol_index_opt: std::usize::MAX,
461 }
462 }
463
464 fn new_empty_rule(id: i32, symbol_index: usize, typ: ActionType) -> Action
465 { Action
466 { id,
467 symbol_index,
468 typ,
469 x: StateOrRule::EmptyRule,
470 symbol_index_opt: std::usize::MAX,
471 }
472 }
473}
474impl cmp::Ord for Action
475{ fn cmp(&self, other: &Self) -> cmp::Ordering
476 { let index = self.symbol_index;
477 let other_index = other.symbol_index;
478 let mut res = index.cmp(&other_index);
479 if res == Ordering::Equal
480 { res = self.typ.cmp(&other.typ);
481 if res == Ordering::Equal
482 { if self.typ==ActionType::Reduce || self.typ==ActionType::ShiftReduce
483 { if let StateOrRule::Rule(n_rule) = self.x
484 { if let StateOrRule::Rule(other_n_rule) = other.x
485 { if n_rule < other_n_rule
486 { return Ordering::Less;
487 }
488 if n_rule > other_n_rule
489 { return Ordering::Greater;
490 }
491 }
492 }
493 }
494 res = self.id.cmp(&other.id);
495 }
496 }
497 res
498 }
499}
500impl cmp::PartialOrd for Action
501{ fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering>
502 { Some(self.cmp(other))
503 }
504}
505impl cmp::PartialEq for Action
506{ fn eq(&self, other: &Self) -> bool
507 { self.cmp(other) == Ordering::Equal
508 }
509}
510impl Eq for Action {}
511
512#[derive(Debug)]
514struct State
515{ basis: Vec<Rc<RefCell<Config>>>, configurations: Vec<Rc<RefCell<Config>>>, n_state: usize, actions: Vec<Rc<RefCell<Action>>>, n_token_act: usize,
520 n_nt_act: usize, token_offset: isize,
522 nt_offset: isize, default_reduce_action: usize, default_reduce_rule: usize, auto_reduce: bool,
526}
527impl State
528{ pub fn new(n_state: usize, basis: Vec<Rc<RefCell<Config>>>, configurations: Vec<Rc<RefCell<Config>>>) -> Self
529 { Self
530 { basis,
531 configurations,
532 n_state,
533 actions: Vec::new(),
534 n_token_act: 0,
535 n_nt_act: 0,
536 token_offset: 0,
537 nt_offset: 0,
538 default_reduce_action: 0,
539 default_reduce_rule: std::usize::MAX,
540 auto_reduce: false,
541 }
542 }
543}
544
545#[derive(Debug)]
550struct AxSet
551{ n_state: usize, is_tkn: bool, n_action: usize, i_order: usize, }
556impl AxSet
557{ fn new(n_state: usize, is_tkn: bool, n_action: usize, i_order: usize) -> Self
558 { Self
559 { n_state,
560 is_tkn,
561 n_action,
562 i_order,
563 }
564 }
565}
566impl cmp::Ord for AxSet
567{ fn cmp(&self, other: &Self) -> cmp::Ordering
568 { let mut res = other.n_action.cmp(&self.n_action); if res == Ordering::Equal
570 { res = self.i_order.cmp(&other.i_order);
571 }
572 res
573 }
574}
575impl cmp::PartialOrd for AxSet
576{ fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering>
577 { Some(self.cmp(other))
578 }
579}
580impl cmp::PartialEq for AxSet
581{ fn eq(&self, other: &Self) -> bool
582 { self.cmp(other) == Ordering::Equal
583 }
584}
585impl Eq for AxSet {}
586
587#[derive(Copy, Clone, Eq, PartialEq, Debug)]
606struct LookaheadAction
607{ lookahead: usize, action: usize, }
610impl LookaheadAction
611{ fn new(lookahead: usize, action: usize) -> Self
612 { Self
613 { lookahead,
614 action,
615 }
616 }
617}
618
619#[derive(Debug)]
620struct ActTab
621{ 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,
632 max_token_offset: isize,
633 min_nt_offset: isize,
634 max_nt_offset: isize,
635
636 n_fallbacks: usize,
637 n_shift_offset: usize,
638 reduce_count: usize,
639}
640impl ActTab
641{ fn new(n_terminals: usize, n_symbols: usize) -> Self
642 { Self
643 { n_action: 0,
644 a_action: Vec::new(),
645 a_lookahead: Vec::new(),
646 min_lookahead: 0,
647 max_lookahead: 0,
648 min_action: 0,
649
650 n_terminals,
651 n_symbols,
652
653 min_token_offset: 0,
654 max_token_offset: 0,
655 min_nt_offset: 0,
656 max_nt_offset: 0,
657
658 n_fallbacks: 0,
659 n_shift_offset: 0,
660 reduce_count: 0,
661 }
662 }
663
664 fn get_n_lookahead(&self) -> usize
665 { self.n_action
666 }
667
668 fn get_n_actions(&self) -> usize
669 { let mut n_action = self.n_action;
670 for rec in self.a_action.iter().take(n_action).rev()
671 { if rec.lookahead == std::usize::MAX
672 { n_action -= 1;
673 }
674 else
675 { break;
676 }
677 }
678 n_action
679 }
680
681 fn iter(&self) -> Take<Iter<'_, LookaheadAction>>
682 { self.a_action.iter().take(self.n_action)
683 }
684
685 fn acttab_action(&mut self, lookahead: usize, action: usize)
688 { if self.a_lookahead.len() == 0
689 { self.max_lookahead = lookahead;
690 self.min_lookahead = lookahead;
691 self.min_action = action;
692 }
693 else
694 { if self.max_lookahead < lookahead
695 { self.max_lookahead = lookahead;
696 }
697 if self.min_lookahead > lookahead
698 { self.min_lookahead = lookahead;
699 self.min_action = action;
700 }
701 }
702 self.a_lookahead.push(LookaheadAction::new(lookahead, action));
703 }
704
705 fn acttab_insert(&mut self, make_it_safe: bool) -> isize
710 { assert!(self.a_lookahead.len() > 0);
711
712 if self.n_action + self.n_symbols + 1 >= self.a_action.len()
715 { self.a_action.resize(self.n_action + self.n_symbols + self.a_action.len() + 21, LookaheadAction::new(std::usize::MAX, std::usize::MAX));
716 }
717
718 let mut found_offset = std::usize::MAX;
723 let end = if make_it_safe {self.min_lookahead} else {0};
724'l: for i in (end .. self.n_action).rev()
725 { if self.a_action[i].lookahead == self.min_lookahead
726 { if self.a_action[i].action == self.min_action
728 { for j in 0..self.a_lookahead.len()
729 { let k = self.a_lookahead[j].lookahead + i - self.min_lookahead;
730 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
731 { continue 'l;
732 }
733 }
734 let mut n = 0;
736 for j in 0..self.n_action
737 { if self.a_action[j].lookahead != std::usize::MAX
738 { if self.a_action[j].lookahead == (j + self.min_lookahead).wrapping_sub(i)
739 { n += 1;
740 }
741 }
742 }
743 if n == self.a_lookahead.len()
744 { found_offset = i; break;
746 }
747 }
748 }
749 }
750
751 if found_offset == std::usize::MAX
753 { found_offset = if make_it_safe {self.min_lookahead} else {0};
756'm: for i in found_offset .. self.a_action.len() - self.max_lookahead
757 { if self.a_action[i].lookahead == std::usize::MAX
758 { for j in 0 .. self.a_lookahead.len()
759 { let k = self.a_lookahead[j].lookahead + i - self.min_lookahead;
760 if k >= self.a_action.len() || self.a_action[k].lookahead != std::usize::MAX
761 { continue 'm;
762 }
763 }
764 for j in 0 .. self.n_action
765 { if self.a_action[j].lookahead == (j + self.min_lookahead).wrapping_sub(i)
766 { continue 'm;
767 }
768 }
769 found_offset = i; break;
771 }
772 }
773 }
774
775 for j in 0 .. self.a_lookahead.len()
777 { let k = self.a_lookahead[j].lookahead - self.min_lookahead + found_offset;
778 self.a_action[k] = self.a_lookahead[j];
779 if k >= self.n_action
780 { self.n_action = k + 1;
781 }
782 }
783 if make_it_safe && found_offset+self.n_terminals >= self.n_action
784 { self.n_action = found_offset+self.n_terminals+1;
785 }
786 self.a_lookahead.clear();
787
788 return found_offset as isize - self.min_lookahead as isize;
790 }
791}
792
793#[derive(Debug)]
794struct SymbolsBuilder
795{ symbols_map: HashMap<Arc<String>, Symbol>,
796 n_terminals: usize,
797 n_nonterminals: usize,
798}
799impl SymbolsBuilder
800{ pub fn new(empty: bool) -> Self
801 { let mut this = Self
802 { symbols_map: HashMap::new(),
803 n_terminals: 0,
804 n_nonterminals: 0,
805 };
806 if !empty
807 { this.add(&Arc::new("$".to_string()));
808 }
809 this
810 }
811
812 pub fn add(&mut self, symbol_name: &Arc<String>) -> usize
814 { if let Some(symbol) = self.symbols_map.get(symbol_name)
815 { symbol.index
816 }
817 else
818 { let index = if is_terminal_name(symbol_name.as_ref()) || symbol_name.as_ref()=="$"
819 { self.n_terminals += 1;
820 self.n_terminals - 1
821 }
822 else
823 { self.n_nonterminals += 1;
824 self.n_nonterminals - 1
825 };
826 let symbol = Symbol::new(symbol_name, index); self.symbols_map.insert(Arc::clone(symbol_name), symbol);
828 index
829 }
830 }
831
832 pub fn get(&self, symbol_name: &Arc<String>) -> &Symbol
833 { &self.symbols_map[symbol_name]
834 }
835
836 pub fn get_mut(&mut self, symbol_name: &Arc<String>) -> &mut Symbol
837 { self.symbols_map.get_mut(symbol_name).unwrap()
838 }
839
840 pub fn into_symbols(mut self, start_name: &String, nonterminal_types: HashMap<String, StringInFile>, precedence: HashMap<String, PrecedenceInFile>, rules: &mut Vec<Rule>) -> ParserResult<Symbols>
841 { for (symbol_name, symbol_type) in nonterminal_types
843 { if let Some(symbol) = self.symbols_map.get_mut(&symbol_name)
844 { symbol.data_type = symbol_type.string;
845 }
846 else
847 { return Err(LemonMintError::new(&symbol_type.filename, symbol_type.n_line, format!("No such nonterminal symbol when defining symbol type: \"{}\"", symbol_name)));
848 }
849 }
850 for (symbol_name, precedence) in precedence
852 { if let Some(symbol) = self.symbols_map.get_mut(&symbol_name)
853 { symbol.prec = precedence.precedence;
854 symbol.assoc = precedence.assoc;
855 }
856 else
857 { return Err(LemonMintError::new(&precedence.filename, precedence.n_line, format!("No such terminal symbol \"{}\" when defining precedence", symbol_name)));
858 }
859 }
860 for rule in rules
862 { rule.lhs_index += self.n_terminals;
863 for rhs in rule.rhs.iter_mut()
864 { if self.symbols_map[&rhs.name].typ == SymbolType::NONTERMINAL
865 { rhs.index += self.n_terminals;
866 }
867 }
868 }
869 let n_symbols = self.symbols_map.len();
871 let default_symbol = self.add(&Arc::new("{default}".to_string()));
872 let default_symbol_index = default_symbol + self.n_terminals;
873 let mut start_symbol_index = std::usize::MAX;
874 let mut error_symbol_index = std::usize::MAX;
875 let mut array = Vec::with_capacity(self.symbols_map.len());
876 for (symbol_name, mut symbol) in self.symbols_map
877 { if symbol.typ == SymbolType::NONTERMINAL
878 { symbol.index += self.n_terminals;
879 if symbol_name.as_ref() == start_name
880 { start_symbol_index = symbol.index;
881 }
882 else if symbol_name.as_ref() == "error"
883 { error_symbol_index = symbol.index;
884 }
885 }
886 else if symbol.index == 0
887 { symbol.typ = SymbolType::NONTERMINAL; }
889 symbol.name = Arc::clone(&symbol_name);
890 array.push(symbol);
891 }
892 array.sort_by(|a, b| a.index.cmp(&b.index));
893 Ok(Symbols {array, n_symbols, n_terminals: self.n_terminals, default_symbol_index, start_symbol_index, error_symbol_index})
894 }
895}
896
897#[derive(Debug)]
898struct Symbols
899{ pub array: Vec<Symbol>, pub n_symbols: usize, pub n_terminals: usize, pub start_symbol_index: usize,
903 pub default_symbol_index: usize,
904 pub error_symbol_index: usize,
905}
906impl Symbols
907{ pub fn get_start_symbol(&self) -> &Symbol
908 { &self.array[self.start_symbol_index]
909 }
910
911 pub fn get_error_symbol(&self) -> Option<&Symbol>
912 { self.array.get(self.error_symbol_index)
913 }
914}
915
916#[derive(Debug)]
917struct States
918{ pub array: Vec<State>,
919 pub n_no_tail: usize, }
921
922#[derive(Debug)]
923struct StatesBuilder;
924impl StatesBuilder
925{ pub fn build(symbols: &Symbols, rules: &mut Vec<Rule>, start: &Symbol, n_terminals: usize, actions_enum: &mut i32) -> ParserResult<States>
927 { let mut configs_basis_keys_arr = Vec::new();
928 let mut configs_basis_arr = Vec::new();
929 let mut configs_arr = Vec::new();
930 let mut configs_map = HashMap::new();
931 let mut states_map = HashMap::new();
932
933 for n_rule in start.sym_rules_arr.iter()
935 { rules[*n_rule].lhs_start = true;
936 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);
937 }
938
939 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)?;
942
943 let mut states = States {array: Vec::with_capacity(states_map.len()), n_no_tail: 0}; for (_, elem) in states_map
945 { states.array.push(Rc::try_unwrap(elem).unwrap().into_inner());
946 }
947 states.array.sort_by(|a, b| a.n_state.cmp(&b.n_state));
948 states.n_no_tail = states.array.len();
949 Ok(states)
950 }
951
952 fn getstate
954 ( symbols: &Symbols,
955 rules: &Vec<Rule>,
956 configs_basis_keys_arr: &mut Vec<ConfigKey>,
957 configs_basis_arr: &mut Vec<Rc<RefCell<Config>>>,
958 configs_arr: &mut Vec<Rc<RefCell<Config>>>,
959 configs_map: &mut HashMap<ConfigKey, Rc<RefCell<Config>>>,
960 states_map: &mut HashMap<Vec<ConfigKey>, Rc<RefCell<State>>>,
961 n_terminals: usize,
962 actions_enum: &mut i32,
963 ) -> ParserResult<usize>
964 { let mut basis_keys = mem::replace(configs_basis_keys_arr, Vec::new());
966 let mut basis = mem::replace(configs_basis_arr, Vec::new());
967 basis_keys.sort();
968 basis.sort();
969
970 if let Some(found) = states_map.get(&basis_keys)
972 { let found = found.borrow();
973 let n_state = found.n_state;
974 for (i, x) in basis.iter().enumerate()
977 { let mut y = found.basis[i].borrow_mut();
978 if let Ok(mut x) = x.try_borrow_mut()
979 { mem::swap(&mut x.bplp, &mut y.bplp);
980 y.bplp.reserve(x.bplp.len());
981 for config in x.bplp.iter()
982 { y.bplp.push(Rc::clone(config));
983 }
984 }
985 else
986 { let len = y.bplp.len();
988 y.bplp.reserve(len);
989 for i in 0 .. len
990 { let o = Rc::clone(&y.bplp[i]);
991 y.bplp.push(o);
992 }
993 }
994 }
995 configs_arr.clear();
996 Ok(n_state)
997 }
998 else
999 { Self::configlist_closure(symbols, rules, configs_basis_keys_arr, configs_basis_arr, configs_arr, configs_map, n_terminals)?; let n_state = states_map.len();
1002 let mut configurations = mem::replace(configs_arr, Vec::new());
1003 configurations.sort(); let stp = State::new ( n_state, basis, configurations );
1009 let stp = Rc::new(RefCell::new(stp));
1010 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;
1013 Ok(n_state)
1014 }
1015 }
1016
1017 fn buildshifts
1019 ( symbols: &Symbols,
1020 rules: &Vec<Rule>,
1021 configs_basis_keys_arr: &mut Vec<ConfigKey>,
1022 configs_basis_arr: &mut Vec<Rc<RefCell<Config>>>,
1023 configs_arr: &mut Vec<Rc<RefCell<Config>>>,
1024 configs_map: &mut HashMap<ConfigKey, Rc<RefCell<Config>>>,
1025 states_map: &mut HashMap<Vec<ConfigKey>, Rc<RefCell<State>>>,
1026 n_terminals: usize,
1027 actions_enum: &mut i32,
1028 stp: &Rc<RefCell<State>>
1029 ) -> ParserResult<Vec<Rc<RefCell<Action>>>>
1030 { let mut actions = Vec::new();
1031
1032 for cfp in stp.borrow().configurations.iter()
1034 { cfp.borrow_mut().status_is_complete = false;
1035 }
1036
1037 for (i, cfp) in stp.borrow().configurations.iter().enumerate()
1039 { let (status_is_complete, dot, n_rule) =
1040 { let cfp = cfp.borrow();
1041 (cfp.status_is_complete, cfp.dot, cfp.n_rule)
1042 };
1043 if !status_is_complete && dot<rules[n_rule].rhs.len() { configs_basis_keys_arr.clear();
1045 configs_basis_arr.clear();
1046 configs_arr.clear();
1047 configs_map.clear();
1048 let sp = rules[n_rule].rhs[dot].index; for bcfp in stp.borrow().configurations.iter().skip(i)
1053 { 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);
1058 newcfg.borrow_mut().bplp.push(Rc::clone(bcfp));
1059 }
1060 }
1061 }
1062
1063 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;
1069 }
1070 }
1071 Ok(actions)
1072 }
1073
1074 fn configlist_add
1077 ( rules: &Vec<Rule>,
1078 configs_basis_keys_arr: &mut Vec<ConfigKey>,
1079 configs_basis_arr: &mut Vec<Rc<RefCell<Config>>>,
1080 configs_arr: &mut Vec<Rc<RefCell<Config>>>,
1081 configs_map: &mut HashMap<ConfigKey, Rc<RefCell<Config>>>,
1082 n_terminals: usize,
1083 n_rule: usize,
1084 dot: usize,
1085 is_basis: bool
1086 ) -> Rc<RefCell<Config>>
1087 { let key = ConfigKey {n_rule: rules[n_rule].index, dot};
1088
1089 if let Some(found) = configs_map.get(&key)
1090 { Rc::clone(found)
1091 }
1092 else
1093 { let cfp = Rc::new(RefCell::new(Config::new(n_rule, dot, n_terminals+1)));
1094 configs_arr.push(Rc::clone(&cfp));
1095 let key = ConfigKey::new(&cfp.borrow());
1096 if is_basis
1097 { configs_basis_keys_arr.push(key);
1098 configs_basis_arr.push(Rc::clone(&cfp));
1099 }
1100 configs_map.insert(key, Rc::clone(&cfp));
1101 cfp
1102 }
1103 }
1104
1105 fn configlist_closure
1107 ( symbols: &Symbols,
1108 rules: &Vec<Rule>,
1109 configs_basis_keys_arr: &mut Vec<ConfigKey>,
1110 configs_basis_arr: &mut Vec<Rc<RefCell<Config>>>,
1111 configs_arr: &mut Vec<Rc<RefCell<Config>>>,
1112 configs_map: &mut HashMap<ConfigKey, Rc<RefCell<Config>>>,
1113 n_terminals: usize
1114 ) -> ParserResult<()>
1115 { let mut c = 0;
1116 while c < configs_arr.len() { let (rule, dot) =
1118 { let config = configs_arr[c].borrow();
1119 (&rules[config.n_rule], config.dot)
1120 };
1121 if dot < rule.rhs.len()
1122 { let sp = &symbols.array[rule.rhs[dot].index];
1123 if sp.typ == SymbolType::NONTERMINAL
1124 { if sp.index!=symbols.error_symbol_index && sp.sym_rules_arr.is_empty()
1125 { return Err(LemonMintError::new(&rule.rule_filename, rule.rule_n_line, format!("Nonterminal \"{}\" has no rules.", sp.name)));
1126 }
1127 for new_n_rule in sp.sym_rules_arr.iter()
1128 { let newcfp = Self::configlist_add(rules, configs_basis_keys_arr, configs_basis_arr, configs_arr, configs_map, n_terminals, *new_n_rule, 0, false);
1129 let mut found = false;
1130 for i in dot+1 .. rule.rhs.len()
1131 { let xsp = &symbols.array[rule.rhs[i].index];
1132 if xsp.typ == SymbolType::TERMINAL
1133 { newcfp.borrow_mut().fws.add(xsp.index);
1134 found = true;
1135 break;
1136 }
1137 newcfp.borrow_mut().fws.intersect(&xsp.firstset);
1138 if !xsp.lambda
1139 { found = true;
1140 break;
1141 }
1142 }
1143 if !found
1144 { configs_arr[c].borrow_mut().fplp.insert(0, newcfp); }
1146 }
1147 }
1148 }
1149 c += 1;
1150 }
1151 Ok(())
1152 }
1153}
1154
1155#[derive(Debug)]
1156struct StringInFile
1157{ filename: Arc<String>,
1158 n_line: usize,
1159 string: String,
1160}
1161
1162#[derive(Debug)]
1163struct PrecedenceInFile
1164{ filename: Arc<String>,
1165 n_line: usize,
1166 assoc: Associativity,
1167 precedence: i32,
1168}
1169
1170struct ArrayFormatter
1171{ i: usize,
1172 values_on_line: usize,
1173 endl: &'static str,
1174}
1175impl ArrayFormatter
1176{ pub fn new(values_on_line: usize) -> Self
1177 { Self
1178 { i: 0,
1179 values_on_line,
1180 endl: "\n[\t",
1181 }
1182 }
1183
1184 pub fn separ<W>(&mut self, out: &mut W) -> io::Result<()> where W: io::Write
1185 { if self.i % self.values_on_line == 0
1186 { write!(out, "{}/* {:5} */ ", self.endl, self.i)?;
1187 self.endl = ",\n\t";
1188 }
1189 else
1190 { write!(out, ", ")?;
1191 }
1192 self.i += 1;
1193 Ok(())
1194 }
1195
1196 pub fn end<W>(self, out: &mut W) -> io::Result<()> where W: io::Write
1197 { writeln!(out, "{}];", if self.i==0 {" ["} else {"\n"})
1198 }
1199}
1200
1201#[derive(Debug)]
1228pub struct LemonMintBuilder
1229{ rules: Vec<Rule>, token_type: String, vartype: String, start_name: String, with_trace: bool,
1234 trace_prompt: String, extracode: String, n_conflicts: usize, n_action_table_entries: usize, tables_size: usize, has_fallback: bool, symbols_builder: SymbolsBuilder,
1241 prec_counter: i32,
1242 actions_enum: i32,
1243 nonterminal_types: HashMap<String, StringInFile>,
1244 precedence: HashMap<String, PrecedenceInFile>,
1245 extra_argument_type: String,
1246 min_shift_reduce: usize,
1247 error_action: usize,
1248 accept_action: usize,
1249 no_action: usize,
1250 min_reduce: usize,
1251 max_action: usize,
1252 no_compress: bool, no_resort: bool, }
1255impl LemonMintBuilder
1256{ pub fn new() -> Self
1258 { Self
1259 { rules: Vec::with_capacity(64),
1260 token_type: String::new(),
1261 vartype: String::new(),
1262 start_name: String::new(),
1263 with_trace: false,
1264 trace_prompt: String::new(),
1265 extracode: String::new(),
1266 n_conflicts: 0,
1267 n_action_table_entries: 0,
1268 tables_size: 0,
1269 has_fallback: false,
1270 symbols_builder: SymbolsBuilder::new(false),
1271 prec_counter: 1,
1272 actions_enum: 0,
1273 nonterminal_types: HashMap::new(),
1274 precedence: HashMap::new(),
1275 extra_argument_type: String::new(),
1276 min_shift_reduce: 0,
1277 error_action: 0,
1278 accept_action: 0,
1279 no_action: 0,
1280 min_reduce: 0,
1281 max_action: 0,
1282 no_compress: false,
1283 no_resort: false,
1284 }
1285 }
1286
1287 fn find_rule_precedences(symbols: &mut Symbols, rules: &mut Vec<Rule>)
1293 { for rule in rules.iter_mut()
1294 { if rule.precsym_index == std::usize::MAX
1295 { for sp in &rule.rhs
1296 { if symbols.array[sp.index].prec >= 0
1297 { rule.precsym_index = sp.index;
1298 break;
1299 }
1300 }
1301 }
1302 }
1303 }
1304
1305 fn find_first_sets(&self, symbols: &mut Symbols, rules: &mut Vec<Rule>)
1308 { for (i, symbol) in symbols.array[0 .. symbols.n_symbols].iter_mut().enumerate()
1309 { symbol.lambda = false;
1310 if i >= symbols.n_terminals
1311 { symbol.firstset.set_size(symbols.n_terminals + 1);
1312 }
1313 }
1314
1315 let mut progress = true;
1317 while progress
1318 { progress = false;
1319'l: for rule in rules.iter()
1320 { let rule = rule;
1321 if !symbols.array[rule.lhs_index].lambda
1322 { for sp in &rule.rhs
1323 { let sp = &symbols.array[sp.index];
1324 assert!(sp.typ==SymbolType::NONTERMINAL || !sp.lambda);
1325 if !sp.lambda
1326 { continue 'l;
1327 }
1328 }
1329 symbols.array[rule.lhs_index].lambda = true;
1330 progress = true;
1331 }
1332 }
1333 }
1334
1335 progress = true;
1337 while progress
1338 { progress = false;
1339 for rule in rules.iter()
1340 { for rhs in &rule.rhs
1341 { if symbols.array[rhs.index].typ == SymbolType::TERMINAL
1342 { if symbols.array[rule.lhs_index].firstset.add(rhs.index)
1343 { progress = true;
1344 }
1345 break;
1346 }
1347 else if rule.lhs_index == rhs.index
1348 { if !symbols.array[rule.lhs_index].lambda
1349 { break;
1350 }
1351 }
1352 else
1353 { let set = mem::replace(&mut symbols.array[rhs.index].firstset, Set::new(0));
1354 if symbols.array[rule.lhs_index].firstset.intersect(&set)
1355 { progress = true;
1356 }
1357 symbols.array[rhs.index].firstset = set;
1358 if !symbols.array[rhs.index].lambda
1359 { break;
1360 }
1361 }
1362 }
1363 }
1364 }
1365 }
1366
1367 fn find_links(states: &States)
1369 { for stp in states.array.iter()
1372 { for cfp in stp.configurations.iter()
1373 { cfp.borrow_mut().n_state = stp.n_state;
1374 }
1375 }
1376
1377 for stp in states.array.iter()
1380 { for cfp in stp.configurations.iter()
1381 { for plp in cfp.borrow().bplp.iter()
1382 { plp.borrow_mut().fplp.insert(0, Rc::clone(&cfp)); }
1384 }
1385 }
1386 }
1387
1388 fn find_follow_sets(states: &States)
1392 { for stp in states.array.iter()
1393 { for cfp in stp.configurations.iter()
1394 { cfp.borrow_mut().status_is_complete = false;
1395 }
1396 }
1397
1398 let mut progress = true;
1399 while progress
1400 { progress = false;
1401 for stp in states.array.iter()
1402 { for cfp in stp.configurations.iter()
1403 { if !cfp.borrow().status_is_complete
1404 { for plp in cfp.borrow().fplp.iter()
1405 { let mut plp = plp.borrow_mut();
1406 if plp.fws.intersect(&cfp.borrow().fws) { plp.status_is_complete = false;
1408 progress = true;
1409 }
1410 }
1411 cfp.borrow_mut().status_is_complete = true;
1412 }
1413 }
1414 }
1415 }
1416 }
1417
1418 fn resolve_conflict(symbols: &Symbols, rules: &mut Vec<Rule>, apx: &Rc<RefCell<Action>>, apy: &Rc<RefCell<Action>>) -> usize
1427 { let mut errcnt = 0;
1428 let mut apx = apx.borrow_mut();
1429 let mut apy = apy.borrow_mut();
1430 assert_eq!(apx.symbol_index, apy.symbol_index); let mut apx_typ = apx.typ;
1432 let mut apy_typ = apy.typ;
1433 if apx_typ==ActionType::Shift && apy_typ==ActionType::Shift
1434 { apy_typ = ActionType::SsConflict;
1435 errcnt += 1;
1436 }
1437 if apx_typ==ActionType::Shift && apy_typ==ActionType::Reduce
1438 { let spx = &symbols.array[apx.symbol_index];
1439 if let StateOrRule::Rule(n_rule) = apy.x
1440 { let spy = rules[n_rule].precsym_index;
1441 if spy != std::usize::MAX
1442 { let spy = &symbols.array[spy];
1443 if spx.prec<0 || spy.prec<0
1444 { apy_typ = ActionType::SrConflict;
1446 errcnt += 1;
1447 }
1448 else if spx.prec > spy.prec { apy_typ = ActionType::RdResolved;
1450 }
1451 else if spx.prec < spy.prec
1452 { apx_typ = ActionType::ShResolved;
1453 }
1454 else if spx.prec==spy.prec && spx.assoc== Associativity::RIGHT { apy_typ = ActionType::RdResolved; }
1457 else if spx.prec==spy.prec && spx.assoc== Associativity::LEFT { apx_typ = ActionType::ShResolved;
1459 }
1460 else
1461 { assert!(spx.prec==spy.prec && spx.assoc== Associativity::NONASSOC);
1462 apy_typ = ActionType::Error;
1463 }
1464 }
1465 else
1466 { apy_typ = ActionType::SrConflict;
1468 errcnt += 1;
1469 }
1470 }
1471 }
1472 else if apx_typ==ActionType::Reduce && apy_typ==ActionType::Reduce
1473 { if let StateOrRule::Rule(n_rule_x) = apx.x
1474 { if let StateOrRule::Rule(n_rule_y) = apy.x
1475 { let spx = rules[n_rule_x].precsym_index;
1476 let spy = rules[n_rule_y].precsym_index;
1477 if spx != std::usize::MAX
1478 { if spy != std::usize::MAX
1479 { let spx = &symbols.array[spx];
1480 let spy = &symbols.array[spy];
1481 if spx.prec<0 || spy.prec<0 || spx.prec==spy.prec
1482 { apy_typ = ActionType::RrConflict;
1483 errcnt += 1;
1484 }
1485 else if spx.prec > spy.prec
1486 { apy_typ = ActionType::RdResolved;
1487 }
1488 else if spx.prec < spy.prec
1489 { apx_typ = ActionType::RdResolved;
1490 }
1491 }
1492 else
1493 { apy_typ = ActionType::RrConflict;
1494 errcnt += 1;
1495 }
1496 }
1497 else
1498 { apy_typ = ActionType::RrConflict;
1499 errcnt += 1;
1500 }
1501 }
1502 }
1503 }
1504 else
1505 { assert!
1506 ( apx_typ == ActionType::ShResolved ||
1507 apx_typ == ActionType::RdResolved ||
1508 apx_typ == ActionType::SsConflict ||
1509 apx_typ == ActionType::SrConflict ||
1510 apx_typ == ActionType::RrConflict ||
1511 apy_typ == ActionType::ShResolved ||
1512 apy_typ == ActionType::RdResolved ||
1513 apy_typ == ActionType::SsConflict ||
1514 apy_typ == ActionType::SrConflict ||
1515 apy_typ == ActionType::RrConflict
1516 );
1517 }
1520 apx.typ = apx_typ;
1521 apy.typ = apy_typ;
1522 errcnt
1523 }
1524
1525 fn find_actions(&mut self, symbols: &Symbols, rules: &mut Vec<Rule>, states: &mut States) -> ParserResult<()>
1527 { 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()
1533 { if cfp.borrow().fws.contains(j)
1534 { stp.actions.push(Rc::new(RefCell::new(Action::new_rule(self.actions_enum, symbol.index, ActionType::Reduce, cfp.borrow().n_rule))));
1536 self.actions_enum += 1;
1537 }
1538 }
1539 }
1540 }
1541 }
1542
1543 states.array[0].actions.push(Rc::new(RefCell::new(Action::new_empty_rule(self.actions_enum, symbols.start_symbol_index, ActionType::Accept))));
1546 self.actions_enum += 1;
1547
1548 for stp in states.array.iter_mut()
1550 { if stp.actions.len() != 0
1551 { stp.actions.sort();
1552 for action in stp.actions.windows(2)
1553 { if action[0].borrow().symbol_index == action[1].borrow().symbol_index
1554 { self.n_conflicts += Self::resolve_conflict(symbols, rules, &action[0], &action[1]);
1557 }
1558 }
1559 }
1560 }
1561
1562 for stp in states.array.iter_mut()
1564 { for action in stp.actions.iter()
1565 { if action.borrow().typ == ActionType::Reduce
1566 { if let StateOrRule::Rule(n_rule) = action.borrow().x
1567 { rules[n_rule].can_reduce = true;
1568 }
1569 }
1570 }
1571 }
1572 for rule in rules.iter()
1573 { if !rule.can_reduce
1574 { return Err(LemonMintError::new(&rule.rule_filename, rule.rule_n_line, "This rule can not be reduced.\n".to_string()));
1575 }
1576 }
1577 Ok(())
1578 }
1579
1580 fn get_filename_of_first_rule(rules: &Vec<Rule>) -> Arc<String>
1581 { if let Some(rule) = rules.iter().next()
1582 { return Arc::clone(&rule.rule_filename);
1583 }
1584 Arc::new("".to_string())
1585 }
1586
1587 fn compress_tables(&self, symbols: &Symbols, rules: &Vec<Rule>, states: &mut States, default_symbol_index: usize)
1591 { for state in states.array.iter_mut()
1592 { let mut n_best = 0;
1593 let mut r_best = std::usize::MAX;
1594
1595 let mut it = state.actions.iter();
1596 while let Some(action) = it.next()
1597 { if action.borrow().typ == ActionType::Reduce
1598 { if let StateOrRule::Rule(n_rule) = action.borrow().x
1599 { let rule = &rules[n_rule];
1600 if !rule.lhs_start && n_rule != r_best
1601 { let mut n = 1;
1602 let mut it2 = it.clone();
1603 while let Some(ap2) = it2.next()
1604 { if ap2.borrow().typ == ActionType::Reduce
1605 { if let StateOrRule::Rule(n_rule_2) = ap2.borrow().x
1606 { if n_rule_2 != r_best && n_rule_2 == n_rule
1607 { n += 1;
1608 }
1609 }
1610 }
1611 }
1612 if n > n_best
1613 { n_best = n;
1614 r_best = n_rule;
1615 }
1616 }
1617 }
1618 }
1619 }
1620
1621 if n_best < 1
1623 { continue;
1624 }
1625
1626 let mut found = false;
1628 for action in state.actions.iter()
1629 { let mut action = action.borrow_mut();
1630 if action.typ == ActionType::Reduce
1631 { if let StateOrRule::Rule(n_rule) = action.x
1632 { if rules[n_rule].index == r_best
1633 { if !found
1634 { action.symbol_index = default_symbol_index;
1635 found = true;
1636 }
1637 else
1638 { action.typ = ActionType::NotUsed;
1639 }
1640 }
1641 }
1642 }
1643 }
1644 assert!(found);
1645 state.actions.sort();
1646
1647 found = false;
1648 for action in state.actions.iter()
1649 { let action = action.borrow();
1650 if action.typ==ActionType::Shift || action.typ==ActionType::Reduce && match action.x {StateOrRule::Rule(n_rule) => rules[n_rule].index != r_best, _ => false}
1651 { found = true;
1652 break;
1653 }
1654 }
1655 if !found
1656 { state.auto_reduce = true;
1657 state.default_reduce_rule = r_best;
1658 }
1659 }
1660
1661 for stp in states.array.iter()
1663 { for action in stp.actions.iter()
1664 { let mut action = action.borrow_mut();
1665 if action.typ == ActionType::Shift
1666 { if let StateOrRule::State(next_n_state) = action.x
1667 { let next_state = &states.array[next_n_state];
1668 if next_state.auto_reduce && next_state.default_reduce_rule!=std::usize::MAX
1669 { action.typ = ActionType::ShiftReduce;
1670 action.x = StateOrRule::Rule(next_state.default_reduce_rule);
1671 }
1672 }
1673 }
1674 }
1675 }
1676
1677 for stp in states.array.iter()
1681 { for action in stp.actions.iter()
1682 { let mut done = false;
1683 while !done
1684 { done = true;
1685 let mut ap2 = None;
1686 { let action = action.borrow();
1687 if action.typ == ActionType::ShiftReduce
1688 { if let StateOrRule::Rule(n_rule) = action.x
1689 { let rp = &rules[n_rule];
1690 if rp.code.is_empty() && rp.rhs.len()==1
1691 { if action.symbol_index >= symbols.n_terminals
1693 { ap2 = stp.actions.iter().find
1695 ( |a|
1696 { let a = a.borrow();
1697 a.id!= action.id && a.symbol_index==rp.lhs_index
1698 }
1699 );
1700 assert!(ap2.is_some());
1701 done = false;
1702 }
1703 }
1704 }
1705 }
1706 }
1707 if let Some(ap2) = ap2
1708 { let mut action = action.borrow_mut();
1709 let ap2 = ap2.borrow();
1710 action.symbol_index_opt = ap2.symbol_index;
1711 action.typ = ap2.typ;
1712 action.x = ap2.x;
1713 }
1714 }
1715 }
1716 }
1717 }
1718
1719 fn compute_action(&self, symbols: &Symbols, action: &Rc<RefCell<Action>>) -> usize
1722 { let action = action.borrow();
1723 match action.typ
1724 { ActionType::Shift =>
1725 { match action.x
1726 { StateOrRule::State(n_state) => n_state,
1727 _ => std::usize::MAX
1728 }
1729 }
1730 ActionType::ShiftReduce =>
1731 { match action.x
1733 { StateOrRule::Rule(n_rule) =>
1734 { if action.symbol_index >= symbols.n_terminals
1735 { self.min_reduce + n_rule
1736 }
1737 else
1738 { self.min_shift_reduce + n_rule
1739 }
1740 },
1741 _ => std::usize::MAX
1742 }
1743 }
1744 ActionType::Reduce =>
1745 { match action.x
1746 { StateOrRule::Rule(n_rule) => self.min_reduce + n_rule,
1747 _ => std::usize::MAX
1748 }
1749 }
1750 ActionType::Error =>
1751 { self.error_action
1752 }
1753 ActionType::Accept =>
1754 { self.accept_action
1755 }
1756 _ => std::usize::MAX
1757 }
1758 }
1759
1760 fn resort_states(&mut self, symbols: &Symbols, states: &mut States)
1762 { let sorted_len = states.array.len();
1763 for stp in states.array.iter_mut()
1764 { stp.n_token_act = 0;
1765 stp.n_nt_act = 0;
1766 stp.default_reduce_action = std::usize::MAX; stp.token_offset = std::isize::MIN;
1768 stp.nt_offset = std::isize::MIN;
1769 for action in stp.actions.iter()
1770 { let n_action = self.compute_action(symbols, action);
1771 if n_action != std::usize::MAX
1772 { let action = action.borrow();
1773 if action.symbol_index < symbols.n_terminals
1774 { stp.n_token_act += 1;
1775 }
1776 else if action.symbol_index < symbols.n_symbols
1777 { stp.n_nt_act += 1;
1778 }
1779 else
1780 { assert!(!stp.auto_reduce || action.x == StateOrRule::Rule(stp.default_reduce_rule));
1781 stp.default_reduce_action = n_action;
1782 }
1783 }
1784 }
1785 }
1786
1787 if sorted_len > 2
1790 { states.array[1 ..].sort_by
1791 ( |a, b|
1792 { let mut res = b.n_nt_act.cmp(&a.n_nt_act);
1793 if res == Ordering::Equal
1794 { res = b.n_token_act.cmp(&a.n_token_act);
1795 if res == Ordering::Equal
1796 { res = b.n_state.cmp(&a.n_state);
1797 }
1798 }
1799 res
1800 }
1801 );
1802 }
1803
1804 let mut map = Vec::new();
1806 map.resize(states.array.len(), 0);
1807 for (i, stp) in states.array.iter().enumerate()
1808 { map[stp.n_state] = i;
1809 }
1810 for stp in states.array.iter()
1811 { for action in stp.actions.iter()
1812 { if let StateOrRule::State(ref mut state) = action.borrow_mut().x
1813 { *state = map[*state];
1814 }
1815 }
1816 for configuration in stp.configurations.iter()
1817 { let mut configuration = configuration.borrow_mut();
1818 configuration.n_state = map[configuration.n_state];
1819 }
1820 }
1821
1822 for (new_n_state, stp) in states.array.iter_mut().enumerate()
1824 { stp.n_state = new_n_state;
1825 }
1826
1827 while states.n_no_tail>1 && states.array[states.n_no_tail-1].auto_reduce
1828 { states.n_no_tail -= 1;
1829 }
1830 }
1831
1832 fn minimum_size_type(lower: isize, upper: isize) -> isize
1834 { if lower >= 0
1835 { if upper <= 255
1836 { 1
1837 }
1838 else if upper < 65535
1839 { 2
1840 }
1841 else
1842 { 4
1843 }
1844 }
1845 else
1846 { if lower>=-127 && upper<=127
1847 { -1
1848 }
1849 else if lower>=-32767 && upper<32767
1850 { -2
1851 }
1852 else
1853 { -4
1854 }
1855 }
1856 }
1857
1858 fn translate_code(&self, rule: &mut Rule) -> ParserResult<()>
1860 { let mut used = Vec::new(); used.resize(rule.rhs.len(), false);
1862
1863 let mut it = rule.code.chars();
1864 let mut it_prev = it.clone();
1865
1866 while let Some(cp) = it.next()
1867 { if cp.is_ascii_alphabetic()
1868 { let ident: String = it_prev.take_while(|c| c.is_ascii_alphanumeric() || *c=='_').collect();
1869 if ident.len() > 1
1870 { it.nth(ident.chars().count() - 2).unwrap();
1871 }
1872 for (i, rhs) in rule.rhs.iter().enumerate()
1873 { if rhs.alias == ident
1874 { used[i] = true;
1875 break;
1876 }
1877 }
1878 }
1879 it_prev = it.clone();
1880 }
1881
1882 for (i, rhs) in rule.rhs.iter().enumerate()
1884 { if !rhs.alias.is_empty() && !used[i]
1885 { return Err
1886 ( LemonMintError::new
1887 ( &rule.rule_filename,
1888 rule.rule_n_line,
1889 format!("Label {} for \"{}({})\" is never used.", rhs.alias, rhs.name, rhs.alias)
1890 )
1891 );
1892 }
1893 }
1894
1895 Ok(())
1896 }
1897
1898 fn get_minor_type(&self, symbols: &mut Symbols) -> Vec<(String, String)>
1906 { let arraysize = symbols.n_symbols * 2; let mut types = Vec::new(); types.resize(arraysize, String::new());
1910
1911 'l: for (i, sp) in symbols.array[0 .. symbols.n_symbols].iter_mut().enumerate()
1915 { if i == symbols.error_symbol_index
1916 { sp.dtnum = arraysize+1;
1917 continue;
1918 }
1919 if sp.typ==SymbolType::TERMINAL || (sp.data_type.is_empty() && self.vartype.is_empty())
1920 { sp.dtnum = 0;
1921 continue;
1922 }
1923 let stddt = if !sp.data_type.is_empty()
1924 { &sp.data_type
1925 }
1926 else
1927 { &self.vartype
1928 };
1929 if !self.token_type.is_empty() && &self.token_type == stddt
1930 { sp.dtnum = 0;
1931 continue;
1932 }
1933 let mut hash = DefaultHasher::new();
1934 stddt.hash(&mut hash);
1935 let mut hash = hash.finish() as usize % arraysize;
1936 while !types[hash].is_empty()
1937 { if &types[hash] == stddt
1938 { sp.dtnum = hash + 1;
1939 continue 'l;
1940 }
1941 hash += 1;
1942 if hash >= arraysize
1943 { hash = 0;
1944 }
1945 }
1946 sp.dtnum = hash + 1;
1947 types[hash] = stddt.to_string(); }
1949
1950 let mut minor_type = Vec::with_capacity(arraysize+3);
1952 minor_type.push(("None".to_string(), "".to_string()));
1953 minor_type.push(("Symbol0".to_string(), "TokenValue".to_string()));
1954 let mut i = 1;
1955 for name in types
1956 { if !name.is_empty()
1957 { minor_type.push((format!("Symbol{}", i), name));
1958 }
1959 i += 1;
1960 }
1961 if let Some(symbol) = symbols.get_error_symbol()
1962 { minor_type.push((format!("Symbol{}", symbol.dtnum), "i32".to_string()));
1963 }
1964
1965 minor_type
1967 }
1968
1969 fn init_acttab(&mut self, symbols: &Symbols, rules: &mut Vec<Rule>, states: &mut States) -> ActTab
1970 { let mut acttab = ActTab::new(symbols.n_terminals, symbols.n_symbols);
1971
1972 let mut ax = Vec::with_capacity(states.n_no_tail*2);
1974 for stp in states.array[0 .. states.n_no_tail].iter()
1975 { ax.push(AxSet::new(stp.n_state, true, stp.n_token_act, ax.len()));
1976 ax.push(AxSet::new(stp.n_state, false, stp.n_nt_act, ax.len()));
1977 }
1978 ax.sort();
1979
1980 let mut min_token_offset = 0;
1981 let mut max_token_offset = 0;
1982 let mut min_nt_offset = 0;
1983 let mut max_nt_offset = 0;
1984
1985 for ax_i in ax.iter()
1987 { if ax_i.n_action == 0
1988 { break;
1989 }
1990 let stp = &mut states.array[ax_i.n_state];
1991 if ax_i.is_tkn
1992 { for action in stp.actions.iter()
1993 { if action.borrow().symbol_index < symbols.n_terminals
1994 { let n_action = self.compute_action(symbols, action);
1995 if n_action != std::usize::MAX
1996 { acttab.acttab_action(action.borrow().symbol_index, n_action);
1997 }
1998 }
1999 }
2000 stp.token_offset = acttab.acttab_insert(true);
2001 if stp.token_offset < min_token_offset
2002 { min_token_offset = stp.token_offset;
2003 }
2004 if stp.token_offset > max_token_offset
2005 { max_token_offset = stp.token_offset;
2006 }
2007 }
2008 else
2009 { for action in stp.actions.iter()
2010 { if action.borrow().symbol_index >= symbols.n_terminals && action.borrow().symbol_index != symbols.n_symbols
2011 { let n_action = self.compute_action(symbols, action);
2012 if n_action != std::usize::MAX
2013 { acttab.acttab_action(action.borrow().symbol_index, n_action);
2014 }
2015 }
2016 }
2017 stp.nt_offset = acttab.acttab_insert(false);
2018 if stp.nt_offset < min_nt_offset
2019 { min_nt_offset = stp.nt_offset;
2020 }
2021 if stp.nt_offset > max_nt_offset
2022 { max_nt_offset = stp.nt_offset;
2023 }
2024 }
2025 }
2026
2027 for rule in rules.iter_mut()
2029 { rule.does_reduce = false;
2030 }
2031 for state in states.array[0 .. states.n_no_tail].iter()
2032 { for action in state.actions.iter()
2033 { let action = action.borrow_mut();
2034 if action.typ==ActionType::Reduce || action.typ==ActionType::ShiftReduce
2035 { if let StateOrRule::Rule(n_rule) = action.x
2036 { rules[n_rule].does_reduce = true;
2037 }
2038 }
2039 }
2040 }
2041
2042 let mut n_fallbacks = 0;
2043 if self.has_fallback
2044 { n_fallbacks = symbols.n_terminals - 1;
2045 while n_fallbacks>0 && symbols.array[n_fallbacks].fallback_index==std::usize::MAX
2046 { n_fallbacks -= 1;
2047 }
2048 n_fallbacks += 1;
2049 }
2050 self.has_fallback = n_fallbacks != 0;
2051
2052 let mut n_shift_offset = states.n_no_tail;
2053 while n_shift_offset >0 && states.array[n_shift_offset -1].token_offset == std::isize::MIN
2054 { n_shift_offset -= 1;
2055 }
2056
2057 let mut reduce_count = states.n_no_tail;
2058 while reduce_count>0 && states.array[reduce_count-1].nt_offset == std::isize::MIN
2059 { reduce_count -= 1;
2060 }
2061
2062 acttab.min_token_offset = min_token_offset;
2063 acttab.max_token_offset = max_token_offset;
2064 acttab.min_nt_offset = min_nt_offset;
2065 acttab.max_nt_offset = max_nt_offset;
2066 acttab.n_fallbacks = n_fallbacks;
2067 acttab.n_shift_offset = n_shift_offset;
2068 acttab.reduce_count = reduce_count;
2069
2070 acttab
2071 }
2072
2073 fn get_lemon(mut self, mut symbols: Symbols, mut rules: Vec<Rule>, states: States, acttab: ActTab) -> ParserResult<LemonMint>
2075 { let sz_code_type = Self::minimum_size_type(0, symbols.n_symbols as isize+1);
2077 let sz_action_type = Self::minimum_size_type(0, (states.array.len()+rules.len()+5) as isize);
2078 let sz_shift_offset_type = Self::minimum_size_type(acttab.min_token_offset-1, acttab.max_token_offset);
2079 let sz_reduce_offset_type = Self::minimum_size_type(acttab.min_nt_offset-1, acttab.max_nt_offset);
2080
2081 let mut token = Vec::with_capacity(symbols.n_terminals);
2083 for symbol in symbols.array[1 .. symbols.n_terminals].iter()
2084 { token.push(Arc::clone(&symbol.name));
2085 }
2086
2087 self.tables_size += rules.len() * sz_code_type.abs() as usize;
2090
2091 self.n_action_table_entries = acttab.get_n_actions();
2104 let mut n = acttab.get_n_lookahead();
2105 let n_lookahead = std::cmp::max(n, symbols.n_terminals + self.n_action_table_entries);
2106 let mut lookahead_and_action = Vec::with_capacity(n_lookahead);
2107 for (i, LookaheadAction {lookahead, action}) in acttab.iter().enumerate()
2108 { let lookahead = if *lookahead == std::usize::MAX {symbols.n_symbols} else {*lookahead};
2109 let action = if i >= self.n_action_table_entries {0} else if *action == std::usize::MAX {self.no_action} else {*action};
2110 lookahead_and_action.push((lookahead, action));
2111 }
2112 while n < n_lookahead
2115 { lookahead_and_action.push((symbols.n_terminals, 0));
2116 n += 1;
2117 }
2118 self.tables_size += lookahead_and_action.len() * (sz_code_type + sz_action_type).abs() as usize;
2119
2120 let mut shift_offset = Vec::with_capacity(acttab.n_shift_offset);
2122 for stp in states.array.iter().take(acttab.n_shift_offset)
2123 { shift_offset.push(if stp.token_offset==std::isize::MIN {acttab.min_token_offset - 1} else {stp.token_offset});
2124 }
2125 self.tables_size += shift_offset.len() * sz_shift_offset_type.abs() as usize;
2126
2127 let mut reduce_offset = Vec::with_capacity(acttab.reduce_count);
2129 for stp in states.array.iter().take(acttab.reduce_count)
2130 { reduce_offset.push(if stp.nt_offset==std::isize::MIN {acttab.min_nt_offset - 1} else {stp.nt_offset});
2131 }
2132 self.tables_size += reduce_offset.len() * sz_reduce_offset_type.abs() as usize;
2133
2134 let mut default = Vec::with_capacity(states.n_no_tail);
2136 for stp in states.array.iter().take(states.n_no_tail)
2137 { default.push(if stp.default_reduce_action!=std::usize::MAX {stp.default_reduce_action + self.min_reduce} else {self.error_action});
2138 }
2139 self.tables_size += default.len() * sz_action_type.abs() as usize;
2140
2141 let mut fallback = Vec::new();
2143 if self.has_fallback
2144 { fallback.reserve(acttab.n_fallbacks);
2145 for symbol in symbols.array.iter().take(acttab.n_fallbacks)
2146 { if symbol.fallback_index != std::usize::MAX
2147 { let fb = &symbols.array[symbol.fallback_index];
2148 fallback.push((fb.index, Arc::clone(&symbol.name), Arc::clone(&fb.name)));
2149 }
2150 else
2151 { fallback.push((0, Arc::clone(&symbol.name), Arc::new(String::new())));
2152 }
2153 }
2154 }
2155 self.tables_size += fallback.len() * sz_code_type.abs() as usize;
2156
2157 let mut token_names = Vec::new();
2159 if self.with_trace && symbols.n_symbols!=0
2160 { token_names.reserve(symbols.n_symbols);
2161 for symbol in symbols.array.iter().take(symbols.n_symbols)
2162 { token_names.push(Arc::clone(&symbol.name));
2163 }
2164 }
2165
2166 for sym in symbols.array.iter()
2168 { for n_rule in sym.sym_rules_arr.iter()
2169 { self.translate_code(&mut rules[*n_rule])?;
2170 }
2171 }
2172
2173 let start_type = symbols.get_start_symbol().data_type.clone();
2174 let minor_type = self.get_minor_type(&mut symbols);
2175 let n_symbols = symbols.n_symbols;
2176 let n_states = states.array.len();
2177 let n_no_tail = states.n_no_tail;
2178 let error_symbol = if let Some(symbol) = symbols.get_error_symbol() {symbol.index} else {0};
2179 let n_terminals = symbols.n_terminals;
2180 let n_nonterminals = symbols.n_symbols - symbols.n_terminals;
2181
2182 Ok
2183 ( LemonMint
2184 { symbols,
2185 rules,
2186 states,
2187 token_type: self.token_type,
2188 vartype: self.vartype,
2189 start_name: self.start_name,
2190 start_type,
2191 extra_argument_type: self.extra_argument_type,
2192 extracode: self.extracode,
2193 minor_type,
2194 token,
2195
2196 sz_code_type,
2197 sz_action_type,
2198 sz_shift_offset_type,
2199 sz_reduce_offset_type,
2200
2201 n_symbols,
2202 n_states,
2203 n_no_tail,
2204 n_fallbacks: acttab.n_fallbacks,
2205 error_symbol,
2206 with_fallback: self.has_fallback,
2207 shift_count: acttab.n_shift_offset-1,
2208 reduce_count: acttab.reduce_count-1,
2209 with_trace: self.with_trace,
2210 trace_prompt: self.trace_prompt,
2211 shift_min: acttab.min_token_offset,
2212 shift_max: acttab.max_token_offset,
2213 reduce_min: acttab.min_nt_offset,
2214 reduce_max: acttab.max_nt_offset,
2215
2216 n_terminals,
2217 n_nonterminals,
2218 tables_size: self.tables_size,
2219 n_action_table_entries: self.n_action_table_entries,
2220
2221 lookahead_and_action,
2222 shift_offset,
2223 reduce_offset,
2224 default,
2225 fallback,
2226 token_names,
2227 }
2228 )
2229 }
2230
2231 pub fn load_y_file(self, filename: &Arc<String>) -> ParserResult<Self>
2233 { self.load_y(filename, File::open(filename.as_ref()).map_err(|e| LemonMintError::new(filename, 1, e.to_string()))?)
2234 }
2235
2236 pub fn load_y<R>(mut self, filename: &Arc<String>, input: R) -> ParserResult<Self> where R: io::Read
2248 { let input = BufReader::new(input);
2249 let mut n_line = 0;
2250 let mut lines = input.lines();
2251 let mut part_till_comment: Option<String> = None; 'l: while let Some(line) = lines.next()
2253 { n_line += 1;
2254 let mut line = line.map_err(|e| LemonMintError::new(filename, n_line, e.to_string()))?;
2255 if let Some(part) = part_till_comment.take()
2257 { if let Some(pos) = line.find("*/")
2258 { line.replace_range(.. pos+2, &part);
2259 }
2260 else
2261 { part_till_comment = Some(part);
2262 continue;
2263 }
2264 }
2265 loop
2266 { if let Some(pos) = line.find('/')
2267 { match line.bytes().skip(pos+1).next()
2268 { Some(b'/') => { line.truncate(pos);
2270 }
2271 Some(b'*') => { if let Some(len_minus_2) = line[pos+2 ..].find("*/")
2273 { line.replace_range(pos .. pos+len_minus_2+2, "");
2274 continue;
2275 }
2276 else
2277 { line.truncate(pos);
2278 part_till_comment = Some(line);
2279 continue 'l;
2280 }
2281 }
2282 _ => {}
2283 }
2284 }
2285 break;
2286 }
2287 let mut line = line.trim();
2289 if !line.is_empty()
2290 { let mut directive = Directive::Rule;
2291 let mut symbol_name: Cow<str> = "".into();
2292 let mut rule_rhs: Cow<str> = "".into();
2293 if line.as_bytes()[0] == b'%'
2294 { let pos = line.bytes().position(|c| c.is_ascii_whitespace()).unwrap_or(line.len());
2295 let token = &line[1 .. pos];
2296 line = &line[pos ..].trim_start();
2297 directive = match token
2298 { "token_type" => Directive::TokenType,
2299 "type" => Directive::Type,
2300 "default_type" => Directive::DefaultType,
2301 "start_symbol" => Directive::StartSymbol,
2302 "trace" => Directive::Trace,
2303 "extra_argument" => Directive::ExtraArgument,
2304 "left" => Directive::Left,
2305 "right" => Directive::Right,
2306 "nonassoc" => Directive::Nonassoc,
2307 "fallback" => Directive::Fallback,
2308 "code" | "include" => Directive::Code,
2309 _ =>
2310 { return Err(LemonMintError::new(filename, n_line, format!("Directive not supported: %{}", token)));
2311 }
2312 };
2313 }
2314 match directive
2315 { Directive::Type | Directive::Fallback =>
2316 { let pos = line.bytes().position(|c| !c.is_ascii_alphanumeric() && c!=b'_').unwrap_or(line.len());
2318 if pos == 0
2319 { return Err(LemonMintError::new(filename, n_line, "Expected symbol name after %type".to_string()));
2320 }
2321 symbol_name = line[.. pos].to_string().into();
2322 line = &line[pos ..].trim_start();
2323 }
2324 Directive::Rule =>
2325 { let pos = line.find("::=").ok_or_else(|| LemonMintError::new(filename, n_line, "Couldn't interpret this line".to_string()))?;
2326 symbol_name = line[.. pos].trim_end().to_string().into();
2327 line = &line[pos+3 ..].trim_start();
2328 let pos = line.find('.').ok_or_else(|| LemonMintError::new(filename, n_line, "Rules must be terminated with a dot".to_string()))?;
2329 rule_rhs = line[.. pos].trim_end().to_string().into();
2330 line = &line[pos+1 ..].trim_start();
2331 }
2332 _ => {}
2333 }
2334 let mut value: Cow<str> = line.into();
2335 if line.bytes().next() == Some(b'{')
2336 { line = &line[1 ..].trim_start(); let (mut balance, mut last_close) = (1, usize::MAX);
2338 Self::balanced_braces(filename, n_line, line, &mut balance, &mut last_close)?;
2339 if balance == 0
2340 { value = line[.. last_close].into(); }
2342 else
2343 { let mut buffer = String::with_capacity(128);
2345 buffer.push_str(line);
2346 buffer.push('\n');
2347 let from_n_line = n_line;
2348 while let Some(line) = lines.next()
2349 { n_line += 1;
2350 let line = line.map_err(|e| LemonMintError::new(filename, n_line, e.to_string()))?;
2351 Self::balanced_braces(filename, n_line, &line, &mut balance, &mut last_close)?;
2352 if balance == 0
2353 { buffer.push_str(&line[.. last_close]); break;
2355 }
2356 buffer.push_str(&line);
2357 buffer.push('\n');
2358 }
2359 if balance > 0
2360 { return Err(LemonMintError::new(filename, n_line, format!("Braces not closed at the end of file since line {}", from_n_line)));
2361 }
2362 value = buffer.into();
2363 }
2364 }
2365 else if !line.is_empty() && line.as_bytes()[line.len()-1]==b'.'
2366 { value = line[.. line.len()-1].trim_end().into(); }
2368 self = match directive
2369 { Directive::Rule => self.add_rule(filename, n_line, symbol_name.into(), rule_rhs.as_ref(), value.into()),
2370 Directive::TokenType => self.set_token_type(value.into()),
2371 Directive::Type => self.add_type(filename, n_line, symbol_name.into(), value.into()),
2372 Directive::DefaultType => self.set_default_type(value.into()),
2373 Directive::StartSymbol => self.set_start_symbol(filename, n_line, value.into()),
2374 Directive::Trace => self.set_trace_prompt(value.into()),
2375 Directive::ExtraArgument => self.set_extra_argument_type(value.into()),
2376 Directive::Left => self.set_left(filename, n_line, value.as_ref()),
2377 Directive::Right => self.set_right(filename, n_line, value.as_ref()),
2378 Directive::Nonassoc => self.set_nonassoc(filename, n_line, value.as_ref()),
2379 Directive::Fallback => self.add_fallback(filename, n_line, symbol_name.into(), value.as_ref()),
2380 Directive::Code => self.add_code(value.into()),
2381 }?;
2382 }
2383 }
2384 Ok(self)
2385 }
2386
2387 fn balanced_braces(filename: &Arc<String>, n_line: usize, line: &str, balance: &mut i32, last_close: &mut usize) -> ParserResult<()>
2388 { for (i, c) in line.bytes().enumerate()
2389 { match c
2390 { b'{' => *balance += 1,
2391 b'}' => {*balance -= 1; *last_close = i}
2392 _ => {}
2393 }
2394 }
2395 if *balance < 0
2396 { return Err(LemonMintError::new(filename, n_line, "Braces on line not balanced".to_string()));
2397 }
2398 if *balance == 0
2399 { if !line[*last_close+1 ..].trim_end().is_empty()
2400 { return Err(LemonMintError::new(filename, n_line, "Junk after closing brace".to_string()));
2401 }
2402 }
2403 Ok(())
2404 }
2405
2406 pub fn set_start_symbol(mut self, filename: &Arc<String>, n_line: usize, mut value: String) -> ParserResult<Self>
2408 { let trimmed = value.trim();
2409 if trimmed.len() != value.len()
2410 { value = trimmed.to_string();
2411 }
2412 if value.find(|c: char| !c.is_ascii_alphanumeric() && c!='_').is_some()
2413 { return Err(LemonMintError::new(filename, n_line, format!("Invalid start symbol name: {}", value)));
2414 }
2415 if is_terminal_name(&value)
2416 { return Err(LemonMintError::new(filename, n_line, "Start symbol must be nonterminal".to_string()));
2417 }
2418 self.start_name = value;
2419 Ok(self)
2420 }
2421
2422 pub fn set_token_type(mut self, value: String) -> ParserResult<Self>
2424 { self.token_type = typename_to_string(value);
2425 Ok(self)
2426 }
2427
2428 pub fn set_default_type(mut self, value: String) -> ParserResult<Self>
2430 { self.vartype = typename_to_string(value);
2431 Ok(self)
2432 }
2433
2434 pub fn set_trace_prompt(mut self, value: String) -> ParserResult<Self>
2437 { self.with_trace = true;
2438 self.trace_prompt = value;
2439 Ok(self)
2440 }
2441
2442 pub fn set_extra_argument_type(mut self, value: String) -> ParserResult<Self>
2469 { self.extra_argument_type = typename_to_string(value);
2470 Ok(self)
2471 }
2472
2473 pub fn set_left(self, filename: &Arc<String>, n_line: usize, symbol_names: &str) -> ParserResult<Self>
2488 { self.add_associativity(filename, n_line, symbol_names, Associativity::LEFT)
2489 }
2490
2491 pub fn set_right(self, filename: &Arc<String>, n_line: usize, symbol_names: &str) -> ParserResult<Self>
2493 { self.add_associativity(filename, n_line, symbol_names, Associativity::RIGHT)
2494 }
2495
2496 pub fn set_nonassoc(self, filename: &Arc<String>, n_line: usize, symbol_names: &str) -> ParserResult<Self>
2498 { self.add_associativity(filename, n_line, symbol_names, Associativity::NONASSOC)
2499 }
2500
2501 fn add_associativity(mut self, filename: &Arc<String>, n_line: usize, symbol_names: &str, assoc: Associativity) -> ParserResult<Self>
2502 { for symbol_name in symbol_names.trim().split(|c: char| c.is_ascii_whitespace())
2503 { if !symbol_name.is_empty()
2504 { if symbol_name.find(|c: char| !c.is_ascii_alphanumeric() && c!='_').is_some()
2505 { return Err(LemonMintError::new(filename, n_line, format!("Invalid token name: {}", symbol_name)));
2506 }
2507 if !is_terminal_name(symbol_name)
2508 { return Err(LemonMintError::new(filename, n_line, format!("Can only set precedence for terminal symbols, not \"{}\"", symbol_name)));
2509 }
2510 if let Some(prev) = self.precedence.get(symbol_name)
2511 { return Err(LemonMintError::new(filename, n_line, format!("Symbol \"{}\" has already be given a precedence at {}:{}", symbol_name, prev.filename, prev.n_line)));
2512 }
2513 self.precedence.insert
2514 ( symbol_name.to_string(),
2515 PrecedenceInFile
2516 { filename: Arc::clone(filename),
2517 n_line,
2518 assoc,
2519 precedence: self.prec_counter,
2520 }
2521 );
2522 }
2523 }
2524 self.prec_counter += 1;
2525 Ok(self)
2526 }
2527
2528 pub fn add_type(mut self, filename: &Arc<String>, n_line: usize, mut symbol_name: String, type_name: String) -> ParserResult<Self>
2530 { let trimmed = symbol_name.trim();
2531 if trimmed.len() != symbol_name.len()
2532 { symbol_name = trimmed.to_string();
2533 }
2534 if symbol_name.find(|c: char| !c.is_ascii_alphanumeric() && c!='_').is_some()
2535 { return Err(LemonMintError::new(filename, n_line, format!("Invalid symbol name: {}", symbol_name)));
2536 }
2537 if is_terminal_name(&symbol_name)
2538 { return Err(LemonMintError::new(filename, n_line, format!("Can only set type for nonterminal symbols, not \"{}\"", symbol_name)));
2539 }
2540 if let Some(prev) = self.nonterminal_types.get(&symbol_name)
2541 { return Err(LemonMintError::new(filename, n_line, format!("Type for symbol \"{}\" already defined at {}:{}", symbol_name, prev.filename, prev.n_line)));
2542 }
2543 self.nonterminal_types.insert
2544 ( symbol_name,
2545 StringInFile
2546 { filename: Arc::clone(filename),
2547 n_line,
2548 string: typename_to_string(type_name),
2549 }
2550 );
2551 Ok(self)
2552 }
2553
2554 pub fn get_type(&self, mut symbol_name: &str) -> Option<(Arc<String>, usize)>
2556 { symbol_name = symbol_name.trim();
2557 self.nonterminal_types.get(symbol_name).map(|v| (Arc::clone(&v.filename), v.n_line))
2558 }
2559
2560 pub fn add_fallback(mut self, filename: &Arc<String>, n_line: usize, mut fallback_to_symbol_name: String, symbol_names: &str) -> ParserResult<Self>
2562 { let trimmed = fallback_to_symbol_name.trim();
2563 if trimmed.len() != fallback_to_symbol_name.len()
2564 { fallback_to_symbol_name = trimmed.to_string();
2565 }
2566 if fallback_to_symbol_name.find(|c: char| !c.is_ascii_alphanumeric() && c!='_').is_some()
2567 { return Err(LemonMintError::new(filename, n_line, format!("Invalid token name: {}", fallback_to_symbol_name)));
2568 }
2569 let fallback_to_symbol_name = Arc::new(fallback_to_symbol_name);
2570 for symbol_name in symbol_names.trim().split(|c: char| c.is_ascii_whitespace())
2571 { if !symbol_name.is_empty()
2572 { if symbol_name.find(|c: char| !c.is_ascii_alphanumeric() && c!='_').is_some()
2573 { return Err(LemonMintError::new(filename, n_line, format!("Invalid token name: {}", symbol_name)));
2574 }
2575 if !is_terminal_name(symbol_name)
2576 { return Err(LemonMintError::new(filename, n_line, format!("Can only set fallback to terminal symbols, not \"{}\"", symbol_name)));
2577 }
2578 let symbol_name = Arc::new(symbol_name.to_string());
2579 self.symbols_builder.add(&symbol_name);
2580 self.symbols_builder.add(&fallback_to_symbol_name);
2581 let sp = self.symbols_builder.get(&symbol_name);
2582 if sp.fallback_index != std::usize::MAX
2583 { return Err(LemonMintError::new(filename, n_line, format!("More than one fallback assigned to token \"{}\"", symbol_name)));
2584 }
2585 let fsp = self.symbols_builder.get(&fallback_to_symbol_name);
2586 if *fsp == *sp
2587 { return Err(LemonMintError::new(filename, n_line, format!("Symbol \"{}\" is asked fallback to self // {}, {}", symbol_name, fallback_to_symbol_name, symbol_name)));
2588 }
2589 self.symbols_builder.get_mut(&symbol_name).fallback_index = fsp.index;
2590 }
2591 }
2592 Ok(self)
2593 }
2594
2595 pub fn add_rule(mut self, filename: &Arc<String>, n_line: usize, mut lhs_name: String, rhs_names_aliases: &str, code: String) -> ParserResult<Self>
2597 { let trimmed = lhs_name.trim();
2598 if trimmed.len() != lhs_name.len()
2599 { lhs_name = trimmed.to_string();
2600 }
2601 if is_terminal_name(&lhs_name)
2602 { return Err(LemonMintError::new(filename, n_line, format!("Invalid LHS symbol: \"{}\"", lhs_name)));
2603 }
2604 let mut code = code;
2605 if code.trim().is_empty()
2606 { code = String::new();
2607 }
2608 if self.start_name.is_empty()
2609 { self.start_name = lhs_name.clone();
2610 }
2611 let lhs_name = Arc::new(lhs_name);
2612 let lhs_index = self.symbols_builder.add(&lhs_name);
2613 let mut rule = Rule::new(filename, n_line, &lhs_name, lhs_index, self.rules.len(), code);
2614 let mut s = rhs_names_aliases.trim_start();
2616 while s.len() != 0
2617 { let name_len = s.chars().position(|c| !c.is_ascii_alphanumeric() && c!='_').unwrap_or(s.len());
2618 if name_len == 0
2619 { return Err(LemonMintError::new(filename, n_line, format!("Invalid RHS expression: \"{}\"", rhs_names_aliases)));
2620 }
2621 let rhs_name = Arc::new(s[.. name_len].to_string());
2622 let rhs_index = self.symbols_builder.add(&rhs_name);
2623 s = s[name_len ..].trim_start();
2624 let mut alias = String::new();
2625 if s.bytes().next() == Some(b'(')
2626 { s = s[1 ..].trim_start();
2627 let alias_len = s.chars().position(|c| !c.is_ascii_alphanumeric() && c!='_').unwrap_or(s.len());
2628 alias = s[.. alias_len].to_string();
2629 s = s[alias_len ..].trim_start();
2630 if alias_len==0 || s.bytes().next() != Some(b')')
2631 { return Err(LemonMintError::new(filename, n_line, format!("Invalid alias in RHS expression: \"{}\"", rhs_names_aliases)));
2632 }
2633 s = s[1 ..].trim_start();
2634 }
2635 rule.rhs.push(Rhs{name: rhs_name, index: rhs_index, alias});
2636 }
2637 self.symbols_builder.get_mut(&lhs_name).sym_rules_arr.insert(0, self.rules.len()); self.rules.push(rule);
2639 Ok(self)
2640 }
2641
2642 pub fn add_code(mut self, code: String) -> ParserResult<Self>
2644 { if self.extracode.is_empty()
2645 { self.extracode = code;
2646 }
2647 else
2648 { self.extracode.push_str("\n\n");
2649 self.extracode.push_str(&code);
2650 }
2651 Ok(self)
2652 }
2653
2654 pub fn set_no_compress(mut self, new_no_compress: bool) -> ParserResult<Self>
2656 { self.no_compress = new_no_compress;
2657 Ok(self)
2658 }
2659
2660 pub fn set_no_resort(mut self, new_no_resort: bool) -> ParserResult<Self>
2662 { self.no_resort = new_no_resort;
2663 Ok(self)
2664 }
2665
2666 pub fn try_into_lemon(mut self) -> ParserResult<LemonMint>
2670 { let mut rules = mem::replace(&mut self.rules, Vec::new());
2672 if rules.len() == 0
2673 { return Err(LemonMintError::new(&Arc::new(String::new()), 1, "Empty grammar".to_string()));
2674 }
2675
2676 let mut symbols =
2678 { let symbols_builder = mem::replace(&mut self.symbols_builder, SymbolsBuilder::new(true));
2679 let nonterminal_types = mem::replace(&mut self.nonterminal_types, HashMap::new());
2680 let precedence = mem::replace(&mut self.precedence, HashMap::new());
2681
2682 symbols_builder.into_symbols(&self.start_name, nonterminal_types, precedence, &mut rules)? };
2684
2685 rules.sort_by
2687 ( |a, b|
2688 { if a.code.is_empty() == b.code.is_empty()
2689 { a.index.cmp(&b.index)
2690 }
2691 else if a.code.is_empty()
2692 { Ordering::Greater
2693 }
2694 else
2695 { Ordering::Less
2696 }
2697 }
2698 );
2699 for (i, rule) in rules.iter_mut().enumerate()
2700 { rule.index = i;
2701 }
2702
2703 Self::find_rule_precedences(&mut symbols, &mut rules);
2705
2706 self.find_first_sets(&mut symbols, &mut rules);
2708
2709 if !self.start_name.is_empty()
2711 { if symbols.start_symbol_index == std::usize::MAX
2712 { 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)));
2713 }
2714 }
2715 else
2716 { return Err(LemonMintError::new(&Self::get_filename_of_first_rule(&rules), 1, "Please, specify a start symbol".to_string()));
2717 }
2718
2719 for rule in rules.iter()
2722 { for rhs in &rule.rhs
2723 { if rhs.index == symbols.start_symbol_index
2724 { 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)));
2725 }
2726 }
2727 }
2728
2729 dump_symbols(&symbols, &rules);
2730
2731 let mut states = StatesBuilder::build(&symbols, &mut rules, symbols.get_start_symbol(), symbols.n_terminals, &mut self.actions_enum)?;
2733
2734 dump_states(&states, &rules, &symbols, 1);
2735
2736 Self::find_links(&states);
2738
2739 dump_states(&states, &rules, &symbols, 2);
2740
2741 Self::find_follow_sets(&states);
2743
2744 dump_states(&states, &rules, &symbols, 3);
2745
2746 self.find_actions(&symbols, &mut rules, &mut states)?;
2748
2749 dump_states(&states, &rules, &symbols, 4);
2750
2751 if !self.no_compress
2753 { self.compress_tables(&symbols, &rules, &mut states, symbols.default_symbol_index);
2754 }
2755
2756 dump_states(&states, &rules, &symbols, 5);
2757
2758 if !self.no_resort
2761 { self.resort_states(&symbols, &mut states);
2762 }
2763
2764 dump_states(&states, &rules, &symbols, 6);
2765
2766 self.min_shift_reduce = states.array.len();
2768 self.error_action = self.min_shift_reduce + rules.len();
2769 self.accept_action = self.error_action + 1;
2770 self.no_action = self.accept_action + 1;
2771 self.min_reduce = self.no_action + 1;
2772 self.max_action = self.min_reduce + rules.len();
2773 let acttab = self.init_acttab(&symbols, &mut rules, &mut states);
2774
2775 dump_states(&states, &rules, &symbols, 7);
2776
2777 if self.n_conflicts > 0
2779 { Err(LemonMintError::new(&Self::get_filename_of_first_rule(&rules), 1, format!("{} parsing conflicts", self.n_conflicts)))
2780 }
2781 else
2782 { self.get_lemon(symbols, rules, states, acttab)
2783 }
2784 }
2785}
2786
2787#[derive(Debug, Copy, Clone, PartialEq)]
2788enum Lang
2789{ Rust
2790}
2791
2792fn size_type_to_str(lang: Lang, n_bytes: isize) -> &'static str
2793{ match (lang, n_bytes)
2794 { (Lang::Rust, -1) => "i8",
2795 (Lang::Rust, -2) => "i16",
2796 (Lang::Rust, -4) => "i32",
2797 (Lang::Rust, 1) => "u8",
2798 (Lang::Rust, 2) => "u16",
2799 (Lang::Rust, 4) => "u32",
2800 (Lang::Rust, _) => "isize",
2801 }
2802}
2803
2804#[derive(Debug)]
2806pub struct LemonMint
2807{ symbols: Symbols,
2808 rules: Vec<Rule>, states: States,
2810 token_type: String, vartype: String, start_name: String, start_type: String,
2814 extra_argument_type: String,
2815 extracode: String,
2816 minor_type: Vec<(String, String)>,
2817 token: Vec<Arc<String>>,
2818
2819 sz_code_type: isize,
2820 sz_action_type: isize,
2821 sz_shift_offset_type: isize,
2822 sz_reduce_offset_type: isize,
2823
2824 n_symbols: usize,
2825 n_states: usize,
2826 n_no_tail: usize,
2827 n_fallbacks: usize,
2828 error_symbol: usize,
2829 #[allow(dead_code)] with_fallback: bool,
2830 shift_count: usize,
2831 reduce_count: usize,
2832 with_trace: bool,
2833 trace_prompt: String, shift_min: isize,
2835 shift_max: isize,
2836 reduce_min: isize,
2837 reduce_max: isize,
2838
2839 n_terminals: usize,
2840 #[allow(dead_code)] n_nonterminals: usize,
2841 #[allow(dead_code)] tables_size: usize, n_action_table_entries: usize, lookahead_and_action: Vec<(usize, usize)>,
2845 shift_offset: Vec<isize>,
2846 reduce_offset: Vec<isize>,
2847 default: Vec<usize>,
2848 fallback: Vec<(usize, Arc<String>, Arc<String>)>,
2849 token_names: Vec<Arc<String>>,
2850}
2851impl LemonMint
2852{ pub fn gen_rust<W>(&self, out: &mut W) -> io::Result<()> where W: io::Write
2854 { writeln!(out, "pub mod code {{")?;
2855
2856 let mut lempar_reader = LemparReader::new();
2857 lempar_reader.copy_part(out)?; writeln!(out, "pub type TokenValue = {};", if !self.token_type.is_empty() {&self.token_type} else {"String"})?;
2861 writeln!(out, "pub type ExtraArgumentType = {};", if !self.extra_argument_type.is_empty() {&self.extra_argument_type} else {"()"})?;
2862 writeln!(out, "pub type StartType = {};", if !self.start_type.is_empty() {&self.start_type} else {"()"})?;
2863 writeln!(out, "type CodeType = {};", size_type_to_str(Lang::Rust, self.sz_code_type))?;
2864 writeln!(out, "type ActionType = {};", size_type_to_str(Lang::Rust, self.sz_action_type))?;
2865 writeln!(out, "type ShiftOffsetType = {};", size_type_to_str(Lang::Rust, self.sz_shift_offset_type))?;
2866 writeln!(out, "type ReduceOffsetType = {};", size_type_to_str(Lang::Rust, self.sz_reduce_offset_type))?;
2867
2868 write!(out, "enum MinorType\n{{")?;
2869 for (variant, typ) in self.minor_type.iter()
2870 { if typ.is_empty()
2871 { writeln!(out, "\t{},", variant)?;
2872 }
2873 else
2874 { writeln!(out, "\t{}({}),", variant, typ)?;
2875 }
2876 }
2877 writeln!(out, "}}")?;
2878
2879 writeln!(out, "#[repr(u32)]\n#[derive(Copy, Clone, PartialEq)]\n#[allow(non_camel_case_types)]")?;
2881 write!(out, "pub enum Token\n{{")?;
2882 for (i, name) in self.token.iter().enumerate()
2883 { if self.token_type.is_empty()
2884 { writeln!(out, "\t{:<30} = {:2},", name, i+1)?;
2885 }
2886 else
2887 { writeln!(out, "\t{:<30} = {:2},", name, i+1)?;
2888 }
2889 }
2890 writeln!(out, "}}\n")?;
2891
2892 writeln!(out, "const NO_CODE: CodeType = {}; // YYNOCODE", self.n_symbols)?;
2894 writeln!(out, "const N_STATES: usize = {}; // YYNSTATE", self.n_no_tail)?;
2895 writeln!(out, "const N_RULES: usize = {}; // YYNRULE", self.rules.len())?;
2896 writeln!(out, "const N_TERMINALS: usize = {}; // YYNTOKEN", self.n_terminals)?;
2897 writeln!(out, "const MAX_SHIFT: usize = N_STATES-1; // YY_MAX_SHIFT")?;
2898 writeln!(out, "const MIN_SHIFTREDUCE: usize = {}; // YY_MIN_SHIFTREDUCE", self.n_states)?;
2899 writeln!(out, "const MAX_SHIFTREDUCE: usize = MIN_SHIFTREDUCE + N_RULES - 1; // YY_MAX_SHIFTREDUCE")?;
2900 writeln!(out, "const ERROR_ACTION: usize = MAX_SHIFTREDUCE + 1; // YY_ERROR_ACTION")?;
2901 writeln!(out, "const ACCEPT_ACTION: usize = ERROR_ACTION + 1; // YY_ACCEPT_ACTION")?;
2902 writeln!(out, "const NO_ACTION: usize = ACCEPT_ACTION + 1; // YY_NO_ACTION")?;
2903 writeln!(out, "const MIN_REDUCE: usize = NO_ACTION + 1; // YY_MIN_REDUCE")?;
2904 writeln!(out, "//const MAX_REDUCE: usize = MIN_REDUCE + N_RULES - 1; // YY_MAX_REDUCE")?;
2905 writeln!(out, "const ERROR_SYMBOL: CodeType = {}; // YYERRORSYMBOL", self.error_symbol)?;
2906 writeln!(out, "const WITH_FALLBACK: bool = {}; // YYFALLBACK", if self.n_fallbacks>0 {"true"} else {"false"})?;
2907 writeln!(out, "const SHIFT_COUNT: usize = {}; // YY_SHIFT_COUNT", self.shift_count)?;
2908 writeln!(out, "const REDUCE_COUNT: usize = {}; // YY_REDUCE_COUNT", self.reduce_count)?;
2909 writeln!(out, "//const SHIFT_MIN: i32 = {}; // YY_SHIFT_MIN", self.shift_min)?;
2910 writeln!(out, "//const SHIFT_MAX: i32 = {}; // YY_SHIFT_MAX", self.shift_max)?;
2911 writeln!(out, "//const REDUCE_MIN: i32 = {}; // YY_REDUCE_MIN", self.reduce_min)?;
2912 writeln!(out, "//const REDUCE_MAX: i32 = {}; // YY_REDUCE_MAX", self.reduce_max)?;
2913 writeln!(out, "const ACTTAB_COUNT: usize = {}; // YY_ACTTAB_COUNT", self.n_action_table_entries)?;
2914 writeln!(out, "const TRACE: bool = {};", if self.with_trace {"true"} else {"false"})?;
2915
2916 if self.trace_prompt.chars().position(|c| c=='\\' || c=='"').is_none()
2918 { writeln!(out, "const TRACE_PROMPT: &str = \"{}\";", self.trace_prompt)?;
2919 }
2920 else
2921 { let mut tag = String::with_capacity(self.trace_prompt.len()+1);
2922 for _i in 0 .. self.trace_prompt.len()+1
2923 { tag.push('#');
2924 if !self.trace_prompt.contains(&tag)
2925 { break;
2926 }
2927 }
2928 writeln!(out, "const TRACE_PROMPT: &str = r{tag}\"{}\"{tag};", self.trace_prompt, tag=tag)?;
2929 }
2930
2931 write!(out, "const LOOKAHEAD_AND_ACTION: [LookaheadAndAction; {}] =", self.lookahead_and_action.len())?;
2944 let mut formatter = ArrayFormatter::new(2);
2945 for (lookahead, action) in self.lookahead_and_action.iter()
2946 { formatter.separ(out)?;
2947 write!(out, "LookaheadAndAction {{lookahead: {:4}, action: {:4}}}", lookahead, action)?;
2948 }
2949 formatter.end(out)?;
2950
2951 write!(out, "const SHIFT_OFFSET: [ShiftOffsetType; {}] =", self.shift_offset.len())?;
2953 let mut formatter = ArrayFormatter::new(16);
2954 for offset in self.shift_offset.iter()
2955 { formatter.separ(out)?;
2956 write!(out, "{:4}", offset)?;
2957 }
2958 formatter.end(out)?;
2959
2960 write!(out, "const REDUCE_OFFSET: [ReduceOffsetType; {}] =", self.reduce_offset.len())?;
2962 let mut formatter = ArrayFormatter::new(16);
2963 for offset in self.reduce_offset.iter()
2964 { formatter.separ(out)?;
2965 write!(out, "{:4}", offset)?;
2966 }
2967 formatter.end(out)?;
2968
2969 write!(out, "const DEFAULT: [ActionType; {}] =", self.default.len())?;
2971 let mut formatter = ArrayFormatter::new(16);
2972 for action in self.default.iter()
2973 { formatter.separ(out)?;
2974 write!(out, "{:4}", action)?;
2975 }
2976 formatter.end(out)?;
2977
2978 lempar_reader.copy_part(out)?; write!(out, "const FALLBACK: [CodeType; {}] =", self.fallback.len())?;
2983 let mut formatter = ArrayFormatter::new(1);
2984 for (index, name, to_name) in self.fallback.iter()
2985 { formatter.separ(out)?;
2986 write!(out, "{:3} /* {:10} => {} */", index, name, to_name)?;
2987 }
2988 formatter.end(out)?;
2989
2990 lempar_reader.copy_part(out)?; write!(out, "const TOKEN_NAMES: [&str; {}] =", self.token_names.len())?;
2995 let mut formatter = ArrayFormatter::new(1);
2996 for name in self.token_names.iter()
2997 { formatter.separ(out)?;
2998 write!(out, "{:<15}", format!("\"{}\"", name))?;
2999 }
3000 formatter.end(out)?;
3001
3002 lempar_reader.copy_part(out)?; write!(out, "const RULE_NAMES: [&str; {}] =", self.rules.len())?;
3008 let mut formatter = ArrayFormatter::new(1);
3009 for rule in self.rules.iter()
3010 { formatter.separ(out)?;
3011 write!(out, "\"{}\"", rule)?;
3012 }
3013 formatter.end(out)?;
3014
3015 lempar_reader.copy_part(out)?; write!(out, "const RULES_INFO: [CodeType; {}] =", self.rules.len())?;
3021 let mut formatter = ArrayFormatter::new(16);
3022 for rule in &self.rules
3023 { formatter.separ(out)?;
3024 write!(out, "{:4}", rule.lhs_index)?;
3025 }
3026 formatter.end(out)?;
3027
3028 lempar_reader.copy_part(out)?; for rule in self.rules.iter()
3033 { if !rule.code.is_empty() { write!(out, "\t\t\t{} =>", rule.index)?;
3035 let has_data_type = !self.symbols.array[rule.lhs_index].data_type.is_empty();
3036 let mut next_indent = "\t\t\t\t";
3037 if has_data_type && !rule.lhs_start
3038 { write!(out, " MinorType::Symbol{}\n\t\t\t(\t{{", self.symbols.array[rule.lhs_index].dtnum)?;
3039 next_indent = "\t\t\t\t\t";
3040 }
3041 else
3042 { write!(out, "\n\t\t\t{{")?;
3043 }
3044 let mut indent = "\t";
3045 let mut n_aliases = 0;
3046 let n_args = rule.rhs.len();
3047 for i in (0 .. n_args).rev()
3048 { let has_alias = !rule.rhs[i].alias.is_empty();
3049 if has_alias
3050 { n_aliases += 1;
3051 writeln!(out, "{}let arg{} = self.stack.pop().unwrap();", indent, i+1)?;
3052 }
3053 else
3054 { writeln!(out, "{}self.stack.pop();", indent)?;
3055 }
3056 indent = next_indent;
3057 }
3058 if n_aliases > 0
3059 { write!(out, "{}{}match {}", indent, if rule.lhs_start {"let result = "} else {""}, if n_aliases>1 {"("} else {""})?;
3060 let mut comma = "";
3061 for i in 0 .. n_args
3062 { if !rule.rhs[i].alias.is_empty()
3063 { write!(out, "{}arg{}.minor", comma, i+1)?;
3064 comma = ", ";
3065 }
3066 }
3067 write!(out, "{}\n{}{{\t{}", if n_aliases>1 {")"} else {""}, indent, if n_aliases>1 {"("} else {""})?;
3068 comma = "";
3069 for (i, rhs) in rule.rhs.iter().enumerate()
3070 { if !rhs.alias.is_empty()
3071 { write!(out, "{}MinorType::Symbol{}(arg{})", comma, self.symbols.array[rhs.index].dtnum, i+1)?;
3072 comma = ", ";
3073 }
3074 }
3075 write!(out, "{} => super::rules::do_rule_{}(&mut self.extra", if n_aliases>1 {")"} else {""}, rule.index)?;
3076 for i in 0 .. n_args
3077 { if !rule.rhs[i].alias.is_empty()
3078 { write!(out, ", arg{}", i+1)?;
3079 }
3080 }
3081 if rule.lhs_start
3082 { 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)?;
3083 }
3084 else if has_data_type
3085 { writeln!(out, "),\n{}\t_ => unreachable!()\n{}}}\n\t\t\t\t}}\n\t\t\t),", indent, indent)?;
3086 }
3087 else
3088 { writeln!(out, "),\n{}\t_ => unreachable!()\n{}}};\n\t\t\t\tMinorType::None\n\t\t\t}},", indent, indent)?;
3089 }
3090 }
3091 else
3092 { if rule.lhs_start
3093 { 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)?;
3094 }
3095 else if has_data_type
3096 { writeln!(out, "{}super::rules::do_rule_{}(&mut self.extra)\n\t\t\t}}),", indent, rule.index)?;
3097 }
3098 else
3099 { writeln!(out, "{}super::rules::do_rule_{}(&mut self.extra);\n\t\t\t\tMinorType::None\n\t\t\t}},", indent, rule.index)?;
3100 }
3101 }
3102 }
3103 }
3104 writeln!(out, "\t\t\t_ =>\n\t\t\t{{\tself.stack.pop(); MinorType::None\n\t\t\t}}")?;
3106
3107 lempar_reader.copy_part(out)?; writeln!(out, "\n}}\n\n\nmod rules\n{{\tuse super::code::{{TokenValue, ExtraArgumentType}};")?;
3111 for rule in self.rules.iter()
3112 { let rule = rule;
3113 if !rule.code.is_empty()
3114 { write!(out, "\n\t/// {}\n", rule)?;
3115 write!(out, "\t#[inline]\n\t#[allow(non_snake_case, unused_variables)]\n")?;
3116 write!(out, "\tpub fn do_rule_{}(extra: &mut ExtraArgumentType", rule.index)?;
3117 for rhs in &rule.rhs
3118 { if !rhs.alias.is_empty()
3119 { let data_type = if rhs.index < self.n_terminals
3120 { "TokenValue"
3121 }
3122 else
3123 { &self.symbols.array[rhs.index].data_type
3124 };
3125 write!(out, ", {}: {}", rhs.alias, if data_type.is_empty() {"()"} else {data_type})?;
3126 }
3127 }
3128 write!(out, ")")?;
3129 let lhs = &self.symbols.array[rule.lhs_index];
3130 if !lhs.data_type.is_empty()
3131 { write!(out, " -> {}", lhs.data_type)?;
3132 }
3133 write!(out, "\n\t{{\t")?;
3134 let mut it = rule.code.chars();
3135'l: while let Some(mut c) = it.next()
3136 { 'm:while c == '\n'
3137 { write!(out, "\n\t\t")?;
3138 while let Some(c2) = it.next()
3139 { if c2=='\n' || !c2.is_ascii_whitespace()
3140 { c = c2;
3141 continue 'm;
3142 }
3143 }
3144 break 'l;
3145 }
3146 write!(out, "{}", c)?;
3147 }
3148 writeln!(out, "\n\t}}")?;
3149 }
3150 }
3151 writeln!(out, "}}\n")?;
3152
3153 lempar_reader.copy_part(out)?;
3155 if !self.extracode.is_empty()
3156 { writeln!(out, "\n\n{}", self.extracode)?;
3157 }
3158
3159 Ok(())
3160 }
3161
3162 pub fn gen_log<W>(&self, out: &mut W, basisflag: bool, show_precedence_conflict: bool) -> io::Result<()> where W: io::Write
3167 { for stp in self.states.array[0 .. self.states.n_no_tail].iter()
3168 { writeln!(out, "State {}:", stp.n_state)?;
3169
3170 for cfp in stp.configurations.iter()
3171 { if basisflag
3172 { let mut is_basis = false;
3173 for bp in stp.basis.iter()
3174 { if *cfp.borrow() == *bp.borrow()
3175 { is_basis = true;
3176 break;
3177 }
3178 }
3179 if !is_basis
3180 { continue;
3181 }
3182 }
3183 if cfp.borrow().dot == self.rules[cfp.borrow().n_rule].rhs.len()
3184 { let buf = format!("({})", self.rules[cfp.borrow().n_rule].index);
3185 write!(out, " {:>5} ", buf)?;
3186 }
3187 else
3188 { write!(out, " ")?;
3189 }
3190 Self::config_print(&self.rules, out, cfp)?;
3191 writeln!(out, "")?;
3192 }
3193
3194 writeln!(out, "")?;
3195 for action in stp.actions.iter()
3196 { if Self::print_action(&self.symbols, &self.rules, action, out, 30, show_precedence_conflict)?
3197 { writeln!(out, "")?;
3198 }
3199 }
3200 writeln!(out, "")?;
3201 }
3202 writeln!(out, "----------------------------------------------------")?;
3203 writeln!(out, "Symbols:")?;
3204 for i in 0 .. self.symbols.n_symbols
3205 { let sp = &self.symbols.array[i];
3206 write!(out, " {:>3}: {}", i, sp.name)?;
3207 if sp.typ == SymbolType::NONTERMINAL
3208 { write!(out, ":")?;
3209 if sp.lambda
3210 { write!(out, " <lambda>")?;
3211 }
3212 for j in 0 .. self.symbols.n_terminals
3213 { if sp.firstset.len()>0 && sp.firstset.contains(j)
3214 { write!(out, " {}", self.symbols.array[j].name)?;
3215 }
3216 }
3217 }
3218 writeln!(out, "")?;
3219 }
3220 Ok(())
3221 }
3222
3223 fn config_print<W>(rules: &Vec<Rule>, out: &mut W, cfp: &Rc<RefCell<Config>>) -> io::Result<()> where W: io::Write
3224 { write!(out, "{} ::=", rules[cfp.borrow().n_rule].lhs)?;
3225 for i in 0 ..= rules[cfp.borrow().n_rule].rhs.len()
3226 { if i == cfp.borrow().dot
3227 { write!(out, " *")?;
3228 }
3229 if i == rules[cfp.borrow().n_rule].rhs.len()
3230 { break;
3231 }
3232 write!(out, " {}", rules[cfp.borrow().n_rule].rhs[i].name)?;
3233 }
3234 Ok(())
3235 }
3236
3237 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
3239 { let mut result = false;
3240 match action.borrow().typ
3241 { ActionType::Shift =>
3242 { if let StateOrRule::State(n_state) = action.borrow().x
3243 { write!(out, "{:>w$} shift {:<7}", symbols.array[action.borrow().symbol_index].name, n_state, w=indent)?;
3244 result = true;
3245 }
3246 }
3247 ActionType::Reduce =>
3248 { if let StateOrRule::Rule(n_rule) = action.borrow().x
3249 { write!(out, "{:>w$} reduce {:<7}", symbols.array[action.borrow().symbol_index].name, rules[n_rule].index, w=indent)?;
3250 Self::rule_print(out, &rules[n_rule], std::usize::MAX)?;
3251 result = true;
3252 }
3253 }
3254 ActionType::ShiftReduce =>
3255 { if let StateOrRule::Rule(n_rule) = action.borrow().x
3256 { write!(out, "{:>w$} shift-reduce {:<7}", symbols.array[action.borrow().symbol_index].name, rules[n_rule].index, w=indent)?;
3257 Self::rule_print(out, &rules[n_rule], std::usize::MAX)?;
3258 result = true;
3259 }
3260 }
3261 ActionType::Accept =>
3262 { write!(out, "{:>w$} accept", symbols.array[action.borrow().symbol_index].name, w=indent)?;
3263 result = true;
3264 }
3265 ActionType::Error =>
3266 { write!(out, "{:>w$} error", symbols.array[action.borrow().symbol_index].name, w=indent)?;
3267 result = true;
3268 }
3269 ActionType::SrConflict | ActionType::RrConflict =>
3270 { if let StateOrRule::Rule(n_rule) = action.borrow().x
3271 { write!(out, "{:>w$} reduce {:<7} ** Parsing conflict **", symbols.array[action.borrow().symbol_index].name, rules[n_rule].index, w=indent)?;
3272 result = true;
3273 }
3274 }
3275 ActionType::SsConflict =>
3276 { if let StateOrRule::State(n_state) = action.borrow().x
3277 { write!(out, "{:>w$} shift {:<7} ** Parsing conflict **", symbols.array[action.borrow().symbol_index].name, n_state, w=indent)?;
3278 result = true;
3279 }
3280 }
3281 ActionType::ShResolved =>
3282 { if show_precedence_conflict
3283 { if let StateOrRule::State(n_state) = action.borrow().x
3284 { write!(out, "{:>w$} shift {:<7} -- dropped by precedence", symbols.array[action.borrow().symbol_index].name, n_state, w=indent)?;
3285 result = true;
3286 }
3287 }
3288 }
3289 ActionType::RdResolved =>
3290 { if show_precedence_conflict
3291 { if let StateOrRule::Rule(n_rule) = action.borrow().x
3292 { write!(out, "{:>w$} reduce {:<7} -- dropped by precedence", symbols.array[action.borrow().symbol_index].name, rules[n_rule].index, w=indent)?;
3293 result = true;
3294 }
3295 }
3296 }
3297 ActionType::NotUsed => {}
3298 }
3299 Ok(result)
3300 }
3301
3302 fn rule_print<W>(out: &mut W, rule: &Rule, cursor: usize) -> io::Result<()> where W: io::Write
3304 { write!(out, "{} ::=", rule.lhs)?;
3305 for (i, symbol) in rule.rhs.iter().enumerate()
3306 { if i == cursor
3307 { write!(out, " *")?;
3308 }
3309 write!(out, " {}", symbol.name)?;
3310 }
3311 if cursor == rule.rhs.len()
3312 { write!(out, " *")?;
3313 }
3314 Ok(())
3315 }
3316
3317 pub fn gen_y<W>(&self, out: &mut W) -> io::Result<()> where W: io::Write
3319 { writeln!(out, "// Symbols:")?;
3320 let mut maxlen = 10;
3321 for sp in self.symbols.array[0 .. self.symbols.n_symbols].iter()
3322 { if sp.name.len() > maxlen
3323 { maxlen = sp.name.len();
3324 }
3325 }
3326 let mut ncolumns = 76 / (maxlen+5);
3327 if ncolumns < 1
3328 { ncolumns = 1;
3329 }
3330 let skip = (self.symbols.n_symbols+ncolumns-1) / ncolumns;
3331 for i in 0 .. skip
3332 { write!(out, "//")?;
3333 for j in (i .. self.symbols.n_symbols).step_by(skip)
3334 { let sp = &self.symbols.array[j];
3335 assert_eq!(sp.index, j);
3336 write!(out, " {:3} {:<w$}", maxlen, sp.name, w=maxlen)?;
3337 }
3338 writeln!(out, "")?;
3339 }
3340 writeln!(out, "")?;
3341 if !self.start_name.is_empty()
3343 { writeln!(out, "%start_symbol {{{}}}", self.start_name)?;
3344 }
3345 if !self.token_type.is_empty()
3347 { writeln!(out, "%token_type {{{}}}", self.token_type)?;
3348 }
3349 if !self.vartype.is_empty()
3351 { writeln!(out, "%default_type {{{}}}", self.vartype)?;
3352 }
3353 if !self.extra_argument_type.is_empty()
3355 { writeln!(out, "%extra_argument {{{}}}", self.extra_argument_type)?;
3356 }
3357 let mut prec = 0;
3359 loop
3360 { let mut has_greater_prec = false;
3361 let mut started = false;
3362 for symbol in self.symbols.array[1 .. self.symbols.n_terminals].iter()
3363 { if symbol.prec >= prec
3364 { if symbol.prec > prec
3365 { has_greater_prec = true;
3366 }
3367 else
3368 { if !started
3369 { write!(out, "{}", if symbol.assoc== Associativity::LEFT {"%left"} else if symbol.assoc== Associativity::RIGHT {"%right"} else {"%nonassoc"})?;
3370 started = true;
3371 }
3372 write!(out, " {}", symbol.name)?;
3373 }
3374 }
3375 }
3376 if started
3377 { writeln!(out, ".")?;
3378 }
3379 if !has_greater_prec
3380 { break;
3381 }
3382 prec += 1;
3383 }
3384 for symbol in self.symbols.array[self.symbols.n_terminals+1 .. self.symbols.n_symbols].iter()
3386 { let symbol = symbol;
3387 writeln!(out, "%type {} {{{}}}", symbol.name, symbol.data_type)?;
3388 }
3389 for rule in self.rules.iter()
3391 { write!(out, "{}", rule.lhs)?;
3392 if self.symbols.array[rule.lhs_index].dtnum != 0
3393 { write!(out, "(RESULT)")?;
3394 }
3395 write!(out, " ::=")?;
3396 for sp in &rule.rhs
3397 { write!(out, " {}", sp.name)?;
3398 if !sp.alias.is_empty()
3399 { write!(out, "({})", sp.alias)?;
3400 }
3401 }
3402 write!(out, ".")?;
3403 if rule.precsym_index != std::usize::MAX
3404 { write!(out, " [{}]", self.symbols.array[rule.precsym_index].name)?;
3405 }
3406 if !rule.code.is_empty()
3407 { writeln!(out, " {{\n{}\n}}", rule.code)?;
3408 }
3409 writeln!(out, "")?;
3410 }
3411 Ok(())
3412 }
3413}
3414impl TryFrom<LemonMintBuilder> for LemonMint
3415{ type Error = LemonMintError;
3416
3417 fn try_from(builder: LemonMintBuilder) -> ParserResult<Self>
3418 { builder.try_into_lemon()
3419 }
3420}
3421
3422#[cfg(not(feature = "with-debug"))]
3423fn dump_symbols(_symbols: &Symbols, _rules: &Vec<Rule>)
3424{
3425}
3426
3427#[cfg(not(feature = "with-debug"))]
3428fn dump_states(_states: &States, _rules: &Vec<Rule>, _symbols: &Symbols, _n: i32)
3429{
3430}
3431
3432#[cfg(feature = "with-debug")]
3433fn dump_symbols(symbols: &Symbols, rules: &Vec<Rule>)
3434{ use std::io::prelude::*;
3435 let mut out = File::create("/tmp/symbols-rust.js").unwrap();
3436 for s in symbols.array.iter()
3437 { writeln!(out, "{} ({}) {:?} #{} {:?} {} {}LAM:", s.name, s.index, s.typ, s.dtnum, s.assoc, s.prec, if s.lambda {""} else {"!"}).unwrap();
3438 if s.firstset.len() > 0
3439 { write!(out, " ").unwrap();
3440 for (j, v) in s.firstset.data.iter().enumerate()
3441 { write!(out, "{}{}", if j%4==0&&j>0 {" "} else {""}, if *v {'y'} else {'n'}).unwrap();
3442 }
3443 writeln!(out).unwrap();
3444 }
3445 for n_rule in s.sym_rules_arr.iter()
3446 { let rule = &rules[*n_rule];
3447 writeln!(out, " {} = {}", rule.index, rule.code).unwrap();
3448 }
3449 }
3450 }
3477
3478#[cfg(feature = "with-debug")]
3479fn dump_states(states: &States, rules: &Vec<Rule>, symbols: &Symbols, n: i32)
3480{ use std::io::prelude::*;
3481 let mut out = File::create(format!("/tmp/states-{}-rust.js", n)).unwrap();
3482 for s in states.array.iter()
3483 { writeln!
3484 ( out,
3485 "{}. nTknAct={}, nNtAct={}, iTknOfst={}, iNtOfst={}, iDfltReduce={}, {} dfR{}[{}]",
3486 s.n_state,
3487 s.n_token_act,
3488 s.n_nt_act,
3489 if s.token_offset==std::isize::MIN {-1000} else {s.token_offset},
3490 if s.nt_offset==std::isize::MIN {-1000} else {s.nt_offset},
3491 if s.default_reduce_action==std::usize::MAX {-1} else {s.default_reduce_action as isize},
3492 if s.auto_reduce {"A"} else {"!A"},
3493 if s.default_reduce_rule==std::usize::MAX {-1} else {s.default_reduce_rule as isize},
3494 if s.default_reduce_rule==std::usize::MAX {"".to_string()} else {rules[s.default_reduce_rule].lhs.to_string()}
3495 ).unwrap();
3496 for cfp in s.basis.iter()
3497 { let cfp = cfp.borrow();
3498 writeln!(out, " bs{} R{}[{}] .{}", cfp.n_state as isize, cfp.n_rule, rules[cfp.n_rule].lhs, cfp.dot).unwrap();
3499 }
3500 for cfp in s.configurations.iter()
3501 { let cfp = cfp.borrow();
3502 writeln!(out, " cf{} R{}[{}] .{}", cfp.n_state as isize, cfp.n_rule, rules[cfp.n_rule].lhs, cfp.dot).unwrap();
3504 let mut delim = "";
3506 write!(out, "{:<12}[", "").unwrap();
3507 for (j, v) in cfp.fws.data.iter().enumerate()
3508 { if *v
3509 { write!(out, "{}{}", delim, symbols.array[j].name).unwrap();
3510 delim = " ";
3511 }
3512 }
3513 writeln!(out, "]").unwrap();
3514 for cfp in cfp.fplp.iter()
3516 { write!(out, "{:<12}{} (state {:2}) ", "", "To ", cfp.borrow().n_state as isize).unwrap();
3517 LemonMint::config_print(rules, &mut out, cfp).unwrap();
3518 writeln!(out).unwrap();
3519 }
3520 for cfp in cfp.bplp.iter()
3522 { write!(out, "{:<12}{} (state {:2}) ", "", "From", cfp.borrow().n_state as isize).unwrap();
3523 LemonMint::config_print(rules, &mut out, cfp).unwrap();
3524 writeln!(out).unwrap();
3525 }
3526 }
3527 for action in s.actions.iter()
3528 { if LemonMint::print_action(symbols, rules, action, &mut out, 30, true).unwrap()
3529 { writeln!(out).unwrap();
3530 }
3531 }
3532 }
3533 }