(* Generated by tools/syntax-spec write from etc/syntax/grammar.x. Read grammar.md and lexical.md for contextual contracts. Strings are token spellings; ? ... ? marks external recognition. *) source-unit = ( translation-unit | script-unit ) ; script-unit = ? script partition described in grammar.md entry points ? ; translation-unit = { unit-item } ; unit-item = ( directive | static-assert | import-declaration | protocol-form | macro-definition | keyword-definition | ( [ "static" ] , lisp-escape ) | linkage-group | declaration-definition | unit-extension ) ; linkage-group = ( "extern" , c-string , "{" , { unit-item } , "}" ) ; declaration-definition = ( [ ( "meta" , [ "native" ] ) ] , declaration-row , ( ";" | function-body ) ) ; function-body = ( block | ( "=" , ">" , expression , ";" ) ) ; import-declaration = ( "import" , c-string , [ ( "as" , identifier ) ] , [ ( "with" , import-member , { ( "," , import-member ) } ) ] , ";" ) ; import-member = ( identifier , [ ( "as" , identifier ) ] ) ; static-assert = ( "_Static_assert" , "(" , assignment , "," , assignment , ")" , ";" ) ; declaration-row = ( declaration-group , { ( "," , declaration-group ) } ) ; declaration-group = ( ( specifiers , declarator-list ) | ( specifiers , destructuring-targets , "=" , assignment ) ) ; specifiers = ( { declaration-prefix } , { qualifier } , type-specifier , { trailing-storage } ) ; declaration-prefix = ( storage | "inline" | "_Noreturn" | attribute | prefix-macro ) ; trailing-storage = ( storage | "inline" | prefix-macro ) ; storage = ( "typedef" | ( "extern" , [ c-string ] ) | "static" | "auto" | "register" | "threaded" ) ; qualifier = ( "const" | "restrict" | "volatile" ) ; type-specifier = ( scalar-specifiers | aggregate | enumeration | type-reference | type-slot ) ; scalar-specifiers = ( scalar-word , { scalar-word } ) ; scalar-word = ( "void" | "char" | "short" | "int" | "long" | "float" | "double" | "signed" | "unsigned" ) ; type-reference = ( identifier , [ ( "." , identifier ) ] ) ; type-name = ( { qualifier } , type-specifier , { pointer-part } ) ; type-operand = declaration-group ; declarator-list = ( init-declarator , { ( "," , init-declarator ) } ) ; init-declarator = ( ( declarator | declarator-row-slot ) , [ ( "=" , assignment ) ] ) ; declarator = ( { pointer-part } , [ direct-declarator ] , { declarator-suffix } ) ; pointer-part = ( "*" | "^" | ( "&" , [ "?" ] ) | qualifier | qualifier-macro ) ; direct-declarator = ( declaration-name | ( "(" , declarator , ")" ) ) ; declaration-name = ( identifier | method-name | name-slot ) ; method-name = ( method-owner , "." , identifier ) ; method-owner = ? contextual type owner under D1 ? ; declarator-suffix = ( ( "[" , [ expression ] , "]" ) | ( "(" , parameter-list , ")" ) | ( ":" , primary ) | attribute ) ; parameter-list = ( parameter , { ( "," , parameter ) } ) ; parameter = ( ( { qualifier } , type-specifier , declarator ) | "..." | parameter-slot ) ; destructuring-targets = ( "(" , identifier , "," , identifier , { ( "," , identifier ) } , ")" ) ; typed-destructuring = ( "(" , parameter-list , ")" , "=" , assignment , ";" ) ; aggregate = ( ( "struct" | "union" ) , { attribute } , [ declaration-name ] , [ ( "{" , field , { field } , "}" , { attribute } ) ] ) ; field = ( ( [ "delegate" ] , declaration-row , ";" ) | static-assert | field-extension ) ; enumeration = ( "enum" , { attribute } , [ declaration-name ] , [ ( "{" , [ ( enumerator , { ( "," , enumerator ) } , [ "," ] ) ] , "}" , { attribute } ) ] ) ; enumerator = ( ( declaration-name , [ ( "=" , conditional ) ] ) | enumerator-extension ) ; named-type = ( ( identifier , ( ";" | ( { qualifier } , ( type-specifier | ( [ ( "struct" | "union" ) ] , "{" , { field } , "}" ) ) , abstract-declarator , ";" ) ) ) | named-type-slot ) ; abstract-declarator = ? declarator with no declared name ? ; attribute = ? balanced GNU attribute or known annotation-macro invocation ? ; prefix-macro = ? known native declaration-prefix macro; contract D3 ? ; qualifier-macro = ? known native macro supplying qualifiers ? ; protocol-form = ( ( "protocol" , type-name , "(" , identifier , ")" , "{" , { associated-type } , { protocol-member } , "}" ) | ( [ "meta" ] , [ "static" ] , "protocol" , type-name , "(" , type-name , ")" , [ ( ( "as" , type-name ) | ( "tag" , ( atomic | expression-slot ) ) ) ] , ";" ) ) ; associated-type = ( "associated" , identifier , "=" , type-name , ";" ) ; protocol-member = ( specifiers , declarator , [ ( "=" , identifier ) ] , ";" ) ; block = ( "{" , { block-item } , "}" ) ; block-item = ( directive | static-assert | ( declaration-row , ";" ) | local-macro-definition | statement | block-extension ) ; statement = ( block | ";" | ( expression , ";" ) | typed-destructuring | ( ( identifier | name-slot ) , ":" ) | ( "case" , expression , ":" ) | ( "default" , ":" ) | ( "if" , "(" , expression , ")" , governed , [ ( "else" , governed ) ] ) | ( "while" , "(" , expression , ")" , governed ) | ( "do" , governed , "while" , "(" , expression , ")" ) | ( "for" , "(" , [ for-init ] , ";" , [ expression ] , ";" , [ expression ] , ")" , governed ) | ( "switch" , "(" , expression , ")" , governed ) | ( "return" , [ expression ] , ";" ) | ( ( "break" | "continue" ) , ";" ) | ( "goto" , declaration-name , ";" ) | ( "defer" , governed ) | with-statement | match-statement | try-statement | raise-statement | statement-extension ) ; for-init = ( type-operand | expression ) ; governed = ? one statement, with directive handling G1 ? ; with-statement = ( "with" , expression , [ ( "as" , identifier ) ] , block ) ; match-statement = ( "match" , "(" , expression , ")" , ( ( "{" , { ( directive | match-row ) } , "}" ) | match-row ) ) ; match-row = ( ( ( ( "case" , pattern ) | "default" ) , [ ( "if" , "(" , expression , ")" ) ] , ":" , governed ) | match-row-slot ) ; pattern = ? expression yielding a static List pattern, or macro pattern P1 ? ; try-statement = ( "try" , governed , ( ( catch-arm , { catch-arm } , [ ( "finally" , governed ) ] ) | ( "finally" , governed ) ) ) ; catch-arm = ( "catch" , ( ( [ catch-payload ] , ":" , governed ) | catch-slot ) ) ; catch-payload = ( "%(" , list-element , { catch-detail } , ")" ) ; catch-detail = ( sequence-pattern | ( "(" , bare-symbol , list-element , ")" ) ) ; sequence-pattern = ? list-mode atom beginning with '*' ? ; raise-statement = ( "raise" , "%(" , ( bare-symbol | insertion | expression-slot ) , { ( raise-detail | argument-slot ) } , ")" , ";" ) ; raise-detail = ( "(" , ( bare-symbol | expression-slot ) , list-element , ")" ) ; bare-symbol = ? bare lit-atom whose decoded spelling is an exact Symbol ? ; expression = ( assignment , { ( "," , assignment ) } ) ; assignment = ( conditional , [ ( assignment-op , assignment ) ] ) ; assignment-op = ( "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "<<=" | ">>=" | "&=" | "^=" | "|=" ) ; conditional = ( logical-or , [ ( "?" , expression , ":" , conditional ) ] ) ; logical-or = ( logical-and , { ( "||" , logical-and ) } ) ; logical-and = ( bitwise-or , { ( "&&" , bitwise-or ) } ) ; bitwise-or = ( bitwise-xor , { ( "|" , bitwise-xor ) } ) ; bitwise-xor = ( bitwise-and , { ( "^" , bitwise-and ) } ) ; bitwise-and = ( equality , { ( "&" , equality ) } ) ; equality = ( relational , { ( ( "==" | "!=" | "===" | "!==" ) , relational ) } ) ; relational = ( shift , { ( ( ( "<" | "<=" | ">" | ">=" | "in" ) , shift ) | ( "is" , [ "not" ] , type-selector ) ) } ) ; type-selector = ( type-name | ( "(" , type-name , ")" ) | cast ) ; shift = ( additive , { ( ( "<<" | ">>" ) , additive ) } ) ; additive = ( multiplicative , { ( ( "+" | "-" ) , multiplicative ) } ) ; multiplicative = ( cast , { ( ( "*" | "/" | "%" ) , cast ) } ) ; cast = ( ( "(" , type-operand , ")" , cast ) | unary ) ; unary = ( ( ( "++" | "--" ) , unary ) | ( ( "&" | "*" | "+" | "-" | "~" | "!" ) , cast ) | ( "sizeof" , ( ( "(" , ( type-operand | expression ) , ")" ) | type-operand | unary ) ) | postfix ) ; postfix = ( primary , { postfix-part } ) ; postfix-part = ( ( "[" , expression , "]" ) | ( "[" , [ expression ] , ":" , [ expression ] , [ ( ":" , [ expression ] ) ] , "]" ) | ( "(" , [ arguments ] , ")" ) | ( ( "." | "->" ) , member-name ) | "++" | "--" ) ; arguments = ( argument , { ( "," , argument ) } , [ "," ] ) ; argument = ( assignment | argument-slot ) ; member-name = ( identifier | name-slot ) ; primary = ( atomic | c-string-run | identifier | ( "(" , expression , ")" ) | statement-expression | initializer | array | map | quoted-list | quoted-array | quoted-map | percent-string | symbol-set | lambda | generic | va-arg | offsetof | lisp-escape | macro-expression | quotation | expression-slot ) ; atomic = ( integer | floating | character | c-string | symbol | atom | "void" ) ; c-string-run = ( c-string , { ( c-string | native-string-word ) } ) ; native-string-word = ? adjacent native macro or unbound word accepted by E3 ? ; statement-expression = ( "(" , block , ")" ) ; initializer = ( "{" , [ ( initializer-item , { ( "," , initializer-item ) } , [ "," ] ) ] , "}" ) ; initializer-item = ( assignment | argument-slot | ( designator , { designator } , "=" , assignment ) ) ; designator = ( ( "." , identifier ) | ( "[" , assignment , "]" ) ) ; array = ( "[" , [ ( assignment , { ( "," , assignment ) } , [ "," ] ) ] , "]" ) ; map = ( "{" , [ ( map-entry , { ( "," , map-entry ) } , [ "," ] ) ] , "}" ) ; map-entry = ( ( ( identifier | assignment ) , ":" , assignment ) | entry-extension ) ; generic = ( "_Generic" , "(" , assignment , { ( "," , ( type-name | "default" ) , ":" , assignment ) } , ")" ) ; va-arg = ( "va_arg" , "(" , assignment , "," , type-operand , ")" ) ; offsetof = ( "offsetof" , "(" , type-name , "," , identifier , { ( ( "." , identifier ) | ( "[" , expression , "]" ) ) } , ")" ) ; lambda = ( "%!" , "(" , [ ( parameter-list | bare-parameters ) ] , ")" , [ ( "using" , capture-list ) ] , "=" , ">" , ( block | assignment ) ) ; bare-parameters = ( identifier , { ( "," , identifier ) } ) ; capture-list = ( ( "&" , declaration-name , { ( "," , "&" , declaration-name ) } ) | captures-slot ) ; quoted-list = ( "%(" , { list-element } , ")" ) ; nested-list = ( "(" , { list-element } , ")" ) ; list-element = ( literal-element | insertion | splice | ( reader-prefix , list-element ) ) ; literal-element = ( atomic | nested-list | quoted-array | quoted-map | percent-string | typed-capture ) ; insertion = ( ( "$" , identifier ) | ( "${" , expression , "}" ) ) ; splice = ( ( "@" , identifier ) | ( "@{" , expression , "}" ) ) ; reader-prefix = ( "\'" | "`" | "," | ",@" ) ; typed-capture = ( "?(" , type-name , identifier , ")" ) ; quoted-array = ( "%[" , [ ( quoted-array-item , { ( "," , quoted-array-item ) } , [ "," ] ) ] , "]" ) ; quoted-array-item = ( data-element | argument-slot ) ; data-element = ( literal-element | insertion ) ; quoted-map = ( "%{" , [ ( quoted-entry , { ( "," , quoted-entry ) } , [ "," ] ) ] , "}" ) ; quoted-entry = ( ( data-element , ":" , data-element ) | quoted-entry-extension ) ; quoted-entry-extension = ( "${" , entry-extension , "}" ) ; percent-string = ( "%\"" , { ( string-segment | insertion ) } , "\"" ) ; symbol-set = ( "%<<" , { symbol-set-member } , ">>" ) ; symbol-set-member = ? symbol-set-mode lit-atom or lit-symbol ? ; unit-extension = ( class-declaration | unit-macro | decorator ) ; class-declaration = ( [ "static" ] , "class" , named-type ) ; statement-extension = ( foreach-statement | statement-macro | decorator ) ; foreach-statement = ( "foreach" , "(" , declaration-argument , ( "in" | "," ) , assignment , ")" , governed ) ; declaration-argument = ( specifiers , ( init-declarator | destructuring-targets ) ) ; keyword-definition = ( [ "static" ] , "keyword" , identifier , macro-name , ";" ) ; macro-name = ( "$" , identifier , { ( "." , identifier ) } ) ; macro-definition = ( [ "static" ] , "macro" , result-kind , macro-name , macro-signature , macro-body ) ; local-macro-definition = ( "macro" , result-kind , identifier , macro-signature , macro-body ) ; anonymous-macro = ( "macro" , result-kind , macro-signature , macro-body ) ; macro-expression = ( macro-call | local-macro-call | anonymous-macro | meta-call | macro-name ) ; macro-signature = ( "(" , [ ( hole-parameter , { ( "," , hole-parameter ) } ) ] , ")" , [ ( "using" , using-list ) ] ) ; hole-parameter = ( [ hole-kind ] , ( "$" | "@" ) , identifier ) ; using-list = ( ( "$" , identifier , { ( "," , "$" , identifier ) } ) | ( identifier , { ( "," , identifier ) } ) ) ; macro-body = ? body selected by result/target kind; contract M2 ? ; macro-call = ( macro-name , "(" , macro-arguments , ")" ) ; local-macro-call = ( identifier , "(" , macro-arguments , ")" ) ; meta-call = ( macro-name , "(" , [ ( meta-argument , { ( "," , meta-argument ) } ) ] , ")" ) ; meta-argument = ( assignment | meta-value-hole ) ; meta-value-hole = ? whole template hole passed as a value, under M5 ? ; macro-arguments = ? signature-directed argument sequence; contract M1 ? ; decorator = ? visible decorator invocation followed by its target; M3 ? ; quotation = ( "$" , "!" , ( ( "(" , expression , ")" ) | ( [ quotation-kind ] , "{" , quotation-items , "}" ) | ( quotation-type , "{" , expression , "}" ) ) ) ; quotation-kind = ( result-kind | "Type" | "Param" ) ; quotation-type = ? type operand or computed type under M4 ? ; quotation-items = ? contents selected by quotation kind, with ${expr} and @{expr} holes; M4 ? ; result-kind = ( "Expr" | "Expression" | "Stmt" | "Field" | "Entry" | "Enumerator" | "Unit" | "Declaration" | "Decorator" ) ; hole-kind = ( "Expr" | "Expression" | "Stmt" | "Field" | "Entry" | "Enumerator" | "Unit" | "Function" | "NamedType" | "Type" | "Decl" | "DeclaratorRow" | "Name" | "Literal" | "Param" | "Catch" | "Captures" | "MatchRow" ) ; expression-slot = ? expression slot under M5 ? ; argument-slot = ? argument sequence slot: @name, @call(...), or @(form); M5 ? ; declarator-row-slot = ? declarator row slot under M5 ? ; named-type-slot = ? named type slot under M5 ? ; type-slot = ? type slot under M5 ? ; name-slot = ? name slot under M5 ? ; parameter-slot = ? parameter slot under M5 ? ; captures-slot = ? capture slot under M5 ? ; catch-slot = ? catch-arm slot under M5 ? ; match-row-slot = ? match-row slot under M5 ? ; unit-macro = ? unit-position macro/slot under M1-M5 ? ; block-extension = ? block-position macro/slot under M1-M5 ? ; statement-macro = ? statement-position macro/slot under M1-M5 ? ; field-extension = ? field-position macro/slot under M1-M5 ? ; enumerator-extension = ? enumerator-position macro/slot under M1-M5 ? ; entry-extension = ? map-entry-position macro/slot under M1-M5 ? ; lisp-escape = ( "$(" , { lisp-form } , ")" ) ; lisp-form = ( lisp-atom | ( "(" , { lisp-form } , ")" ) | ( reader-prefix , lisp-form ) | lisp-hole ) ; lisp-atom = ( integer | floating | c-string | symbol | lisp-identifier ) ; lisp-hole = ? template hole in compiler Lisp; M5 ? ; lisp-identifier = ? ident token in Lisp mode ? ; identifier = ? identifier accepted in the current name position; D1 ? ; integer = ? lit-int ? ; floating = ? lit-float ? ; character = ? lit-char ? ; c-string = ? lit-char* ? ; symbol = ? lit-symbol ? ; atom = ? lit-atom ? ; string-segment = ? segment ? ; directive = ? preproc token retained/selected by preprocessing; G1 ? ;