File size: 2,195 Bytes
2409829
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
WHITESPACE    =  _{ " " | "\t" }

// TODO: Proper indentation and formatting
program       =  _{ SOI ~ expr ~ EOI }

expr          =  { atom ~ (infix ~ atom)* }
atom          =  _{ prefix? ~ primary ~ postfix? }
infix         =  _{ add | sub | mul | div | pow | paren }
add           =  { "+" }    // Addition
sub           =  { "-" }    // Subtraction
mul           =  { "*" }    // Multiplication
div           =  { "/" }    // Division
mod           =  { "%" }    // Modulo
pow           =  { "^" }    // Exponentiation
paren         =  { ""  }    // Implicit multiplication operator

prefix        =  _{ neg | sqrt }
neg           =  { "-" }    // Negation
sqrt          =  { "sqrt" }

postfix       =  _{ fac }
fac           =  { "!" }    // Factorial

primary       =  _{ ("(" ~ expr ~ ")") | lit | constant | fn_call | ident  }
fn_call       =  { ident ~ "(" ~ expr ~ ("," ~ expr)* ~ ")" }
ident           =  @{ (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_")* }
lit           =  { unit | ((float | int) ~ unit?) }

float         =  @{ int ~ "." ~ int? ~ exp? | int ~ exp }
exp           =  _{ ^"e" ~ ("+" | "-")? ~ int }
int           =  @{ ASCII_DIGIT+ }

unit          =  ${ (scale ~ base_unit) | base_unit ~ !ident}
base_unit     =  _{ meter | second | gram }
meter         =  { "m" }
second        =  { "s" }
gram          =  { "g" }

scale         =  _{ nano | micro | milli | centi | deci | deca | hecto | kilo | mega | giga | tera }
nano          =  { "n" }
micro         =  { "µ" | "u" }
milli         =  { "m" }
centi         =  { "c" }
deci          =  { "d" }
deca          =  { "da" }
hecto         =  { "h" }
kilo          =  { "k" }
mega          =  { "M" }
giga          =  { "G" }
tera          =  { "T" }

// Constants
constant              =  { infinity | imaginary_unit | pi | tau | euler_number | golden_ratio | gravity_acceleration }
infinity              =  { "inf" | "INF" | "infinity" | "INFINITY" | "∞" }
imaginary_unit        =  { "i" | "I" }
pi                    =  { "pi" | "PI" | "π" }
tau                   =  { "tau" | "TAU" | "τ" }
euler_number          =  { "e" }
golden_ratio          =  { "phi" | "PHI" | "φ" }
gravity_acceleration  =  { "G" }