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" }