1use std::{
2 cell::RefCell,
3 collections::{HashSet, VecDeque},
4 fmt::Debug,
5 ops::Range,
6 rc::Rc,
7};
8
9use petgraph::{graph::Edges, prelude::*};
10
11use crate::{
12 context::Context, input::Input, lexer::Token, location::Location, lr::builder::LRBuilder,
13 parser::State,
14};
15
16pub struct GssGraph<'i, I: Input + ?Sized, S, P, TK: Copy>(
21 #[allow(clippy::type_complexity)] Graph<GssHead<'i, I, S, TK>, Rc<Parent<'i, I, P, TK>>>,
22);
23
24impl<I, S, P, TK> Default for GssGraph<'_, I, S, P, TK>
25where
26 I: Input + ?Sized,
27 TK: Copy,
28{
29 fn default() -> Self {
30 Self(Default::default())
31 }
32}
33
34impl<'i, I, S, P, TK> GssGraph<'i, I, S, P, TK>
35where
36 I: Input + ?Sized,
37 TK: Copy,
38{
39 pub fn new() -> Self {
40 Self::default()
41 }
42
43 #[inline]
44 pub fn add_head(&mut self, head: GssHead<'i, I, S, TK>) -> NodeIndex {
45 self.0.add_node(head)
46 }
47
48 #[inline]
49 pub fn head(&self, head: NodeIndex) -> &GssHead<'i, I, S, TK> {
50 self.0.node_weight(head).expect("Invalid Gss head index!")
51 }
52
53 #[inline]
54 pub fn head_mut(&mut self, head: NodeIndex) -> &mut GssHead<'i, I, S, TK> {
55 self.0
56 .node_weight_mut(head)
57 .expect("Invalid Gss head index!")
58 }
59
60 #[inline]
61 pub fn parent(&self, index: EdgeIndex) -> Rc<Parent<'i, I, P, TK>> {
62 self.0.edge_weight(index).unwrap().clone()
63 }
64
65 #[inline]
66 pub fn add_parent(
67 &mut self,
68 start: NodeIndex,
69 end: NodeIndex,
70 parent: Rc<Parent<'i, I, P, TK>>,
71 ) -> EdgeIndex {
72 self.0.add_edge(start, end, parent)
73 }
74
75 pub fn add_solution(
82 &mut self,
83 start: NodeIndex,
84 end: NodeIndex,
85 solution: Rc<SPPFTree<'i, I, P, TK>>,
86 ) -> Option<EdgeIndex> {
87 if let Some(edge) = self.edge_between(start, end) {
88 self.parent(edge).possibilities.borrow_mut().push(solution);
89 None
90 } else {
91 Some(self.add_parent(start, end, Rc::new(Parent::new(end, start, vec![solution]))))
92 }
93 }
94
95 #[inline]
96 pub fn backedges(&self, head: NodeIndex) -> Edges<'_, Rc<Parent<'i, I, P, TK>>, Directed> {
97 self.0.edges_directed(head, Direction::Outgoing)
98 }
99
100 #[inline]
101 pub fn start(&self, edge: EdgeIndex) -> NodeIndex {
102 self.0
103 .edge_endpoints(edge)
104 .expect("Invalid Gss edge index!")
105 .0
106 }
107
108 #[inline]
109 pub fn end(&self, edge: EdgeIndex) -> NodeIndex {
110 self.0
111 .edge_endpoints(edge)
112 .expect("Invalid Gss edge index!")
113 .1
114 }
115
116 #[inline]
117 pub fn edge_between(&self, start: NodeIndex, end: NodeIndex) -> Option<EdgeIndex> {
118 self.0.find_edge(start, end)
119 }
120}
121
122#[derive(Debug)]
130pub struct GssHead<'i, I, S, TK>
131where
132 I: Input + ?Sized,
133{
134 state: S,
138
139 pub frontier: usize,
141
142 position: usize,
144
145 range: Range<usize>,
147
148 location: Location,
149
150 layout_ahead: Option<&'i I>,
152
153 token_ahead: Option<Token<'i, I, TK>>,
156}
157
158impl<I, S, TK> Clone for GssHead<'_, I, S, TK>
159where
160 I: Input + ?Sized,
161 S: State,
162 TK: Copy,
163{
164 fn clone(&self) -> Self {
165 Self {
166 state: self.state,
167 frontier: self.frontier,
168 position: self.position,
169 range: self.range.clone(),
170 location: self.location,
171 layout_ahead: self.layout_ahead,
172 token_ahead: self.token_ahead().cloned(),
173 }
174 }
175}
176
177impl<I: Input + ?Sized, S: Default, TK> Default for GssHead<'_, I, S, TK> {
178 fn default() -> Self {
179 Self {
180 state: Default::default(),
181 frontier: Default::default(),
182 position: Default::default(),
183 range: Default::default(),
184 location: I::start_location(),
185 layout_ahead: Default::default(),
186 token_ahead: Default::default(),
187 }
188 }
189}
190
191impl<'i, I, S, TK> GssHead<'i, I, S, TK>
192where
193 I: Input + ?Sized,
194 S: State,
195 TK: Copy,
196{
197 #[allow(clippy::too_many_arguments)]
198 pub fn new(
199 state: S,
200 frontier: usize,
201 position: usize,
202 range: Range<usize>,
203 location: Location,
204 layout_ahead: Option<&'i I>,
205 token_ahead: Option<Token<'i, I, TK>>,
206 ) -> Self {
207 Self {
208 state,
209 frontier,
210 position,
211 range,
212 location,
213 layout_ahead,
214 token_ahead,
215 }
216 }
217 pub fn with_tok_state(&self, token_ahead: Token<'i, I, TK>, state: S) -> Self {
218 Self {
219 state,
220 token_ahead: Some(token_ahead),
221 range: self.range(),
222 ..*self
223 }
224 }
225 pub fn with_tok(&self, token_ahead: Token<'i, I, TK>) -> Self {
226 Self {
227 token_ahead: Some(token_ahead),
228 range: self.range(),
229 ..*self
230 }
231 }
232}
233
234impl<'i, S, I, TK> Context<'i, I, S, TK> for GssHead<'i, I, S, TK>
235where
236 I: Input + ?Sized,
237 S: State,
238{
239 #[inline]
240 fn state(&self) -> S {
241 self.state
242 }
243
244 #[inline]
245 fn set_state(&mut self, state: S) {
246 self.state = state
247 }
248
249 #[inline]
250 fn position(&self) -> usize {
251 self.position
252 }
253
254 #[inline]
255 fn set_position(&mut self, position: usize) {
256 self.position = position
257 }
258
259 #[inline]
260 fn location(&self) -> Location {
261 self.location
262 }
263
264 #[inline]
265 fn set_location(&mut self, location: Location) {
266 self.location = location
267 }
268
269 #[inline]
270 fn range(&self) -> Range<usize> {
271 self.range.clone()
272 }
273
274 #[inline]
275 fn set_range(&mut self, range: Range<usize>) {
276 self.range = range
277 }
278
279 #[inline]
280 fn token_ahead(&self) -> Option<&Token<'i, I, TK>> {
281 self.token_ahead.as_ref()
282 }
283
284 #[inline]
285 fn set_token_ahead(&mut self, token: Token<'i, I, TK>) {
286 self.token_ahead = Some(token)
287 }
288
289 #[inline]
290 fn layout_ahead(&self) -> Option<&'i I> {
291 self.layout_ahead
292 }
293
294 #[inline]
295 fn set_layout_ahead(&mut self, layout: Option<&'i I>) {
296 self.layout_ahead = layout
297 }
298}
299
300#[derive(Debug)]
302pub enum SPPFTree<'i, I, P, TK>
303where
304 I: Input + ?Sized,
305 TK: Copy,
306{
307 Term {
308 token: Token<'i, I, TK>,
309 data: TreeData<'i, I>,
310 },
311 NonTerm {
312 prod: P,
313 data: TreeData<'i, I>,
314
315 children: RefCell<VecDeque<Rc<Parent<'i, I, P, TK>>>>,
319 },
320 Empty,
322}
323
324impl<'i, I, P, TK> SPPFTree<'i, I, P, TK>
325where
326 I: Input + ?Sized,
327 TK: Copy,
328{
329 fn solutions(&self) -> usize {
330 match self {
331 SPPFTree::Term { .. } => 1,
332 SPPFTree::NonTerm { children, .. } => {
333 children.borrow().iter().map(|p| p.solutions()).product()
334 }
335 SPPFTree::Empty => 0,
336 }
337 }
338
339 #[allow(clippy::mutable_key_type)]
340 fn ambiguities(&self, visited: &mut HashSet<Rc<Parent<'i, I, P, TK>>>) -> usize {
341 match self {
342 SPPFTree::Term { .. } | SPPFTree::Empty => 0,
343 SPPFTree::NonTerm { children, .. } => children
344 .borrow()
345 .iter()
346 .map(|p| {
347 if visited.contains(p) {
348 0
349 } else {
350 visited.insert(Rc::clone(p));
351 p.ambiguities(visited)
352 }
353 })
354 .sum(),
355 }
356 }
357}
358
359impl<'i, I, S, P, TK> Context<'i, I, S, TK> for SPPFTree<'i, I, P, TK>
361where
362 I: Input + ?Sized,
363 TK: Copy,
364 S: State,
365{
366 fn state(&self) -> S {
367 panic!("state() called on SPPFTree")
368 }
369
370 fn set_state(&mut self, _state: S) {}
371
372 fn position(&self) -> usize {
373 panic!("position() called on SPPFTree")
374 }
375
376 fn set_position(&mut self, _position: usize) {}
377
378 fn location(&self) -> Location {
379 match self {
380 SPPFTree::Term { data, .. } | SPPFTree::NonTerm { data, .. } => data.location,
381 _ => panic!("Called location() on empty tree!"),
382 }
383 }
384
385 fn set_location(&mut self, _location: Location) {}
386
387 fn range(&self) -> Range<usize> {
388 match self {
389 SPPFTree::Term { data, .. } | SPPFTree::NonTerm { data, .. } => data.range.clone(),
390 _ => panic!("Called range() on empty tree!"),
391 }
392 }
393
394 fn set_range(&mut self, _range: Range<usize>) {}
395
396 fn token_ahead(&self) -> Option<&Token<'i, I, TK>> {
397 None
398 }
399
400 fn set_token_ahead(&mut self, _token: Token<'i, I, TK>) {}
401
402 fn layout_ahead(&self) -> Option<&'i I> {
403 match self {
404 SPPFTree::Term { data, .. } | SPPFTree::NonTerm { data, .. } => data.layout,
405 _ => panic!("Called layout_ahead() on empty tree!"),
406 }
407 }
408
409 fn set_layout_ahead(&mut self, _layout: Option<&'i I>) {}
410}
411
412impl<I, P, TK> Default for SPPFTree<'_, I, P, TK>
413where
414 I: Input + ?Sized,
415 TK: Copy,
416{
417 fn default() -> Self {
418 Self::Empty
419 }
420}
421
422impl<I, P, TK> Clone for SPPFTree<'_, I, P, TK>
423where
424 I: Input + ?Sized,
425 P: Clone,
426 TK: Copy,
427{
428 fn clone(&self) -> Self {
429 match self {
430 Self::Term { token, data } => Self::Term {
431 token: token.clone(),
432 data: data.clone(),
433 },
434 Self::NonTerm {
435 prod,
436 data,
437 children,
438 } => Self::NonTerm {
439 prod: prod.clone(),
440 data: data.clone(),
441 children: children.clone(),
442 },
443 Self::Empty => Self::Empty,
444 }
445 }
446}
447
448#[derive(Debug)]
450pub struct TreeData<'i, I>
451where
452 I: Input + ?Sized,
453{
454 pub range: Range<usize>,
455 pub location: Location,
456 pub layout: Option<&'i I>,
457}
458
459impl<I> Clone for TreeData<'_, I>
460where
461 I: Input + ?Sized,
462{
463 fn clone(&self) -> Self {
464 Self {
465 range: self.range.clone(),
466 location: self.location,
467 layout: self.layout,
468 }
469 }
470}
471
472#[derive(Debug)]
475pub struct Parent<'i, I, P, TK>
476where
477 I: Input + ?Sized,
478 TK: Copy,
479{
480 pub root_node: NodeIndex,
481 pub head_node: NodeIndex,
482
483 pub possibilities: RefCell<Vec<Rc<SPPFTree<'i, I, P, TK>>>>,
487}
488
489impl<I, P, TK> PartialEq for Parent<'_, I, P, TK>
490where
491 I: Input + ?Sized,
492 TK: Copy,
493{
494 fn eq(&self, other: &Self) -> bool {
495 self.root_node == other.root_node && self.head_node == other.head_node
496 }
497}
498impl<I, P, TK> Eq for Parent<'_, I, P, TK>
499where
500 I: Input + ?Sized,
501 TK: Copy,
502{
503}
504
505impl<I, P, TK> std::hash::Hash for Parent<'_, I, P, TK>
506where
507 I: Input + ?Sized,
508 TK: Copy,
509{
510 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
511 self.root_node.hash(state);
512 self.head_node.hash(state);
513 }
514}
515
516impl<'i, I, P, TK> Parent<'i, I, P, TK>
517where
518 I: Input + ?Sized,
519 TK: Copy,
520{
521 pub fn new(
522 root_node: NodeIndex,
523 head_node: NodeIndex,
524 possibilities: Vec<Rc<SPPFTree<'i, I, P, TK>>>,
525 ) -> Self {
526 Self {
527 root_node,
528 head_node,
529 possibilities: RefCell::new(possibilities),
530 }
531 }
532
533 pub fn solutions(&self) -> usize {
538 self.possibilities
539 .borrow()
540 .iter()
541 .map(|n| n.solutions())
542 .sum()
543 }
544
545 #[allow(clippy::mutable_key_type)]
548 pub fn ambiguities(&self, visited: &mut HashSet<Rc<Parent<'i, I, P, TK>>>) -> usize {
549 let ambiguity: usize = if self.possibilities.borrow().len() > 1 {
550 1
551 } else {
552 0
553 };
554
555 ambiguity
556 + self
557 .possibilities
558 .borrow()
559 .iter()
560 .map(|n| n.ambiguities(visited))
561 .sum::<usize>()
562 }
563}
564
565pub struct Tree<'i, I, P, TK>
568where
569 I: Input + ?Sized,
570 TK: Copy,
571{
572 idx: usize,
573 root: Rc<SPPFTree<'i, I, P, TK>>,
574}
575
576impl<I, P, TK> Debug for Tree<'_, I, P, TK>
577where
578 I: Input + ?Sized + Debug,
579 TK: Copy,
580{
581 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
582 match &*self.root {
583 SPPFTree::Term { token, .. } => write!(f, "{:#?}", token.value),
584 SPPFTree::NonTerm { .. } => write!(f, "{:#?}", self.children()),
585 SPPFTree::Empty => write!(f, "EMPTY"),
586 }
587 }
588}
589
590impl<'i, I, P, TK> Tree<'i, I, P, TK>
591where
592 I: Input + ?Sized,
593 TK: Copy,
594{
595 pub fn new(root: Rc<SPPFTree<'i, I, P, TK>>, idx: usize) -> Self {
596 Self { root, idx }
597 }
598
599 pub fn children(&self) -> Vec<Tree<'i, I, P, TK>> {
602 match *self.root {
603 SPPFTree::Term { .. } | SPPFTree::Empty => vec![],
604 SPPFTree::NonTerm { ref children, .. } => {
605 let mut tree_idx = self.idx;
606 let weights = children
610 .borrow()
611 .iter()
612 .map(|c| c.solutions())
613 .collect::<Vec<_>>();
614 children
615 .borrow()
616 .iter()
617 .enumerate()
618 .map(|(idx, child)| {
619 let factor: usize = weights[(idx + 1)..].iter().product();
620 let tree_idx_residual = tree_idx / factor;
621 tree_idx %= factor;
622 let (root, new_tree_idx) =
623 Self::find_tree_root(&child.possibilities.borrow(), tree_idx_residual)
624 .expect("Tree index must be valid.");
625 Tree::new(root, new_tree_idx)
626 })
627 .collect()
628 }
629 }
630 }
631
632 pub fn build<B: LRBuilder<'i, I, GssHead<'i, I, S, TK>, S, P, TK>, S>(
634 &self,
635 builder: &mut B,
636 ) -> B::Output
637 where
638 S: State,
639 P: Copy,
640 {
641 let mut context = GssHead::default();
642 self.build_inner(&mut context, builder);
643 builder.get_result()
644 }
645
646 fn build_inner<B: LRBuilder<'i, I, C, S, P, TK>, C, S>(&self, context: &mut C, builder: &mut B)
647 where
648 C: Context<'i, I, S, TK> + Default,
649 S: State,
650 P: Copy,
651 {
652 match &*self.root {
653 SPPFTree::Term { token, .. } => {
654 context.set_location(Context::<I, S, TK>::location(&*self.root));
655 builder.shift_action(context, token.clone())
656 }
657 SPPFTree::NonTerm { prod, .. } => {
658 let children = self.children();
659 children.iter().for_each(|c| {
660 c.build_inner(context, builder);
661 });
662 context.set_location(Context::<I, S, TK>::location(&*self.root));
663 builder.reduce_action(context, *prod, children.len())
664 }
665 SPPFTree::Empty => (),
666 }
667 }
668
669 #[allow(clippy::type_complexity)]
672 fn find_tree_root(
673 roots: &[Rc<SPPFTree<'i, I, P, TK>>],
674 tree_idx: usize,
675 ) -> Option<(Rc<SPPFTree<'i, I, P, TK>>, usize)> {
676 if roots.is_empty() {
677 return None;
678 }
679 let mut tree_idx = tree_idx;
680 let mut root_idx = 0;
681 let mut solutions = roots[root_idx].solutions();
682 while solutions <= tree_idx {
683 root_idx += 1;
684 if root_idx >= roots.len() {
685 return None;
687 }
688 tree_idx -= solutions;
689 solutions = roots[root_idx].solutions();
690 }
691 Some((Rc::clone(&roots[root_idx]), tree_idx))
692 }
693
694 }
696
697#[derive(Debug)]
706pub struct Forest<'i, I, P, TK>
707where
708 I: Input + ?Sized,
709 TK: Copy,
710{
711 results: Vec<Rc<SPPFTree<'i, I, P, TK>>>,
716}
717
718impl<'i, I, P, TK> Forest<'i, I, P, TK>
719where
720 I: Input + ?Sized,
721 TK: Copy,
722{
723 pub fn new(results: Vec<Rc<SPPFTree<'i, I, P, TK>>>) -> Self {
724 Forest { results }
725 }
726
727 #[inline]
728 pub fn get_first_tree(&self) -> Option<Tree<'i, I, P, TK>> {
729 self.get_tree(0)
730 }
731
732 pub fn get_tree(&self, idx: usize) -> Option<Tree<'i, I, P, TK>> {
734 Tree::find_tree_root(&self.results, idx).map(|(root, idx)| Tree::new(root, idx))
735 }
736
737 #[inline]
738 pub fn is_empty(&self) -> bool {
739 self.results.is_empty()
740 }
741
742 #[inline]
744 pub fn solutions(&self) -> usize {
745 self.results.iter().map(|n| n.solutions()).sum()
746 }
747
748 #[inline]
753 pub fn ambiguities(&self) -> usize {
754 #[allow(clippy::mutable_key_type)]
755 let mut visited: HashSet<Rc<Parent<'i, I, P, TK>>> = HashSet::new();
756 self.results
757 .iter()
758 .map(|n| n.ambiguities(&mut visited))
759 .sum::<usize>()
760 + if self.results.len() > 1 { 1 } else { 0 }
761 }
762}
763
764pub struct ForestIntoIter<'i, I, P, TK>
766where
767 I: Input + ?Sized,
768 TK: Copy,
769{
770 forest: Forest<'i, I, P, TK>,
771 tree_idx: usize,
772}
773
774impl<'i, I, P, TK> IntoIterator for Forest<'i, I, P, TK>
775where
776 I: Input + ?Sized,
777 TK: Copy,
778{
779 type Item = Tree<'i, I, P, TK>;
780 type IntoIter = ForestIntoIter<'i, I, P, TK>;
781
782 fn into_iter(self) -> Self::IntoIter {
783 ForestIntoIter {
784 forest: self,
785 tree_idx: 0,
786 }
787 }
788}
789
790impl<'i, I, P, TK> Iterator for ForestIntoIter<'i, I, P, TK>
791where
792 I: Input + ?Sized,
793 TK: Copy,
794{
795 type Item = Tree<'i, I, P, TK>;
796
797 fn next(&mut self) -> Option<Self::Item> {
798 let tree = self.forest.get_tree(self.tree_idx);
799 if tree.is_some() {
800 self.tree_idx += 1;
801 }
802 tree
803 }
804}
805
806impl<'i, I, P, TK> Forest<'i, I, P, TK>
808where
809 I: Input + ?Sized,
810 TK: Copy,
811{
812 pub fn iter<'f>(&'f self) -> ForestIterator<'i, 'f, I, P, TK> {
813 ForestIterator {
814 forest: self,
815 tree_idx: 0,
816 }
817 }
818}
819
820pub struct ForestIterator<'i, 'f, I, P, TK>
821where
822 I: Input + ?Sized,
823 TK: Copy,
824{
825 forest: &'f Forest<'i, I, P, TK>,
826 tree_idx: usize,
827}
828
829impl<'i, I, P, TK> Iterator for ForestIterator<'i, '_, I, P, TK>
830where
831 I: Input + ?Sized,
832 TK: Copy,
833{
834 type Item = Tree<'i, I, P, TK>;
835
836 fn next(&mut self) -> Option<Self::Item> {
837 let tree = self.forest.get_tree(self.tree_idx);
838 if tree.is_some() {
839 self.tree_idx += 1;
840 }
841 tree
842 }
843}
844
845impl<'i, 'f, I, P, TK> IntoIterator for &'f Forest<'i, I, P, TK>
847where
848 I: Input + ?Sized,
849 TK: Copy,
850{
851 type Item = Tree<'i, I, P, TK>;
852 type IntoIter = ForestIterator<'i, 'f, I, P, TK>;
853
854 fn into_iter(self) -> Self::IntoIter {
855 self.iter()
856 }
857}