LR-Style Parser Generator
A Tutorial with several examples is available.
Besides traditional LR and LALR parser generation, Rustlr supports the following options
*
, +
and ?
, which simplify
the writing of grammars and allow better ASTs to be created.The following are the contents of a Rustlr grammar file, simplecalc.grammar
:
```
auto
terminals + * - / ( )
valueterminal VAL ~ i32 ~ Num(n) ~ n as i32
nonterminal E
nonterminal T : E
nonterminal F : E
startsymbol E
variant-group Operator + - * /
E --> E + T | E - T | T T --> T * F | T / F | F F:Neg --> - F F:Val --> VAL F --> ( E )
!mod simplecalcast; !fn main() { ! let mut scanner1 = simplecalclexer::fromstr("3+2*4"); ! let mut parser1 = makeparser(); ! let parseresult = parsewith(&mut parser1, &mut scanner1); ! let ast = ! parseresult. ! unwraporelse(|x| { ! println!("Parsing errors encountered; results not guaranteed.."); ! x ! }); ! println!("\nAST: {:?}\n",&ast); !}//main ```
In addition to a parser, the grammar generates a lexical scanner from the declarations of terminal symbols. It also created the following abstract syntax type and the semantic actions that produce instances of the type. ```
pub enum E {
Operator(&'static str,LBox
The form of the AST type(s) was determined by additional declarations within
the grammar, including
variant-groupand the labels given to left-hand
side non-terminal symbols (
Negand
Val). The
variant-groupdeclaration
combined what would-have-been four enum variants into a single "Operator"
variant. The enum
variants generated from the productions for
Tand
Fare merged into the
type for
Eby the declarations
nonterminal T : Eand
nonterminal F : E.
Specifying operator precedence and associativity instead of using the
T
and
F` categories is also supported.
Rustlr contains a custom smart pointer, LBox, that automatically contains the line and column position of the start of the AST construct in the original source. This information is usually required beyond the parsing stage.
Rustlr AST types implement the Default trait so that a partial result is always returned even when parse errors are encountered.
Automatically generated AST types and semantic actions can always be manually overridden. A mixed approach is also possible.
As this is a quick example, we've also injected a main
that demonstrates how to invoke the parser directly into
the generated parser file. To run this example,
cargo install rustlr
rustlr = "0.4"
in its dependencies
(cargo add rustlr
)simplecalc.grammar
.
The filename determines the names of the modules created, and must
have a .grammar
suffix.rustlr simplecalc.grammar -o src/main.rs
cargo run
The expected output is ``` AST: Operator("+", Val(3), Operator("*", Val(2), Val(4)))
```
Please consult the tutorial for further documentation.