// ====================================================== // LEXICAL // ====================================================== WHITESPACE = _{ " " | "\t" | "\r" | "\n" } COMMENT = _{ "//" ~ (!"\n" ~ ANY)* } // ------------------------------------------------------ // PRIMITIVES // ------------------------------------------------------ keyword = { "if" | "else" | "for" | "while" | "match" | "return" | "break" | "continue" | "struct" | "enum" | "class" | "trait" | "impl" | "pub" | "mut" | "var" | "true" | "false" | "dyn" | "self" } identifier = @{ !keyword ~ (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 } // ====================================================== // MODIFIERS // ====================================================== visibility = { "pub" ~ ("(" ~ static_path ~ ")")? } mutable = { "mut" } var = { "var" } // ====================================================== // ERROR RECOVERY // ====================================================== unexpected_statement = { (!(semicolon | "}" | statement) ~ ANY)+ } // ====================================================== // GENERICS // ====================================================== generic_decl = { lifetime | (identifier ~ (":" ~ type_expr_param ~ ("+" ~ type_expr_param)*)?) } generics_decl = { "<" ~ (generic_decl ~ ("," ~ generic_decl)*)? ~ ">" } generic = { lifetime | type_expr_param } generics = { "<" ~ (generic ~ ("," ~ generic)*)? ~ ">" } // ====================================================== // TYPES // ====================================================== tuple_type = { "(" ~ (type_expr ~ ("," ~ type_expr)*)? ~ ")" } path_type = { static_path ~ ("<" ~ (type_expr_param ~ ("," ~ type_expr_param)*)? ~ ">")? } ref_type = { mutable? ~ lifetime? ~ "*" } dyn_type = { "dyn" } type_expr = { (path_type | tuple_type) ~ (ref_type | dyn_type)* } lifetime = { "'" ~ identifier } type_expr_param = { type_expr | lifetime } // ====================================================== // LITERALS // ====================================================== literal = { float | integer | boolean | string_lit } // ====================================================== // PATTERNS // ====================================================== tuple_pattern = { "[" ~ (identifier ~ ("," ~ identifier)*) ~ "]" } named_tuple_pattern = { static_path ~ "[" ~ (identifier ~ ("," ~ identifier)*)? ~ "]" } struct_pattern = { static_path ~ "{" ~ (identifier ~ ("," ~ identifier)*)? ~ "}" } pattern = _{ named_tuple_pattern | tuple_pattern | struct_pattern | literal | static_path } // ====================================================== // ATTRIBUTES / META // ====================================================== attribute = { "#" ~ "[" ~ meta ~ "]" } mod_attribute = { "#" ~ "!" ~ "[" ~ meta ~ "]" } meta = { static_path ~ ("=" ~ literal | "(" ~ meta_list? ~ ")")? } meta_list = { meta ~ ("," ~ meta)* ~ ","? } attributes = { attribute* } // ====================================================== // DECLARATION HELPERS // ====================================================== var_decl = { (var | type_expr) ~ mutable? ~ pattern } field = { visibility? ~ type_expr ~ identifier } field_list = { field ~ ("," ~ field)* ~ ","? } param_list = { var_decl ~ ("," ~ var_decl)* ~ ","? } // ====================================================== // IMPORTS / MODULES // ====================================================== import = { visibility? ~ "use" ~ "<" ~ static_path ~ ">" ~ semicolon } mod_package = { visibility? ~ "mod" ~ 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_fields = _{ enum_field ~ ("," ~ enum_field)* ~ ","? } enum_decl = { visibility? ~ "enum" ~ identifier ~ generics_decl? ~ "{" ~ enum_fields ~ "}" } // ====================================================== // CLASSES // ====================================================== class_constructor = { visibility? ~ "constructor" ~ generics_decl? ~ "(" ~ param_list? ~ ")" ~ block } class_fields = { class_field* } class_field = { field ~ ("=" ~ expr)? ~ semicolon } self_param = { "self" ~ mutable? ~ deref_px? } method = { visibility? ~ type_expr ~ identifier ~ generics_decl? ~ "(" ~ self_param? ~ ("," ~ param_list?)? ~ ")" ~ block } class_item = _{ impl_decl | method } class_decl = { visibility? ~ "class" ~ identifier ~ generics_decl? ~ "{" ~ class_fields ~ class_constructor ~ class_item* ~ "}" } // ====================================================== // IMPL // ====================================================== impl_for_decl = { "impl" ~ generics_decl? ~ type_expr ~ "for" ~ type_expr ~ "{" ~ method* ~ "}" } impl_decl = { "impl" ~ generics_decl? ~ type_expr ~ "{" ~ method* ~ "}" } // ====================================================== // Traits // ====================================================== trait_requirements = { ":" ~ type_expr_param ~ ("+" ~ type_expr_param)* } method_no_body = { visibility? ~ type_expr ~ identifier ~ generics_decl? ~ "(" ~ self_param? ~ ("," ~ param_list?)? ~ ")" ~ semicolon } trait_item = _{ method | method_no_body } trait_decl = { visibility? ~ "trait" ~ identifier ~ generics_decl? ~ trait_requirements? ~ "{" ~ trait_item* ~ "}" } // ====================================================== // FUNCTIONS // ====================================================== function_decl = { visibility? ~ type_expr ~ identifier ~ "(" ~ param_list? ~ ")" ~ block } // ====================================================== // TOP LEVEL // ====================================================== top_level = { (attributes ~ (import | impl_for_decl | impl_decl | trait_decl | struct_decl | enum_decl | class_decl | mod_package | function_decl)) | mod_attribute } // ====================================================== // STATEMENTS // ====================================================== block = { "{" ~ (statement | unexpected_statement)* ~ "}" } statement = _{ control_flow | (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 | block } statement_branch = { "(" ~ expr ~ ")" ~ statement } else_if = { "else" ~ "if" ~ statement_branch } else_if_list = { else_if* } if_stmt = { "if" ~ statement_branch ~ else_if_list ~ ("else" ~ statement)? } // ------------------------------------------------------ // LOOPS // ------------------------------------------------------ while_stmt = { "while" ~ statement_branch } c_for_stmt = { "for" ~ "(" ~ statement ~ expr ~ semicolon ~ statement ~ ")" ~ statement } for_stmt = { "for" ~ "(" ~ mutable? ~ pattern ~ "in" ~ expr ~ ")" ~ statement } // ------------------------------------------------------ // MATCH // ------------------------------------------------------ pattern_list = { pattern ~ ("|" ~ pattern)* } match_item = { pattern_list ~ "=>" ~ block } match_stmt = { "match" ~ "(" ~ expr ~ ")" ~ "{" ~ match_item* ~ "}" } // ====================================================== // EXPRESSIONS // ====================================================== // ------------------------------------------------------ // TUPLES & ARRAYS // ------------------------------------------------------ tuple = { "(" ~ (expr ~ ("," ~ expr)*)? ~ ")" } array = { "[" ~ expr ~ ";" ~ expr ~ "]" // Repeat notation: [0; 10] | "[" ~ (expr ~ ("," ~ expr)* ~ ","?)? ~ "]" // Standard elements initialization } // ------------------------------------------------------ // MACROS // ------------------------------------------------------ macro_inner_v = { string_lit | ("(" ~ macro_inner_v* ~ ")") | (!("(" | ")") ~ ANY) } // ------------------------------------------------------ // PRIMARY EXPRESSIONS // ------------------------------------------------------ expr_path_segment = { identifier ~ ("::" ~ generics)? } expr_path = { expr_path_segment ~ ("::" ~ expr_path_segment)* } primary = { basic_stmt | literal | expr_path | tuple | array } // ------------------------------------------------------ // POSTFIX EXPRESSIONS // ------------------------------------------------------ field_px = { "." ~ identifier ~ ("::" ~ generics)? } call_px = { "(" ~ (expr ~ ("," ~ expr)*)? ~ ")" } macro_call_px = { "!" ~ "(" ~ 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 | call_px | macro_call_px | struct_px | index_px | as_px | try_px | increment | decrement } // ------------------------------------------------------ // PREFIX EXPRESSIONS // ------------------------------------------------------ deref_px = { "*" } mut_ref_px = { "&" ~ mutable } ref_px = { "&" } new_px = { "new" ~ generics? } not_px = { "!" } neg_px = { "-" } prefix = { deref_px | mut_ref_px | ref_px | new_px | not_px | neg_px } // ------------------------------------------------------ // OPERATORS // ------------------------------------------------------ bin_op = { "+=" | "-=" | "/=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | "<<" | ">>" | "..=" | ".." | "<=" | ">=" | "==" | "!=" | "&&" | "||" | "+" | "-" | "*" | "/" | "%" | "<" | ">" | "&" | "|" | "^" | "=" } // ------------------------------------------------------ // EXPRESSIONS // ------------------------------------------------------ expr = { term ~ (bin_op ~ term)* } term = { prefix* ~ primary ~ postfix* }