grammar_utils/lr0/
table.rs1use 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 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}