== A.13 Grammar == Below is a recapitulation of the grammar that was given throughout the earlier part of this appendix. It has exactly the same content, but is in different order. The grammar has undefined terminal symbols integer-constant, character-constant, floating-constant, identifier, string, and enumeration-constant; the typewriter style words and symbols are terminals given literally. This grammar can be transformed mechanically into input acceptable for an automatic parser-generator. Besides adding whatever syntactic marking is used to indicate alternatives in productions, it is necessary to expand the ``one of'' constructions, and (depending on the rules of the parser-generator) to duplicate each production with an opt symbol, once with the symbol and once without. With one further change, namely deleting the production typedef-name: identifier and making typedef-name a terminal symbol, this grammar is acceptable to the YACC parser-generator. It has only one conflict, generated by the if-else ambiguity. translation-unit: external-declaration translation-unit external-declaration external-declaration: function-definition declaration function-definition: declaration-specifiersopt declarator declaration-listopt compound-statement declaration: declaration-specifiers init-declarator-listopt; declaration-list: declaration declaration-list declaration declaration-specifiers: storage-class-specifier declaration-specifiersopt type-specifier declaration-specifiersopt type-qualifier declaration-specifiersopt storage-class specifier: one of auto register static extern typedef type specifier: one of void char short int long float double signed unsigned struct-or-union-specifier enum-specifier typedef-name type-qualifier: one of const volatile struct-or-union-specifier: struct-or-union identifieropt { struct-declaration-list } struct-or-union identifier struct-or-union: one of struct union struct-declaration-list: struct declaration struct-declaration-list struct declaration init-declarator-list: init-declarator init-declarator-list, init-declarator init-declarator: declarator declarator = initializer struct-declaration: specifier-qualifier-list struct-declarator-list; specifier-qualifier-list: type-specifier specifier-qualifier-listopt type-qualifier specifier-qualifier-listopt struct-declarator-list: struct-declarator struct-declarator-list , struct-declarator struct-declarator: declarator declaratoropt : constant-expression enum-specifier: enum identifieropt { enumerator-list } enum identifier enumerator-list: enumerator enumerator-list , enumerator enumerator: identifier identifier = constant-expression declarator: pointeropt direct-declarator direct-declarator: identifier (declarator) direct-declarator [ constant-expressionopt ] direct-declarator ( parameter-type-list ) direct-declarator ( identifier-listopt ) pointer: * type-qualifier-listopt * type-qualifier-listopt pointer type-qualifier-list: type-qualifier type-qualifier-list type-qualifier parameter-type-list: parameter-list parameter-list , ... parameter-list: parameter-declaration parameter-list , parameter-declaration parameter-declaration: declaration-specifiers declarator declaration-specifiers abstract-declaratoropt identifier-list: identifier identifier-list , identifier initializer: assignment-expression { initializer-list } { initializer-list , } initializer-list: initializer initializer-list , initializer type-name: specifier-qualifier-list abstract-declaratoropt abstract-declarator: pointer pointeropt direct-abstract-declarator direct-abstract-declarator: ( abstract-declarator ) direct-abstract-declaratoropt [constant-expressionopt] direct-abstract-declaratoropt (parameter-type-listopt) typedef-name: identifier statement: labeled-statement expression-statement compound-statement selection-statement iteration-statement jump-statement labeled-statement: identifier : statement case constant-expression : statement default : statement expression-statement: expressionopt; compound-statement: { declaration-listopt statement-listopt } statement-list: statement statement-list statement selection-statement: if (expression) statement if (expression) statement else statement switch (expression) statement iteration-statement: while (expression) statement do statement while (expression); for (expressionopt; expressionopt; expressionopt) statement jump-statement: goto identifier; continue; break; return expressionopt; expression: assignment-expression expression , assignment-expression assignment-expression: conditional-expression unary-expression assignment-operator assignment-expression assignment-operator: one of = *= /= %= += -= <<= >>= &= ^= |= conditional-expression: logical-OR-expression logical-OR-expression ? expression : conditional-expression constant-expression: conditional-expression logical-OR-expression: logical-AND-expression logical-OR-expression || logical-AND-expression logical-AND-expression: inclusive-OR-expression logical-AND-expression && inclusive-OR-expression inclusive-OR-expression: exclusive-OR-expression inclusive-OR-expression | exclusive-OR-expression exclusive-OR-expression: AND-expression exclusive-OR-expression ^ AND-expression AND-expression: equality-expression AND-expression & equality-expression equality-expression: relational-expression equality-expression == relational-expression equality-expression != relational-expression relational-expression: shift-expression relational-expression < shift-expression relational-expression > shift-expression relational-expression <= shift-expression relational-expression >= shift-expression shift-expression: additive-expression shift-expression << additive-expression shift-expression >> additive-expression additive-expression: multiplicative-expression additive-expression + multiplicative-expression additive-expression - multiplicative-expression multiplicative-expression: multiplicative-expression * cast-expression multiplicative-expression / cast-expression multiplicative-expression % cast-expression cast-expression: unary expression (type-name) cast-expression unary-expression: postfix expression ++unary expression --unary expression unary-operator cast-expression sizeof unary-expression sizeof (type-name) unary operator: one of & * + - ~ ! postfix-expression: primary-expression postfix-expression[expression] postfix-expression(argument-expression-listopt) postfix-expression.identifier postfix-expression->+identifier postfix-expression++ postfix-expression-- primary-expression: identifier constant string (expression) argument-expression-list: assignment-expression assignment-expression-list , assignment-expression constant: integer-constant character-constant floating-constant enumeration-constant The following grammar for the preprocessor summarizes the structure of control lines, but is not suitable for mechanized parsing. It includes the symbol text, which means ordinary program text, non-conditional preprocessor control lines, or complete preprocessor conditional instructions. control-line: # define identifier token-sequence # define identifier(identifier, ... , identifier) token-sequence # undef identifier # include # include "filename" # line constant "filename" # line constant # error token-sequenceopt # pragma token-sequenceopt # preprocessor-conditional preprocessor-conditional: if-line text elif-parts else-partopt #endif if-line: # if constant-expression # ifdef identifier # ifndef identifier elif-parts: elif-line text elif-partsopt elif-line: # elif constant-expression else-part: else-line text else-line: #else