/* [The "BSD licence"] Copyright (c) 2013 Sam Harwell All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** C 2011 grammar built from the C11 Spec */ grammar C; primaryExpression : Identifier | Constant | StringLiteral+ | '__extension__'? '(' expression ')' | genericSelection | '__extension__'? '(' compoundStatement ')' // Blocks (GCC extension) | '__builtin_va_arg' '(' unaryExpression ',' typeName ')' | '__builtin_offsetof' '(' typeName ',' unaryExpression ')' ; genericSelection : '_Generic' '(' assignmentExpression ',' genericAssocList ')' ; genericAssocList : genericAssociation (',' genericAssociation)* ; genericAssociation : (typeName | 'default') ':' assignmentExpression ; postfixExpression : ( primaryExpression | '__extension__'? '(' typeName ')' '{' initializerList ','? '}' ) ('[' expression ']' | '(' argumentExpressionList? ')' | ('.' | '->') Identifier | ('++' | '--') )* ; passignmentExpression : ( specifierQualifierList | assignmentExpression ) ; argumentExpressionList : passignmentExpression (',' passignmentExpression)* ; unaryExpression : ('++' | '--' | 'sizeof')* (postfixExpression | unaryOperator castExpression | ('sizeof' | '_Alignof') '(' typeName ')' | '&&' Identifier // GCC extension address of label ) ; unaryOperator : '&' | '*' | '+' | '-' | '~' | '!' ; castExpression : '__extension__'? '(' typeName ')' castExpression | unaryExpression | DigitSequence // for ; multiplicativeExpression : castExpression (('*'|'/'|'%') castExpression)* ; additiveExpression : multiplicativeExpression (('+'|'-') multiplicativeExpression)* ; shiftExpression : additiveExpression (('<<'|'>>') additiveExpression)* ; relationalExpression : shiftExpression (('<'|'>'|'<='|'>=') shiftExpression)* ; equalityExpression : relationalExpression (('=='| '!=') relationalExpression)* ; andExpression : equalityExpression ( '&' equalityExpression)* ; exclusiveOrExpression : andExpression ('^' andExpression)* ; inclusiveOrExpression : exclusiveOrExpression ('|' exclusiveOrExpression)* ; logicalAndExpression : inclusiveOrExpression ('&&' inclusiveOrExpression)* ; logicalOrExpression : logicalAndExpression ( '||' logicalAndExpression)* ; conditionalExpression : logicalOrExpression ('?' expression ':' conditionalExpression)? ; assignmentExpression : conditionalExpression | unaryExpression assignmentOperator assignmentExpression | DigitSequence // for ; assignmentOperator : '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|=' ; expression : assignmentExpression (',' assignmentExpression)* ; constantExpression : conditionalExpression ; declaration : fptypeSpecifier | declarationSpecifiers initDeclaratorList? ';' | staticAssertDeclaration ; declarationSpecifiers : declarationSpecifier+ ; funcDeclarationSpecifiers : funcDeclarationSpecifier* declarationSpecifier funcDeclarationSpecifier* ; declarationSpecifiers2 : declarationSpecifier+ ; funcDeclarationSpecifier : storageClassSpecifier | typeQualifier | functionSpecifier | alignmentSpecifier ; declarationSpecifier : storageClassSpecifier | typeSpecifier | typeQualifier | functionSpecifier | alignmentSpecifier ; // | pointer initDeclaratorList : initDeclarator (',' initDeclarator)* ; initDeclarator : declarator ('=' initializer)? ; storageClassSpecifier : 'typedef' | 'extern' | 'static' | '_Thread_local' | 'auto' | 'register' ; fptypeSpecifier : 'typedef' functionPtrDeclaration ; typeSpecifier : ('void' | 'char' | 'short' | 'int' | 'long' | 'float' | 'double' | 'signed' | 'unsigned' | '_Bool' | '_Complex' | '__m128' | '__m128d' | '__m128i')+ | '__extension__' 'typedef'? typeSpecifier+ | '__extension__' '(' ('__m128' | '__m128d' | '__m128i') ')' | atomicTypeSpecifier | '__extension__'? structOrUnionSpecifier | enumSpecifier | '__typeof__' '(' constantExpression ')' // GCC extension | typeSpecifier pointer | typedefName | gccAttributeSpecifier ; structOrUnionSpecifier : structOrUnion Identifier? '{' structDeclarationList '}' | structOrUnion Identifier ; structOrUnion : 'struct' | 'union' ; structDeclarationList : structDeclaration+ ; structDeclaration : specifierQualifierList structDeclaratorList? ';' | staticAssertDeclaration ; specifierQualifierList : (functionPtrDeclaration | typeSpecifier| typeQualifier) specifierQualifierList? ; structDeclaratorList : structDeclarator (',' structDeclarator)* ; structDeclarator : declarator | declarator? ':' constantExpression ; enumSpecifier : 'enum' Identifier? '{' enumeratorList ','? '}' | 'enum' Identifier ; enumeratorList : enumerator (',' enumerator)* ; enumerator : enumerationConstant ('=' constantExpression)? ; enumerationConstant : Identifier ; atomicTypeSpecifier : '_Atomic' '(' typeName ')' ; typeQualifier : 'const' | 'restrict' | '__restrict' | '__restrict__' | 'volatile' | 'register' | '_Atomic' ; functionSpecifier : ('inline' | '__extension__' | '_Noreturn' | '__inline' // GCC extension | '__inline__' // GCC extension | '__stdcall') | gccAttributeSpecifier | '__declspec' '(' Identifier ')' ; alignmentSpecifier : '_Alignas' '(' (typeName | constantExpression) ')' ; declarator : pointer? directDeclarator gccDeclaratorExtension* ; funcDeclarator : pointer? directFunctionDeclarator gccDeclaratorExtension* ; directFunctionDeclarator : directDeclarator '(' parameterTypeList? ')' | directDeclarator '(' identifierList? ')' ; directDeclarator : Identifier | '(' declarator ')' | directDeclarator '[' typeQualifierList? assignmentExpression? ']' | directDeclarator '[' 'static' typeQualifierList? assignmentExpression ']' | directDeclarator '[' typeQualifierList 'static' assignmentExpression ']' | directDeclarator '[' typeQualifierList? '*' ']' | directDeclarator '(' parameterTypeList ')' | directDeclarator '(' identifierList? ')' | Identifier ':' DigitSequence // bit field | '(' typeSpecifier? pointer directDeclarator ')' // function pointer like: (__cdecl *f) ; gccDeclaratorExtension : '__asm' '(' StringLiteral+ ')' | '__asm__' '(' StringLiteral+ ')' | gccAttributeSpecifier ; gccAttributeSpecifier : '__attribute__' '(' '(' gccAttributeList ')' ')' ; gccAttributeList : gccAttribute? (',' gccAttribute?)* ; gccAttribute : ~(',' | '(' | ')') // relaxed def for "identifier or reserved word" ('(' argumentExpressionList? ')')? ; nestedParenthesesBlock : ( ~('(' | ')') | '(' nestedParenthesesBlock ')' )* ; pointer : (('*'|'^') typeQualifierList?)+ // ^ - Blocks language extension ; typeQualifierList : typeQualifier+ ; parameterTypeList : parameterList (',' '...')? ; parameterList : parameterDeclaration (',' parameterDeclaration)* ; parameterDeclaration : declarationSpecifiers declarator | declarationSpecifiers2 abstractDeclarator? ; identifierList : Identifier (',' Identifier)* ; typeName : specifierQualifierList abstractDeclarator? ; abstractDeclarator : pointer | pointer? directAbstractDeclarator gccDeclaratorExtension* ; directAbstractDeclarator : '(' abstractDeclarator ')' gccDeclaratorExtension* | '[' typeQualifierList? assignmentExpression? ']' | '[' 'static' typeQualifierList? assignmentExpression ']' | '[' typeQualifierList 'static' assignmentExpression ']' | '[' '*' ']' | '(' parameterTypeList? ')' gccDeclaratorExtension* | directAbstractDeclarator '[' typeQualifierList? assignmentExpression? ']' | directAbstractDeclarator '[' 'static' typeQualifierList? assignmentExpression ']' | directAbstractDeclarator '[' typeQualifierList 'static' assignmentExpression ']' | directAbstractDeclarator '[' '*' ']' | directAbstractDeclarator '(' parameterTypeList? ')' gccDeclaratorExtension* ; typedefName : Identifier ; initializer : assignmentExpression | '{' initializerList ','? '}' | '{' '}' ; initializerList : designation? initializer (',' designation? initializer)* ; designation : designatorList '=' ; designatorList : designator+ ; designator : '[' constantExpression ']' | '.' Identifier ; staticAssertDeclaration : '_Static_assert' '(' constantExpression ',' StringLiteral+ ')' ';' ; statement : labeledStatement | compoundStatement | expressionStatement | selectionStatement | iterationStatement | jumpStatement | macroSelectionStatement | ('__asm' | '__asm__') ('volatile' | '__volatile__') '(' (logicalOrExpression (',' logicalOrExpression)*)? (':' (logicalOrExpression (',' logicalOrExpression)*)?)* ')' ';' ; /* labeledStatement : Identifier ':' blockItemList | 'case' constantExpression ':' blockItemList | 'default' ':' blockItemList ; */ labeledStatement : Identifier ':' statement | 'case' constantExpression ':' ( declaration | statement ) | 'default' ':' ( declaration | statement ) ; compoundStatement : '{' blockItemList? '}' ; blockItemList : blockItem+ ; blockItem : declaration | statement ; expressionStatement : expression? ';' ; selectionStatement : 'if' '(' expression ')' statement ('else' statement)? | 'switch' '(' expression ')' statement ; macroSelectionStatement : '#ifdef' Identifier blockItemList ('#else' blockItemList)? '#endif' ; iterationStatement : While '(' expression ')' statement | Do statement While '(' expression ')' ';' | For '(' forCondition ')' statement ; // | 'for' '(' expression? ';' expression? ';' forUpdate? ')' statement // | For '(' declaration expression? ';' expression? ')' statement forCondition : (forDeclaration | expression?) ';' forExpression? ';' forExpression? ; forDeclaration : declarationSpecifiers initDeclaratorList? ; forExpression : assignmentExpression (',' assignmentExpression)* ; jumpStatement : ('goto' Identifier | ('continue'| 'break') | 'return' expression? | 'goto' unaryExpression // GCC extension ) ';' ; compilationUnit : translationUnit? EOF ; translationUnit : externalDeclaration+ ; externalDeclaration : fptypeSpecifier | functionDeclaration | functionDefinition | declaration | macroDefinition | ';' // stray ; ; functionPtrDeclaration : typeSpecifier+ gccAttributeSpecifier? '(' pointer Identifier ')' '(' parameterTypeList? ')' | typeSpecifier+ '(' gccAttributeSpecifier? '(' pointer Identifier ')' ')' '(' parameterTypeList? ')' ; functionDeclaration : ~'typedef' funcDeclarationSpecifiers? funcDeclarator declarationList? ';' ; functionDefinition : funcDeclarationSpecifiers? declarator declarationList? compoundStatement ; stringIdentifier : ( Identifier+ | StringLiteral | Constant) ; stringIdentifierList : stringIdentifier (',' stringIdentifier )* ; macroDefinition : (directDeclarator|Identifier) '(' stringIdentifierList? ')' ';'? ; declarationList : declaration+ ; Auto : 'auto'; Break : 'break'; Case : 'case'; Char : 'char'; Const : 'const'; Continue : 'continue'; Default : 'default'; Do : 'do'; Double : 'double'; Else : 'else'; Enum : 'enum'; Extern : 'extern'; Float : 'float'; For : 'for'; Goto : 'goto'; If : 'if'; Inline : 'inline'; Int : 'int'; Long : 'long'; Register : 'register'; Restrict : 'restrict'; Return : 'return'; Short : 'short'; Signed : 'signed'; Sizeof : 'sizeof'; Static : 'static'; Struct : 'struct'; Switch : 'switch'; Typedef : 'typedef'; Union : 'union'; Unsigned : 'unsigned'; Void : 'void'; Volatile : 'volatile'; While : 'while'; Alignas : '_Alignas'; Alignof : '_Alignof'; Atomic : '_Atomic'; Bool : '_Bool'; Complex : '_Complex'; Generic : '_Generic'; Imaginary : '_Imaginary'; Noreturn : '_Noreturn'; StaticAssert : '_Static_assert'; ThreadLocal : '_Thread_local'; LeftParen : '('; RightParen : ')'; LeftBracket : '['; RightBracket : ']'; LeftBrace : '{'; RightBrace : '}'; Less : '<'; LessEqual : '<='; Greater : '>'; GreaterEqual : '>='; LeftShift : '<<'; RightShift : '>>'; Plus : '+'; PlusPlus : '++'; Minus : '-'; MinusMinus : '--'; Star : '*'; Div : '/'; Mod : '%'; And : '&'; Or : '|'; AndAnd : '&&'; OrOr : '||'; Caret : '^'; Not : '!'; Tilde : '~'; Question : '?'; Colon : ':'; Semi : ';'; Comma : ','; Assign : '='; // '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|=' StarAssign : '*='; DivAssign : '/='; ModAssign : '%='; PlusAssign : '+='; MinusAssign : '-='; LeftShiftAssign : '<<='; RightShiftAssign : '>>='; AndAssign : '&='; XorAssign : '^='; OrAssign : '|='; Equal : '=='; NotEqual : '!='; Arrow : '->'; Dot : '.'; Ellipsis : '...'; Identifier : IdentifierNondigit ( IdentifierNondigit | Digit )* ; fragment IdentifierNondigit : Nondigit | UniversalCharacterName //| // other implementation-defined characters... ; fragment Nondigit : [a-zA-Z_] ; fragment Digit : [0-9] ; fragment UniversalCharacterName : '\\u' HexQuad | '\\U' HexQuad HexQuad ; fragment HexQuad : HexadecimalDigit HexadecimalDigit HexadecimalDigit HexadecimalDigit ; Constant : IntegerConstant | FloatingConstant //| EnumerationConstant | CharacterConstant ; fragment IntegerConstant : DecimalConstant IntegerSuffix? | OctalConstant IntegerSuffix? | HexadecimalConstant IntegerSuffix? | BinaryConstant ; fragment BinaryConstant : '0' [bB] [0-1]+ ; fragment DecimalConstant : NonzeroDigit Digit* ; fragment OctalConstant : '0' OctalDigit* ; fragment HexadecimalConstant : HexadecimalPrefix HexadecimalDigit+ ; fragment HexadecimalPrefix : '0' [xX] ; fragment NonzeroDigit : [1-9] ; fragment OctalDigit : [0-7] ; fragment HexadecimalDigit : [0-9a-fA-F] ; fragment IntegerSuffix : UnsignedSuffix LongSuffix? | UnsignedSuffix LongLongSuffix | LongSuffix UnsignedSuffix? | LongLongSuffix UnsignedSuffix? ; fragment UnsignedSuffix : [uU] ; fragment LongSuffix : [lL] ; fragment LongLongSuffix : 'll' | 'LL' ; fragment FloatingConstant : DecimalFloatingConstant | HexadecimalFloatingConstant ; fragment DecimalFloatingConstant : FractionalConstant ExponentPart? FloatingSuffix? | DigitSequence ExponentPart FloatingSuffix? ; fragment HexadecimalFloatingConstant : HexadecimalPrefix (HexadecimalFractionalConstant | HexadecimalDigitSequence) BinaryExponentPart FloatingSuffix? ; fragment FractionalConstant : DigitSequence? '.' DigitSequence | DigitSequence '.' ; fragment ExponentPart : [eE] Sign? DigitSequence ; fragment Sign : [+-] ; DigitSequence : Digit+ ; fragment HexadecimalFractionalConstant : HexadecimalDigitSequence? '.' HexadecimalDigitSequence | HexadecimalDigitSequence '.' ; fragment BinaryExponentPart : [pP] Sign? DigitSequence ; fragment HexadecimalDigitSequence : HexadecimalDigit+ ; fragment FloatingSuffix : [flFL] ; fragment CharacterConstant : '\'' CCharSequence '\'' | 'L\'' CCharSequence '\'' | 'u\'' CCharSequence '\'' | 'U\'' CCharSequence '\'' ; fragment CCharSequence : CChar+ ; fragment CChar : ~['\\\r\n] | EscapeSequence ; fragment EscapeSequence : SimpleEscapeSequence | OctalEscapeSequence | HexadecimalEscapeSequence | UniversalCharacterName ; fragment SimpleEscapeSequence : '\\' ['"?abfnrtv\\] ; fragment OctalEscapeSequence : '\\' OctalDigit OctalDigit? OctalDigit? ; fragment HexadecimalEscapeSequence : '\\x' HexadecimalDigit+ ; StringLiteral : EncodingPrefix? '"' SCharSequence? '"' ; fragment EncodingPrefix : 'u8' | 'u' | 'U' | 'L' ; fragment SCont : '\\\n' // Added line | '\\\r\n' // Added line ; fragment SCharSequence : SChar+ ; fragment SChar : ~["\\\r\n] | EscapeSequence | SCont ; ComplexDefine : '#' Whitespace? 'define' ( ~[\\\r\n]* SCont )* ~[\r\n]* -> skip ; Macroundef : '#' Whitespace? 'undef' ~[\r\n]* -> skip ; Macroifdef : '#' Whitespace? 'ifdef' ~[\r\n]* -> skip ; Macroifndef : '#' Whitespace? 'ifndef' ~[\r\n]* -> skip ; Macroelse : '#' Whitespace? 'else' ~[\r\n]* -> skip ; Macroendif : '#' Whitespace? 'endif' ~[\r\n]* -> skip ; IncludeDirective : '#' Whitespace? ('include'|'import') Whitespace? (('"' ~[\r\n]* '"') | ('<' ~[\r\n]* '>' )) Whitespace? LineComment? Newline -> skip ; // ignore the following asm blocks: /* asm { mfspr x, 286; } */ AsmBlock : 'asm' ~'{'* '{' ~'}'* '}' -> skip ; // ignore the lines generated by c preprocessor // sample line : '#line 1 "/home/dm/files/dk1.h" 1' LineAfterPreprocessing : '#line' Whitespace* ~[\r\n]* -> skip ; LineDirective : '#' Whitespace? DecimalConstant Whitespace? StringLiteral ~[\r\n]* -> skip ; PragmaDirective : '#' Whitespace? ('pragma'|'error') Whitespace ~[\r\n]* -> skip ; Whitespace : [ \t]+ -> skip ; Newline : ( '\r' '\n'? | '\n' ) -> skip ; BlockComment : '/*' .*? '*/' -> skip ; LineComment : '//' ~[\r\n]* -> skip ;