Skip to main content

grammar_utils/lr0/
table.rs

1use std::collections::BTreeMap;
2
3use crate::*;
4use super::*;
5
6#[derive(Debug)]
7pub struct ParseTable<'g> {
8    grammar: &'g Grammar,
9    pub(crate) states: Vec<State<'g>>,
10    pub(crate) actions: BTreeMap<(StateIndex, Option<Symbol<'g>>), Vec<Action<'g>>>,
11}
12
13#[derive(Debug)]
14#[derive(Clone, Copy, PartialEq, Eq)]
15pub enum Action<'g> {
16    Shift(StateIndex),
17    Reduce(Rule<'g>),
18    Halt,
19}
20
21#[derive(Clone)]
22pub struct Conflict<'g, 't> {
23    table: &'t ParseTable<'g>,
24    state: StateIndex,
25    symbol: Option<Symbol<'g>>,
26    actions: Vec<Action<'g>>,
27}
28
29impl<'g> std::fmt::Debug for State<'g> {
30    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31        write!(f, "{:?}", &self.itemset().items())
32    }
33}
34
35impl<'g> ParseTable<'g> {
36    pub fn build(grammar: &'g Grammar, start_rule: Rule<'g>) -> ParseTable<'g> {
37        let states = Self::build_states(&grammar, start_rule);
38        let actions = Self::build_actions(&grammar, &states, start_rule);
39
40        ParseTable {
41            grammar,
42            states,
43            actions,
44        }
45    }
46
47    pub fn grammar(&self) -> &'g Grammar {
48        self.grammar
49    }
50
51    fn build_states(grammar: &'g Grammar, start_rule: Rule<'g>) -> Vec<State<'g>> {
52        let mut states = vec![];
53        let start_state = State::new(ItemSet::singleton(Item::new(start_rule, 0)));
54        let mut states_remaining = vec![start_state];
55
56        while let Some(state) = states_remaining.pop() {
57            for symbol in grammar.symbols() {
58                let next_state = State::new(state.itemset().follow(symbol));
59
60                if next_state.itemset().is_empty() {
61                    continue;
62                }
63
64                if !states.contains(&next_state) {
65                    states_remaining.push(next_state);
66                }
67            }
68
69            if !states.contains(&state) {
70                states.push(state);
71            }
72        }
73
74        states
75    }
76
77    fn build_actions(
78        grammar: &'g Grammar,
79        states: &[State<'g>],
80        start_rule: Rule<'g>,
81    ) -> BTreeMap<(StateIndex, Option<Symbol<'g>>), Vec<Action<'g>>> {
82
83        let mut actions = BTreeMap::new();
84
85        // Pre-allocate an empty list for all (state_i, maybe_symbol)-pairs
86        for (src_state_index, _src_state) in states.iter().enumerate() {
87            let src_state_index = StateIndex(src_state_index);
88            for symbol in grammar.symbols() {
89                let key = (src_state_index, Some(symbol));
90                actions.insert(key, vec![]);
91            }
92            actions.insert((src_state_index, None), vec![]);
93        }
94
95        for (src_state_index, src_state) in states.iter().enumerate() {
96            let src_state_index = StateIndex(src_state_index);
97            for src_item in src_state.itemset().items() {
98                match src_item.next_symbol() {
99                    Some(symbol) => {
100                        let dst_state = src_state.itemset().follow(symbol);
101                        let dst_state_index = Self::state_index(&dst_state, states);
102                        let key = (src_state_index, Some(symbol));
103                        let actions_for = actions.get_mut(&key).unwrap();
104
105                        let action = Action::Shift(StateIndex(dst_state_index));
106                        if !actions_for.contains(&action) {
107                            actions_for.push(action);
108                        }
109
110                    }
111                    None => {
112                        for symbol in grammar.symbols() {
113                            let key = (src_state_index, Some(symbol));
114                            let actions_for = actions.get_mut(&key).unwrap();
115                            actions_for.push(Action::Reduce(src_item.rule()));
116                        }
117
118                        let key = (src_state_index, None);
119                        let actions_for = actions.get_mut(&key).unwrap();
120                        actions_for.push(Action::Reduce(src_item.rule()));
121                    }
122                }
123            }
124        }
125
126        let key = (StateIndex(0), Some(start_rule.lhs()));
127        actions.get_mut(&key).unwrap().insert(0, Action::Halt);
128
129        actions
130    }
131
132    fn state_index(itemset: &ItemSet, itemsets: &[State]) -> usize {
133        itemsets
134            .iter()
135            .enumerate()
136            .find_map(|(j, st)| {
137                if itemset == st.itemset() {
138                    Some(j)
139                } else {
140                    None
141                }
142            })
143            .unwrap()
144    }
145
146    pub fn conflicts(&self) -> Vec<Conflict> {
147        let mut conflicts = vec![];
148        for (state_index, _state) in self.states.iter().enumerate() {
149            let state_index = StateIndex(state_index);
150            for symbol in self.grammar.symbols() {
151                let key = (state_index, Some(symbol));
152                let actions = &self.actions[&key];
153                if actions.len() > 1 {
154                    conflicts.push(Conflict {
155                        table: self,
156                        state: state_index,
157                        symbol: Some(symbol),
158                        actions: actions.clone(),
159                    });
160                }
161            }
162        }
163        conflicts
164    }
165
166    pub fn get(&self, state_index: StateIndex, symbol: Option<Symbol<'g>>) -> Vec<Action<'g>> {
167        let key = (state_index, symbol);
168        self.actions.get(&key).unwrap().to_vec()
169    }
170
171    pub fn dump(&self) {
172        for (state_index, state) in self.states.iter().enumerate() {
173            let state_index = StateIndex(state_index);
174            eprintln!("{state_index:?}");
175            eprintln!("{state:?}");
176
177            for symbol in self.grammar.symbols() {
178                eprintln!("    {symbol:?} => {:?}", self.get(state_index, Some(symbol)));
179            }
180            eprintln!("    None => {:?}", self.get(state_index, None));
181            eprintln!();
182        }
183    }
184}
185
186impl<'g, 't> std::fmt::Debug for Conflict<'g, 't> {
187    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
188        let state_id = self.state;
189        let symbol = self.symbol;
190        let actions = &self.actions;
191        write!(f, "Conflict(state={state_id:?}, symbol={symbol:?}, actions={actions:?})")?;
192        Ok(())
193    }
194}
195
196impl<'g, 't> Conflict<'g, 't> {
197    pub fn table(&self) -> &'t ParseTable<'g> {
198        self.table
199    }
200
201    pub fn state(&self) -> &'t State {
202        &self.table.states[usize::from(self.state)]
203    }
204
205    pub fn symbol(&self) -> Option<Symbol<'g>> {
206        self.symbol
207    }
208
209    pub fn actions(&self) -> &[Action<'g>] {
210        &self.actions
211    }
212}