-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlang.lalrpop
60 lines (47 loc) · 1.24 KB
/
lang.lalrpop
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use crate::front::ast::*;
use crate::patch::*;
grammar;
pub Prog: Vec<Stmt> = {
Stmt*
};
Stmt: Stmt = {
"get" <Key> ";" => Stmt::Get(<>),
"put" <Key> <Expr> ";" => Stmt::Put(<>),
<Ident> "=" <Expr> ";" => Stmt::Assign(<>),
"if" <BoolExpr> "{" <Prog> "}" "else" "{" <Prog> "}" => Stmt::If(<>),
"if" <BoolExpr> "{" <Prog> "}" => Stmt::If(<>, vec![]),
};
Expr: Expr = {
<l: Expr> "+" <r: Factor> => Expr::ArithOp(Box::new(l), ArithOp::Add, Box::new(r)),
Factor,
};
Factor: Expr = {
Term,
};
Term: Expr = {
"(" <Expr> ")",
Value => Expr::Const(<>),
<Ident> => Expr::Ident(<>),
"get" <Key> => Expr::Get(<>),
};
BoolExpr: BoolExpr = {
<l: BoolExpr> "||" <r: BFactor> => BoolExpr::Conn(Box::new(l), BoolOp::Or, Box::new(r)),
BFactor,
};
BFactor: BoolExpr = {
<l: BFactor> "&&" <r: BTerm> => BoolExpr::Conn(Box::new(l), BoolOp::And, Box::new(r)),
BTerm,
};
BTerm: BoolExpr = {
"(" <BoolExpr> ")",
<l: Expr> "==" <r: Expr> => BoolExpr::Cmp(l, CmpOp::Eq, r),
};
Ident: Ident = {
// FIXME: limit the length of identifiers
r"[A-Za-z]+" => Ident((<>).to_string())
};
Key: Key = { String };
Value: Value = { String };
String: String = {
<s:r#""[^"]*""#> => s[1..s.len()-1].to_string()
}