Finish state parameter example

This commit is contained in:
Sosthène Guédon 2019-12-24 11:54:27 +01:00
parent a8d82ccde1
commit f1a8e2bd67

View File

@ -1,38 +1,16 @@
# Passing state parameter
When building the AST, it might be useful to pass parameters to the parser.
By default, the parser doesn't take any argument other than the input.
When building the AST, it might be useful to pass parameters to the parser, which might be needed to the construction of the tree.
Going back to the calculator4 example it is possible to pass an argument to the parser :
```rust
use std::str::FromStr;
use ast::{Expr, Opcode};
grammar(scale: i32);
```
pub Expr: Box<Expr> = { // (1)
Expr ExprOp Factor => Box::new(Expr::Op(<>)), // (2)
Factor,
};
ExprOp: Opcode = { // (3)
"+" => Opcode::Add,
"-" => Opcode::Sub,
};
Factor: Box<Expr> = {
Factor FactorOp Term => Box::new(Expr::Op(<>)),
Term,
};
FactorOp: Opcode = {
"*" => Opcode::Mul,
"/" => Opcode::Div,
};
Term: Box<Expr> = {
Num => Box::new(Expr::Number(<>)),
"(" <Expr> ")"
};
```rust
Num: i32 = {
r"[0-9]+" => i32::from_str(<>).unwrap()*scale,
};
@ -40,4 +18,19 @@ Num: i32 = {
Here the parser will accept a scale parameter that will scale every number encountered.
It can then be called with the scale parameter :
```rust
#[test]
fn calculator7() {
let scale = 2;
let expr = calculator7::ExprParser::new()
.parse(scale,"11 * 22 + 33")
.unwrap();
assert_eq!(&format!("{:?}", expr), "((22 * 44) + 66)");
}
```
For a more practical example with a custom tree structure, check out [this parser](https://github.com/lalrpop/lalrpop/blob/master/lalrpop-test/src/expr_arena.lalrpop) using [this structure](https://github.com/lalrpop/lalrpop/blob/master/lalrpop-test/src/expr_arena_ast.rs) to build the AST.