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