sunflower/src/grammar.pest

92 lines
2.3 KiB
Plaintext

WHITESPACE = _{ " " | "\t" | NEWLINE }
COMMENT = _{ "/*" ~ (!"*/" ~ ANY)* ~ "*/" | "//" ~ (!NEWLINE ~ ANY)* }
number = @{
"-"?
~ ("0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*)
~ ("." ~ ASCII_DIGIT+)?
~ (^"e" ~ ("+" | "-")? ~ ASCII_DIGIT+)?
}
string = ${ "\"" ~ inner ~ "\"" }
inner = @{ character* }
character = {
!("\"" | "\\") ~ ANY
| "\\" ~ ("\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t")
| "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4})
}
char = ${ "\'" ~ character ~ "\'" }
boolean = { "true" | "false" }
identifier = @{ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_" )* }
call = ${
identifier ~ call_params
}
call_params = !{ "(" ~ (expression ~ ","?)* ~ ")" }
parens = { "(" ~ expression ~ ")" }
const_value = { number | string | char | boolean }
value = { (const_value | call | identifier | parens) ~ method_call }
method_call = { (("." ~ identifier ~ call_params) ~ method_call)? }
expression = { if_block_expr | equality }
equality = { inequality ~ ((equals | not_equals) ~ inequality)? }
inequality = { sum ~ ((less_than | greater_than | less_than_or_equal | greater_than_or_equal) ~ sum)? }
sum = { product ~ ((plus | minus) ~ product)* }
product = { value ~ ((times | divide | modulo) ~ value)* }
root_statement = {
SOI ~ statement* ~ EOI
}
statement = { ( ret | assignment | assignment_let | expression ) ~ ";" | def | while_block | if_block | block }
block = { "{" ~ statement* ~ "}" }
func_block = { "{" ~ statement* ~ expression? ~ "}" }
assignment_let = { "let" ~ identifier ~ "=" ~ expression }
assignment = { identifier ~ "=" ~ expression }
ret = { "return" ~ expression? }
while_block = { "while" ~ expression ~ block }
if_block = { "if" ~ expression ~ block ~ ("else if" ~ expression ~ block)* ~ ("else" ~ block)? }
if_block_expr = { "if" ~ expression ~ if_block_expr_block ~ ("else if" ~ expression ~ if_block_expr_block)* ~ "else" ~ if_block_expr_block }
if_block_expr_block = { "{" ~ statement* ~ expression ~ "}" }
def_params = { "(" ~ (identifier ~ ","?)* ~ ")" }
def = { "def" ~ identifier ~ def_params ~ func_block }
equals = { "==" }
not_equals = { "!=" }
less_than = { "<" }
greater_than = { ">" }
less_than_or_equal = { "<=" }
greater_than_or_equal = { ">=" }
plus = { "+" }
minus = { "-" }
times = { "*" }
divide = { "/" }
modulo = { "%" }