Files
mist/crates/parser/src/grammar.pest
T

712 lines
14 KiB
Plaintext

// ======================================================
// LEXICAL
// ======================================================
WHITESPACE = _{ " " | "\t" | "\r" | "\n" }
COMMENT = _{ "//" ~ (!"\n" ~ ANY)* }
// ------------------------------------------------------
// PRIMITIVES
// ------------------------------------------------------
keyword = {
"if"
| "else"
| "fn"
| "for"
| "while"
| "match"
| "return"
| "break"
| "continue"
| "struct"
| "enum"
| "class"
| "trait"
| "impl"
| "use"
| "pub"
| "mut"
| "let"
| "true"
| "false"
| "dyn"
| "loop"
| "unsafe"
| "override"
| "const"
| "type"
| "virtual"
}
identifier = @{
!(keyword ~ !(ASCII_ALPHANUMERIC | "_")) ~ (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_")*
}
integer = @{ ASCII_DIGIT+ }
float = @{
ASCII_DIGIT+ ~ "." ~ ASCII_DIGIT+
}
boolean = {
"true"
| "false"
}
string_lit = {
"\"" ~ inner_str ~ "\""
}
inner_str = @{
(!"\"" ~ ("\\\"" | ANY))*
}
semicolon = _{ ";" }
static_path = {
identifier ~ ("::" ~ identifier)*
}
// ======================================================
// PROGRAM
// ======================================================
program = {
SOI ~ top_level* ~ EOI
}
module_program = {
SOI ~ top_level?
}
// ======================================================
// MODIFIERS
// ======================================================
visibility = { "pub" ~ ("(" ~ static_path ~ ")")? }
mutable = { "mut" }
// ======================================================
// GENERICS
// ======================================================
generic_decl = { lifetime | (identifier ~ (":" ~ generic ~ ("+" ~ generic)*)?) }
generics_decl = { "<" ~ (generic_decl ~ ("," ~ generic_decl)*)? ~ ">" }
generic = { lifetime | type_expr }
generics = { "<" ~ (generic ~ ("," ~ generic)*)? ~ ">" }
// ======================================================
// TYPES
// ======================================================
tuple_type = {
"(" ~ (type_expr ~ ("," ~ type_expr)*)? ~ ","? ~ ")"
}
path_type = {
static_path ~ generics?
}
unsafe_ref_type = {
mutable? ~ "unsafe" ~ "*"
}
ref_type = {
mutable? ~ lifetime? ~ "&"
}
fn_kind_fn = { "fn" }
fn_kind_unsafe = { "unsafe" ~ "fn" }
fn_kind_closure = { "Fn" }
fn_kind_once = { "FnOnce" }
fn_kind_mut = { "FnMut" }
fn_kind = _{
fn_kind_fn
| fn_kind_unsafe
| fn_kind_closure
| fn_kind_once
| fn_kind_mut
}
fn_type = {
fn_kind ~ "(" ~ (type_expr ~ ("," ~ type_expr)*)? ~ ")"
}
dyn_type = {
"dyn" ~ type_expr
}
void_type = {
"void"
}
array_type = {
"[" ~ integer? ~ "]"
}
type_expr = {
(void_type | path_type | tuple_type | dyn_type) ~ (unsafe_ref_type | ref_type | fn_type | array_type)*
}
lifetime = {
"'" ~ identifier
}
// ======================================================
// LITERALS
// ======================================================
literal = {
float
| integer
| boolean
| string_lit
}
// ======================================================
// PATTERNS
// ======================================================
etc_pattern = { ".." }
multi_pat_template = _{
((pattern | etc_pattern) ~ ("," ~ (pattern | etc_pattern))* ~ ","?)?
}
tuple_pattern = {
"(" ~ (pattern | etc_pattern) ~ "," ~ multi_pat_template ~ ")"
}
named_tuple_pattern = {
static_path ~ "(" ~ multi_pat_template ~ ")"
}
struct_destruct = {
identifier ~ (":" ~ pattern)?
}
struct_pattern = {
static_path ~ "{" ~ ((struct_destruct | etc_pattern) ~ ("," ~ (struct_destruct | etc_pattern))*)? ~ "}"
}
path_pattern = {
mutable? ~ static_path
}
pattern = _{
named_tuple_pattern
| tuple_pattern
| struct_pattern
| literal
| path_pattern
}
// ======================================================
// ATTRIBUTES / META
// ======================================================
attribute = {
"#" ~ "[" ~ meta ~ "]"
}
mod_attribute = {
"#" ~ "!" ~ "[" ~ meta ~ "]"
}
meta = {
static_path ~ ("=" ~ literal | "(" ~ meta_list? ~ ")")?
}
meta_list = {
(meta ~ ("," ~ meta)* ~ ","?)?
}
attributes = {
attribute*
}
// ======================================================
// DECLARATION HELPERS
// ======================================================
as_kw = { "as" }
var_decl = {
("let" ~ pattern ~ ("," ~ pattern)*)
| (type_expr ~ as_kw ~ (!tuple_pattern ~ pattern ~ ("," ~ pattern)+))
| (type_expr ~ (!tuple_pattern ~ pattern ~ ("," ~ pattern)*))
}
field = {
visibility? ~ type_expr ~ identifier
}
param = {
(type_expr ~ pattern)
| pattern
}
field_list = {
(field ~ ";")*
}
param_list = {
(param ~ ("," ~ param)* ~ ","?)?
}
// ======================================================
// IMPORTS / MODULES
// ======================================================
include_global = {
"#" ~ "include" ~ "<" ~ identifier ~ ("/" ~ identifier)* ~ ">"
}
include_use_global = {
visibility? ~ "#" ~ "use" ~ static_path ~ semicolon
}
include_local = {
"#" ~ "include" ~ string_lit
}
import = {
visibility? ~ "use" ~ static_path ~ semicolon
}
declare_module = {
visibility? ~ "module" ~ identifier ~ semicolon
}
// ======================================================
// STRUCTS
// ======================================================
struct_decl = {
visibility? ~ "struct" ~ identifier ~ generics_decl? ~ "{" ~ field_list ~ "}"
}
// ======================================================
// ENUMS
// ======================================================
enum_named = {
identifier
}
enum_tuple = {
identifier ~ tuple_type
}
enum_struct = {
identifier ~ "{" ~ field_list ~ "}"
}
enum_field = _{
enum_tuple
| enum_struct
| enum_named
}
enum_decl = {
visibility? ~ "enum" ~ identifier ~ generics_decl? ~ "{" ~ (enum_field ~ ";")* ~ "}"
}
// ======================================================
// CLASSES
// ======================================================
class_constructor = {
visibility? ~ "constructor" ~ generics_decl? ~ "(" ~ param_list ~ ")" ~ block
}
class_fields = {
class_field*
}
class_field = {
field ~ ("=" ~ expr)? ~ semicolon
}
self_param = {
(ref_px ~ lifetime?)? ~ mutable? ~ "self"
}
method_args = _{
((self_param ~ ("," ~ param_list)?) | param_list) ~ ","?
}
class_item = _{
impl_decl
| function_decl
}
class_decl = {
visibility? ~ "class" ~ identifier ~ generics_decl? ~ (":" ~ expr_path)? ~ "{" ~ class_fields ~ class_constructor? ~ class_item* ~ "}"
}
// ======================================================
// IMPL
// ======================================================
impl_for_decl = {
"impl" ~ generics_decl? ~ type_expr ~ "for" ~ type_expr ~ "{" ~ function_decl* ~ "}"
}
impl_decl = {
"impl" ~ generics_decl? ~ type_expr ~ "{" ~ function_decl* ~ "}"
}
// ======================================================
// Traits
// ======================================================
trait_requirements = { ":" ~ generic ~ ("+" ~ generic)* }
trait_item = _{
function_decl
}
trait_decl = {
visibility? ~ "trait" ~ identifier ~ generics_decl? ~ trait_requirements? ~ "{" ~ trait_item* ~ "}"
}
// ======================================================
// FUNCTIONS
// ======================================================
virtual_kw = { "virtual" }
override_kw = { "override" ~ ("(" ~ expr_path ~ ")")? }
function_decl = {
visibility? ~ virtual_kw? ~ ("void" | type_expr) ~ identifier ~ generics_decl? ~ "(" ~ method_args ~ ")" ~ override_kw? ~ (block | semicolon)
}
// ======================================================
// CONSTANTS / STATIC
// ======================================================
const_decl = { "const" ~ var_decl_statement ~ ";" }
static_decl = { "static" ~ var_decl_statement ~ ";" }
// ======================================================
// Type aliases
// ======================================================
type_alias = { "type" ~ identifier ~ generics_decl? ~ "=" ~ type_expr ~ ";" }
// ======================================================
// TOP LEVEL
// ======================================================
top_level = {
mod_attribute
| (attributes ~ (include_global | include_local | include_use_global | import | impl_for_decl | impl_decl | trait_decl | struct_decl | enum_decl | class_decl | declare_module | function_decl | const_decl | static_decl | type_alias))
}
// ======================================================
// STATEMENTS
// ======================================================
block = {
"{" ~ statement_list ~ expr? ~ "}"
}
unsafe_block = {
"unsafe" ~ block
}
statement_list = {
statement*
}
statement = _{
control_flow
| top_level
| (expr ~ semicolon)
}
// ------------------------------------------------------
// BASIC STATEMENTS
// ------------------------------------------------------
basic_stmt = {
return_stmt
| break_stmt
| continue_stmt
| var_decl_statement
}
return_stmt = {
"return" ~ expr?
}
break_stmt = {
"break"
}
continue_stmt = {
"continue"
}
var_decl_statement = {
var_decl ~ ("=" ~ expr)?
}
// ------------------------------------------------------
// CONDITIONALS
// ------------------------------------------------------
control_flow = {
if_stmt
| while_stmt
| c_for_stmt
| for_stmt
| match_stmt
| loop_stmt
| block
| unsafe_block
}
statement_branch = { (expr_no_struct | ("(" ~ expr ~ ")")) ~ block }
else_if = _{
"else" ~ "if" ~ statement_branch
}
else_if_list = {
else_if*
}
if_stmt = {
"if" ~ statement_branch ~ else_if_list ~ ("else" ~ block)?
}
// ------------------------------------------------------
// LOOPS
// ------------------------------------------------------
while_stmt = {
"while" ~ statement_branch
}
c_for_stmt = {
"for" ~ "(" ~ statement ~ statement ~ expr ~ ")" ~ block
}
for_stmt = {
"for" ~ pattern ~ "in" ~ expr ~ block
}
loop_stmt = {
"loop" ~ block
}
// ------------------------------------------------------
// MATCH
// ------------------------------------------------------
pattern_list = { pattern ~ ("|" ~ pattern)* }
match_item = {
pattern_list ~ "=>" ~ (block | (expr ~ ","))
}
match_stmt = {
"match" ~ (expr_no_struct | "(" ~ expr ~ ")") ~ "{" ~ match_item* ~ "}"
}
// ======================================================
// EXPRESSIONS
// ======================================================
// ------------------------------------------------------
// CLOSURES
// ------------------------------------------------------
closure = {
("(" ~ param_list ~ ")" ~ "=>" ~ expr)
| (type_expr ~ "(" ~ param_list ~ ")" ~ "=>" ~ expr)
}
// ------------------------------------------------------
// TUPLES & ARRAYS
// ------------------------------------------------------
tuple = {
"(" ~ (expr ~ ("," ~ expr)*)? ~ ","? ~ ")"
}
array_repeat = {
"[" ~ expr ~ ";" ~ expr ~ "]"
}
array = {
"[" ~ (expr ~ ("," ~ expr)* ~ ","?)? ~ "]"
}
// ------------------------------------------------------
// MACROS
// ------------------------------------------------------
macro_inner_v = @{
string_lit
| ("(" ~ macro_inner_v* ~ ")")
| ("[" ~ macro_inner_v* ~ "]")
| ("{" ~ macro_inner_v* ~ "}")
| (!("(" | ")" | "[" | "]" | "{" | "}") ~ ANY)
}
// ------------------------------------------------------
// PRIMARY EXPRESSIONS
// ------------------------------------------------------
expr_path_segment = {
identifier ~ generics?
}
expr_path = {
expr_path_segment ~ ("::" ~ expr_path_segment)*
}
primary = {
control_flow
| closure
| basic_stmt
| literal
| expr_path
| tuple
| array_repeat
| array
}
// ------------------------------------------------------
// POSTFIX EXPRESSIONS
// ------------------------------------------------------
field_px = {
"." ~ identifier ~ generics?
}
tuple_field_px = {
"." ~ integer ~ generics?
}
call_px = {
"(" ~ (expr ~ ("," ~ expr)*)? ~ ")"
}
macro_call_paren = { "!" ~ "(" ~ macro_inner_v* ~ ")" }
macro_call_bracket = { "!" ~ "[" ~ macro_inner_v* ~ "]" }
macro_call_brace = { "!" ~ "{" ~ macro_inner_v* ~ "}" }
struct_field_decl = {
identifier ~ (":" ~ expr)?
}
struct_px = {
"{" ~ (struct_field_decl ~ ("," ~ struct_field_decl)*)? ~ ","? ~ "}"
}
index_px = {
"[" ~ expr ~ "]"
}
as_px = {
"as" ~ type_expr
}
try_px = {
"?"
}
increment = {
"++"
}
decrement = {
"--"
}
postfix = {
field_px
| tuple_field_px
| call_px
| macro_call_paren
| macro_call_bracket
| macro_call_brace
| struct_px
| index_px
| as_px
| try_px
| increment
| decrement
}
// ------------------------------------------------------
// PREFIX EXPRESSIONS
// ------------------------------------------------------
deref_px = { "*" }
mut_ref_px = { "&" ~ mutable }
ref_px = { "&" }
not_px = { "!" }
neg_px = { "-" }
prefix = {
deref_px
| mut_ref_px
| ref_px
| not_px
| neg_px
}
// ------------------------------------------------------
// OPERATORS
// ------------------------------------------------------
bin_op = {
"+="
| "-="
| "*="
| "/="
| "%="
| "&="
| "|="
| "^="
| "<<="
| ">>="
| "<<"
| ">>"
| "..="
| ".."
| "<="
| ">="
| "=="
| "!="
| "&&"
| "||"
| "->"
| "+"
| "-"
| "*"
| "/"
| "%"
| "<"
| ">"
| "&"
| "|"
| "^"
| "="
}
// ------------------------------------------------------
// EXPRESSIONS
// ------------------------------------------------------
expr = { term ~ (bin_op ~ term)* }
term = { prefix* ~ primary ~ postfix* }
expr_no_struct = { term_no_struct ~ (bin_op ~ term_no_struct)* }
term_no_struct = { prefix* ~ primary ~ (!struct_px ~ postfix)* }