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)* ~ "*/" }

