/** * * Copyright (C) 1996, 1997 Sun Microsystems Inc. * * Use of this file and the system it is part of is constrained by the * file COPYRIGHT in the root directory of this system. You may, however, * make any modifications you wish to this file. * * Java files generated by running JavaCC on this file (or modified versions * of this file) may be used in exactly the same manner as Java files * generated from any grammar developed by you. * * Author: Sriram Sankar * Date: 3/5/97 * * This file contains a Java grammar and actions that implement a front-end. * */ options { JAVA_UNICODE_ESCAPE = true; } PARSER_BEGIN(JavaComponentParser) /** * This class is part of project that implements Aspectual Components * * Author: Predrag Petkovic, predrag@ccs.neu.edu * Northeastern University * * This class parse original component source and write out same * code instrumented in a way that instrumented component is able to be hooked * to the application using deployment map. */ package edu.neu.ccs.aspects.javaCC; import java.util.Vector; import java.io.*; public class JavaComponentParser { public static void main(String args[]) { JavaComponentParser parser; if (args.length == 0) { System.out.println("//Java1.1 Component Parser: Reading from standard input . . ."); parser = new JavaComponentParser(System.in); } else if (args.length == 1 || args.length == 2) { System.out.println("//Java1.1 Component Parser: Reading from file " + args[0] + " . . ."); try { if (args.length == 2) { System.out.println("//Java1.1 Application Parser: Writing to file " + args[1] + " . . ."); setOutputStream(new java.io.FileOutputStream(args[1])); } parser = new JavaComponentParser(new java.io.FileInputStream(args[0])); } catch (java.io.FileNotFoundException e) { System.out.println("//Java1.1 Component Parser: File " + args[0] + " not found."); return; } } else { System.out.println("Java1.1 Component Parser: Usage is one of:"); System.out.println(" java JavaComponentParser < inputfile [> outputfile]"); System.out.println("OR"); System.out.println(" java JavaComponentParser inputfile [outputfile]"); return; } try { parser.CompilationUnit(); System.out.println("//Java Parser Version 1.1: Java program parsed successfully."); } catch (ParseException e) { System.out.println(e.getMessage()); System.out.println("Java Parser Version 1.1: Encountered errors during parse."); } } private static PrintStream out = System.out; public static void setOutputStream(OutputStream o) { out = new PrintStream(o); } public static void write(String s) { out.print(s); } static class Method { String name = ""; String participantName; String resultType = ""; Vector parameterTypes = new Vector(); Vector parameterIds = new Vector(); boolean abstractMethod = false; public String getLongName() { String longName = participantName+name; for (int i=0; i { input_stream.backup(1); } : IN_FORMAL_COMMENT | "/*" : IN_MULTI_LINE_COMMENT } SPECIAL_TOKEN : { {JavaComponentParser.write(image.toString()); }: DEFAULT } SPECIAL_TOKEN : { {JavaComponentParser.write(image.toString()); }: DEFAULT } SPECIAL_TOKEN : { {JavaComponentParser.write(image.toString()); } : DEFAULT } MORE : { < ~[] > } /* RESERVED WORDS AND LITERALS */ TOKEN : { < ABSTRACT: "abstract" > | < BOOLEAN: "boolean" > | < BREAK: "break" > | < BYTE: "byte" > | < CASE: "case" > | < CATCH: "catch" > | < CHAR: "char" > | < CLASS: "class" > | < CONST: "const" > | < CONTINUE: "continue" > | < _DEFAULT: "default" > | < DO: "do" > | < DOUBLE: "double" > | < ELSE: "else" > | < EXTENDS: "extends" > | < FALSE: "false" > | < FINAL: "final" > | < FINALLY: "finally" > | < FLOAT: "float" > | < FOR: "for" > | < GOTO: "goto" > | < IF: "if" > | < IMPLEMENTS: "implements" > | < IMPORT: "import" > | < INSTANCEOF: "instanceof" > | < INT: "int" > | < INTERFACE: "interface" > | < LONG: "long" > | < NATIVE: "native" > | < NEW: "new" > | < NULL: "null" > | < PACKAGE: "package"> | < PRIVATE: "private" > | < PROTECTED: "protected" > | < PUBLIC: "public" > | < RETURN: "return" > | < SHORT: "short" > | < STATIC: "static" > | < SUPER: "super" > | < SWITCH: "switch" > | < SYNCHRONIZED: "synchronized" > | < THIS: "this" > | < THROW: "throw" > | < THROWS: "throws" > | < TRANSIENT: "transient" > | < TRUE: "true" > | < TRY: "try" > | < VOID: "void" > | < VOLATILE: "volatile" > | < WHILE: "while" > } /* LITERALS */ TOKEN : { < INTEGER_LITERAL: (["l","L"])? | (["l","L"])? | (["l","L"])? > | < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* > | < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ > | < #OCTAL_LITERAL: "0" (["0"-"7"])* > | < FLOATING_POINT_LITERAL: (["0"-"9"])+ "." (["0"-"9"])* ()? (["f","F","d","D"])? | "." (["0"-"9"])+ ()? (["f","F","d","D"])? | (["0"-"9"])+ (["f","F","d","D"])? | (["0"-"9"])+ ()? ["f","F","d","D"] > | < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ > | < CHARACTER_LITERAL: "'" ( (~["'","\\","\n","\r"]) | ("\\" ( ["n","t","b","r","f","\\","'","\""] | ["0"-"7"] ( ["0"-"7"] )? | ["0"-"3"] ["0"-"7"] ["0"-"7"] ) ) ) "'" > | < STRING_LITERAL: "\"" ( (~["\"","\\","\n","\r"]) | ("\\" ( ["n","t","b","r","f","\\","'","\""] | ["0"-"7"] ( ["0"-"7"] )? | ["0"-"3"] ["0"-"7"] ["0"-"7"] ) ) )* "\"" > } /* IDENTIFIERS */ TOKEN : { < IDENTIFIER: (|)* > | < #LETTER: [ "\u0024", "\u0041"-"\u005a", "\u005f", "\u0061"-"\u007a", "\u00c0"-"\u00d6", "\u00d8"-"\u00f6", "\u00f8"-"\u00ff", "\u0100"-"\u1fff", "\u3040"-"\u318f", "\u3300"-"\u337f", "\u3400"-"\u3d2d", "\u4e00"-"\u9fff", "\uf900"-"\ufaff" ] > | < #DIGIT: [ "\u0030"-"\u0039", "\u0660"-"\u0669", "\u06f0"-"\u06f9", "\u0966"-"\u096f", "\u09e6"-"\u09ef", "\u0a66"-"\u0a6f", "\u0ae6"-"\u0aef", "\u0b66"-"\u0b6f", "\u0be7"-"\u0bef", "\u0c66"-"\u0c6f", "\u0ce6"-"\u0cef", "\u0d66"-"\u0d6f", "\u0e50"-"\u0e59", "\u0ed0"-"\u0ed9", "\u1040"-"\u1049" ] > } /* SEPARATORS */ TOKEN : { < LPAREN: "(" > | < RPAREN: ")" > | < LBRACE: "{" > | < RBRACE: "}" > | < LBRACKET: "[" > | < RBRACKET: "]" > | < SEMICOLON: ";" > | < COMMA: "," > | < DOT: "." > } /* OPERATORS */ TOKEN : { < ASSIGN: "=" > | < GT: ">" > | < LT: "<" > | < BANG: "!" > | < TILDE: "~" > | < HOOK: "?" > | < COLON: ":" > | < EQ: "==" > | < LE: "<=" > | < GE: ">=" > | < NE: "!=" > | < SC_OR: "||" > | < SC_AND: "&&" > | < INCR: "++" > | < DECR: "--" > | < PLUS: "+" > | < MINUS: "-" > | < STAR: "*" > | < SLASH: "/" > | < BIT_AND: "&" > | < BIT_OR: "|" > | < XOR: "^" > | < REM: "%" > | < LSHIFT: "<<" > | < RSIGNEDSHIFT: ">>" > | < RUNSIGNEDSHIFT: ">>>" > | < PLUSASSIGN: "+=" > | < MINUSASSIGN: "-=" > | < STARASSIGN: "*=" > | < SLASHASSIGN: "/=" > | < ANDASSIGN: "&=" > | < ORASSIGN: "|=" > | < XORASSIGN: "^=" > | < REMASSIGN: "%=" > | < LSHIFTASSIGN: "<<=" > | < RSIGNEDSHIFTASSIGN: ">>=" > | < RUNSIGNEDSHIFTASSIGN: ">>>=" > } /***************************************** * THE JAVA LANGUAGE GRAMMAR STARTS HERE * *****************************************/ /* * Program structuring syntax follows. */ void CompilationUnit() : {} { [ PackageDeclaration() ] ( ImportDeclaration() )* ( TypeDeclaration() )* } void PackageDeclaration() : {} { "package" {write("package"); } Name() {write(""); } ";" {write(";"); } } void ImportDeclaration() : {} { "import" {write("import"); } Name() [ "." {write("."); } "*" {write("*"); } ] ";" {write(";"); } } void TypeDeclaration() : {} { LOOKAHEAD( ( "abstract" | "final" | "public" )* "class" ) ClassDeclaration() | InterfaceDeclaration() | ";" {write(";"); } } /* * Declaration syntax follows. */ void ClassDeclaration() : { boolean prevValue = isClass; nestingLevel++; isClass = true; } { ( "abstract" {/* ignore abstract*/ } | "final" {write("final "); } | "public" {write("public "); } )* UnmodifiedClassDeclaration() {nestingLevel--; isClass = prevValue; } } void UnmodifiedClassDeclaration() : {Token t;} { "class" {write("class"); } t= {write(t.image); if (nestingLevel == 1) componentName = t.image; else if (nestingLevel == 2) { participantName = t.image; if (publicClass) participants.add(participantName); } } [ "extends" {write("extends"); } Name() ] { if (nestingLevel == 1) writeImplementComponent(); } [ "implements" {write("implements"); } NameList() ] ClassBody() } void ClassBody() : {} { "{" {write("{"); } ( ClassBodyDeclaration() )* "}" {if (nestingLevel == 1) addCodeToComponent(); write("}"); } } void NestedClassDeclaration() : { boolean prevValue = isClass; boolean prevPublic = publicClass; publicClass = false; nestingLevel++; isClass = true; } { ( "static" {write("static "); } | "abstract" {if (nestingLevel == 2) /*ignore*/; else write("abstract "); } | "final" {write("final "); } | "public" {write("public "); publicClass = true;} | "protected" {write("protected "); } | "private" {write("private "); } )* UnmodifiedClassDeclaration() {nestingLevel--; isClass = prevValue; publicClass = prevPublic; } } void ClassBodyDeclaration() : {} { LOOKAHEAD(2) Initializer() | LOOKAHEAD( ( "static" | "abstract" | "final" | "public" | "protected" | "private" )* "class" ) NestedClassDeclaration() | LOOKAHEAD( ( "static" | "abstract" | "final" | "public" | "protected" | "private" )* "interface" ) NestedInterfaceDeclaration() | LOOKAHEAD( [ "public" | "protected" | "private" ] Name() "(" ) ConstructorDeclaration() | LOOKAHEAD( MethodDeclarationLookahead() ) MethodDeclaration() | FieldDeclaration() } // This production is to determine lookahead only. void MethodDeclarationLookahead() : {} { ( "public" | "protected" | "private" | "static" | "abstract" | "final" | "native" | "synchronized" )* ResultType() "(" } void InterfaceDeclaration() : { boolean prevValue = isClass; nestingLevel++; isClass = false; } { ( "abstract" {write("abstract "); } | "public" {write("public "); } )* UnmodifiedInterfaceDeclaration() {nestingLevel--; isClass = prevValue; } } void NestedInterfaceDeclaration() : { boolean prevValue = isClass; nestingLevel++; isClass = false; } { ( "static" {write("static "); } | "abstract" {write("abstract "); } | "final" {write("final "); } | "public" {write("public "); } | "protected" {write("protected "); } | "private" {write("private "); } )* UnmodifiedInterfaceDeclaration() {nestingLevel--; isClass = prevValue; } } void UnmodifiedInterfaceDeclaration() : {Token t;} { "interface" {write("interface"); } t= {write(t.image); } [ "extends" {write("extends"); } NameList() ] "{" {write("{"); } ( InterfaceMemberDeclaration() )* "}" {write("}"); } } void InterfaceMemberDeclaration() : {} { LOOKAHEAD( ( "static" | "abstract" | "final" | "public" | "protected" | "private" )* "class" ) NestedClassDeclaration() | LOOKAHEAD( ( "static" | "abstract" | "final" | "public" | "protected" | "private" )* "interface" ) NestedInterfaceDeclaration() | LOOKAHEAD( MethodDeclarationLookahead() ) MethodDeclaration() | FieldDeclaration() } void FieldDeclaration() : {} { ( "public" {write("public "); } | "protected" {write("protected "); } | "private" {write("private "); } | "static" {write("static "); } | "final" {write("final "); } | "transient" {write("transient "); } | "volatile" {write("volatile "); } )* Type() VariableDeclarator() ( "," {write(","); } VariableDeclarator() )* ";" {write(";"); } } void VariableDeclarator() : {} { VariableDeclaratorId() [ "=" {write("="); } VariableInitializer() ] } String VariableDeclaratorId() : {Token t; String s = "";} { t= {write(" " + t.image); s += t.image; } ( "[" {write("["); } "]" {write("]"); } )* {return s;} } void VariableInitializer() : {} { ArrayInitializer() | Expression() } void ArrayInitializer() : {} { "{" {write("{"); } [ VariableInitializer() ( LOOKAHEAD(2) "," {write(","); } VariableInitializer() )* ] [ "," {write(","); } ] "}" {write("}"); } } void MethodDeclaration() : {currentMethod = new Method(); currentMethod.participantName = participantName; } { ( "public" {write("public "); } | "protected" {write("protected "); } | "private" {write("private "); } | "static" {write("static "); } | "abstract" {if (!(isClass && ((nestingLevel == 2 && publicClass) || nestingLevel == 1))) write("abstract "); } | "final" {write("final "); } | "native" {write("native "); } | "synchronized" {write("synchronized "); } )* currentMethod.resultType = ResultType() MethodDeclarator() [ "throws" {write("throws"); } NameList() ] ( Block() | ";" {if (isClass && publicClass && nestingLevel == 2) { currentMethod.writeExpected(); methods.add(currentMethod); } else if (isClass && nestingLevel == 1 && currentMethod.name.equals("getHost")) writeGetHost(); else write(";"); } ) } void MethodDeclarator() : {Token t;} { t= {write(" " + t.image); currentMethod.name = t.image;} FormalParameters() ( "[" {write("["); } "]" {write("]"); } )* } void FormalParameters() : {} { "(" {write("("); } [ FormalParameter() ( "," {write(","); } FormalParameter() )* ] ")" {write(")"); } } void FormalParameter() : {String type = ""; String id; String t = "";} { [ "final" {write("final"); type += "final ";} ] t = Type() {type += t; currentMethod.parameterTypes.add(type); } id = VariableDeclaratorId(){currentMethod.parameterIds.add(id); } } void ConstructorDeclaration() : {Token t;} { [ "public" {write("public "); } | "protected" {write("protected "); } | "private" {write("private "); } ] t= {write(t.image); } FormalParameters() [ "throws" {write("throws"); } NameList() ] "{" {write("{"); } [ LOOKAHEAD(ExplicitConstructorInvocation()) ExplicitConstructorInvocation() ] ( BlockStatement() )* "}" {write("}"); } } void ExplicitConstructorInvocation() : {} { LOOKAHEAD("this" Arguments() ";") "this" {write("this"); } Arguments() ";" {write(";"); } | [ LOOKAHEAD(2) PrimaryExpression() "." {write("."); } ] "super" {write("super"); } Arguments() ";" {write(";"); } } void Initializer() : {} { [ "static" {write("static"); } ] Block() } /* * Type, name and expression syntax follows. */ String Type() : {String s;} { ( s = PrimitiveType() | s = Name() ) ( "[" {write("["); s += "[";} "]" {write("]"); s += "]";} )* { return s; } } String PrimitiveType() : {String s; } { "boolean" {write("boolean"); return "boolean";} | "char" {write("char"); return "char";} | "byte" {write("byte"); return "byte";} | "short" {write("short"); return "short";} | "int" {write("int"); return "int";} | "long" {write("long"); return "long";} | "float" {write("float"); return "float";} | "double" {write("double"); return "double"; } } String ResultType() : {String s;} { "void" {write("void"); return "void";} | s = Type() { return s;} } String Name() : /* * A lookahead of 2 is required below since "Name" can be followed * by a ".*" when used in the context of an "ImportDeclaration". */ {Token t; String s;} { t= {write(t.image); s = t.image;} ( LOOKAHEAD(2) "." {write("."); s += ".";} t= {write(t.image); s += t.image;} )* { return s; } } void NameList() : {} { Name() ( "," {write(","); } Name() )* } /* * Expression syntax follows. */ void Expression() : /* * This expansion has been written this way instead of: * Assignment() | ConditionalExpression() * for performance reasons. * However, it is a weakening of the grammar for it allows the LHS of * assignments to be any conditional expression whereas it can only be * a primary expression. Consider adding a semantic predicate to work * around this. */ {} { ConditionalExpression() [ AssignmentOperator() Expression() ] } void AssignmentOperator() : {} { "=" {write("="); } | "*=" {write("*="); } | "/=" {write("/="); } | "%=" {write("%="); } | "+=" {write("+="); } | "-=" {write("-="); } | "<<=" {write("<<="); } | ">>=" {write(">>="); } | ">>>=" {write(">>>="); } | "&=" {write("&="); } | "^=" {write("^="); } | "|=" {write("|="); } } void ConditionalExpression() : {} { ConditionalOrExpression() [ "?" {write("?"); } Expression() ":" {write(":"); } ConditionalExpression() ] } void ConditionalOrExpression() : {} { ConditionalAndExpression() ( "||" {write("||"); } ConditionalAndExpression() )* } void ConditionalAndExpression() : {} { InclusiveOrExpression() ( "&&" {write("&&"); } InclusiveOrExpression() )* } void InclusiveOrExpression() : {} { ExclusiveOrExpression() ( "|" {write("|"); } ExclusiveOrExpression() )* } void ExclusiveOrExpression() : {} { AndExpression() ( "^" {write("^"); } AndExpression() )* } void AndExpression() : {} { EqualityExpression() ( "&" {write("&"); } EqualityExpression() )* } void EqualityExpression() : {} { InstanceOfExpression() ( ( "==" {write("=="); } | "!=" {write("!="); } ) InstanceOfExpression() )* } void InstanceOfExpression() : {} { RelationalExpression() [ "instanceof" {write("instanceof"); } Type() ] } void RelationalExpression() : {} { ShiftExpression() ( ( "<" {write("<"); } | ">" {write(">"); } | "<=" {write("<="); } | ">=" {write(">="); } ) ShiftExpression() )* } void ShiftExpression() : {} { AdditiveExpression() ( ( "<<" {write("<<"); } | ">>" {write(">>"); } | ">>>" {write(">>>"); } ) AdditiveExpression() )* } void AdditiveExpression() : {} { MultiplicativeExpression() ( ( "+" {write("+"); } | "-" {write("-"); } ) MultiplicativeExpression() )* } void MultiplicativeExpression() : {} { UnaryExpression() ( ( "*" {write("*"); } | "/" {write("/"); } | "%" {write("%"); } ) UnaryExpression() )* } void UnaryExpression() : {} { ( "+" {write("+"); } | "-" {write("-"); } ) UnaryExpression() | PreIncrementExpression() | PreDecrementExpression() | UnaryExpressionNotPlusMinus() } void PreIncrementExpression() : {} { "++" {write("++"); } PrimaryExpression() } void PreDecrementExpression() : {} { "--" {write("--"); } PrimaryExpression() } void UnaryExpressionNotPlusMinus() : {} { ( "~" {write("~"); } | "!" {write("!"); } ) UnaryExpression() | LOOKAHEAD( CastLookahead() ) CastExpression() | PostfixExpression() } // This production is to determine lookahead only. The LOOKAHEAD specifications // below are not used, but they are there just to indicate that we know about // this. void CastLookahead() : {} { LOOKAHEAD(2) "(" PrimitiveType() | LOOKAHEAD("(" Name() "[") "(" Name() "[" "]" | "(" Name() ")" ( "~" | "!" | "(" | | "this" | "super" | "new" | Literal() ) } void PostfixExpression() : {} { PrimaryExpression() [ "++" {write("++"); } | "--" {write("--"); } ] } void CastExpression() : {} { LOOKAHEAD("(" PrimitiveType()) "(" {write("("); } Type() ")" {write(")"); } UnaryExpression() | "(" {write("("); } Type() ")" {write(")"); } UnaryExpressionNotPlusMinus() } void PrimaryExpression() : {} { PrimaryPrefix() ( LOOKAHEAD(2) PrimarySuffix() )* } void PrimaryPrefix() : {Token t;} { Literal() | "this" {write("this"); } | "super" {write("super"); } "." {write("."); } t= {write(t.image); } | "(" {write("("); } Expression() ")" {write(")"); } | AllocationExpression() | LOOKAHEAD( ResultType() "." "class" ) ResultType() "." {write("."); } "class" {write("class"); } | Name() } void PrimarySuffix() : {Token t;} { LOOKAHEAD(2) "." {write("."); } "this" {write("this"); } | LOOKAHEAD(2) "." {write("."); } AllocationExpression() | "[" {write("["); } Expression() "]" {write("]"); } | "." {write("."); } t= {write(t.image); } | Arguments() } void Literal() : {Token t;} { t= {write(t.image); } | t= {write(t.image); } | t= {write(t.image); } | t= {write(t.image); } | BooleanLiteral() | NullLiteral() } void BooleanLiteral() : {} { "true" {write("true"); } | "false" {write("false"); } } void NullLiteral() : {} { "null" {write("null"); } } void Arguments() : {} { "(" {write("("); } [ ArgumentList() ] ")" {write(")"); } } void ArgumentList() : {} { Expression() ( "," {write(","); } Expression() )* } void AllocationExpression() : {} { LOOKAHEAD(2) "new" {write("new "); } PrimitiveType() ArrayDimsAndInits() | "new" {write("new "); } Name() ( ArrayDimsAndInits() | Arguments() [ ClassBody() ] ) } /* * The third LOOKAHEAD specification below is to parse to PrimarySuffix * if there is an expression between the "[...]". */ void ArrayDimsAndInits() : {} { LOOKAHEAD(2) ( LOOKAHEAD(2) "[" {write("["); } Expression() "]" {write("]"); } )+ ( LOOKAHEAD(2) "[" {write("["); } "]" {write("]"); } )* | ( "[" {write("["); } "]" {write("]"); } )+ ArrayInitializer() } /* * Statement syntax follows. */ void Statement() : {} { LOOKAHEAD(2) LabeledStatement() | Block() | EmptyStatement() | StatementExpression() ";" {write(";"); } | SwitchStatement() | IfStatement() | WhileStatement() | DoStatement() | ForStatement() | BreakStatement() | ContinueStatement() | ReturnStatement() | ThrowStatement() | SynchronizedStatement() | TryStatement() } void LabeledStatement() : {Token t;} { t= {write(t.image); } ":" {write(":"); } Statement() } void Block() : {} { "{" {write("{"); } ( BlockStatement() )* "}" {write("}"); } } void BlockStatement() : {} { LOOKAHEAD([ "final" ] Type() ) LocalVariableDeclaration() ";" {write(";"); } | Statement() | UnmodifiedClassDeclaration() | UnmodifiedInterfaceDeclaration() } void LocalVariableDeclaration() : {} { [ "final" {write("final "); } ] Type() VariableDeclarator() ( "," {write(","); } VariableDeclarator() )* } void EmptyStatement() : {} { ";" {write(";"); } } void StatementExpression() : /* * The last expansion of this production accepts more than the legal * Java expansions for StatementExpression. This expansion does not * use PostfixExpression for performance reasons. */ {} { PreIncrementExpression() | PreDecrementExpression() | PrimaryExpression() [ "++" {write("++"); } | "--" {write("--"); } | AssignmentOperator() Expression() ] } void SwitchStatement() : {} { "switch" {write("switch"); } "(" {write("("); } Expression() ")" {write(")"); } "{" {write("{"); } ( SwitchLabel() ( BlockStatement() )* )* "}" {write("}"); } } void SwitchLabel() : {} { "case" {write("case"); } Expression() ":" {write(":"); } | "default" {write("default"); } ":" {write(":"); } } void IfStatement() : /* * The disambiguating algorithm of JavaCC automatically binds dangling * else's to the innermost if statement. The LOOKAHEAD specification * is to tell JavaCC that we know what we are doing. */ {} { "if" {write("if"); } "(" {write("("); } Expression() ")" {write(")"); } Statement() [ LOOKAHEAD(1) "else" {write("else "); } Statement() ] } void WhileStatement() : {} { "while" {write("while"); } "(" {write("("); } Expression() ")" {write(")"); } Statement() } void DoStatement() : {} { "do" {write("do "); } Statement() "while" {write("while"); } "(" {write("("); } Expression() ")" {write(")"); } ";" {write(";"); } } void ForStatement() : {} { "for" {write("for"); } "(" {write("("); } [ ForInit() ] ";" {write(";"); } [ Expression() ] ";" {write(";"); } [ ForUpdate() ] ")" {write(")"); } Statement() } void ForInit() : {} { LOOKAHEAD( [ "final" ] Type() ) LocalVariableDeclaration() | StatementExpressionList() } void StatementExpressionList() : {} { StatementExpression() ( "," {write(","); } StatementExpression() )* } void ForUpdate() : {} { StatementExpressionList() } void BreakStatement() : {Token t;} { "break" {write("break"); } [ t= {write(t.image); } ] ";" {write(";"); } } void ContinueStatement() : {Token t;} { "continue" {write("continue"); } [ t= {write(t.image); } ] ";" {write(";"); } } void ReturnStatement() : {} { "return" {write("return"); } [ Expression() ] ";" {write(";"); } } void ThrowStatement() : {} { "throw" {write("throw"); } Expression() ";" {write(";"); } } void SynchronizedStatement() : {} { "synchronized" {write("synchronized"); } "(" {write("("); } Expression() ")" {write(")"); } Block() } void TryStatement() : /* * Semantic check required here to make sure that at least one * finally/catch is present. */ {} { "try" {write("try"); } Block() ( "catch" {write("catch"); } "(" {write("("); } FormalParameter() ")" {write(")"); } Block() )* [ "finally" {write("finally"); } Block() ] }