package Parse; import java_cup.runtime.*; import Lex.Lexer; import IR.Tree.*; /* Java 1.4 parser for CUP. * Copyright (C) 2002-2003 C. Scott Ananian * This program is released under the terms of the GPL; see the file * COPYING for more details. There is NO WARRANTY on this code. */ /* JDK 1.4 Features added: assertion statement. statement_without_trailing_substatement ::= ... | assert_statement ; assert_statement ::= ASSERT expression SEMICOLON | ASSERT expression COLON expression SEMICOLON ; */ parser code {: Lexer lexer; public Parser(Lexer l) { this(); lexer=l; } public void syntax_error(java_cup.runtime.Symbol current) { report_error("Syntax error (" + current.sym + ")", current); } public void report_error(String message, java_cup.runtime.Symbol info) { lexer.errorMsg(message, info); } :}; scan with {: return lexer.nextToken(); :}; terminal BOOLEAN; // primitive_type terminal BYTE, SHORT, INT, LONG, CHAR; // integral_type terminal FLOAT, DOUBLE; // floating_point_type terminal LBRACK, RBRACK; // array_type terminal java.lang.String IDENTIFIER; // name terminal DOT; // qualified_name terminal SEMICOLON, MULT, COMMA, LBRACE, RBRACE, EQ, LPAREN, RPAREN, COLON; terminal PACKAGE; // package_declaration terminal IMPORT; // import_declaration terminal PUBLIC, PROTECTED, PRIVATE; // modifier terminal STATIC; // modifier terminal ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, TRANSIENT, VOLATILE; terminal CLASS; // class_declaration terminal EXTENDS; // super terminal IMPLEMENTS; // interfaces terminal VOID; // method_header terminal THROWS; // throws terminal THIS, SUPER; // explicit_constructor_invocation terminal INTERFACE; // interface_declaration terminal IF, ELSE; // if_then_statement, if_then_else_statement terminal SWITCH; // switch_statement terminal CASE, DEFAULT; // switch_label terminal DO, WHILE; // while_statement, do_statement terminal FOR; // for_statement terminal BREAK; // break_statement terminal CONTINUE; // continue_statement terminal RETURN; // return_statement terminal THROW; // throw_statement terminal TRY; // try_statement terminal CATCH; // catch_clause terminal FINALLY; // finally terminal NEW; // class_instance_creation_expression terminal NEWFLAG; // class_instance_creation_expression terminal PLUSPLUS; // postincrement_expression terminal MINUSMINUS; // postdecrement_expression terminal PLUS, MINUS, COMP, NOT, DIV, MOD; terminal LSHIFT, RSHIFT, URSHIFT; // shift_expression terminal LT, GT, LTEQ, GTEQ, INSTANCEOF; // relational_expression terminal EQEQ, NOTEQ; // equality_expression terminal AND; // and_expression terminal XOR; // exclusive_or_expression terminal OR; // inclusive_or_expression terminal ANDAND; // conditional_and_expression terminal OROR; // conditional_or_expression terminal QUESTION; // conditional_expression terminal MULTEQ, DIVEQ, MODEQ, PLUSEQ, MINUSEQ; // assignment_operator terminal LSHIFTEQ, RSHIFTEQ, URSHIFTEQ; // assignment_operator terminal ANDEQ, XOREQ, OREQ; // assignment_operator terminal AT; // support annotations terminal LOCDEF; // declaration of location hierarchy terminal java.lang.Number INTEGER_LITERAL; terminal java.lang.Number FLOATING_POINT_LITERAL; terminal java.lang.Boolean BOOLEAN_LITERAL; terminal java.lang.Character CHARACTER_LITERAL; terminal java.lang.String STRING_LITERAL; terminal NULL_LITERAL; // Reserved but unused: terminal CONST, GOTO; // strictfp keyword, new in Java 1.2 terminal STRICTFP; // assert keyword, new in Java 1.4 terminal ASSERT; // assert_statement // lexer compatibility with Java 1.5 terminal ELLIPSIS; terminal ENUM; // added for disjoint reachability analysis terminal GENREACH; terminal GEN_DEF_REACH; // 19.2) The Syntactic Grammar non terminal ParseNode goal; // 19.3) Lexical Structure non terminal ParseNode literal; // 19.4) Types, Values, and Variables non terminal ParseNode type, primitive_type, numeric_type; non terminal ParseNode integral_type, floating_point_type; non terminal ParseNode reference_type; non terminal ParseNode class_or_interface_type; non terminal ParseNode class_type; non terminal ParseNode interface_type; non terminal ParseNode array_type; // 19.5) Names non terminal ParseNode name, simple_name, qualified_name; // 19.6) Packages non terminal ParseNode compilation_unit; non terminal ParseNode package_declaration_opt, package_declaration; non terminal ParseNode import_declarations_opt, import_declarations; non terminal ParseNode type_declarations_opt, type_declarations; non terminal ParseNode import_declaration; non terminal ParseNode single_type_import_declaration; non terminal ParseNode type_import_on_demand_declaration; non terminal ParseNode type_declaration; // 19.7) Productions used only in the LALR(1) grammar non terminal ParseNode modifiers_opt, modifiers, modifiers_at, modifier; non terminal ParseNode mixed_modifiers, mixed_modifiers_at; // 19.8.1) Class Declaration non terminal ParseNode class_declaration, super, super_opt; non terminal ParseNode interfaces, interfaces_opt, interface_type_list; non terminal ParseNode class_body; non terminal ParseNode class_body_declarations, class_body_declarations_opt; non terminal ParseNode class_body_declaration, class_member_declaration; // 19.8.2) Field Declarations non terminal ParseNode field_declaration, variable_declarators, variable_declarator; non terminal ParseNode variable_declarator_id; non terminal ParseNode variable_initializer; // 19.8.3) Method Declarations non terminal ParseNode method_declaration, method_header, method_declarator; non terminal ParseNode formal_parameter_list_opt, formal_parameter_list; non terminal ParseNode formal_parameter; non terminal ParseNode throws_opt; non terminal ParseNode throws; non terminal ParseNode class_type_list; non terminal ParseNode method_body; // 19.8.4) Static Initializers non terminal ParseNode static_initializer; // 19.8.5) Constructor Declarations non terminal ParseNode constructor_declaration, constructor_declarator; non terminal ParseNode constructor_body; non terminal ParseNode explicit_constructor_invocation; // 19.9.1) Interface Declarations non terminal ParseNode interface_declaration; //non terminal ParseNode normal_interface_declaration non terminal ParseNode annotation_type_declaration; non terminal ParseNode extends_interfaces_opt, extends_interfaces; non terminal ParseNode interface_body; non terminal ParseNode interface_member_declarations_opt, interface_member_declarations; non terminal ParseNode interface_member_declaration, constant_declaration; non terminal ParseNode abstract_method_declaration; // 19.10) Arrays non terminal ParseNode array_initializer; non terminal ParseNode variable_initializers; // 19.11) Blocks and Statements non terminal ParseNode block; non terminal ParseNode block_statements_opt, block_statements, block_statement; non terminal ParseNode local_variable_declaration_statement, local_variable_declaration; non terminal ParseNode statement, statement_no_short_if; non terminal ParseNode statement_without_trailing_substatement; non terminal ParseNode empty_statement; non terminal ParseNode labeled_statement, labeled_statement_no_short_if; non terminal ParseNode expression_statement, statement_expression; non terminal ParseNode if_then_statement; non terminal ParseNode if_then_else_statement, if_then_else_statement_no_short_if; non terminal ParseNode switch_statement, switch_block; non terminal ParseNode switch_block_statement_groups; non terminal ParseNode switch_block_statement_group; non terminal ParseNode switch_labels, switch_label; non terminal ParseNode while_statement, while_statement_no_short_if; non terminal ParseNode do_statement; non terminal ParseNode for_statement, for_statement_no_short_if; non terminal ParseNode for_init_opt, for_init; non terminal ParseNode for_update_opt, for_update; non terminal ParseNode statement_expression_list; non terminal ParseNode identifier_opt; non terminal ParseNode break_statement, continue_statement; non terminal ParseNode return_statement; non terminal ParseNode throw_statement; non terminal ParseNode synchronized_statement; non terminal ParseNode try_statement; non terminal ParseNode catches_opt; non terminal ParseNode catches, catch_clause; non terminal ParseNode finally; //non terminal ParseNode assert_statement; non terminal ParseNode genreach_statement; non terminal ParseNode gen_def_reach_statement; // 19.12) Expressions non terminal ParseNode primary, primary_no_new_array; non terminal ParseNode class_instance_creation_expression; non terminal ParseNode cons_argument_list_opt, cons_argument_list; non terminal ParseNode argument_list_opt, argument_list; non terminal ParseNode array_creation_init; non terminal ParseNode array_creation_uninit; non terminal ParseNode dim_exprs, dim_expr; non terminal Integer dims_opt, dims; non terminal ParseNode field_access, method_invocation; non terminal ParseNode array_access; non terminal ParseNode postfix_expression; non terminal ParseNode postincrement_expression, postdecrement_expression; non terminal ParseNode unary_expression, unary_expression_not_plus_minus; non terminal ParseNode preincrement_expression, predecrement_expression; non terminal ParseNode cast_expression; non terminal ParseNode multiplicative_expression, additive_expression; non terminal ParseNode shift_expression, relational_expression, equality_expression; non terminal ParseNode and_expression, exclusive_or_expression, inclusive_or_expression; non terminal ParseNode conditional_and_expression, conditional_or_expression; non terminal ParseNode conditional_expression; non terminal ParseNode assignment_expression; non terminal ParseNode assignment; non terminal ParseNode assignment_operator; non terminal ParseNode expression_opt, expression; non terminal ParseNode constant_expression; //failure aware computation keywords terminal FLAG; terminal OPTIONAL; terminal ISAVAILABLE; terminal EXTERNAL; terminal TAG; terminal TASK; terminal TASKEXIT; non terminal ParseNode flag_declaration; non terminal ParseNode task_declaration; non terminal ParseNode task_parameter_list; non terminal ParseNode task_parameter; non terminal ParseNode flag_expression; non terminal ParseNode flag_andexpression; non terminal ParseNode flag_notexpression; non terminal ParseNode task_exitstatement; non terminal ParseNode flag_effects_opt; non terminal ParseNode flag_effects; non terminal ParseNode flag_effect; non terminal ParseNode flag_list; non terminal ParseNode flag_list_opt; non terminal ParseNode flag_change; non terminal ParseNode cons_checks_opt; non terminal ParseNode cons_checks; non terminal ParseNode cons_check; non terminal ParseNode tag_variable_declaration_statement; non terminal ParseNode tag_expression_list; non terminal ParseNode tag_expression; non terminal ParseNode tag_list; non terminal ParseNode tag_list_opt; non terminal ParseNode tag_change; //distributed transaction keywords terminal ATOMIC; terminal GLOBAL; terminal SCRATCH; terminal GETOFFSET; non terminal ParseNode atomic_statement; non terminal ParseNode getoffset_expression; //disjointness for Java terminal DISJOINT; //coarse-grain parallelization terminal SESE; terminal RBLOCK; non terminal ParseNode sese_statement; // mgc // JSR-201) Enum Declaration non terminal ParseNode enum_declaration; non terminal ParseNode enum_body, enum_constants_opt, enum_constants, enum_constant; //non terminal ParseNode enum_arguments_opt, enum_body_declarations_opt; // annotation expressions // non terminal ParseNode annotations_opt, non terminal ParseNode annotations, annotations_at, annotation, annotation_body; non terminal ParseNode normal_annotation_body, marker_annotation_body; non terminal ParseNode single_element_annotation_body; non terminal ParseNode annotation_type_body, annotation_type_element_declarations; non terminal ParseNode annotation_type_element_declarations_opt; non terminal ParseNode annotation_type_element_declaration, default_value_opt, default_value; non terminal ParseNode element_value_pairs_opt, element_value_pairs, element_value_pair; non terminal ParseNode element_values_opt, element_values, element_value, element_value_array_initializer; start with goal; // Task declarations task_declaration ::= TASK IDENTIFIER:id LPAREN task_parameter_list:tpl RPAREN flag_effects_opt:feo method_body:body {: ParseNode pn=new ParseNode("task_declaration",parser.lexer.line_num); pn.addChild("name").addChild(id); pn.addChild(tpl); pn.addChild(feo); pn.addChild("body").addChild(body); RESULT=pn; :}; task_parameter_list ::= task_parameter:fp {: ParseNode pn=new ParseNode("task_parameter_list",parser.lexer.line_num); pn.addChild(fp); RESULT=pn; :} | task_parameter_list:fpl COMMA task_parameter:fp {: fpl.addChild(fp); RESULT=fpl; :} ; task_parameter ::= type:type variable_declarator_id:name LBRACE flag_expression:exp RBRACE {: ParseNode pn=new ParseNode("task_parameter",parser.lexer.line_num); pn.addChild(type); pn.addChild(name); pn.addChild("flag").addChild(exp); RESULT=pn; :} | type:type variable_declarator_id:name LBRACE flag_expression:exp RBRACE LBRACE tag_expression_list:texp RBRACE {: ParseNode pn=new ParseNode("task_parameter",parser.lexer.line_num); pn.addChild(type); pn.addChild(name); pn.addChild("flag").addChild(exp); pn.addChild("tag").addChild(texp); RESULT=pn; :} | type:type variable_declarator_id:name LBRACE RBRACE LBRACE tag_expression_list:texp RBRACE {: ParseNode pn=new ParseNode("task_parameter",parser.lexer.line_num); pn.addChild(type); pn.addChild(name); pn.addChild("tag").addChild(texp); RESULT=pn; :} | OPTIONAL task_parameter:fp {: ParseNode pn=new ParseNode("task_parameter",parser.lexer.line_num); pn.addChild("optional").addChild(fp); RESULT=pn; :} ; tag_expression_list ::= tag_expression:te {: ParseNode pn=new ParseNode("tag_expression_list",parser.lexer.line_num); pn.addChild(te); RESULT=pn; :} | tag_expression_list:tel COMMA tag_expression:te {: tel.addChild(te); RESULT=tel; :} ; tag_expression ::= IDENTIFIER:type IDENTIFIER:id {: ParseNode pn=new ParseNode("tag_expression",parser.lexer.line_num); pn.addChild("type").addChild(type); pn.addChild("single").addChild(id); RESULT=pn; :} ; tag_list_opt ::= LBRACE tag_list:fl RBRACE {:RESULT=fl;:} | LBRACE RBRACE {: RESULT = new ParseNode("empty",parser.lexer.line_num); :} | {: RESULT = new ParseNode("empty",parser.lexer.line_num); :} ; tag_list ::= tag_change:fc {: ParseNode pn=new ParseNode("tag_list",parser.lexer.line_num); pn.addChild(fc); RESULT=pn; :} | tag_list:fl COMMA tag_change:fc {: fl.addChild(fc); RESULT=fl; :}; tag_change ::= IDENTIFIER:id {: RESULT=new ParseNode("name",parser.lexer.line_num).addChild(id).getRoot(); :} | NOT IDENTIFIER:id {: RESULT=new ParseNode("not",parser.lexer.line_num).addChild("name").addChild(id).getRoot(); :}; flag_expression ::= flag_andexpression:exp {: RESULT=exp; :} | flag_expression:exp1 OROR flag_andexpression:exp2 {: ParseNode pn=new ParseNode("or",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} ; flag_andexpression ::= flag_notexpression:exp {: RESULT=exp; :} | flag_notexpression:exp1 ANDAND flag_andexpression:exp2 {: ParseNode pn=new ParseNode("and",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} ; flag_notexpression ::= NOT flag_notexpression:exp {: ParseNode pn=new ParseNode("not",parser.lexer.line_num); pn.addChild(exp); RESULT=pn; :} | LPAREN flag_expression:exp RPAREN {: RESULT=exp; :} | IDENTIFIER:id {: ParseNode pn=new ParseNode("name",parser.lexer.line_num); pn.addChild(id); RESULT=pn; :} ; task_exitstatement ::= TASKEXIT flag_effects_opt:opt cons_checks_opt:cco SEMICOLON {: RESULT=(new ParseNode("taskexit",parser.lexer.line_num)).addChild(opt).getRoot().addChild(cco).getRoot(); :}; cons_checks_opt ::= ASSERT LPAREN cons_checks:cc RPAREN {: RESULT=cc; :} | {: RESULT = new ParseNode("empty",parser.lexer.line_num); :} ; cons_checks ::= cons_check:cc {: ParseNode pn=new ParseNode("cons_checks",parser.lexer.line_num); pn.addChild(cc); RESULT=pn; :} | cons_checks:ccs COMMA cons_check:cc {: ccs.addChild(cc); RESULT=ccs; :}; cons_check ::= IDENTIFIER:name LPAREN cons_argument_list_opt:args RPAREN {: ParseNode pn=new ParseNode("cons_check",parser.lexer.line_num); pn.addChild("name").addChild("identifier").addChild(name); pn.addChild(args); RESULT=pn; :}; flag_effects_opt ::= LPAREN flag_effects:fe RPAREN {:RESULT=fe;:} | {: RESULT = new ParseNode("empty",parser.lexer.line_num); :} ; flag_effects ::= flag_effect:fe {: ParseNode pn=new ParseNode("flag_effects_list",parser.lexer.line_num); pn.addChild(fe); RESULT=pn; :} | flag_effects:fes COMMA flag_effect:fe {: fes.addChild(fe); RESULT=fes; :}; flag_effect ::= IDENTIFIER:id LBRACE flag_list:fl RBRACE tag_list_opt:tlo {: ParseNode pn=new ParseNode("flag_effect",parser.lexer.line_num); pn.addChild("name").addChild(id); pn.addChild(fl); pn.addChild(tlo); RESULT=pn; :} | IDENTIFIER:id LBRACE RBRACE LBRACE tag_list:tl RBRACE {: ParseNode pn=new ParseNode("flag_effect",parser.lexer.line_num); pn.addChild("name").addChild(id); pn.addChild(tl); RESULT=pn; :}; flag_list_opt ::= LBRACE flag_list:fl RBRACE {:RESULT=fl;:} | LBRACE RBRACE {: RESULT = new ParseNode("empty",parser.lexer.line_num); :} | {: RESULT = new ParseNode("empty",parser.lexer.line_num); :} ; flag_list ::= flag_change:fc {: ParseNode pn=new ParseNode("flag_list",parser.lexer.line_num); pn.addChild(fc); RESULT=pn; :} | flag_list:fl COMMA flag_change:fc {: fl.addChild(fc); RESULT=fl; :}; flag_change ::= IDENTIFIER:id {: RESULT=new ParseNode("name",parser.lexer.line_num).addChild(id).getRoot(); :} | NOT IDENTIFIER:id {: RESULT=new ParseNode("not",parser.lexer.line_num).addChild("name").addChild(id).getRoot(); :}; // 19.2) The Syntactic Grammar goal ::= compilation_unit:cu {: RESULT = cu; :} ; // 19.3) Lexical Structure. literal ::= INTEGER_LITERAL:integer_lit {: ParseNode pn=new ParseNode("literal",parser.lexer.line_num); pn.addChild("integer").setLiteral(integer_lit); RESULT=pn; :} | FLOATING_POINT_LITERAL:float_lit {: ParseNode pn=new ParseNode("literal",parser.lexer.line_num); pn.addChild("float").setLiteral(float_lit); RESULT=pn; :} | BOOLEAN_LITERAL:boolean_lit {: ParseNode pn=new ParseNode("literal",parser.lexer.line_num); pn.addChild("boolean").setLiteral(boolean_lit); RESULT=pn; :} | CHARACTER_LITERAL:char_lit {: ParseNode pn=new ParseNode("literal",parser.lexer.line_num); pn.addChild("char").setLiteral(char_lit); RESULT=pn; :} | STRING_LITERAL:string_lit {: ParseNode pn=new ParseNode("literal",parser.lexer.line_num); pn.addChild("string").setLiteral(string_lit); RESULT=pn; :} | NULL_LITERAL {: RESULT=(new ParseNode("literal",parser.lexer.line_num)).addChild("null").getRoot(); :} ; // 19.4) Types, Values, and Variables type ::= primitive_type:type {: RESULT=type; :} | reference_type:type {: RESULT=type; :} ; primitive_type ::= numeric_type:type {: RESULT=type; :} | BOOLEAN {: RESULT=(new ParseNode("type",parser.lexer.line_num)).addChild("boolean").getRoot(); :} ; numeric_type::= integral_type:type {: RESULT=type; :} | floating_point_type:type {: RESULT=type; :} ; integral_type ::= BYTE {: RESULT=(new ParseNode("type",parser.lexer.line_num)).addChild("byte").getRoot(); :} | SHORT {: RESULT=(new ParseNode("type",parser.lexer.line_num)).addChild("short").getRoot(); :} | INT {: RESULT=(new ParseNode("type",parser.lexer.line_num)).addChild("int").getRoot(); :} | LONG {: RESULT=(new ParseNode("type",parser.lexer.line_num)).addChild("long").getRoot(); :} | CHAR {: RESULT=(new ParseNode("type",parser.lexer.line_num)).addChild("char").getRoot(); :} ; floating_point_type ::= FLOAT {: RESULT=(new ParseNode("type",parser.lexer.line_num)).addChild("float").getRoot(); :} | DOUBLE {: RESULT=(new ParseNode("type",parser.lexer.line_num)).addChild("double").getRoot(); :} ; reference_type ::= class_or_interface_type:type {: RESULT=type; :} | array_type:type {: RESULT=type; :} ; class_or_interface_type ::= name:name {: RESULT=(new ParseNode("type",parser.lexer.line_num)).addChild("class").addChild(name).getRoot(); :}; class_type ::= class_or_interface_type:type {: RESULT=type; :}; interface_type ::= class_or_interface_type:type {: RESULT=type; :}; array_type ::= primitive_type:prim dims:dims {: ParseNode pn=(new ParseNode("type",parser.lexer.line_num)).addChild("array"); pn.addChild("basetype").addChild(prim); pn.addChild("dims").setLiteral(dims); RESULT=pn.getRoot(); :} | name:name dims:dims {: ParseNode pn=(new ParseNode("type",parser.lexer.line_num)).addChild("array"); pn.addChild("basetype").addChild("type").addChild("class").addChild(name); pn.addChild("dims").setLiteral(dims); RESULT=pn.getRoot(); :} ; // 19.5) Names name ::= simple_name:name {: RESULT=name; :} | qualified_name:name {: RESULT=name; :} ; simple_name ::= IDENTIFIER:id {: RESULT=(new ParseNode("name",parser.lexer.line_num)).addChild("identifier").addChild(id).getRoot(); :} ; qualified_name ::= name:name DOT IDENTIFIER:id {: ParseNode pn=new ParseNode("name",parser.lexer.line_num); pn.addChild("base").addChild(name); pn.addChild("identifier").addChild(id); RESULT=pn; :} ; // 19.6) Packages compilation_unit ::= package_declaration_opt:pdo import_declarations_opt:ido type_declarations_opt:tdo {: ParseNode pn=new ParseNode("compilation_unit",parser.lexer.line_num); pn.addChild(tdo); pn.addChild("packages").addChild(pdo); pn.addChild("imports").addChild(ido); RESULT=pn; :} ; package_declaration_opt ::= package_declaration:pdo {: RESULT=pdo; :} | {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} ; import_declarations_opt ::= import_declarations:ido {: RESULT=ido; :} | {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} ; type_declarations_opt ::= type_declarations:tds {: RESULT=tds; :} | {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} ; import_declarations ::= import_declaration:id {: ParseNode pn=new ParseNode("import_decls_list",parser.lexer.line_num); pn.addChild(id); RESULT=pn; :} | import_declarations:ids import_declaration:id {: ids.addChild(id); RESULT=ids; :} ; type_declarations ::= type_declaration:td {: ParseNode pn=new ParseNode("type_declaration_list",parser.lexer.line_num); pn.addChild(td); RESULT=pn; :} | type_declarations:tds type_declaration:td {: tds.addChild(td); RESULT=tds; :} ; package_declaration ::= PACKAGE name:name SEMICOLON {: ParseNode pn=new ParseNode("package",parser.lexer.line_num); pn.addChild(name); RESULT=pn; :} ; import_declaration ::= single_type_import_declaration:sid {: RESULT=sid; :} | type_import_on_demand_declaration:iod {: RESULT=iod; :} ; single_type_import_declaration ::= IMPORT name:name SEMICOLON {: ParseNode pn=new ParseNode("import_single",parser.lexer.line_num); pn.addChild(name); RESULT=pn; :} ; type_import_on_demand_declaration ::= IMPORT name:name DOT MULT SEMICOLON {: ParseNode pn=new ParseNode("import_ondemand",parser.lexer.line_num); pn.addChild(name); RESULT=pn; :} ; type_declaration ::= class_declaration:cd {: RESULT=cd; :} | enum_declaration:ed {: RESULT=ed; :} | task_declaration:td {: RESULT=td; :} | interface_declaration:in {: RESULT=in; :} | SEMICOLON {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} ; // 19.7) Productions used only in the LALR(1) grammar modifiers_opt::= {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} | modifiers:mo {: RESULT=mo; :} ; modifiers_at ::= mixed_modifiers_at | annotations_at ; modifiers ::= mixed_modifiers : mmo {: RESULT=mmo; :} | annotations : an {: ParseNode pn=new ParseNode("modifier_list",parser.lexer.line_num); pn.addChild(an); RESULT=pn; :} ; mixed_modifiers_at ::= mixed_modifiers : mmos AT {: RESULT=mmos; :} ; mixed_modifiers ::= modifier : mo {: ParseNode pn=new ParseNode("modifier_list",parser.lexer.line_num); pn.addChild(mo); RESULT=pn; :} | annotations:as modifier:mo {: ParseNode pn=new ParseNode("modifier_list",parser.lexer.line_num); pn.addChild(mo); pn.addChild(as); RESULT=pn; :} | mixed_modifiers : mmos modifier : mo {: mmos.addChild(mo); RESULT=mmos; :} | mixed_modifiers_at:mma annotation_body:ab {: mma.addChild("annotation_list",parser.lexer.line_num).addChild(ab); RESULT=mma; :} ; modifier ::= PUBLIC {: RESULT=new ParseNode("public",parser.lexer.line_num); :}| PROTECTED {: RESULT=new ParseNode("protected",parser.lexer.line_num); :}| PRIVATE {: RESULT=new ParseNode("private",parser.lexer.line_num); :}| STATIC {: RESULT=new ParseNode("static",parser.lexer.line_num); :} | ABSTRACT {: RESULT=new ParseNode("abstract",parser.lexer.line_num); :} | FINAL {: RESULT=new ParseNode("final",parser.lexer.line_num); :}| NATIVE {: RESULT=new ParseNode("native",parser.lexer.line_num); :} | SYNCHRONIZED {: RESULT=new ParseNode("synchronized",parser.lexer.line_num); :} | ATOMIC {: RESULT=new ParseNode("atomic",parser.lexer.line_num); :} | VOLATILE {: RESULT=new ParseNode("volatile",parser.lexer.line_num); :} | TRANSIENT {: RESULT=new ParseNode("transient",parser.lexer.line_num); :} // STRICTFP // note that semantic analysis must check that the // context of the modifier allows strictfp. ; //annotations_opt ::= // {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} // | annotations:an {: // RESULT=an; // :} // ; annotations ::= AT annotation_body:ab {: ParseNode pn=new ParseNode("annotation_list",parser.lexer.line_num); pn.addChild(ab); RESULT=pn; :} | annotations_at:aat annotation_body:ab {: aat.addChild(ab); RESULT=aat; :} ; annotations_at ::= annotations:as AT {: RESULT=as; :} ; annotation ::= AT annotation_body:ab {: RESULT=ab; :} ; annotation_body ::= normal_annotation_body:nab {: ParseNode pn=new ParseNode("annotation_body",parser.lexer.line_num); pn.addChild(nab); RESULT = pn; :} | marker_annotation_body:mab {: ParseNode pn=new ParseNode("annotation_body",parser.lexer.line_num); pn.addChild(mab); RESULT = pn; :} | single_element_annotation_body:seab {: ParseNode pn=new ParseNode("annotation_body",parser.lexer.line_num); pn.addChild(seab); RESULT = pn; :} ; normal_annotation_body ::= IDENTIFIER LPAREN element_value_pairs_opt RPAREN ; marker_annotation_body ::= IDENTIFIER:id {: ParseNode pn=new ParseNode("marker_annotation",parser.lexer.line_num); pn.addChild("name").addChild(id); RESULT=pn; :} ; single_element_annotation_body ::= IDENTIFIER:id LPAREN STRING_LITERAL:ev RPAREN {: ParseNode pn=new ParseNode("single_annotation",parser.lexer.line_num); pn.addChild("name").addChild(id); pn.addChild("element_value").addChild(ev); RESULT=pn; :} ; element_value_pairs_opt ::= | element_value_pairs ; element_value_pairs ::= element_value_pair | element_value_pairs COMMA element_value_pair ; element_value_pair ::= IDENTIFIER EQ element_value ; element_value ::= annotation:an {: RESULT=an; :} | element_value_array_initializer:evai {: RESULT=evai; :} | conditional_expression:ce {: RESULT=ce; :} ; element_value_array_initializer ::= LBRACE element_values_opt RBRACE ; element_values_opt ::= | element_values ; element_values ::= element_value | element_values COMMA element_value ; // 19.8) Classes // 19.8.1) Class Declaration: class_declaration ::= modifiers_opt:mo CLASS IDENTIFIER:id super_opt:so interfaces_opt:ifo class_body:body {: ParseNode pn=new ParseNode("class_declaration",parser.lexer.line_num); pn.addChild("modifiers").addChild(mo); pn.addChild("name").addChild(id); pn.addChild("super").addChild(so); pn.addChild("superIF").addChild(ifo); pn.addChild("classbody").addChild(body); RESULT=pn; :} ; super ::= EXTENDS class_type:classtype {: RESULT=classtype; :} ; super_opt ::= {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} | super:su {: RESULT=su; :} ; interfaces ::= IMPLEMENTS interface_type_list:iftl {: RESULT=iftl; :} ; interfaces_opt ::= {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} | interfaces:ifs {: RESULT=ifs; :} ; interface_type_list ::= interface_type:ift {: ParseNode pn=new ParseNode("interface_type_list",parser.lexer.line_num); pn.addChild(ift); RESULT=pn; :} | interface_type_list:iftl COMMA interface_type:ift {: iftl.addChild(ift); RESULT=iftl; :} ; class_body ::= LBRACE class_body_declarations_opt:cbdo RBRACE {: RESULT=cbdo; :} ; class_body_declarations_opt ::= {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} | class_body_declarations:cbd {: RESULT=cbd; :}; class_body_declarations ::= class_body_declaration:cbd {: ParseNode pn=new ParseNode("class_body_declaration_list",parser.lexer.line_num); pn.addChild(cbd); RESULT=pn; :} | class_body_declarations:cbds class_body_declaration:cbd {: cbds.addChild(cbd); RESULT=cbds; :} ; class_body_declaration ::= class_member_declaration:member {: RESULT=(new ParseNode("member",parser.lexer.line_num)).addChild(member).getRoot(); :} | static_initializer:block{: RESULT=(new ParseNode("static_block",parser.lexer.line_num)).addChild(block).getRoot(); :} | constructor_declaration:constructor {: RESULT=(new ParseNode("constructor",parser.lexer.line_num)).addChild(constructor).getRoot(); :} | block:block {: RESULT=(new ParseNode("block",parser.lexer.line_num)).addChild(block).getRoot(); :} ; class_member_declaration ::= //failure aware computation flag_declaration:flag {: RESULT=(new ParseNode("flag",parser.lexer.line_num)).addChild(flag).getRoot(); :} | field_declaration:field {: RESULT=(new ParseNode("field",parser.lexer.line_num)).addChild(field).getRoot(); :} | method_declaration:method {: RESULT=(new ParseNode("method",parser.lexer.line_num)).addChild(method).getRoot(); :} /* repeat the prod for 'class_declaration' here: */ | modifiers_opt:mo CLASS IDENTIFIER:id super_opt:so interfaces_opt:ifo class_body:body {: ParseNode pn=new ParseNode("inner_class_declaration",parser.lexer.line_num); pn.addChild("modifiers").addChild(mo); pn.addChild("name").addChild(id); pn.addChild("super").addChild(so); pn.addChild("superIF").addChild(ifo); pn.addChild("classbody").addChild(body); RESULT=pn; :} | enum_declaration:ed {: RESULT=ed; :} | interface_declaration:interfaced {: RESULT=interfaced; :} | SEMICOLON {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} ; // mgc // JSR-201) Enum Declaration enum_declaration ::= modifiers_opt:mo ENUM IDENTIFIER:id /*interfaces_opt:io*/ enum_body:body {: ParseNode pn=new ParseNode("enum_declaration",parser.lexer.line_num); pn.addChild("modifiers").addChild(mo); pn.addChild("name").addChild(id); //pn.addChild("superIF").addChild(ifo); pn.addChild("enumbody").addChild(body); RESULT=pn; :} ; enum_body ::= LBRACE enum_constants_opt:eco /*enum_body_declarations_opt:ebdo*/ RBRACE {: RESULT=eco; :} ; enum_constants_opt ::= {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} | enum_constants:ecs {: RESULT=ecs; :} ; enum_constants ::= enum_constant:ec {: ParseNode pn=new ParseNode("enum_constants_list",parser.lexer.line_num); pn.addChild(ec); RESULT=pn; :} | enum_constants:ecs COMMA enum_constant:ec {: ecs.addChild(ec); RESULT=ecs; :} ; enum_constant ::= IDENTIFIER:id /*enum_arguments_opt*/ {: ParseNode pn=new ParseNode("enum_constant",parser.lexer.line_num); pn.addChild("name").addChild(id); RESULT=pn; :} // | IDENTIFIER enum_arguments_opt class_body ; //enum_arguments_opt ::= // | LPAREN argument_list_opt RPAREN // ; //enum_body_declarations_opt ::= // | SEMICOLON class_body_declarations_opt:cbdo // ; //Failure aware computation flag_declaration ::= FLAG IDENTIFIER:id SEMICOLON {: ParseNode pn=new ParseNode("flag_declaration",parser.lexer.line_num); pn.addChild("name").addChild(id); RESULT=pn; :} | EXTERNAL FLAG IDENTIFIER:id SEMICOLON {: ParseNode pn=new ParseNode("flag_declaration",parser.lexer.line_num); pn.addChild("name").addChild(id); pn.addChild("external"); RESULT=pn; :} ; // 19.8.2) Field Declarations field_declaration ::= modifiers_opt:mo type:type variable_declarators:var SEMICOLON {: ParseNode pn=new ParseNode("field_declaration",parser.lexer.line_num); pn.addChild("modifier").addChild(mo); pn.addChild("type").addChild(type); pn.addChild("variables").addChild(var); RESULT=pn; :} | modifiers_opt:mo GLOBAL type:type variable_declarators:var SEMICOLON {: ParseNode pn=new ParseNode("field_declaration",parser.lexer.line_num); pn.addChild("modifier").addChild(mo); pn.addChild("type").addChild(type); pn.addChild("variables").addChild(var); pn.addChild("global"); RESULT=pn; :} ; variable_declarators ::= variable_declarator:vd {: ParseNode pn=new ParseNode("variable_declarators_list",parser.lexer.line_num); pn.addChild(vd); RESULT=pn; :} | variable_declarators:vds COMMA variable_declarator:vd {: vds.addChild(vd); RESULT=vds; :} ; variable_declarator ::= variable_declarator_id:id {: ParseNode pn=new ParseNode("variable_declarator",parser.lexer.line_num); pn.addChild(id); RESULT=pn; :} | variable_declarator_id:id EQ variable_initializer:init {: ParseNode pn=new ParseNode("variable_declarator",parser.lexer.line_num); pn.addChild(id); pn.addChild("initializer").addChild(init); RESULT=pn; :} ; variable_declarator_id ::= IDENTIFIER:id {: RESULT=(new ParseNode("single",parser.lexer.line_num)).addChild(id).getRoot();:} | variable_declarator_id:id LBRACK RBRACK {: RESULT=(new ParseNode("array",parser.lexer.line_num)).addChild(id).getRoot();:} ; variable_initializer ::= expression:exp {: RESULT=exp; :} | array_initializer:ai {: RESULT=(new ParseNode("array_initializer",parser.lexer.line_num)).addChild(ai).getRoot(); :} ; // 19.8.3) Method Declarations method_declaration ::= method_header:header method_body:body {: ParseNode pn=new ParseNode("method_declaration",parser.lexer.line_num); pn.addChild(header); pn.addChild("body").addChild(body); RESULT=pn; :} ; method_header ::= modifiers_opt:mo type:type method_declarator:decl throws_opt:to {: ParseNode pn=new ParseNode("method_header",parser.lexer.line_num); pn.addChild("modifiers").addChild(mo); pn.addChild("returntype").addChild(type); pn.addChild("throws").addChild(to); pn.addChild(decl); RESULT=pn; :} | modifiers_opt:mo VOID method_declarator:decl throws_opt:to {: ParseNode pn=new ParseNode("method_header",parser.lexer.line_num); pn.addChild("modifiers").addChild(mo); pn.addChild("throws").addChild(to); pn.addChild(decl); RESULT=pn; :} ; method_declarator ::= IDENTIFIER:id LPAREN formal_parameter_list_opt:params RPAREN {: ParseNode pn=new ParseNode("method_declarator",parser.lexer.line_num); pn.addChild("name").addChild(id); pn.addChild("parameters").addChild(params); RESULT=pn; :} // | method_declarator LBRACK RBRACK // deprecated // be careful; the above production also allows 'void foo() []' ; formal_parameter_list_opt ::= {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} | formal_parameter_list:fpl {: RESULT=fpl; :} ; formal_parameter_list ::= formal_parameter:fp {: ParseNode pn=new ParseNode("formal_parameter_list",parser.lexer.line_num); pn.addChild(fp); RESULT=pn; :} | formal_parameter_list:fpl COMMA formal_parameter:fp {: fpl.addChild(fp); RESULT=fpl; :} ; formal_parameter ::= type:type variable_declarator_id:name {: ParseNode pn=new ParseNode("formal_parameter",parser.lexer.line_num); pn.addChild(type); pn.addChild(name); RESULT=pn; :} | TAG variable_declarator_id:name {: ParseNode pn=new ParseNode("tag_parameter",parser.lexer.line_num); pn.addChild(name); RESULT=pn; :} | FINAL type:type variable_declarator_id:name {: ParseNode pn=new ParseNode("formal_parameter",parser.lexer.line_num); pn.addChild(type); pn.addChild(name); RESULT=pn; :} | annotations:an type:type variable_declarator_id:name {: ParseNode pn=new ParseNode("annotation_parameter",parser.lexer.line_num); pn.addChild(type); pn.addChild(name); pn.addChild(an); RESULT=pn; :} ; throws_opt ::= {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} | throws:trs {: RESULT=trs; :} ; throws ::= THROWS class_type_list:ctl {: RESULT=(new ParseNode("throw_list",parser.lexer.line_num)).addChild(ctl).getRoot(); :} ; class_type_list ::= class_type:ct {: ParseNode pn=new ParseNode("class_type_list",parser.lexer.line_num); pn.addChild(ct); RESULT=pn; :} | class_type_list:ctl COMMA class_type:ct {: ctl.addChild(ct); RESULT=ctl; :} ; method_body ::= block:block {: RESULT=block; :} | SEMICOLON {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} ; // 19.8.4) Static Initializers static_initializer ::= STATIC block:body {: ParseNode pn=new ParseNode("static_block_declaration",parser.lexer.line_num); pn.addChild("body").addChild(body); RESULT=pn; :} ; // 19.8.5) Constructor Declarations constructor_declaration ::= modifiers_opt:mo constructor_declarator:cd throws_opt:to constructor_body:body {: ParseNode pn=new ParseNode("constructor_declaration",parser.lexer.line_num); pn.addChild("modifiers").addChild(mo); pn.addChild("throws").addChild(to); pn.addChild(cd); pn.addChild("body").addChild(body); RESULT=pn; :} | modifiers_opt:mo GLOBAL constructor_declarator:cd throws_opt:to constructor_body:body {: ParseNode pn=new ParseNode("constructor_declaration",parser.lexer.line_num); pn.addChild("global"); pn.addChild("modifiers").addChild(mo); pn.addChild("throws").addChild(to); pn.addChild(cd); pn.addChild("body").addChild(body); RESULT=pn; :} ; constructor_declarator ::= simple_name:name LPAREN formal_parameter_list_opt:fplo RPAREN {: ParseNode pn=new ParseNode("constructor_declarator",parser.lexer.line_num); pn.addChild(name); pn.addChild("parameters").addChild(fplo); RESULT=pn; :} ; constructor_body ::= LBRACE explicit_constructor_invocation:eci block_statements:bs RBRACE {: ParseNode pn=new ParseNode("constructor_body",parser.lexer.line_num); pn.addChild(eci); pn.addChild(bs); RESULT=pn; :} | LBRACE explicit_constructor_invocation:eci RBRACE {: ParseNode pn=new ParseNode("constructor_body",parser.lexer.line_num); pn.addChild(eci); RESULT=pn; :} | LBRACE block_statements:block RBRACE {: ParseNode pn=new ParseNode("constructor_body",parser.lexer.line_num); pn.addChild(block); RESULT=pn; :} | LBRACE RBRACE {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} ; explicit_constructor_invocation ::= THIS LPAREN argument_list_opt:alo RPAREN SEMICOLON {: ParseNode pn=new ParseNode("explconstrinv",parser.lexer.line_num); pn.addChild(alo); RESULT=pn; :} | SUPER LPAREN argument_list_opt:alo RPAREN SEMICOLON {: ParseNode pn=new ParseNode("superinvoke",parser.lexer.line_num); pn.addChild(alo); RESULT=pn; :} | primary DOT THIS LPAREN argument_list_opt RPAREN SEMICOLON | primary DOT SUPER LPAREN argument_list_opt RPAREN SEMICOLON ; // 19.9) Interfaces // 19.9.1) Interface Declarations interface_declaration ::= modifiers_opt:mo INTERFACE IDENTIFIER:id extends_interfaces_opt:io interface_body:body {: ParseNode pn=new ParseNode("interface_declaration",parser.lexer.line_num); pn.addChild("modifiers").addChild(mo); pn.addChild("name").addChild(id); pn.addChild("superIF").addChild(io); pn.addChild("interfacebody").addChild(body); RESULT=pn; :} | annotation_type_declaration:atd{: RESULT=atd; :} ; extends_interfaces_opt ::= {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} | extends_interfaces:eifs {: RESULT=eifs; :} ; extends_interfaces ::= EXTENDS interface_type:ift {: ParseNode pn=new ParseNode("extend_interface_list",parser.lexer.line_num); pn.addChild(ift); RESULT=pn; :} | extends_interfaces:eifs COMMA interface_type:ift {: eifs.addChild(ift); RESULT=eifs; :} ; interface_body ::= LBRACE interface_member_declarations_opt:imdo RBRACE {: RESULT=imdo; :} ; interface_member_declarations_opt ::= {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} | interface_member_declarations:imd {: RESULT=imd; :} ; interface_member_declarations ::= interface_member_declaration:imd {: ParseNode pn=new ParseNode("interface_member_declaration_list",parser.lexer.line_num); pn.addChild(imd); RESULT=pn; :} | interface_member_declarations:imds interface_member_declaration:imd {: imds.addChild(imd); RESULT=imds; :} ; interface_member_declaration ::= constant_declaration:constant {: RESULT=(new ParseNode("constant",parser.lexer.line_num)).addChild(constant).getRoot(); :} | abstract_method_declaration:method {: RESULT=(new ParseNode("method",parser.lexer.line_num)).addChild(method).getRoot(); :} | enum_declaration:ed {: RESULT=(new ParseNode("enum_declaration",parser.lexer.line_num)).addChild(ed).getRoot(); :} // | class_declaration:class | interface_declaration:interfaced {: RESULT=interfaced; :} | SEMICOLON {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} ; constant_declaration ::= field_declaration:fd {: RESULT=fd; :} // need to semantically check that modifiers of field declaration // include only PUBLIC, STATIC, or FINAL. Other modifiers are // disallowed. ; abstract_method_declaration ::= method_header:header SEMICOLON {: ParseNode pn=new ParseNode("method_declaration",parser.lexer.line_num); pn.addChild("header").addChild(header); pn.addChild("body").addChild(new ParseNode("empty",parser.lexer.line_num)); RESULT=pn; :} ; annotation_type_declaration ::= AT INTERFACE IDENTIFIER:id annotation_type_body:atb{: ParseNode pn=new ParseNode("annotation_type_declaration",parser.lexer.line_num); pn.addChild("name").addChild(id); pn.addChild("body").addChild(atb); RESULT=pn; :} | modifiers_at:ma INTERFACE IDENTIFIER:id annotation_type_body:atb{: ParseNode pn=new ParseNode("annotation_type_declaration",parser.lexer.line_num); pn.addChild("name").addChild(id); pn.addChild("modifiers").addChild(ma); pn.addChild("body").addChild(atb); RESULT=pn; :} ; annotation_type_body ::= LBRACE annotation_type_element_declarations_opt:atedo RBRACE{: RESULT=atedo; :} ; annotation_type_element_declarations_opt ::={: RESULT=new ParseNode("empty",parser.lexer.line_num); :} | annotation_type_element_declarations:ated{: RESULT=ated; :} ; annotation_type_element_declarations ::= annotation_type_element_declaration:ated{: ParseNode pn=new ParseNode("annotation_type_element_list",parser.lexer.line_num); pn.addChild(ated); RESULT=pn; :} | annotation_type_element_declarations:ateds annotation_type_element_declaration:ated{: ateds.addChild(ated); RESULT=ateds; :} ; annotation_type_element_declaration ::= constant_declaration:cd {: RESULT=cd; :} | modifiers_opt:mo type:type IDENTIFIER:id LPAREN RPAREN default_value_opt:dvo SEMICOLON {: ParseNode pn=new ParseNode("annotation_type_element_declaration",parser.lexer.line_num); pn.addChild("modifier").addChild(mo); pn.addChild("type").addChild(type); pn.addChild("name").addChild(id); pn.addChild("defaultvalue").addChild(dvo); RESULT=pn; :} | class_declaration:cd{: RESULT=cd; :} | enum_declaration:ed{: RESULT=ed; :} | interface_declaration:id{: RESULT=id; :} | SEMICOLON{: RESULT=new ParseNode("empty",parser.lexer.line_num); :} ; default_value_opt ::= {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} | default_value:dv{: RESULT=dv; :} ; default_value ::= DEFAULT element_value:ev {: RESULT=ev; :} ; // 19.10) Arrays array_initializer ::= LBRACE variable_initializers:var_init_list COMMA RBRACE {: RESULT=var_init_list; :} | LBRACE variable_initializers:var_init_list RBRACE {: RESULT=var_init_list; :} | LBRACE COMMA RBRACE {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} | LBRACE RBRACE {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} ; variable_initializers ::= variable_initializer:var_init {: ParseNode pn=new ParseNode("var_init_list",parser.lexer.line_num); pn.addChild(var_init); RESULT=pn; :} | variable_initializers:var_init_list COMMA variable_initializer:var_init {: var_init_list.addChild(var_init); RESULT=var_init_list; :} ; // 19.11) Blocks and Statements block ::= LBRACE block_statements_opt:bso RBRACE {: RESULT=bso; :} ; block_statements_opt ::= {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} | block_statements:bs {: RESULT=bs; :} ; block_statements ::= block_statement:bs {: ParseNode pn=new ParseNode("block_statement_list",parser.lexer.line_num); pn.addChild(bs); RESULT=pn; :} | block_statements:bss block_statement:bs {: bss.addChild(bs); RESULT=bss; :} ; block_statement ::= tag_variable_declaration_statement:tvds {: RESULT=tvds; :} | local_variable_declaration_statement:lvds {: RESULT=lvds; :} | statement:statement {: RESULT=statement; :} // | enum_declaration:ed {: // RESULT=ed; // :} // | class_declaration // | interface_declaration ; tag_variable_declaration_statement ::= TAG IDENTIFIER:id EQ NEW TAG LPAREN IDENTIFIER:type RPAREN SEMICOLON {: ParseNode pn=new ParseNode("tag_declaration",parser.lexer.line_num); pn.addChild("single").addChild(id); pn.addChild("type").addChild(type); RESULT=pn; :} ; local_variable_declaration_statement ::= local_variable_declaration:lvd SEMICOLON {: RESULT=lvd; :} ; local_variable_declaration ::= type:type variable_declarators:var {: ParseNode pn=new ParseNode("local_variable_declaration",parser.lexer.line_num); pn.addChild(type); pn.addChild(var); RESULT=pn; :} // | FINAL type:type variable_declarators:var {: /* CAUTION: only FINAL and annotations are legal modifiers here */ | modifiers:mo type:type variable_declarators:var {: ParseNode pn=new ParseNode("local_variable_declaration",parser.lexer.line_num); pn.addChild(type); pn.addChild(var); pn.addChild("modifiers").addChild(mo); RESULT=pn; :} ; statement ::= statement_without_trailing_substatement:st {: RESULT=st; :} | labeled_statement:st {: RESULT=st; :} | if_then_statement:st {: RESULT=st; :} | if_then_else_statement:st {: RESULT=st; :} | while_statement:st {: RESULT=st; :} | for_statement:st {: RESULT=st; :} ; statement_no_short_if ::= statement_without_trailing_substatement:st {: RESULT=st; :} | labeled_statement_no_short_if:st {: RESULT=st; :} | if_then_else_statement_no_short_if:st {: RESULT=st; :} | while_statement_no_short_if:st {: RESULT=st; :} | for_statement_no_short_if:st {: RESULT=st; :} ; statement_without_trailing_substatement ::= block:st {: RESULT=st; :} | empty_statement:st {: RESULT=st; :} | expression_statement:st {: RESULT=st; :} | switch_statement:st {: RESULT=st; :} | do_statement:dos {:RESULT=dos; :} | break_statement:st {: RESULT=st; :} | continue_statement:st {: RESULT=st; :} | return_statement:st {: RESULT=st; :} | task_exitstatement:st {: RESULT=st; :} | atomic_statement:st {: RESULT=st; :} | sese_statement:st {: RESULT=st; :} | synchronized_statement:st {: RESULT=st; :} | genreach_statement:st {: RESULT=st; :} | gen_def_reach_statement:st {: RESULT=st; :} | throw_statement:st {: RESULT=st; :} | try_statement:st {: RESULT=st; :} // | assert_statement ; empty_statement ::= SEMICOLON {: RESULT=new ParseNode("nop",parser.lexer.line_num); :} ; labeled_statement ::= IDENTIFIER:id COLON statement:st {: ParseNode pn=new ParseNode("labeledstatement",parser.lexer.line_num); pn.addChild("name").addChild(id); pn.addChild("statement").addChild(st); RESULT=pn; :} ; labeled_statement_no_short_if ::= IDENTIFIER:id COLON statement_no_short_if:st {: ParseNode pn=new ParseNode("labeledstatement",parser.lexer.line_num); pn.addChild("name").addChild(id); pn.addChild("statement").addChild(st); RESULT=pn; :} ; expression_statement ::= statement_expression:se SEMICOLON {: ParseNode pn=new ParseNode("expression",parser.lexer.line_num); pn.addChild(se); RESULT=pn; :} ; statement_expression ::= assignment:st {: RESULT=st; :} | preincrement_expression:st {: RESULT=st; :} | predecrement_expression:st {: RESULT=st; :} | postincrement_expression:st {: RESULT=st; :} | postdecrement_expression:st {: RESULT=st; :} | method_invocation:st {: RESULT=st; :} | class_instance_creation_expression:st {: RESULT=st; :} ; if_then_statement ::= IF LPAREN expression:exp RPAREN statement:st {: ParseNode pn=new ParseNode("ifstatement",parser.lexer.line_num); pn.addChild("condition").addChild(exp); pn.addChild("statement").addChild(st); RESULT=pn; :} ; if_then_else_statement ::= IF LPAREN expression:exp RPAREN statement_no_short_if:st ELSE statement:else_st {: ParseNode pn=new ParseNode("ifstatement",parser.lexer.line_num); pn.addChild("condition").addChild(exp); pn.addChild("statement").addChild(st); pn.addChild("else_statement").addChild(else_st); RESULT=pn; :} ; if_then_else_statement_no_short_if ::= IF LPAREN expression:exp RPAREN statement_no_short_if:st ELSE statement_no_short_if:else_st {: ParseNode pn=new ParseNode("ifstatement",parser.lexer.line_num); pn.addChild("condition").addChild(exp); pn.addChild("statement").addChild(st); pn.addChild("else_statement").addChild(else_st); RESULT=pn; :} ; switch_statement ::= SWITCH LPAREN expression:exp RPAREN switch_block:body {: ParseNode pn=new ParseNode("switch_statement",parser.lexer.line_num); pn.addChild("condition").addChild(exp); pn.addChild("statement").addChild(body); RESULT=pn; :} ; switch_block ::= LBRACE switch_block_statement_groups:sbsg switch_labels:sl RBRACE {: ParseNode pn = new ParseNode("switch_block",parser.lexer.line_num); pn.addChild("switch_labels").addChild(sl); pn.addChild("switch_statements").addChild(new ParseNode("empty",parser.lexer.line_num)); sbsg.addChild(pn); RESULT=sbsg; :} | LBRACE switch_block_statement_groups:sbsg RBRACE {: RESULT=sbsg; :} | LBRACE switch_labels:sl RBRACE {: ParseNode pnb = new ParseNode("switch_block_list",parser.lexer.line_num); ParseNode pn = new ParseNode("switch_block",parser.lexer.line_num); pn.addChild("switch_labels").addChild(sl); pn.addChild("switch_statements").addChild(new ParseNode("empty",parser.lexer.line_num)); pnb.addChild(pn); RESULT=pnb; :} | LBRACE RBRACE {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} ; switch_block_statement_groups ::= switch_block_statement_group:sbsg {: ParseNode pn = new ParseNode("switch_block_list",parser.lexer.line_num); pn.addChild(sbsg); RESULT=pn; :} | switch_block_statement_groups:sbsgs switch_block_statement_group:sbsg {: sbsgs.addChild(sbsg); RESULT=sbsgs; :} ; switch_block_statement_group ::= switch_labels:sls block_statements:body {: ParseNode pn=new ParseNode("switch_block",parser.lexer.line_num); pn.addChild("switch_labels").addChild(sls); pn.addChild("switch_statements").addChild(body); RESULT=pn; :} ; switch_labels ::= switch_label:sl {: ParseNode pn=new ParseNode("switch_label_list",parser.lexer.line_num); pn.addChild(sl); RESULT=pn; :} | switch_labels:sls switch_label:sl {: sls.addChild(sl); RESULT=sls; :} ; switch_label ::= CASE constant_expression:ce COLON {: ParseNode pn=new ParseNode("switch_label",parser.lexer.line_num); pn.addChild(ce); RESULT=pn; :} | DEFAULT COLON {: RESULT=new ParseNode("default_switch_label",parser.lexer.line_num); :} ; while_statement ::= WHILE LPAREN expression:exp RPAREN statement:st {: ParseNode pn=new ParseNode("whilestatement",parser.lexer.line_num); pn.addChild("condition").addChild(exp); pn.addChild("statement").addChild(st); RESULT=pn; :} ; while_statement_no_short_if ::= WHILE LPAREN expression:exp RPAREN statement_no_short_if:st {: ParseNode pn=new ParseNode("whilestatement",parser.lexer.line_num); pn.addChild("condition").addChild(exp); pn.addChild("statement").addChild(st); RESULT=pn; :} ; do_statement ::= DO statement:st WHILE LPAREN expression:exp RPAREN SEMICOLON {: ParseNode pn=new ParseNode("dowhilestatement",parser.lexer.line_num); pn.addChild("condition").addChild(exp); pn.addChild("statement").addChild(st); RESULT=pn; :} ; for_statement ::= FOR LPAREN for_init_opt:init SEMICOLON expression_opt:exp SEMICOLON for_update_opt:update RPAREN statement:st {: ParseNode pn=new ParseNode("forstatement",parser.lexer.line_num); pn.addChild("initializer").addChild(init); pn.addChild("condition").addChild(exp); pn.addChild("update").addChild(update); pn.addChild("statement").addChild(st); RESULT=pn; :} ; for_statement_no_short_if ::= FOR LPAREN for_init_opt:init SEMICOLON expression_opt:exp SEMICOLON for_update_opt:update RPAREN statement_no_short_if:st {: ParseNode pn=new ParseNode("forstatement",parser.lexer.line_num); pn.addChild("initializer").addChild(init); pn.addChild("condition").addChild(exp); pn.addChild("update").addChild(update); pn.addChild("statement").addChild(st); RESULT=pn; :} ; for_init_opt ::= {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} | for_init:init {: RESULT=init; :} ; for_init ::= statement_expression_list:list {: RESULT=list; :} | local_variable_declaration:decl {: RESULT=decl; :} ; for_update_opt ::= {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} | for_update:update {: RESULT=update; :} ; for_update ::= statement_expression_list:list {: RESULT=list; :} ; statement_expression_list ::= statement_expression:expr {: RESULT=(new ParseNode("statement_expression_list",parser.lexer.line_num)).addChild(expr).getRoot(); :} | statement_expression_list:list COMMA statement_expression:expr {: list.addChild(expr); RESULT=list; :} ; identifier_opt ::= {: RESULT=new ParseNode("identifier_opt",parser.lexer.line_num); :} | IDENTIFIER:id {: ParseNode pn=new ParseNode("identifier_opt",parser.lexer.line_num); pn.addChild("name").addChild(id); RESULT=pn; :} ; break_statement ::= BREAK identifier_opt:id SEMICOLON {: ParseNode pn=new ParseNode("break",parser.lexer.line_num); pn.addChild(id); RESULT=pn; :} ; continue_statement ::= CONTINUE //identifier_opt SEMICOLON {: RESULT=new ParseNode("continue",parser.lexer.line_num); :} ; return_statement ::= RETURN expression_opt:exp SEMICOLON {: RESULT=(new ParseNode("return",parser.lexer.line_num)).addChild(exp).getRoot(); :} ; throw_statement ::= THROW expression:exp SEMICOLON {: RESULT=(new ParseNode("throwstatement",parser.lexer.line_num)).addChild(exp).getRoot(); :} ; synchronized_statement ::= SYNCHRONIZED LPAREN expression:e RPAREN block:b {: ParseNode pn=new ParseNode("synchronized",parser.lexer.line_num); pn.addChild("expr").addChild(e); pn.addChild("block").addChild(b); RESULT=pn; :} ; atomic_statement ::= ATOMIC block:blk {: RESULT=(new ParseNode("atomic",parser.lexer.line_num)).addChild(blk).getRoot(); :} ; sese_statement ::= SESE block:blk {: ParseNode pn = new ParseNode("sese",parser.lexer.line_num); pn.addChild("body").addChild(blk); RESULT=pn; :} | SESE variable_declarator_id:id block:blk {: ParseNode pn = new ParseNode("sese",parser.lexer.line_num); pn.addChild("body").addChild(blk); pn.addChild("identifier").addChild(id); RESULT=pn; :} | RBLOCK block:blk {: ParseNode pn = new ParseNode("sese",parser.lexer.line_num); pn.addChild("body").addChild(blk); RESULT=pn; :} | RBLOCK variable_declarator_id:id block:blk {: ParseNode pn = new ParseNode("sese",parser.lexer.line_num); pn.addChild("body").addChild(blk); pn.addChild("identifier").addChild(id); RESULT=pn; :} ; try_statement ::= TRY block:bk catches:ca {: ParseNode pn=new ParseNode("trycatchstatement",parser.lexer.line_num); pn.addChild("tryblock").addChild(bk); pn.addChild("catchblock").addChild(ca); RESULT=pn; :} | TRY block:bk catches_opt:ca finally:fi {: ParseNode pn=new ParseNode("trycatchstatement",parser.lexer.line_num); pn.addChild("tryblock").addChild(bk); pn.addChild("catchblock").addChild(ca); pn.addChild("finallyblock").addChild(fi); RESULT=pn; :} ; catches_opt ::= {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} | catches:ca {: RESULT=ca; :} ; catches ::= catch_clause:ca {: ParseNode pn=new ParseNode("catchlist",parser.lexer.line_num); pn.addChild(ca); RESULT=pn; :} | catches:cas catch_clause:ca {: cas.addChild(ca); RESULT=cas; :} ; catch_clause ::= CATCH LPAREN formal_parameter:fp RPAREN block:bk {: ParseNode pn=new ParseNode("catchclause",parser.lexer.line_num); pn.addChild("parameter").addChild(fp); pn.addChild("block").addChild(bk); RESULT=pn; :} ; finally ::= FINALLY block:bk {: RESULT=bk; :} ; //assert_statement ::= // ASSERT expression SEMICOLON // | ASSERT expression COLON expression SEMICOLON // ; // 19.12) Expressions primary ::= primary_no_new_array:st {: RESULT=st; :} | array_creation_init:st {: RESULT=st; :} | array_creation_uninit:st {: RESULT=st; :} ; primary_no_new_array ::= literal:lit {: RESULT=lit; :} | THIS {: RESULT=new ParseNode("this",parser.lexer.line_num); :} | LPAREN expression:exp RPAREN {: RESULT=exp; :} | class_instance_creation_expression:exp {: RESULT=exp; :} | field_access:exp {: RESULT=exp; :} | method_invocation:exp {: RESULT=exp; :} | array_access:exp {: RESULT=exp; :} | ISAVAILABLE LPAREN IDENTIFIER:id RPAREN {: ParseNode pn=new ParseNode("isavailable",parser.lexer.line_num); pn.addChild(id); RESULT=pn; :} | primitive_type:pt DOT CLASS {: ParseNode pn=new ParseNode("class_type",parser.lexer.line_num); pn.addChild(pt); RESULT=pn; :} | VOID DOT CLASS {: ParseNode pn=new ParseNode("class_type",parser.lexer.line_num); pn.addChild("type").addChild("void"); RESULT=pn; :} | array_type:at DOT CLASS {: ParseNode pn=new ParseNode("class_type",parser.lexer.line_num); pn.addChild(at); RESULT=pn; :} | name:name DOT CLASS {: ParseNode pn=new ParseNode("class_type",parser.lexer.line_num); pn.addChild("type").addChild("class").addChild(name); RESULT=pn; :} | name:name DOT THIS {: ParseNode pn=new ParseNode("parentclass",parser.lexer.line_num); pn.addChild("name").addChild(name); RESULT=pn; :} ; class_instance_creation_expression ::= NEWFLAG class_or_interface_type:type LPAREN argument_list_opt:args RPAREN flag_list_opt:feo {: ParseNode pn=new ParseNode("createobject",parser.lexer.line_num); pn.addChild(type); pn.addChild(args); pn.addChild(feo); RESULT=pn; :} | NEW class_or_interface_type:type LPAREN argument_list_opt:args RPAREN {: ParseNode pn=new ParseNode("createobject",parser.lexer.line_num); pn.addChild(type); pn.addChild(args); RESULT=pn; :} //Global object | GLOBAL NEW class_or_interface_type:type LPAREN argument_list_opt:args RPAREN {: ParseNode pn=new ParseNode("createobject",parser.lexer.line_num); pn.addChild(type); pn.addChild(args); pn.addChild("global"); RESULT=pn; :} | SCRATCH NEW class_or_interface_type:type LPAREN argument_list_opt:args RPAREN flag_list_opt:feo {: ParseNode pn=new ParseNode("createobject",parser.lexer.line_num); pn.addChild(type); pn.addChild(args); pn.addChild("scratch"); RESULT=pn; :} // Objects we want to track in disjointness analysis | DISJOINT IDENTIFIER:id NEW class_or_interface_type:type LPAREN argument_list_opt:args RPAREN {: ParseNode pn=new ParseNode("createobject",parser.lexer.line_num); pn.addChild(type); pn.addChild(args); pn.addChild("disjoint").addChild(id); RESULT=pn; :} | NEWFLAG class_or_interface_type:type LPAREN argument_list_opt:args RPAREN LBRACE RBRACE LBRACE tag_list:tl RBRACE {: ParseNode pn=new ParseNode("createobject",parser.lexer.line_num); pn.addChild(type); pn.addChild(args); pn.addChild(tl); RESULT=pn; :} | NEWFLAG class_or_interface_type:type LPAREN argument_list_opt:args RPAREN LBRACE flag_list:fl RBRACE LBRACE tag_list:tl RBRACE {: ParseNode pn=new ParseNode("createobject",parser.lexer.line_num); pn.addChild(type); pn.addChild(args); pn.addChild(fl); pn.addChild(tl); RESULT=pn; :} | NEW class_or_interface_type:type LPAREN argument_list_opt:args RPAREN class_body:body {: ParseNode pn=new ParseNode("createobjectcls",parser.lexer.line_num); pn.addChild(type); pn.addChild(args); pn.addChild("decl").addChild("classbody").addChild(body); RESULT=pn; :} | primary: base DOT NEW class_or_interface_type:type LPAREN argument_list_opt:args RPAREN {: ParseNode pn=new ParseNode("createobject",parser.lexer.line_num); pn.addChild(type); pn.addChild(args); pn.addChild( "base" ).addChild( base ); RESULT=pn; :} | primary: base DOT NEW class_or_interface_type:type LPAREN argument_list_opt:args RPAREN class_body:body {: ParseNode pn=new ParseNode("createobjectcls",parser.lexer.line_num); pn.addChild(type); pn.addChild(args); pn.addChild( "base" ).addChild( base ); pn.addChild("decl").addChild("classbody").addChild(body); RESULT=pn; :} | name:id DOT NEW class_or_interface_type:type LPAREN argument_list_opt:args RPAREN {: ParseNode pn=new ParseNode("createobject",parser.lexer.line_num); pn.addChild(type); pn.addChild(args); pn.addChild( "id" ).addChild( id ); RESULT=pn; :} | name:id DOT NEW class_or_interface_type:type LPAREN argument_list_opt:args RPAREN class_body:body {: ParseNode pn=new ParseNode("createobjectcls",parser.lexer.line_num); pn.addChild(type); pn.addChild(args); pn.addChild("decl").addChild("classbody").addChild(body); pn.addChild( "id" ).addChild( id ); RESULT=pn; :} ; cons_argument_list_opt ::= {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} | cons_argument_list:args {: RESULT=args; :} ; cons_argument_list ::= IDENTIFIER:id COLON expression:exp {: ParseNode pn=new ParseNode("cons_argument_list",parser.lexer.line_num); ParseNode pnarg=pn.addChild("binding"); pnarg.addChild("var").addChild(id); pnarg.addChild("exp").addChild(exp); RESULT=pn; :} | argument_list:list COMMA IDENTIFIER:id COLON expression:exp {: ParseNode pnarg=new ParseNode("binding",parser.lexer.line_num); pnarg.addChild("var").addChild(id); pnarg.addChild("exp").addChild(exp); list.addChild(pnarg); RESULT=list; :} ; argument_list_opt ::= {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} | argument_list:args {: RESULT=args; :} ; argument_list ::= expression:exp {: ParseNode pn=new ParseNode("argument_list",parser.lexer.line_num); pn.addChild(exp); RESULT=pn; :} | argument_list:list COMMA expression:exp {: list.addChild(exp); RESULT=list; :} ; array_creation_uninit ::= NEW primitive_type:type dim_exprs:dimexpr dims_opt:dims {: ParseNode pn=new ParseNode("createarray",parser.lexer.line_num); pn.addChild(type); pn.addChild(dimexpr); pn.addChild("dims_opt").setLiteral(dims); RESULT=pn; :} | NEW class_or_interface_type:type dim_exprs:dimexpr dims_opt:dims {: ParseNode pn=new ParseNode("createarray",parser.lexer.line_num); pn.addChild(type); pn.addChild(dimexpr); pn.addChild("dims_opt").setLiteral(dims); RESULT=pn; :} | GLOBAL NEW primitive_type:type dim_exprs:dimexpr dims_opt:dims {: ParseNode pn=new ParseNode("createarray",parser.lexer.line_num); pn.addChild(type); pn.addChild(dimexpr); pn.addChild("dims_opt").setLiteral(dims); pn.addChild("global"); RESULT=pn; :} | SCRATCH NEW primitive_type:type dim_exprs:dimexpr dims_opt:dims {: ParseNode pn=new ParseNode("createarray",parser.lexer.line_num); pn.addChild(type); pn.addChild(dimexpr); pn.addChild("dims_opt").setLiteral(dims); pn.addChild("scratch"); RESULT=pn; :} | DISJOINT IDENTIFIER:id NEW primitive_type:type dim_exprs:dimexpr dims_opt:dims {: ParseNode pn=new ParseNode("createarray",parser.lexer.line_num); pn.addChild(type); pn.addChild(dimexpr); pn.addChild("dims_opt").setLiteral(dims); pn.addChild("disjoint").addChild(id); RESULT=pn; :} | GLOBAL NEW class_or_interface_type:type dim_exprs:dimexpr dims_opt:dims {: ParseNode pn=new ParseNode("createarray",parser.lexer.line_num); pn.addChild(type); pn.addChild(dimexpr); pn.addChild("dims_opt").setLiteral(dims); pn.addChild("global"); RESULT=pn; :} | SCRATCH NEW class_or_interface_type:type dim_exprs:dimexpr dims_opt:dims {: ParseNode pn=new ParseNode("createarray",parser.lexer.line_num); pn.addChild(type); pn.addChild(dimexpr); pn.addChild("dims_opt").setLiteral(dims); pn.addChild("scratch"); RESULT=pn; :} | DISJOINT IDENTIFIER:id NEW class_or_interface_type:type dim_exprs:dimexpr dims_opt:dims {: ParseNode pn=new ParseNode("createarray",parser.lexer.line_num); pn.addChild(type); pn.addChild(dimexpr); pn.addChild("dims_opt").setLiteral(dims); pn.addChild("disjoint").addChild(id); RESULT=pn; :} ; array_creation_init ::= NEW primitive_type:type dims:dims array_initializer:ai {: ParseNode pn=new ParseNode("createarray2",parser.lexer.line_num); pn.addChild(type); pn.addChild("dims_opt").setLiteral(dims); pn.addChild("initializer").addChild(ai); RESULT=pn; :} | NEW class_or_interface_type:type dims:dims array_initializer:ai {: ParseNode pn=new ParseNode("createarray2",parser.lexer.line_num); pn.addChild(type); pn.addChild("dims_opt").setLiteral(dims); pn.addChild("initializer").addChild(ai); RESULT=pn; :} ; dim_exprs ::= dim_expr:exp {: ParseNode pn=new ParseNode("dim_exprs",parser.lexer.line_num); pn.addChild(exp); RESULT=pn; :} | dim_exprs:base dim_expr:exp {: base.addChild(exp); RESULT=base; :} ; dim_expr ::= LBRACK expression:exp RBRACK {: RESULT=exp; :} ; dims_opt ::= {: RESULT=new Integer(0); :} | dims:dims {: RESULT = dims; :} ; dims ::= LBRACK RBRACK {: RESULT=new Integer(1); :} | dims:dims LBRACK RBRACK {: RESULT=new Integer(dims.intValue()+1); :} ; field_access ::= primary:base DOT IDENTIFIER:id {: ParseNode pn=new ParseNode("fieldaccess",parser.lexer.line_num); pn.addChild("base").addChild(base); pn.addChild("field").addChild(id); RESULT=pn; :} | SUPER DOT IDENTIFIER:id {: ParseNode pn=new ParseNode("superfieldaccess",parser.lexer.line_num); pn.addChild("field").addChild(id); RESULT=pn; :} | name:name DOT SUPER DOT IDENTIFIER:id {: ParseNode pn=new ParseNode("supernamefieldaccess",parser.lexer.line_num); pn.addChild("base").addChild(name); pn.addChild("field").addChild(id); RESULT=pn; :} ; method_invocation ::= name:name LPAREN argument_list_opt:args RPAREN {: ParseNode pn=new ParseNode("methodinvoke1",parser.lexer.line_num); pn.addChild(name); pn.addChild(args); RESULT=pn; :} | primary:base DOT IDENTIFIER:name LPAREN argument_list_opt:args RPAREN {: ParseNode pn=new ParseNode("methodinvoke2",parser.lexer.line_num); pn.addChild("base").addChild(base); pn.addChild("id").addChild(name); pn.addChild(args); RESULT=pn; :} | SUPER DOT IDENTIFIER:id LPAREN argument_list_opt:args RPAREN {: ParseNode name=new ParseNode("name",parser.lexer.line_num); name.addChild("base").addChild("name").addChild("identifier").addChild("super"); name.addChild("identifier").addChild(id); ParseNode pn=new ParseNode("methodinvoke1",parser.lexer.line_num); pn.addChild(name); pn.addChild(args); RESULT=pn; :} // | name DOT SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN ; array_access ::= name:name LBRACK expression:exp RBRACK {: ParseNode pn=new ParseNode("arrayaccess",parser.lexer.line_num); pn.addChild("base").addChild(name); pn.addChild("index").addChild(exp); RESULT=pn; :} | primary_no_new_array:base LBRACK expression:exp RBRACK {: ParseNode pn=new ParseNode("arrayaccess",parser.lexer.line_num); pn.addChild("base").addChild(base); pn.addChild("index").addChild(exp); RESULT=pn; :} // | array_creation_init:init LBRACK expression:exp RBRACK {: // ParseNode pn=new ParseNode("arrayaccess",parser.lexer.line_num); // pn.addChild("init").addChild(init); // pn.addChild("index").addChild(exp); // RESULT=pn; // :} ; postfix_expression ::= primary:exp {: RESULT=exp; :} | name:exp {: RESULT=exp; :} | postincrement_expression:exp {: RESULT=exp; :} | postdecrement_expression:exp {: RESULT=exp; :} ; postincrement_expression ::= postfix_expression:exp PLUSPLUS {: RESULT=(new ParseNode("postinc",parser.lexer.line_num)).addChild(exp).getRoot(); :} ; postdecrement_expression ::= postfix_expression:exp MINUSMINUS {: RESULT=(new ParseNode("postdec",parser.lexer.line_num)).addChild(exp).getRoot(); :} ; unary_expression ::= preincrement_expression:exp {: RESULT=exp; :} | predecrement_expression:exp {: RESULT=exp; :} | PLUS unary_expression:exp {: RESULT=(new ParseNode("unaryplus",parser.lexer.line_num)).addChild(exp).getRoot(); :} | MINUS unary_expression:exp {: RESULT=(new ParseNode("unaryminus",parser.lexer.line_num)).addChild(exp).getRoot(); :} | unary_expression_not_plus_minus:exp {: RESULT=exp; :} ; preincrement_expression ::= PLUSPLUS unary_expression:exp {: RESULT=(new ParseNode("preinc",parser.lexer.line_num)).addChild(exp).getRoot(); :} ; predecrement_expression ::= MINUSMINUS unary_expression:exp {: RESULT=(new ParseNode("predec",parser.lexer.line_num)).addChild(exp).getRoot(); :} ; unary_expression_not_plus_minus ::= postfix_expression:exp {: RESULT=exp; :} | COMP unary_expression:exp {: RESULT=(new ParseNode("comp",parser.lexer.line_num)).addChild(exp).getRoot(); :} | NOT unary_expression:exp {: RESULT=(new ParseNode("not",parser.lexer.line_num)).addChild(exp).getRoot(); :} | cast_expression:exp {: RESULT=exp; :} ; cast_expression ::= LPAREN primitive_type:type dims_opt:dims RPAREN unary_expression:exp {: ParseNode pn=new ParseNode("cast1",parser.lexer.line_num); if (dims.intValue()==0) pn.addChild("type").addChild(type); else { ParseNode arrayt=pn.addChild("type").addChild("type").addChild("array"); arrayt.addChild("basetype").addChild(type); arrayt.addChild("dims").setLiteral(dims); } pn.addChild("exp").addChild(exp); RESULT=pn; :} | LPAREN expression:type RPAREN unary_expression_not_plus_minus:exp {: ParseNode pn=new ParseNode("cast2",parser.lexer.line_num); pn.addChild("type").addChild(type); pn.addChild("exp").addChild(exp); RESULT=pn; :} | LPAREN name:name dims:dims RPAREN unary_expression_not_plus_minus:exp {: ParseNode pn=new ParseNode("cast1",parser.lexer.line_num); if (dims.intValue()==0) pn.addChild("type").addChild("class").addChild(name); else { ParseNode arrayt=pn.addChild("type").addChild("type").addChild("array"); arrayt.addChild("basetype").addChild("type").addChild("class").addChild(name); arrayt.addChild("dims").setLiteral(dims); } pn.addChild("exp").addChild(exp); RESULT=pn; :} ; multiplicative_expression ::= unary_expression:exp {: RESULT=exp; :} | multiplicative_expression:exp1 MULT unary_expression:exp2 {: ParseNode pn=new ParseNode("mult",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} | multiplicative_expression:exp1 DIV unary_expression:exp2 {: ParseNode pn=new ParseNode("div",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} | multiplicative_expression:exp1 MOD unary_expression:exp2 {: ParseNode pn=new ParseNode("mod",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} ; additive_expression ::= multiplicative_expression:exp {: RESULT=exp; :} | additive_expression:exp1 PLUS multiplicative_expression:exp2 {: ParseNode pn=new ParseNode("add",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} | additive_expression:exp1 MINUS multiplicative_expression:exp2 {: ParseNode pn=new ParseNode("sub",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} ; shift_expression ::= additive_expression:exp {: RESULT=exp; :} | shift_expression:exp1 LSHIFT additive_expression:exp2 {: ParseNode pn=new ParseNode("leftshift",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} | shift_expression:exp1 RSHIFT additive_expression:exp2 {: ParseNode pn=new ParseNode("rightshift",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} | shift_expression:exp1 URSHIFT additive_expression:exp2 {: ParseNode pn=new ParseNode("urightshift",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} ; relational_expression ::= shift_expression:exp {: RESULT=exp; :} | relational_expression:exp1 LT shift_expression:exp2 {: ParseNode pn=new ParseNode("comp_lt",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} | relational_expression:exp1 GT shift_expression:exp2 {: ParseNode pn=new ParseNode("comp_gt",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} | relational_expression:exp1 LTEQ shift_expression:exp2 {: ParseNode pn=new ParseNode("comp_lte",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} | relational_expression:exp1 GTEQ shift_expression:exp2 {: ParseNode pn=new ParseNode("comp_gte",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} | relational_expression:exp INSTANCEOF reference_type:type {: ParseNode pn=new ParseNode("instanceof",parser.lexer.line_num); pn.addChild("exp").addChild(exp); pn.addChild(type); RESULT=pn; :} ; equality_expression ::= relational_expression:exp {: RESULT=exp; :} | equality_expression:exp1 EQEQ relational_expression:exp2 {: ParseNode pn=new ParseNode("equal",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} | equality_expression:exp1 NOTEQ relational_expression:exp2 {: ParseNode pn=new ParseNode("not_equal",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} ; and_expression ::= equality_expression:exp {: RESULT=exp; :} | and_expression:exp1 AND equality_expression:exp2 {: ParseNode pn=new ParseNode("bitwise_and",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} ; exclusive_or_expression ::= and_expression:expr {: RESULT=expr; :} | exclusive_or_expression:exp1 XOR and_expression:exp2 {: ParseNode pn=new ParseNode("bitwise_xor",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} ; inclusive_or_expression ::= exclusive_or_expression:exclor {: RESULT=exclor; :} | inclusive_or_expression:exp1 OR exclusive_or_expression:exp2 {: ParseNode pn=new ParseNode("bitwise_or",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} ; conditional_and_expression ::= inclusive_or_expression:inclor {: RESULT=inclor; :} | conditional_and_expression:exp1 ANDAND inclusive_or_expression:exp2 {: ParseNode pn=new ParseNode("logical_and",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} ; conditional_or_expression ::= conditional_and_expression:condand {: RESULT=condand; :} | conditional_or_expression:exp1 OROR conditional_and_expression:exp2 {: ParseNode pn=new ParseNode("logical_or",parser.lexer.line_num); pn.addChild(exp1); pn.addChild(exp2); RESULT=pn; :} ; conditional_expression ::= conditional_or_expression:condor {: RESULT=condor; :} | conditional_or_expression:condor QUESTION expression:exptrue COLON conditional_expression:expfalse {: ParseNode pn=new ParseNode("tert",parser.lexer.line_num); pn.addChild("cond").addChild(condor); pn.addChild("trueexpr").addChild(exptrue); pn.addChild("falseexpr").addChild(expfalse); RESULT=pn; :} ; getoffset_expression ::= GETOFFSET LBRACE class_or_interface_type:type COMMA IDENTIFIER:id RBRACE {: ParseNode pn = new ParseNode("getoffset",parser.lexer.line_num); pn.addChild(type); pn.addChild("field").addChild(id); RESULT = pn; :} ; assignment_expression ::= conditional_expression:expr {: RESULT=expr; :} | assignment:assign {: RESULT=assign; :} | getoffset_expression:expr {: RESULT=expr; :} ; // semantic check necessary here to ensure a valid left-hand side. // allowing a parenthesized variable here on the lhs was introduced in // JLS 2; thanks to Eric Blake for pointing this out. assignment ::= postfix_expression:lvalue assignment_operator:op assignment_expression:rvalue {: ParseNode pn=new ParseNode("assignment",parser.lexer.line_num); pn.addChild("op").addChild(op); ParseNode pnargs=pn.addChild("args"); pnargs.addChild(lvalue); pnargs.addChild(rvalue); RESULT=pn; :} ; assignment_operator ::= EQ {: RESULT=new ParseNode("eq",parser.lexer.line_num); :} | MULTEQ {: RESULT=new ParseNode("multeq",parser.lexer.line_num); :} | DIVEQ {: RESULT=new ParseNode("diveq",parser.lexer.line_num); :} | MODEQ {: RESULT=new ParseNode("modeq",parser.lexer.line_num); :} | PLUSEQ {: RESULT=new ParseNode("pluseq",parser.lexer.line_num); :} | MINUSEQ {: RESULT=new ParseNode("minuseq",parser.lexer.line_num); :} | LSHIFTEQ {: RESULT=new ParseNode("lshifteq",parser.lexer.line_num); :} | RSHIFTEQ {: RESULT=new ParseNode("rshifteq",parser.lexer.line_num); :} | URSHIFTEQ {: RESULT=new ParseNode("urshifteq",parser.lexer.line_num); :} | ANDEQ {: RESULT=new ParseNode("andeq",parser.lexer.line_num); :} | XOREQ {: RESULT=new ParseNode("xoreq",parser.lexer.line_num); :} | OREQ {: RESULT=new ParseNode("oreq",parser.lexer.line_num); :} ; expression_opt ::= {: RESULT=new ParseNode("empty",parser.lexer.line_num); :} | expression:exp {: RESULT=exp; :} ; expression ::= assignment_expression:exp {: RESULT=exp; :} ; // note that this constraint must be enforced during semantic checking // 'constant_expression' should include enumerated constants. constant_expression ::= expression:exp {: ParseNode pn = new ParseNode("constant_expression",parser.lexer.line_num); pn.addChild(exp); RESULT=pn; :} ; genreach_statement ::= GENREACH IDENTIFIER:graphName SEMICOLON {: ParseNode pn=new ParseNode("genreach",parser.lexer.line_num); pn.addChild("graphName").addChild(graphName); RESULT=pn; :} ; gen_def_reach_statement ::= GEN_DEF_REACH IDENTIFIER:outputName SEMICOLON {: ParseNode pn=new ParseNode("gen_def_reach",parser.lexer.line_num); pn.addChild("outputName").addChild(outputName); RESULT=pn; :} ;