--- /dev/null
+/*
+
+ C grammar defintion for use with JavaCC
+ Contributed by Doug South (dsouth@squirrel.com.au) 21/3/97
+
+ This parser assumes that the C source file has been preprocessed : all
+ #includes have been included and all macros have been expanded. I accomplish
+ this with "gcc -P -E <source file> > <output file>".
+
+ There is a problem with compiler specific types, such as __signed, __const,
+ __inline__, etc. These types can be added as typedef types before the parser
+ is run on a file. See main() for an example. I have also found a strange little
+ compiler specific "type" if you can call it that. It is __attribute__, but it
+ does not seem to be used as a type. I found that just deleting the __attribute__
+ and the following "offensive" code works.
+
+ This grammar also prints out all the types defined while parsing the file. This
+ is done via a call to printTypes() when the parser is complete. If you do not want
+ this, just comment out the printTypes() method call in the production rule
+ TranslationUnit(), which BTW is the root node for parsing a C source file.
+
+ I have not in anyway extensively tested this grammar, in fact it is barely tested,
+ but I imagine it is better to have a starting point for a C grammar other than from
+ scratch. It has not been optimized in anyway, my main aim was to get a parser that
+ works. Lookahead may not be optimum at choice points and may even be insufficient at
+ times. I choose to err on the side of not optimum if I made a choice at all.
+
+ If you use this grammar, I would appreciate hearing from you. I will try to maintain
+ this grammar to the best of my ability, but at this point in time, this is only a side
+ hobby (unless someone wants to pay me for doing JavaCC work!). In that regards, I am
+ interested in hearing bugs and comments.
+
+ TODO:
+
+ Insert the appropriate code to enable C source trees from this grammar.
+
+=============================================
+3/2/06: Modified by Tom Copeland
+- STRING_LITERAL now handles embedded escaped newlines, thanks to J.Chris Findlay for the patch
+- Works with JavaCC 4.0
+- Preprocessor directives are now simply SKIP'd, so no need to run C files through GCC first
+
+ */
+
+PARSER_BEGIN(CParser)
+
+import java.util.*;
+
+ public class CParser{
+
+ // Run the parser
+ public static void main ( String args [ ] ) {
+ CParser parser ;
+
+
+ if(args.length == 0){
+ System.out.println("C Parser Version 0.1Alpha: Reading from standard input . . .");
+ parser = new CParser(System.in);
+ }
+ else if(args.length == 1){
+ System.out.println("C Parser Version 0.1Alpha: Reading from file " + args[0] + " . . ." );
+ try {
+ parser = new CParser(new java.io.FileInputStream(args[0]));
+ }
+ catch(java.io.FileNotFoundException e){
+ System.out.println("C Parser Version 0.1: File " + args[0] + " not found.");
+ return ;
+ }
+ }
+ else {
+ System.out.println("C Parser Version 0.1Alpha: Usage is one of:");
+ System.out.println(" java CParser < inputfile");
+ System.out.println("OR");
+ System.out.println(" java CParser inputfile");
+ return ;
+ }
+ try {
+ parser.TranslationUnit();
+ System.out.println("C Parser Version 0.1Alpha: Java program parsed successfully.");
+ }
+ catch(ParseException e){
+ System.out.println("C Parser Version 0.1Alpha: Encountered errors during parse.");
+ e.printStackTrace();
+ }
+ }
+ }
+
+PARSER_END(CParser)
+
+SKIP : {
+ " "
+| "\t"
+| "\n"
+| "\r"
+| <"//" (~["\n","\r"])* ("\n" | "\r" | "\r\n")>
+| <"/*" (~["*"])* "*" ("*" | ~["*","/"] (~["*"])* "*")* "/">
+| "#" : PREPROCESSOR_OUTPUT
+}
+
+<PREPROCESSOR_OUTPUT> SKIP:
+{
+ "\n" : DEFAULT
+}
+
+<PREPROCESSOR_OUTPUT> MORE:
+{
+ "\\\n"
+ |
+ "\\\r\n"
+ |
+ < ~[] >
+}
+
+
+TOKEN : {
+ <INTEGER_LITERAL: <DECIMAL_LITERAL> (["l","L"])? | <HEX_LITERAL> (["l","L"])? | <OCTAL_LITERAL> (["l","L"])?>
+| <#DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])*>
+| <#HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+>
+| <#OCTAL_LITERAL: "0" (["0"-"7"])*>
+| <FLOATING_POINT_LITERAL: (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])? | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])? | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])? | (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"]>
+| <#EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+>
+| <CHARACTER_LITERAL: "\'" (~["\'","\\","\n","\r"] | "\\" (["n","t","b","r","f","\\","\'","\""] | ["0"-"7"] (["0"-"7"])? | ["0"-"3"] ["0"-"7"] ["0"-"7"])) "\'">
+| <STRING_LITERAL: "\"" ( ~["\"","\\","\n","\r"] | "\\" ( ["n","t","b","r","f","\\","\'","\""] | ["0"-"7"] (["0"-"7"])? | ["0"-"3"] ["0"-"7"] ["0"-"7"] | ( ["\n","\r"] | "\r\n")))* "\"">
+}
+
+TOKEN : {
+ <CONTINUE: "continue"> |
+ <VOLATILE: "volatile"> |
+ <REGISTER: "register"> |
+ <UNSIGNED: "unsigned"> |
+ <TYPEDEF: "typedef"> |
+ <DFLT: "default"> |
+ <DOUBLE: "double"> |
+ <SIZEOF: "sizeof"> |
+ <SWITCH: "switch"> |
+ <RETURN: "return"> |
+ <EXTERN: "extern"> |
+ <STRUCT: "struct"> |
+ <STATIC: "static"> |
+ <SIGNED: "signed"> |
+ <WHILE: "while"> |
+ <BREAK: "break"> |
+ <UNION: "union"> |
+ <CONST: "const"> |
+ <FLOAT: "float"> |
+ <SHORT: "short"> |
+ <ELSE: "else"> |
+ <CASE: "case"> |
+ <LONG: "long"> |
+ <ENUM: "enum"> |
+ <AUTO: "auto"> |
+ <VOID: "void"> |
+ <CHAR: "char"> |
+ <GOTO: "goto"> |
+ <FOR: "for"> |
+ <INT: "int"> |
+ <IF: "if"> |
+ <DO: "do">
+}
+
+TOKEN : {
+ <IDENTIFIER: <LETTER> (<LETTER> | <DIGIT>)*>
+| <#LETTER: ["$","A"-"Z","_","a"-"z"]>
+| <#DIGIT: ["0"-"9"]>
+}
+
+void TranslationUnit() : {}
+{
+ (ExternalDeclaration())+
+}
+
+void ExternalDeclaration() : {}
+{
+ ( LOOKAHEAD( FunctionDefinition() ) FunctionDefinition() | Declaration())
+}
+
+void FunctionDefinition() : {}
+{
+ [LOOKAHEAD(DeclarationSpecifiers()) DeclarationSpecifiers()] Declarator() [ DeclarationList() ]
+ CompoundStatement()
+}
+
+void Declaration() : {}
+{
+ DeclarationSpecifiers() [ InitDeclaratorList() ] ";"
+}
+
+void DeclarationList() : {}
+{
+ ( LOOKAHEAD(Declaration()) Declaration() )+
+}
+
+void DeclarationSpecifiers() : {}
+{
+ StorageClassSpecifier() [ LOOKAHEAD(DeclarationSpecifiers())
+ DeclarationSpecifiers() ] |
+ TypeSpecifier() [ LOOKAHEAD(DeclarationSpecifiers())
+ DeclarationSpecifiers() ] |
+ TypeQualifier() [ LOOKAHEAD(DeclarationSpecifiers())
+ DeclarationSpecifiers() ]
+}
+
+void StorageClassSpecifier() : {}
+{
+ ( <AUTO> | <REGISTER> | <STATIC> | <EXTERN> | <TYPEDEF>
+ )
+}
+
+void TypeSpecifier() : {}
+{
+ ( <VOID> | <CHAR> | <SHORT> | <INT> | <LONG> | <FLOAT> | <DOUBLE> | <SIGNED> |
+ <UNSIGNED> | StructOrUnionSpecifier() | EnumSpecifier() | TypedefName() )
+}
+
+void TypeQualifier() : {}
+{
+ ( <CONST> | <VOLATILE> )
+}
+
+void StructOrUnionSpecifier() : {}
+{
+ StructOrUnion() ( LOOKAHEAD(3) [ <IDENTIFIER> ] "{" StructDeclarationList() "}" | <IDENTIFIER> )
+
+}
+
+void StructOrUnion() : {}
+{
+ ( <STRUCT> | <UNION> )
+}
+
+void StructDeclarationList() : {}
+{
+ (StructDeclaration())+
+}
+
+void InitDeclaratorList() : {}
+{
+ InitDeclarator() ("," InitDeclarator())*
+}
+
+void InitDeclarator() : {}
+{
+ Declarator() [ "=" Initializer() ]
+}
+
+void StructDeclaration() : {}
+{
+ SpecifierQualifierList() StructDeclaratorList() ";"
+}
+
+void SpecifierQualifierList() : {}
+{
+ TypeSpecifier() [ LOOKAHEAD(SpecifierQualifierList())
+ SpecifierQualifierList() ]|
+ TypeQualifier() [ LOOKAHEAD(SpecifierQualifierList())
+ SpecifierQualifierList() ]
+}
+
+void StructDeclaratorList() : {}
+{
+ StructDeclarator() ( "," StructDeclarator() )*
+}
+
+void StructDeclarator() : {}
+{
+ ( LOOKAHEAD(3) Declarator() | [ Declarator() ] ":" ConstantExpression() )
+}
+
+void EnumSpecifier() : {}
+{
+ <ENUM> ( LOOKAHEAD(3) [ <IDENTIFIER> ] "{" EnumeratorList() "}" | <IDENTIFIER> )
+}
+
+void EnumeratorList() : {}
+{
+ Enumerator() ("," Enumerator())*
+}
+
+void Enumerator() : {}
+{
+ <IDENTIFIER> [ "=" ConstantExpression() ]
+}
+
+void Declarator() : {}
+{
+ [ Pointer() ] DirectDeclarator()
+}
+
+void DirectDeclarator() : {}
+{
+ ( <IDENTIFIER>
+ | "(" Declarator() ")" )
+
+ ( "[" [ ConstantExpression() ] "]" |
+ LOOKAHEAD(3) "(" ParameterTypeList() ")" |
+ "(" [ IdentifierList() ] ")" )*
+}
+
+void Pointer() : {}
+{
+ "*" [ TypeQualifierList() ] [ Pointer() ]
+}
+
+void TypeQualifierList() : {}
+{
+ (TypeQualifier())+
+}
+
+void ParameterTypeList() : {}
+{
+ ParameterList() ["," "..." ]
+}
+
+void ParameterList() : {}
+{
+ ParameterDeclaration() (LOOKAHEAD(2) "," ParameterDeclaration())*
+}
+
+void ParameterDeclaration() : {}
+{
+ DeclarationSpecifiers() ( LOOKAHEAD(Declarator()) Declarator() | [ AbstractDeclarator() ] )
+}
+
+void IdentifierList() : {}
+{
+ <IDENTIFIER> ("," <IDENTIFIER>)*
+}
+
+void Initializer() : {}
+{
+ ( AssignmentExpression() |
+ "{" InitializerList() [","] "}" )
+}
+
+void InitializerList() : {}
+{
+ Initializer() (LOOKAHEAD(2) "," Initializer())*
+}
+
+void TypeName() : {}
+{
+ SpecifierQualifierList() [ AbstractDeclarator() ]
+
+}
+
+void AbstractDeclarator() : {}
+{
+ ( LOOKAHEAD(3) Pointer() |
+ [Pointer()] DirectAbstractDeclarator() )
+}
+
+void DirectAbstractDeclarator() : {}
+{
+ ( LOOKAHEAD(2) "(" AbstractDeclarator() ")" |
+ "[" [ConstantExpression()] "]" |
+ "(" [ParameterTypeList()] ")" )
+
+ ( "[" [ ConstantExpression() ] "]" | "(" [ ParameterTypeList() ] ")" )*
+}
+
+void TypedefName() : {}
+{
+ <IDENTIFIER>
+}
+
+void Statement() : {}
+{
+ ( LOOKAHEAD(2) LabeledStatement() |
+ ExpressionStatement() |
+ CompoundStatement() |
+ SelectionStatement() |
+ IterationStatement() |
+ JumpStatement() )
+}
+
+void LabeledStatement() : {}
+{
+ ( <IDENTIFIER> ":" Statement() |
+ <CASE> ConstantExpression() ":" Statement() |
+ <DFLT> ":" Statement() )
+}
+
+void ExpressionStatement() : {}
+{
+ [ Expression() ] ";"
+}
+
+void CompoundStatement() : {}
+{
+ "{" [ LOOKAHEAD(DeclarationList()) DeclarationList() ]
+ [ StatementList() ]
+ "}"
+}
+
+void StatementList() : {}
+{
+ (Statement())+
+}
+
+void SelectionStatement() : {}
+{
+ ( <IF> "(" Expression() ")" Statement() [ LOOKAHEAD(2) <ELSE> Statement() ] |
+ <SWITCH> "(" Expression() ")" Statement() )
+}
+
+void IterationStatement() : {}
+{
+ ( <WHILE> "(" Expression() ")" Statement() |
+ <DO> Statement() <WHILE> "(" Expression() ")" ";" |
+ <FOR> "(" [ Expression() ] ";" [ Expression() ] ";" [ Expression() ] ")" Statement() )
+}
+
+void JumpStatement() : {}
+{
+ ( <GOTO> <IDENTIFIER> ";" |
+ <CONTINUE> ";" |
+ <BREAK> ";" |
+ <RETURN> [ Expression() ] ";" )
+}
+
+void Expression() : {}
+{
+ AssignmentExpression() ( "," AssignmentExpression() )*
+}
+
+void AssignmentExpression() : {}
+{
+ LOOKAHEAD(UnaryExpression() AssignmentOperator()) UnaryExpression() AssignmentOperator() AssignmentExpression() |
+ LOOKAHEAD(3) ConditionalExpression()
+}
+
+void AssignmentOperator() : {}
+{
+ ( "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | "&=" | "^=" | "|=" )
+}
+
+void ConditionalExpression() : {}
+{
+ LogicalORExpression() [ "?" Expression() ":" ConditionalExpression() ]
+}
+
+void ConstantExpression() : {}
+{
+ ConditionalExpression()
+}
+
+void LogicalORExpression() : {}
+{
+ LogicalANDExpression() [ "||" LogicalORExpression() ]
+}
+
+void LogicalANDExpression() : {}
+{
+ InclusiveORExpression() [ "&&" LogicalANDExpression() ]
+}
+
+void InclusiveORExpression() : {}
+{
+ ExclusiveORExpression() [ "|" InclusiveORExpression() ]
+}
+
+void ExclusiveORExpression() : {}
+{
+ ANDExpression() [ "^" ExclusiveORExpression() ]
+}
+
+void ANDExpression() : {}
+{
+ EqualityExpression() [ "&" ANDExpression() ]
+}
+
+void EqualityExpression() : {}
+{
+ RelationalExpression() [ ( "==" | "!=" ) EqualityExpression() ]
+}
+
+void RelationalExpression() : {}
+{
+ ShiftExpression() [ ( "<" | ">" | "<=" | ">=" ) RelationalExpression() ]
+}
+
+void ShiftExpression() : {}
+{
+ AdditiveExpression() [ ( "<<" | ">>" ) ShiftExpression() ]
+}
+
+void AdditiveExpression() : {}
+{
+ MultiplicativeExpression() [ ( "+" | "-" ) AdditiveExpression() ]
+}
+
+void MultiplicativeExpression() : {}
+{
+ CastExpression() [ ( "*" | "/" | "%" ) MultiplicativeExpression() ]
+}
+
+void CastExpression() : {}
+{
+ ( LOOKAHEAD("(" TypeName() ")" CastExpression() ) "(" TypeName() ")" CastExpression() |
+ UnaryExpression() )
+}
+
+void UnaryExpression() : {}
+{
+ ( LOOKAHEAD(3) PostfixExpression() |
+ "++" UnaryExpression() |
+ "--" UnaryExpression() |
+ UnaryOperator() CastExpression() |
+ <SIZEOF> ( LOOKAHEAD(UnaryExpression() ) UnaryExpression() | "(" TypeName() ")" ) )
+}
+
+void UnaryOperator() : {}
+{
+ ( "&" | "*" | "+" | "-" | "~" | "!" )
+}
+
+void PostfixExpression() : {}
+{
+ PrimaryExpression() ( "[" Expression() "]" |
+ "(" [ LOOKAHEAD(ArgumentExpressionList() ) ArgumentExpressionList() ] ")" |
+ "." <IDENTIFIER> |
+ "->" <IDENTIFIER> |
+ "++" |
+ "--" )*
+}
+
+void PrimaryExpression() : {}
+{
+ ( <IDENTIFIER> |
+ Constant() |
+ "(" Expression() ")" )
+}
+
+void ArgumentExpressionList() : {}
+{
+ AssignmentExpression() ( "," AssignmentExpression() )*
+}
+
+void Constant() : {}
+{
+ <INTEGER_LITERAL> | <FLOATING_POINT_LITERAL> | <CHARACTER_LITERAL> | <STRING_LITERAL>
+}
+