tribble1/
tribble1.rs

1// Copyright (c) 2018 Fabian Schuiki
2extern crate perplex;
3
4use std::fs::File;
5
6use perplex::grammar::{self, Grammar, Rule};
7use perplex::item_set::ItemSets;
8use perplex::machine::StateMachine;
9use perplex::backend::{generate_parser, Backend};
10
11#[allow(non_snake_case)]
12fn main() {
13    // Build the grammar in David Tribble's example 11.
14    let mut g = Grammar::new();
15    let (ntS, ntA, ntB) = (
16        g.add_nonterminal("S"),
17        g.add_nonterminal("A"),
18        g.add_nonterminal("B"),
19    );
20    let (ta, tb, tc, td, te) = (
21        g.add_terminal("a"),
22        g.add_terminal("b"),
23        g.add_terminal("c"),
24        g.add_terminal("d"),
25        g.add_terminal("e"),
26    );
27    g.add_rule(Rule::new(ntS, vec![ta.into(), ntA.into(), td.into()]));
28    g.add_rule(Rule::new(ntS, vec![ta.into(), ntB.into(), te.into()]));
29    g.add_rule(Rule::new(ntS, vec![tb.into(), ntA.into(), te.into()]));
30    g.add_rule(Rule::new(ntS, vec![tb.into(), ntB.into(), td.into()]));
31    g.add_rule(Rule::new(ntA, vec![tc.into()]));
32    g.add_rule(Rule::new(ntB, vec![tc.into()]));
33
34    // Compute the first sets for the grammar.
35    let is = ItemSets::compute(&g);
36    println!("{}", is.pretty(&g));
37
38    // Generate the parser code.
39    let sm = StateMachine::try_from(&is).unwrap();
40    let mut backend = Backend::new();
41    backend.add_nonterminal(ntS, "NodeS");
42    backend.add_nonterminal(ntA, "NodeA");
43    backend.add_nonterminal(ntB, "NodeB");
44    backend.add_terminal(grammar::END, "Token::Eof");
45    backend.add_terminal(ta, "Token::A");
46    backend.add_terminal(tb, "Token::B");
47    backend.add_terminal(tc, "Token::C");
48    backend.add_terminal(td, "Token::D");
49    backend.add_terminal(te, "Token::E");
50    generate_parser(
51        &mut File::create("tests/generated/tribble1_parser.rs").unwrap(),
52        &backend,
53        &sm,
54        &g,
55    ).unwrap();
56}