%options scopes,act,an=javaact.cpp,hn=javaact.h,em,tab,gp=c++, %options fp=java,escape=$,prefix=TK_,em,defer,output-size=125 %options hblockb=\:,hblocke=:\ %options nogoto-default %options single-productions %options la=2,names=max -- This software is subject to the terms of the IBM Jikes Compiler -- License Agreement available at the following URL: -- http://www.ibm.com/research/jikes. -- Copyright (C) 1996, 1999, International Business Machines Corporation -- and others. All Rights Reserved. -- You must accept the terms of that agreement to use this software. ------------------------------------------------------------------------ -- -- J A V A -- -- This Java grammar is almost identical to the grammar defined in -- chapter 19 of the Java Language Specification manual together with -- the additional rules found in the 1.1 document. It is written here -- in JIKES PG format with semantic actions following each rule. In -- specifying the rules we enclosed all terminal symbols in single -- quotes so that they can be quickly distinguished from -- non-terminals. Optional symbols are suffixed with a question mark (?) -- and the rules expanding such definitions can be found at the end. -- -- This grammar is totally faithful to the original rules except that -- some syntactic markers: PackageHeaderMarker, MethodHeaderMarker and -- BodyMarker, were added to allow the parser to skip certain irrelevant -- syntactic components when they are not needed. -- -- The file javaact.h produced by JIKESPG from this file (java.g) contains a -- very readable definition of the grammar rules together with their -- associated semantic actions. That file is marked with appropriate -- location directives (automatically generated) which instructs the C++ -- compiler to issue error messages in terms of this file (java.g). -- Therefore, though the user is encouraged to read javaact.h, no -- change should ever be made to that file. Instead, changes should -- always be made in this file and javaact.h should be regenerated -- using JIKESPG. -- ------------------------------------------------------------------------ $Define -- -- This macro generates a header for an action function consisting -- of the rule in question (commented) and a location directive. -- $location /. // // Rule $rule_number: $rule_text // #line $next_line "$input_file"./ -- -- This macro is used to initialize the rule_action array -- to an unnamed function. A name is generated using the -- number of the rule in question. -- $action /. #ifndef HEADERS rule_action[$rule_number] = &Parser::Act$rule_number; #else void Act$rule_number(void); #endif ./ -- -- These macros are used to initialize the rule_action array -- to a specific named function. -- $MakeArrayType /. #ifndef HEADERS rule_action[$rule_number] = &Parser::MakeArrayType; #endif ./ $MakeSimpleName /. #ifndef HEADERS rule_action[$rule_number] = &Parser::MakeSimpleName; #endif ./ $MakeFieldAccess /. #ifndef HEADERS rule_action[$rule_number] = &Parser::MakeFieldAccess; #endif ./ $MakeQualifiedSuper /. #ifndef HEADERS rule_action[$rule_number] = &Parser::MakeQualifiedSuper; #endif ./ $MakeQualifiedNew /. #ifndef HEADERS rule_action[$rule_number] = &Parser::MakeQualifiedNew; #endif ./ $SetSym1ToSym2 /. #ifndef HEADERS rule_action[$rule_number] = &Parser::SetSym1ToSym2; #endif ./ $MakeEmptyStatement /. #ifndef HEADERS rule_action[$rule_number] = &Parser::MakeEmptyStatement; #endif ./ $MakeLabeledStatement /. #ifndef HEADERS rule_action[$rule_number] = &Parser::MakeLabeledStatement; #endif ./ $MakeExpressionStatement /. #ifndef HEADERS rule_action[$rule_number] = &Parser::MakeExpressionStatement; #endif ./ $MakeIfThenElseStatement /. #ifndef HEADERS rule_action[$rule_number] = &Parser::MakeIfThenElseStatement; #endif ./ $MakeWhileStatement /. #ifndef HEADERS rule_action[$rule_number] = &Parser::MakeWhileStatement; #endif ./ $MakeForStatement /. #ifndef HEADERS rule_action[$rule_number] = &Parser::MakeForStatement; #endif ./ $MakeArrayCreationExpression /. #ifndef HEADERS rule_action[$rule_number] = &Parser::MakeArrayCreationExpression; #endif ./ $MakeSuperFieldAccess /. #ifndef HEADERS rule_action[$rule_number] = &Parser::MakeSuperFieldAccess; #endif ./ $MakeSuperDoubleFieldAccess /. #ifndef HEADERS rule_action[$rule_number] = &Parser::MakeSuperDoubleFieldAccess; #endif ./ $MakeArrayAccess /. #ifndef HEADERS rule_action[$rule_number] = &Parser::MakeArrayAccess; #endif ./ $MakeCastExpression /. #ifndef HEADERS rule_action[$rule_number] = &Parser::MakeCastExpression; #endif ./ -- -- This macro is used to initialize the rule_action array -- to the NullAction function. -- $NullAction /. #ifndef HEADERS rule_action[$rule_number] = &Parser::NullAction; #endif ./ -- -- This macro is used to initialize the rule_action array -- to the NoAction function. -- $NoAction /. #ifndef HEADERS rule_action[$rule_number] = &Parser::NoAction; #endif ./ -- -- This macro generates a header for a named action function that is -- already defined and will be shared. -- $shared_function /. // // Rule $rule_number: $rule_text./ -- -- This macro generates a header for a rule that invokes the -- no_function routine. -- $shared_NoAction /. // // Rule $rule_number: $rule_text // // void NoAction(void); //./ -- -- This macro generates a header for a rule that invokes the -- null_function routine. -- $shared_NullAction /. // // Rule $rule_number: $rule_text // // void NullAction(void); //./ $Terminals BodyMarker Identifier abstract boolean break byte case catch char class const continue default do double else extends false final finally float for goto if implements import instanceof int interface long native new null package private protected public return short static strictfp super switch synchronized this throw throws transient true try void volatile while IntegerLiteral LongLiteral FloatingPointLiteral DoubleLiteral CharacterLiteral StringLiteral PLUS_PLUS MINUS_MINUS EQUAL_EQUAL LESS_EQUAL GREATER_EQUAL NOT_EQUAL LEFT_SHIFT RIGHT_SHIFT UNSIGNED_RIGHT_SHIFT PLUS_EQUAL MINUS_EQUAL MULTIPLY_EQUAL DIVIDE_EQUAL AND_EQUAL OR_EQUAL XOR_EQUAL REMAINDER_EQUAL LEFT_SHIFT_EQUAL RIGHT_SHIFT_EQUAL UNSIGNED_RIGHT_SHIFT_EQUAL OR_OR AND_AND PLUS MINUS NOT REMAINDER XOR AND MULTIPLY OR TWIDDLE DIVIDE GREATER LESS LPAREN RPAREN LBRACE RBRACE LBRACKET RBRACKET SEMICOLON QUESTION COLON COMMA DOT EQUAL ERROR EOF EOL $Alias '++' ::= PLUS_PLUS '--' ::= MINUS_MINUS '==' ::= EQUAL_EQUAL '<=' ::= LESS_EQUAL '>=' ::= GREATER_EQUAL '!=' ::= NOT_EQUAL '<<' ::= LEFT_SHIFT '>>' ::= RIGHT_SHIFT '>>>' ::= UNSIGNED_RIGHT_SHIFT '+=' ::= PLUS_EQUAL '-=' ::= MINUS_EQUAL '*=' ::= MULTIPLY_EQUAL '/=' ::= DIVIDE_EQUAL '&=' ::= AND_EQUAL '|=' ::= OR_EQUAL '^=' ::= XOR_EQUAL '%=' ::= REMAINDER_EQUAL '<<=' ::= LEFT_SHIFT_EQUAL '>>=' ::= RIGHT_SHIFT_EQUAL '>>>=' ::= UNSIGNED_RIGHT_SHIFT_EQUAL '||' ::= OR_OR '&&' ::= AND_AND '+' ::= PLUS '-' ::= MINUS '!' ::= NOT '%' ::= REMAINDER '^' ::= XOR '&' ::= AND '*' ::= MULTIPLY '|' ::= OR '~' ::= TWIDDLE '/' ::= DIVIDE '>' ::= GREATER '<' ::= LESS '(' ::= LPAREN ')' ::= RPAREN '{' ::= LBRACE '}' ::= RBRACE '[' ::= LBRACKET ']' ::= RBRACKET ';' ::= SEMICOLON '?' ::= QUESTION ':' ::= COLON ',' ::= COMMA '.' ::= DOT '=' ::= EQUAL $EOF ::= EOF $ERROR ::= ERROR $EOL ::= ; $Start Goal $Rules \: // // This software is subject to the terms of the IBM Jikes Compiler Open // Source License Agreement available at the following URL: // http://www.ibm.com/research/jikes. // Copyright (C) 1996, 1998, International Business Machines Corporation // and others. All Rights Reserved. // You must accept the terms of that agreement to use this software. // #ifndef HEADERS void Parser::InitRuleAction() { rule_action[0] = &Parser::BadAction; #else void BadAction(void); void NoAction(void); void NullAction(void); void MakeArrayType(void); void MakeSimpleName(void); void MakeFieldAccess(void); void MakeQualifiedSuper(void); void MakeQualifiedNew(void); void SetSym1ToSym2(void); void MakeEmptyStatement(void); void MakeLabeledStatement(void); void MakeExpressionStatement(void); void MakeIfThenElseStatement(void); void MakeWhileStatement(void); void MakeForStatement(void); void MakeArrayCreationExpression(void); void MakeSuperFieldAccess(void); void MakeSuperDoubleFieldAccess(void); void MakeArrayAccess(void); void MakeCastExpression(void); #endif :\ /.#line $next_line "$input_file" // // This software is subject to the terms of the IBM Jikes Compiler Open // Source License Agreement available at the following URL: // http://www.ibm.com/research/jikes. // Copyright (C) 1996, 1998, International Business Machines Corporation // and others. All Rights Reserved. // You must accept the terms of that agreement to use this software. // #include "config.h" #include "parser.h" #include "ast.h" #undef HEADERS #include "javaact.h" //****************************************************************************// //****************************************************************************// //* *// //* Below, we show each rule of the Java grammar together with the semantic *// //* action that is invoked when the parser performs a reduction by that rule.*// //* *// //****************************************************************************// //****************************************************************************// ./ --18.2 Productions from 2.3: The syntactic Grammar Goal -> CompilationUnit \:$NoAction:\ /.$location // // Given a rule of the form A ::= x1 x2 ... xn n >= 1 // // Do nothing - Whatever Ast was produced for x1 is inherited by A. // void Parser::BadAction(void) { assert(0); } void Parser::NoAction(void) {} ./ Goal ::= BodyMarker ConstructorBody \:$action:\ /.$location // // This rule was added to allow the parser to recognize the body of a // funtion (constructor or method, as the definition of the body of a // method is subsumed by the definition of the body of a constructor) // out of context. Note that the artificial terminal BodyMarker is // added here to prevent an ordinary parse from accepting a body as // a valid input - i.e., to recognize a body out-of-context, the // BodyMarker terminal must be inserted in front of the input stream // containing the body in question. // void Parser::Act$rule_number(void) { Sym(1) = Sym(2); } ./ --18.3 Productions from 3: Lexical Structure -- -- Expand the definition IntegerLiteral and BooleanLiteral -- Literal ::= IntegerLiteral \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewIntegerLiteral(Token(1)); } ./ Literal ::= LongLiteral \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewLongLiteral(Token(1)); } ./ Literal ::= FloatingPointLiteral \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewFloatingPointLiteral(Token(1)); } ./ Literal ::= DoubleLiteral \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewDoubleLiteral(Token(1)); } ./ Literal -> BooleanLiteral \:$NoAction:\ /.$shared_NoAction./ Literal ::= CharacterLiteral \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewCharacterLiteral(Token(1)); } ./ Literal ::= StringLiteral \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewStringLiteral(Token(1)); } ./ Literal ::= null \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewNullLiteral(Token(1)); } ./ BooleanLiteral ::= true \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewTrueLiteral(Token(1)); } ./ BooleanLiteral ::= false \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewFalseLiteral(Token(1)); } ./ --18.4 Productions from 4: Types, Values and Variables Type -> PrimitiveType \:$NoAction:\ /.$shared_NoAction./ Type -> ReferenceType \:$NoAction:\ /.$shared_NoAction./ PrimitiveType -> NumericType \:$NoAction:\ /.$shared_NoAction./ PrimitiveType ::= 'boolean' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewPrimitiveType(Ast::BOOLEAN, Token(1)); } ./ NumericType -> IntegralType \:$NoAction:\ /.$shared_NoAction./ NumericType -> FloatingPointType \:$NoAction:\ /.$shared_NoAction./ IntegralType ::= 'byte' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewPrimitiveType(Ast::BYTE, Token(1)); } ./ IntegralType ::= 'short' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewPrimitiveType(Ast::SHORT, Token(1)); } ./ IntegralType ::= 'int' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewPrimitiveType(Ast::INT, Token(1)); } ./ IntegralType ::= 'long' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewPrimitiveType(Ast::LONG, Token(1)); } ./ IntegralType ::= 'char' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewPrimitiveType(Ast::CHAR, Token(1)); } ./ FloatingPointType ::= 'float' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewPrimitiveType(Ast::FLOAT, Token(1)); } ./ FloatingPointType ::= 'double' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewPrimitiveType(Ast::DOUBLE, Token(1)); } ./ ReferenceType -> ClassOrInterfaceType \:$NoAction:\ /.$shared_NoAction./ ReferenceType -> ArrayType \:$NoAction:\ /.$shared_NoAction./ ClassOrInterfaceType -> Name \:$NoAction:\ /.$shared_NoAction./ -- -- These rules have been rewritten to avoid some conflicts introduced -- by adding the 1.1 features -- -- ArrayType ::= PrimitiveType '[' ']' -- ArrayType ::= Name '[' ']' -- ArrayType ::= ArrayType '[' ']' -- ArrayType ::= PrimitiveType Dims \:$MakeArrayType:\ /.$location void Parser::MakeArrayType(void) { AstArrayType *p = ast_pool -> NewArrayType(); p -> type = Sym(1); // // The list of modifiers is guaranteed not empty // { AstListNode *tail = (AstListNode *) Sym(2); p -> AllocateBrackets(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddBrackets((AstBrackets *) root -> element); } while(root != tail); FreeCircularList(tail); } Sym(1) = p; } ./ ArrayType ::= Name Dims \:$MakeArrayType:\ /.$shared_function // // void MakeArrayType(void); //./ ClassType -> ClassOrInterfaceType \:$NoAction:\ /.$shared_NoAction./ InterfaceType -> ClassOrInterfaceType \:$NoAction:\ /.$shared_NoAction./ --18.5 Productions from 6: Names Name -> SimpleName \:$NoAction:\ /.$shared_NoAction./ Name -> QualifiedName \:$NoAction:\ /.$shared_NoAction./ SimpleName ::= 'Identifier' \:$MakeSimpleName:\ /.$location void Parser::MakeSimpleName(void) { Sym(1) = ast_pool -> NewSimpleName(Token(1)); } ./ QualifiedName ::= Name '.' 'Identifier' \:$MakeFieldAccess:\ /.$location void Parser::MakeFieldAccess(void) { AstFieldAccess *p = ast_pool -> NewFieldAccess(); p -> base = (AstExpression *) Sym(1); p -> dot_token = Token(2); p -> identifier_token = Token(3); Sym(1) = p; } ./ --18.6 Productions from 7: Packages CompilationUnit ::= PackageDeclarationopt ImportDeclarationsopt TypeDeclarationsopt \:$action:\ /.$location void Parser::Act$rule_number(void) { AstCompilationUnit *p = ast_pool -> NewCompilationUnit(); p -> package_declaration_opt = (AstPackageDeclaration *) Sym(1); if (Sym(2) != NULL) { AstListNode *tail = (AstListNode *) Sym(2); p -> AllocateImportDeclarations(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddImportDeclaration((AstImportDeclaration *) root -> element); } while(root != tail); FreeCircularList(tail); } if (Sym(3) != NULL) { AstListNode *tail = (AstListNode *) Sym(3); p -> AllocateTypeDeclarations(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddTypeDeclaration(root -> element); } while(root != tail); FreeCircularList(tail); } Sym(1) = p; } ./ ImportDeclarations ::= ImportDeclaration \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *p = AllocateListNode(); p -> next = p; p -> element = Sym(1); p -> index = 0; Sym(1) = p; } ./ ImportDeclarations ::= ImportDeclarations ImportDeclaration \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *tail = (AstListNode *) Sym(1); AstListNode *p = AllocateListNode(); p -> element = Sym(2); p -> index = tail -> index + 1; p -> next = tail -> next; tail -> next = p; Sym(1) = p; } ./ TypeDeclarations ::= TypeDeclaration \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *p = AllocateListNode(); p -> next = p; p -> element = Sym(1); p -> index = 0; Sym(1) = p; } ./ TypeDeclarations ::= TypeDeclarations TypeDeclaration \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *tail = (AstListNode *) Sym(1); AstListNode *p = AllocateListNode(); p -> element = Sym(2); p -> index = tail -> index + 1; p -> next = tail -> next; tail -> next = p; Sym(1) = p; } ./ PackageDeclaration ::= 'package' Name PackageHeaderMarker ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstPackageDeclaration *p = ast_pool -> NewPackageDeclaration(); p -> package_token = Token(1); p -> name = (AstExpression *) Sym(2); p -> semicolon_token = Token(3); Sym(1) = p; } ./ ImportDeclaration -> SingleTypeImportDeclaration \:$NoAction:\ /.$shared_NoAction./ ImportDeclaration -> TypeImportOnDemandDeclaration \:$NoAction:\ /.$shared_NoAction./ SingleTypeImportDeclaration ::= 'import' Name ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstImportDeclaration *p = ast_pool -> NewImportDeclaration(); p -> import_token = Token(1); p -> name = (AstExpression *) Sym(2); p -> star_token_opt = 0; p -> semicolon_token = Token(3); Sym(1) = p; } ./ TypeImportOnDemandDeclaration ::= 'import' Name '.' '*' ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstImportDeclaration *p = ast_pool -> NewImportDeclaration(); p -> import_token = Token(1); p -> name = (AstExpression *) Sym(2); p -> star_token_opt = Token(4); p -> semicolon_token = Token(5); Sym(1) = p; } ./ TypeDeclaration -> ClassDeclaration \:$NoAction:\ /.$shared_NoAction./ TypeDeclaration -> InterfaceDeclaration \:$NoAction:\ /.$shared_NoAction./ TypeDeclaration ::= ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewEmptyDeclaration(Token(1)); } ./ --18.7 Only in the LALR(1) Grammar Modifiers ::= Modifier \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *p = AllocateListNode(); p -> next = p; p -> element = Sym(1); p -> index = 0; Sym(1) = p; } ./ Modifiers ::= Modifiers Modifier \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *tail = (AstListNode *) Sym(1); AstListNode *p = AllocateListNode(); p -> element = Sym(2); p -> index = tail -> index + 1; p -> next = tail -> next; tail -> next = p; Sym(1) = p; } ./ Modifier ::= 'public' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewModifier(Ast::PUBLIC, Token(1)); } ./ Modifier ::= 'protected' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewModifier(Ast::PROTECTED, Token(1)); } ./ Modifier ::= 'private' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewModifier(Ast::PRIVATE, Token(1)); } ./ Modifier ::= 'static' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewModifier(Ast::STATIC, Token(1)); } ./ Modifier ::= 'abstract' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewModifier(Ast::ABSTRACT, Token(1)); } ./ Modifier ::= 'final' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewModifier(Ast::FINAL, Token(1)); } ./ Modifier ::= 'native' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewModifier(Ast::NATIVE, Token(1)); } ./ Modifier ::= 'strictfp' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewModifier(Ast::STRICTFP, Token(1)); } ./ Modifier ::= 'synchronized' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewModifier(Ast::SYNCHRONIZED, Token(1)); } ./ Modifier ::= 'transient' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewModifier(Ast::TRANSIENT, Token(1)); } ./ Modifier ::= 'volatile' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewModifier(Ast::VOLATILE, Token(1)); } ./ --18.8 Productions from 8: Class Declarations --ClassModifier ::= -- 'abstract' -- | 'final' -- | 'public' --18.8.1 Productions from 8.1: Class Declarations ClassDeclaration ::= Modifiersopt 'class' 'Identifier' Superopt Interfacesopt ClassBody \:$action:\ /.$location void Parser::Act$rule_number(void) { AstClassDeclaration *p = ast_pool -> NewClassDeclaration(); if (Sym(1) != NULL) { AstListNode *tail = (AstListNode *) Sym(1); p -> AllocateClassModifiers(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddClassModifier((AstModifier *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> class_token = Token(2); p -> identifier_token = Token(3); p -> super_opt = (AstExpression *) Sym(4); if (Sym(5) != NULL) { AstListNode *tail = (AstListNode *) Sym(5); p -> AllocateInterfaces(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddInterface((AstExpression *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> class_body = (AstClassBody *) Sym(6); Sym(1) = p; } ./ Super ::= 'extends' ClassType \:$SetSym1ToSym2:\ /.$location void Parser::SetSym1ToSym2(void) { Sym(1) = Sym(2); } ./ Interfaces ::= 'implements' InterfaceTypeList \:$SetSym1ToSym2:\ /.$shared_function // // void SetSym1ToSym2(void); //./ InterfaceTypeList ::= InterfaceType \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *p = AllocateListNode(); p -> next = p; p -> element = Sym(1); p -> index = 0; Sym(1) = p; } ./ InterfaceTypeList ::= InterfaceTypeList ',' InterfaceType \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *tail = (AstListNode *) Sym(1); AstListNode *p = AllocateListNode(); p -> element = Sym(3); p -> index = tail -> index + 1; p -> next = tail -> next; tail -> next = p; Sym(1) = p; } ./ ClassBody ::= '{' ClassBodyDeclarationsopt '}' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstClassBody *p = ast_pool -> NewClassBody(); if (parse_header_only) p -> mark_unparsed(); p -> left_brace_token = Token(1); if (Sym(2) != NULL) { int num_instance_variables = 0, num_class_variables = 0, num_methods = 0, num_constructors = 0, num_static_initializers = 0, num_inner_classes = 0, num_inner_interfaces = 0, num_blocks = 0, num_empty_declarations = 0; AstListNode *tail = (AstListNode *) Sym(2); p -> AllocateClassBodyDeclarations(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddClassBodyDeclaration(root -> element); AstFieldDeclaration *field_declaration = root -> element -> FieldDeclarationCast(); if (field_declaration) { for (int i = 0; i < field_declaration -> NumVariableModifiers(); i++) { if (field_declaration -> VariableModifier(i) -> kind == Ast::STATIC) { field_declaration -> MarkStatic(); break; } } if (field_declaration -> StaticFieldCast()) num_class_variables++; else num_instance_variables++; } else if (root -> element -> MethodDeclarationCast()) { num_methods++; } else if (root -> element -> ConstructorDeclarationCast()) { num_constructors++; } else if (root -> element -> StaticInitializerCast()) { num_static_initializers++; } else if (root -> element -> ClassDeclarationCast()) { num_inner_classes++; } else if (root -> element -> InterfaceDeclarationCast()) { num_inner_interfaces++; } else if (root -> element -> BlockCast()) { num_blocks++; } else num_empty_declarations++; } while(root != tail); p -> AllocateInstanceVariables(num_instance_variables); p -> AllocateClassVariables(num_class_variables); p -> AllocateMethods(num_methods); p -> AllocateConstructors(num_constructors); p -> AllocateStaticInitializers(num_static_initializers); p -> AllocateNestedClasses(num_inner_classes); p -> AllocateNestedInterfaces(num_inner_interfaces); p -> AllocateBlocks(num_blocks); p -> AllocateEmptyDeclarations(num_empty_declarations); root = tail; do { root = root -> next; AstFieldDeclaration *field_declaration; AstMethodDeclaration *method_declaration; AstConstructorDeclaration *constructor_declaration; AstStaticInitializer *static_initializer; AstClassDeclaration *class_declaration; AstInterfaceDeclaration *interface_declaration; AstBlock *block; if (field_declaration = root -> element -> FieldDeclarationCast()) { if (field_declaration -> StaticFieldCast()) p -> AddClassVariable(field_declaration); else p -> AddInstanceVariable(field_declaration); } else if (method_declaration = root -> element -> MethodDeclarationCast()) { p -> AddMethod(method_declaration); } else if (constructor_declaration = root -> element -> ConstructorDeclarationCast()) { p -> AddConstructor(constructor_declaration); } else if (static_initializer = root -> element -> StaticInitializerCast()) { p -> AddStaticInitializer(static_initializer); } else if (class_declaration = root -> element -> ClassDeclarationCast()) { p -> AddNestedClass(class_declaration); } else if (interface_declaration = root -> element -> InterfaceDeclarationCast()) { p -> AddNestedInterface(interface_declaration); } else if (block = root -> element -> BlockCast()) { p -> AddBlock(block); } else // assert(block = root -> element -> EmptyDeclarationCast()) { p -> AddEmptyDeclaration((AstEmptyDeclaration *) root -> element); } } while(root != tail); FreeCircularList(tail); } p -> right_brace_token = Token(3); p -> pool = body_pool; // from now on, this is the storage pool to use for this type Sym(1) = p; } ./ ClassBodyDeclarations ::= ClassBodyDeclaration \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *p = AllocateListNode(); p -> next = p; p -> element = Sym(1); p -> index = 0; Sym(1) = p; } ./ ClassBodyDeclarations ::= ClassBodyDeclarations ClassBodyDeclaration \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *tail = (AstListNode *) Sym(1); AstListNode *p = AllocateListNode(); p -> element = Sym(2); p -> index = tail -> index + 1; p -> next = tail -> next; tail -> next = p; Sym(1) = p; } ./ ClassBodyDeclaration -> ClassMemberDeclaration \:$NoAction:\ /.$shared_NoAction./ ClassBodyDeclaration -> StaticInitializer \:$NoAction:\ /.$shared_NoAction./ ClassBodyDeclaration -> ConstructorDeclaration \:$NoAction:\ /.$shared_NoAction./ --1.1 feature ClassBodyDeclaration ::= MethodHeaderMarker Block \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = Sym(2); } ./ ClassMemberDeclaration -> FieldDeclaration \:$NoAction:\ /.$shared_NoAction./ ClassMemberDeclaration -> MethodDeclaration \:$NoAction:\ /.$shared_NoAction./ --1.1 feature ClassMemberDeclaration -> ClassDeclaration \:$NoAction:\ /.$shared_NoAction./ --1.1 feature ClassMemberDeclaration -> InterfaceDeclaration \:$NoAction:\ /.$shared_NoAction./ -- -- Empty declarations are not valid Java ClassMemberDeclarations. -- However, since the current (2/14/97) Java compiler accepts them -- (in fact, some of the official tests contain this erroneous -- syntax), we decided to accept them as valid syntax and flag them -- as a warning during semantic processing. -- ClassMemberDeclaration ::= ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewEmptyDeclaration(Token(1)); } ./ --18.8.2 Productions from 8.3: Field Declarations --VariableModifier ::= -- 'public' -- | 'protected' -- | 'private' -- | 'static' -- | 'final' -- | 'transient' -- | 'volatile' FieldDeclaration ::= Modifiersopt Type VariableDeclarators ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstFieldDeclaration *p = ast_pool -> NewFieldDeclaration(); if (Sym(1) != NULL) { AstListNode *tail = (AstListNode *) Sym(1); p -> AllocateVariableModifiers(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddVariableModifier((AstModifier *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> type = Sym(2); // // The list of declarators is guaranteed not empty // { AstListNode *tail = (AstListNode *) Sym(3); p -> AllocateVariableDeclarators(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddVariableDeclarator((AstVariableDeclarator *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> semicolon_token = Token(4); Sym(1) = p; } ./ VariableDeclarators ::= VariableDeclarator \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *p = AllocateListNode(); p -> next = p; p -> element = Sym(1); p -> index = 0; Sym(1) = p; } ./ VariableDeclarators ::= VariableDeclarators ',' VariableDeclarator \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *tail = (AstListNode *) Sym(1); AstListNode *p = AllocateListNode(); p -> element = Sym(3); p -> index = tail -> index + 1; p -> next = tail -> next; tail -> next = p; Sym(1) = p; } ./ VariableDeclarator ::= VariableDeclaratorId \:$action:\ /.$location void Parser::Act$rule_number(void) { AstVariableDeclarator *p = ast_pool -> NewVariableDeclarator(); p -> variable_declarator_name = (AstVariableDeclaratorId *) Sym(1); p -> variable_initializer_opt = NULL; Sym(1) = p; } ./ VariableDeclarator ::= VariableDeclaratorId '=' VariableInitializer \:$action:\ /.$location void Parser::Act$rule_number(void) { AstVariableDeclarator *p = ast_pool -> NewVariableDeclarator(); p -> variable_declarator_name = (AstVariableDeclaratorId *) Sym(1); p -> variable_initializer_opt = Sym(3); Sym(1) = p; } ./ VariableDeclaratorId ::= 'Identifier' Dimsopt \:$action:\ /.$location void Parser::Act$rule_number(void) { AstVariableDeclaratorId *p = ast_pool -> NewVariableDeclaratorId(); p -> identifier_token = Token(1); if (Sym(2) != NULL) { AstListNode *tail = (AstListNode *) Sym(2); p -> AllocateBrackets(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddBrackets((AstBrackets *) root -> element); } while(root != tail); FreeCircularList(tail); } Sym(1) = p; } ./ VariableInitializer -> Expression \:$NoAction:\ /.$shared_NoAction./ VariableInitializer -> ArrayInitializer \:$NoAction:\ /.$shared_NoAction./ --18.8.3 Productions from 8.4: Method Declarations --MethodModifier ::= -- 'public' -- | 'protected' -- | 'private' -- | 'static' -- | 'abstract' -- | 'final' -- | 'native' -- | 'synchronized' -- -- The original rule does not contain the "MethodHeaderMarker. -- See explanation above. -- -- MethodDeclaration ::= MethodHeader MethodBody -- MethodDeclaration ::= MethodHeader MethodHeaderMarker MethodBody \:$action:\ /.$location void Parser::Act$rule_number(void) { ((AstMethodDeclaration *) Sym(1)) -> method_body = (AstStatement *) Sym(3); } ./ MethodHeader ::= Modifiersopt Type MethodDeclarator Throwsopt \:$action:\ /.$location void Parser::Act$rule_number(void) { AstMethodDeclaration *p = ast_pool -> NewMethodDeclaration(); if (Sym(1) != NULL) { AstListNode *tail = (AstListNode *) Sym(1); p -> AllocateMethodModifiers(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddMethodModifier((AstModifier *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> type = Sym(2); p -> method_declarator = (AstMethodDeclarator *) Sym(3); if (Sym(4) != NULL) { AstListNode *tail = (AstListNode *) Sym(4); p -> AllocateThrows(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddThrow((AstExpression *) root -> element); } while(root != tail); FreeCircularList(tail); } Sym(1) = p; } ./ MethodHeader ::= Modifiersopt 'void' MethodDeclarator Throwsopt \:$action:\ /.$location void Parser::Act$rule_number(void) { AstMethodDeclaration *p = ast_pool -> NewMethodDeclaration(); if (Sym(1) != NULL) { AstListNode *tail = (AstListNode *) Sym(1); p -> AllocateMethodModifiers(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddMethodModifier((AstModifier *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> type = ast_pool -> NewPrimitiveType(Ast::VOID_TYPE, Token(2)); p -> method_declarator = (AstMethodDeclarator *) Sym(3); if (Sym(4) != NULL) { AstListNode *tail = (AstListNode *) Sym(4); p -> AllocateThrows(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddThrow((AstExpression *) root -> element); } while(root != tail); FreeCircularList(tail); } Sym(1) = p; } ./ MethodDeclarator ::= 'Identifier' '(' FormalParameterListopt ')' Dimsopt \:$action:\ /.$location void Parser::Act$rule_number(void) { AstMethodDeclarator *p = ast_pool -> NewMethodDeclarator(); p -> identifier_token = Token(1); p -> left_parenthesis_token = Token(2); if (Sym(3) != NULL) { AstListNode *tail = (AstListNode *) Sym(3); p -> AllocateFormalParameters(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddFormalParameter((AstFormalParameter *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> right_parenthesis_token = Token(4); if (Sym(5) != NULL) { AstListNode *tail = (AstListNode *) Sym(5); p -> AllocateBrackets(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddBrackets((AstBrackets *) root -> element); } while(root != tail); FreeCircularList(tail); } Sym(1) = p; } ./ FormalParameterList ::= FormalParameter \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *p = AllocateListNode(); p -> next = p; p -> element = Sym(1); p -> index = 0; Sym(1) = p; } ./ FormalParameterList ::= FormalParameterList ',' FormalParameter \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *tail = (AstListNode *) Sym(1); AstListNode *p = AllocateListNode(); p -> element = Sym(3); p -> index = tail -> index + 1; p -> next = tail -> next; tail -> next = p; Sym(1) = p; } ./ FormalParameter ::= Type VariableDeclaratorId \:$action:\ /.$location void Parser::Act$rule_number(void) { AstFormalParameter *p = ast_pool -> NewFormalParameter(); p -> type = Sym(1); p -> variable_declarator_name = (AstVariableDeclaratorId *) Sym(2); Sym(1) = p; } ./ --1.1 feature FormalParameter ::= Modifiers Type VariableDeclaratorId \:$action:\ /.$location void Parser::Act$rule_number(void) { AstFormalParameter *p = ast_pool -> NewFormalParameter(); // // The list of modifiers is guaranteed not empty // { AstListNode *tail = (AstListNode *) Sym(1); p -> AllocateParameterModifiers(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddParameterModifier((AstModifier *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> type = Sym(2); p -> variable_declarator_name = (AstVariableDeclaratorId *) Sym(3); Sym(1) = p; } ./ Throws ::= 'throws' ClassTypeList \:$SetSym1ToSym2:\ /.$shared_function // // void SetSym1ToSym2(void); //./ ClassTypeList ::= ClassType \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *p = AllocateListNode(); p -> next = p; p -> element = Sym(1); p -> index = 0; Sym(1) = p; } ./ ClassTypeList ::= ClassTypeList ',' ClassType \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *tail = (AstListNode *) Sym(1); AstListNode *p = AllocateListNode(); p -> element = Sym(3); p -> index = tail -> index + 1; p -> next = tail -> next; tail -> next = p; Sym(1) = p; } ./ MethodBody -> Block \:$NoAction:\ /.$shared_NoAction./ MethodBody ::= ';' \:$MakeEmptyStatement:\ /.$location void Parser::MakeEmptyStatement(void) { Sym(1) = ast_pool -> NewEmptyStatement(Token(1)); } ./ --18.8.4 Productions from 8.5: Static Initializers StaticInitializer ::= 'static' MethodHeaderMarker Block \:$action:\ /.$location void Parser::Act$rule_number(void) { AstStaticInitializer *p = ast_pool -> NewStaticInitializer(); p -> static_token = Token(1); p -> block = (AstBlock *) Sym(3); Sym(1) = p; } ./ --18.8.5 Productions from 8.6: Constructor Declarations --ConstructorModifier ::= -- 'public' -- | 'protected' -- | 'private' -- -- -- The original rule does not contain a "MethodHeaderMarker". See -- explanation above. -- -- ConstructorDeclaration ::= Modifiersopt ConstructorDeclarator Throwsopt ConstructorBody -- ConstructorDeclaration ::= Modifiersopt ConstructorDeclarator Throwsopt MethodHeaderMarker ConstructorBody \:$action:\ /.$location void Parser::Act$rule_number(void) { AstConstructorBlock *block = Sym(5) -> ConstructorBlockCast(); if (! block) { block = ast_pool -> NewConstructorBlock(); block -> left_brace_token = Sym(5) -> LeftToken(); block -> explicit_constructor_invocation_opt = NULL; block -> block = (AstBlock *) Sym(5); block -> right_brace_token = Sym(5) -> RightToken(); } AstConstructorDeclaration *p = ast_pool -> NewConstructorDeclaration(); if (Sym(1) != NULL) { AstListNode *tail = (AstListNode *) Sym(1); p -> AllocateConstructorModifiers(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddConstructorModifier((AstModifier *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> constructor_declarator = (AstMethodDeclarator *) Sym(2); if (Sym(3) != NULL) { AstListNode *tail = (AstListNode *) Sym(3); p -> AllocateThrows(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddThrow((AstExpression *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> constructor_body = block; Sym(1) = p; } ./ -- -- The original rule specifies SimpleName but it appears to be an -- error as the rule for a method declarator uses an Identifier. --...Until further notice, ... -- -- ConstructorDeclarator ::= SimpleName '(' FormalParameterListopt ')' -- ConstructorDeclarator ::= 'Identifier' '(' FormalParameterListopt ')' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstMethodDeclarator *p = ast_pool -> NewMethodDeclarator(); p -> identifier_token = Token(1); p -> left_parenthesis_token = Token(2); if (Sym(3) != NULL) { AstListNode *tail = (AstListNode *) Sym(3); p -> AllocateFormalParameters(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddFormalParameter((AstFormalParameter *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> right_parenthesis_token = Token(4); Sym(1) = p; } ./ -- -- NOTE that the rules ExplicitConstructorInvocationopt has been expanded -- in the rule below in order to make the grammar lalr(1). -- -- ConstructorBody ::= '{' ExplicitConstructorInvocationopt BlockStatementsopt '}' -- ConstructorBody -> Block \:$NoAction:\ /.$shared_NoAction./ ConstructorBody ::= '{' ExplicitConstructorInvocation BlockStatementsopt '}' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBlock *block = ast_pool -> NewBlock(); if (Sym(3) != NULL) { AstListNode *tail = (AstListNode *) Sym(3); block -> AllocateBlockStatements(tail -> index + 1); AstListNode *root = tail; block -> left_brace_token = root -> element -> LeftToken(); block -> right_brace_token = tail -> element -> RightToken(); do { root = root -> next; block -> AddStatement((AstStatement *) root -> element); } while(root != tail); FreeCircularList(tail); } else { block -> left_brace_token = Token(4); block -> right_brace_token = Token(4); } AstConstructorBlock *p = ast_pool -> NewConstructorBlock(); p -> left_brace_token = Token(1); p -> explicit_constructor_invocation_opt = Sym(2); p -> block = block; p -> right_brace_token = Token(4); Sym(1) = p; } ./ ExplicitConstructorInvocation ::= 'this' '(' ArgumentListopt ')' ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstThisCall *p = ast_pool -> NewThisCall(); p -> base_opt = NULL; p -> dot_token_opt = 0; p -> this_token = Token(1); p -> left_parenthesis_token = Token(2); if (Sym(3) != NULL) { AstListNode *tail = (AstListNode *) Sym(3); p -> AllocateArguments(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddArgument((AstExpression *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> right_parenthesis_token = Token(4); p -> semicolon_token = Token(5); Sym(1) = p; } ./ ExplicitConstructorInvocation ::= 'super' '(' ArgumentListopt ')' ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstSuperCall *p = ast_pool -> NewSuperCall(); p -> base_opt = NULL; p -> dot_token_opt = 0; p -> super_token = Token(1); p -> left_parenthesis_token = Token(2); if (Sym(3) != NULL) { AstListNode *tail = (AstListNode *) Sym(3); p -> AllocateArguments(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddArgument((AstExpression *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> right_parenthesis_token = Token(4); p -> semicolon_token = Token(5); Sym(1) = p; } ./ --1.2 feature ExplicitConstructorInvocation ::= Primary '.' 'this' '(' ArgumentListopt ')' ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstThisCall *p = ast_pool -> NewThisCall(); p -> base_opt = (AstExpression *) Sym(1); p -> dot_token_opt = Token(2); p -> this_token = Token(3); p -> left_parenthesis_token = Token(4); if (Sym(5) != NULL) { AstListNode *tail = (AstListNode *) Sym(5); p -> AllocateArguments(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddArgument((AstExpression *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> right_parenthesis_token = Token(6); p -> semicolon_token = Token(7); Sym(1) = p; } ./ --1.1 feature ExplicitConstructorInvocation ::= Primary '.' 'super' '(' ArgumentListopt ')' ';' \:$MakeQualifiedSuper:\ /.$location void Parser::MakeQualifiedSuper(void) { AstSuperCall *p = ast_pool -> NewSuperCall(); p -> base_opt = (AstExpression *) Sym(1); p -> dot_token_opt = Token(2); p -> super_token = Token(3); p -> left_parenthesis_token = Token(4); if (Sym(5) != NULL) { AstListNode *tail = (AstListNode *) Sym(5); p -> AllocateArguments(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddArgument((AstExpression *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> right_parenthesis_token = Token(6); p -> semicolon_token = Token(7); Sym(1) = p; } ./ --1.1 feature ExplicitConstructorInvocation ::= Name '.' 'super' '(' ArgumentListopt ')' ';' \:$MakeQualifiedSuper:\ /.$shared_function // // void MakeQualifiedSuper(void); //./ --18.9 Productions from 9: Interface Declarations --18.9.1 Productions from 9.1: Interface Declarations --InterfaceModifier ::= -- 'public' -- | 'abstract' -- InterfaceDeclaration ::= Modifiersopt 'interface' 'Identifier' ExtendsInterfacesopt InterfaceBody \:$action:\ /.$location void Parser::Act$rule_number(void) { AstInterfaceDeclaration *p = (AstInterfaceDeclaration *) Sym(5); if (Sym(1) != NULL) { AstListNode *tail = (AstListNode *) Sym(1); p -> AllocateInterfaceModifiers(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddInterfaceModifier((AstModifier *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> interface_token = Token(2); p -> identifier_token = Token(3); if (Sym(4) != NULL) { AstListNode *tail = (AstListNode *) Sym(4); p -> AllocateExtendsInterfaces(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddExtendsInterface((AstExpression *) root -> element); } while(root != tail); FreeCircularList(tail); } Sym(1) = p; } ./ ExtendsInterfaces ::= 'extends' InterfaceTypeList \:$SetSym1ToSym2:\ /.$shared_function // // void SetSym1ToSym2(void); //./ InterfaceBody ::= '{' InterfaceMemberDeclarationsopt '}' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstInterfaceDeclaration *p = ast_pool -> NewInterfaceDeclaration(); if (parse_header_only) p -> mark_unparsed(); p -> left_brace_token = Token(1); if (Sym(2) != NULL) { int num_class_variables = 0, num_methods = 0, num_inner_classes = 0, num_inner_interfaces = 0, num_empty_declarations = 0; AstListNode *tail = (AstListNode *) Sym(2); p -> AllocateInterfaceMemberDeclarations(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddInterfaceMemberDeclaration(root -> element); AstFieldDeclaration *field_declaration = root -> element -> FieldDeclarationCast(); if (field_declaration) { field_declaration -> MarkStatic(); num_class_variables++; } else if (root -> element -> MethodDeclarationCast()) { num_methods++; } else if (root -> element -> ClassDeclarationCast()) { num_inner_classes++; } else if (root -> element -> InterfaceDeclarationCast()) { num_inner_interfaces++; } else num_empty_declarations++; } while(root != tail); p -> AllocateClassVariables(num_class_variables); p -> AllocateMethods(num_methods); p -> AllocateNestedClasses(num_inner_classes); p -> AllocateNestedInterfaces(num_inner_interfaces); p -> AllocateEmptyDeclarations(num_empty_declarations); root = tail; do { root = root -> next; AstFieldDeclaration *field_declaration; AstMethodDeclaration *method_declaration; AstClassDeclaration *class_declaration; AstInterfaceDeclaration *interface_declaration; if (field_declaration = root -> element -> FieldDeclarationCast()) { p -> AddClassVariable(field_declaration); } else if (method_declaration = root -> element -> MethodDeclarationCast()) { p -> AddMethod(method_declaration); } else if (class_declaration = root -> element -> ClassDeclarationCast()) { p -> AddNestedClass(class_declaration); } else if (interface_declaration = root -> element -> InterfaceDeclarationCast()) { p -> AddNestedInterface(interface_declaration); } else // assert(interface_declaration = root -> element -> EmptyDeclarationCast()) { p -> AddEmptyDeclaration((AstEmptyDeclaration *) root -> element); } } while(root != tail); FreeCircularList(tail); } p -> right_brace_token = Token(3); p -> pool = body_pool; // from now on, this is the storage pool to use for this type Sym(1) = p; } ./ InterfaceMemberDeclarations ::= InterfaceMemberDeclaration \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *p = AllocateListNode(); p -> next = p; p -> element = Sym(1); p -> index = 0; Sym(1) = p; } ./ InterfaceMemberDeclarations ::= InterfaceMemberDeclarations InterfaceMemberDeclaration \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *tail = (AstListNode *) Sym(1); AstListNode *p = AllocateListNode(); p -> element = Sym(2); p -> index = tail -> index + 1; p -> next = tail -> next; tail -> next = p; Sym(1) = p; } ./ InterfaceMemberDeclaration -> ConstantDeclaration \:$NoAction:\ /.$shared_NoAction./ InterfaceMemberDeclaration -> AbstractMethodDeclaration \:$NoAction:\ /.$shared_NoAction./ --1.1 feature InterfaceMemberDeclaration -> ClassDeclaration \:$NoAction:\ /.$shared_NoAction./ --1.1 feature InterfaceMemberDeclaration -> InterfaceDeclaration \:$NoAction:\ /.$shared_NoAction./ -- -- Empty declarations are not valid Java InterfaceMemberDeclarations. -- However, since the current (2/14/97) Java compiler accepts them -- (in fact, some of the official tests contain this erroneous -- syntax), we decided to accept them as valid syntax and flag them -- as a warning during semantic processing. -- InterfaceMemberDeclaration ::= ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewEmptyDeclaration(Token(1)); } ./ ConstantDeclaration -> FieldDeclaration \:$NoAction:\ /.$shared_NoAction./ AbstractMethodDeclaration ::= MethodHeader ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { ((AstMethodDeclaration *) Sym(1)) -> method_body = ast_pool -> NewEmptyStatement(Token(2)); } ./ --18.10 Productions from 10: Arrays -- -- NOTE that the rules VariableInitializersopt and ,opt have been expanded, -- where appropriate, in the rule below in order to make the grammar lalr(1). -- -- ArrayInitializer ::= '{' VariableInitializersopt ,opt '}' -- ArrayInitializer ::= '{' ,opt '}' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstArrayInitializer *p = ast_pool -> NewArrayInitializer(); p -> left_brace_token = Token(1); p -> right_brace_token = Token(3); Sym(1) = p; } ./ ArrayInitializer ::= '{' VariableInitializers '}' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstArrayInitializer *p = ast_pool -> NewArrayInitializer(); p -> left_brace_token = Token(1); if (Sym(2) != NULL) { AstListNode *tail = (AstListNode *) Sym(2); p -> AllocateVariableInitializers(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddVariableInitializer(root -> element); } while(root != tail); FreeCircularList(tail); } p -> right_brace_token = Token(3); Sym(1) = p; } ./ ArrayInitializer ::= '{' VariableInitializers , '}' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstArrayInitializer *p = ast_pool -> NewArrayInitializer(); p -> left_brace_token = Token(1); if (Sym(2) != NULL) { AstListNode *tail = (AstListNode *) Sym(2); p -> AllocateVariableInitializers(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddVariableInitializer(root -> element); } while(root != tail); FreeCircularList(tail); } p -> right_brace_token = Token(4); Sym(1) = p; } ./ VariableInitializers ::= VariableInitializer \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *p = AllocateListNode(); p -> next = p; p -> element = Sym(1); p -> index = 0; Sym(1) = p; } ./ VariableInitializers ::= VariableInitializers ',' VariableInitializer \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *tail = (AstListNode *) Sym(1); AstListNode *p = AllocateListNode(); p -> element = Sym(3); p -> index = tail -> index + 1; p -> next = tail -> next; tail -> next = p; Sym(1) = p; } ./ --18.11 Productions from 13: Blocks and Statements Block ::= '{' BlockStatementsopt '}' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBlock *p = ast_pool -> NewBlock(); p -> left_brace_token = Token(1); if (Sym(2) != NULL) { AstListNode *tail = (AstListNode *) Sym(2); p -> AllocateBlockStatements(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddStatement((AstStatement *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> right_brace_token = Token(3); Sym(1) = p; } ./ BlockStatements ::= BlockStatement \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *p = AllocateListNode(); p -> next = p; p -> element = Sym(1); p -> index = 0; Sym(1) = p; } ./ BlockStatements ::= BlockStatements BlockStatement \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *tail = (AstListNode *) Sym(1); AstListNode *p = AllocateListNode(); p -> element = Sym(2); p -> index = tail -> index + 1; p -> next = tail -> next; tail -> next = p; Sym(1) = p; } ./ BlockStatement -> LocalVariableDeclarationStatement \:$NoAction:\ /.$shared_NoAction./ BlockStatement -> Statement \:$NoAction:\ /.$shared_NoAction./ --1.1 feature BlockStatement -> ClassDeclaration \:$NoAction:\ /.$shared_NoAction./ LocalVariableDeclarationStatement ::= LocalVariableDeclaration ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { ((AstLocalVariableDeclarationStatement *) Sym(1)) -> semicolon_token_opt = Token(2); } ./ LocalVariableDeclaration ::= Type VariableDeclarators \:$action:\ /.$location void Parser::Act$rule_number(void) { AstLocalVariableDeclarationStatement *p = ast_pool -> NewLocalVariableDeclarationStatement(); p -> type = Sym(1); // // The list of declarators is guaranteed not empty // { AstListNode *tail = (AstListNode *) Sym(2); p -> AllocateVariableDeclarators(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddVariableDeclarator((AstVariableDeclarator *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> semicolon_token_opt = 0; Sym(1) = p; } ./ --1.1 feature LocalVariableDeclaration ::= Modifiers Type VariableDeclarators \:$action:\ /.$location void Parser::Act$rule_number(void) { AstLocalVariableDeclarationStatement *p = ast_pool -> NewLocalVariableDeclarationStatement(); // // The list of modifiers is guaranteed not empty // { AstListNode *tail = (AstListNode *) Sym(1); p -> AllocateLocalModifiers(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddLocalModifier((AstModifier *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> type = Sym(2); // // The list of declarators is guaranteed not empty // { AstListNode *tail = (AstListNode *) Sym(3); p -> AllocateVariableDeclarators(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddVariableDeclarator((AstVariableDeclarator *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> semicolon_token_opt = 0; Sym(1) = p; } ./ Statement -> StatementWithoutTrailingSubstatement \:$NoAction:\ /.$shared_NoAction./ Statement -> LabeledStatement \:$NoAction:\ /.$shared_NoAction./ Statement -> IfThenStatement \:$NoAction:\ /.$shared_NoAction./ Statement -> IfThenElseStatement \:$NoAction:\ /.$shared_NoAction./ Statement -> WhileStatement \:$NoAction:\ /.$shared_NoAction./ Statement -> ForStatement \:$NoAction:\ /.$shared_NoAction./ StatementNoShortIf -> StatementWithoutTrailingSubstatement \:$NoAction:\ /.$shared_NoAction./ StatementNoShortIf -> LabeledStatementNoShortIf \:$NoAction:\ /.$shared_NoAction./ StatementNoShortIf -> IfThenElseStatementNoShortIf \:$NoAction:\ /.$shared_NoAction./ StatementNoShortIf -> WhileStatementNoShortIf \:$NoAction:\ /.$shared_NoAction./ StatementNoShortIf -> ForStatementNoShortIf \:$NoAction:\ /.$shared_NoAction./ StatementWithoutTrailingSubstatement -> Block \:$NoAction:\ /.$shared_NoAction./ StatementWithoutTrailingSubstatement -> EmptyStatement \:$NoAction:\ /.$shared_NoAction./ StatementWithoutTrailingSubstatement -> ExpressionStatement \:$NoAction:\ /.$shared_NoAction./ StatementWithoutTrailingSubstatement -> SwitchStatement \:$NoAction:\ /.$shared_NoAction./ StatementWithoutTrailingSubstatement -> DoStatement \:$NoAction:\ /.$shared_NoAction./ StatementWithoutTrailingSubstatement -> BreakStatement \:$NoAction:\ /.$shared_NoAction./ StatementWithoutTrailingSubstatement -> ContinueStatement \:$NoAction:\ /.$shared_NoAction./ StatementWithoutTrailingSubstatement -> ReturnStatement \:$NoAction:\ /.$shared_NoAction./ StatementWithoutTrailingSubstatement -> SynchronizedStatement \:$NoAction:\ /.$shared_NoAction./ StatementWithoutTrailingSubstatement -> ThrowStatement \:$NoAction:\ /.$shared_NoAction./ StatementWithoutTrailingSubstatement -> TryStatement \:$NoAction:\ /.$shared_NoAction./ EmptyStatement ::= ';' \:$MakeEmptyStatement:\ /.$shared_function // // void MakeEmptyStatement(void); //./ LabeledStatement ::= 'Identifier' ':' Statement \:$MakeLabeledStatement:\ /.$location void Parser::MakeLabeledStatement(void) { AstBlock *p = Sym(3) -> BlockCast(); if (! (p && p -> NumStatements() == 1 && (p -> Statement(0) -> kind == Ast::FOR || p -> Statement(0) -> kind == Ast::WHILE || p -> Statement(0) -> kind == Ast::DO))) { // // When a statement is labeled, it is enclosed in a block. // This is necessary in order to allow the same name to be // reused to label a subsequent statement at the same nesting // level... See ProcessBlock, ProcessStatement,... // p = ast_pool -> NewBlock(); p -> AllocateBlockStatements(1); // allocate 1 element p -> left_brace_token = Token(1); p -> AddStatement((AstStatement *) Sym(3)); p -> right_brace_token = Sym(3) -> RightToken(); } p -> label_token_opt = Token(1); // add label to statement Sym(1) = p; // The final result is a block containing the labeled-statement } ./ LabeledStatementNoShortIf ::= 'Identifier' ':' StatementNoShortIf \:$MakeLabeledStatement:\ /.$shared_function // // void MakeLabeledStatement(void); //./ ExpressionStatement ::= StatementExpression ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { ((AstExpressionStatement *) Sym(1)) -> semicolon_token_opt = Token(2); } ./ StatementExpression ::= Assignment \:$MakeExpressionStatement:\ /.$location void Parser::MakeExpressionStatement(void) { AstExpressionStatement *p = ast_pool -> NewExpressionStatement(); p -> expression = (AstExpression *) Sym(1); p -> semicolon_token_opt = 0; Sym(1) = p; } ./ StatementExpression ::= PreIncrementExpression \:$MakeExpressionStatement:\ /.$shared_function // // void MakeExpressionStatement(void); //./ StatementExpression ::= PreDecrementExpression \:$MakeExpressionStatement:\ /.$shared_function // // void MakeExpressionStatement(void); //./ StatementExpression ::= PostIncrementExpression \:$MakeExpressionStatement:\ /.$shared_function // // void MakeExpressionStatement(void); //./ StatementExpression ::= PostDecrementExpression \:$MakeExpressionStatement:\ /.$shared_function // // void MakeExpressionStatement(void); //./ StatementExpression ::= MethodInvocation \:$MakeExpressionStatement:\ /.$shared_function // // void MakeExpressionStatement(void); //./ StatementExpression ::= ClassInstanceCreationExpression \:$MakeExpressionStatement:\ /.$shared_function // // void MakeExpressionStatement(void); //./ IfThenStatement ::= 'if' '(' Expression ')' Statement \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBlock *block = Sym(5) -> BlockCast(); if (! block) { block = ast_pool -> NewBlock(); block -> AllocateBlockStatements(1); // allocate 1 element block -> left_brace_token = Token(5); block -> AddStatement((AstStatement *) Sym(5)); block -> right_brace_token = Sym(5) -> RightToken(); } AstIfStatement *p = ast_pool -> NewIfStatement(); p -> if_token = Token(1); p -> expression = (AstExpression *) Sym(3); p -> true_statement = block; p -> false_statement_opt = NULL; Sym(1) = p; } ./ IfThenElseStatement ::= 'if' '(' Expression ')' StatementNoShortIf 'else' Statement \:$MakeIfThenElseStatement:\ /.$location void Parser::MakeIfThenElseStatement(void) { AstBlock *true_block = Sym(5) -> BlockCast(); if (! true_block) { true_block = ast_pool -> NewBlock(); true_block -> AllocateBlockStatements(1); // allocate 1 element true_block -> left_brace_token = Token(5); true_block -> AddStatement((AstStatement *) Sym(5)); true_block -> right_brace_token = Sym(5) -> RightToken(); } AstBlock *false_block = Sym(7) -> BlockCast(); if (! false_block) { false_block = ast_pool -> NewBlock(); false_block -> AllocateBlockStatements(1); // allocate 1 element false_block -> left_brace_token = Token(7); false_block -> AddStatement((AstStatement *) Sym(7)); false_block -> right_brace_token = Sym(7) -> RightToken(); } AstIfStatement *p = ast_pool -> NewIfStatement(); p -> if_token = Token(1); p -> expression = (AstExpression *) Sym(3); p -> true_statement = true_block; p -> false_statement_opt = false_block; Sym(1) = p; } ./ IfThenElseStatementNoShortIf ::= 'if' '(' Expression ')' StatementNoShortIf 'else' StatementNoShortIf \:$MakeIfThenElseStatement:\ /.$shared_function // // void MakeIfThenElseStatement(void); //./ SwitchStatement ::= 'switch' '(' Expression ')' SwitchBlock \:$action:\ /.$location void Parser::Act$rule_number(void) { AstSwitchStatement *p = (AstSwitchStatement *) Sym(5); p -> switch_token = Token(1); p -> expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ SwitchBlock ::= '{' '}' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstSwitchStatement *p = ast_pool -> NewSwitchStatement(); AstBlock *block = ast_pool -> NewBlock(); block -> left_brace_token = Token(1); block -> right_brace_token = Token(2); p -> switch_block = block; Sym(1) = p; } ./ SwitchBlock ::= '{' SwitchBlockStatements '}' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstSwitchStatement *p = ast_pool -> NewSwitchStatement(); AstBlock *block = ast_pool -> NewBlock(); block -> left_brace_token = Token(1); if (Sym(2) != NULL) { AstListNode *tail = (AstListNode *) Sym(2); block -> AllocateBlockStatements(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; block -> AddStatement((AstStatement *) root -> element); } while(root != tail); FreeCircularList(tail); } block -> right_brace_token = Token(3); p -> switch_block = block; Sym(1) = p; } ./ SwitchBlock ::= '{' SwitchLabels '}' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstSwitchStatement *p = ast_pool -> NewSwitchStatement(); AstSwitchBlockStatement *q = ast_pool -> NewSwitchBlockStatement(); // // The list of SwitchBlockStatements is never null // { AstListNode *tail = (AstListNode *) Sym(2); q -> AllocateSwitchLabels(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; q -> AddSwitchLabel((AstStatement *) root -> element); } while(root != tail); FreeCircularList(tail); } AstBlock *block = ast_pool -> NewBlock(); block -> AllocateBlockStatements(1); // allocate 1 element block -> left_brace_token = Token(1); block -> AddStatement(q); block -> right_brace_token = Token(3); p -> switch_block = block; Sym(1) = p; } ./ SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstSwitchStatement *p = ast_pool -> NewSwitchStatement(); AstBlock *block = ast_pool -> NewBlock(); block -> left_brace_token = Token(1); // // The list of SwitchBlockStatements is never null // { AstListNode *tail = (AstListNode *) Sym(2); block -> AllocateBlockStatements(tail -> index + 2); // +1 because of extra statement for additional SwithLabels AstListNode *root = tail; do { root = root -> next; block -> AddStatement((AstStatement *) root -> element); } while(root != tail); FreeCircularList(tail); } AstSwitchBlockStatement *q = ast_pool -> NewSwitchBlockStatement(); // // The list of SwitchLabels is never null // { AstListNode *tail = (AstListNode *) Sym(3); q -> AllocateSwitchLabels(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; q -> AddSwitchLabel(root -> element); } while(root != tail); FreeCircularList(tail); } block -> AddStatement(q); block -> right_brace_token = Token(4); p -> switch_block = block; Sym(1) = p; } ./ SwitchBlockStatements ::= SwitchBlockStatement \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *p = AllocateListNode(); p -> next = p; p -> element = Sym(1); p -> index = 0; Sym(1) = p; } ./ SwitchBlockStatements ::= SwitchBlockStatements SwitchBlockStatement \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *tail = (AstListNode *) Sym(1); AstListNode *p = AllocateListNode(); p -> element = Sym(2); p -> index = tail -> index + 1; p -> next = tail -> next; tail -> next = p; Sym(1) = p; } ./ SwitchBlockStatement ::= SwitchLabels BlockStatements \:$action:\ /.$location void Parser::Act$rule_number(void) { AstSwitchBlockStatement *p = ast_pool -> NewSwitchBlockStatement(); // // The list of SwitchLabels is never null // { AstListNode *tail = (AstListNode *) Sym(1); p -> AllocateSwitchLabels(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddSwitchLabel(root -> element); } while(root != tail); FreeCircularList(tail); } // // The list of SwitchBlockStatements is never null // { AstListNode *tail = (AstListNode *) Sym(2); p -> AllocateBlockStatements(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddStatement((AstStatement *) root -> element); } while(root != tail); FreeCircularList(tail); } Sym(1) = p; } ./ SwitchLabels ::= SwitchLabel \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *p = AllocateListNode(); p -> next = p; p -> element = Sym(1); p -> index = 0; Sym(1) = p; } ./ SwitchLabels ::= SwitchLabels SwitchLabel \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *tail = (AstListNode *) Sym(1); AstListNode *p = AllocateListNode(); p -> element = Sym(2); p -> index = tail -> index + 1; p -> next = tail -> next; tail -> next = p; Sym(1) = p; } ./ SwitchLabel ::= 'case' ConstantExpression ':' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstCaseLabel *p = ast_pool -> NewCaseLabel(); p -> case_token = Token(1); p -> expression = (AstExpression *) Sym(2); p -> colon_token = Token(3); Sym(1) = p; } ./ SwitchLabel ::= 'default' ':' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstDefaultLabel *p = ast_pool -> NewDefaultLabel(); p -> default_token = Token(1); p -> colon_token = Token(2); Sym(1) = p; } ./ WhileStatement ::= 'while' '(' Expression ')' Statement \:$MakeWhileStatement:\ /.$location void Parser::MakeWhileStatement(void) { AstWhileStatement *p = ast_pool -> NewWhileStatement(); p -> while_token = Token(1); p -> expression = (AstExpression *) Sym(3); p -> statement = (AstStatement *) Sym(5); AstBlock *block = ast_pool -> NewBlock(); block -> AllocateBlockStatements(1); // allocate 1 element block -> left_brace_token = Token(1); // point to 'FOR' keyword block -> AddStatement(p); block -> right_brace_token = Sym(5) -> RightToken(); // point to last token in statement Sym(1) = block; } ./ WhileStatementNoShortIf ::= 'while' '(' Expression ')' StatementNoShortIf \:$MakeWhileStatement:\ /.$shared_function // // void MakeWhileStatement(void); //./ DoStatement ::= 'do' Statement 'while' '(' Expression ')' ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstDoStatement *p = ast_pool -> NewDoStatement(); p -> do_token = Token(1); p -> statement = (AstStatement *) Sym(2); p -> while_token = Token(3); p -> expression = (AstExpression *) Sym(5); p -> semicolon_token = Token(7); AstBlock *block = ast_pool -> NewBlock(); block -> AllocateBlockStatements(1); // allocate 1 element block -> left_brace_token = Token(1); block -> AddStatement(p); block -> right_brace_token = Token(7); Sym(1) = block; } ./ ForStatement ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' Statement \:$MakeForStatement:\ /.$location void Parser::MakeForStatement(void) { AstForStatement *p = ast_pool -> NewForStatement(); p -> for_token = Token(1); if (Sym(3) != NULL) { AstListNode *tail = (AstListNode *) Sym(3); p -> AllocateForInitStatements(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddForInitStatement((AstStatement *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> end_expression_opt = (AstExpression *) Sym(5); if (Sym(7) != NULL) { AstListNode *tail = (AstListNode *) Sym(7); p -> AllocateForUpdateStatements(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddForUpdateStatement((AstExpressionStatement *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> statement = (AstStatement *) Sym(9); AstBlock *block = ast_pool -> NewBlock(); block -> AllocateBlockStatements(1); // allocate 1 element block -> left_brace_token = Token(1); block -> AddStatement(p); block -> right_brace_token = Sym(9) -> RightToken(); Sym(1) = block; } ./ ForStatementNoShortIf ::= 'for' '(' ForInitopt ';' Expressionopt ';' ForUpdateopt ')' StatementNoShortIf \:$MakeForStatement:\ /.$shared_function // // void MakeForStatement(void); //./ ForInit -> StatementExpressionList \:$NoAction:\ /.$shared_NoAction./ ForInit ::= LocalVariableDeclaration \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *p = AllocateListNode(); p -> next = p; p -> element = Sym(1); p -> index = 0; Sym(1) = p; } ./ ForUpdate -> StatementExpressionList \:$NoAction:\ /.$shared_NoAction./ StatementExpressionList ::= StatementExpression \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *p = AllocateListNode(); p -> next = p; p -> element = Sym(1); p -> index = 0; Sym(1) = p; } ./ StatementExpressionList ::= StatementExpressionList ',' StatementExpression \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *tail = (AstListNode *) Sym(1); AstListNode *p = AllocateListNode(); p -> element = Sym(3); p -> index = tail -> index + 1; p -> next = tail -> next; tail -> next = p; Sym(1) = p; } ./ -- -- NOTE that the rule Identifieropt was expanded in line in the two -- contexts where it appeared: Break and Continue statements. -- This was done because there is no straightforward way of passing -- optional token information in the parse stack. -- BreakStatement ::= 'break' ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBreakStatement *p = ast_pool -> NewBreakStatement(); p -> break_token = Token(1); p -> identifier_token_opt = 0; p -> semicolon_token = Token(2); Sym(1) = p; } ./ BreakStatement ::= 'break' 'Identifier' ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBreakStatement *p = ast_pool -> NewBreakStatement(); p -> break_token = Token(1); p -> identifier_token_opt = Token(2); p -> semicolon_token = Token(3); Sym(1) = p; } ./ ContinueStatement ::= 'continue' ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstContinueStatement *p = ast_pool -> NewContinueStatement(); p -> continue_token = Token(1); p -> identifier_token_opt = 0; p -> semicolon_token = Token(2); Sym(1) = p; } ./ ContinueStatement ::= 'continue' 'Identifier' ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstContinueStatement *p = ast_pool -> NewContinueStatement(); p -> continue_token = Token(1); p -> identifier_token_opt = Token(2); p -> semicolon_token = Token(3); Sym(1) = p; } ./ ReturnStatement ::= 'return' Expressionopt ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstReturnStatement *p = ast_pool -> NewReturnStatement(); p -> return_token = Token(1); p -> expression_opt = (AstExpression *) Sym(2); p -> semicolon_token = Token(3); Sym(1) = p; } ./ ThrowStatement ::= 'throw' Expression ';' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstThrowStatement *p = ast_pool -> NewThrowStatement(); p -> throw_token = Token(1); p -> expression = (AstExpression *) Sym(2); p -> semicolon_token = Token(3); Sym(1) = p; } ./ SynchronizedStatement ::= 'synchronized' '(' Expression ')' Block \:$action:\ /.$location void Parser::Act$rule_number(void) { AstSynchronizedStatement *p = ast_pool -> NewSynchronizedStatement(); p -> synchronized_token = Token(1); p -> expression = (AstExpression *) Sym(3); p -> block = (AstBlock *) Sym(5); Sym(1) = p; } ./ TryStatement ::= 'try' Block Catches \:$action:\ /.$location void Parser::Act$rule_number(void) { AstTryStatement *p = ast_pool -> NewTryStatement(); p -> try_token = Token(1); p -> block = (AstBlock *) Sym(2); // // The list of modifiers is guaranteed not empty // { AstListNode *tail = (AstListNode *) Sym(3); p -> AllocateCatchClauses(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddCatchClause((AstCatchClause *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> finally_clause_opt = NULL; Sym(1) = p; } ./ TryStatement ::= 'try' Block Catchesopt Finally \:$action:\ /.$location void Parser::Act$rule_number(void) { AstTryStatement *p = ast_pool -> NewTryStatement(); p -> try_token = Token(1); p -> block = (AstBlock *) Sym(2); if (Sym(3) != NULL) { AstListNode *tail = (AstListNode *) Sym(3); p -> AllocateCatchClauses(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddCatchClause((AstCatchClause *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> finally_clause_opt = (AstFinallyClause *) Sym(4); Sym(1) = p; } ./ Catches ::= CatchClause \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *p = AllocateListNode(); p -> next = p; p -> element = Sym(1); p -> index = 0; Sym(1) = p; } ./ Catches ::= Catches CatchClause \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *tail = (AstListNode *) Sym(1); AstListNode *p = AllocateListNode(); p -> element = Sym(2); p -> index = tail -> index + 1; p -> next = tail -> next; tail -> next = p; Sym(1) = p; } ./ CatchClause ::= 'catch' '(' FormalParameter ')' Block \:$action:\ /.$location void Parser::Act$rule_number(void) { AstCatchClause *p = ast_pool -> NewCatchClause(); p -> catch_token = Token(1); p -> formal_parameter = (AstFormalParameter *) Sym(3); p -> block = (AstBlock *) Sym(5); Sym(1) = p; } ./ Finally ::= 'finally' Block \:$action:\ /.$location void Parser::Act$rule_number(void) { AstFinallyClause *p = ast_pool -> NewFinallyClause(); p -> finally_token = Token(1); p -> block = (AstBlock *) Sym(2); Sym(1) = p; } ./ --18.12 Productions from 14: Expressions Primary -> PrimaryNoNewArray \:$NoAction:\ /.$shared_NoAction./ Primary -> ArrayCreationExpression \:$NoAction:\ /.$shared_NoAction./ PrimaryNoNewArray -> Literal \:$NoAction:\ /.$shared_NoAction./ PrimaryNoNewArray ::= this \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewThisExpression(Token(1)); } ./ PrimaryNoNewArray ::= '(' Expression ')' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstParenthesizedExpression *p = ast_pool -> NewParenthesizedExpression(); p -> left_parenthesis_token = Token(1); p -> expression = (AstExpression *) Sym(2); p -> right_parenthesis_token = Token(3); Sym(1) = p; } ./ PrimaryNoNewArray -> ClassInstanceCreationExpression \:$NoAction:\ /.$shared_NoAction./ PrimaryNoNewArray -> FieldAccess \:$NoAction:\ /.$shared_NoAction./ --1.1 feature PrimaryNoNewArray ::= Name '.' 'this' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstFieldAccess *p = ast_pool -> NewFieldAccess(AstFieldAccess::THIS_TAG); p -> base = (AstExpression *) Sym(1); p -> dot_token = Token(2); p -> identifier_token = Token(3); Sym(1) = p; } ./ --1.1 feature PrimaryNoNewArray ::= Type '.' 'class' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstFieldAccess *p = ast_pool -> NewFieldAccess(AstFieldAccess::CLASS_TAG); p -> base = ast_pool -> NewTypeExpression(Sym(1)); p -> dot_token = Token(2); p -> identifier_token = Token(3); Sym(1) = p; } ./ --1.1 feature PrimaryNoNewArray ::= 'void' '.' 'class' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstFieldAccess *p = ast_pool -> NewFieldAccess(AstFieldAccess::CLASS_TAG); p -> base = ast_pool -> NewTypeExpression(ast_pool -> NewPrimitiveType(Ast::VOID_TYPE, Token(1))); p -> dot_token = Token(2); p -> identifier_token = Token(3); Sym(1) = p; } ./ PrimaryNoNewArray -> MethodInvocation \:$NoAction:\ /.$shared_NoAction./ PrimaryNoNewArray -> ArrayAccess \:$NoAction:\ /.$shared_NoAction./ --1.1 feature -- -- In Java 1.0 a ClassBody could not appear at all in a -- ClassInstanceCreationExpression. -- ClassInstanceCreationExpression ::= 'new' ClassType '(' ArgumentListopt ')' ClassBodyopt \:$action:\ /.$location void Parser::Act$rule_number(void) { AstClassInstanceCreationExpression *p = ast_pool -> NewClassInstanceCreationExpression(); p -> base_opt = NULL; p -> dot_token_opt = 0; p -> new_token = Token(1); p -> class_type = ast_pool -> NewTypeExpression(Sym(2)); p -> left_parenthesis_token = Token(3); if (Sym(4) != NULL) { AstListNode *tail = (AstListNode *) Sym(4); p -> AllocateArguments(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddArgument((AstExpression *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> right_parenthesis_token = Token(5); p -> class_body_opt = (AstClassBody *) Sym(6); Sym(1) = p; } ./ --1.1 feature ClassInstanceCreationExpression ::= Primary '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt \:$MakeQualifiedNew:\ /.$location void Parser::MakeQualifiedNew(void) { AstClassInstanceCreationExpression *p = ast_pool -> NewClassInstanceCreationExpression(); p -> base_opt = (AstExpression *) Sym(1); p -> dot_token_opt = Token(2); p -> new_token = Token(3); p -> class_type = ast_pool -> NewTypeExpression(Sym(4)); p -> left_parenthesis_token = Token(5); if (Sym(6) != NULL) { AstListNode *tail = (AstListNode *) Sym(6); p -> AllocateArguments(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddArgument((AstExpression *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> right_parenthesis_token = Token(7); p -> class_body_opt = (AstClassBody *) Sym(8); Sym(1) = p; } ./ --1.1 feature ClassInstanceCreationExpression ::= Name '.' 'new' SimpleName '(' ArgumentListopt ')' ClassBodyopt \:$MakeQualifiedNew:\ /.$shared_function // // void MakeQualifiedNew(void); //./ ArgumentList ::= Expression \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *p = AllocateListNode(); p -> next = p; p -> element = Sym(1); p -> index = 0; Sym(1) = p; } ./ ArgumentList ::= ArgumentList ',' Expression \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *tail = (AstListNode *) Sym(1); AstListNode *p = AllocateListNode(); p -> element = Sym(3); p -> index = tail -> index + 1; p -> next = tail -> next; tail -> next = p; Sym(1) = p; } ./ ArrayCreationExpression ::= 'new' PrimitiveType DimExprs Dimsopt \:$MakeArrayCreationExpression:\ /.$location void Parser::MakeArrayCreationExpression(void) { AstArrayCreationExpression *p = ast_pool -> NewArrayCreationExpression(); p -> new_token = Token(1); p -> array_type = Sym(2); // // The list of DimExprs is never null // { AstListNode *tail = (AstListNode *) Sym(3); p -> AllocateDimExprs(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddDimExpr((AstDimExpr *) root -> element); } while(root != tail); FreeCircularList(tail); } if (Sym(4) != NULL) { AstListNode *tail = (AstListNode *) Sym(4); p -> AllocateBrackets(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddBrackets((AstBrackets *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> array_initializer_opt = NULL; Sym(1) = p; } ./ ArrayCreationExpression ::= 'new' ClassOrInterfaceType DimExprs Dimsopt \:$MakeArrayCreationExpression:\ /.$shared_function // // void MakeArrayCreationExpression(void); //./ --1.1 feature ArrayCreationExpression ::= 'new' ArrayType ArrayInitializer \:$action:\ /.$location void Parser::Act$rule_number(void) { AstArrayCreationExpression *p = ast_pool -> NewArrayCreationExpression(); p -> new_token = Token(1); p -> array_type = Sym(2); p -> array_initializer_opt = (AstArrayInitializer *) Sym(3); Sym(1) = p; } ./ DimExprs ::= DimExpr \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *p = AllocateListNode(); p -> next = p; p -> element = Sym(1); p -> index = 0; Sym(1) = p; } ./ DimExprs ::= DimExprs DimExpr \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *tail = (AstListNode *) Sym(1); AstListNode *p = AllocateListNode(); p -> element = Sym(2); p -> index = tail -> index + 1; p -> next = tail -> next; tail -> next = p; Sym(1) = p; } ./ DimExpr ::= '[' Expression ']' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstDimExpr *p = ast_pool -> NewDimExpr(); p -> left_bracket_token = Token(1); p -> expression = (AstExpression *) Sym(2); p -> right_bracket_token = Token(3); Sym(1) = p; } ./ Dims ::= '[' ']' \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *p = AllocateListNode(); p -> next = p; p -> element = ast_pool -> NewBrackets(Token(1), Token(2)); p -> index = 0; Sym(1) = p; } ./ Dims ::= Dims '[' ']' \:$action:\ /.$location // // Note that the list is circular so as to preserve the order of the elements // void Parser::Act$rule_number(void) { AstListNode *tail = (AstListNode *) Sym(1); AstListNode *p = AllocateListNode(); p -> element = ast_pool -> NewBrackets(Token(2), Token(3)); p -> index = tail -> index + 1; p -> next = tail -> next; tail -> next = p; Sym(1) = p; } ./ FieldAccess ::= Primary '.' 'Identifier' \:$MakeFieldAccess:\ /.$shared_function // // void MakeFieldAccess(void); //./ FieldAccess ::= 'super' '.' 'Identifier' \:$MakeSuperFieldAccess:\ /.$location void Parser::MakeSuperFieldAccess(void) { Sym(1) = ast_pool -> NewSuperExpression(Token(1)); MakeFieldAccess(); } ./ --1.2 feature FieldAccess ::= Name '.' 'super' '.' 'Identifier' \:$MakeSuperDoubleFieldAccess:\ /.$location void Parser::MakeSuperDoubleFieldAccess(void) { AstFieldAccess *p = ast_pool -> NewFieldAccess(); AstFieldAccess *q = ast_pool -> NewFieldAccess(AstFieldAccess::SUPER_TAG); q -> base = (AstExpression *) Sym(1); q -> dot_token = Token(2); q -> identifier_token = Token(3); p -> base = q; p -> dot_token = Token(4); p -> identifier_token = Token(5); Sym(1) = p; } ./ MethodInvocation ::= Name '(' ArgumentListopt ')' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstMethodInvocation *p = ast_pool -> NewMethodInvocation(); p -> method = (AstExpression *) Sym(1); p -> left_parenthesis_token = Token(2); if (Sym(3) != NULL) { AstListNode *tail = (AstListNode *) Sym(3); p -> AllocateArguments(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddArgument((AstExpression *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> right_parenthesis_token = Token(4); Sym(1) = p; } ./ MethodInvocation ::= Primary '.' 'Identifier' '(' ArgumentListopt ')' \:$action:\ /.$location void Parser::Act$rule_number(void) { MakeFieldAccess(); AstMethodInvocation *p = ast_pool -> NewMethodInvocation(); p -> method = (AstExpression *) Sym(1); p -> left_parenthesis_token = Token(4); if (Sym(5) != NULL) { AstListNode *tail = (AstListNode *) Sym(5); p -> AllocateArguments(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddArgument((AstExpression *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> right_parenthesis_token = Token(6); Sym(1) = p; } ./ MethodInvocation ::= 'super' '.' 'Identifier' '(' ArgumentListopt ')' \:$action:\ /.$location void Parser::Act$rule_number(void) { MakeSuperFieldAccess(); AstMethodInvocation *p = ast_pool -> NewMethodInvocation(); p -> method = (AstExpression *) Sym(1); p -> left_parenthesis_token = Token(4); if (Sym(5) != NULL) { AstListNode *tail = (AstListNode *) Sym(5); p -> AllocateArguments(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddArgument((AstExpression *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> right_parenthesis_token = Token(6); Sym(1) = p; } ./ --1.2 feature MethodInvocation ::= Name '.' 'super' '.' 'Identifier' '(' ArgumentListopt ')' \:$action:\ /.$location void Parser::Act$rule_number(void) { MakeSuperDoubleFieldAccess(); AstMethodInvocation *p = ast_pool -> NewMethodInvocation(); p -> method = (AstExpression *) Sym(1); p -> left_parenthesis_token = Token(6); if (Sym(7) != NULL) { AstListNode *tail = (AstListNode *) Sym(7); p -> AllocateArguments(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddArgument((AstExpression *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> right_parenthesis_token = Token(8); Sym(1) = p; } ./ ArrayAccess ::= Name '[' Expression ']' \:$MakeArrayAccess:\ /.$location void Parser::MakeArrayAccess(void) { AstArrayAccess *p = ast_pool -> NewArrayAccess(); p -> base = (AstExpression *) Sym(1); p -> left_bracket_token = Token(2); p -> expression = (AstExpression *) Sym(3); p -> right_bracket_token = Token(4); Sym(1) = p; } ./ ArrayAccess ::= PrimaryNoNewArray '[' Expression ']' \:$MakeArrayAccess:\ /.$shared_function // // void MakeArrayAccess(void); //./ PostfixExpression -> Primary \:$NoAction:\ /.$shared_NoAction./ PostfixExpression -> Name \:$NoAction:\ /.$shared_NoAction./ PostfixExpression -> PostIncrementExpression \:$NoAction:\ /.$shared_NoAction./ PostfixExpression -> PostDecrementExpression \:$NoAction:\ /.$shared_NoAction./ PostIncrementExpression ::= PostfixExpression '++' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstPostUnaryExpression *p = ast_pool -> NewPostUnaryExpression(AstPostUnaryExpression::PLUSPLUS); p -> expression = (AstExpression *) Sym(1); p -> post_operator_token = Token(2); Sym(1) = p; } ./ PostDecrementExpression ::= PostfixExpression '--' \:$action:\ /.$location void Parser::Act$rule_number(void) { AstPostUnaryExpression *p = ast_pool -> NewPostUnaryExpression(AstPostUnaryExpression::MINUSMINUS); p -> expression = (AstExpression *) Sym(1); p -> post_operator_token = Token(2); Sym(1) = p; } ./ UnaryExpression -> PreIncrementExpression \:$NoAction:\ /.$shared_NoAction./ UnaryExpression -> PreDecrementExpression \:$NoAction:\ /.$shared_NoAction./ UnaryExpression ::= '+' UnaryExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstPreUnaryExpression *p = ast_pool -> NewPreUnaryExpression(AstPreUnaryExpression::PLUS); p -> pre_operator_token = Token(1); p -> expression = (AstExpression *) Sym(2); Sym(1) = p; } ./ UnaryExpression ::= '-' UnaryExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstPreUnaryExpression *p = ast_pool -> NewPreUnaryExpression(AstPreUnaryExpression::MINUS); p -> pre_operator_token = Token(1); p -> expression = (AstExpression *) Sym(2); Sym(1) = p; } ./ UnaryExpression -> UnaryExpressionNotPlusMinus \:$NoAction:\ /.$shared_NoAction./ PreIncrementExpression ::= '++' UnaryExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstPreUnaryExpression *p = ast_pool -> NewPreUnaryExpression(AstPreUnaryExpression::PLUSPLUS); p -> pre_operator_token = Token(1); p -> expression = (AstExpression *) Sym(2); Sym(1) = p; } ./ PreDecrementExpression ::= '--' UnaryExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstPreUnaryExpression *p = ast_pool -> NewPreUnaryExpression(AstPreUnaryExpression::MINUSMINUS); p -> pre_operator_token = Token(1); p -> expression = (AstExpression *) Sym(2); Sym(1) = p; } ./ UnaryExpressionNotPlusMinus -> PostfixExpression \:$NoAction:\ /.$shared_NoAction./ UnaryExpressionNotPlusMinus ::= '~' UnaryExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstPreUnaryExpression *p = ast_pool -> NewPreUnaryExpression(AstPreUnaryExpression::TWIDDLE); p -> pre_operator_token = Token(1); p -> expression = (AstExpression *) Sym(2); Sym(1) = p; } ./ UnaryExpressionNotPlusMinus ::= '!' UnaryExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstPreUnaryExpression *p = ast_pool -> NewPreUnaryExpression(AstPreUnaryExpression::NOT); p -> pre_operator_token = Token(1); p -> expression = (AstExpression *) Sym(2); Sym(1) = p; } ./ UnaryExpressionNotPlusMinus -> CastExpression \:$NoAction:\ /.$shared_NoAction./ CastExpression ::= '(' PrimitiveType Dimsopt ')' UnaryExpression \:$MakeCastExpression:\ /.$location void Parser::MakeCastExpression(void) { AstCastExpression *p = ast_pool -> NewCastExpression(); p -> left_parenthesis_token_opt = Token(1); p -> type_opt = Sym(2); if (Sym(3) != NULL) { AstListNode *tail = (AstListNode *) Sym(3); p -> AllocateBrackets(tail -> index + 1); AstListNode *root = tail; do { root = root -> next; p -> AddBrackets((AstBrackets *) root -> element); } while(root != tail); FreeCircularList(tail); } p -> right_parenthesis_token_opt = Token(4); p -> expression = (AstExpression *) Sym(5); Sym(1) = p; } ./ CastExpression ::= '(' Expression ')' UnaryExpressionNotPlusMinus \:$action:\ /.$location void Parser::Act$rule_number(void) { // // Note that Expression must be a name - i.e., Sym(2) -> isName() == true // This check is not performed here and should be performed during // semantic processing. // AstCastExpression *p = ast_pool -> NewCastExpression(); p -> left_parenthesis_token_opt = Token(1); p -> type_opt = Sym(2); p -> right_parenthesis_token_opt = Token(3); p -> expression = (AstExpression *) Sym(4); Sym(1) = p; } ./ CastExpression ::= '(' Name Dims ')' UnaryExpressionNotPlusMinus \:$MakeCastExpression:\ /.$shared_function // // void MakeCastExpression(void); //./ MultiplicativeExpression -> UnaryExpression \:$NoAction:\ /.$shared_NoAction./ MultiplicativeExpression ::= MultiplicativeExpression '*' UnaryExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::STAR); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ MultiplicativeExpression ::= MultiplicativeExpression '/' UnaryExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::SLASH); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ MultiplicativeExpression ::= MultiplicativeExpression '%' UnaryExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::MOD); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ AdditiveExpression -> MultiplicativeExpression \:$NoAction:\ /.$shared_NoAction./ AdditiveExpression ::= AdditiveExpression '+' MultiplicativeExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::PLUS); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ AdditiveExpression ::= AdditiveExpression '-' MultiplicativeExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::MINUS); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ ShiftExpression -> AdditiveExpression \:$NoAction:\ /.$shared_NoAction./ ShiftExpression ::= ShiftExpression '<<' AdditiveExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::LEFT_SHIFT); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ ShiftExpression ::= ShiftExpression '>>' AdditiveExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::RIGHT_SHIFT); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ ShiftExpression ::= ShiftExpression '>>>' AdditiveExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::UNSIGNED_RIGHT_SHIFT); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ RelationalExpression -> ShiftExpression \:$NoAction:\ /.$shared_NoAction./ RelationalExpression ::= RelationalExpression '<' ShiftExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::LESS); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ RelationalExpression ::= RelationalExpression '>' ShiftExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::GREATER); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ RelationalExpression ::= RelationalExpression '<=' ShiftExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::LESS_EQUAL); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ RelationalExpression ::= RelationalExpression '>=' ShiftExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::GREATER_EQUAL); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ RelationalExpression ::= RelationalExpression 'instanceof' ReferenceType \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::INSTANCEOF); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = ast_pool -> NewTypeExpression(Sym(3)); Sym(1) = p; } ./ EqualityExpression -> RelationalExpression \:$NoAction:\ /.$shared_NoAction./ EqualityExpression ::= EqualityExpression '==' RelationalExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::EQUAL_EQUAL); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ EqualityExpression ::= EqualityExpression '!=' RelationalExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::NOT_EQUAL); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ AndExpression -> EqualityExpression \:$NoAction:\ /.$shared_NoAction./ AndExpression ::= AndExpression '&' EqualityExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::AND); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ ExclusiveOrExpression -> AndExpression \:$NoAction:\ /.$shared_NoAction./ ExclusiveOrExpression ::= ExclusiveOrExpression '^' AndExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::XOR); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ InclusiveOrExpression -> ExclusiveOrExpression \:$NoAction:\ /.$shared_NoAction./ InclusiveOrExpression ::= InclusiveOrExpression '|' ExclusiveOrExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::IOR); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ ConditionalAndExpression -> InclusiveOrExpression \:$NoAction:\ /.$shared_NoAction./ ConditionalAndExpression ::= ConditionalAndExpression '&&' InclusiveOrExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::AND_AND); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ ConditionalOrExpression -> ConditionalAndExpression \:$NoAction:\ /.$shared_NoAction./ ConditionalOrExpression ::= ConditionalOrExpression '||' ConditionalAndExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstBinaryExpression *p = ast_pool -> NewBinaryExpression(AstBinaryExpression::OR_OR); p -> left_expression = (AstExpression *) Sym(1); p -> binary_operator_token = Token(2); p -> right_expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ ConditionalExpression -> ConditionalOrExpression \:$NoAction:\ /.$shared_NoAction./ ConditionalExpression ::= ConditionalOrExpression '?' Expression ':' ConditionalExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstConditionalExpression *p = ast_pool -> NewConditionalExpression(); p -> test_expression = (AstExpression *) Sym(1); p -> question_token = Token(2); p -> true_expression = (AstExpression *) Sym(3); p -> colon_token = Token(4); p -> false_expression = (AstExpression *) Sym(5); Sym(1) = p; } ./ AssignmentExpression -> ConditionalExpression \:$NoAction:\ /.$shared_NoAction./ AssignmentExpression -> Assignment \:$NoAction:\ /.$shared_NoAction./ Assignment ::= LeftHandSide AssignmentOperator AssignmentExpression \:$action:\ /.$location void Parser::Act$rule_number(void) { AstAssignmentExpression *p = (AstAssignmentExpression *) Sym(2); p -> left_hand_side = (AstExpression *) Sym(1); p -> expression = (AstExpression *) Sym(3); Sym(1) = p; } ./ LeftHandSide -> Name \:$NoAction:\ /.$shared_NoAction./ LeftHandSide -> FieldAccess \:$NoAction:\ /.$shared_NoAction./ LeftHandSide -> ArrayAccess \:$NoAction:\ /.$shared_NoAction./ AssignmentOperator ::= '=' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewAssignmentExpression(AstAssignmentExpression::EQUAL, Token(1)); } ./ AssignmentOperator ::= '*=' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewAssignmentExpression(AstAssignmentExpression::STAR_EQUAL, Token(1)); } ./ AssignmentOperator ::= '/=' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewAssignmentExpression(AstAssignmentExpression::SLASH_EQUAL, Token(1)); } ./ AssignmentOperator ::= '%=' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewAssignmentExpression(AstAssignmentExpression::MOD_EQUAL, Token(1)); } ./ AssignmentOperator ::= '+=' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewAssignmentExpression(AstAssignmentExpression::PLUS_EQUAL, Token(1)); } ./ AssignmentOperator ::= '-=' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewAssignmentExpression(AstAssignmentExpression::MINUS_EQUAL, Token(1)); } ./ AssignmentOperator ::= '<<=' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewAssignmentExpression(AstAssignmentExpression::LEFT_SHIFT_EQUAL, Token(1)); } ./ AssignmentOperator ::= '>>=' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewAssignmentExpression(AstAssignmentExpression::RIGHT_SHIFT_EQUAL, Token(1)); } ./ AssignmentOperator ::= '>>>=' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewAssignmentExpression(AstAssignmentExpression::UNSIGNED_RIGHT_SHIFT_EQUAL, Token(1)); } ./ AssignmentOperator ::= '&=' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewAssignmentExpression(AstAssignmentExpression::AND_EQUAL, Token(1)); } ./ AssignmentOperator ::= '^=' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewAssignmentExpression(AstAssignmentExpression::XOR_EQUAL, Token(1)); } ./ AssignmentOperator ::= '|=' \:$action:\ /.$location void Parser::Act$rule_number(void) { Sym(1) = ast_pool -> NewAssignmentExpression(AstAssignmentExpression::IOR_EQUAL, Token(1)); } ./ Expression -> AssignmentExpression \:$NoAction:\ /.$shared_NoAction./ ConstantExpression -> Expression \:$NoAction:\ /.$shared_NoAction./ --------------------------------------------------------------------------------------- -- -- The following rules are for optional nonterminals. -- --------------------------------------------------------------------------------------- PackageDeclarationopt ::= $empty \:$NullAction:\ /.$location // // Given a rule of the form A ::= x1 x2 ... xn // // Construct a NULL Ast for A. // void Parser::NullAction(void) { Sym(1) = NULL; } ./ PackageDeclarationopt -> PackageDeclaration \:$NoAction:\ /.$shared_NoAction./ Superopt ::= $empty \:$NullAction:\ /.$shared_NullAction./ Superopt -> Super \:$NoAction:\ /.$shared_NoAction./ Expressionopt ::= $empty \:$NullAction:\ /.$shared_NullAction./ Expressionopt -> Expression \:$NoAction:\ /.$shared_NoAction./ --1.1 feature ClassBodyopt ::= $empty \:$NullAction:\ /.$shared_NullAction./ --1.1 feature ClassBodyopt -> ClassBody \:$NoAction:\ /.$shared_NoAction./ --------------------------------------------------------------------------------------- -- -- The rules below are for optional terminal symbols. An optional comma, -- is only used in the context of an array initializer - It is a -- "syntactic sugar" that otherwise serves no other purpose. By contrast, -- an optional identifier is used in the definition of a break and -- continue statement. When the identifier does not appear, a NULL -- is produced. When the identifier is present, the user should use the -- corresponding Token(i) method. See break statement as an example. -- --------------------------------------------------------------------------------------- ,opt ::= $empty \:$NullAction:\ /.$shared_NullAction./ ,opt -> , \:$NoAction:\ /.$shared_NoAction./ ImportDeclarationsopt ::= $empty \:$NullAction:\ /.$shared_NullAction./ ImportDeclarationsopt -> ImportDeclarations \:$NoAction:\ /.$shared_NoAction./ TypeDeclarationsopt ::= $empty \:$NullAction:\ /.$shared_NullAction./ TypeDeclarationsopt -> TypeDeclarations \:$NoAction:\ /.$shared_NoAction./ ClassBodyDeclarationsopt ::= $empty \:$NullAction:\ /.$shared_NullAction./ ClassBodyDeclarationsopt -> ClassBodyDeclarations \:$NoAction:\ /.$shared_NoAction./ Modifiersopt ::= $empty \:$NullAction:\ /.$shared_NullAction./ Modifiersopt -> Modifiers \:$NoAction:\ /.$shared_NoAction./ BlockStatementsopt ::= $empty \:$NullAction:\ /.$shared_NullAction./ BlockStatementsopt -> BlockStatements \:$NoAction:\ /.$shared_NoAction./ Dimsopt ::= $empty \:$NullAction:\ /.$shared_NullAction./ Dimsopt -> Dims \:$NoAction:\ /.$shared_NoAction./ ArgumentListopt ::= $empty \:$NullAction:\ /.$shared_NullAction./ ArgumentListopt -> ArgumentList \:$NoAction:\ /.$shared_NoAction./ Throwsopt ::= $empty \:$NullAction:\ /.$shared_NullAction./ Throwsopt -> Throws \:$NoAction:\ /.$shared_NoAction./ FormalParameterListopt ::= $empty \:$NullAction:\ /.$shared_NullAction./ FormalParameterListopt -> FormalParameterList \:$NoAction:\ /.$shared_NoAction./ Interfacesopt ::= $empty \:$NullAction:\ /.$shared_NullAction./ Interfacesopt -> Interfaces \:$NoAction:\ /.$shared_NoAction./ InterfaceMemberDeclarationsopt ::= $empty \:$NullAction:\ /.$shared_NullAction./ InterfaceMemberDeclarationsopt -> InterfaceMemberDeclarations \:$NoAction:\ /.$shared_NoAction./ ForInitopt ::= $empty \:$NullAction:\ /.$shared_NullAction./ ForInitopt -> ForInit \:$NoAction:\ /.$shared_NoAction./ ForUpdateopt ::= $empty \:$NullAction:\ /.$shared_NullAction./ ForUpdateopt -> ForUpdate \:$NoAction:\ /.$shared_NoAction./ ExtendsInterfacesopt ::= $empty \:$NullAction:\ /.$shared_NullAction./ ExtendsInterfacesopt -> ExtendsInterfaces \:$NoAction:\ /.$shared_NoAction./ Catchesopt ::= $empty \:$NullAction:\ /.$shared_NullAction./ Catchesopt -> Catches \:$NoAction:\ /.$shared_NoAction./ PackageHeaderMarker ::= $empty \:$action:\ /.$location // // When this function is invoked, if the "parse_package_header_only" flag // is turned on, we skip to the end-of-file token. // void Parser::Act$rule_number(void) { if (parse_package_header_only) lex_stream -> Reset(lex_stream -> NumTokens() - 1); // point to the EOF token Sym(1) = NULL; } ./ MethodHeaderMarker ::= $empty \:$action:\ /.$location // // When this function is invoked, if the "parse_header_only" flag // is turned on, the body of the method being parsed is skipped. // void Parser::Act$rule_number(void) { if (parse_header_only) { TokenObject token = Token(1); // // If the first token immediately following the method header // is not an open brace, then we have a syntactic error. Do // nothing and let the error recovery take care of it. // if (lex_stream -> Kind(token) == TK_LBRACE) lex_stream -> Reset(lex_stream -> MatchingBrace(token)); } Sym(1) = NULL; } ./ --------------------------------------------------------------------------------------- \: #ifndef HEADERS return; } #endif :\ $names BodyMarker ::= '"class Identifier { ... MethodHeader "' void ::= ResultType PLUS_PLUS ::= '++' MINUS_MINUS ::= '--' EQUAL_EQUAL ::= '==' LESS_EQUAL ::= '<=' GREATER_EQUAL ::= '>=' NOT_EQUAL ::= '!=' LEFT_SHIFT ::= '<<' RIGHT_SHIFT ::= '>>' UNSIGNED_RIGHT_SHIFT ::= '>>>' PLUS_EQUAL ::= '+=' MINUS_EQUAL ::= '-=' MULTIPLY_EQUAL ::= '*=' DIVIDE_EQUAL ::= '/=' AND_EQUAL ::= '&=' OR_EQUAL ::= '|=' XOR_EQUAL ::= '^=' REMAINDER_EQUAL ::= '%=' LEFT_SHIFT_EQUAL ::= '<<=' RIGHT_SHIFT_EQUAL ::= '>>=' UNSIGNED_RIGHT_SHIFT_EQUAL ::= '>>>=' OR_OR ::= '||' AND_AND ::= '&&' PLUS ::= '+' MINUS ::= '-' NOT ::= '!' REMAINDER ::= '%' XOR ::= '^' AND ::= '&' MULTIPLY ::= '*' OR ::= '|' TWIDDLE ::= '~' DIVIDE ::= '/' GREATER ::= '>' LESS ::= '<' LPAREN ::= '(' RPAREN ::= ')' LBRACE ::= '{' RBRACE ::= '}' LBRACKET ::= '[' RBRACKET ::= ']' SEMICOLON ::= ';' QUESTION ::= '?' COLON ::= ':' COMMA ::= ',' DOT ::= '.' EQUAL ::= '=' $end