15
8
Fork
You've already forked zig-spec
2

Trying to validate grammar #30

Open
opened 2021年03月09日 18:56:30 +01:00 by markfirmware · 16 comments
markfirmware commented 2021年03月09日 18:56:30 +01:00 (Migrated from github.com)
Copy link

I cannot get validation on a 20.04 cloud host, a gitpod cloud host nor in gh actions. All of the tests have 127 vs 0

cd grammar
./validate.sh
I cannot get validation on a 20.04 cloud host, a [gitpod cloud host](https://gitpod.io/#https://github.com/markfirmware/zig-spec/tree/gh-actions-validation) nor in [gh actions](https://github.com/markfirmware/zig-spec/actions). All of the tests have 127 vs 0 cd grammar ./validate.sh
markfirmware commented 2021年03月09日 18:59:51 +01:00 (Migrated from github.com)
Copy link
FYI https://discord.com/channels/223421264751099906/302022825752002561/818905779733266453
markfirmware commented 2021年03月10日 20:50:32 +01:00 (Migrated from github.com)
Copy link

Is the grammar in working order? Do you typically use some other than linux to run check_parser.sh?

I noticed a different version of the grammar at the web page
github.com/ziglang/www.ziglang.org@0888fffe95/content/documentation/master/index.html (L13092-L13593)

Is the grammar in working order? Do you typically use some other than linux to run check_parser.sh? I noticed a different version of the grammar at the web page https://github.com/ziglang/www.ziglang.org/blob/0888fffe9589b72245f62766e94581adf4784a12/content/documentation/master/index.html#L13092-L13593
markfirmware commented 2021年03月10日 20:54:49 +01:00 (Migrated from github.com)
Copy link

Did not intend to close.

Did not intend to close.
mingodad commented 2021年05月10日 20:31:08 +02:00 (Migrated from github.com)
Copy link

Here is a naive conversion (basically replace <- by ::= and / by | and cut several token declarations) of the grammar at https://github.com/ziglang/zig-spec/blob/master/grammar/grammar.y to EBNF accepted by https://www.bottlecaps.de/rr/ui to generate a railroad diagram (copy the grammar bellow to Edit Grammar tab and then click on View Diagram tab):

Root ::= skip container_doc_comment? ContainerMembers eof
//# *** Top level ***
ContainerMembers
 ::= (
 TestDecl ContainerMembers
 | TopLevelComptime ContainerMembers
 | doc_comment? KEYWORD_pub? TopLevelDecl ContainerMembers
 | ContainerField COMMA ContainerMembers
 | ContainerField
 )
TestDecl ::= doc_comment? KEYWORD_test STRINGLITERALSINGLE? Block
TopLevelComptime ::= doc_comment? KEYWORD_comptime BlockExpr
TopLevelDecl
 ::= (KEYWORD_export | KEYWORD_extern STRINGLITERALSINGLE? | (KEYWORD_inline | KEYWORD_noinline))? FnProto (SEMICOLON | Block)
 | (KEYWORD_export | KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl
 | KEYWORD_usingnamespace Expr SEMICOLON
FnProto ::= KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? CallConv? EXCLAMATIONMARK? (KEYWORD_anytype | TypeExpr)
VarDecl ::= (KEYWORD_const | KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
ContainerField ::= doc_comment? KEYWORD_comptime? IDENTIFIER (COLON (KEYWORD_anytype | TypeExpr) ByteAlign?)? (EQUAL Expr)?
//# *** Block Level ***
Statement
 ::= KEYWORD_comptime? VarDecl
 | KEYWORD_comptime BlockExprStatement
 | KEYWORD_nosuspend BlockExprStatement
 | KEYWORD_suspend (SEMICOLON | BlockExprStatement)
 | KEYWORD_defer BlockExprStatement
 | KEYWORD_errdefer Payload? BlockExprStatement
 | IfStatement
 | LabeledStatement
 | SwitchExpr
 | AssignExpr SEMICOLON
IfStatement
 ::= IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )?
 | IfPrefix AssignExpr ( SEMICOLON | KEYWORD_else Payload? Statement )
LabeledStatement ::= BlockLabel? (Block | LoopStatement)
LoopStatement ::= KEYWORD_inline? (ForStatement | WhileStatement)
ForStatement
 ::= ForPrefix BlockExpr ( KEYWORD_else Statement )?
 | ForPrefix AssignExpr ( SEMICOLON | KEYWORD_else Statement )
WhileStatement
 ::= WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )?
 | WhilePrefix AssignExpr ( SEMICOLON | KEYWORD_else Payload? Statement )
BlockExprStatement
 ::= BlockExpr
 | AssignExpr SEMICOLON
BlockExpr ::= BlockLabel? Block
//# *** Expression Level ***
AssignExpr ::= Expr (AssignOp Expr)?
Expr ::= BoolOrExpr
BoolOrExpr ::= 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?
 | BlockLabel? LoopExpr
 | Block
 | CurlySuffixExpr
IfExpr ::= IfPrefix Expr (KEYWORD_else Payload? Expr)?
Block ::= LBRACE Statement* RBRACE
LoopExpr ::= KEYWORD_inline? (ForExpr | WhileExpr)
ForExpr ::= ForPrefix Expr (KEYWORD_else Expr)?
WhileExpr ::= WhilePrefix Expr (KEYWORD_else Payload? Expr)?
CurlySuffixExpr ::= TypeExpr InitList?
InitList
 ::= LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE
 | LBRACE Expr (COMMA Expr)* COMMA? RBRACE
 | LBRACE RBRACE
TypeExpr ::= PrefixTypeOp* ErrorUnionExpr
ErrorUnionExpr ::= SuffixExpr (EXCLAMATIONMARK TypeExpr)?
SuffixExpr
 ::= KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments
 | PrimaryTypeExpr (SuffixOp | FnCallArguments)*
PrimaryTypeExpr
 ::= BUILTINIDENTIFIER FnCallArguments
 | CHAR_LITERAL
 | ContainerDecl
 | DOT IDENTIFIER
 | DOT InitList
 | ErrorSetDecl
 | FLOAT
 | FnProto
 | GroupedExpr
 | LabeledTypeExpr
 | IDENTIFIER
 | IfTypeExpr
 | INTEGER
 | KEYWORD_comptime TypeExpr
 | KEYWORD_error DOT IDENTIFIER
 | KEYWORD_false
 | KEYWORD_null
 | KEYWORD_anyframe
 | KEYWORD_true
 | KEYWORD_undefined
 | KEYWORD_unreachable
 | STRINGLITERAL
 | SwitchExpr
ContainerDecl ::= (KEYWORD_extern | KEYWORD_packed)? ContainerDeclAuto
ErrorSetDecl ::= KEYWORD_error LBRACE IdentifierList RBRACE
GroupedExpr ::= LPAREN Expr RPAREN
IfTypeExpr ::= IfPrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
LabeledTypeExpr
 ::= BlockLabel Block
 | BlockLabel? LoopTypeExpr
LoopTypeExpr ::= KEYWORD_inline? (ForTypeExpr | WhileTypeExpr)
ForTypeExpr ::= ForPrefix TypeExpr (KEYWORD_else TypeExpr)?
WhileTypeExpr ::= WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
SwitchExpr ::= KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE
//# *** Assembly ***
AsmExpr ::= KEYWORD_asm KEYWORD_volatile? LPAREN STRINGLITERAL AsmOutput? RPAREN
AsmOutput ::= COLON AsmOutputList AsmInput?
AsmOutputItem ::= LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr | IDENTIFIER) RPAREN
AsmInput ::= COLON AsmInputList AsmClobbers?
AsmInputItem ::= LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN
AsmClobbers ::= COLON StringList
//# *** Helper grammar ***
BreakLabel ::= COLON IDENTIFIER
BlockLabel ::= IDENTIFIER COLON
FieldInit ::= DOT IDENTIFIER EQUAL Expr
WhileContinueExpr ::= COLON LPAREN AssignExpr RPAREN
LinkSection ::= KEYWORD_linksection LPAREN Expr RPAREN
//# Fn specific
CallConv ::= KEYWORD_callconv LPAREN Expr RPAREN
ParamDecl ::= doc_comment? (KEYWORD_noalias | KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
ParamType
 ::= KEYWORD_anytype
 | DOT3
 | TypeExpr
//# Control flow prefixes
IfPrefix ::= KEYWORD_if LPAREN Expr RPAREN PtrPayload?
WhilePrefix ::= KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr?
ForPrefix ::= KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload
//# Payloads
Payload ::= PIPE IDENTIFIER PIPE
PtrPayload ::= PIPE ASTERISK? IDENTIFIER PIPE
PtrIndexPayload ::= PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE
//# Switch specific
SwitchProng ::= SwitchCase EQUALRARROW PtrPayload? AssignExpr
SwitchCase
 ::= SwitchItem (COMMA SwitchItem)* COMMA?
 | KEYWORD_else
SwitchItem ::= Expr (DOT3 Expr)?
//# Operators
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 (ByteAlign | 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 ExprList RPAREN
//# Ptr specific
SliceTypeStart ::= LBRACKET (COLON Expr)? RBRACKET
PtrTypeStart
 ::= ASTERISK
 | ASTERISK2
 | LBRACKET ASTERISK (LETTERC | COLON Expr)? RBRACKET
ArrayTypeStart ::= LBRACKET Expr (COLON Expr)? RBRACKET
//# ContainerDecl specific
ContainerDeclAuto ::= ContainerDeclType LBRACE container_doc_comment? ContainerMembers RBRACE
ContainerDeclType
 ::= KEYWORD_struct
 | KEYWORD_opaque
 | KEYWORD_enum (LPAREN Expr RPAREN)?
 | KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? | Expr) RPAREN)?
//# Alignment
ByteAlign ::= KEYWORD_align LPAREN Expr RPAREN
//# Lists
IdentifierList ::= (doc_comment? IDENTIFIER COMMA)* (doc_comment? IDENTIFIER)?
SwitchProngList ::= (SwitchProng COMMA)* SwitchProng?
AsmOutputList ::= (AsmOutputItem COMMA)* AsmOutputItem?
AsmInputList ::= (AsmInputItem COMMA)* AsmInputItem?
StringList ::= (STRINGLITERAL COMMA)* STRINGLITERAL?
ParamDeclList ::= (ParamDecl COMMA)* ParamDecl?
ExprList ::= (Expr COMMA)* Expr?
//# *** Tokens ***
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 ::= '~'
KEYWORD_align ::= 'align'
KEYWORD_allowzero ::= 'allowzero'
KEYWORD_and ::= 'and'
KEYWORD_anyframe ::= 'anyframe'
KEYWORD_anytype ::= 'anytype'
KEYWORD_asm ::= 'asm'
KEYWORD_async ::= 'async'
KEYWORD_await ::= 'await'
KEYWORD_break ::= 'break'
KEYWORD_callconv ::= 'callconv'
KEYWORD_catch ::= 'catch'
KEYWORD_comptime ::= 'comptime'
KEYWORD_const ::= 'const'
KEYWORD_continue ::= 'continue'
KEYWORD_defer ::= 'defer'
KEYWORD_else ::= 'else'
KEYWORD_enum ::= 'enum'
KEYWORD_errdefer ::= 'errdefer'
KEYWORD_error ::= 'error'
KEYWORD_export ::= 'export'
KEYWORD_extern ::= 'extern'
KEYWORD_false ::= 'false'
KEYWORD_fn ::= 'fn'
KEYWORD_for ::= 'for'
KEYWORD_if ::= 'if'
KEYWORD_inline ::= 'inline'
KEYWORD_noalias ::= 'noalias'
KEYWORD_nosuspend ::= 'nosuspend'
KEYWORD_noinline ::= 'noinline'
KEYWORD_null ::= 'null'
KEYWORD_opaque ::= 'opaque'
KEYWORD_or ::= 'or'
KEYWORD_orelse ::= 'orelse'
KEYWORD_packed ::= 'packed'
KEYWORD_pub ::= 'pub'
KEYWORD_resume ::= 'resume'
KEYWORD_return ::= 'return'
KEYWORD_linksection ::= 'linksection'
KEYWORD_struct ::= 'struct'
KEYWORD_suspend ::= 'suspend'
KEYWORD_switch ::= 'switch'
KEYWORD_test ::= 'test'
KEYWORD_threadlocal ::= 'threadlocal'
KEYWORD_true ::= 'true'
KEYWORD_try ::= 'try'
KEYWORD_undefined ::= 'undefined'
KEYWORD_union ::= 'union'
KEYWORD_unreachable ::= 'unreachable'
KEYWORD_usingnamespace ::= 'usingnamespace'
KEYWORD_var ::= 'var'
KEYWORD_volatile ::= 'volatile'
KEYWORD_while ::= 'while'
Here is a naive conversion (basically replace `<-` by `::=` and `/` by `|` and cut several token declarations) of the grammar at https://github.com/ziglang/zig-spec/blob/master/grammar/grammar.y to EBNF accepted by https://www.bottlecaps.de/rr/ui to generate a railroad diagram (copy the grammar bellow to `Edit Grammar` tab and then click on `View Diagram` tab): ``` Root ::= skip container_doc_comment? ContainerMembers eof //# *** Top level *** ContainerMembers ::= ( TestDecl ContainerMembers | TopLevelComptime ContainerMembers | doc_comment? KEYWORD_pub? TopLevelDecl ContainerMembers | ContainerField COMMA ContainerMembers | ContainerField ) TestDecl ::= doc_comment? KEYWORD_test STRINGLITERALSINGLE? Block TopLevelComptime ::= doc_comment? KEYWORD_comptime BlockExpr TopLevelDecl ::= (KEYWORD_export | KEYWORD_extern STRINGLITERALSINGLE? | (KEYWORD_inline | KEYWORD_noinline))? FnProto (SEMICOLON | Block) | (KEYWORD_export | KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl | KEYWORD_usingnamespace Expr SEMICOLON FnProto ::= KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? CallConv? EXCLAMATIONMARK? (KEYWORD_anytype | TypeExpr) VarDecl ::= (KEYWORD_const | KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON ContainerField ::= doc_comment? KEYWORD_comptime? IDENTIFIER (COLON (KEYWORD_anytype | TypeExpr) ByteAlign?)? (EQUAL Expr)? //# *** Block Level *** Statement ::= KEYWORD_comptime? VarDecl | KEYWORD_comptime BlockExprStatement | KEYWORD_nosuspend BlockExprStatement | KEYWORD_suspend (SEMICOLON | BlockExprStatement) | KEYWORD_defer BlockExprStatement | KEYWORD_errdefer Payload? BlockExprStatement | IfStatement | LabeledStatement | SwitchExpr | AssignExpr SEMICOLON IfStatement ::= IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )? | IfPrefix AssignExpr ( SEMICOLON | KEYWORD_else Payload? Statement ) LabeledStatement ::= BlockLabel? (Block | LoopStatement) LoopStatement ::= KEYWORD_inline? (ForStatement | WhileStatement) ForStatement ::= ForPrefix BlockExpr ( KEYWORD_else Statement )? | ForPrefix AssignExpr ( SEMICOLON | KEYWORD_else Statement ) WhileStatement ::= WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )? | WhilePrefix AssignExpr ( SEMICOLON | KEYWORD_else Payload? Statement ) BlockExprStatement ::= BlockExpr | AssignExpr SEMICOLON BlockExpr ::= BlockLabel? Block //# *** Expression Level *** AssignExpr ::= Expr (AssignOp Expr)? Expr ::= BoolOrExpr BoolOrExpr ::= 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? | BlockLabel? LoopExpr | Block | CurlySuffixExpr IfExpr ::= IfPrefix Expr (KEYWORD_else Payload? Expr)? Block ::= LBRACE Statement* RBRACE LoopExpr ::= KEYWORD_inline? (ForExpr | WhileExpr) ForExpr ::= ForPrefix Expr (KEYWORD_else Expr)? WhileExpr ::= WhilePrefix Expr (KEYWORD_else Payload? Expr)? CurlySuffixExpr ::= TypeExpr InitList? InitList ::= LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE | LBRACE Expr (COMMA Expr)* COMMA? RBRACE | LBRACE RBRACE TypeExpr ::= PrefixTypeOp* ErrorUnionExpr ErrorUnionExpr ::= SuffixExpr (EXCLAMATIONMARK TypeExpr)? SuffixExpr ::= KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments | PrimaryTypeExpr (SuffixOp | FnCallArguments)* PrimaryTypeExpr ::= BUILTINIDENTIFIER FnCallArguments | CHAR_LITERAL | ContainerDecl | DOT IDENTIFIER | DOT InitList | ErrorSetDecl | FLOAT | FnProto | GroupedExpr | LabeledTypeExpr | IDENTIFIER | IfTypeExpr | INTEGER | KEYWORD_comptime TypeExpr | KEYWORD_error DOT IDENTIFIER | KEYWORD_false | KEYWORD_null | KEYWORD_anyframe | KEYWORD_true | KEYWORD_undefined | KEYWORD_unreachable | STRINGLITERAL | SwitchExpr ContainerDecl ::= (KEYWORD_extern | KEYWORD_packed)? ContainerDeclAuto ErrorSetDecl ::= KEYWORD_error LBRACE IdentifierList RBRACE GroupedExpr ::= LPAREN Expr RPAREN IfTypeExpr ::= IfPrefix TypeExpr (KEYWORD_else Payload? TypeExpr)? LabeledTypeExpr ::= BlockLabel Block | BlockLabel? LoopTypeExpr LoopTypeExpr ::= KEYWORD_inline? (ForTypeExpr | WhileTypeExpr) ForTypeExpr ::= ForPrefix TypeExpr (KEYWORD_else TypeExpr)? WhileTypeExpr ::= WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)? SwitchExpr ::= KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE //# *** Assembly *** AsmExpr ::= KEYWORD_asm KEYWORD_volatile? LPAREN STRINGLITERAL AsmOutput? RPAREN AsmOutput ::= COLON AsmOutputList AsmInput? AsmOutputItem ::= LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr | IDENTIFIER) RPAREN AsmInput ::= COLON AsmInputList AsmClobbers? AsmInputItem ::= LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN AsmClobbers ::= COLON StringList //# *** Helper grammar *** BreakLabel ::= COLON IDENTIFIER BlockLabel ::= IDENTIFIER COLON FieldInit ::= DOT IDENTIFIER EQUAL Expr WhileContinueExpr ::= COLON LPAREN AssignExpr RPAREN LinkSection ::= KEYWORD_linksection LPAREN Expr RPAREN //# Fn specific CallConv ::= KEYWORD_callconv LPAREN Expr RPAREN ParamDecl ::= doc_comment? (KEYWORD_noalias | KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType ParamType ::= KEYWORD_anytype | DOT3 | TypeExpr //# Control flow prefixes IfPrefix ::= KEYWORD_if LPAREN Expr RPAREN PtrPayload? WhilePrefix ::= KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr? ForPrefix ::= KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload //# Payloads Payload ::= PIPE IDENTIFIER PIPE PtrPayload ::= PIPE ASTERISK? IDENTIFIER PIPE PtrIndexPayload ::= PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE //# Switch specific SwitchProng ::= SwitchCase EQUALRARROW PtrPayload? AssignExpr SwitchCase ::= SwitchItem (COMMA SwitchItem)* COMMA? | KEYWORD_else SwitchItem ::= Expr (DOT3 Expr)? //# Operators 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 (ByteAlign | 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 ExprList RPAREN //# Ptr specific SliceTypeStart ::= LBRACKET (COLON Expr)? RBRACKET PtrTypeStart ::= ASTERISK | ASTERISK2 | LBRACKET ASTERISK (LETTERC | COLON Expr)? RBRACKET ArrayTypeStart ::= LBRACKET Expr (COLON Expr)? RBRACKET //# ContainerDecl specific ContainerDeclAuto ::= ContainerDeclType LBRACE container_doc_comment? ContainerMembers RBRACE ContainerDeclType ::= KEYWORD_struct | KEYWORD_opaque | KEYWORD_enum (LPAREN Expr RPAREN)? | KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? | Expr) RPAREN)? //# Alignment ByteAlign ::= KEYWORD_align LPAREN Expr RPAREN //# Lists IdentifierList ::= (doc_comment? IDENTIFIER COMMA)* (doc_comment? IDENTIFIER)? SwitchProngList ::= (SwitchProng COMMA)* SwitchProng? AsmOutputList ::= (AsmOutputItem COMMA)* AsmOutputItem? AsmInputList ::= (AsmInputItem COMMA)* AsmInputItem? StringList ::= (STRINGLITERAL COMMA)* STRINGLITERAL? ParamDeclList ::= (ParamDecl COMMA)* ParamDecl? ExprList ::= (Expr COMMA)* Expr? //# *** Tokens *** 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 ::= '~' KEYWORD_align ::= 'align' KEYWORD_allowzero ::= 'allowzero' KEYWORD_and ::= 'and' KEYWORD_anyframe ::= 'anyframe' KEYWORD_anytype ::= 'anytype' KEYWORD_asm ::= 'asm' KEYWORD_async ::= 'async' KEYWORD_await ::= 'await' KEYWORD_break ::= 'break' KEYWORD_callconv ::= 'callconv' KEYWORD_catch ::= 'catch' KEYWORD_comptime ::= 'comptime' KEYWORD_const ::= 'const' KEYWORD_continue ::= 'continue' KEYWORD_defer ::= 'defer' KEYWORD_else ::= 'else' KEYWORD_enum ::= 'enum' KEYWORD_errdefer ::= 'errdefer' KEYWORD_error ::= 'error' KEYWORD_export ::= 'export' KEYWORD_extern ::= 'extern' KEYWORD_false ::= 'false' KEYWORD_fn ::= 'fn' KEYWORD_for ::= 'for' KEYWORD_if ::= 'if' KEYWORD_inline ::= 'inline' KEYWORD_noalias ::= 'noalias' KEYWORD_nosuspend ::= 'nosuspend' KEYWORD_noinline ::= 'noinline' KEYWORD_null ::= 'null' KEYWORD_opaque ::= 'opaque' KEYWORD_or ::= 'or' KEYWORD_orelse ::= 'orelse' KEYWORD_packed ::= 'packed' KEYWORD_pub ::= 'pub' KEYWORD_resume ::= 'resume' KEYWORD_return ::= 'return' KEYWORD_linksection ::= 'linksection' KEYWORD_struct ::= 'struct' KEYWORD_suspend ::= 'suspend' KEYWORD_switch ::= 'switch' KEYWORD_test ::= 'test' KEYWORD_threadlocal ::= 'threadlocal' KEYWORD_true ::= 'true' KEYWORD_try ::= 'try' KEYWORD_undefined ::= 'undefined' KEYWORD_union ::= 'union' KEYWORD_unreachable ::= 'unreachable' KEYWORD_usingnamespace ::= 'usingnamespace' KEYWORD_var ::= 'var' KEYWORD_volatile ::= 'volatile' KEYWORD_while ::= 'while' ```
mingodad commented 2021年05月11日 10:08:32 +02:00 (Migrated from github.com)
Copy link

Effectively the grammar on ziglang.org documentation do not match the one here, here is the EBNF for the 0.7.1 and the dev versions to be viewd at https://www.bottlecaps.de/rr/ui:

Zig-0.7.1.ebnf:

Root ::= skip ContainerMembers eof
//# *** Top level ***
ContainerMembers
 ::= TestDecl ContainerMembers
 | TopLevelComptime ContainerMembers
 | KEYWORD_pub? TopLevelDecl ContainerMembers
 | ContainerField COMMA ContainerMembers
 | ContainerField
TestDecl ::= KEYWORD_test STRINGLITERALSINGLE Block
TopLevelComptime ::= KEYWORD_comptime BlockExpr
TopLevelDecl
 ::= (KEYWORD_export | KEYWORD_extern STRINGLITERALSINGLE? | KEYWORD_inline)? FnProto (SEMICOLON | Block)
 | (KEYWORD_export | KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl
 | KEYWORD_usingnamespace Expr SEMICOLON
FnProto ::= KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_anytype | TypeExpr)
VarDecl ::= (KEYWORD_const | KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
ContainerField ::= KEYWORD_comptime? IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)?
//# *** Block Level ***
Statement
 ::= KEYWORD_comptime? VarDecl
 | KEYWORD_comptime BlockExprStatement
 | KEYWORD_nosuspend BlockExprStatement
 | KEYWORD_suspend (SEMICOLON | BlockExprStatement)
 | KEYWORD_defer BlockExprStatement
 | KEYWORD_errdefer BlockExprStatement
 | IfStatement
 | LabeledStatement
 | SwitchExpr
 | AssignExpr SEMICOLON
IfStatement
 ::= IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )?
 | IfPrefix AssignExpr ( SEMICOLON | KEYWORD_else Payload? Statement )
LabeledStatement ::= BlockLabel? (Block | LoopStatement)
LoopStatement ::= KEYWORD_inline? (ForStatement | WhileStatement)
ForStatement
 ::= ForPrefix BlockExpr ( KEYWORD_else Statement )?
 | ForPrefix AssignExpr ( SEMICOLON | KEYWORD_else Statement )
WhileStatement
 ::= WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )?
 | WhilePrefix AssignExpr ( SEMICOLON | KEYWORD_else Payload? Statement )
BlockExprStatement
 ::= BlockExpr
 | AssignExpr SEMICOLON
BlockExpr ::= BlockLabel? Block
//# *** Expression Level ***
AssignExpr ::= Expr (AssignOp Expr)?
Expr ::= KEYWORD_try* BoolOrExpr
BoolOrExpr ::= 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?
 | BlockLabel? LoopExpr
 | Block
 | CurlySuffixExpr
IfExpr ::= IfPrefix Expr (KEYWORD_else Payload? Expr)?
Block ::= LBRACE Statement* RBRACE
LoopExpr ::= KEYWORD_inline? (ForExpr | WhileExpr)
ForExpr ::= ForPrefix Expr (KEYWORD_else Expr)?
WhileExpr ::= WhilePrefix Expr (KEYWORD_else Payload? Expr)?
CurlySuffixExpr ::= TypeExpr InitList?
InitList
 ::= LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE
 | LBRACE Expr (COMMA Expr)* COMMA? RBRACE
 | LBRACE RBRACE
TypeExpr ::= PrefixTypeOp* ErrorUnionExpr
ErrorUnionExpr ::= SuffixExpr (EXCLAMATIONMARK TypeExpr)?
SuffixExpr
 ::= KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments
 | PrimaryTypeExpr (SuffixOp | FnCallArguments)*
PrimaryTypeExpr
 ::= BUILTINIDENTIFIER FnCallArguments
 | CHAR_LITERAL
 | ContainerDecl
 | DOT IDENTIFIER
 | DOT InitList
 | ErrorSetDecl
 | FLOAT
 | FnProto
 | GroupedExpr
 | LabeledTypeExpr
 | IDENTIFIER
 | IfTypeExpr
 | INTEGER
 | KEYWORD_comptime TypeExpr
 | KEYWORD_error DOT IDENTIFIER
 | KEYWORD_false
 | KEYWORD_null
 | KEYWORD_anyframe
 | KEYWORD_true
 | KEYWORD_undefined
 | KEYWORD_unreachable
 | STRINGLITERAL
 | SwitchExpr
ContainerDecl ::= (KEYWORD_extern | KEYWORD_packed)? ContainerDeclAuto
ErrorSetDecl ::= KEYWORD_error LBRACE IdentifierList RBRACE
GroupedExpr ::= LPAREN Expr RPAREN
IfTypeExpr ::= IfPrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
LabeledTypeExpr
 ::= BlockLabel Block
 | BlockLabel? LoopTypeExpr
LoopTypeExpr ::= KEYWORD_inline? (ForTypeExpr | WhileTypeExpr)
ForTypeExpr ::= ForPrefix TypeExpr (KEYWORD_else TypeExpr)?
WhileTypeExpr ::= WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
SwitchExpr ::= KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE
//# *** Assembly ***
AsmExpr ::= KEYWORD_asm KEYWORD_volatile? LPAREN STRINGLITERAL AsmOutput? RPAREN
AsmOutput ::= COLON AsmOutputList AsmInput?
AsmOutputItem ::= LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr | IDENTIFIER) RPAREN
AsmInput ::= COLON AsmInputList AsmClobbers?
AsmInputItem ::= LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN
AsmClobbers ::= COLON StringList
//# *** Helper grammar ***
BreakLabel ::= COLON IDENTIFIER
BlockLabel ::= IDENTIFIER COLON
FieldInit ::= DOT IDENTIFIER EQUAL Expr
WhileContinueExpr ::= COLON LPAREN AssignExpr RPAREN
LinkSection ::= KEYWORD_linksection LPAREN Expr RPAREN
ParamDecl ::= (KEYWORD_noalias | KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
ParamType
 ::= KEYWORD_anytype
 | DOT3
 | TypeExpr
//# Control flow prefixes
IfPrefix ::= KEYWORD_if LPAREN Expr RPAREN PtrPayload?
WhilePrefix ::= KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr?
ForPrefix ::= KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload
//# Payloads
Payload ::= PIPE IDENTIFIER PIPE
PtrPayload ::= PIPE ASTERISK? IDENTIFIER PIPE
PtrIndexPayload ::= PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE
//# Switch specific
SwitchProng ::= SwitchCase EQUALRARROW PtrPayload? AssignExpr
SwitchCase
 ::= SwitchItem (COMMA SwitchItem)* COMMA?
 | KEYWORD_else
SwitchItem ::= Expr (DOT3 Expr)?
//# Operators
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
 | ArrayTypeStart (ByteAlign | KEYWORD_const | KEYWORD_volatile | KEYWORD_allowzero)*
 | PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN | KEYWORD_const | KEYWORD_volatile | KEYWORD_allowzero)*
SuffixOp
 ::= LBRACKET Expr (DOT2 Expr?)? RBRACKET
 | DOT IDENTIFIER
 | DOTASTERISK
 | DOTQUESTIONMARK
FnCallArguments ::= LPAREN ExprList RPAREN
//# Ptr specific
ArrayTypeStart ::= LBRACKET Expr? RBRACKET
PtrTypeStart
 ::= ASTERISK
 | ASTERISK2
 | PTRUNKNOWN
 | PTRC
//# ContainerDecl specific
ContainerDeclAuto ::= ContainerDeclType LBRACE ContainerMembers RBRACE
ContainerDeclType
 ::= (KEYWORD_struct | KEYWORD_enum | KEYWORD_opaque) (LPAREN Expr RPAREN)?
 | KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? | Expr) RPAREN)?
//# Alignment
ByteAlign ::= KEYWORD_align LPAREN Expr RPAREN
//# Lists
IdentifierList ::= (IDENTIFIER COMMA)* IDENTIFIER?
SwitchProngList ::= (SwitchProng COMMA)* SwitchProng?
AsmOutputList ::= (AsmOutputItem COMMA)* AsmOutputItem?
AsmInputList ::= (AsmInputItem COMMA)* AsmInputItem?
StringList ::= (STRINGLITERAL COMMA)* STRINGLITERAL?
ParamDeclList ::= (ParamDecl COMMA)* ParamDecl?
ExprList ::= (Expr COMMA)* Expr?
//# *** Tokens ***
eof ::= "!."
hex ::= [0-9a-fA-F]
char_escape
 ::= "\\x" hex hex
 | "\\u{" hex+ "}"
 | "\\" [nr\\t'"]
char_char
 ::= char_escape
 | [^\\'\n]
string_char
 ::= char_escape
 | [^\\"\n]
line_comment ::= '//'[^\n]*
line_string ::= ("\\\\" [^\n]* [ \n]*)+
skip ::= ([ \n] | line_comment)*
CHAR_LITERAL ::= "'" char_char "'" skip
FLOAT
 ::= "0x" hex+ "." hex+ ([pP] [-+]? hex+)? skip
 | [0-9]+ "." [0-9]+ ([eE] [-+]? [0-9]+)? skip
 | "0x" hex+ "."? [pP] [-+]? hex+ skip
 | [0-9]+ "."? [eE] [-+]? [0-9]+ skip
INTEGER
 ::= "0b" [01]+ skip
 | "0o" [0-7]+ skip
 | "0x" hex+ skip
 | [0-9]+ skip
STRINGLITERALSINGLE ::= '"' string_char* '"' skip
STRINGLITERAL
 ::= STRINGLITERALSINGLE
 | line_string skip
IDENTIFIER
 ::= '!' keyword [A-Za-z_] [A-Za-z0-9_]* skip
 | '@"' string_char* '"' skip
BUILTINIDENTIFIER ::= "@"[A-Za-z_][A-Za-z0-9_]* skip
AMPERSAND ::= '&' // ![=] skip
AMPERSANDEQUAL ::= '&=' // skip
ASTERISK ::= '*' // ![*%=] skip
ASTERISK2 ::= '**' // skip
ASTERISKEQUAL ::= '*=' // skip
ASTERISKPERCENT ::= '*%' // ![=] skip
ASTERISKPERCENTEQUAL ::= '*%=' // skip
CARET ::= '^' // ![=] skip
CARETEQUAL ::= '^=' // skip
COLON ::= ':' // skip
COMMA ::= ',' // skip
DOT ::= '.' // ![*.?] skip
DOT2 ::= '..' // ![.] skip
DOT3 ::= '...' // skip
DOTASTERISK ::= '.*' // skip
DOTQUESTIONMARK ::= '.?' // skip
EQUAL ::= '=' // ![>=] skip
EQUALEQUAL ::= '==' // skip
EQUALRARROW ::= '=>' // skip
EXCLAMATIONMARK ::= '!' // ![=] skip
EXCLAMATIONMARKEQUAL ::= '!=' // skip
LARROW ::= '<' // ![<=] skip
LARROW2 ::= '<<' // ![=] skip
LARROW2EQUAL ::= '<<=' // skip
LARROWEQUAL ::= '<=' // skip
LBRACE ::= '{' // skip
LBRACKET ::= '[' // ![*] skip
LPAREN ::= '(' // skip
MINUS ::= '-' // ![%=>] skip
MINUSEQUAL ::= '-=' // skip
MINUSPERCENT ::= '-%' // ![=] skip
MINUSPERCENTEQUAL ::= '-%=' // skip
MINUSRARROW ::= '->' // skip
PERCENT ::= '%' // ![=] skip
PERCENTEQUAL ::= '%=' // skip
PIPE ::= '|' // ![|=] skip
PIPE2 ::= '||' // skip
PIPEEQUAL ::= '|=' // skip
PLUS ::= '+' // ![%+=] skip
PLUS2 ::= '++' // skip
PLUSEQUAL ::= '+=' // skip
PLUSPERCENT ::= '+%' // ![=] skip
PLUSPERCENTEQUAL ::= '+%=' // skip
PTRC ::= '[*c]' // skip
PTRUNKNOWN ::= '[*]' // skip
QUESTIONMARK ::= '?' // skip
RARROW ::= '>' // ![>=] skip
RARROW2 ::= '>>' // ![=] skip
RARROW2EQUAL ::= '>>=' // skip
RARROWEQUAL ::= '>=' // skip
RBRACE ::= '}' // skip
RBRACKET ::= ']' // skip
RPAREN ::= ')' // skip
SEMICOLON ::= ';' // skip
SLASH ::= '/' // ![=] skip
SLASHEQUAL ::= '/=' // skip
TILDE ::= '~' // skip
end_of_word ::= '!'[a-zA-Z0-9_] skip
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_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_false ::= 'false' //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_null ::= 'null' //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_true ::= 'true' //end_of_word
KEYWORD_try ::= 'try' //end_of_word
KEYWORD_undefined ::= 'undefined' //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_and | KEYWORD_anyframe | KEYWORD_anytype
 | KEYWORD_allowzero | KEYWORD_asm | KEYWORD_async | KEYWORD_await | KEYWORD_break
 | KEYWORD_catch | KEYWORD_comptime | KEYWORD_const | KEYWORD_continue
 | KEYWORD_defer | KEYWORD_else | KEYWORD_enum | KEYWORD_errdefer
 | KEYWORD_error | KEYWORD_export | KEYWORD_extern | KEYWORD_false
 | KEYWORD_fn | KEYWORD_for | KEYWORD_if | KEYWORD_inline
 | KEYWORD_noalias | KEYWORD_null | 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_true | KEYWORD_try
 | KEYWORD_undefined | KEYWORD_union | KEYWORD_unreachable
 | KEYWORD_usingnamespace | KEYWORD_var | KEYWORD_volatile | KEYWORD_while

Zig-dev.ebnf:

Root ::= skip ContainerMembers eof
//# *** Top level ***
ContainerMembers
 ::= TestDecl ContainerMembers
 | TopLevelComptime ContainerMembers
 | KEYWORD_pub? TopLevelDecl ContainerMembers
 | ContainerField COMMA ContainerMembers
 | ContainerField
TestDecl ::= KEYWORD_test STRINGLITERALSINGLE Block
TopLevelComptime ::= KEYWORD_comptime BlockExpr
TopLevelDecl
 ::= (KEYWORD_export | KEYWORD_extern STRINGLITERALSINGLE? | (KEYWORD_inline | KEYWORD_noinline))? FnProto (SEMICOLON | Block)
 | (KEYWORD_export | KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl
 | KEYWORD_usingnamespace Expr SEMICOLON
FnProto ::= KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? CallConv? EXCLAMATIONMARK? (KEYWORD_anytype | TypeExpr)
VarDecl ::= (KEYWORD_const | KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
ContainerField ::= KEYWORD_comptime? IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)?
//# *** Block Level ***
Statement
 ::= KEYWORD_comptime? VarDecl
 | KEYWORD_comptime BlockExprStatement
 | KEYWORD_nosuspend BlockExprStatement
 | KEYWORD_suspend (SEMICOLON | BlockExprStatement)
 | KEYWORD_defer BlockExprStatement
 | KEYWORD_errdefer BlockExprStatement
 | IfStatement
 | LabeledStatement
 | SwitchExpr
 | AssignExpr SEMICOLON
IfStatement
 ::= IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )?
 | IfPrefix AssignExpr ( SEMICOLON | KEYWORD_else Payload? Statement )
LabeledStatement ::= BlockLabel? (Block | LoopStatement)
LoopStatement ::= KEYWORD_inline? (ForStatement | WhileStatement)
ForStatement
 ::= ForPrefix BlockExpr ( KEYWORD_else Statement )?
 | ForPrefix AssignExpr ( SEMICOLON | KEYWORD_else Statement )
WhileStatement
 ::= WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )?
 | WhilePrefix AssignExpr ( SEMICOLON | KEYWORD_else Payload? Statement )
BlockExprStatement
 ::= BlockExpr
 | AssignExpr SEMICOLON
BlockExpr ::= BlockLabel? Block
//# *** Expression Level ***
AssignExpr ::= Expr (AssignOp Expr)?
Expr ::= BoolOrExpr
BoolOrExpr ::= 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?
 | BlockLabel? LoopExpr
 | Block
 | CurlySuffixExpr
IfExpr ::= IfPrefix Expr (KEYWORD_else Payload? Expr)?
Block ::= LBRACE Statement* RBRACE
LoopExpr ::= KEYWORD_inline? (ForExpr | WhileExpr)
ForExpr ::= ForPrefix Expr (KEYWORD_else Expr)?
WhileExpr ::= WhilePrefix Expr (KEYWORD_else Payload? Expr)?
CurlySuffixExpr ::= TypeExpr InitList?
InitList
 ::= LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE
 | LBRACE Expr (COMMA Expr)* COMMA? RBRACE
 | LBRACE RBRACE
TypeExpr ::= PrefixTypeOp* ErrorUnionExpr
ErrorUnionExpr ::= SuffixExpr (EXCLAMATIONMARK TypeExpr)?
SuffixExpr
 ::= KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments
 | PrimaryTypeExpr (SuffixOp | FnCallArguments)*
PrimaryTypeExpr
 ::= BUILTINIDENTIFIER FnCallArguments
 | CHAR_LITERAL
 | ContainerDecl
 | DOT IDENTIFIER
 | DOT InitList
 | ErrorSetDecl
 | FLOAT
 | FnProto
 | GroupedExpr
 | LabeledTypeExpr
 | IDENTIFIER
 | IfTypeExpr
 | INTEGER
 | KEYWORD_comptime TypeExpr
 | KEYWORD_error DOT IDENTIFIER
 | KEYWORD_false
 | KEYWORD_null
 | KEYWORD_anyframe
 | KEYWORD_true
 | KEYWORD_undefined
 | KEYWORD_unreachable
 | STRINGLITERAL
 | SwitchExpr
ContainerDecl ::= (KEYWORD_extern | KEYWORD_packed)? ContainerDeclAuto
ErrorSetDecl ::= KEYWORD_error LBRACE IdentifierList RBRACE
GroupedExpr ::= LPAREN Expr RPAREN
IfTypeExpr ::= IfPrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
LabeledTypeExpr
 ::= BlockLabel Block
 | BlockLabel? LoopTypeExpr
LoopTypeExpr ::= KEYWORD_inline? (ForTypeExpr | WhileTypeExpr)
ForTypeExpr ::= ForPrefix TypeExpr (KEYWORD_else TypeExpr)?
WhileTypeExpr ::= WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)?
SwitchExpr ::= KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE
//# *** Assembly ***
AsmExpr ::= KEYWORD_asm KEYWORD_volatile? LPAREN STRINGLITERAL AsmOutput? RPAREN
AsmOutput ::= COLON AsmOutputList AsmInput?
AsmOutputItem ::= LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr | IDENTIFIER) RPAREN
AsmInput ::= COLON AsmInputList AsmClobbers?
AsmInputItem ::= LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN
AsmClobbers ::= COLON StringList
//# *** Helper grammar ***
BreakLabel ::= COLON IDENTIFIER
BlockLabel ::= IDENTIFIER COLON
FieldInit ::= DOT IDENTIFIER EQUAL Expr
WhileContinueExpr ::= COLON LPAREN AssignExpr RPAREN
LinkSection ::= KEYWORD_linksection LPAREN Expr RPAREN
CallConv ::= KEYWORD_callconv LPAREN Expr RPAREN
ParamDecl ::= (KEYWORD_noalias | KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
ParamType
 ::= KEYWORD_anytype
 | DOT3
 | TypeExpr
//# Control flow prefixes
IfPrefix ::= KEYWORD_if LPAREN Expr RPAREN PtrPayload?
WhilePrefix ::= KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr?
ForPrefix ::= KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload
//# Payloads
Payload ::= PIPE IDENTIFIER PIPE
PtrPayload ::= PIPE ASTERISK? IDENTIFIER PIPE
PtrIndexPayload ::= PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE
//# Switch specific
SwitchProng ::= SwitchCase EQUALRARROW PtrPayload? AssignExpr
SwitchCase
 ::= SwitchItem (COMMA SwitchItem)* COMMA?
 | KEYWORD_else
SwitchItem ::= Expr (DOT3 Expr)?
//# Operators
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
 | ArrayTypeStart (ByteAlign | KEYWORD_const | KEYWORD_volatile | KEYWORD_allowzero)*
 | PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN | KEYWORD_const | KEYWORD_volatile | KEYWORD_allowzero)*
SuffixOp
 ::= LBRACKET Expr (DOT2 Expr?)? RBRACKET
 | DOT IDENTIFIER
 | DOTASTERISK
 | DOTQUESTIONMARK
FnCallArguments ::= LPAREN ExprList RPAREN
//# Ptr specific
ArrayTypeStart ::= LBRACKET Expr? (COLON Expr)? RBRACKET
PtrTypeStart
 ::= ASTERISK
 | ASTERISK2
 | LBRACKET ASTERISK (LETTERC | COLON Expr)? RBRACKET
//# ContainerDecl specific
ContainerDeclAuto ::= ContainerDeclType LBRACE ContainerMembers RBRACE
ContainerDeclType
 ::= KEYWORD_struct
 | KEYWORD_opaque
 | KEYWORD_enum (LPAREN Expr RPAREN)?
 | KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? | Expr) RPAREN)?
//# Alignment
ByteAlign ::= KEYWORD_align LPAREN Expr RPAREN
//# Lists
IdentifierList ::= (IDENTIFIER COMMA)* IDENTIFIER?
SwitchProngList ::= (SwitchProng COMMA)* SwitchProng?
AsmOutputList ::= (AsmOutputItem COMMA)* AsmOutputItem?
AsmInputList ::= (AsmInputItem COMMA)* AsmInputItem?
StringList ::= (STRINGLITERAL COMMA)* STRINGLITERAL?
ParamDeclList ::= (ParamDecl COMMA)* ParamDecl?
ExprList ::= (Expr COMMA)* Expr?
//# *** Tokens ***
eof ::= '!.'
eol ::= ('\r'? '\n') | eof
hex ::= [0-9a-fA-F]
hex_ ::= ('_'/hex)
dec ::= [0-9]
dec_ ::= ('_'/dec)
dec_int ::= dec (dec_* dec)?
hex_int ::= hex (hex_* dec)?
char_escape
 ::= '\\x' hex hex
 | '\\u{' hex+ '}'
 | '\\' [nr\\t'"]
char_char
 ::= char_escape
 | [^\\'\r\n]
string_char
 ::= char_escape
 | [^\\"\r\n]
line_comment ::= '//'[^\r\n]* eol
line_string ::= ('\\\\' [^\r\n]* eol skip)+
skip ::= ([ \t] | eol | line_comment)*
CHAR_LITERAL ::= "'" char_char "'" skip
FLOAT
 ::= '0x' hex_* hex '.' hex_int ([pP] [-+]? hex_int)? skip
 | dec_int '.' dec_int ([eE] [-+]? dec_int)? skip
 | '0x' hex_* hex '.'? [pP] [-+]? hex_int skip
 | dec_int '.'? [eE] [-+]? dec_int skip
INTEGER
 ::= '0b' [_01]* [01] skip
 | '0o' [_0-7]* [0-7] skip
 | '0x' hex_* hex skip
 | dec_int skip
STRINGLITERALSINGLE ::= '"' string_char* '"' skip
STRINGLITERAL
 ::= STRINGLITERALSINGLE
 | line_string skip
IDENTIFIER
 ::= '!'keyword [A-Za-z_] [A-Za-z0-9_]* skip
 | '@"' string_char* '"' skip
BUILTINIDENTIFIER ::= '@'[A-Za-z_][A-Za-z0-9_]* skip
AMPERSAND ::= '&' //![=] skip
AMPERSANDEQUAL ::= '&=' // skip
ASTERISK ::= '*' //![*%=] skip
ASTERISK2 ::= '**' // skip
ASTERISKEQUAL ::= '*=' // skip
ASTERISKPERCENT ::= '*%' //![=] skip
ASTERISKPERCENTEQUAL ::= '*%=' // skip
CARET ::= '^' //![=] skip
CARETEQUAL ::= '^=' // skip
COLON ::= ':' // skip
COMMA ::= ',' // skip
DOT ::= '.' //![*.?] skip
DOT2 ::= '..' //![.] skip
DOT3 ::= '...' // skip
DOTASTERISK ::= '.*' // skip
DOTQUESTIONMARK ::= '.?' // skip
EQUAL ::= '=' //![>=] skip
EQUALEQUAL ::= '==' // skip
EQUALRARROW ::= '=>' // skip
EXCLAMATIONMARK ::= '!' //![=] skip
EXCLAMATIONMARKEQUAL ::= '!=' // skip
LARROW ::= '<' //![<=] skip
LARROW2 ::= '<<' //![=] skip
LARROW2EQUAL ::= '<<=' // skip
LARROWEQUAL ::= '<=' // skip
LBRACE ::= '{' // skip
LBRACKET ::= '[' // skip
LPAREN ::= '(' // skip
MINUS ::= '-' //![%=>] skip
MINUSEQUAL ::= '-=' // skip
MINUSPERCENT ::= '-%' //![=] skip
MINUSPERCENTEQUAL ::= '-%=' // skip
MINUSRARROW ::= '->' // skip
PERCENT ::= '%' //![=] skip
PERCENTEQUAL ::= '%=' // skip
PIPE ::= '|' //![|=] skip
PIPE2 ::= '||' // skip
PIPEEQUAL ::= '|=' // skip
PLUS ::= '+' //![%+=] skip
PLUS2 ::= '++' // skip
PLUSEQUAL ::= '+=' // skip
PLUSPERCENT ::= '+%' //![=] skip
PLUSPERCENTEQUAL ::= '+%=' // skip
LETTERC ::= 'c' // skip
QUESTIONMARK ::= '?' // skip
RARROW ::= '>' //![>=] skip
RARROW2 ::= '>>' //![=] skip
RARROW2EQUAL ::= '>>=' // skip
RARROWEQUAL ::= '>=' // skip
RBRACE ::= '}' // skip
RBRACKET ::= ']' // skip
RPAREN ::= ')' // skip
SEMICOLON ::= ';' // skip
SLASH ::= '/' //![=] skip
SLASHEQUAL ::= '/=' // skip
TILDE ::= '~' // skip
end_of_word ::= '!'[a-zA-Z0-9_] skip
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_false ::= 'false' //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_null ::= 'null' //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_true ::= 'true' //end_of_word
KEYWORD_try ::= 'try' //end_of_word
KEYWORD_undefined ::= 'undefined' //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_false | KEYWORD_fn | KEYWORD_for | KEYWORD_if
 | KEYWORD_inline | KEYWORD_noalias | KEYWORD_nosuspend | KEYWORD_noinline
 | KEYWORD_null | 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_true | KEYWORD_try
 | KEYWORD_undefined | KEYWORD_union | KEYWORD_unreachable
 | KEYWORD_usingnamespace | KEYWORD_var | KEYWORD_volatile | KEYWORD_while
Effectively the grammar on ziglang.org documentation do not match the one here, here is the EBNF for the `0.7.1` and the `dev` versions to be viewd at https://www.bottlecaps.de/rr/ui: Zig-0.7.1.ebnf: ``` Root ::= skip ContainerMembers eof //# *** Top level *** ContainerMembers ::= TestDecl ContainerMembers | TopLevelComptime ContainerMembers | KEYWORD_pub? TopLevelDecl ContainerMembers | ContainerField COMMA ContainerMembers | ContainerField TestDecl ::= KEYWORD_test STRINGLITERALSINGLE Block TopLevelComptime ::= KEYWORD_comptime BlockExpr TopLevelDecl ::= (KEYWORD_export | KEYWORD_extern STRINGLITERALSINGLE? | KEYWORD_inline)? FnProto (SEMICOLON | Block) | (KEYWORD_export | KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl | KEYWORD_usingnamespace Expr SEMICOLON FnProto ::= KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_anytype | TypeExpr) VarDecl ::= (KEYWORD_const | KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON ContainerField ::= KEYWORD_comptime? IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)? //# *** Block Level *** Statement ::= KEYWORD_comptime? VarDecl | KEYWORD_comptime BlockExprStatement | KEYWORD_nosuspend BlockExprStatement | KEYWORD_suspend (SEMICOLON | BlockExprStatement) | KEYWORD_defer BlockExprStatement | KEYWORD_errdefer BlockExprStatement | IfStatement | LabeledStatement | SwitchExpr | AssignExpr SEMICOLON IfStatement ::= IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )? | IfPrefix AssignExpr ( SEMICOLON | KEYWORD_else Payload? Statement ) LabeledStatement ::= BlockLabel? (Block | LoopStatement) LoopStatement ::= KEYWORD_inline? (ForStatement | WhileStatement) ForStatement ::= ForPrefix BlockExpr ( KEYWORD_else Statement )? | ForPrefix AssignExpr ( SEMICOLON | KEYWORD_else Statement ) WhileStatement ::= WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )? | WhilePrefix AssignExpr ( SEMICOLON | KEYWORD_else Payload? Statement ) BlockExprStatement ::= BlockExpr | AssignExpr SEMICOLON BlockExpr ::= BlockLabel? Block //# *** Expression Level *** AssignExpr ::= Expr (AssignOp Expr)? Expr ::= KEYWORD_try* BoolOrExpr BoolOrExpr ::= 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? | BlockLabel? LoopExpr | Block | CurlySuffixExpr IfExpr ::= IfPrefix Expr (KEYWORD_else Payload? Expr)? Block ::= LBRACE Statement* RBRACE LoopExpr ::= KEYWORD_inline? (ForExpr | WhileExpr) ForExpr ::= ForPrefix Expr (KEYWORD_else Expr)? WhileExpr ::= WhilePrefix Expr (KEYWORD_else Payload? Expr)? CurlySuffixExpr ::= TypeExpr InitList? InitList ::= LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE | LBRACE Expr (COMMA Expr)* COMMA? RBRACE | LBRACE RBRACE TypeExpr ::= PrefixTypeOp* ErrorUnionExpr ErrorUnionExpr ::= SuffixExpr (EXCLAMATIONMARK TypeExpr)? SuffixExpr ::= KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments | PrimaryTypeExpr (SuffixOp | FnCallArguments)* PrimaryTypeExpr ::= BUILTINIDENTIFIER FnCallArguments | CHAR_LITERAL | ContainerDecl | DOT IDENTIFIER | DOT InitList | ErrorSetDecl | FLOAT | FnProto | GroupedExpr | LabeledTypeExpr | IDENTIFIER | IfTypeExpr | INTEGER | KEYWORD_comptime TypeExpr | KEYWORD_error DOT IDENTIFIER | KEYWORD_false | KEYWORD_null | KEYWORD_anyframe | KEYWORD_true | KEYWORD_undefined | KEYWORD_unreachable | STRINGLITERAL | SwitchExpr ContainerDecl ::= (KEYWORD_extern | KEYWORD_packed)? ContainerDeclAuto ErrorSetDecl ::= KEYWORD_error LBRACE IdentifierList RBRACE GroupedExpr ::= LPAREN Expr RPAREN IfTypeExpr ::= IfPrefix TypeExpr (KEYWORD_else Payload? TypeExpr)? LabeledTypeExpr ::= BlockLabel Block | BlockLabel? LoopTypeExpr LoopTypeExpr ::= KEYWORD_inline? (ForTypeExpr | WhileTypeExpr) ForTypeExpr ::= ForPrefix TypeExpr (KEYWORD_else TypeExpr)? WhileTypeExpr ::= WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)? SwitchExpr ::= KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE //# *** Assembly *** AsmExpr ::= KEYWORD_asm KEYWORD_volatile? LPAREN STRINGLITERAL AsmOutput? RPAREN AsmOutput ::= COLON AsmOutputList AsmInput? AsmOutputItem ::= LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr | IDENTIFIER) RPAREN AsmInput ::= COLON AsmInputList AsmClobbers? AsmInputItem ::= LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN AsmClobbers ::= COLON StringList //# *** Helper grammar *** BreakLabel ::= COLON IDENTIFIER BlockLabel ::= IDENTIFIER COLON FieldInit ::= DOT IDENTIFIER EQUAL Expr WhileContinueExpr ::= COLON LPAREN AssignExpr RPAREN LinkSection ::= KEYWORD_linksection LPAREN Expr RPAREN ParamDecl ::= (KEYWORD_noalias | KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType ParamType ::= KEYWORD_anytype | DOT3 | TypeExpr //# Control flow prefixes IfPrefix ::= KEYWORD_if LPAREN Expr RPAREN PtrPayload? WhilePrefix ::= KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr? ForPrefix ::= KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload //# Payloads Payload ::= PIPE IDENTIFIER PIPE PtrPayload ::= PIPE ASTERISK? IDENTIFIER PIPE PtrIndexPayload ::= PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE //# Switch specific SwitchProng ::= SwitchCase EQUALRARROW PtrPayload? AssignExpr SwitchCase ::= SwitchItem (COMMA SwitchItem)* COMMA? | KEYWORD_else SwitchItem ::= Expr (DOT3 Expr)? //# Operators 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 | ArrayTypeStart (ByteAlign | KEYWORD_const | KEYWORD_volatile | KEYWORD_allowzero)* | PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN | KEYWORD_const | KEYWORD_volatile | KEYWORD_allowzero)* SuffixOp ::= LBRACKET Expr (DOT2 Expr?)? RBRACKET | DOT IDENTIFIER | DOTASTERISK | DOTQUESTIONMARK FnCallArguments ::= LPAREN ExprList RPAREN //# Ptr specific ArrayTypeStart ::= LBRACKET Expr? RBRACKET PtrTypeStart ::= ASTERISK | ASTERISK2 | PTRUNKNOWN | PTRC //# ContainerDecl specific ContainerDeclAuto ::= ContainerDeclType LBRACE ContainerMembers RBRACE ContainerDeclType ::= (KEYWORD_struct | KEYWORD_enum | KEYWORD_opaque) (LPAREN Expr RPAREN)? | KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? | Expr) RPAREN)? //# Alignment ByteAlign ::= KEYWORD_align LPAREN Expr RPAREN //# Lists IdentifierList ::= (IDENTIFIER COMMA)* IDENTIFIER? SwitchProngList ::= (SwitchProng COMMA)* SwitchProng? AsmOutputList ::= (AsmOutputItem COMMA)* AsmOutputItem? AsmInputList ::= (AsmInputItem COMMA)* AsmInputItem? StringList ::= (STRINGLITERAL COMMA)* STRINGLITERAL? ParamDeclList ::= (ParamDecl COMMA)* ParamDecl? ExprList ::= (Expr COMMA)* Expr? //# *** Tokens *** eof ::= "!." hex ::= [0-9a-fA-F] char_escape ::= "\\x" hex hex | "\\u{" hex+ "}" | "\\" [nr\\t'"] char_char ::= char_escape | [^\\'\n] string_char ::= char_escape | [^\\"\n] line_comment ::= '//'[^\n]* line_string ::= ("\\\\" [^\n]* [ \n]*)+ skip ::= ([ \n] | line_comment)* CHAR_LITERAL ::= "'" char_char "'" skip FLOAT ::= "0x" hex+ "." hex+ ([pP] [-+]? hex+)? skip | [0-9]+ "." [0-9]+ ([eE] [-+]? [0-9]+)? skip | "0x" hex+ "."? [pP] [-+]? hex+ skip | [0-9]+ "."? [eE] [-+]? [0-9]+ skip INTEGER ::= "0b" [01]+ skip | "0o" [0-7]+ skip | "0x" hex+ skip | [0-9]+ skip STRINGLITERALSINGLE ::= '"' string_char* '"' skip STRINGLITERAL ::= STRINGLITERALSINGLE | line_string skip IDENTIFIER ::= '!' keyword [A-Za-z_] [A-Za-z0-9_]* skip | '@"' string_char* '"' skip BUILTINIDENTIFIER ::= "@"[A-Za-z_][A-Za-z0-9_]* skip AMPERSAND ::= '&' // ![=] skip AMPERSANDEQUAL ::= '&=' // skip ASTERISK ::= '*' // ![*%=] skip ASTERISK2 ::= '**' // skip ASTERISKEQUAL ::= '*=' // skip ASTERISKPERCENT ::= '*%' // ![=] skip ASTERISKPERCENTEQUAL ::= '*%=' // skip CARET ::= '^' // ![=] skip CARETEQUAL ::= '^=' // skip COLON ::= ':' // skip COMMA ::= ',' // skip DOT ::= '.' // ![*.?] skip DOT2 ::= '..' // ![.] skip DOT3 ::= '...' // skip DOTASTERISK ::= '.*' // skip DOTQUESTIONMARK ::= '.?' // skip EQUAL ::= '=' // ![>=] skip EQUALEQUAL ::= '==' // skip EQUALRARROW ::= '=>' // skip EXCLAMATIONMARK ::= '!' // ![=] skip EXCLAMATIONMARKEQUAL ::= '!=' // skip LARROW ::= '<' // ![<=] skip LARROW2 ::= '<<' // ![=] skip LARROW2EQUAL ::= '<<=' // skip LARROWEQUAL ::= '<=' // skip LBRACE ::= '{' // skip LBRACKET ::= '[' // ![*] skip LPAREN ::= '(' // skip MINUS ::= '-' // ![%=>] skip MINUSEQUAL ::= '-=' // skip MINUSPERCENT ::= '-%' // ![=] skip MINUSPERCENTEQUAL ::= '-%=' // skip MINUSRARROW ::= '->' // skip PERCENT ::= '%' // ![=] skip PERCENTEQUAL ::= '%=' // skip PIPE ::= '|' // ![|=] skip PIPE2 ::= '||' // skip PIPEEQUAL ::= '|=' // skip PLUS ::= '+' // ![%+=] skip PLUS2 ::= '++' // skip PLUSEQUAL ::= '+=' // skip PLUSPERCENT ::= '+%' // ![=] skip PLUSPERCENTEQUAL ::= '+%=' // skip PTRC ::= '[*c]' // skip PTRUNKNOWN ::= '[*]' // skip QUESTIONMARK ::= '?' // skip RARROW ::= '>' // ![>=] skip RARROW2 ::= '>>' // ![=] skip RARROW2EQUAL ::= '>>=' // skip RARROWEQUAL ::= '>=' // skip RBRACE ::= '}' // skip RBRACKET ::= ']' // skip RPAREN ::= ')' // skip SEMICOLON ::= ';' // skip SLASH ::= '/' // ![=] skip SLASHEQUAL ::= '/=' // skip TILDE ::= '~' // skip end_of_word ::= '!'[a-zA-Z0-9_] skip 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_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_false ::= 'false' //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_null ::= 'null' //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_true ::= 'true' //end_of_word KEYWORD_try ::= 'try' //end_of_word KEYWORD_undefined ::= 'undefined' //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_and | KEYWORD_anyframe | KEYWORD_anytype | KEYWORD_allowzero | KEYWORD_asm | KEYWORD_async | KEYWORD_await | KEYWORD_break | KEYWORD_catch | KEYWORD_comptime | KEYWORD_const | KEYWORD_continue | KEYWORD_defer | KEYWORD_else | KEYWORD_enum | KEYWORD_errdefer | KEYWORD_error | KEYWORD_export | KEYWORD_extern | KEYWORD_false | KEYWORD_fn | KEYWORD_for | KEYWORD_if | KEYWORD_inline | KEYWORD_noalias | KEYWORD_null | 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_true | KEYWORD_try | KEYWORD_undefined | KEYWORD_union | KEYWORD_unreachable | KEYWORD_usingnamespace | KEYWORD_var | KEYWORD_volatile | KEYWORD_while ``` Zig-dev.ebnf: ``` Root ::= skip ContainerMembers eof //# *** Top level *** ContainerMembers ::= TestDecl ContainerMembers | TopLevelComptime ContainerMembers | KEYWORD_pub? TopLevelDecl ContainerMembers | ContainerField COMMA ContainerMembers | ContainerField TestDecl ::= KEYWORD_test STRINGLITERALSINGLE Block TopLevelComptime ::= KEYWORD_comptime BlockExpr TopLevelDecl ::= (KEYWORD_export | KEYWORD_extern STRINGLITERALSINGLE? | (KEYWORD_inline | KEYWORD_noinline))? FnProto (SEMICOLON | Block) | (KEYWORD_export | KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl | KEYWORD_usingnamespace Expr SEMICOLON FnProto ::= KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? CallConv? EXCLAMATIONMARK? (KEYWORD_anytype | TypeExpr) VarDecl ::= (KEYWORD_const | KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON ContainerField ::= KEYWORD_comptime? IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)? //# *** Block Level *** Statement ::= KEYWORD_comptime? VarDecl | KEYWORD_comptime BlockExprStatement | KEYWORD_nosuspend BlockExprStatement | KEYWORD_suspend (SEMICOLON | BlockExprStatement) | KEYWORD_defer BlockExprStatement | KEYWORD_errdefer BlockExprStatement | IfStatement | LabeledStatement | SwitchExpr | AssignExpr SEMICOLON IfStatement ::= IfPrefix BlockExpr ( KEYWORD_else Payload? Statement )? | IfPrefix AssignExpr ( SEMICOLON | KEYWORD_else Payload? Statement ) LabeledStatement ::= BlockLabel? (Block | LoopStatement) LoopStatement ::= KEYWORD_inline? (ForStatement | WhileStatement) ForStatement ::= ForPrefix BlockExpr ( KEYWORD_else Statement )? | ForPrefix AssignExpr ( SEMICOLON | KEYWORD_else Statement ) WhileStatement ::= WhilePrefix BlockExpr ( KEYWORD_else Payload? Statement )? | WhilePrefix AssignExpr ( SEMICOLON | KEYWORD_else Payload? Statement ) BlockExprStatement ::= BlockExpr | AssignExpr SEMICOLON BlockExpr ::= BlockLabel? Block //# *** Expression Level *** AssignExpr ::= Expr (AssignOp Expr)? Expr ::= BoolOrExpr BoolOrExpr ::= 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? | BlockLabel? LoopExpr | Block | CurlySuffixExpr IfExpr ::= IfPrefix Expr (KEYWORD_else Payload? Expr)? Block ::= LBRACE Statement* RBRACE LoopExpr ::= KEYWORD_inline? (ForExpr | WhileExpr) ForExpr ::= ForPrefix Expr (KEYWORD_else Expr)? WhileExpr ::= WhilePrefix Expr (KEYWORD_else Payload? Expr)? CurlySuffixExpr ::= TypeExpr InitList? InitList ::= LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE | LBRACE Expr (COMMA Expr)* COMMA? RBRACE | LBRACE RBRACE TypeExpr ::= PrefixTypeOp* ErrorUnionExpr ErrorUnionExpr ::= SuffixExpr (EXCLAMATIONMARK TypeExpr)? SuffixExpr ::= KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments | PrimaryTypeExpr (SuffixOp | FnCallArguments)* PrimaryTypeExpr ::= BUILTINIDENTIFIER FnCallArguments | CHAR_LITERAL | ContainerDecl | DOT IDENTIFIER | DOT InitList | ErrorSetDecl | FLOAT | FnProto | GroupedExpr | LabeledTypeExpr | IDENTIFIER | IfTypeExpr | INTEGER | KEYWORD_comptime TypeExpr | KEYWORD_error DOT IDENTIFIER | KEYWORD_false | KEYWORD_null | KEYWORD_anyframe | KEYWORD_true | KEYWORD_undefined | KEYWORD_unreachable | STRINGLITERAL | SwitchExpr ContainerDecl ::= (KEYWORD_extern | KEYWORD_packed)? ContainerDeclAuto ErrorSetDecl ::= KEYWORD_error LBRACE IdentifierList RBRACE GroupedExpr ::= LPAREN Expr RPAREN IfTypeExpr ::= IfPrefix TypeExpr (KEYWORD_else Payload? TypeExpr)? LabeledTypeExpr ::= BlockLabel Block | BlockLabel? LoopTypeExpr LoopTypeExpr ::= KEYWORD_inline? (ForTypeExpr | WhileTypeExpr) ForTypeExpr ::= ForPrefix TypeExpr (KEYWORD_else TypeExpr)? WhileTypeExpr ::= WhilePrefix TypeExpr (KEYWORD_else Payload? TypeExpr)? SwitchExpr ::= KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE //# *** Assembly *** AsmExpr ::= KEYWORD_asm KEYWORD_volatile? LPAREN STRINGLITERAL AsmOutput? RPAREN AsmOutput ::= COLON AsmOutputList AsmInput? AsmOutputItem ::= LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr | IDENTIFIER) RPAREN AsmInput ::= COLON AsmInputList AsmClobbers? AsmInputItem ::= LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN AsmClobbers ::= COLON StringList //# *** Helper grammar *** BreakLabel ::= COLON IDENTIFIER BlockLabel ::= IDENTIFIER COLON FieldInit ::= DOT IDENTIFIER EQUAL Expr WhileContinueExpr ::= COLON LPAREN AssignExpr RPAREN LinkSection ::= KEYWORD_linksection LPAREN Expr RPAREN CallConv ::= KEYWORD_callconv LPAREN Expr RPAREN ParamDecl ::= (KEYWORD_noalias | KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType ParamType ::= KEYWORD_anytype | DOT3 | TypeExpr //# Control flow prefixes IfPrefix ::= KEYWORD_if LPAREN Expr RPAREN PtrPayload? WhilePrefix ::= KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr? ForPrefix ::= KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload //# Payloads Payload ::= PIPE IDENTIFIER PIPE PtrPayload ::= PIPE ASTERISK? IDENTIFIER PIPE PtrIndexPayload ::= PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE //# Switch specific SwitchProng ::= SwitchCase EQUALRARROW PtrPayload? AssignExpr SwitchCase ::= SwitchItem (COMMA SwitchItem)* COMMA? | KEYWORD_else SwitchItem ::= Expr (DOT3 Expr)? //# Operators 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 | ArrayTypeStart (ByteAlign | KEYWORD_const | KEYWORD_volatile | KEYWORD_allowzero)* | PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN | KEYWORD_const | KEYWORD_volatile | KEYWORD_allowzero)* SuffixOp ::= LBRACKET Expr (DOT2 Expr?)? RBRACKET | DOT IDENTIFIER | DOTASTERISK | DOTQUESTIONMARK FnCallArguments ::= LPAREN ExprList RPAREN //# Ptr specific ArrayTypeStart ::= LBRACKET Expr? (COLON Expr)? RBRACKET PtrTypeStart ::= ASTERISK | ASTERISK2 | LBRACKET ASTERISK (LETTERC | COLON Expr)? RBRACKET //# ContainerDecl specific ContainerDeclAuto ::= ContainerDeclType LBRACE ContainerMembers RBRACE ContainerDeclType ::= KEYWORD_struct | KEYWORD_opaque | KEYWORD_enum (LPAREN Expr RPAREN)? | KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? | Expr) RPAREN)? //# Alignment ByteAlign ::= KEYWORD_align LPAREN Expr RPAREN //# Lists IdentifierList ::= (IDENTIFIER COMMA)* IDENTIFIER? SwitchProngList ::= (SwitchProng COMMA)* SwitchProng? AsmOutputList ::= (AsmOutputItem COMMA)* AsmOutputItem? AsmInputList ::= (AsmInputItem COMMA)* AsmInputItem? StringList ::= (STRINGLITERAL COMMA)* STRINGLITERAL? ParamDeclList ::= (ParamDecl COMMA)* ParamDecl? ExprList ::= (Expr COMMA)* Expr? //# *** Tokens *** eof ::= '!.' eol ::= ('\r'? '\n') | eof hex ::= [0-9a-fA-F] hex_ ::= ('_'/hex) dec ::= [0-9] dec_ ::= ('_'/dec) dec_int ::= dec (dec_* dec)? hex_int ::= hex (hex_* dec)? char_escape ::= '\\x' hex hex | '\\u{' hex+ '}' | '\\' [nr\\t'"] char_char ::= char_escape | [^\\'\r\n] string_char ::= char_escape | [^\\"\r\n] line_comment ::= '//'[^\r\n]* eol line_string ::= ('\\\\' [^\r\n]* eol skip)+ skip ::= ([ \t] | eol | line_comment)* CHAR_LITERAL ::= "'" char_char "'" skip FLOAT ::= '0x' hex_* hex '.' hex_int ([pP] [-+]? hex_int)? skip | dec_int '.' dec_int ([eE] [-+]? dec_int)? skip | '0x' hex_* hex '.'? [pP] [-+]? hex_int skip | dec_int '.'? [eE] [-+]? dec_int skip INTEGER ::= '0b' [_01]* [01] skip | '0o' [_0-7]* [0-7] skip | '0x' hex_* hex skip | dec_int skip STRINGLITERALSINGLE ::= '"' string_char* '"' skip STRINGLITERAL ::= STRINGLITERALSINGLE | line_string skip IDENTIFIER ::= '!'keyword [A-Za-z_] [A-Za-z0-9_]* skip | '@"' string_char* '"' skip BUILTINIDENTIFIER ::= '@'[A-Za-z_][A-Za-z0-9_]* skip AMPERSAND ::= '&' //![=] skip AMPERSANDEQUAL ::= '&=' // skip ASTERISK ::= '*' //![*%=] skip ASTERISK2 ::= '**' // skip ASTERISKEQUAL ::= '*=' // skip ASTERISKPERCENT ::= '*%' //![=] skip ASTERISKPERCENTEQUAL ::= '*%=' // skip CARET ::= '^' //![=] skip CARETEQUAL ::= '^=' // skip COLON ::= ':' // skip COMMA ::= ',' // skip DOT ::= '.' //![*.?] skip DOT2 ::= '..' //![.] skip DOT3 ::= '...' // skip DOTASTERISK ::= '.*' // skip DOTQUESTIONMARK ::= '.?' // skip EQUAL ::= '=' //![>=] skip EQUALEQUAL ::= '==' // skip EQUALRARROW ::= '=>' // skip EXCLAMATIONMARK ::= '!' //![=] skip EXCLAMATIONMARKEQUAL ::= '!=' // skip LARROW ::= '<' //![<=] skip LARROW2 ::= '<<' //![=] skip LARROW2EQUAL ::= '<<=' // skip LARROWEQUAL ::= '<=' // skip LBRACE ::= '{' // skip LBRACKET ::= '[' // skip LPAREN ::= '(' // skip MINUS ::= '-' //![%=>] skip MINUSEQUAL ::= '-=' // skip MINUSPERCENT ::= '-%' //![=] skip MINUSPERCENTEQUAL ::= '-%=' // skip MINUSRARROW ::= '->' // skip PERCENT ::= '%' //![=] skip PERCENTEQUAL ::= '%=' // skip PIPE ::= '|' //![|=] skip PIPE2 ::= '||' // skip PIPEEQUAL ::= '|=' // skip PLUS ::= '+' //![%+=] skip PLUS2 ::= '++' // skip PLUSEQUAL ::= '+=' // skip PLUSPERCENT ::= '+%' //![=] skip PLUSPERCENTEQUAL ::= '+%=' // skip LETTERC ::= 'c' // skip QUESTIONMARK ::= '?' // skip RARROW ::= '>' //![>=] skip RARROW2 ::= '>>' //![=] skip RARROW2EQUAL ::= '>>=' // skip RARROWEQUAL ::= '>=' // skip RBRACE ::= '}' // skip RBRACKET ::= ']' // skip RPAREN ::= ')' // skip SEMICOLON ::= ';' // skip SLASH ::= '/' //![=] skip SLASHEQUAL ::= '/=' // skip TILDE ::= '~' // skip end_of_word ::= '!'[a-zA-Z0-9_] skip 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_false ::= 'false' //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_null ::= 'null' //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_true ::= 'true' //end_of_word KEYWORD_try ::= 'try' //end_of_word KEYWORD_undefined ::= 'undefined' //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_false | KEYWORD_fn | KEYWORD_for | KEYWORD_if | KEYWORD_inline | KEYWORD_noalias | KEYWORD_nosuspend | KEYWORD_noinline | KEYWORD_null | 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_true | KEYWORD_try | KEYWORD_undefined | KEYWORD_union | KEYWORD_unreachable | KEYWORD_usingnamespace | KEYWORD_var | KEYWORD_volatile | KEYWORD_while ```
mingodad commented 2021年05月11日 14:01:49 +02:00 (Migrated from github.com)
Copy link

Looking through the code in src/stage1/parser.cpp the statement in grammar.y should be:

Statement
 <- KEYWORD_comptime? VarDecl
 / KEYWORD_comptime BlockExprStatement
 / KEYWORD_nosuspend BlockExprStatement
 / KEYWORD_suspend (SEMICOLON / BlockExprStatement)
 / KEYWORD_defer Payload? BlockExprStatement //////!!!! missing Payload here
 / KEYWORD_errdefer Payload? BlockExprStatement
 / IfStatement
 / LabeledStatement
 / SwitchExpr
 / AssignExpr SEMICOLON
Looking through the code in `src/stage1/parser.cpp` the statement in grammar.y should be: ``` Statement <- KEYWORD_comptime? VarDecl / KEYWORD_comptime BlockExprStatement / KEYWORD_nosuspend BlockExprStatement / KEYWORD_suspend (SEMICOLON / BlockExprStatement) / KEYWORD_defer Payload? BlockExprStatement //////!!!! missing Payload here / KEYWORD_errdefer Payload? BlockExprStatement / IfStatement / LabeledStatement / SwitchExpr / AssignExpr SEMICOLON ```
ifreund commented 2021年05月11日 14:12:52 +02:00 (Migrated from github.com)
Copy link

@mingodad you'd be better off looking at the self hosted parser in lib/std/zig/parse.zig. The grammar in this repo is correct and defer does not allow a Payload.

@mingodad you'd be better off looking at the self hosted parser in `lib/std/zig/parse.zig`. The grammar in this repo is correct and `defer` does not allow a `Payload`.
mingodad commented 2021年05月11日 14:16:04 +02:00 (Migrated from github.com)
Copy link

Thanks for pointing out !
This mean that the src/stage1/parser.cpp is out of sync ?

Thanks for pointing out ! This mean that the `src/stage1/parser.cpp` is out of sync ?
ifreund commented 2021年05月11日 14:22:01 +02:00 (Migrated from github.com)
Copy link

This mean that the src/stage1/parser.cpp is out of sync ?

No, on looking at it myself the stage1 parser adhears to the grammar in this case:
github.com/ziglang/zig@ac546f56eb/src/stage1/parser.cpp (L965-L966)

> This mean that the `src/stage1/parser.cpp` is out of sync ? No, on looking at it myself the stage1 parser adhears to the grammar in this case: https://github.com/ziglang/zig/blob/ac546f56eb2b9fd50a69f1d0bda3d0d070b76f52/src/stage1/parser.cpp#L965-L966
mingodad commented 2021年05月11日 14:25:14 +02:00 (Migrated from github.com)
Copy link

Thank you for pointing out !
Looking at it again as you pointed out I can see that I failed to understand the code.
Thank you again !

Thank you for pointing out ! Looking at it again as you pointed out I can see that I failed to understand the code. Thank you again !
ifreund commented 2021年05月11日 14:29:28 +02:00 (Migrated from github.com)
Copy link

Thank you for pointing out !
Looking at it again as you pointed out I can see that I failed to understand the code.
Thank you again !

No problem, as usual the self hosted parser is much more readable :)

> Thank you for pointing out ! > Looking at it again as you pointed out I can see that I failed to understand the code. > Thank you again ! No problem, as usual the self hosted parser is much more readable :)
mingodad commented 2021年05月11日 17:30:32 +02:00 (Migrated from github.com)
Copy link

I'm trying to write a zig parser using CocoR https://ssw.jku.at/Research/Projects/Coco/ and in doing so I'm getting lots of warnings/errors due to grammar ambiguity and recursion, for example comptime in PimaryExpr is recursive and zig actually accepts things like this (also with other qualifiers/attributes):

const std = @import("std");
fn fibonacci(index: u32) u32 {
 if (index < 2) return index;
 return fibonacci(index - 1) + fibonacci(index - 2);
}
pub fn main() !void {
 const stdout = std.io.getStdOut().writer();
 try stdout.print("Hello, {}!\n", .{"world"});
 try stdout.print("fibonacci(7)= {}\n", .{fibonacci(7)});
 var x7 = comptime comptime comptime fibonacci(7); ////!!! we can have an infinite/long sequence of comptime
 try stdout.print("fibonacci(7)= {}\n", .{x7});
}
I'm trying to write a zig parser using CocoR https://ssw.jku.at/Research/Projects/Coco/ and in doing so I'm getting lots of warnings/errors due to grammar ambiguity and recursion, for example `comptime` in `PimaryExpr` is recursive and zig actually accepts things like this (also with other qualifiers/attributes): ``` const std = @import("std"); fn fibonacci(index: u32) u32 { if (index < 2) return index; return fibonacci(index - 1) + fibonacci(index - 2); } pub fn main() !void { const stdout = std.io.getStdOut().writer(); try stdout.print("Hello, {}!\n", .{"world"}); try stdout.print("fibonacci(7)= {}\n", .{fibonacci(7)}); var x7 = comptime comptime comptime fibonacci(7); ////!!! we can have an infinite/long sequence of comptime try stdout.print("fibonacci(7)= {}\n", .{x7}); } ```
ifreund commented 2021年05月11日 17:50:56 +02:00 (Migrated from github.com)
Copy link

I'm trying to write a zig parser using CocoR https://ssw.jku.at/Research/Projects/Coco/ and in doing so I'm getting lots of warnings/errors due to grammar ambiguity and recursion, for example comptime in PimaryExpr is recursive and zig actually accepts things like this (also with other qualifiers/attributes):

Parsing Expression Grammars such as the grammar in this repo are by definition unambiguous. I don't see recursion as an issue in general either, although that specific case of repeated comptime keywords will be addressed by https://github.com/ziglang/zig/issues/8364.

> I'm trying to write a zig parser using CocoR https://ssw.jku.at/Research/Projects/Coco/ and in doing so I'm getting lots of warnings/errors due to grammar ambiguity and recursion, for example `comptime` in `PimaryExpr` is recursive and zig actually accepts things like this (also with other qualifiers/attributes): Parsing Expression Grammars such as the grammar in this repo are by definition unambiguous. I don't see recursion as an issue in general either, although that specific case of repeated `comptime` keywords will be addressed by https://github.com/ziglang/zig/issues/8364.
mingodad commented 2021年05月11日 17:51:29 +02:00 (Migrated from github.com)
Copy link

One recursion/duplicate/ambiguity for comptime starts in Statement:

Statement
 <- KEYWORD_comptime? VarDecl
 / KEYWORD_comptime BlockExprStatement ///!!! BlockExprStatement can start with comptime
...
BlockExprStatement
 <- BlockExpr
 / AssignExpr SEMICOLON ///!!! from here
...
AssignExpr <- Expr (AssignOp Expr)? ///!!! going down here Expr can start recursively with comptime
...
PrimaryExpr
 <- AsmExpr
...
 / KEYWORD_comptime Expr ///!!! here the recursion starts
...
One recursion/duplicate/ambiguity for `comptime` starts in `Statement`: ``` Statement <- KEYWORD_comptime? VarDecl / KEYWORD_comptime BlockExprStatement ///!!! BlockExprStatement can start with comptime ... BlockExprStatement <- BlockExpr / AssignExpr SEMICOLON ///!!! from here ... AssignExpr <- Expr (AssignOp Expr)? ///!!! going down here Expr can start recursively with comptime ... PrimaryExpr <- AsmExpr ... / KEYWORD_comptime Expr ///!!! here the recursion starts ... ```
mingodad commented 2021年05月11日 19:49:12 +02:00 (Migrated from github.com)
Copy link

It also happen with nosuspend:

const std = @import("std");
fn fibonacci(index: u32) u32 {
 if (index < 2) return index;
 return fibonacci(index - 1) + fibonacci(index - 2);
}
pub fn main() !void {
 const stdout = std.io.getStdOut().writer();
 try stdout.print("Hello, {}!\n", .{"world"});
 try stdout.print("fibonacci(7)= {}\n", .{fibonacci(7)});
 var x7 = comptime nosuspend comptime nosuspend comptime comptime nosuspend nosuspend fibonacci(7);
 try stdout.print("fibonacci(7)= {}\n", .{x7});
}

Output:

zig run hello-ct.zig 
Hello, world!
fibonacci(7)= 13
fibonacci(7)= 13
It also happen with `nosuspend`: ``` const std = @import("std"); fn fibonacci(index: u32) u32 { if (index < 2) return index; return fibonacci(index - 1) + fibonacci(index - 2); } pub fn main() !void { const stdout = std.io.getStdOut().writer(); try stdout.print("Hello, {}!\n", .{"world"}); try stdout.print("fibonacci(7)= {}\n", .{fibonacci(7)}); var x7 = comptime nosuspend comptime nosuspend comptime comptime nosuspend nosuspend fibonacci(7); try stdout.print("fibonacci(7)= {}\n", .{x7}); } ``` Output: ``` zig run hello-ct.zig Hello, world! fibonacci(7)= 13 fibonacci(7)= 13 ```
mingodad commented 2021年05月12日 14:55:47 +02:00 (Migrated from github.com)
Copy link

After talking with my pillow I'm convinced that one good way to make this grammar less trick/ambiguous/recursive would be to create a subgroup of Expr let's call it AssignableExpr with all valid Expr elements that are valid on the left hand side of an assignment.

//# *** Expression Level ***
AssignExpr =
	AssignableExpr [AssignOp Expr]
	.
AssignableExpr =
	/*Expr*/
	IDENTIFIER
 ...
	.

Also remove all recursive elements from PrimaryExpr and PrimaryTypeExpr like comptime that as I could see so far is used/valid in four cases: TopLevelComptime, VarDecl, prefixing function calls and prefixing parameter declarations.

After talking with my pillow I'm convinced that one good way to make this grammar less trick/ambiguous/recursive would be to create a subgroup of `Expr` let's call it `AssignableExpr` with all valid `Expr` elements that are valid on the **left hand** side of an **assignment**. ``` //# *** Expression Level *** AssignExpr = AssignableExpr [AssignOp Expr] . AssignableExpr = /*Expr*/ IDENTIFIER ... . ``` Also remove all recursive elements from `PrimaryExpr` and `PrimaryTypeExpr` like `comptime` that as I could see so far is used/valid in four cases: `TopLevelComptime`, `VarDecl`, prefixing function calls and prefixing parameter declarations.
alexrp unlocked this conversation 2025年12月13日 01:58:51 +01:00
Sign in to join this conversation.
No Branch/Tag specified
master
sync
disorganized-spec-chunks
No results found.
Labels
Clear labels
bounty
https://ziglang.org/news/announcing-donor-bounties
bug
Observed behavior contradicts documented or intended behavior.
contributor-friendly
This issue is limited in scope and/or knowledge of project internals.
downstream
An issue with a third-party project that uses this project.
enhancement
Solving this issue will likely involve adding new logic or components to the codebase.
infra
An issue related to project infrastructure, e.g. continuous integration.
optimization
A task to improve performance and/or resource usage.
question
No questions on the issue tracker; use a community space instead.
regression
Something that used to work in a previous version stopped working
upstream
An issue with a third-party project that this project uses.
use case
Describes a real use case that is difficult or impossible, but does not propose a solution.
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ziglang/zig-spec#30
Reference in a new issue
ziglang/zig-spec
No description provided.
Delete branch "%!s()"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?