-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathformula_parser.lalrpop
86 lines (70 loc) · 1.95 KB
/
formula_parser.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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use std::str::FromStr;
use crate::ast::{Expr, Opcode, Func, Constant};
grammar;
pub Formula: Box<Expr<'input>> = {
"eps" "=" <KKRExpression> => Box::new(Expr::Dielectric(<>)),
"n" "=" <KKRExpression> => Box::new(Expr::Index(<>)),
};
KKRExpression: Box<Expr<'input>> = {
"<kkr>" "+" "1j" "*" <Expr<Term>> => Box::new(Expr::KramersKronig(<>)),
Expr<Term>,
};
Tier<Op,NextTier>: Box<Expr<'input>> = {
Tier<Op,NextTier> Op NextTier => Box::new(Expr::Op(<>)),
NextTier,
};
Expr<TermType> = Tier<ExprOp, Factor<TermType>>;
Factor<TermType> = Tier<FactorOp, Power<TermType>>;
Power<TermType> = Tier<PowerOp, TermType>;
ExprOp: Opcode = {
"+" => Opcode::Add,
"-" => Opcode::Sub,
};
FactorOp: Opcode = {
"*" => Opcode::Mul,
"/" => Opcode::Div,
};
PowerOp: Opcode = {
"**" => Opcode::Pow,
};
SumTerm: Box<Expr<'input>> = {
ConstantsAndNumbers,
Var => Box::new(Expr::RepeatedVar(<>)),
<Func> "(" <Expr<SumTerm>> ")" => Box::new(Expr::Func(<>)),
"(" <Expr<SumTerm>> ")",
};
Term: Box<Expr<'input>> = {
ConstantsAndNumbers,
Var => Box::new(Expr::Var(<>)),
<Func> "(" <Expr<Term>> ")" => Box::new(Expr::Func(<>)),
"(" <Expr<Term>> ")",
"sum" "[" <Expr<SumTerm>> "]" => Box::new(Expr::Sum(<>)),
};
ConstantsAndNumbers: Box<Expr<'input>> = {
Num => Box::new(Expr::Number(<>)),
Constant => Box::new(Expr::Constant(<>)),
};
Func: Func = {
"sin" => Func::Sin,
"cos" => Func::Cos,
"tan" => Func::Tan,
"sqrt" => Func::Sqrt,
"dawsn" => Func::Dawsn,
"ln" => Func::Ln,
"log" => Func::Log,
"heaviside" => Func::Heaviside,
};
Constant: Constant = {
"1j" => Constant::I,
"pi" => Constant::Pi,
"eps_0" => Constant::Eps0,
"hbar" => Constant::PlanckConstBar,
"h" => Constant::PlanckConst,
"c" => Constant::SpeedOfLight,
};
Num: f64 = {
r"[+-]?[0-9]+(\.[0-9]*)?([eE][-+]?[0-9]+)?" => f64::from_str(<>).unwrap(),
};
Var: &'input str = {
r"[a-zA-Z][a-zA-Z_0-9]*"
};