lila/src/parsing/backend/pest/grammar.pest
Romain Paquet 99434748fa restructure parsing and typing modules
* parsing backend submodules
* move typing to its own module
2023-07-05 16:15:05 +02:00

70 lines
2.2 KiB
Text

// This file is just a little test of pest.rs
source_file = { SOI ~ module_items ~ EOI }
module_items = { (use_statement | definition)* }
// Statements
statement = { assign_statement | declare_statement | return_statement | call_statement | use_statement | while_statement | if_statement }
declare_statement = { ident ~ "=" ~ expr ~ ";" }
assign_statement = { "set" ~ ident ~ "=" ~ expr ~ ";" }
return_statement = { "return" ~ expr? ~ ";" }
call_statement = { call ~ ";" }
use_statement = { "use" ~ import_path ~ ";" }
while_statement = { "while" ~ expr ~ block ~ ";" }
if_statement = { if_branch ~ ("else" ~ (if_branch | block))? ~ ";" }
if_branch = _{ "if" ~ expr ~ block }
// Module paths
import_path = { ident ~ ("::" ~ ident)* }
// Function call
call = { ident ~ "(" ~ args ~ ")" }
args = { (expr ~ ",")* ~ expr? }
definition = { func_def }
// Function definition
func_def = { "fn" ~ ident ~ "(" ~ parameters ~ ")" ~ typ? ~ block }
parameters = {
(parameter ~ ",")* ~ (parameter)?
}
parameter = { ident ~ ":" ~ typ }
// Operators
infix = _{ add | subtract | multiply | divide | not_equal | equal | modulo }
add = { "+" }
subtract = { "-" }
multiply = { "*" }
divide = { "/" }
modulo = { "%" }
equal = { "==" }
not_equal = { "!=" }
prefix = _{ not }
not = { "!" }
// Expressions
expr = { prefix? ~ atom ~ (infix ~ prefix? ~ atom)* }
atom = _{ call | if_expr | block | literal | ident | "(" ~ expr ~ ")" }
block = { "{" ~ statement* ~ expr? ~ "}" }
if_expr = { "if" ~ expr ~ block ~ "else" ~ (block | if_expr) }
ident = @{ (ASCII_ALPHANUMERIC | "_")+ }
typ = _{ ident }
// Literals
literal = _{ boolean_literal | float_literal | integer_literal | string_literal }
boolean_literal = @{ "true" | "false" }
string_literal = ${ "\"" ~ string_content ~ "\"" }
string_content = @{ char* }
char = {
!("\"" | "\\") ~ ANY
| "\\" ~ ("\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t")
| "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4})
}
integer_literal = @{ ASCII_DIGIT+ }
float_literal = @{ ("0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*) ~ "." ~ ASCII_DIGIT* }
WHITESPACE = _{ " " | "\n" | "\t" }
COMMENT = _{ "//" ~ (!NEWLINE ~ ANY)* }