Skip to main content

grammar_utils/ll1/
machine.rs

1use std::iter::Peekable;
2
3use crate::*;
4use super::*;
5
6pub struct Machine<'g, I>
7    where I: Iterator<Item=Symbol<'g>> {
8    table: ParseTable<'g>,
9    stack: Vec<Symbol<'g>>,
10    input: Peekable<I>,
11}
12
13impl<'g, I> Machine<'g, I> where I: Iterator<Item=Symbol<'g>> {
14    pub fn new(table: ParseTable<'g>, start_symbol: Symbol<'g>, input: I) -> Machine<'g, I> {
15        Machine {
16            table,
17            input: input.peekable(),
18            stack: vec![start_symbol],
19        }
20    }
21
22    pub fn step(&mut self) -> bool {
23        match (self.stack.pop(), self.input.peek()) {
24            (None, Some(_symbol)) => {
25                return true;
26            }
27            (Some(state), token) => {
28                if Some(state) == token.copied() {
29                    self.input.next();
30                } else {
31                    let rules = self.table.get(state, token.copied());
32                    match rules.as_slice() {
33                        [] => panic!("Parse error"),
34                        [rule] => {
35                            for symbol in rule.rhs().into_iter().rev() {
36                                self.stack.push(symbol);
37                            }
38                        }
39                        _ => panic!("Conflict"),
40                    }
41                }
42            }
43            (None, None) => return true,
44        }
45        false
46    }
47
48    pub fn run(&mut self) {
49        self.dump();
50        loop {
51            let halt = self.step();
52            self.dump();
53            if halt {
54                break;
55            }
56        }
57    }
58
59    fn dump(&mut self) {
60        eprintln!("Input: {:?}", self.input.peek());
61        eprintln!("Stack: {}", self.stack.iter().map(|symbol| format!("{symbol:?}")).collect::<Vec<_>>().join(" "));
62        eprintln!();
63    }
64}