use lr1::core::*;
use grammar::repr::*;
use super::Tracer;
use super::trace_graph::*;
#[cfg(test)] mod test;
impl<'trace, 'grammar> Tracer<'trace, 'grammar> {
pub fn backtrace_shift(mut self,
item_state: StateIndex,
item: LR0Item<'grammar>)
-> TraceGraph<'grammar> {
let symbol_sets = item.symbol_sets();
let pred_states = self.state_graph.trace_back(item_state, symbol_sets.prefix);
self.trace_graph.add_edge(item.production.nonterminal, item, symbol_sets);
for pred_state in pred_states {
self.trace_epsilon_edges(pred_state, item.production.nonterminal);
}
self.trace_graph
}
fn trace_epsilon_edges(&mut self,
item_state: StateIndex,
nonterminal: NonterminalString) {
if self.visited_set.insert((item_state, nonterminal)) {
for pred_item in self.states[item_state.0].items.vec.iter() {
if pred_item.can_shift_nonterminal(nonterminal) {
if pred_item.index > 0 {
self.trace_graph.add_edge(pred_item,
nonterminal,
pred_item.symbol_sets());
} else {
let pred_nonterminal = pred_item.production.nonterminal;
self.trace_graph.add_edge(pred_nonterminal,
nonterminal,
pred_item.symbol_sets());
self.trace_epsilon_edges(item_state, pred_nonterminal);
}
}
}
}
}
}