root := ( toplevel )\n toplevel := externfunc | function | constant | typedef path := NAME function := [ COMMENT ] [ "export" ] "func" NAME "(" ( param ), ")" [ type ] block param := NAME type externfunc := "extern" "func" NAME "(" ( type ), ")" [ type ] constant := [ COMMENT ] "const" NAME "=" ( NUMBER | bool | STRING* ) typedef := [ COMMENT ] "type" NAME type block := [ ":" NAME ] "{" ( command )\n "}" command := block | statement control := if | for statement := ( return | break | continue | declaration | defer ) if := "if" expression block elseif* else* elseif := "else" "if" expression block else := "else" block for := "for" [ assignment ";" ] expression [ ";" assignment ] block return := "return" [ expression ] break := "break" [ ":" NAME ] [ expression ] continue := "continue" [ ":" NAME ] declaration := ( "const" | "var" ) NAME "=" expression assignment := location "=" expression location := path ( index | field )* [ "*" ] index := "[" expression "]" field := "." NAME call := location "(" ( expression ), ")" defer := "defer" call type := "*" type | "?" type | "!" type | bool | integer | float | struct | enum | union | array | path numtype := integer | float integer := "int8" | "uint8" | "int16" | "uint16" | "int32" | "uint32" | "int64" | "uint64" | "int" | "uint" float := "float32" | "float64" array := "[" [ expression ] "]" type struct := "struct" "{" fields "}" enum := "enum" [ "(" integer ")" ] [ "=" expression ] "{" ( NAME ), "}" union := "union" [ "(" type ")" ] "{" ( type ), "}" fields := ( NAME type ), expression := disjunction disjunction := conjunction ( "||" conjunction )* conjunction := boolean ( "&&" boolean )* boolean := equality equality := comparison [ ( "==" | "!=" ) comparison ] comparison := term [ ( "<" | "<=" | ">" | ">=" ) term ] term := numeral [ ( "<<" | ">>" ) numeral ] numeral := factor ( ( "+" | "-" ) factor )* factor := binary ( ( "*" | "/" | "%" ) binary )* binary := bitsummand ( "|" bitsummand )* bitsummand := bitfactor ( "^" | bitfactor )* bitfactor := unaryprefix ( "&" unaryprefix )* unaryprefix := [ "-" | "!" | "~" ] unarypostfix unarypostfix := primary [ "*" | "?" | "!" ] primary := control | grouping | literal | named named := assignment | call | location grouping := "(" expression ")" literal := bool | string | number | arrayelems bool := "true" | "false" string := STRING* number := NUMBER numtype arrayelems := array "{" ( expression ), "}"