import java_cup.runtime.*; import java.io.*; /* MiniJava parser for CUP. * Copyright (C) 2006 Silvano Rivoira * This program is released under the terms of the GPL; see the file * COPYING for more details. There is NO WARRANTY on this code. */ parser code {: public static Scanner s; public static int errors = 0; public static void main(String argv[]) { for (int i = 0; i < argv.length; i++) { try { System.out.println("Parsing ["+argv[i]+"]"); s = new Scanner(new FileReader(argv[i])); mjavac p = new mjavac(s); p.parse(); System.out.println("Number of errors = " + errors + "."); } catch (Exception e) { e.printStackTrace(System.out); System.exit(1); } } } public void report_error(String message, Object info) { if (info instanceof String){ errors++; System.err.println(" "+ errors + "==> " + info + " "+ message + "\n Parsing resumed from 2nd token before" + s.current_lexeme()+"\n"); } else { StringBuffer m = new StringBuffer("Error "); if (info instanceof java_cup.runtime.Symbol) m.append( "("+info.toString()+")" ); m.append(" : "+message); System.err.println(m); } } public void report_fatal_error(String message, Object info) { report_error(message, info); throw new RuntimeException("Fatal Syntax Error"); } :}; terminal BOOLEAN; // primitive_type terminal INT, CHAR, FLOAT; // numeric_type terminal LBRACK, RBRACK; // array_type terminal DOT; // qualified_name terminal SEMICOLON, MULT, COMMA, LBRACE, RBRACE, EQ, LPAREN, RPAREN, COLON; terminal PUBLIC; // modifier terminal CLASS; // class_declaration terminal EXTENDS; // super terminal VOID; // method_header terminal THIS, SUPER; // explicit_constructor_invocation terminal AT; // reference operator terminal IF, ELSE; // if_then_statement, if_then_else_statement terminal WHILE; // while_statement, do_statement terminal RETURN; // return_statement terminal NEW; // class_instance_creation_expression terminal PLUS, MINUS, NOT, DIV, MOD; terminal LT, GT, LTEQ, GTEQ; // relational_expression terminal EQEQ, NOTEQ; // equality_expression terminal ANDAND; // conditional_and_expression terminal OROR; // conditional_or_expression terminal QUESTION; // conditional_expression terminal ILLEGAL_CHARACTER; // illegal_character 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 java.lang.String IDENTIFIER; // name terminal NULL_LITERAL; // 1) The Syntactic Grammar non terminal goal; // 2) Lexical Structure non terminal literal; // 3) Types, Values, and Variables non terminal type, primitive_type, numeric_type; non terminal reference_type; non terminal array_type; // 4) Names non terminal name; // 5) Classes non terminal class_declarations; // 5.1) Class Declaration non terminal class_declaration, sup, super_opt; non terminal class_body, class_body_opt, modifiers_opt; non terminal class_body_declarations, class_body_declarations_opt; non terminal class_body_declaration, class_member_declaration; // 5.2) Field Declarations non terminal field_declaration, variable_declarators, M; non terminal variable_declarator_id; // 5.3) Method Declarations non terminal method_declaration, method_header; non terminal formal_parameter_list_opt, formal_parameter_list; non terminal formal_parameter; non terminal method_body; // 5.4) Constructor Declarations non terminal constructor_declaration, constructor_declarator; non terminal constructor_body; non terminal explicit_constructor_invocation; // 6) Blocks and Statements non terminal block; non terminal block_statements_opt, block_statements, block_statement; non terminal local_variable_declaration_statement; non terminal statement, statement_no_short_if; non terminal statement_without_trailing_substatement; non terminal empty_statement; non terminal expression_statement, statement_expression; non terminal if_then_statement; non terminal if_then_else_statement, if_then_else_statement_no_short_if; non terminal while_statement, while_statement_no_short_if; non terminal return_statement; // 7) Expressions non terminal primary, primary_no_new_array; non terminal class_instance_creation_expression; non terminal argument_list_opt, argument_list; non terminal array_creation_expression; non terminal dim_exprs, dim_expr, dims_opt, dims; non terminal field_access, method_invocation, array_access; non terminal postfix_expression; non terminal unary_expression; non terminal multiplicative_expression, additive_expression; non terminal relational_expression, equality_expression; non terminal conditional_and_expression, conditional_or_expression; non terminal conditional_expression, assignment_expression; non terminal assignment; non terminal left_hand_side; non terminal expression_opt, expression; start with goal; // 1) The Syntactic Grammar goal ::= class_declarations ; // 2) Lexical Structure. literal ::= INTEGER_LITERAL | FLOATING_POINT_LITERAL | BOOLEAN_LITERAL | CHARACTER_LITERAL | STRING_LITERAL | NULL_LITERAL ; // 3) Types, Values, and Variables type ::= primitive_type | reference_type ; primitive_type ::= numeric_type | BOOLEAN ; numeric_type ::= INT | CHAR | FLOAT ; reference_type ::= name | array_type ; array_type ::= primitive_type dims | name dims ; // 4) Names name ::= IDENTIFIER | name DOT IDENTIFIER ; modifiers_opt::= | PUBLIC ; // 5) Classes class_declarations ::= | class_declarations class_declaration | error {: parser.report_error("class_declarations","WRONG"); :} class_declaration ; // 5.1) Class Declaration class_declaration ::= modifiers_opt CLASS IDENTIFIER super_opt class_body ; super_opt ::= | sup ; sup ::= EXTENDS name ; class_body ::= LBRACE class_body_declarations_opt RBRACE ; class_body_declarations_opt ::= | class_body_declarations ; class_body_declarations ::= class_body_declaration | class_body_declarations class_body_declaration ; class_body_declaration ::= class_member_declaration | constructor_declaration | block ; class_member_declaration ::= field_declaration | method_declaration | SEMICOLON ; // 5.2) Field Declarations field_declaration ::= modifiers_opt type variable_declarators SEMICOLON | modifiers_opt type error {: parser.report_error("variable_declarators","WRONG"); :} SEMICOLON | modifiers_opt type error {: parser.report_error("field_declaration","WRONG"); :} method_declaration ; variable_declarators ::= variable_declarator_id | variable_declarators COMMA variable_declarator_id | error {: parser.report_error("variable_declarators","WRONG"); :} COMMA variable_declarator_id ; variable_declarator_id ::= IDENTIFIER | variable_declarator_id LBRACK RBRACK ; // 5.3) Method Declarations method_declaration ::= modifiers_opt method_header method_body ; method_header ::= type IDENTIFIER M LPAREN formal_parameter_list_opt RPAREN | VOID IDENTIFIER M LPAREN formal_parameter_list_opt RPAREN | error {: parser.report_error("method_header","WRONG"); :} LPAREN formal_parameter_list_opt RPAREN ; M ::= ; formal_parameter_list_opt ::= | formal_parameter_list ; formal_parameter_list ::= formal_parameter | formal_parameter_list COMMA formal_parameter | error {: parser.report_error("formal_parameter_list","WRONG"); :} COMMA formal_parameter ; formal_parameter ::= type variable_declarator_id ; method_body ::= block | SEMICOLON ; // 5.4) Constructor Declarations constructor_declaration ::= modifiers_opt constructor_declarator constructor_body ; constructor_declarator ::= IDENTIFIER M LPAREN formal_parameter_list_opt RPAREN ; constructor_body ::= LBRACE explicit_constructor_invocation block_statements RBRACE | LBRACE explicit_constructor_invocation RBRACE | LBRACE block_statements RBRACE | LBRACE RBRACE ; explicit_constructor_invocation ::= THIS LPAREN argument_list_opt RPAREN SEMICOLON | SUPER LPAREN argument_list_opt RPAREN SEMICOLON | primary DOT THIS LPAREN argument_list_opt RPAREN SEMICOLON | primary DOT SUPER LPAREN argument_list_opt RPAREN SEMICOLON ; // 6) Blocks and Statements block ::= LBRACE block_statements_opt RBRACE | LBRACE error {: parser.report_error("block","WRONG"); :} RBRACE ; block_statements_opt ::= | block_statements ; block_statements ::= block_statement | block_statements block_statement | error {: parser.report_error("block_statements","WRONG"); :} block_statement ; block_statement ::= local_variable_declaration_statement | statement ; local_variable_declaration_statement ::= type variable_declarators SEMICOLON | type error {: parser.report_error("local_variable_declaration_statement","WRONG"); :} SEMICOLON ; statement ::= statement_without_trailing_substatement | if_then_statement | if_then_else_statement | while_statement ; statement_no_short_if ::= statement_without_trailing_substatement | if_then_else_statement_no_short_if | while_statement_no_short_if ; statement_without_trailing_substatement ::= block | empty_statement | expression_statement | return_statement ; empty_statement ::= SEMICOLON ; expression_statement ::= statement_expression SEMICOLON ; statement_expression ::= assignment | method_invocation | class_instance_creation_expression ; if_then_statement ::= IF LPAREN expression RPAREN statement | IF error {: parser.report_error("expression","WRONG"); :} RPAREN statement ; if_then_else_statement ::= IF LPAREN expression RPAREN statement_no_short_if ELSE statement | IF LPAREN error {: parser.report_error("expression","WRONG"); :} RPAREN statement_no_short_if ELSE statement ; if_then_else_statement_no_short_if ::= IF LPAREN expression RPAREN statement_no_short_if ELSE statement_no_short_if ; while_statement ::= WHILE LPAREN expression RPAREN statement | WHILE error {: parser.report_error("expression","WRONG"); :} RPAREN statement ; while_statement_no_short_if ::= WHILE LPAREN expression RPAREN statement_no_short_if ; return_statement ::= RETURN expression_opt SEMICOLON ; // 7) Expressions primary ::= primary_no_new_array | array_creation_expression ; primary_no_new_array ::= literal | THIS | LPAREN expression RPAREN | class_instance_creation_expression | field_access | method_invocation | array_access | primitive_type DOT CLASS | VOID DOT CLASS | array_type DOT CLASS | name DOT CLASS | name DOT THIS | LPAREN error {: parser.report_error("primary_no_new_array","WRONG"); :} RPAREN | error {: parser.report_error("primary_no_new_array","WRONG"); :} DOT THIS ; class_instance_creation_expression ::= NEW name LPAREN argument_list_opt RPAREN class_body_opt | primary DOT NEW IDENTIFIER LPAREN argument_list_opt RPAREN class_body_opt ; class_body_opt ::= | class_body ; argument_list_opt ::= | argument_list ; argument_list ::= expression | argument_list COMMA expression | error {: parser.report_error("argument_list","WRONG"); :} expression ; array_creation_expression ::= NEW primitive_type dim_exprs dims_opt | NEW name dim_exprs dims_opt ; dim_exprs ::= dim_expr | dim_exprs dim_expr | error {: parser.report_error("dim_exprs","WRONG"); :} dim_expr ; dim_expr ::= LBRACK expression RBRACK ; dims_opt ::= | dims ; dims ::= LBRACK RBRACK | dims LBRACK RBRACK ; field_access ::= primary DOT IDENTIFIER | SUPER DOT IDENTIFIER | name DOT SUPER DOT IDENTIFIER ; method_invocation ::= name LPAREN argument_list_opt RPAREN | primary DOT IDENTIFIER LPAREN argument_list_opt RPAREN | SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN | name DOT SUPER DOT IDENTIFIER LPAREN argument_list_opt RPAREN ; array_access ::= name LBRACK expression RBRACK | primary_no_new_array LBRACK expression RBRACK ; postfix_expression ::= primary | name | AT name ; unary_expression ::= postfix_expression | NOT unary_expression | PLUS unary_expression | MINUS unary_expression ; multiplicative_expression ::= unary_expression | multiplicative_expression MULT unary_expression | multiplicative_expression DIV unary_expression | multiplicative_expression MOD unary_expression | error {: parser.report_error("multiplicative_expression","WRONG"); :} MULT unary_expression | error {: parser.report_error("multiplicative_expression","WRONG"); :} DIV unary_expression | error {: parser.report_error("multiplicative_expression","WRONG"); :} MOD unary_expression ; additive_expression ::= multiplicative_expression | additive_expression PLUS multiplicative_expression | additive_expression MINUS multiplicative_expression ; relational_expression ::= additive_expression | relational_expression LT additive_expression | relational_expression GT additive_expression | relational_expression LTEQ additive_expression | relational_expression GTEQ additive_expression | error {: parser.report_error("relational_expression","WRONG"); :} LT additive_expression | error {: parser.report_error("relational_expression","WRONG"); :} GT additive_expression | error {: parser.report_error("relational_expression","WRONG"); :} LTEQ additive_expression | error {: parser.report_error("relational_expression","WRONG"); :} GTEQ additive_expression ; equality_expression ::= relational_expression | equality_expression EQEQ relational_expression | equality_expression NOTEQ relational_expression | error {: parser.report_error("equality_expression","WRONG"); :} EQEQ relational_expression | error {: parser.report_error("equality_expression","WRONG"); :} NOTEQ relational_expression ; conditional_and_expression ::= equality_expression | conditional_and_expression ANDAND equality_expression | error {: parser.report_error("conditional_and_expression","WRONG"); :} ANDAND equality_expression ; conditional_or_expression ::= conditional_and_expression | conditional_or_expression OROR conditional_and_expression | error {: parser.report_error("conditional_or_expression","WRONG"); :} OROR conditional_and_expression ; conditional_expression ::= conditional_or_expression | conditional_or_expression QUESTION expression COLON conditional_expression | error {: parser.report_error("conditional_expression","WRONG"); :} QUESTION expression COLON conditional_or_expression ; assignment_expression ::= conditional_expression | assignment ; assignment ::= left_hand_side EQ assignment_expression | error {: parser.report_error("left_hand_side","WRONG"); :} EQ assignment_expression ; left_hand_side ::= name | field_access | array_access ; expression_opt ::= | expression ; expression ::= assignment_expression ;