Function generate_parser

Source
pub fn generate_parser<W: Write>(
    into: &mut W,
    backend: &Backend,
    machine: &StateMachine,
    grammar: &Grammar,
) -> Result<()>
Expand description

Generate the code for the parser.

Examples found in repository?
examples/tribble1.rs (lines 50-55)
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}
More examples
Hide additional examples
examples/update-grammar.rs (line 179)
12fn main() {
13    // Build the grammar for grammars (how meta!).
14    let mut g = Grammar::new();
15
16    let nt_desc = g.add_nonterminal("desc");
17    let nt_item = g.add_nonterminal("item");
18    let nt_token_decl = g.add_nonterminal("token_decl");
19    let nt_token_name = g.add_nonterminal("token_name");
20    let nt_rule_decl = g.add_nonterminal("rule_decl");
21    let nt_rule_list = g.add_nonterminal("rule_list");
22    let nt_variant = g.add_nonterminal("variant");
23    let nt_sequence_or_epsilon = g.add_nonterminal("sequence_or_epsilon");
24    let nt_sequence = g.add_nonterminal("sequence");
25
26    let t_ident = g.add_terminal("IDENT");
27    let t_code = g.add_terminal("CODE");
28    let t_kw_token = g.add_terminal("'token'");
29    let t_kw_epsilon = g.add_terminal("'epsilon'");
30    let t_kw_end = g.add_terminal("'end'");
31    let t_lparen = g.add_terminal("'('");
32    let t_rparen = g.add_terminal("')'");
33    let t_lbrace = g.add_terminal("'{'");
34    let t_rbrace = g.add_terminal("'}'");
35    let t_period = g.add_terminal("'.'");
36    let t_colon = g.add_terminal("':'");
37    let t_comma = g.add_terminal("','");
38    let t_semicolon = g.add_terminal("';'");
39    let t_pipe = g.add_terminal("'|'");
40
41    // desc : desc item | item | desc ';' | ';' ;
42    let r_desc_a = g.add_rule(Rule::new(nt_desc, vec![nt_desc.into(), nt_item.into()]));
43    let r_desc_b = g.add_rule(Rule::new(nt_desc, vec![nt_item.into()]));
44    let r_desc_c = g.add_rule(Rule::new(nt_desc, vec![nt_desc.into(), t_semicolon.into()]));
45    let r_desc_d = g.add_rule(Rule::new(nt_desc, vec![t_semicolon.into()]));
46
47    // item : token_decl | rule_decl ;
48    let r_item_a = g.add_rule(Rule::new(nt_item, vec![nt_token_decl.into()]));
49    let r_item_b = g.add_rule(Rule::new(nt_item, vec![nt_rule_decl.into()]));
50
51    // token_decl : 'token' token_name '(' CODE ')' ';' ;
52    let r_token_decl = g.add_rule(Rule::new(
53        nt_token_decl,
54        vec![
55            t_kw_token.into(),
56            nt_token_name.into(),
57            t_lparen.into(),
58            t_code.into(),
59            t_rparen.into(),
60            t_semicolon.into(),
61        ],
62    ));
63
64    // token_name : IDENT | 'end' ;
65    let r_token_name_a = g.add_rule(Rule::new(nt_token_name, vec![t_ident.into()]));
66    let r_token_name_b = g.add_rule(Rule::new(nt_token_name, vec![t_kw_end.into()]));
67
68    // rule_decl : IDENT '(' CODE ')' '{' rule_list '}' ;
69    let r_rule_decl = g.add_rule(Rule::new(
70        nt_rule_decl,
71        vec![
72            t_ident.into(),
73            t_lparen.into(),
74            t_code.into(),
75            t_rparen.into(),
76            t_lbrace.into(),
77            nt_rule_list.into(),
78            t_rbrace.into(),
79        ],
80    ));
81
82    // rule_list : rule_list variant | variant;
83    let r_rule_list_a = g.add_rule(Rule::new(
84        nt_rule_list,
85        vec![nt_rule_list.into(), nt_variant.into()],
86    ));
87    let r_rule_list_b = g.add_rule(Rule::new(nt_rule_list, vec![nt_variant.into()]));
88
89    // variant : sequence_or_epsilon '(' CODE ')' ';'
90    let r_variant = g.add_rule(Rule::new(
91        nt_variant,
92        vec![
93            nt_sequence_or_epsilon.into(),
94            t_lparen.into(),
95            t_code.into(),
96            t_rparen.into(),
97            t_semicolon.into(),
98        ],
99    ));
100
101    // sequence_or_epsilon : sequence | 'epsilon' ;
102    let r_sequence_or_epsilon_a =
103        g.add_rule(Rule::new(nt_sequence_or_epsilon, vec![nt_sequence.into()]));
104    let r_sequence_or_epsilon_b =
105        g.add_rule(Rule::new(nt_sequence_or_epsilon, vec![t_kw_epsilon.into()]));
106
107    // sequence : sequence IDENT | IDENT ;
108    let r_sequence_a = g.add_rule(Rule::new(
109        nt_sequence,
110        vec![nt_sequence.into(), t_ident.into()],
111    ));
112    let r_sequence_b = g.add_rule(Rule::new(nt_sequence, vec![t_ident.into()]));
113
114    // Compute the item sets for the grammar.
115    let is = ItemSets::compute(&g);
116    eprintln!("Perplex Grammar Item Sets:");
117    eprintln!("{}", is.pretty(&g));
118
119    // Configure the code generation backend.
120    let mut backend = Backend::new();
121
122    backend.add_nonterminal(nt_desc, "ast::Desc");
123    backend.add_nonterminal(nt_item, "ast::Item");
124    backend.add_nonterminal(nt_token_decl, "ast::TokenDecl");
125    backend.add_nonterminal(nt_token_name, "ast::TokenName");
126    backend.add_nonterminal(nt_rule_decl, "ast::RuleDecl");
127    backend.add_nonterminal(nt_rule_list, "Vec<ast::Variant>");
128    backend.add_nonterminal(nt_variant, "ast::Variant");
129    backend.add_nonterminal(nt_sequence_or_epsilon, "Vec<String>");
130    backend.add_nonterminal(nt_sequence, "Vec<String>");
131
132    backend.add_terminal(grammar::END, "None");
133    backend.add_terminal(t_ident, "Some(Token::Ident(_))");
134    backend.add_terminal(t_code, "Some(Token::Code(_))");
135    backend.add_terminal(t_kw_token, "Some(Token::Keyword(Keyword::Token))");
136    backend.add_terminal(t_kw_epsilon, "Some(Token::Keyword(Keyword::Epsilon))");
137    backend.add_terminal(t_kw_end, "Some(Token::Keyword(Keyword::End))");
138    backend.add_terminal(t_lparen, "Some(Token::LParen)");
139    backend.add_terminal(t_rparen, "Some(Token::RParen)");
140    backend.add_terminal(t_lbrace, "Some(Token::LBrace)");
141    backend.add_terminal(t_rbrace, "Some(Token::RBrace)");
142    backend.add_terminal(t_period, "Some(Token::Period)");
143    backend.add_terminal(t_colon, "Some(Token::Colon)");
144    backend.add_terminal(t_comma, "Some(Token::Comma)");
145    backend.add_terminal(t_semicolon, "Some(Token::Semicolon)");
146    backend.add_terminal(t_pipe, "Some(Token::Pipe)");
147
148    backend.add_reduction_function(r_desc_a, "reduce_desc_a");
149    backend.add_reduction_function(r_desc_b, "reduce_desc_b");
150    backend.add_reduction_function(r_desc_c, "reduce_desc_c");
151    backend.add_reduction_function(r_desc_d, "reduce_desc_d");
152    backend.add_reduction_function(r_item_a, "reduce_item_a");
153    backend.add_reduction_function(r_item_b, "reduce_item_b");
154    backend.add_reduction_function(r_token_decl, "reduce_token_decl");
155    backend.add_reduction_function(r_token_name_a, "reduce_token_name_a");
156    backend.add_reduction_function(r_token_name_b, "reduce_token_name_b");
157    backend.add_reduction_function(r_rule_decl, "reduce_rule_decl");
158    backend.add_reduction_function(r_rule_list_a, "reduce_rule_list_a");
159    backend.add_reduction_function(r_rule_list_b, "reduce_rule_list_b");
160    backend.add_reduction_function(r_variant, "reduce_variant");
161    backend.add_reduction_function(r_sequence_or_epsilon_a, "reduce_sequence_or_epsilon_a");
162    backend.add_reduction_function(r_sequence_or_epsilon_b, "reduce_sequence_or_epsilon_b");
163    backend.add_reduction_function(r_sequence_a, "reduce_sequence_a");
164    backend.add_reduction_function(r_sequence_b, "reduce_sequence_b");
165
166    // // Generate the parser code.
167    // let sm = StateMachine::try_from(&is).expect("failed to generate state machine");
168    // let stdout = std::io::stdout();
169    // generate_parser(&mut stdout.lock(), &backend, &sm, &g).expect("failed to generate parser code");
170
171    // Generate the parser code.
172    let mut path = PathBuf::from(file!());
173    path.pop();
174    path.pop();
175    path.push("src");
176    path.push("parser_states.rs");
177    eprintln!("Generating parser code in {:?}", path);
178    let sm = StateMachine::try_from(&is).expect("failed to generate state machine");
179    generate_parser(&mut File::create(path).unwrap(), &backend, &sm, &g)
180        .expect("failed to generate parser code");
181}