This a grammar for plain C reformatted from 
this
Yacc file.  Tokens are in 
bold.
| TranslationUnit | → | ExternalDecl | 
|  | | | TranslationUnitExternalDecl | 
| ExternalDecl | → | FunctionDefinition | 
|  | | | Decl | 
| FunctionDefinition | → | DeclSpecsDeclaratorDeclListCompoundStat | 
|  | | | DeclaratorDeclListCompoundStat | 
|  | | | DeclSpecsDeclaratorCompoundStat | 
|  | | | DeclaratorCompoundStat | 
| Decl | → | DeclSpecsInitDeclaratorList; | 
|  | | | DeclSpecs; | 
| DeclList | → | Decl | 
|  | | | DeclListDecl | 
| DeclSpecs | → | StorageClassSpecDeclSpecs | 
|  | | | StorageClassSpec | 
|  | | | TypeSpecDeclSpecs | 
|  | | | TypeSpec | 
|  | | | TypeQualifierDeclSpecs | 
|  | | | TypeQualifier | 
| StorageClassSpec | → | auto|register|static|extern|typedef | 
| TypeSpec | → | void|char|short|int|long|float
|double|signed|unsigned | 
|  | | | StructOrUnionSpec|EnumSpec|TypedefName | 
| TypeQualifier | → | const|volatile | 
| StructOrUnionSpec | → | StructOrUnionId{StructDeclList} | 
|  | | | StructOrUnion{StructDeclList} | 
|  | | | StructOrUnionId | 
| StructOrUnion | → | struct|union | 
| StructDeclList | → | StructDecl | 
|  | | | StructDeclListStructDecl | 
| InitDeclaratorList | → | InitDeclarator | 
|  | | | InitDeclaratorList,InitDeclarator | 
| InitDeclarator | → | Declarator | 
|  | | | Declarator=Initializer | 
| StructDecl | → | SpecQualifierListStructDeclaratorList; | 
| SpecQualifierList | → | TypeSpecSpecQualifierList | 
|  | | | TypeSpec | 
|  | | | TypeQualifierSpecQualifierList | 
|  | | | TypeQualifier | 
| StructDeclaratorList | → | StructDeclarator | 
|  | | | StructDeclaratorList,StructDeclarator | 
| StructDeclarator | → | Declarator | 
|  | | | Declarator:ConstExp | 
|  | | | :ConstExp | 
| EnumSpec | → | enumId{EnumeratorList} | 
|  | | | enum{EnumeratorList} | 
|  | | | enumId | 
| EnumeratorList | → | Enumerator | 
|  | | | EnumeratorList,Enumerator | 
| Enumerator | → | Id | 
|  | | | Id=ConstExp | 
| Declarator | → | PointerDirectDeclarator | 
|  | | | DirectDeclarator | 
| DirectDeclarator | → | Id | 
|  | | | (Declarator) | 
|  | | | DirectDeclarator[ConstExp] | 
|  | | | DirectDeclarator[] | 
|  | | | DirectDeclarator(ParamTypeList | 
|  | | | DirectDeclarator(IdList) | 
|  | | | DirectDeclarator() | 
| Pointer | → | *TypeQualifierList | 
|  | | | * | 
|  | | | *TypeQualifierListPointer | 
|  | | | *Pointer | 
| TypeQualifierList | → | TypeQualifier | 
|  | | | TypeQualifierListTypeQualifier | 
| ParamTypeList | → | ParamList | 
|  | | | ParamList,... | 
| ParamList | → | ParamDecl | 
|  | | | ParamList,ParamDecl | 
| ParamDecl | → | DeclSpecsDeclarator | 
|  | | | DeclSpecsAbstractDeclarator | 
|  | | | DeclSpecs | 
| IdList | → | Id | 
|  | | | IdList,Id | 
| Initializer | → | AssignmentExp | 
|  | | | {InitializerList} | 
|  | | | {InitializerList,} | 
| InitializerList | → | Initializer | 
|  | | | InitializerList,Initializer | 
| TypeName | → | SpecQualifierListAbstractDeclarator | 
|  | | | SpecQualifierList | 
| AbstractDeclarator | → | Pointer | 
|  | | | PointerDirectAbstractDeclarator | 
|  | | | DirectAbstractDeclarator | 
| DirectAbstractDeclarator | → | (AbstractDeclarator) | 
|  | | | DirectAbstractDeclarator[ConstExp] | 
|  | | | [ConstExp] | 
|  | | | DirectAbstractDeclarator[] | 
|  | | | [] | 
|  | | | DirectAbstractDeclarator(ParamTypeList) | 
|  | | | (ParamTypeList) | 
|  | | | DirectAbstractDeclarator() | 
|  | | | () | 
| TypedefName | → | Id | 
| Stat | → | LabeledStat|ExpStat|CompoundStat|SelectionStat|
IterationStat|JumpStat | 
| LabeledStat | → | Id:Stat | 
|  | | | caseConstExp:Stat | 
|  | | | default:Stat | 
| ExpStat | → | Exp; | 
|  | | | ; | 
| CompoundStat | → | {DeclListStatList} | 
|  | | | {StatList} | 
|  | | | {DeclList} | 
|  | | | {} | 
| StatList | → | Stat | 
|  | | | StatListStat | 
| SelectionStat | → | if(Exp)Stat | 
|  | | | if(Exp)StatelseStat | 
|  | | | switch(Exp)Stat | 
| IterationStat | → | while(Exp)Stat | 
|  | | | doStatwhile(Exp); | 
|  | | | for(Exp;Exp;Exp)Stat | 
|  | | | for(Exp;Exp;)Stat | 
|  | | | for(Exp;;Exp)Stat | 
|  | | | for(Exp;;)Stat | 
|  | | | for(;Exp;Exp)Stat | 
|  | | | for(;Exp;)Stat | 
|  | | | for(;;Exp)Stat | 
|  | | | for(;;)Stat | 
| JumpStat | → | JumpSpec; | 
| JumpSpec | → | gotoId|continue|break|returnExp|return | 
| Exp | → | AssignmentExp | 
|  | | | Exp,AssignmentExp | 
| AssignmentExp | → | ConditionalExp | 
|  | | | UnaryExpAssignmentOperatorAssignmentExp | 
| AssignmentOperator | → | =|*=|/=|%=|+=|-=|<<=|
>>=|&=|^=||= | 
| ConditionalExp | → | LogicalOrExp | 
|  | | | LogicalOrExp?Exp:ConditionalExp | 
| ConstExp | → | ConditionalExp | 
| LogicalOrExp | → | LogicalAndExp | 
|  | | | LogicalOrExp||LogicalAndExp | 
| LogicalAndExp | → | InclusiveOrExp | 
|  | | | LogicalAndExp&&InclusiveOrExp | 
| InclusiveOrExp | → | ExclusiveOrExp | 
|  | | | InclusiveOrExp|ExclusiveOrExp | 
| ExclusiveOrExp | → | AndExp | 
|  | | | ExclusiveOrExp^AndExp | 
| AndExp | → | EqualityExp | 
|  | | | AndExp&EqualityExp | 
| EqualityExp | → | RelationalExp | 
|  | | | EqualityExp==RelationalExp | 
|  | | | EqualityExp!=RelationalExp | 
| RelationalExp | → | ShiftExpression | 
|  | | | RelationalExp<ShiftExpression | 
|  | | | RelationalExp>ShiftExpression | 
|  | | | RelationalExp<=ShiftExpression | 
|  | | | RelationalExp>=ShiftExpression | 
| ShiftExpression | → | AdditiveExp | 
|  | | | ShiftExpression<<AdditiveExp | 
|  | | | ShiftExpression>>AdditiveExp | 
| AdditiveExp | → | MultExp | 
|  | | | AdditiveExp+MultExp | 
|  | | | AdditiveExp-MultExp | 
| MultExp | → | CastExp | 
|  | | | MultExp*CastExp | 
|  | | | MultExp/CastExp | 
|  | | | MultExp%CastExp | 
| CastExp | → | UnaryExp | 
|  | | | (TypeName)CastExp | 
| UnaryExp | → | PostfixExp | 
|  | | | ++UnaryExp | 
|  | | | --UnaryExp | 
|  | | | UnaryOperatorCastExp | 
|  | | | sizeofUnaryExp | 
|  | | | sizeof(TypeName) | 
| UnaryOperator | → | &|*|+|-|~|! | 
| PostfixExp | → | PrimaryExp | 
|  | | | PostfixExp[Exp] | 
|  | | | PostfixExp(ArgumentExpList) | 
|  | | | PostfixExp() | 
|  | | | PostfixExp.Id | 
|  | | | PostfixExp->Id | 
|  | | | PostfixExp++ | 
|  | | | PostfixExp-- | 
| PrimaryExp | → | Id|IntConst|FloatConst|
EnumerationConst|StringConst|
(Exp) | 
| ArgumentExpList | → | AssignmentExp | 
|  | | | ArgumentExpList,AssignmentExp | 
Nothing Helps
In the above grammar, the replacement is always a non-empty string.
Right sides may be empty, usually written as ε.  A rule can
then take the form 
Whatever→ε, meaning that
the non-terminal 
Whatever is allowed to just disappear during a 
derivation.  This can simplify certain things.  For instance, 
the C 
for statement may omit any of the initialization, 
test, or increment parts of the header.  In the above, this is
represented by giving eight versions of the 
for header, with each
combination of presence or omission.  But using an epsilon rule, we
can write this more concisely.
| IterationStat | → | while(Exp)Stat | 
|  | | | doStatwhile(Exp); | 
|  | | | for(OptExp;OptExp;OptExp)Stat | 
| OptExp | → | Exp|ε | 
Epsilon may help in other places as well, but this seems the most
dramatic.