Skip to main content

grammar_utils/lr1/
item.rs

1use std::collections::BTreeSet;
2
3use crate::*;
4
5#[derive(Clone)]
6pub struct Item<'g> {
7    rule: Rule<'g>,
8    pos: usize,
9    lookahead: BTreeSet<Option<Symbol<'g>>>,
10}
11
12impl<'g> Item<'g> {
13    pub fn new(rule: Rule<'g>, pos: usize, lookahead: BTreeSet<Option<Symbol<'g>>>) -> Item<'g> {
14        assert!(pos <= rule.rhs().len());
15
16        Item {
17            rule,
18            pos,
19            lookahead,
20        }
21    }
22
23    pub fn rule(&self) -> Rule<'g> {
24        self.rule
25    }
26
27    pub fn pos(&self) -> usize {
28        self.pos
29    }
30
31    pub fn lookahead(&self) -> &BTreeSet<Option<Symbol<'g>>> {
32        &self.lookahead
33    }
34
35    pub fn grammar(&self) -> &'g Grammar {
36        self.rule.grammar()
37    }
38
39    pub fn lhs(&'g self) -> Symbol<'g> {
40        self.rule.lhs()
41    }
42
43    pub fn rhs(&self) -> Vec<Symbol<'g>> {
44        self.rule.rhs()
45    }
46
47    pub fn next_symbol(&self) -> Option<Symbol<'g>> {
48        if self.pos() < self.rhs().len() {
49            Some(self.rule.rhs()[self.pos])
50        } else {
51            None
52        }
53    }
54
55    pub fn next_next_symbol(&self) -> Option<Symbol<'g>> {
56        if self.pos() + 1 < self.rhs().len() {
57            Some(self.rule.rhs()[self.pos + 1])
58        } else {
59            None
60        }
61    }
62
63    pub fn step(&self) -> Option<Item<'g>> {
64        if self.pos() < self.rhs().len() {
65            Some(Item::new(self.rule, self.pos + 1, self.lookahead.clone()))
66        } else {
67            None
68        }
69    }
70
71    pub fn is_finished(&self) -> bool {
72        self.pos() == self.rhs().len()
73    }
74}
75
76impl<'g> std::fmt::Debug for Item<'g> {
77    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78        let lhs = self.rule.lhs();
79        let rhs = self.rule.rhs();
80        write!(f, "{lhs:?} ->")?;
81        for i in 0..self.pos {
82            write!(f, " {:?}", &rhs[i])?;
83        }
84
85        write!(f, " .")?;
86
87        for i in self.pos..rhs.len() {
88            write!(f,  " {:?}", &rhs[i])?;
89        }
90
91        write!(f, " {{ ")?;
92        for symbol in &self.lookahead {
93            write!(f, "{symbol:?} ")?;
94        }
95        write!(f, "}}")?;
96        Ok(())
97    }
98}
99
100impl<'g> PartialEq for Item<'g> {
101    fn eq(&self, other: &Self) -> bool {
102        self.rule() == other.rule() && self.pos == other.pos && self.lookahead == other.lookahead
103    }
104}
105
106impl<'g> Eq for Item<'g> {}