BNF for FreeCCParser

NON-TERMINALS



CompilationUnit ::= ( PackageDeclaration )? ( ImportDeclaration )* ( TypeDeclaration )+

PackageDeclaration ::= Modifiers "package" Name ";"

ImportDeclaration ::= "import" ( "static" )? Name ( "." "*" )? ";"

/*
 * Modifiers. We match all modifiers in a single rule to reduce the chances of
 * syntax errors for simple modifier mistakes. It will also enable us to give
 * better error messages.
 */

Modifiers ::= ( ( "public" | "static" | "protected" | "private" | "final" | "abstract" | "synchronized" | "native" | "transient" | "volatile" | "strictfp" | Annotation ))*

/*
 * Declaration syntax follows.
 */
TypeDeclaration ::= ( ";" | Modifiers ( ClassDeclaration | InterfaceDeclaration | EnumDeclaration | AnnotationTypeDeclaration ) )

ClassDeclaration ::= "class" <IDENTIFIER> ( TypeParameters )? ( ExtendsList )? ( ImplementsList )? ClassOrInterfaceBody

InterfaceDeclaration ::= "interface" <IDENTIFIER> ( TypeParameters )? ( ExtendsList )? ClassOrInterfaceBody

ExtendsList ::= "extends" ClassOrInterfaceType ( "," ClassOrInterfaceType )*

ImplementsList ::= "implements" ClassOrInterfaceType ( "," ClassOrInterfaceType )*

EnumDeclaration ::= "enum" <IDENTIFIER> ImplementsList EnumBody

EnumBody ::= "{" ( EnumConstant ( "," EnumConstant )* )? ( "," )? ( ";" ( ClassOrInterfaceBodyDeclaration )* )? "}"

EnumConstant ::= Modifiers <IDENTIFIER> ( Arguments )? ( ClassOrInterfaceBody )?

TypeParameters ::= "<" TypeParameter ( "," TypeParameter )* ">"

TypeParameter ::= <IDENTIFIER> ( TypeBound )?

TypeBound ::= "extends" ClassOrInterfaceType ( "&" ClassOrInterfaceType )*

ClassOrInterfaceBody ::= "{" ( ClassOrInterfaceBodyDeclaration )* "}"

ClassOrInterfaceBodyDeclaration ::= Initializer | Modifiers ( ClassDeclaration | InterfaceDeclaration | EnumDeclaration | ConstructorDeclaration | FieldDeclaration | MethodDeclaration )| ";"

FieldDeclaration ::= Type VariableDeclarator ( "," VariableDeclarator )* ";"

VariableDeclarator ::= VariableDeclaratorId ( "=" VariableInitializer )?

VariableDeclaratorId ::= <IDENTIFIER> ( "[" "]" )*

VariableInitializer ::= ArrayInitializer | Expression

ArrayInitializer ::= "{" ( VariableInitializer ( "," VariableInitializer )* )? ( "," )? "}"

MethodDeclaration ::= ( TypeParameters )? ReturnType MethodDeclarator ( ThrowsList )? ( Block | ";" )

MethodDeclarator ::= <IDENTIFIER> FormalParameters ( "[" "]" )*

FormalParameters ::= "(" ( FormalParameter ( "," FormalParameter )* )? ")"

FormalParameter ::= Modifiers Type ( "..." )? VariableDeclaratorId

ConstructorDeclaration ::= ( TypeParameters )? <IDENTIFIER> FormalParameters ( ThrowsList )? "{" ( ExplicitConstructorInvocation )? ( BlockStatement )* "}"

ExplicitConstructorInvocation ::= "this" Arguments ";" | ( PrimaryExpression "." )? "super" Arguments ";"

Initializer ::= ( "static" )? Block


/*
 * Type, name and expression syntax follows.
 */

Type ::= ReferenceType | PrimitiveType

ReferenceType ::= PrimitiveArrayType | ( ClassOrInterfaceType ) ( "[" "]" )*

ClassOrInterfaceType ::= <IDENTIFIER> ( TypeArguments )? ( "." <IDENTIFIER> ( TypeArguments )? )*

TypeArguments ::= "<" TypeArgument ( "," TypeArgument )* ">"

TypeArgument ::= ReferenceType | "?" ( WildcardBounds )?

WildcardBounds ::= ( "extends" | "super" ) ReferenceType


PrimitiveType ::= "boolean" | "char" | "byte" | "short" | "int" | "long" | "float" | "double"

PrimitiveArrayType ::= PrimitiveType ( "[" "]" )+


ReturnType ::= ( "void" | Type )

Name ::= <IDENTIFIER> ( "." <IDENTIFIER> )*


ThrowsList ::= "throws" Name ( "," Name )*


/*
 * Expression syntax follows.
 */


Expression ::= AssignmentExpression

/*
 * This expansion has been written this way instead of:
 *   Assignment() | TernaryExpression()
 * for performance reasons.
 * However, it is a weakening of the grammar for it allows the LHS of
 * assignments to be any conditional expression whereas it can only be
 * a primary expression.  Consider adding a semantic predicate to work
 * around this.
 */
AssignmentExpression ::= TernaryExpression ( AssignmentOperator Expression )?

AssignmentOperator ::= "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | ">>>=" | "&=" | "^=" | "|="

TernaryExpression ::= ConditionalOrExpression ( "?" Expression ":" Expression )?

ConditionalOrExpression ::= ConditionalAndExpression ( "||" ConditionalAndExpression )*

ConditionalAndExpression ::= InclusiveOrExpression ( "&&" InclusiveOrExpression )*

InclusiveOrExpression ::= ExclusiveOrExpression ( "|" ExclusiveOrExpression )*

ExclusiveOrExpression ::= AndExpression ( "^" AndExpression )*

AndExpression ::= EqualityExpression ( "&" EqualityExpression )*

EqualityExpression ::= InstanceOfExpression ( ( "==" | "!=" ) InstanceOfExpression )*

InstanceOfExpression ::= RelationalExpression ( "instanceof" Type )?

RelationalExpression ::= ShiftExpression ( ( "<" | ">" | "<=" | ">=" ) ShiftExpression )*

ShiftExpression ::= AdditiveExpression ( ( "<<" | ">>" | ">>>" ) AdditiveExpression )*

AdditiveExpression ::= MultiplicativeExpression ( ( "+" | "-" ) MultiplicativeExpression )*

MultiplicativeExpression ::= UnaryExpression ( ( "*" | "/" | "%" ) UnaryExpression )*

UnaryExpression ::= ( "+" | "-" ) UnaryExpression | PreIncrementExpression | PreDecrementExpression | UnaryExpressionNotPlusMinus

PreIncrementExpression ::= "++" PrimaryExpression

PreDecrementExpression ::= "--" PrimaryExpression

UnaryExpressionNotPlusMinus ::= ( "~" | "!" ) UnaryExpression | CastExpression | PostfixExpression

// This production is to determine lookahead only.  The LOOKAHEAD specifications
// below are not used, but they are there just to indicate that we know about
// this.
CastLookahead ::= "(" PrimitiveType | "(" Type "[" "]" | "(" Type ")" ( "~" | "!" | "(" | <IDENTIFIER> | "this" | "super" | "new" | Literal )

PostfixExpression ::= PrimaryExpression ( "++" | "--" )?

CastExpression ::= "(" Type ")" UnaryExpression | "(" Type ")" UnaryExpressionNotPlusMinus

PrimaryExpression ::= PrimaryPrefix ( PrimarySuffix )*

MemberSelector ::= "." TypeArguments <IDENTIFIER>

PrimaryPrefix ::= Literal | "this" | "super" "." <IDENTIFIER> | "(" Expression ")" | AllocationExpression | ReturnType "." "class" | Name

PrimarySuffix ::= "." "this" | "." AllocationExpression | MemberSelector | "[" Expression "]" | "." <IDENTIFIER> | Arguments

Literal ::= <INTEGER_LITERAL> | <FLOATING_POINT_LITERAL> | <CHARACTER_LITERAL> | <STRING_LITERAL> | "true" | "false" | "null"

IntegerLiteral ::= <INTEGER_LITERAL>

Arguments ::= "(" ( Expression ( "," Expression )* )? ")"

AllocationExpression ::= "new" PrimitiveType ArrayDimsAndInits | "new" ClassOrInterfaceType ( TypeArguments )? ( ArrayDimsAndInits | Arguments ( ClassOrInterfaceBody )? )

/*
 * The third LOOKAHEAD specification below is to parse to PrimarySuffix
 * if there is an expression between the "[...]".
 */
ArrayDimsAndInits ::= ( "[" Expression "]" )+ ( "[" "]" )* | ( "[" "]" )+ ArrayInitializer


/*
 * Statement syntax follows.
 */

Statement ::= LabeledStatement | AssertStatement | Block | EmptyStatement | StatementExpression ";" | SwitchStatement | IfStatement | WhileStatement | DoStatement | ForStatement | BreakStatement | ContinueStatement | ReturnStatement | ThrowStatement | SynchronizedStatement | TryStatement

AssertStatement ::= "assert" Expression ( ":" Expression )? ";"

LabeledStatement ::= <IDENTIFIER> ":" Statement

/*
   Overrides the production defined in 
   in Java.freecc. Only to set the inJavaCode variable to true.
*/

Block ::= "{" ( BlockStatement )* "}"

BlockStatement ::= LocalVariableDeclaration ";" | Statement | ClassDeclaration | InterfaceDeclaration

LocalVariableDeclaration ::= Modifiers Type VariableDeclarator ( "," VariableDeclarator )*

EmptyStatement ::= ";"

StatementExpression ::= PreIncrementExpression | PreDecrementExpression | PrimaryExpression ( "++" | "--" | AssignmentOperator Expression )?

SwitchStatement ::= "switch" "(" Expression ")" "{" ( SwitchLabel ( BlockStatement )* )* "}"

SwitchLabel ::= "case" Expression ":" | "default" ":"

IfStatement ::= "if" "(" Expression ")" Statement ( "else" Statement )?

WhileStatement ::= "while" "(" Expression ")" Statement

DoStatement ::= "do" Statement "while" "(" Expression ")" ";"

ForStatement ::= "for" "(" ( Modifiers Type <IDENTIFIER> ":" Expression | ( ForInit )? ";" ( Expression )? ";" ( ForUpdate )? ) ")" Statement

ForInit ::= LocalVariableDeclaration | StatementExpressionList

StatementExpressionList ::= StatementExpression ( "," StatementExpression )*

ForUpdate ::= StatementExpressionList

BreakStatement ::= "break" ( <IDENTIFIER> )? ";"

ContinueStatement ::= "continue" ( <IDENTIFIER> )? ";"

ReturnStatement ::= "return" ( Expression )? ";"

ThrowStatement ::= "throw" Expression ";"

SynchronizedStatement ::= "synchronized" "(" Expression ")" Block

TryStatement ::= "try" Block ( FinallyBlock | ( ( CatchBlock )+ ( FinallyBlock )? ) )

CatchBlock ::= "catch" "(" FormalParameter ")" Block

FinallyBlock ::= "finally" Block


/* Annotation syntax follows. */

Annotation ::= NormalAnnotation | SingleMemberAnnotation | MarkerAnnotation

NormalAnnotation ::= "@" Name "(" ( MemberValuePairs )? ")"

MarkerAnnotation ::= "@" Name

SingleMemberAnnotation ::= "@" Name "(" MemberValue ")"

MemberValuePairs ::= MemberValuePair ( "," MemberValuePair )*

MemberValuePair ::= <IDENTIFIER> "=" MemberValue

MemberValue ::= Annotation | MemberValueArrayInitializer | TernaryExpression

MemberValueArrayInitializer ::= "{" MemberValue ( "," MemberValue )* ( "," )? "}"


/* Annotation Types. */

AnnotationTypeDeclaration ::= "@" "interface" <IDENTIFIER> AnnotationTypeBody

AnnotationTypeBody ::= "{" ( AnnotationTypeMemberDeclaration )* "}"

AnnotationTypeMemberDeclaration ::= Modifiers ( Type <IDENTIFIER> "(" ")" ( DefaultValue )? ";" | ClassDeclaration | InterfaceDeclaration | EnumDeclaration | AnnotationTypeDeclaration | FieldDeclaration )| ( ";" )

DefaultValue ::= "default" MemberValue


Root ::= ( Options )? ( ParserCodeDecls )? ( Production | TokenManagerDecls | CodeInjection | CodeInjection2 | GrammarInclusion )+ <EOF>

ParserCodeDecls ::= "PARSER_BEGIN" "(" <IDENTIFIER> ")" CompilationUnit "PARSER_END" ( "(" <IDENTIFIER> ")" )?

GrammarInclusion ::= <_INCLUDE> "(" <STRING_LITERAL> ")" ( ":" "{" "}" )?

CodeInjection ::= <_INJECT> "(" ( "class" | "interface" )? <IDENTIFIER> ")" ":" "{" ( ImportDeclaration )* ( ExtendsList ( ";" )? )? ( ImplementsList ( ";" )? )? "}" ClassOrInterfaceBody

CodeInjection2 ::= <_INJECT> ":" "{" CompilationUnit "}"


Options ::= <_OPTIONS> ( ":" )? "{" ( option_binding )* "}"

option_binding ::= ( <IDENTIFIER> | "LOOKAHEAD" | "IGNORE_CASE" ) ( "=" ( "true" | "false" | <INTEGER_LITERAL> | <STRING_LITERAL> | <IDENTIFIER> ))? ";"

Production ::= JavaCodeProduction | TokenProduction | BNFProduction

JavaCodeProduction ::= "JAVACODE" ( "public" | "private" | "protected" )? ReturnType <IDENTIFIER> FormalParameters ( ThrowsList )? ( TreeNodeDescriptor )? Block

BNFProduction ::= ( "public" | "private" | "protected" )? ReturnType <IDENTIFIER> FormalParameters ( ThrowsList )? ( TreeNodeDescriptor )? ":" Block "{" ExpansionChoice "}"

TreeNodeDescriptor ::= <HASH_ID> ( <LPAREN> ( ">" )? Expression <RPAREN> )?


TokenProduction ::= ( "<" "*" ">" | "<" <IDENTIFIER> ( "," <IDENTIFIER> )* ">" )? ( <_TOKEN> | <_SPECIAL_TOKEN> | <_MORE> | "SKIP" ) ( "[" "IGNORE_CASE" "]" )? ":" "{" RegexpSpec ( "|" RegexpSpec )* "}"

TokenManagerDecls ::= "TOKEN_MGR_DECLS" ":" ClassOrInterfaceBody

RegexpSpec ::= RegexpExpansion ( <HASH_ID> )? ( Action )? ( ":" <IDENTIFIER> )?

ExpansionChoice ::= ExpansionSequence ( "|" ExpansionSequence )*

ExpansionSequence ::= ( Lookahead )? ( expansion_unit )+



Lookahead ::= "LOOKAHEAD" "(" ( <INTEGER_LITERAL> )? ( "," )? ( ExpansionChoice )? ( "," )? ( "{" Expression "}" )? ")"

expansion_unit ::= ( Lookahead | Action | ZeroOrOne | TryBlock | ( PrimaryExpression "=" )? RegexpExpansion | NonTerminal | "(" ExpansionChoice ")" ( "+" | "*" | "?" )? ) ( TreeNodeDescriptor )?

NonTerminal ::= ( PrimaryExpression "=" )? <IDENTIFIER> ( Arguments )?


ZeroOrOne ::= "[" ExpansionChoice "]"

TryBlock ::= "try" "{" ExpansionChoice "}" ( CatchBlock )* ( FinallyBlock )?

Action ::= Block

RegexpExpansion ::= ( RegexpStringLiteral | InPlaceRegexp | RegexpRef | EndOfFile )

//FIXME
InPlaceRegexp ::= <LT> ( ( <IDENTIFIER> | <HASH_ID> ) ":" )? RegexpChoice <GT>

RegexpStringLiteral ::= <STRING_LITERAL>

RegexpRef ::= "<" <IDENTIFIER> ">"

EndOfFile ::= "<" "EOF" ">"

RegexpChoice ::= RegexpSequence ( "|" RegexpSequence )*

RegexpChoiceInParen ::= "(" RegexpSequence ( "|" RegexpSequence )* ")"

RegexpSequence ::= ( RegexpStringLiteral | RegexpRef | CharacterList | RepeatedRegexp )+

RepeatedRegexp ::= RegexpChoiceInParen ( "+" | "*" | "?" | "{" IntegerLiteral ( "," ( IntegerLiteral )? )? "}" )?

CharacterList ::= ( "~" )? "[" ( CharacterRange ( "," CharacterRange )* )? "]"

CharacterRange ::= <STRING_LITERAL> ( "-" <STRING_LITERAL> )?

TOKENS

<DEFAULT> TOKEN : { 
<_OPTIONS: "options" | "OPTIONS">
|<_INJECT: "INJECT" | "INJECT_CODE">
|<_INCLUDE: "INCLUDE" | "INCLUDE_GRAMMAR">
|<_LOOKAHEAD: "LOOKAHEAD">
|<_IGNORE_CASE: "IGNORE_CASE">
|<_PARSER_BEGIN: "PARSER_BEGIN">
|<_PARSER_END: "PARSER_END">
|<_JAVACODE: "JAVACODE">
|<_TOKEN: "TOKEN" | "REGULAR_TOKEN">
|<_SPECIAL_TOKEN: "SPECIAL_TOKEN" | "UNPARSED_TOKEN">
|<_MORE: "MORE" | "INCOMPLETE_TOKEN">
|<_SKIP: "SKIP">
|<_TOKEN_MGR_DECLS: "TOKEN_MGR_DECLS">
|<_EOF: "EOF">
|<HASH_ID: "#" <IDENTIFIER>>
}

<DEFAULT> SPECIAL_TOKEN : { 
<WHITESPACE: (" " | "\t" | "\n" | "\r" | "\f")+>
}

<DEFAULT> MORE : { 
"//"
|<"/**" ~["/"]>
|"/*"
}

<IN_SINGLE_LINE_COMMENT> SPECIAL_TOKEN : { 
<SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n">
}

<IN_FORMAL_COMMENT> SPECIAL_TOKEN : { 
<FORMAL_COMMENT: "*/">
}

<IN_MULTI_LINE_COMMENT> SPECIAL_TOKEN : { 
<MULTI_LINE_COMMENT: "*/">
}

<IN_SINGLE_LINE_COMMENT, IN_FORMAL_COMMENT, IN_MULTI_LINE_COMMENT> MORE : { 
<~[]>
}

<DEFAULT> TOKEN : { 
<ABSTRACT: "abstract">
|<ASSERT: "assert">
|<BOOLEAN: "boolean">
|<BREAK: "break">
|<BYTE: "byte">
|<CASE: "case">
|<CATCH: "catch">
|<CHAR: "char">
|<CLASS: "class">
|<CONST: "const">
|<CONTINUE: "continue">
|<_DEFAULT: "default">
|<DO: "do">
|<DOUBLE: "double">
|<ELSE: "else">
|<ENUM: "enum">
|<EXTENDS: "extends">
|<FALSE: "false">
|<FINAL: "final">
|<FINALLY: "finally">
|<FLOAT: "float">
|<FOR: "for">
|<GOTO: "goto">
|<IF: "if">
|<IMPLEMENTS: "implements">
|<IMPORT: "import">
|<INSTANCEOF: "instanceof">
|<INT: "int">
|<INTERFACE: "interface">
|<LONG: "long">
|<NATIVE: "native">
|<NEW: "new">
|<NULL: "null">
|<PACKAGE: "package">
|<PRIVATE: "private">
|<PROTECTED: "protected">
|<PUBLIC: "public">
|<RETURN: "return">
|<SHORT: "short">
|<STATIC: "static">
|<STRICTFP: "strictfp">
|<SUPER: "super">
|<SWITCH: "switch">
|<SYNCHRONIZED: "synchronized">
|<THIS: "this">
|<THROW: "throw">
|<THROWS: "throws">
|<TRANSIENT: "transient">
|<TRUE: "true">
|<TRY: "try">
|<VOID: "void">
|<VOLATILE: "volatile">
|<WHILE: "while">
}

<DEFAULT> TOKEN : { 
<INTEGER_LITERAL: <DECIMAL_LITERAL> (["l","L"])? | <HEX_LITERAL> (["l","L"])? | <OCTAL_LITERAL> (["l","L"])?>
|<FLOATING_POINT_LITERAL: <DECIMAL_FLOATING_POINT_LITERAL> | <HEXADECIMAL_FLOATING_POINT_LITERAL>>
|<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"]))* "\"">
}

<DEFAULT> TOKEN : { 
<LPAREN: "(">
|<RPAREN: ")">
|<LBRACE: "{">
|<RBRACE: "}">
|<LBRACKET: "[">
|<RBRACKET: "]">
|<SEMICOLON: ";">
|<COMMA: ",">
|<DOT: ".">
}

<DEFAULT> TOKEN : { 
<ASSIGN: "=">
|<GT: ">">
|<LT: "<">
|<BANG: "!">
|<TILDE: "~">
|<HOOK: "?">
|<COLON: ":">
|<EQ: "==">
|<LE: "<=">
|<GE: ">=">
|<NE: "!=">
|<SC_OR: "||">
|<SC_AND: "&&">
|<INCR: "++">
|<DECR: "--">
|<PLUS: "+">
|<MINUS: "-">
|<STAR: "*">
|<SLASH: "/">
|<BIT_AND: "&">
|<BIT_OR: "|">
|<XOR: "^">
|<REM: "%">
|<LSHIFT: "<<">
|<RSIGNEDSHIFT: ">>">
|<RUNSIGNEDSHIFT: ">>>">
|<PLUSASSIGN: "+=">
|<MINUSASSIGN: "-=">
|<STARASSIGN: "*=">
|<SLASHASSIGN: "/=">
|<ANDASSIGN: "&=">
|<ORASSIGN: "|=">
|<XORASSIGN: "^=">
|<REMASSIGN: "%=">
|<LSHIFTASSIGN: "<<=">
|<RSIGNEDSHIFTASSIGN: ">>=">
|<RUNSIGNEDSHIFTASSIGN: ">>>=">
}

<DEFAULT> TOKEN : { 
<IDENTIFIER: <LETTER> (<PART_LETTER>)*>
|}