1#![allow(unused_imports)]
2#![allow(unused_variables)]
3#![allow(unused_mut)]
4#![allow(dead_code)]
5
6
7use std::collections::HashMap;
8use std::collections::HashSet;
9use std::collections::BTreeMap;
10use std::collections::hash_map::Entry::{Occupied, Vacant};
11use std::sync::mpsc::{Sender, Receiver};
12use std::sync::mpsc;
13use std::thread;
14
15use std::collections::VecDeque;
16use std::rc::{Rc, Weak};
17use std::sync::Arc;
18use std::cell::RefCell;
19use std::mem;
20
21use glr_grammar;
22use glr_lex;
23use glr_grammar::Atom as Atom;
24use glr_lex::Lex as Lex;
25use glr_grammar::GrammarItem as GrammarItem;
26
27#[derive(Clone,Hash,PartialEq,Eq,Ord,PartialOrd,Debug)]
40pub struct LRItem {
41 pub stacktop: u8,
42 pub terminal: Arc<Atom>,
43 pub symbol: Arc<Atom>,
44 pub production: Vec<Arc<Atom>>
45}
46
47
48
49pub fn create_grammars_hashmap(grammars: Vec<Box<GrammarItem>>) -> HashMap<String, Vec<Arc<GrammarItem>>>{
50 let mut grammars_hashmap: HashMap<String, Vec<Arc<GrammarItem>>> = HashMap::new();
51
52 for item in grammars {
53 let symbol_name = glr_grammar::get_atom_string(item.clone().symbol);
54
55 if !grammars_hashmap.contains_key(&symbol_name) {
56 grammars_hashmap.insert(symbol_name.clone(), vec![]);
57 }
58 match grammars_hashmap.entry(symbol_name) {
59 Occupied(entry) => {
60 entry.into_mut().push(Arc::new(*item));
61 },
62 _ => {}
63 }
64 }
65
66 grammars_hashmap
67}
68
69
70
71fn get_first(grammars_hashmap: &HashMap<String, Vec<Arc<GrammarItem>>>, symbol: Arc<Atom>) -> Vec<Arc<Atom>> {
72 let mut ret: Vec<Arc<Atom>> = vec![];
73 let mut symbols: Vec<Arc<Atom>> = vec![symbol.clone()];
74 let mut symbols_expanded: HashSet<Arc<Atom>> = HashSet::new();
75 loop {
76 let current_symbol = match symbols.pop() {Some(x) => x, None => break};
77
78 match *current_symbol {
79 Atom::Symbol(ref x) => {
80 if let Some(grammars) = grammars_hashmap.get(&**x) {
81 for each_grammar in grammars {
82 let mut offsets: Vec<u8> = find_solid_indexes(&grammars_hashmap, &each_grammar.production, 0, vec![0u8]);
83 let offsets_len = offsets.len();
84 offsets.push(offsets_len as u8);
85
86 for offset in offsets {
87 if let Some(__symbol) = each_grammar.production.get(offset as usize) {
88 let _symbol = __symbol.clone();
89
90 if !symbols_expanded.contains(&_symbol) {
91 symbols.push(_symbol.clone());
92 symbols_expanded.insert(_symbol);
93 }
94 }
95 }
96 }
97 }
98 },
99 Atom::Terminal(ref x) => {
100 ret.push(current_symbol.clone());
101 }
102 }
103 }
104
105 ret
107 }
135
136fn get_real_productions(grammars_hashmap: &HashMap<String, Vec<Arc<GrammarItem>>>,
166 production: &Vec<Arc<Atom>>,
167 mut real_prod_cache: &mut HashMap<Vec<Arc<Atom>>, Vec<Vec<Arc<Atom>>>>) -> Vec<Vec<Arc<Atom>>> {
168
169 match real_prod_cache.entry(production.clone()) {
170 Occupied(entry) => {
171 entry.get().clone()
172 },
173 Vacant(entry) => {
174 let mut ret: Vec<Vec<Arc<Atom>>> = vec![vec![]];
175 for item in production.iter() {
176 let mut split = false;
177 match **item {
178 Atom::Symbol(ref x) => {
179 if let Some(atom_str) = x.find('~') {
180 if let Some(grammar_items) = grammars_hashmap.get(&**x) {
181 for item in grammar_items {
182 if item.production.len() == 0 {
183 split = true;
184 break;
185 }
186 }
187 }
188 }
189 },
190 Atom::Terminal(ref x) => {}
191 }
192
193 if !split {
194 for each_ret in &mut ret {
195 each_ret.push(item.clone());
196 }
197 } else {
198 let mut ret_extend: Vec<Vec<Arc<Atom>>> = vec![];
199 for each_ret in ret.iter() {
200 ret_extend.push(each_ret.clone());
201 }
202
203 for each_ret in &mut ret {
204 each_ret.push(item.clone());
205 }
206
207 ret.extend(ret_extend);
208 }
209 }
210
211 entry.insert(ret.clone());
212 ret
213 }
214 }
215}
216fn find_solid_indexes(grammars_hashmap: &HashMap<String, Vec<Arc<GrammarItem>>>,
217 production: &Vec<Arc<Atom>>,
218 start_index: u8,
219 initial_offset: Vec<u8>) -> Vec<u8>{
220
221 let initial_len: u8 = match initial_offset.get(0) {Some(x) => *x, None => 0};
222 let mut offsets: Vec<u8> = initial_offset;
223
224 loop {
225 let mut break_loop = true;
226 if let Some(atom) = production.get((start_index + offsets.len() as u8) as usize) {
227 match **atom {
228 Atom::Symbol(ref x) => {
229 if let Some(grammar_items) = grammars_hashmap.get(&**x) {
230 for item in grammar_items {
231 if item.production.len() == 0 {
232 let len = offsets.len();
233 offsets.push(len as u8 + initial_len);
234 break_loop = false;
235 break;
236 }
237 }
238 }
239 },
240 Atom::Terminal(_) => {}
241 }
242
243 }
244 if break_loop {break}
245 }
246
247 return offsets;
248}
249
250fn get_closure(grammars_hashmap: &HashMap<String, Vec<Arc<GrammarItem>>>,
251 initial_items: Vec<Arc<LRItem>>,
252 mut firsts: &mut HashMap<Arc<String>, Vec<Arc<Atom>>>,
253 mut real_prod_cache: &mut HashMap<Vec<Arc<Atom>>, Vec<Vec<Arc<Atom>>>>) -> Vec<Arc<LRItem>> {
254
255 let mut ret: Vec<Arc<LRItem>> = Vec::new();
256 let mut ret_cache: HashSet<Arc<LRItem>> = HashSet::new();
257
258 let mut working_items = initial_items;
260
261 loop {
262 let mut loop_item = match working_items.pop() {Some(x) => x, None => break};
263
264 if !ret_cache.contains(&loop_item) {
265 let new_lr_item = Arc::new(LRItem {
266 stacktop: loop_item.stacktop,
267 terminal: loop_item.terminal.clone(),
268 symbol: loop_item.symbol.clone(),
269 production: loop_item.production.clone()
270 });
271 ret.push(new_lr_item.clone());
272 ret_cache.insert(new_lr_item);
273 }
274 let mut terminals: Vec<Arc<Atom>> = vec![];
277 let mut offsets: Vec<u8> = find_solid_indexes(&grammars_hashmap, &loop_item.production, loop_item.stacktop, vec![1u8]);
278
279 for stacktop_offset in offsets {
280 terminals.extend(match loop_item.production.get((loop_item.stacktop + stacktop_offset) as usize) {
281 Some(atom) => {
282 let atom_string = match **atom {Atom::Symbol(ref x) => x, Atom::Terminal(ref x) => x};
283
284 match firsts.entry(atom_string.clone()) {
285 Occupied(entry) => {
286 let mut _ret: Vec<Arc<Atom>> = vec![];
287 for item in entry.into_mut().iter() {
288 _ret.push(item.clone());
289 }
290 _ret
291 },
292 Vacant(entry) => {
293 let new_first = get_first(grammars_hashmap, atom.clone());
294 let mut atoms: Vec<Arc<Atom>> = Vec::new();
295 for item in new_first.iter() {
296 atoms.push(item.clone());
297 }
298 entry.insert(atoms);
299 new_first
300 }
301 }
302
303 },
304 None => vec![loop_item.terminal.clone()]
305 });
306 }
307
308
309 let expand_symbol = match loop_item.production.get(loop_item.stacktop as usize) { Some(atom) => { atom }, None => continue };
310 let symbol_name = glr_grammar::get_atom_string(expand_symbol.clone());
311
312 match grammars_hashmap.get(&symbol_name) {
313 Some(grammer_items) => {
314 for each_grammar in grammer_items.iter() {
315 for each_production in get_real_productions(&grammars_hashmap, &each_grammar.production, &mut real_prod_cache).iter() {
316 for terminal_atom in terminals.iter() {
317 let lr_item = Arc::new(LRItem {
318 stacktop: 0,
319 terminal: terminal_atom.clone(),
320 symbol: each_grammar.symbol.clone(),
321 production: each_production.clone()
322 });
323 if !ret_cache.contains(&lr_item) {
324 working_items.push(lr_item);
325 }
326 }
327 }
328 }
329 },
330 None => {}
331 }
332
333 }
334
335 ret
336}
337
338fn goto(grammars_hashmap: &HashMap<String, Vec<Arc<GrammarItem>>>,
367 cc: &Vec<Arc<LRItem>>,
368 goto_atom: Arc<Atom>,
369 mut firsts: &mut HashMap<Arc<String>, Vec<Arc<Atom>>>,
370 goto_cache: &mut HashMap<Vec<Arc<LRItem>>, Vec<Arc<LRItem>>>,
371 mut real_prod_cache: &mut HashMap<Vec<Arc<Atom>>, Vec<Vec<Arc<Atom>>>>) -> Vec<Arc<LRItem>>{
372
373 let mut ret: Vec<Arc<LRItem>> = Vec::new();
374 for item in cc.iter() {
377 match item.production.get(item.stacktop as usize) {
378 None => {},
379 Some(x) => {
380 if *x == goto_atom {
382 ret.push(Arc::new(LRItem {
383 stacktop: item.stacktop + 1u8,
384 symbol: item.symbol.clone(),
385 terminal: item.terminal.clone(),
386 production: item.production.clone()
387 }));
388 }
389 }
390 }
391 }
392
393 match goto_cache.entry(ret.clone()) {
395 Occupied(entry) => {
396 entry.get().clone()
397 },
398 Vacant(entry) => {
399 ret = get_closure(&grammars_hashmap, ret, &mut firsts, &mut real_prod_cache);
400 ret.sort_by(|a, b| b.cmp(a));
401 entry.insert(ret.clone());
402 ret
403 }
404 }
405
406
407}
408
409#[derive(Debug,Clone,Hash,PartialEq,Eq,PartialOrd,Ord)]
419pub enum Action { Reduce, Shift }
420#[derive(Debug,Clone,Hash,PartialEq,Eq,PartialOrd,Ord)]
421pub struct TableItem {
422 state: u32,
423 lr_item: Option<Arc<GrammarItem>>,
424 action: Arc<Action>
425}
426pub fn create_table(grammars_hashmap: &HashMap<String, Vec<Arc<GrammarItem>>>, initial_item: Arc<LRItem>) -> (Vec<HashMap<String, HashSet<Arc<TableItem>>>>, Vec<HashMap<String, u32>>) {
427 let mut firsts: HashMap<Arc<String>, Vec<Arc<Atom>>> = HashMap::new();
428 let mut goto_cache: HashMap<Vec<Arc<LRItem>>, Vec<Arc<LRItem>>> = HashMap::new();
429 let mut real_prod_cache: HashMap<Vec<Arc<Atom>>, Vec<Vec<Arc<Atom>>>> = HashMap::new();
430
431 let mut action_table: Vec<HashMap<String, HashSet<Arc<TableItem>>>> = Vec::new();
432 let mut goto_table: Vec<HashMap<String, u32>> = Vec::new();
433
434 let mut cc0 = get_closure(&grammars_hashmap, vec![initial_item], &mut firsts, &mut real_prod_cache);
435 cc0.sort_by(|a, b| b.cmp(a));
436
437 let mut working_ccs: Vec<Vec<Arc<LRItem>>> = Vec::new();
438 let mut working_ccs_hashmap: HashMap<Vec<Arc<LRItem>>, u32> = HashMap::new();
439
440
441 working_ccs.push(cc0.clone());
442 working_ccs_hashmap.insert(cc0, 0);
443
444 let mut cc_index = 0u32;
445 let mut cc_to_append: Vec<Vec<Arc<LRItem>>> = Vec::new();
446 loop {
447 let mut _append_count = 0u32;
448 for item in cc_to_append.iter() {
449 working_ccs.push(item.clone());
450 working_ccs_hashmap.insert(item.clone(), working_ccs.len() as u32 - 1);
451 }
452 cc_to_append.clear();
453
454 let mut loop_cc = match working_ccs.get(cc_index as usize) { Some(x) => x, None => break };
455
456 let mut new_action: HashMap<String, HashSet<Arc<TableItem>>> = HashMap::new();
457 let mut new_goto: HashMap<String, u32> = HashMap::new();
458
459 let mut next_cache: HashSet<Arc<Atom>> = HashSet::new();
460
461 for item in loop_cc.iter() {
463 let _state: u32 = working_ccs.len() as u32 + cc_to_append.len() as u32;
464 match item.production.get(item.stacktop as usize) {
465 None => { match *item.terminal {
467 Atom::Symbol(ref x) => {},
468 Atom::Terminal(ref x) => {
469 let new_action_item = Arc::new(TableItem {state: 0, action: Arc::new(Action::Reduce), lr_item: Some(Arc::new(GrammarItem {
470 symbol: item.symbol.clone(),
471 production: item.production.clone()
472 }))});
473
474 match new_action.entry((&x).to_string()) {
475 Occupied(entry) => {
476 if item.production.len() > 0 {
477 let mut m_entry = entry.into_mut();
478 if !m_entry.contains(&new_action_item) {
479 m_entry.insert(new_action_item);
480 }
481 }
482 },
483 Vacant(entry) => {
484 let mut _new_set = HashSet::new();
485 _new_set.insert(new_action_item);
486 entry.insert(_new_set);
487 }
488 }
489 }
490 }
491 },
492 Some(x) => { if next_cache.contains(x) {
494 continue
495 } else {
496 next_cache.insert(x.clone());
497 }
498
499 let mut new_cc = goto(&grammars_hashmap, &loop_cc, x.clone(), &mut firsts, &mut goto_cache, &mut real_prod_cache);
516
517 if let Some(index) = working_ccs_hashmap.get(&new_cc) {
518 match **x {
519 Atom::Symbol(ref x) => {
520 new_goto.insert((&x).to_string(), *index);
521
522 },
540 Atom::Terminal(ref x) => {
541 let new_action_item = Arc::new(TableItem {state: *index, action: Arc::new(Action::Shift), lr_item: None});
542
543 match new_action.entry((&x).to_string()) {
544 Occupied(entry) => {
545 let mut m_entry = entry.into_mut();
546 if !m_entry.contains(&new_action_item) {
547 m_entry.insert(new_action_item);
548 }
549 },
550 Vacant(entry) => {
551 let mut _new_set = HashSet::new();
552 _new_set.insert(new_action_item);
553 entry.insert(_new_set);
554 }
555 }
556 }
557 }
558 } else {
559 cc_to_append.push(new_cc);
560
561 match **x {
562 Atom::Symbol(ref x) => {
563 new_goto.insert((&x).to_string(), _state);
564
565
566 },
592 Atom::Terminal(ref x) => {
593 let new_action_item = Arc::new(TableItem {state: _state, action: Arc::new(Action::Shift), lr_item: None});
594
595 match new_action.entry((&x).to_string()) {
596 Occupied(entry) => {
597 let mut m_entry = entry.into_mut();
598 if !m_entry.contains(&new_action_item) {
599 m_entry.insert(new_action_item);
600 }
601 },
602 Vacant(entry) => {
603 let mut _new_set = HashSet::new();
604 _new_set.insert(new_action_item);
605 entry.insert(_new_set);
606 }
607 }
608
609 }
610 }
611
612 }
613 }
617 }
618 }
619
620 action_table.push(new_action);
622 goto_table.push(new_goto);
623
624 cc_index += 1;
625 }
626
627 (action_table, goto_table)
628}
629
630#[derive(Debug,Clone)]
631pub struct SyntaxTreeNode {
632 pub value: Option<Arc<String>>,
633 pub symbol: Arc<String>,
634 pub children: Option<VecDeque<Box<SyntaxTreeNode>>>
636}
637
638
639impl Drop for SyntaxTreeNode {
640 fn drop(&mut self) {
641 let mut childrens: Vec<Option<VecDeque<Box<SyntaxTreeNode>>>> = vec![mem::replace(&mut self.children, None)];
642
643 loop {
644 match childrens.pop() {
645 Some(n) => {
646 match n {
647 Some(mut x) => {
648 for item in x {
649 let mut _item = item;
650 childrens.push(mem::replace(&mut _item.children, None));
651 }
652 },
653 None => {}
654 }
655 },
656 None => break
657 }
658 }
659
660
661 }
662}
663
664struct StateStackMark(*mut HashSet<Vec<u32>>);
665unsafe impl Send for StateStackMark{}
666pub fn parse(words: Vec<Arc<Lex>>, action: Vec<HashMap<String, HashSet<Arc<TableItem>>>>, goto: Vec<HashMap<String, u32>>) -> Vec<VecDeque<Box<SyntaxTreeNode>>>{
667
668 fn _parse(words: Vec<Arc<Lex>>,
669 action: Vec<HashMap<String, HashSet<Arc<TableItem>>>>,
670 goto: Vec<HashMap<String, u32>>,
671 tree_stack: VecDeque<Box<SyntaxTreeNode>>,
672 state_stack: Vec<u32>,
673 word_stack: Vec<Arc<String>>,
674 word_index: u32,
675 curr_lex: Arc<Lex>,
676 curr_word: Arc<String>,
677 curr_value: Option<Arc<String>>,
678 state: u32,
679 cut_count: Vec<u32>,
680 _table_items: Option<HashSet<Arc<TableItem>>>,
681 state_stack_mark: HashSet<Vec<u32>>) -> Vec<VecDeque<Box<SyntaxTreeNode>>>{
682
683 let mut tree_stack = tree_stack;
684 let mut state_stack = state_stack;
685 let mut word_stack = word_stack;
686 let mut word_index = word_index;
687 let mut curr_lex = curr_lex;
688 let mut curr_word = curr_word;
689 let mut curr_value =curr_value;
690 let mut state = state;
691 let mut cut_count = cut_count;
692 let mut _table_items = _table_items;
693 let mut state_stack_mark = state_stack_mark;
694
695 let mut paralle_trees: Vec<VecDeque<Box<SyntaxTreeNode>>> = Vec::new();
696
697 let (tx, rx): (Sender<Vec<VecDeque<Box<SyntaxTreeNode>>>>, Receiver<Vec<VecDeque<Box<SyntaxTreeNode>>>>) = mpsc::channel();
705 let mut spawn_count = 0u32;
706 loop {
707
708 if let Some(ref table_items) = _table_items {
709 if table_items.len() > 1 {
710
711 for table_item in table_items.iter() {
714 let __words = words.clone();
715 let __action = action.clone();
716 let __goto = goto.clone();
717 let __tree_stack = tree_stack.clone();
718 let __state_stack = state_stack.clone();
719 let __word_stack = word_stack.clone();
720 let __word_index = word_index.clone();
721 let __curr_lex = curr_lex.clone();
722 let __curr_word = curr_word.clone();
723 let __curr_value =curr_value.clone();
724 let __state = state.clone();
725 let __cut_count = cut_count.clone();
726 let mut __table_item = HashSet::new();
727 __table_item.insert(table_item.clone());
728 let __state_stack_mark = state_stack_mark.clone();
729
730 let thread_tx = tx.clone();
731 spawn_count += 1;
732
733 thread::spawn(move || {
734 thread_tx.send(_parse(
735 __words, __action, __goto, __tree_stack, __state_stack, __word_stack,
736 __word_index, __curr_lex, __curr_word, __curr_value, __state,
737 __cut_count, Some(__table_item), __state_stack_mark
738 )).unwrap();
739 });
740 }
741
742 break;
743
744 } else {
745
746 let mut table_item = Arc::new(TableItem {state: 0u32, lr_item: None, action: Arc::new(Action::Reduce)});
750
751 for item in table_items.iter()
752 {
753 table_item = item.clone();
754 break;
755 }
756 let _state = table_item.state;
757 let op_lr_item = table_item.lr_item.clone();
758 let _action = table_item.action.clone();
759
760 match *_action {
761 Action::Reduce => {
762 match op_lr_item {
763 Some(_lr_item) =>{
764 let symbol = glr_grammar::get_atom_string(_lr_item.symbol.clone());
765
766 let mut _cut_count = 0u32;
767 for item in _lr_item.production.iter() {
768 state_stack.pop();
769 word_stack.pop();
770
771 let _symbol = match **item {Atom::Symbol(ref x) => &***x, Atom::Terminal(ref x) => ""};
772 match _symbol.find('~') {
773 None => {
774 _cut_count += 1;
775 },
776 _ => {
777 if let Some(x) = cut_count.pop() {
778 _cut_count += x;
779 }
780 }
781 }
782 }
783
784 match symbol.find('~') {
785 Some(_) => {
786
787 cut_count.push(_cut_count);
788 },
789 None => {
790 let mut new_tree_node = Box::new(SyntaxTreeNode {value: None, symbol: match *_lr_item.symbol {Atom::Symbol(ref x) => x.clone(), Atom::Terminal(ref x) => x.clone()}, children: None});
791 let mut tree_node_children: VecDeque<Box<SyntaxTreeNode>> = VecDeque::new();
792
793 for i in 0.._cut_count as usize {
794 match tree_stack.pop_back() {Some(mut x) => {
795 tree_node_children.push_front(x);
797 }, None => {}}
798 }
799
800 new_tree_node.children = Some(tree_node_children);
801 tree_stack.push_back(new_tree_node);
802 }
803 }
804
805 state = match state_stack.get(state_stack.len() - 1) {Some(x) => *x, None => break};
806 word_stack.push(match *_lr_item.symbol {Atom::Symbol(ref x) => x.clone(), Atom::Terminal(ref x) => x.clone()});
807 state_stack.push(match goto.get(state as usize) {Some(x) => match x.get(&symbol) {Some(x) => *x, None => 0}, None => 0});
808
809 },
810 None => {}
811 }
812
813 },
814 Action::Shift => {
815 tree_stack.push_back(Box::new(SyntaxTreeNode {value: curr_value, symbol: curr_word.clone(), children: None}));
816 word_stack.push(curr_word);
817 state_stack.push(_state);
818
819 curr_lex = match words.get(word_index as usize) {Some(x) => x.clone(), None => break};
820 curr_word = match *curr_lex.atom {Atom::Symbol(ref x) => x.clone(), Atom::Terminal(ref x) => x.clone()};
821 curr_value = curr_lex.value.clone();
822
823 word_index += 1;
824 }
825 }
826
827 }
828
829 }
830
831 state = match state_stack.get(state_stack.len() - 1) {Some(x) => *x, None => break};
832
833
834
835 _table_items = match action.get(state as usize) {
836 Some(x) => {
837 match x.get(&**curr_word) {Some(x) => Some(x.clone()), None => {
838 break
840 }
841 }
842 },
843 None => break
844 };
845
846 }
847
848 paralle_trees.push(tree_stack);
850 for _ in 0..spawn_count {
851 paralle_trees.extend(rx.recv().unwrap());
852 }
853 paralle_trees
854 }
855
856
857 let mut tree_stack: VecDeque<Box<SyntaxTreeNode>> = VecDeque::new();
858 let mut state_stack: Vec<u32> = Vec::new();
859 let mut word_stack: Vec<Arc<String>> = Vec::new();
860
861 state_stack.push(0);
862
863 let mut word_index = 1u32;
864 let mut curr_lex = match words.get(0) {Some(x) => x.clone(), None => Arc::new(Lex {value: None, atom: Arc::new(Atom::Terminal(Arc::new("".to_string())))})};
865 let mut curr_word = match *curr_lex.atom {Atom::Symbol(ref x) => x.clone(), Atom::Terminal(ref x) => x.clone()};
866 let mut curr_value = curr_lex.value.clone();
867
868 let mut cut_count: Vec<u32> = Vec::new();
869
870 let mut _table_items = None;
871 let mut state = 0u32;
872
873 let mut state_stack_mark: HashSet<Vec<u32>> = HashSet::new();
875 _parse(
876 words, action, goto, tree_stack, state_stack, word_stack,
877 word_index, curr_lex, curr_word, curr_value, state,
878 cut_count, _table_items, state_stack_mark
879 )
880
881}
882
883