/* * Copyright ツゥ 2002 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * California 95054, U.S.A. All rights reserved. Sun Microsystems, Inc. has * intellectual property rights relating to technology embodied in the product * that is described in this document. In particular, and without limitation, * these intellectual property rights may include one or more of the U.S. * patents listed at http://www.sun.com/patents and one or more additional * patents or pending patent applications in the U.S. and in other countries. * U.S. Government Rights - Commercial software. Government users are subject * to the Sun Microsystems, Inc. standard license agreement and applicable * provisions of the FAR and its supplements. Use is subject to license terms. * Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered * trademarks of Sun Microsystems, Inc. in the U.S. and other countries. This * product is covered and controlled by U.S. Export Control laws and may be * subject to the export or import laws in other countries. Nuclear, missile, * chemical biological weapons or nuclear maritime end uses or end users, * whether direct or indirect, are strictly prohibited. Export or reexport * to countries subject to U.S. embargo or to entities identified on U.S. * export exclusion lists, including, but not limited to, the denied persons * and specially designated nationals lists is strictly prohibited. */ /* * JJmlt (A Java - JavaML Translator based on JavaCC) * (*** This is from "Java1.1.jj" by Sun Mircosystems, Inc.) * $Id: JJmlt.jj,v 2.2 2006/06/02 11:14:26 aman Exp $ * $Revision: 2.2 $ */ options { JAVA_UNICODE_ESCAPE = true; OUTPUT_DIRECTORY = "org/computer/aman/jjmlt"; } PARSER_BEGIN(JJmlt) package org.computer.aman.jjmlt; import java.io.BufferedReader; import java.io.FileReader; import java.util.Vector; import java.util.Stack; import java.util.List; import java.util.LinkedList; import java.util.Iterator; public class JJmlt { static String filename; static int constructorId=0; static int methodId=0; static int formalArgumentId=0; static int VariableId=0; static Vector variableIdInfo = new Vector(); static Stack className = new Stack(); static Stack varIdInfo = new Stack(); static String packageName; static int classLevel = 0; static StringBuffer[] anonymousClass = new StringBuffer[256]; static int[] indentLevel = new int[256]; static boolean printDoctype = false; static final String INDENT = " "; public static void main(String args[]) { JJmlt parser; System.err.print("JJmlt (A Java - JavaML Translator based on JavaCC) "); System.err.println("Ver.2.2"); System.err.print("Copyright (c) 2003 - 2006 Aman Lab., Ehime Univ."); System.err.println(" "); System.err.println("(JavaCC - Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.)"); for( int i = 0; i < args.length; i++ ){ if( args[i].startsWith("-") ){ if( args[i].equals("-doctype") ){ printDoctype = true; } else if ( args[i].equals("-JavaCC_License") ){ System.err.println("JJmlt is developed with JavaCC;"); System.err.println("JavaCC license :"); System.err.println("---------------------------------------------------"); try{ BufferedReader reader = new BufferedReader(new FileReader("LICENSE")); String line = null; while ( (line = reader.readLine()) != null ){ System.err.println(line); } reader.close(); } catch(Exception e){} return; } else{ System.err.println("Wrong option !!"); printUsage(); return; } } else{ filename = args[i]; } } if( filename == null ){ System.err.println("No java file specified !!"); printUsage(); return; } System.err.println("JJmlt: Reading from file " + filename + " . . ."); try { parser = new JJmlt(new java.io.FileReader(filename)); parser.compile(); System.err.println("JJmlt: Java program translated successfully."); } catch (java.io.FileNotFoundException e) { System.err.println("JJmlt: " + filename + " not found."); } catch (ParseException e) { System.err.println("JJmlt: Encountered errors during parse."); System.err.println(e.getMessage()); } catch (TokenMgrError er){ System.err.println("JJmlt: Encountered errors during parse."); System.err.println(er.getMessage()); } } public static void compile() throws ParseException { try{ CompilationUnit(); } catch (TokenMgrError er){ // ファイルの最後が "//" 型のコメントになっていて,なおかつ改行で終わっていない場合に対応 if ( er.getMessage().indexOf("Encountered: after : \"\"") >= 0 ){ println(""); println(""); } else{ throw er; } } } private static void printUsage() { System.err.println(); System.err.println("[usage]"); System.err.println(" java -jar JJmlt.jar [-doctype] [-JavaCC_License] "); System.err.println(); System.err.println(" -doctype : print \"DOCTYPE\" in XML heading"); System.err.println(" -JavaCC_License : show JavaCC License"); } private static void indent() { for( int i = 0; i < indentLevel[classLevel]; i++ ){ print(INDENT); } } private static void print(String str) { if ( classLevel == 0 ){ System.out.print(str); } else{ anonymousClass[classLevel].append(str); } } private static void println(String str) { print(str); print("\n"); } private static String indentExpression(String expr, int expressionIndent) { StringBuffer expression = new StringBuffer(); int beginIndex = 0; int endIndex = 0; while( (endIndex = expr.indexOf("\n", beginIndex)) >= 0 ){ for( int i = 0; i < expressionIndent; i++ ){ expression.append(INDENT); } expression.append( expr.substring(beginIndex, endIndex+1) ); beginIndex = endIndex + 1; } if ( beginIndex < expr.length() ){ for( int i = 0; i < expressionIndent; i++ ){ expression.append(INDENT); } expression.append( expr.substring(beginIndex) ); } return new String(expression); } private static void openTag(final String aTag) { indent(); indentLevel[classLevel]++; if ( aTag.endsWith(">") ){ println(aTag); } else{ print(aTag); } } private static void closeTag(final String aTag) { indentLevel[classLevel]--; indent(); println(aTag); } private static void printExpression(final String anExpression) { print(indentExpression(anExpression,indentLevel[classLevel])); } private static String makeId(final String aType) { StringBuffer id = new StringBuffer(" id=\""); if ( packageName != null ){ id.append(packageName); id.append("."); } id.append((String)className.peek()); id.append(":"); id.append(aType); if ( aType.equals("mth") ){ id.append("-" + (++methodId)); } else if ( aType.equals("frm") ){ id.append("-" + (++formalArgumentId)); } else if ( aType.equals("var") ){ id.append("-" + (++VariableId)); } else if ( aType.equals("ctr") ){ id.append("-" + (++constructorId)); } id.append("\""); return new String(id); } public static void init(final String aFileName) { filename = aFileName; constructorId=0; methodId=0; formalArgumentId=0; VariableId=0; variableIdInfo.clear(); className.clear(); varIdInfo.clear(); packageName = null; classLevel = 0; for ( int i = 0; i < anonymousClass.length; i++ ){ anonymousClass[i] = null; } for ( int i = 0; i < indentLevel.length; i++ ){ indentLevel[i] = 0; } printDoctype = false; String INDENT = " "; } } PARSER_END(JJmlt) /* WHITE SPACE */ SKIP : { " " | "\t" | "\n" | "\r" | "\f" } /* COMMENTS */ MORE : { "//" : IN_SINGLE_LINE_COMMENT | <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT | "/*" : IN_MULTI_LINE_COMMENT } SPECIAL_TOKEN : { : DEFAULT } SPECIAL_TOKEN : { : DEFAULT } SPECIAL_TOKEN : { : 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() : {} { { println(""); if ( printDoctype ){ println(""); } println(""); println(""); if(filename.indexOf("/") >= 0){ int fileNamePrefix = filename.lastIndexOf("/"); filename = filename.substring(fileNamePrefix+1); } println(""); packageName = null; } [ PackageDeclaration() ] ( ImportDeclaration() )* ( TypeDeclaration() )* { println(""); println(""); } } void PackageDeclaration() : {} { "package" packageName=Name() ";" { print(""); } } void ImportDeclaration() : { String importClassName; } { "import" { print(""); } } void TypeDeclaration() : {} { LOOKAHEAD( ( "abstract" | "final" | "public" )* "class" ) ClassDeclaration() | InterfaceDeclaration() | ";" } /* * Declaration syntax follows. */ void ClassDeclaration() : {} { { StringBuffer classVisibility = new StringBuffer(); } ( "abstract" { classVisibility.append(" abstract=\"true\""); } | "final" { classVisibility.append(" final=\"true\""); } | "public" { classVisibility.append(" visibility=\"public\""); } )* UnmodifiedClassDeclaration(new String(classVisibility)) } void UnmodifiedClassDeclaration(String classVisibility) : { Token token; String superclassName = null; List implementNamelist; } { "class" { openTag(" { print("name=\""); print(token.image); print("\""); print(classVisibility); println(">"); className.push(token.image); } [ "extends" { indent(); print(""); } ] { if(superclassName == null){ indent(); println(""); } } [ "implements" implementNamelist=NameList() { Iterator itr = implementNamelist.iterator(); while( itr.hasNext() ){ indent(); print(""); } } ] ClassBody() { closeTag(""); className.pop(); } } void ClassBody() : {} { "{" ( ClassBodyDeclaration() [ ";" ] )* "}" } void NestedClassDeclaration() : {} { { StringBuffer classVisibility = new StringBuffer(); } ( "static" { classVisibility.append(" static=\"true\""); } | "abstract" { classVisibility.append(" abstract=\"true\""); } | "final" { classVisibility.append(" final=\"true\""); } | "public" { classVisibility.append(" visibility=\"public\""); } | "protected" { classVisibility.append(" visibility=\"protected\""); } | "private" { classVisibility.append(" visibility=\"private\""); } )* UnmodifiedClassDeclaration(new String(classVisibility)) } 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() : { String interfaceVisibility=""; } { ( "abstract" | "public" { interfaceVisibility += " visibility=\"public\""; } )* UnmodifiedInterfaceDeclaration(interfaceVisibility) } void NestedInterfaceDeclaration() : { String interfaceVisibility=""; } { ( "static" | "abstract" | "final" | "public" { interfaceVisibility += " visibility=\"public\""; } | "protected" | "private" )* UnmodifiedInterfaceDeclaration(interfaceVisibility) } void UnmodifiedInterfaceDeclaration(String interfaceVisibility) : { Token interfaceName; List extendNamelist; } { "interface" { openTag(" { print(" name=\""); print(interfaceName.image); print("\""); print(interfaceVisibility); println(">"); className.push( interfaceName.image ); } [ "extends" extendNamelist=NameList() { Iterator itr = extendNamelist.iterator(); while ( itr.hasNext() ){ indent(); print(""); } } ] "{" ( InterfaceMemberDeclaration() )* "}" { closeTag(""); className.pop(); } } 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() : { String type; } { { StringBuffer fieldVisibility = new StringBuffer(); } ( "public" { fieldVisibility.append(" visibility=\"public\""); } | "protected" { fieldVisibility.append(" visibility=\"protected\""); } | "private" { fieldVisibility.append(" visibility=\"private\""); } | "static" { fieldVisibility.append(" static=\"true\""); } | "final" { fieldVisibility.append(" final=\"true\""); } | "transient" { fieldVisibility.append(" transient=\"true\""); } | "volatile" { fieldVisibility.append(" volatile=\"true\""); } )* type=Type() { openTag(""); } ( "," { openTag(""); } )* ";" } void VariableDeclarator( String visibility, String type, String isContinued, String localVariableId ) : { String[] variableInfo; String expr; } { variableInfo=VariableDeclaratorId() { print(" name=\""); print(variableInfo[0]); print("\""); print(visibility); print(isContinued); print(localVariableId); println(">"); /*Id情報の取得*/ if ( !varIdInfo.empty() ){ String idInfo=" \"" + variableInfo[0] + "\"" + localVariableId; ((Vector)varIdInfo.peek()).addElement(idInfo); } indent(); if( !variableInfo[1].equals("0") ){ int idx = type.indexOf("primitive="); if( idx >= 0 ){ print(type.substring(0, idx)); print("dimensions=\""); print(variableInfo[1]); println("\"/>"); } else { idx = type.indexOf("dimensions=\""); if( idx >= 0 ){ idx += "dimensions=\"".length(); print(type.substring(0, idx)); String temp = type.substring(idx); idx = temp.indexOf("\""); int dim = Integer.parseInt(temp.substring(0, idx)); dim += Integer.parseInt(variableInfo[1]); println(dim + "\"/>"); } else { idx = type.indexOf("/>"); if( idx >= 0 ){ print(type.substring(0, idx)); print(" dimensions=\""); print(variableInfo[1]); println("\"/>"); } } } } else{ println(type); } } [ "=" expr=VariableInitializer() { printExpression(expr);} ] } String[] VariableDeclaratorId() : { Token variableName; int counter=0; } { variableName= ( "[" "]" { counter++; } )* { return new String[]{ variableName.image, Integer.toString(counter) }; } } String VariableInitializer() : { String expression; } { ( expression=ArrayInitializer() | expression=Expression() ) { return expression; } } String ArrayInitializer() : { int initializeCounter = 0; int expressionCounter = 0; String expression; List exprList = new LinkedList(); } { "{" [ expression=VariableInitializer() { exprList.add( expression ); initializeCounter++; } ( LOOKAHEAD(2) "," expression=VariableInitializer() { exprList.add( expression ); initializeCounter++; } )* ] [ "," ] "}" { StringBuffer arrayInit = new StringBuffer(); for( int i = 0; i < expressionCounter; i++ ){ arrayInit.append(INDENT); } expressionCounter++; arrayInit.append("\n"); Iterator itr = exprList.iterator(); while( itr.hasNext() ){ arrayInit.append(indentExpression((String)itr.next(),expressionCounter)); } expressionCounter--; for( int i = 0; i < expressionCounter++; i++ ){ arrayInit.append(INDENT); } arrayInit.append("\n"); return new String(arrayInit); } } void MethodDeclaration() : { List exceptionName; String resultType; boolean isBlock=false; } { { /*Id情報の初期化*/ Vector variableIdInfo = new Vector(); varIdInfo.push(variableIdInfo); /*methodの作成*/ openTag(""); } } ] ( Block(isBlock) | ";" ) { closeTag(""); varIdInfo.pop(); } } void MethodDeclarator( String methodVisibility, String resultType ) : { Token methodName; } { methodName= { print(" name=\""); print(methodName.image); print("\""); print(methodVisibility); print(makeId("mth")); println(">"); indent(); println(resultType); openTag(""); } FormalParameters() ( "[" "]" )* { closeTag(""); } } void FormalParameters() : {} { "(" [ FormalParameter() ( "," FormalParameter() )* ] ")" } void FormalParameter() : { String formalArgumentVisibility=""; String[] formalArgumentInfo; String formalArgumentType; } { { openTag(""); ((Vector)varIdInfo.peek()).addElement(idInfo); indent(); if( !formalArgumentInfo[1].equals("0") ){ int idx = formalArgumentType.indexOf("primitive="); if( idx >= 0 ){ print(formalArgumentType.substring(0, idx)); println("dimensions=\"" + formalArgumentInfo[1] + "\"/>"); } else { idx = formalArgumentType.indexOf("dimensions=\""); if( idx >= 0 ){ idx += "dimensions=\"".length(); print(formalArgumentType.substring(0, idx)); String temp = formalArgumentType.substring(idx); idx = temp.indexOf("\""); int dim = Integer.parseInt(temp.substring(0, idx)); dim += Integer.parseInt(formalArgumentInfo[1]); println(dim + "\"/>"); } else { idx = formalArgumentType.indexOf("/>"); if( idx >= 0 ){ print(formalArgumentType.substring(0, idx)); println(" dimensions=\"" + formalArgumentInfo[1] + "\"/>"); } } } } else{ println(formalArgumentType); } closeTag(""); } } void ConstructorDeclaration() : { String constructorVisibility=""; Token constructorName; List exceptionName; boolean isBlock=false; } { { /*Id情報の初期化*/ Vector variableIdInfo = new Vector(); varIdInfo.push(variableIdInfo); openTag(" { print(" name=\""); print(constructorName.image); print("\""); print(constructorVisibility); print(makeId("ctr")); println(">"); openTag(""); } FormalParameters() { closeTag(""); } [ "throws" exceptionName=NameList() { Iterator itr = exceptionName.iterator(); while( itr.hasNext() ){ indent(); print(""); } } ] "{" [ LOOKAHEAD(ExplicitConstructorInvocation()) ExplicitConstructorInvocation() ] { indent(); indentLevel[classLevel]++; println(""); } ( BlockStatement(isBlock) )* "}" { closeTag(""); closeTag(""); varIdInfo.pop(); } } void ExplicitConstructorInvocation() : { String arguments=""; } { LOOKAHEAD("this" Arguments() ";") "this" { openTag(""); } arguments=Arguments() ";" { int beginIndex = 0; int endIndex = 0; while( arguments.indexOf("\n", beginIndex) >= 0){ for( int i = 0; i < indentLevel[classLevel]; i++ ){ print(INDENT); } endIndex=arguments.indexOf("\n", beginIndex); print( arguments.substring(beginIndex, endIndex+1) ); beginIndex=endIndex+1; } closeTag(""); } | [ LOOKAHEAD(2) Expression() "." ] "super" { openTag(""); } arguments=Arguments() ";" { int beginIndex = 0; int endIndex = 0; while( arguments.indexOf("\n", beginIndex) >= 0){ indent(); endIndex = arguments.indexOf("\n", beginIndex); print( arguments.substring(beginIndex, endIndex+1) ); beginIndex=endIndex+1; } closeTag(""); } } void Initializer() : { boolean isStatic=false; boolean isBlock=false; } { { varIdInfo.push(new Vector()); /*Id情報の初期化*/ } [ "static" { isStatic = true; openTag(""); } ] { if(!isStatic){ openTag(""); } } Block(isBlock) { if(isStatic){ closeTag(""); } else{ closeTag(""); } varIdInfo.pop(); } } /* * Type, name and expression syntax follows. */ String Type() : { String typeName; String primitiveType = null; int dimensionNumber=0; } { ( typeName=PrimitiveType() { primitiveType=" primitive=\"true\""; } | typeName=Name() ) { StringBuffer type = new StringBuffer(""); } else{ type.append(" dimensions=\"" + dimensionNumber); type.append("\"/>"); } return new String(type); } } String PrimitiveType() : { String typeName; } { ("boolean" { typeName="boolean"; } | "char" { typeName="char"; } | "byte" { typeName="byte"; } | "short" { typeName="short"; } | "int" { typeName="int"; } | "long" { typeName="long"; } | "float" { typeName="float"; } | "double" { typeName="double"; } ) { return typeName; } } String ResultType() : { String type; } { "void" { return ""; } | type=Type() { return type; } } 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 name; } { name= { StringBuffer names = new StringBuffer(name.image); } ( LOOKAHEAD(2) "." name= { names.append("."); names.append(name.image); } )* { return new String(names); } } List NameList() : { List namelist = new LinkedList(); String name; } { name=Name() { namelist.add(name); } ( "," name=Name() { namelist.add(name); } )* { return namelist; } } /* * Expression syntax follows. */ String 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. */ { String operator=""; String expression=""; String expr2=""; } { expression = ConditionalExpression() [ operator=AssignmentOperator() expr2=Expression() { /* assignment-expr の作成 */ StringBuffer expBuf = new StringBuffer("\n"); /* lvalueの作成 */ expBuf.append( indentExpression("\n",1) ); /* lvalue内の要素となる式(expression)を必要な分だけ右にシフトさせる */ expBuf.append( indentExpression(expression,2) ); /* expression 内に field-access タグが存在している場合, 最も外側のみを field-set タグに置換する. */ if ( expBuf.charAt(1) != 'f' || expBuf.charAt(1) != 'v'){ if ( expBuf.indexOf("= 0 ){ int beginIndex = expBuf.indexOf(""); endIndex = beginIndex + "/field-access>".length(); expBuf.replace(beginIndex, endIndex, "/field-set>"); } else { /* expression が var-ref タグのみ場合,var-set タグに置換にする. ※いずれのタグも空タグとして定義されている. */ if( expBuf.toString().endsWith("/>\n") && expBuf.indexOf("= 0){ int beginIndex = expBuf.indexOf("= 0 ){ String tmp = expBuf.substring(beginIndex + "idref=\"".length()); /* idref=" ... " の後の方のダブルクォーテーションの位置を探す. ただし,\" のように「バックスラッシュ+ダブルクォーテーション」はこの限りでない. */ endIndex = beginIndex + "idref=\"".length(); while( endIndex < expBuf.length() ){ if ( expBuf.charAt(endIndex) == '\"' && expBuf.charAt(endIndex-1) != '\\' ){ break; } endIndex++; } expBuf.replace(beginIndex, endIndex+1, ""); } } } } /* lvalue タグを閉じる */ expBuf.append( indentExpression("\n",1) ); /* assignment-expr タグの内容となる式(expr2)を必要な分だけ右にシフトさせ, assignment-expr タグを閉じる. */ expBuf.append( indentExpression(expr2,1) ); expBuf.append("\n"); /* 最後に expression へ戻す */ expression = expBuf.toString(); expBuf = null; } ] { return expression; } } String AssignmentOperator() : { String operator; } { ("=" { operator = "="; } | "*=" { operator = "*="; } | "/=" { operator = "/="; } | "%=" { operator = "%="; } | "+=" { operator = "+="; } | "-=" { operator = "-="; } | "<<=" { operator = "<<="; } | ">>=" { operator = ">>="; } | ">>>=" { operator = ">>>="; } | "&=" { operator = "&="; } | "^=" { operator = "^="; } | "|=" { operator = "|="; } ) { return operator; } } String ConditionalExpression() : { String expression; String expr2; String expr3; } { expression = ConditionalOrExpression() [ "?" expr2=Expression() ":" expr3=ConditionalExpression() { /* conditional-expr タグの作成 */ StringBuffer expBuf = new StringBuffer("\n"); /* conditional-expr タグ内の 1 番目の内容の作成 */ expBuf.append( indentExpression(expression,1) ); /* conditional-expr タグ内の 2 番目の内容の作成 */ expBuf.append( indentExpression(expr2,1) ); /* conditional-expr タグ内の 3 番目の内容の作成 */ expBuf.append( indentExpression(expr3,1) ); /* conditional-expr タグを閉じる */ expBuf.append("\n"); /* 最後に expression へ戻す */ expression = new String(expBuf); } ] { return expression; } } String ConditionalOrExpression() : { String expr1; String expr2; } { expr1=ConditionalAndExpression() ( "||" expr2=ConditionalAndExpression() { /* expr1 と expr2 を ... で囲む */ StringBuffer orExprPair = new StringBuffer("\n"); orExprPair.append( indentExpression(expr1,1) ); orExprPair.append( indentExpression(expr2,1) ); orExprPair.append("\n"); /* 上で作ったタグを改めて expr1 と置けば,"||" の繰り返しにも対応できる */ expr1 = new String(orExprPair); } )* { return expr1; } } String ConditionalAndExpression() : { String expr1; String expr2; } { expr1=InclusiveOrExpression() ( "&&" expr2=InclusiveOrExpression() { /* expr1 と expr2 を ... で囲む */ StringBuffer andExprPair = new StringBuffer("\n"); andExprPair.append( indentExpression(expr1,1) ); andExprPair.append( indentExpression(expr2,1) ); andExprPair.append("\n"); /* 上で作ったタグを改めて expr1 と置けば,"&&" の繰り返しにも対応できる */ expr1 = new String(andExprPair); } )* { return expr1; } } String InclusiveOrExpression() : { String expr1; String expr2; } { expr1=ExclusiveOrExpression() ( "|" expr2=ExclusiveOrExpression() { /* expr1 と expr2 を ... で囲む */ StringBuffer orExprPair = new StringBuffer("\n"); orExprPair.append( indentExpression(expr1,1) ); orExprPair.append( indentExpression(expr2,1) ); orExprPair.append("\n"); /* 上で作ったタグを改めて expr1 と置けば,"|" の繰り返しにも対応できる */ expr1 = new String(orExprPair); } )* { return expr1; } } String ExclusiveOrExpression() : { String expr1; String expr2; } { expr1=AndExpression() ( "^" expr2=AndExpression() { /* expr1 と expr2 を ... で囲む */ StringBuffer eorExprPair = new StringBuffer("\n"); eorExprPair.append( indentExpression(expr1,1) ); eorExprPair.append( indentExpression(expr2,1) ); eorExprPair.append("\n"); /* 上で作ったタグを改めて expr1 と置けば,"^" の繰り返しにも対応できる */ expr1 = new String(eorExprPair); } )* { return expr1; } } String AndExpression() : { String expr1; String expr2; } { expr1=EqualityExpression() ( "&" expr2=EqualityExpression() { /* expr1 と expr2 を ... で囲む */ StringBuffer andExprPair = new StringBuffer("\n"); andExprPair.append( indentExpression(expr1,1) ); andExprPair.append( indentExpression(expr2,1) ); andExprPair.append("\n"); /* 上で作ったタグを改めて expr1 と置けば,"&" の繰り返しにも対応できる */ expr1 = new String(andExprPair); } )* { return expr1; } } String EqualityExpression() : { String expr1; String expr2; String operator; } { expr1=InstanceOfExpression() ( ( "==" { operator = "=="; } | "!=" { operator = "!="; } ) expr2=InstanceOfExpression() { /* expr1 と expr2 を \n"); exprPair.append( indentExpression(expr1,1) ); exprPair.append( indentExpression(expr2,1) ); exprPair.append("\n"); /* 上で作ったタグを改めて expr1 と置けば,"==" または "!=" の繰り返しにも対応できる */ expr1 = new String(exprPair); } )* { return expr1; } } String InstanceOfExpression() : { String expression; String type; } { expression = RelationalExpression() [ "instanceof" type=Type() { StringBuffer expBuf = new StringBuffer("\n"); expBuf.append( indentExpression(expression,1) ); expBuf.append( indentExpression(type,1) ); expBuf.append("\n"); expBuf.append("\n"); expression = new String(expBuf); } ] { return expression; } } String RelationalExpression() : { String expr1; String expr2; String operator; } { expr1=ShiftExpression() ( ( "<" { operator="<"; } | ">" { operator=">"; } | "<=" { operator="<="; } | ">=" { operator=">="; } ) expr2=ShiftExpression() { /* expr1 と expr2 を ... で囲む */ StringBuffer exprPair = new StringBuffer("\n"); exprPair.append( indentExpression(expr1,1) ); exprPair.append( indentExpression(expr2,1) ); exprPair.append("\n"); /* 上で作ったタグを改めて expr1 と置けば,"<" 等 の繰り返しにも対応できる */ expr1 = new String(exprPair); } )* { return expr1; } } String ShiftExpression() : { String expr1; String expr2; String operator; } { expr1=AdditiveExpression() ( ( "<<" { operator = "<<"; } | ">>" { operator = ">>"; } | ">>>" { operator = ">>>"; } ) expr2=AdditiveExpression() { /* expr1 と expr2 を ... で囲む */ StringBuffer exprPair = new StringBuffer("\n"); exprPair.append( indentExpression(expr1,1) ); exprPair.append( indentExpression(expr2,1) ); exprPair.append("\n"); /* 上で作ったタグを改めて expr1 と置けば,"<<" 等 の繰り返しにも対応できる */ expr1 = new String(exprPair); } )* { return expr1; } } String AdditiveExpression() : { String expr1; String expr2; String operator; } { expr1=MultiplicativeExpression() ( ( "+" { operator="+"; } | "-" { operator="-"; } ) expr2=MultiplicativeExpression() { /* expr1 と expr2 を ... で囲む */ StringBuffer exprPair = new StringBuffer("\n"); exprPair.append( indentExpression(expr1,1) ); exprPair.append( indentExpression(expr2,1) ); exprPair.append("\n"); /* 上で作ったタグを改めて expr1 と置けば,"<<" 等 の繰り返しにも対応できる */ expr1 = new String(exprPair); } )* { return expr1;} } String MultiplicativeExpression() : { String expr1; String expr2; String operator; } { expr1=UnaryExpression() ( ( "*" { operator = "*"; } | "/" { operator = "/"; } | "%" { operator = "%"; } ) expr2=UnaryExpression() { /* expr1 と expr2 を ... で囲む */ StringBuffer exprPair = new StringBuffer("\n"); exprPair.append( indentExpression(expr1,1) ); exprPair.append( indentExpression(expr2,1) ); exprPair.append("\n"); /* 上で作ったタグを改めて expr1 と置けば,"*" 等 の繰り返しにも対応できる */ expr1 = new String(exprPair); } )* { return expr1; } } String UnaryExpression() : { String expression; String operator; } { ( ( "+" { operator = "+"; } | "-" { operator = "-"; } ) expression=UnaryExpression() { StringBuffer expBuf = new StringBuffer("\n"); expBuf.append( indentExpression(expression,1) ); expBuf.append("\n"); expression = new String(expBuf); } | expression=PreIncrementExpression() | expression=PreDecrementExpression() | expression=UnaryExpressionNotPlusMinus() ) { return expression; } } String PreIncrementExpression() : { String expression; } { "++" expression=PrimaryExpression() { /* unary-expr タグの作成 */ StringBuffer expBuf = new StringBuffer("\n"); expBuf.append( indentExpression(expression,1) ); expBuf.append("\n"); expression = new String(expBuf); return expression; } } String PreDecrementExpression() : { String expression; } { "--" expression=PrimaryExpression() { /* unary-expr タグの作成 */ StringBuffer expBuf = new StringBuffer("\n"); expBuf.append( indentExpression(expression,1) ); expBuf.append("\n"); expression = new String(expBuf); return expression; } } String UnaryExpressionNotPlusMinus() : { String expression; String operator; } { ( ( "~" { operator = "~"; } | "!" { operator = "!"; } ) expression = UnaryExpression() { StringBuffer expBuf = new StringBuffer("\n"); expBuf.append( indentExpression(expression,1) ); expBuf.append("\n"); expression = new String(expBuf); } | LOOKAHEAD( CastLookahead() ) expression=CastExpression() | expression=PostfixExpression()) { return expression; } } // 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() ) } String PostfixExpression() : { String expression; String operator; } { expression = PrimaryExpression() [ "++" { operator = "++"; } | "--" { operator = "--"; } { /* unary-expr タグの作成 */ StringBuffer expBuf = new StringBuffer("\n"); expBuf.append( indentExpression(expression,1) ); expBuf.append("\n"); expression = new String(expBuf); } ] { return expression; } } String CastExpression() : { String expression=""; String type; boolean isCast=true; } { ( LOOKAHEAD("(" PrimitiveType()) "(" type=Type() ( ")" expression = UnaryExpression() | "." "class" ")" { isCast = false; } ) | "(" type=Type() ( ")" expression = UnaryExpressionNotPlusMinus() | "." "class" ")" { isCast = false; } ) ) { if ( isCast ){ StringBuffer expBuf = new StringBuffer("\n"); expBuf.append( indentExpression(type+"\n",1) ); expBuf.append( indentExpression(expression,1) ); expBuf.append("\n"); expression = new String(expBuf); } else{ /* キャスト式ではなく,"型名.class" という特殊なインスタンス生成式の場合 */ /* 便宜上,Class クラスインスタンスの生成式とする */ StringBuffer expBuf = new StringBuffer(expression); expBuf.append("\n"); expBuf.append(indentExpression("",1)); expBuf.append("\n"); expBuf.append(indentExpression("",1)); expBuf.append("\n\n"); expression = new String(expBuf); } return expression; } } String PrimaryExpression() : { String expression; String expr; } { expression = PrimaryPrefix() { Vector buf = new Vector(); if ( expression.startsWith("#") ){ /* expression == Name() なので分解する */ StringBuffer expBuf = new StringBuffer("= 0 ){ if( nameId.indexOf("id=") >= 0 ){ int beginIndex = nameId.indexOf("id=") + 3; expBuf.append(" idref="); expBuf.append( nameId.substring(beginIndex) ); break; } } } } expBuf.append("/>\n"); buf.add( new String(expBuf) ); while ( endIndex != -1 ){ int beginIndex = endIndex + 1; endIndex = expression.indexOf(".", beginIndex); if ( endIndex != -1 ){ /* "." であったことを示す */ buf.add( "#id:" + expression.substring(beginIndex,endIndex) ); } else{ buf.add( "#id:" + expression.substring(beginIndex) ); } } expression = new String(expBuf); } else if ( expression.startsWith("") ){ int idx = expression.indexOf("\n"); buf.add("\n"); buf.add( "#id:" + expression.substring( idx + 1 )); expression = "\n"; } else{ buf.add( expression ); } } ( LOOKAHEAD(2) expr = PrimarySuffix() { buf.add( expr ); } )* { if ( buf.size() == 1 ){ /* PrimaryPrefix のみの場合 */ return expression; } int i = 1; while ( i < buf.size() ){ String code = (String)buf.get(i); if ( code.equals("#this") ){ /* "." "this" の場合 */ /* 用途が不明のため未処理 */ } else if ( code.startsWith(" の場合 */ String nextCode = null; if ( i+1 < buf.size() ){ nextCode = (String)buf.get(i+1); } if ( nextCode == null || !nextCode.startsWith(" の場合 */ StringBuffer expBuf = new StringBuffer("\n"); expBuf.append( indentExpression(expression,1) ); expBuf.append("\n"); expression = new String(expBuf); } else{ /* の場合 */ StringBuffer expBuf = new StringBuffer("\n"); expBuf.append( indentExpression("\n",1) ); expBuf.append( indentExpression(expression,2) ); expBuf.append( indentExpression("\n",1) ); expBuf.append( indentExpression(nextCode,1) ); expBuf.append("\n"); i++; /* ... の分だけ +1 */ expression = new String(expBuf); } } else if ( code.startsWith("... を持たない タグの場合 */ StringBuffer expBuf = new StringBuffer("\n"); expBuf.append( indentExpression(code,1) ); expBuf.append("\n"); expression = new String(expBuf); } else{ /* "[" 式 "]" の場合 */ StringBuffer expBuf = new StringBuffer("\n"); expBuf.append( indentExpression("\n",1) ); expBuf.append( indentExpression(expression,2) ); expBuf.append( indentExpression("\n",1) ); expBuf.append( indentExpression("\n",1 ) ); expBuf.append( indentExpression(code,2) ); expBuf.append( indentExpression("\n",1) ); expBuf.append("\n"); expression = new String(expBuf); } i++; } } { return expression; } } String PrimaryPrefix() : { String expression; String expr; Token id; } { ( expression = Literal() | "this" { expression = "\n"; } | "super" "." id= { expression = "\n" + id.image; } | "(" expr=Expression() ")" { StringBuffer expBuf = new StringBuffer("\n"); expBuf.append( indentExpression(expr,1) ); expBuf.append("\n"); expression = new String(expBuf); } | expression = AllocationExpression() | LOOKAHEAD( ResultType() "." "class" ) expr=ResultType() "." "class" { /* "クラス名.class" を便宜上,Class クラスインスタンスの生成と解釈する. */ expression = "\n" + indentExpression("",1) + "\n"; expression += indentExpression("",1); expression += "\n\n"; } | expr = Name() { expression = "#" + expr; /* Name() であることの印を付ける */ } ) { return expression; } } String PrimarySuffix() : { String code; Token id; } { ( LOOKAHEAD(2) "." "this" { code = "#this"; } /* ".this" であったことを示す */ | LOOKAHEAD(2) "." code=AllocationExpression() /* ... または ... が代入される */ | "[" code = Expression() "]" | "." id= { code = "#id:" + id.image; } /* "." であったことを示す */ | code=Arguments() /* ... が代入される */ ) { return code; } } String Literal() : { Token token; String expression; String literal; } { { StringBuffer expBuf = new StringBuffer(" { expBuf.append("number kind=\"integer\" value=\""); expBuf.append(token.image); expBuf.append("\""); } | token= { expBuf.append("number kind=\""); if ( (token.image).indexOf("f") == -1 ){ expBuf.append("double"); } else{ expBuf.append("float"); } expBuf.append("\" value=\""); expBuf.append( token.image ); expBuf.append("\""); } | token= { literal = token.image; /* 前後のアポストロフィを無視 */ literal = literal.substring(1, literal.length()-1); /* 特殊文字を置換 */ char c = literal.charAt(0); if ( c >= 0x00 && c <= 0x1f ){ literal = "\\u00" + Integer.toHexString((int)c); } else{ if ( literal.indexOf("&") >= 0 ){ literal = literal.replaceAll("&", "&"); } if ( literal.indexOf("\\") >= 0 ){ /* ' もしくは " の前にある \ を削除 */ StringBuffer buf = new StringBuffer(literal); int idx = buf.indexOf("\\"); if ( buf.length() > 2 ){ while ( idx != -1 && idx < buf.length()-1 ){ if ( buf.charAt(idx+1) == '\'' || buf.charAt(idx+1) == '\"' ){ buf.deleteCharAt(idx); } idx = buf.indexOf("\\", idx+1); } literal = new String(buf); } } if ( literal.indexOf("\'") >= 0 ){ literal = literal.replaceAll("\'", "'"); } if ( literal.indexOf("\"") >= 0 ){ literal = literal.replaceAll("\"", """); } if ( literal.indexOf(">") >= 0 ){ literal = literal.replaceAll(">", ">"); } if ( literal.indexOf("<") >= 0 ){ literal = literal.replaceAll("<", "<"); } } expBuf.append("char value=\""); expBuf.append( literal ); expBuf.append("\""); } | token= { literal = token.image; /* 前後のダブルコーテーションを無視 */ literal = literal.substring(1, literal.length()-1); /* 特殊文字を置換 */ if ( literal.indexOf("&") >= 0 ){ literal = literal.replaceAll("&", "&"); } if ( literal.indexOf("\\") >= 0 ){ /* ' もしくは " の前にある \ を削除 */ StringBuffer buf = new StringBuffer(literal); int idx = buf.indexOf("\\"); if ( buf.length() > 2 ){ while ( idx != -1 && idx < buf.length()-1 ){ if ( buf.charAt(idx+1) == '\'' || buf.charAt(idx+1) == '\"' ){ buf.deleteCharAt(idx); } idx = buf.indexOf("\\", idx+1); } literal = new String(buf); } } if ( literal.indexOf("\'") >= 0 ){ literal = literal.replaceAll("\'", "'"); } if ( literal.indexOf("\"") >= 0 ){ literal = literal.replaceAll("\"", """); } if ( literal.indexOf(">") >= 0 ){ literal = literal.replaceAll(">", ">"); } if ( literal.indexOf("<") >= 0 ){ literal = literal.replaceAll("<", "<"); } expBuf.append("string value=\""); expBuf.append( literal ); expBuf.append("\""); } | literal = BooleanLiteral() { expBuf.append("boolean value=\""); expBuf.append( literal ); expBuf.append("\""); } | NullLiteral() { expBuf.append("null"); } ) { expBuf.append("/>\n"); expression = new String(expBuf); return expression; } } String BooleanLiteral() : { String booleanLiteral; } { ( "true"{ booleanLiteral="true"; } | "false" { booleanLiteral="false"; } ) { return booleanLiteral; } } void NullLiteral() : {} { "null" } String Arguments() : {} { { String argExpression = null; } "(" [ argExpression = ArgumentList() ] ")" { StringBuffer expBuf = new StringBuffer("\n"); if ( argExpression != null ){ expBuf.append( indentExpression(argExpression,1) ); } expBuf.append("\n"); return new String(expBuf); } } String ArgumentList() : { String expr; String expression; } { expression = Expression() { StringBuffer expBuf = new StringBuffer(expression); } ( "," expr = Expression() { expBuf.append( expr ); } )* { return new String(expBuf); } } String AllocationExpression() : { String expression; String expr = null; String type; String typeName; } { ( LOOKAHEAD(2) "new" typeName=PrimitiveType() { type = "\n"; } expression = ArrayDimsAndInits(type) | "new" typeName = Name() { type = "\n"; } ( expression = ArrayDimsAndInits(type) | expression = Arguments() [ { anonymousClass[++classLevel] = new StringBuffer(); } ClassBody() { expr = new String(anonymousClass[classLevel]); anonymousClass[classLevel--] = null; } ] { StringBuffer expBuf = new StringBuffer("\n"); expBuf.append( indentExpression(type,1) ); expBuf.append( indentExpression(expression,1) ); if ( expr != null ){ expBuf.append( indentExpression("\n",1) ); String superClass = type.replaceAll("type ","superclass "); expBuf.append( indentExpression(superClass,2) ); expBuf.append( indentExpression(expr,2) ); expBuf.append( indentExpression("\n",1) ); } expBuf.append("\n"); expression = new String(expBuf); } ) ) { return expression; } } /* * The third LOOKAHEAD specification below is to parse to PrimarySuffix * if there is an expression between the "[...]". */ String ArrayDimsAndInits( String type) : { String expression; StringBuffer expBuf; int dimCounter = 0; List exprList = new LinkedList(); } { LOOKAHEAD(2) ( LOOKAHEAD(2) "[" expression = Expression() "]" { /* new-array の dimensions を数える */ dimCounter++; exprList.add(expression); } )+ ( LOOKAHEAD(2) "[" "]" { dimCounter++; } )* { /* の作成 */ expBuf = new StringBuffer("\n"); /* の作成*/ expBuf.append( indentExpression(type,1) ); /* の作成 */ Iterator itr = exprList.iterator(); while( itr.hasNext() ){ expBuf.append( indentExpression("\n",1) ); expBuf.append( indentExpression((String)itr.next(),2) ); expBuf.append( indentExpression("\n",1) ); } expBuf.append("\n"); return new String(expBuf); } | ( "[" "]" { dimCounter++; } )+ expression = ArrayInitializer() { /* の作成 */ expBuf = new StringBuffer("\n"); /* の作成*/ expBuf.append( indentExpression(type,1) ); /* の作成 */ expBuf.append( indentExpression(expression,1) ); expBuf.append("\n"); return new String(expBuf); } } /* * Statement syntax follows. */ void Statement( boolean isBlock ) : {} { LOOKAHEAD(2) LabeledStatement() | Block(isBlock) | EmptyStatement(isBlock) | StatementExpression() ";" | SwitchStatement() | IfStatement() | WhileStatement() | DoStatement() | ForStatement() | BreakStatement() | ContinueStatement() | ReturnStatement() | ThrowStatement() | SynchronizedStatement() | TryStatement() } void LabeledStatement() : { boolean isLabelBlock=true; Token labelName; } { { openTag(""); indent(); print(" { print(" name=\""); print(labelName.image); println("\"/>"); } ":" Statement(isLabelBlock) { closeTag(""); } } void Block( boolean isLabelBlock ) : { boolean isBlock=false; } { "{" { if( !isLabelBlock ){ openTag(""); isBlock=true; } } ( BlockStatement(isBlock) )* "}" { if( !isLabelBlock ){ closeTag(""); } } } void BlockStatement( boolean isBlock ) : {} { LOOKAHEAD([ "final" ] Type() ) LocalVariableDeclaration() ";" | Statement(isBlock) | UnmodifiedClassDeclaration("") | UnmodifiedInterfaceDeclaration("") } void LocalVariableDeclaration() : { String localVariableVisibility=""; String localVariableType; String localVariableId; String isContinued=""; } { [ "final" { localVariableVisibility = " final=\"true\""; } ] localVariableType=Type() { openTag(""); } ( "," { openTag(""); } )* } void EmptyStatement( boolean isBlock ) : {} { { if(!isBlock){ indent(); println(""); } } ";" } 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. */ { String operator; /*演算子を入れる*/ String expr=""; /*返ってきた値を入れる*/ StringBuffer expressionList; /*field-set,var-setにした場合,変換したものを入れる*/ boolean isExpr=false; } { expr=PreIncrementExpression() { printExpression(expr); } | expr=PreDecrementExpression() { printExpression(expr); } | expr=PrimaryExpression() [ "++" { isExpr=true; openTag(""); printExpression(expr); closeTag(""); } | "--" { isExpr=true; openTag(""); printExpression(expr); closeTag(""); } | { isExpr=true; /*assignment-exprの作成*/ openTag(""); /*lvalueの作成*/ openTag(""); /*lvalue内の要素の作成*/ String expression = indentExpression(expr,indentLevel[classLevel]); /* lvalue内にfield-accessがある場合,field-set に変換する. ただし, 内の場合はその限りでない. */ int beginIndex=0; int endIndex=0; if(expr.indexOf("= 0){ endIndex = expression.indexOf("field-access", beginIndex); String prefix = expression.substring(0,endIndex); if ( prefix.lastIndexOf("\n") && expression.indexOf("var-ref") >= 0 ){ beginIndex = 0; expressionList = new StringBuffer(); if( expression.endsWith("/>\n") && expression.indexOf("var-ref") >= 0 ){ endIndex = expression.indexOf("var-ref", beginIndex); expressionList.append(expression.substring(beginIndex, endIndex)); expressionList.append("var-set"); beginIndex = endIndex + 7; } endIndex = expression.length(); expressionList.append(expression.substring(beginIndex, endIndex)); /*idrefがある場合にidrefを消去する*/ if( expressionList.indexOf("idref=") >=0 ){ beginIndex = endIndex = 0; StringBuffer variableExpr = new StringBuffer(); while( expressionList.indexOf("idref=", beginIndex) >= 0 ){ endIndex = expressionList.indexOf( "idref=" ,beginIndex ); variableExpr.append(expressionList.substring(beginIndex, endIndex-1)); variableExpr.append("/>\n"); beginIndex = expression.indexOf( "\n", endIndex ) + 1; } if( expressionList.indexOf("\n", beginIndex) >= 0 ){ while( expressionList.indexOf("\n", beginIndex) >= 0 ){ endIndex = expressionList.indexOf("\n", beginIndex); variableExpr.append(expressionList.substring(beginIndex, endIndex+1)); beginIndex = endIndex + 1; } } expressionList = variableExpr; } print(new String(expressionList)); } else{ print(expression); } /*lvalueを閉じる*/ closeTag(""); } expr=Expression() { printExpression(expr); } { closeTag(""); } ] { if( !isExpr ){ printExpression(expr); } } } void SwitchStatement() : { boolean isBlock=false; String expr; } { "switch" { openTag(""); } "(" expr=Expression() { printExpression(expr); } ")" "{" ( { openTag(""); } SwitchLabel() ( BlockStatement(isBlock) )* { closeTag(""); } )* "}" { closeTag(""); } } void SwitchLabel() : { String expr; } { "case" { openTag(""); } expr=Expression() ":" { printExpression(expr); } { closeTag(""); } | "default" ":" { indent(); println(""); } } 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. */ { boolean isBlock=false; String expr; } { "if" { openTag(""); } "(" { openTag(""); } expr=Expression() { printExpression(expr); } { closeTag(""); } ")" { openTag(""); } Statement(isBlock) { closeTag(""); } [ LOOKAHEAD(1) "else" { openTag(""); } Statement(isBlock) { closeTag(""); } ] { closeTag(""); } } void WhileStatement() : { boolean isBlock=false; String expr; } { "while" { openTag(""); } "(" { openTag(""); } expr=Expression() { printExpression(expr); } { closeTag(""); } ")" Statement(isBlock) { closeTag(""); } } void DoStatement() : { boolean isBlock=false; String expr; } { "do" { openTag(""); } Statement(isBlock) "while" "(" { openTag(""); } expr=Expression() { printExpression(expr); } { closeTag(""); } ")" ";" { closeTag(""); } } void ForStatement() : { boolean isBlock=false; String expr; } { "for" { openTag(""); } "(" [ ForInit() ] ";" [ { openTag(""); } expr=Expression() { printExpression(expr); } { closeTag(""); } ] ";" [ ForUpdate() ] ")" Statement(isBlock) { closeTag(""); } } void ForInit() : {} { LOOKAHEAD( [ "final" ] Type() ) { openTag(""); } LocalVariableDeclaration() { closeTag(""); } | StatementExpressionList("init") } void StatementExpressionList(String parentTag) : {} { { openTag("<" + parentTag + ">"); } StatementExpression() { closeTag(""); } ( "," { openTag("<" + parentTag + ">"); } StatementExpression() { closeTag(""); } )* } void ForUpdate() : {} { StatementExpressionList("update") } void BreakStatement() : { Token targetName; } { "break" { indent(); print(" { print(" targetname=\""); print(targetName.image); print("\""); } ] ";" { println("/>"); } } void ContinueStatement() : { Token targetName; } { "continue" { indent(); print(" { print(" targetname=\""); print(targetName.image); print("\""); } ] ";" { println("/>"); } } void ReturnStatement() : { String expr; } { "return" { openTag(""); } [ expr=Expression() { printExpression(expr); } ] ";" { closeTag(""); } } void ThrowStatement() : { String expr; } { "throw" { openTag(""); } expr=Expression() ";" { printExpression(expr); } { closeTag(""); } } void SynchronizedStatement() : { boolean isBlock=false; String expr; } { "synchronized" { openTag(""); } "(" { openTag(""); } expr=Expression() { printExpression(expr); } { closeTag(""); } ")" Block(isBlock) { closeTag(""); } } void TryStatement() : /* * Semantic check required here to make sure that at least one * finally/catch is present. */ { boolean isBlock=false; } { "try" { openTag(""); } Block(isBlock) ( "catch" { openTag(""); } "(" FormalParameter() ")" Block(isBlock) { closeTag(""); } )* [ "finally" { openTag(""); } Block(isBlock) { closeTag(""); } ] { closeTag(""); } }