glr_analysis/
glr-analysis.rs

1// Copyright (c) 2018 Fabian Schuiki
2extern crate perplex;
3
4use perplex::grammar::{Grammar, Rule};
5use perplex::item_set::ItemSets;
6use perplex::glr::GlrAnalysis;
7
8#[allow(non_snake_case)]
9fn main() {
10    // Build the following grammar which has a shift/reduce conflict in the
11    // first item set, which can be resolved with an additional lookahead token.
12    //
13    //   S : A B z ;
14    //
15    //   B : B y C | C ;
16    //   C : x ;
17    //
18    //   A : D | E ;
19    //   D : x ;
20    //   E : epsilon ;
21    //
22    let mut g = Grammar::new();
23
24    let nt_s = g.add_nonterminal("S");
25    let nt_a = g.add_nonterminal("A");
26    let nt_b = g.add_nonterminal("B");
27    let nt_c = g.add_nonterminal("C");
28    let nt_d = g.add_nonterminal("D");
29    let nt_e = g.add_nonterminal("E");
30    let t_x = g.add_terminal("x");
31    let t_y = g.add_terminal("y");
32    let t_z = g.add_terminal("z");
33
34    g.add_rule(Rule::new(nt_s, vec![nt_a.into(), nt_b.into(), t_z.into()]));
35    g.add_rule(Rule::new(nt_b, vec![nt_b.into(), t_y.into(), nt_c.into()]));
36    g.add_rule(Rule::new(nt_b, vec![nt_c.into()]));
37    g.add_rule(Rule::new(nt_c, vec![t_x.into()]));
38    g.add_rule(Rule::new(nt_a, vec![nt_d.into()]));
39    g.add_rule(Rule::new(nt_a, vec![nt_e.into()]));
40    g.add_rule(Rule::new(nt_d, vec![t_x.into()]));
41    g.add_rule(Rule::new(nt_e, vec![]));
42
43    // Compute the item sets for the grammar.
44    let is = ItemSets::compute(&g);
45    println!("{}", is.pretty(&g));
46
47    // Perform the GLR analysis.
48    let ga = GlrAnalysis::compute(&g, &is);
49    println!("{:#?}", ga);
50
51    // Generate the parser code.
52    // let sm = StateMachine::try_from(&is).unwrap();
53    // let backend = Backend::new();
54    // generate_parser(
55    //     &mut File::create("tests/generated/tribble2_parser.rs").unwrap(),
56    //     &backend,
57    //     &sm,
58    //     &g,
59    // ).unwrap();
60}