Root <- container_doc_comment? container_members eof container_members <- container_declarations (container_field COMMA)* (container_field / container_declarations) container_declarations <- test_decl container_declarations / top_level_comptime container_declarations / doc_comment? KEYWORD_PUB? top_level_decl container_declarations / end_of_word test_decl <- doc_comment? KEYWORD_TEST block top_level_comptime <- doc_comment? KEYWORD_COMPTIME block_expr top_level_decl <- (KEYWORD_EXPORT / KEYWORD_EXTERN / (KEYWORD_INLINE / KEYWORD_NOINLINE))? fn_proto (SEMICOLON / block) / (KEYWORD_EXPORT / KEYWORD_EXTERN )? KEYWORD_THREADLOCAL? var_decl / KEYWORD_USINGNAMESPACE expr SEMICOLON fn_proto <- KEYWORD_FN IDENTIFIER? LPAREN param_decl_list RPAREN byte_align? link_section? call_conv? EXCLAMATIONMARK? type_expr var_decl <- (KEYWORD_CONST / KEYWORD_VAR) IDENTIFIER (COLON type_expr)? byte_align? link_section? (EQUAL expr)? SEMICOLON container_field <- doc_comment? KEYWORD_COMPTIME? IDENTIFIER (COLON (KEYWORD_ANYTYPE / type_expr) byte_align?)? (EQUAL expr)? statement <- KEYWORD_COMPTIME? var_decl / KEYWORD_COMPTIME block_expr_satement / KEYWORD_NOSUSPEND block_expr_satement / KEYWORD_SUSPEND block_expr_satement / KEYWORD_DEFER block_expr_satement / KEYWORD_ERRDEFER payload? block_expr_satement / if_statement / labeled_statement / switch_expr / assign_expr SEMICOLON if_statement <- if_prefix block_expr ( KEYWORD_ELSE payload? statement )? / if_prefix assign_expr ( SEMICOLON / KEYWORD_ELSE payload? statement ) labeled_statement <- block_label? (block / loop_statement) loop_statement <- KEYWORD_INLINE? (for_statement / while_statement) for_statement <- for_prefix block_expr ( KEYWORD_ELSE statement )? / for_prefix assign_expr ( SEMICOLON / KEYWORD_ELSE statement ) while_statement <- WhilePrefix block_expr ( KEYWORD_ELSE payload? statement )? / WhilePrefix assign_expr ( SEMICOLON / KEYWORD_ELSE payload? statement ) block_expr_satement <- block_expr / assign_expr SEMICOLON block_expr <- block_label? block assign_expr <- expr (AssignOp expr)? expr <- bool_or_expr bool_or_expr <- BoolAndExpr (KEYWORD_OR BoolAndExpr)* BoolAndExpr <- CompareExpr (KEYWORD_AND CompareExpr)* CompareExpr <- BitwiseExpr (CompareOp BitwiseExpr)? BitwiseExpr <- BitShiftExpr (BitwiseOp BitShiftExpr)* BitShiftExpr <- AdditionExpr (BitShiftOp AdditionExpr)* AdditionExpr <- MultiplyExpr (AdditionOp MultiplyExpr)* MultiplyExpr <- PrefixExpr (MultiplyOp PrefixExpr)* PrefixExpr <- PrefixOp* PrimaryExpr PrimaryExpr <- AsmExpr / IfExpr / KEYWORD_BREAK BreakLabel? expr? / KEYWORD_COMPTIME expr / KEYWORD_NOSUSPEND expr / KEYWORD_CONTINUE BreakLabel? / KEYWORD_RESUME expr / KEYWORD_RETURN expr? / block_label? LoopExpr / block / CurlySuffixExpr IfExpr <- if_prefix expr (KEYWORD_ELSE payload? expr)? block <- LBRACE statement* RBRACE LoopExpr <- KEYWORD_INLINE? (ForExpr / WhileExpr) ForExpr <- for_prefix expr (KEYWORD_ELSE expr)? WhileExpr <- WhilePrefix expr (KEYWORD_ELSE payload? expr)? CurlySuffixExpr <- type_expr InitList? InitList <- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE / LBRACE expr (COMMA expr)* COMMA? RBRACE / LBRACE RBRACE type_expr <- PrefixTypeOp* ErrorUnionExpr ErrorUnionExpr <- SuffixExpr (EXCLAMATIONMARK type_expr)? SuffixExpr <- KEYWORD_ASYNC PrimaryTypeExpr SuffixOp* FnCallArguments / PrimaryTypeExpr (SuffixOp / FnCallArguments)* PrimaryTypeExpr <- BUILTINIDENTIFIER FnCallArguments / CHAR_LITERAL / ContainerDecl / DOT IDENTIFIER / DOT InitList / ErrorSetDecl / FLOAT / fn_proto / GroupedExpr / LabeledTypeExpr / IDENTIFIER / IfTypeExpr / INTEGER / KEYWORD_COMPTIME type_expr / KEYWORD_ERROR DOT IDENTIFIER / KEYWORD_ANYFRAME / KEYWORD_UNREACHABLE / STRINGLITERAL / switch_expr ContainerDecl <- (KEYWORD_EXTERN / KEYWORD_PACKED)? ContainerDeclAuto ErrorSetDecl <- KEYWORD_ERROR LBRACE IdentifierList RBRACE GroupedExpr <- LPAREN expr RPAREN IfTypeExpr <- if_prefix type_expr (KEYWORD_ELSE payload? type_expr)? LabeledTypeExpr <- block_label block / block_label? LoopTypeExpr LoopTypeExpr <- KEYWORD_INLINE? (ForTypeExpr / WhileTypeExpr) ForTypeExpr <- for_prefix type_expr (KEYWORD_ELSE type_expr)? WhileTypeExpr <- WhilePrefix type_expr (KEYWORD_ELSE payload? type_expr)? switch_expr <- KEYWORD_SWITCH LPAREN expr RPAREN LBRACE switch_prong_list RBRACE AsmExpr <- KEYWORD_ASM KEYWORD_VOLATILE? LPAREN expr AsmOutput? RPAREN AsmOutput <- COLON AsmOutputList AsmInput? AsmOutputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW type_expr / IDENTIFIER) RPAREN AsmInput <- COLON AsmInputList AsmClobbers? AsmInputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN expr RPAREN AsmClobbers <- COLON StringList BreakLabel <- COLON IDENTIFIER block_label <- IDENTIFIER COLON FieldInit <- DOT IDENTIFIER EQUAL expr while_continue_expr <- COLON LPAREN assign_expr RPAREN link_section <- KEYWORD_LINKSECTION LPAREN expr RPAREN call_conv <- KEYWORD_CALLCONV LPAREN expr RPAREN param_decl <- doc_comment? (KEYWORD_NOALIAS / KEYWORD_COMPTIME)? (IDENTIFIER COLON)? param_type / DOT3 param_type <- KEYWORD_ANYTYPE / type_expr if_prefix <- KEYWORD_IF LPAREN expr RPAREN PtrPayload? WhilePrefix <- KEYWORD_WHILE LPAREN expr RPAREN PtrPayload? while_continue_expr? for_prefix <- KEYWORD_FOR LPAREN expr RPAREN ptr_index_payload payload <- PIPE IDENTIFIER PIPE PtrPayload <- PIPE ASTERISK? IDENTIFIER PIPE ptr_index_payload <- PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE SwitchProng <- SwitchCase EQUALRARROW PtrPayload? assign_expr SwitchCase <- SwitchItem (COMMA SwitchItem)* COMMA? / KEYWORD_ELSE SwitchItem <- expr (DOT3 expr)? AssignOp <- ASTERISKEQUAL / SLASHEQUAL / PERCENTEQUAL / PLUSEQUAL / MINUSEQUAL / LARROW2EQUAL / RARROW2EQUAL / AMPERSANDEQUAL / CARETEQUAL / PIPEEQUAL / ASTERISKPERCENTEQUAL / PLUSPERCENTEQUAL / MINUSPERCENTEQUAL / EQUAL CompareOp <- EQUALEQUAL / EXCLAMATIONMARKEQUAL / LARROW / RARROW / LARROWEQUAL / RARROWEQUAL BitwiseOp <- AMPERSAND / CARET / PIPE / KEYWORD_ORELSE / KEYWORD_CATCH payload? BitShiftOp <- LARROW2 / RARROW2 AdditionOp <- PLUS / MINUS / PLUS2 / PLUSPERCENT / MINUSPERCENT MultiplyOp <- PIPE2 / ASTERISK / SLASH / PERCENT / ASTERISK2 / ASTERISKPERCENT PrefixOp <- EXCLAMATIONMARK / MINUS / TILDE / MINUSPERCENT / AMPERSAND / KEYWORD_TRY / KEYWORD_AWAIT PrefixTypeOp <- QUESTIONMARK / KEYWORD_ANYFRAME MINUSRARROW / SliceTypeStart (byte_align / KEYWORD_CONST / KEYWORD_VOLATILE / KEYWORD_ALLOWZERO)* / PtrTypeStart (KEYWORD_ALIGN LPAREN expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_CONST / KEYWORD_VOLATILE / KEYWORD_ALLOWZERO)* / ArrayTypeStart SuffixOp <- LBRACKET expr (DOT2 (expr? (COLON expr)?)?)? RBRACKET / DOT IDENTIFIER / DOTASTERISK / DOTQUESTIONMARK FnCallArguments <- LPAREN expr_list RPAREN SliceTypeStart <- LBRACKET (COLON expr)? RBRACKET PtrTypeStart <- ASTERISK / ASTERISK2 / LBRACKET ASTERISK (LETTERC / COLON expr)? RBRACKET ArrayTypeStart <- LBRACKET expr (COLON expr)? RBRACKET ContainerDeclAuto <- ContainerDeclType LBRACE container_doc_comment? container_members RBRACE ContainerDeclType <- KEYWORD_STRUCT / KEYWORD_OPAQUE / KEYWORD_ENUM (LPAREN expr RPAREN)? / KEYWORD_UNION (LPAREN (KEYWORD_ENUM (LPAREN expr RPAREN)? / expr) RPAREN)? byte_align <- KEYWORD_ALIGN LPAREN expr RPAREN IdentifierList <- (doc_comment? IDENTIFIER COMMA)* (doc_comment? IDENTIFIER)? switch_prong_list <- (SwitchProng COMMA)* SwitchProng? AsmOutputList <- (AsmOutputItem COMMA)* AsmOutputItem? AsmInputList <- (AsmInputItem COMMA)* AsmInputItem? StringList <- (STRINGLITERAL COMMA)* STRINGLITERAL? param_decl_list <- (param_decl COMMA)* param_decl? expr_list <- (expr COMMA)* expr? eof <- !. bin <- [01] bin_ <- '_'? bin oct <- [0-7] oct_ <- '_'? oct hex <- [0-9a-fA-F] hex_ <- '_'? hex dec <- [0-9] dec_ <- '_'? dec bin_int <- bin bin_* oct_int <- oct oct_* dec_int <- dec dec_* hex_int <- hex hex_* ox80_oxBF <- [\200-\277] oxF4 <- '\364' ox80_ox8F <- [\200-\217] oxF1_oxF3 <- [\361-\363] oxF0 <- '\360' ox90_0xBF <- [\220-\277] oxEE_oxEF <- [\356-\357] oxED <- '\355' ox80_ox9F <- [\200-\237] oxE1_oxEC <- [\341-\354] oxE0 <- '\340' oxA0_oxBF <- [\240-\277] oxC2_oxDF <- [\302-\337] mb_utf8_literal <- oxF4 ox80_ox8F ox80_oxBF ox80_oxBF / oxF1_oxF3 ox80_oxBF ox80_oxBF ox80_oxBF / oxF0 ox90_0xBF ox80_oxBF ox80_oxBF / oxEE_oxEF ox80_oxBF ox80_oxBF / oxED ox80_ox9F ox80_oxBF / oxE1_oxEC ox80_oxBF ox80_oxBF / oxE0 oxA0_oxBF ox80_oxBF / oxC2_oxDF ox80_oxBF ascii_char_not_nl_slash_squote <- [\000-\011\013-\046-\050-\133\135-\177] char_escape <- "\\x" hex hex / "\\u{" hex+ "}" / "\\" [nr\\t'"] char_char <- mb_utf8_literal / char_escape / ascii_char_not_nl_slash_squote string_char <- char_escape / [^\\"\n] container_doc_comment <- ('//!' [^\n]* [ \n]*)+ doc_comment <- ('///' [^\n]* [ \n]*)+ line_comment <- '//' ![!/][^\n]* / '////' [^\n]* line_string <- ("\\\\" [^\n]* [ \n]*)+ CHAR_LITERAL <- "'" char_char "'" FLOAT <- "0x" hex_int "." hex_int ([pP] [-+]? dec_int)? / dec_int "." dec_int ([eE] [-+]? dec_int)? / "0x" hex_int [pP] [-+]? dec_int / dec_int [eE] [-+]? dec_int INTEGER <- "0b" bin_int / "0o" oct_int / "0x" hex_int / dec_int STRINGLITERALSINGLE <- '"' string_char* '"' STRINGLITERAL <- STRINGLITERALSINGLE / (line_string)+ IDENTIFIER <- !KEYWORD [A-Za-z_] [A-Za-z0-9_]* BUILTINIDENTIFIER <- "@"[A-Za-z_][A-Za-z0-9_]* AMPERSAND <- '&' ![=] AMPERSANDEQUAL <- '&=' ASTERISK <- '*' ![*%=] ASTERISK2 <- '**' ASTERISKEQUAL <- '*=' ASTERISKPERCENT <- '*%' ![=] ASTERISKPERCENTEQUAL <- '*%=' CARET <- '^' ![=] CARETEQUAL <- '^=' COLON <- ':' COMMA <- ',' DOT <- '.' ![*.?] DOT2 <- '..' ![.] DOT3 <- '...' DOTASTERISK <- '.*' DOTQUESTIONMARK <- '.?' EQUAL <- '=' ![>=] EQUALEQUAL <- '==' EQUALRARROW <- '=>' EXCLAMATIONMARK <- '!' ![=] EXCLAMATIONMARKEQUAL <- '!=' LARROW <- '<' ![<=] LARROW2 <- '<<' ![=] LARROW2EQUAL <- '<<=' LARROWEQUAL <- '<=' LBRACE <- '{' LBRACKET <- '[' LPAREN <- '(' MINUS <- '-' ![%=>] MINUSEQUAL <- '-=' MINUSPERCENT <- '-%' ![=] MINUSPERCENTEQUAL <- '-%=' MINUSRARROW <- '->' PERCENT <- '%' ![=] PERCENTEQUAL <- '%=' PIPE <- '|' ![|=] PIPE2 <- '||' PIPEEQUAL <- '|=' PLUS <- '+' ![%+=] PLUS2 <- '++' PLUSEQUAL <- '+=' PLUSPERCENT <- '+%' ![=] PLUSPERCENTEQUAL <- '+%=' LETTERC <- 'c' QUESTIONMARK <- '?' RARROW <- '>' ![>=] RARROW2 <- '>>' ![=] RARROW2EQUAL <- '>>=' RARROWEQUAL <- '>=' RBRACE <- '}' RBRACKET <- ']' RPAREN <- ')' SEMICOLON <- ';' SLASH <- '/' ![=] SLASHEQUAL <- '/=' TILDE <- '~' fragment end_of_word <- ![a-zA-Z0-9_] KEYWORD_ALIGN <- 'align' end_of_word KEYWORD_ALLOWZERO <- 'allowzero' end_of_word KEYWORD_AND <- 'and' end_of_word KEYWORD_ANYFRAME <- 'anyframe' end_of_word KEYWORD_ANYTYPE <- 'anytype' end_of_word KEYWORD_ASM <- 'asm' end_of_word KEYWORD_ASYNC <- 'async' end_of_word KEYWORD_AWAIT <- 'await' end_of_word KEYWORD_BREAK <- 'break' end_of_word KEYWORD_CALLCONV <- 'callconv' end_of_word KEYWORD_CATCH <- 'catch' end_of_word KEYWORD_COMPTIME <- 'comptime' end_of_word KEYWORD_CONST <- 'const' end_of_word KEYWORD_CONTINUE <- 'continue' end_of_word KEYWORD_DEFER <- 'defer' end_of_word KEYWORD_ELSE <- 'else' end_of_word KEYWORD_ENUM <- 'enum' end_of_word KEYWORD_ERRDEFER <- 'errdefer' end_of_word KEYWORD_ERROR <- 'error' end_of_word KEYWORD_EXPORT <- 'export' end_of_word KEYWORD_EXTERN <- 'extern' end_of_word KEYWORD_FN <- 'fn' end_of_word KEYWORD_FOR <- 'for' end_of_word KEYWORD_IF <- 'if' end_of_word KEYWORD_INLINE <- 'inline' end_of_word KEYWORD_NOALIAS <- 'noalias' end_of_word KEYWORD_NOSUSPEND <- 'nosuspend' end_of_word KEYWORD_NOINLINE <- 'noinline' end_of_word KEYWORD_OPAQUE <- 'opaque' end_of_word KEYWORD_OR <- 'or' end_of_word KEYWORD_ORELSE <- 'orelse' end_of_word KEYWORD_PACKED <- 'packed' end_of_word KEYWORD_PUB <- 'pub' end_of_word KEYWORD_RESUME <- 'resume' end_of_word KEYWORD_RETURN <- 'return' end_of_word KEYWORD_LINKSECTION <- 'linksection' end_of_word KEYWORD_STRUCT <- 'struct' end_of_word KEYWORD_SUSPEND <- 'suspend' end_of_word KEYWORD_SWITCH <- 'switch' end_of_word KEYWORD_TEST <- 'test' end_of_word KEYWORD_THREADLOCAL <- 'threadlocal' end_of_word KEYWORD_TRY <- 'try' end_of_word KEYWORD_UNION <- 'union' end_of_word KEYWORD_UNREACHABLE <- 'unreachable' end_of_word KEYWORD_USINGNAMESPACE <- 'usingnamespace' end_of_word KEYWORD_VAR <- 'var' end_of_word KEYWORD_VOLATILE <- 'volatile' end_of_word KEYWORD_WHILE <- 'while' end_of_word KEYWORD <- KEYWORD_ALIGN / KEYWORD_ALLOWZERO / KEYWORD_AND / KEYWORD_ANYFRAME / KEYWORD_ANYTYPE / KEYWORD_ASM / KEYWORD_ASYNC / KEYWORD_AWAIT / KEYWORD_BREAK / KEYWORD_CALLCONV / KEYWORD_CATCH / KEYWORD_COMPTIME / KEYWORD_CONST / KEYWORD_CONTINUE / KEYWORD_DEFER / KEYWORD_ELSE / KEYWORD_ENUM / KEYWORD_ERRDEFER / KEYWORD_ERROR / KEYWORD_EXPORT / KEYWORD_EXTERN / KEYWORD_FN / KEYWORD_FOR / KEYWORD_IF / KEYWORD_INLINE / KEYWORD_NOALIAS / KEYWORD_NOSUSPEND / KEYWORD_NOINLINE / KEYWORD_OPAQUE / KEYWORD_OR / KEYWORD_ORELSE / KEYWORD_PACKED / KEYWORD_PUB / KEYWORD_RESUME / KEYWORD_RETURN / KEYWORD_LINKSECTION / KEYWORD_STRUCT / KEYWORD_SUSPEND / KEYWORD_SWITCH / KEYWORD_TEST / KEYWORD_THREADLOCAL / KEYWORD_TRY / KEYWORD_UNION / KEYWORD_UNREACHABLE / KEYWORD_USINGNAMESPACE / KEYWORD_VAR / KEYWORD_VOLATILE / KEYWORD_WHILE