# Grammar This page is the canonical grammar reference for Decodal syntax. Parser implementations such as the Rust parser, Tree-sitter grammar, and Lezer grammar should follow this grammar and may add implementation-specific precedence annotations where needed. ## Lexical grammar ```ebnf source_character = ? any Unicode scalar value ? ; newline = "\n" | "\r\n" | "\r" ; space = " " | "\t" | newline ; comment = "#" , { ? any character except newline ? } ; digit = "0" … "9" ; letter = "A" … "Z" | "a" … "z" ; identifier = letter , { letter | digit | "_" } ; integer = digit , { digit } ; float = digit , { digit } , "." , digit , { digit } ; string = '"' , { string_character | escape } , '"' ; string_character = ? any character except '"', "\\", or newline ? ; escape = "\\" , source_character ; regex = "/" , regex_character , { regex_character } , "/" ; regex_character = escape | ? any character except "/", "\\", or newline ? ; ``` Whitespace and comments separate tokens and are otherwise ignored by the parser. ## Syntactic grammar ```ebnf module = { statement } ; statement = field_definition , [ ";" ] | expression , [ ";" ] ; expression = default_expression ; default_expression = patch_expression , [ "default" , default_expression ] ; patch_expression = compose_expression , { "//" , compose_expression } ; compose_expression = logical_or_expression , { "&" , logical_or_expression } ; logical_or_expression = logical_and_expression , { "||" , logical_and_expression } ; logical_and_expression = comparison_expression , { "&&" , comparison_expression } ; comparison_expression = concat_expression , [ comparison_operator , concat_expression ] ; concat_expression = additive_expression , { "++" , additive_expression } ; additive_expression = multiplicative_expression , { ( "+" | "-" ) , multiplicative_expression } ; multiplicative_expression = unary_expression , { ( "*" | "/" ) , unary_expression } ; unary_expression = [ "!" | "-" ] , postfix_expression ; postfix_expression = primary_expression , { call_suffix | path_suffix } ; call_suffix = "(" , [ argument_list ] , ")" ; path_suffix = "." , identifier ; primary_expression = literal | identifier | comparison_constraint | object | array | let_expression | function_expression | match_expression | import_expression | "(" , expression , ")" ; literal = string | integer | float | "true" | "false" | regex ; comparison_operator = "==" | "!=" | "<" | "<=" | ">" | ">=" ; comparison_constraint = ( "<" | "<=" | ">" | ">=" ) , expression ; object = "{" , [ field_definition , { ";" , field_definition } , [ ";" ] ] , "}" ; field_definition = field_path , "=" , expression ; field_path = identifier , { "." , identifier } ; array = "[" , [ expression , { "," , expression } , [ "," ] ] , "]" ; let_expression = "let" , { field_definition , ";" } , "in" , expression ; function_expression = "(" , [ parameter_list ] , ")" , "=>" , expression ; parameter_list = parameter , { "," , parameter } , [ "," ] ; parameter = identifier , [ ":" , expression ] ; match_expression = "match" , expression , "{" , [ match_arm , { ";" , match_arm } , [ ";" ] ] , "}" ; match_arm = pattern , ":" , expression ; pattern = "_" | expression ; import_expression = "import" , string ; argument_list = expression , { "," , expression } , [ "," ] ; ``` ## Precedence Precedence is highest first. 1. function call and field path reference 2. unary `!` and `-` 3. `*` and `/` 4. `+` and `-` 5. `++` 6. `==`, `!=`, `<`, `<=`, `>`, `>=` 7. `&&` 8. `||` 9. `&` 10. `//` 11. `default` Binary operators are left-associative except `default`, which is right-associative. ## Tooling mapping Syntax tooling should derive token categories from this grammar rather than making a tool-specific grammar canonical. Tree-sitter and Lezer grammars are implementation artifacts that follow this page.