main = { SOI ~ model+ ~ EOI }
model = { "model" ~ name ~ "(" ~ unknown? ~ ("," ~ unknown)* ~ ")" ~ "{" ~ statement* ~ "}" }
definition = { "let" ~ name ~ "=" ~ expression }
unknown = { name ~ dependents? ~ codomain? }
dependents = { "(" ~ name ~ ("," ~ name )* ~ ")" }
codomain = { "->" ~ domain }
domain = { range | domain_name }
range = { "[" ~ real ~ "..." ~ real ~ "]" }
statement = { definition | submodel | rate_equation | equation }
submodel = { "use" ~ call ~ ("as" ~ name)? }
rate_equation = { "dot" ~ "(" ~ name ~ ")" ~ ("+=" | "=") ~ expression }
equation = { expression ~ "=" ~ expression }
expression = { sign? ~ term ~ (term_op ~ term)* }
term = { factor ~ (factor_op ~ factor)* }
factor = { call | real | integer | name | "(" ~ expression ~ ")" }
call = { name ~ "(" ~ call_arg ~ ("," ~ call_arg )* ~ ")" }
call_arg = { (name ~ "=")? ~ expression }
sign = @{ ("-"|"+") }
term_op = @{ "-"|"+" }
factor_op = @{ "*"|"/" }
name = @{ 'a'..'z' ~ ("_" | 'a'..'z' | 'A'..'Z' | '0'..'9')* }
domain_name = @{ 'A'..'Z' ~ ('a'..'z' | 'A'..'Z' | '0'..'9')* }
integer = @{ ('0'..'9')+ }
real = @{ ( ('0'..'9')+ ~ "." ~ ('0'..'9')+ ) | integer }
WHITESPACE = _{ " " | NEWLINE | "\t" }
COMMENT = _{
"/*" ~ (!"*/" ~ ANY)* ~ "*/"
| "//" ~ (!NEWLINE ~ ANY)*
}