{-# LANGUAGE DeriveAnyClass, DeriveGeneric, TypeFamilies, QuasiQuotes , DataKinds, ScopedTypeVariables, OverloadedStrings, TypeSynonymInstances , FlexibleInstances, UndecidableInstances, TemplateHaskell #-} module CParser where import Language.ANTLR4 {- [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 */ -} {- [g4| grammar C; primaryExpression : Identifier | Constant | StringLiteral+ | '(' expression ')' | genericSelection | '__extension__'? '(' compoundStatement ')' // Blocks (GCC extension) | '__builtin_va_arg' '(' unaryExpression ',' typeName ')' | '__builtin_offsetof' '(' typeName ',' unaryExpression ')' ; genericSelection : '_Generic' '(' assignmentExpression ',' genericAssocList ')' ; genericAssocList : genericAssociation | genericAssocList ',' genericAssociation ; genericAssociation : typeName ':' assignmentExpression | 'default' ':' assignmentExpression ; postfixExpression : primaryExpression | postfixExpression '[' expression ']' | postfixExpression '(' argumentExpressionList? ')' | postfixExpression '.' Identifier | postfixExpression '->' Identifier | postfixExpression '++' | postfixExpression '--' | '(' typeName ')' '{' initializerList '}' | '(' typeName ')' '{' initializerList ',' '}' | '__extension__' '(' typeName ')' '{' initializerList '}' | '__extension__' '(' typeName ')' '{' initializerList ',' '}' ; argumentExpressionList : assignmentExpression | argumentExpressionList ',' assignmentExpression ; unaryExpression : postfixExpression | '++' unaryExpression | '--' unaryExpression | unaryOperator castExpression | 'sizeof' unaryExpression | 'sizeof' '(' typeName ')' | '_Alignof' '(' typeName ')' | '&&' Identifier // GCC extension address of label ; unaryOperator : '&' | '*' | '+' | '-' | '~' | '!' ; castExpression : '(' typeName ')' castExpression | '__extension__' '(' typeName ')' castExpression | unaryExpression | DigitSequence // for ; multiplicativeExpression : castExpression | multiplicativeExpression '*' castExpression | multiplicativeExpression '/' castExpression | multiplicativeExpression '%' castExpression ; additiveExpression : multiplicativeExpression | additiveExpression '+' multiplicativeExpression | additiveExpression '-' multiplicativeExpression ; shiftExpression : additiveExpression | shiftExpression '<<' additiveExpression | shiftExpression '>>' additiveExpression ; relationalExpression : shiftExpression | relationalExpression '<' shiftExpression | relationalExpression '>' shiftExpression | relationalExpression '<=' shiftExpression | relationalExpression '>=' shiftExpression ; equalityExpression : relationalExpression | equalityExpression '==' relationalExpression | equalityExpression '!=' relationalExpression ; andExpression : equalityExpression | andExpression '&' equalityExpression ; exclusiveOrExpression : andExpression | exclusiveOrExpression '^' andExpression ; inclusiveOrExpression : exclusiveOrExpression | inclusiveOrExpression '|' exclusiveOrExpression ; logicalAndExpression : inclusiveOrExpression | logicalAndExpression '&&' inclusiveOrExpression ; logicalOrExpression : logicalAndExpression | logicalOrExpression '||' logicalAndExpression ; conditionalExpression : logicalOrExpression ('?' expression ':' conditionalExpression)? ; assignmentExpression : conditionalExpression | unaryExpression assignmentOperator assignmentExpression | DigitSequence // for ; assignmentOperator : '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|=' ; expression : assignmentExpression | expression ',' assignmentExpression ; constantExpression : conditionalExpression ; declaration : declarationSpecifiers initDeclaratorList ';' | declarationSpecifiers ';' | staticAssertDeclaration ; declarationSpecifiers : declarationSpecifier+ ; declarationSpecifiers2 : declarationSpecifier+ ; declarationSpecifier : storageClassSpecifier | typeSpecifier | typeQualifier | functionSpecifier | alignmentSpecifier ; initDeclaratorList : initDeclarator | initDeclaratorList ',' initDeclarator ; initDeclarator : declarator | declarator '=' initializer ; storageClassSpecifier : 'typedef' | 'extern' | 'static' | '_Thread_local' | 'auto' | 'register' ; m128_di : '__m128' | '__m128d' | '__m128i' ; typeSpecifier : 'void' | 'char' | 'short' | 'int' | 'long' | 'float' | 'double' | 'signed' | 'unsigned' | '_Bool' | '_Complex' | '__m128' | '__m128d' | '__m128i' | '__extension__' '(' m128_di ')' | atomicTypeSpecifier | structOrUnionSpecifier | enumSpecifier | typedefName | '__typeof__' '(' constantExpression ')' // GCC extension | typeSpecifier pointer ; structOrUnionSpecifier : structOrUnion Identifier? '{' structDeclarationList '}' | structOrUnion Identifier ; structOrUnion : 'struct' | 'union' ; structDeclarationList : structDeclaration | structDeclarationList structDeclaration ; structDeclaration : specifierQualifierList structDeclaratorList? ';' | staticAssertDeclaration ; specifierQualifierList : typeSpecifier specifierQualifierList? | typeQualifier specifierQualifierList? ; structDeclaratorList : structDeclarator | structDeclaratorList ',' structDeclarator ; structDeclarator : declarator | declarator? ':' constantExpression ; enumSpecifier : 'enum' Identifier? '{' enumeratorList '}' | 'enum' Identifier? '{' enumeratorList ',' '}' | 'enum' Identifier ; enumeratorList : enumerator | enumeratorList ',' enumerator ; enumerator : enumerationConstant | enumerationConstant '=' constantExpression ; enumerationConstant : Identifier ; atomicTypeSpecifier : '_Atomic' '(' typeName ')' ; typeQualifier : 'const' | 'restrict' | 'volatile' | '_Atomic' ; functionSpecifier : 'inline' | '_Noreturn' | '__inline__' // GCC extension | '__stdcall' | gccAttributeSpecifier | '__declspec' '(' Identifier ')' ; alignmentSpecifier : '_Alignas' '(' typeName ')' | '_Alignas' '(' constantExpression ')' ; declarator : pointer? directDeclarator gccDeclaratorExtension* ; 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+ ')' | gccAttributeSpecifier ; gccAttributeSpecifier : '__attribute__' '(' '(' gccAttributeList ')' ')' ; gccCommaAttr : ',' gccAttribute ; gccAttributeList : gccAttribute gccCommaAttr* | // empty ; NotCommaParen : [^,()] ; argExpList : '(' argumentExpressionList? ')' ; gccAttribute : NotCommaParen // relaxed def for "identifier or reserved word" argExpList? | // empty ; NotParens : [^()] ; nestedParenthesesBlockOne : NotParens | '(' nestedParenthesesBlock ')' ; nestedParenthesesBlock : nestedParenthesesBlockOne* ; pointer : '*' typeQualifierList? | '*' typeQualifierList? pointer | '^' typeQualifierList? // Blocks language extension | '^' typeQualifierList? pointer // Blocks language extension ; typeQualifierList : typeQualifier | typeQualifierList typeQualifier ; parameterTypeList : parameterList | parameterList ',' '...' ; parameterList : parameterDeclaration | parameterList ',' parameterDeclaration ; parameterDeclaration : declarationSpecifiers declarator | declarationSpecifiers2 abstractDeclarator? ; identifierList : Identifier | identifierList ',' 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 ',' '}' ; initializerList : designation? initializer | initializerList ',' designation? initializer ; designation : designatorList '=' ; designatorList : designator | designatorList designator ; designator : '[' constantExpression ']' | '.' Identifier ; staticAssertDeclaration : '_Static_assert' '(' constantExpression ',' StringLiteral+ ')' ';' ; asmBoth : '__asm' | '__asm__' ; volatileBoth : 'volatile' | '__volatile__' ; statement : labeledStatement | compoundStatement | expressionStatement | selectionStatement | iterationStatement | jumpStatement | asmBoth volatileBoth '(' beforeColon? afterColon* ')' ';' ; afterColon : ':' beforeColon? ; beforeColon : logicalOrExpression multiLogical* ; multiLogical : ',' logicalOrExpression ; labeledStatement : Identifier ':' statement | 'case' constantExpression ':' statement | 'default' ':' statement ; compoundStatement : '{' blockItemList? '}' ; blockItemList : blockItem | blockItemList blockItem ; blockItem : statement | declaration ; expressionStatement : expression? ';' ; elseStmt : 'else' statement ; selectionStatement : 'if' '(' expression ')' statement elseStmt? | 'switch' '(' expression ')' statement ; iterationStatement : While '(' expression ')' statement | Do statement While '(' expression ')' ';' | For '(' forCondition ')' statement ; // | 'for' '(' expression? ';' expression? ';' forUpdate? ')' statement // | For '(' declaration expression? ';' expression? ')' statement forCondition : forDeclaration ';' forExpression? ';' forExpression? | expression? ';' forExpression? ';' forExpression? ; forDeclaration : declarationSpecifiers initDeclaratorList | declarationSpecifiers ; forExpression : assignmentExpression | forExpression ',' assignmentExpression ; jumpStatement : 'goto' Identifier ';' | 'continue' ';' | 'break' ';' | 'return' expression? ';' | 'goto' unaryExpression ';' // GCC extension ; compilationUnit : translationUnit? EOF ; translationUnit : externalDeclaration | translationUnit externalDeclaration ; externalDeclaration : functionDefinition | declaration | ';' // stray ; ; functionDefinition : declarationSpecifiers? declarator declarationList? compoundStatement ; declarationList : declaration | 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 BinaryExponentPart FloatingSuffix? | HexadecimalPrefix HexadecimalDigitSequence BinaryExponentPart FloatingSuffix? ; fragment FractionalConstant : DigitSequence? '.' DigitSequence | DigitSequence '.' ; fragment ExponentPart : 'e' Sign? DigitSequence | 'E' Sign? DigitSequence ; fragment Sign : '+' | '-' ; DigitSequence : Digit+ ; fragment HexadecimalFractionalConstant : HexadecimalDigitSequence? '.' HexadecimalDigitSequence | HexadecimalDigitSequence '.' ; fragment BinaryExponentPart : 'p' Sign? DigitSequence | 'P' Sign? DigitSequence ; fragment HexadecimalDigitSequence : HexadecimalDigit+ ; fragment FloatingSuffix : 'f' | 'l' | 'F' | 'L' ; 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 | '\\' OctalDigit OctalDigit OctalDigit ; fragment HexadecimalEscapeSequence : '\\x' HexadecimalDigit+ ; StringLiteral : EncodingPrefix? '"' SCharSequence? '"' ; fragment EncodingPrefix : 'u8' | 'u' | 'U' | 'L' ; fragment SCharSequence : SChar+ ; fragment SChar : ~["\\\r\n] | EscapeSequence | '\\\n' // Added line | '\\\r\n' // Added line ; ComplexDefine : '#' Whitespace? 'define' ~[#]* -> 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' Whitespace ~[\r\n]* -> skip ; Whitespace : [ \t]+ -> skip ; Newline : ( '\r' '\n'? | '\n' ) -> skip ; BlockComment : '/*' .*? '*/' -> skip ; LineComment : '//' ~[\r\n]* -> skip ; |] -}