[JWebUnit-development] SF.net SVN: jwebunit:[869] trunk
Brought to you by:
henryju
From: <he...@us...> - 2010-10-20 10:03:00
|
Revision: 869 http://jwebunit.svn.sourceforge.net/jwebunit/?rev=869&view=rev Author: henryju Date: 2010-10-20 10:02:51 +0000 (Wed, 20 Oct 2010) Log Message: ----------- JUnit 4 migration part 3: restored WebTestCase generator and added a new generator for JWebUnit. Modified Paths: -------------- trunk/jwebunit-core/pom.xml Added Paths: ----------- trunk/jwebunit-webtestcase-generator/src/main/javacc/JWebUnit.jj trunk/jwebunit-webtestcase-generator/src/main/javacc/WebTestCase.jj Removed Paths: ------------- trunk/jwebunit-webtestcase-generator/src/main/javacc/Java1.5.jj Modified: trunk/jwebunit-core/pom.xml =================================================================== --- trunk/jwebunit-core/pom.xml 2010-10-20 09:17:31 UTC (rev 868) +++ trunk/jwebunit-core/pom.xml 2010-10-20 10:02:51 UTC (rev 869) @@ -41,21 +41,34 @@ <artifactId>exec-maven-plugin</artifactId> <executions> <execution> + <id>generate-webtestcase</id> <phase>generate-sources</phase> <goals> <goal>java</goal> </goals> <configuration> - <sourceRoot> - ${project.build.directory}/generated-sources/main/java - </sourceRoot> + <mainClass> + net.sourceforge.jwebunit.javacc.WebTestCaseGenerator + </mainClass> </configuration> </execution> + <execution> + <id>generate-jwebunit</id> + <phase>generate-sources</phase> + <goals> + <goal>java</goal> + </goals> + <configuration> + <mainClass> + net.sourceforge.jwebunit.javacc.JWebUnitGenerator + </mainClass> + </configuration> + </execution> </executions> <configuration> - <mainClass> - net.sourceforge.jwebunit.javacc.WebTestCaseGenerator - </mainClass> + <sourceRoot> + ${project.build.directory}/generated-sources/main/java + </sourceRoot> <arguments> <argument>${basedir}/src/main/java</argument> <argument> Copied: trunk/jwebunit-webtestcase-generator/src/main/javacc/JWebUnit.jj (from rev 860, trunk/jwebunit-webtestcase-generator/src/main/javacc/Java1.5.jj) =================================================================== --- trunk/jwebunit-webtestcase-generator/src/main/javacc/JWebUnit.jj (rev 0) +++ trunk/jwebunit-webtestcase-generator/src/main/javacc/JWebUnit.jj 2010-10-20 10:02:51 UTC (rev 869) @@ -0,0 +1,1605 @@ + +/* + * 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. + */ + +options { + JAVA_UNICODE_ESCAPE = true; + ERROR_REPORTING = false; + STATIC = false; +} + +PARSER_BEGIN(JWebUnitGenerator) +package net.sourceforge.jwebunit.javacc; + +import java.io.*; +import java.util.*; + +/** + * Grammar to parse Java version 1.5 + * @author Sreenivasa Viswanadha - Simplified and enhanced for 1.5 + */ +public class JWebUnitGenerator +{ + /** + * Class to hold modifiers. + */ + static public final class ModifierSet + { + /* Definitions of the bits in the modifiers field. */ + public static final int PUBLIC = 0x0001; + public static final int PROTECTED = 0x0002; + public static final int PRIVATE = 0x0004; + public static final int ABSTRACT = 0x0008; + public static final int STATIC = 0x0010; + public static final int FINAL = 0x0020; + public static final int SYNCHRONIZED = 0x0040; + public static final int NATIVE = 0x0080; + public static final int TRANSIENT = 0x0100; + public static final int VOLATILE = 0x0200; + public static final int STRICTFP = 0x1000; + + /** A set of accessors that indicate whether the specified modifier + is in the set. */ + + public boolean isPublic(int modifiers) + { + return (modifiers & PUBLIC) != 0; + } + + public boolean isProtected(int modifiers) + { + return (modifiers & PROTECTED) != 0; + } + + public boolean isPrivate(int modifiers) + { + return (modifiers & PRIVATE) != 0; + } + + public boolean isStatic(int modifiers) + { + return (modifiers & STATIC) != 0; + } + + public boolean isAbstract(int modifiers) + { + return (modifiers & ABSTRACT) != 0; + } + + public boolean isFinal(int modifiers) + { + return (modifiers & FINAL) != 0; + } + + public boolean isNative(int modifiers) + { + return (modifiers & NATIVE) != 0; + } + + public boolean isStrictfp(int modifiers) + { + return (modifiers & STRICTFP) != 0; + } + + public boolean isSynchronized(int modifiers) + { + return (modifiers & SYNCHRONIZED) != 0; + } + + public boolean isTransient(int modifiers) + { + return (modifiers & TRANSIENT) != 0; + } + + public boolean isVolatile(int modifiers) + { + return (modifiers & VOLATILE) != 0; + } + + /** + * Removes the given modifier. + */ + static int removeModifier(int modifiers, int mod) + { + return modifiers & ~mod; + } + } + + public JWebUnitGenerator(String fileName) + { + this(System.in); + try { ReInit(new FileInputStream(new File(fileName))); } + catch(Exception e) { e.printStackTrace(); } + } + + public static void main(String args[]) { + JWebUnitGenerator parser; + StringBuffer sb = new StringBuffer(); + String webTesterPath; + String webTestCasePath; + File inputFile; + File outputFile; + FileOutputStream output; + if (args.length == 2) { + webTesterPath = args[0] + File.separator + "net" + File.separator + "sourceforge" + File.separator + "jwebunit" + File.separator + "junit" + File.separator + "WebTester.java"; + webTestCasePath = args[1] + File.separator + "net" + File.separator + "sourceforge" + File.separator + "jwebunit" + File.separator + "junit" + File.separator + "JWebUnit.java"; + inputFile = new File(webTesterPath); + if (inputFile.exists()) { + System.out.println("JWebUnitGenerator: Reading from file " + webTesterPath + " . . ."); + } else { + System.out.println("JWebUnitGenerator: [ERROR] File " + webTesterPath + " not found . . ."); + return; + } + + try { + parser = new JWebUnitGenerator(new java.io.FileInputStream(inputFile)); + } catch (java.io.FileNotFoundException e) { + System.out.println("JWebUnitGenerator: [ERROR] File " + webTesterPath + " not found . . ."); + return; + } + outputFile = new File(webTestCasePath); + if (!outputFile.getParentFile().exists() && !outputFile.getParentFile().mkdirs()) { + System.out.println("JWebUnitGenerator: [ERROR] Can not create output directory " + outputFile.getParentFile() + "."); + return; + } + try { + output = new java.io.FileOutputStream(outputFile); + } catch (java.io.FileNotFoundException e) { + System.out.println("JWebUnitGenerator: File " + webTestCasePath + " can not be opened."); + return; + } + + } else { + System.out.println("JWebUnitGenerator: Usage is :"); + System.out.println(" java JWebUnitGenerator dir_to_WebTester.java output_dir_for_JWebUnit.java"); + return; + } + try { + + parser.CompilationUnit(sb); + System.out.println("JWebUnitGenerator: WebTester.java parsed successfully."); + } catch (ParseException e) { + System.out.println(e.getMessage()); + System.out.println("JWebUnitGenerator: Encountered errors during parse."); + } + try { + output.write(sb.toString().getBytes("UTF-8")); + output.close(); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} + +PARSER_END(JWebUnitGenerator) + +/* WHITE SPACE */ + +SKIP : +{ + " " +| "\t" +| "\n" +| "\r" +| "\f" +} + +/* COMMENTS */ + +MORE : +{ + "//" : IN_SINGLE_LINE_COMMENT +| + <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT +| + "/*" : IN_MULTI_LINE_COMMENT +} + +<IN_SINGLE_LINE_COMMENT> +SPECIAL_TOKEN : +{ + <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" > : DEFAULT +} + +<IN_FORMAL_COMMENT> +SPECIAL_TOKEN : +{ + <FORMAL_COMMENT: "*/" > : DEFAULT +} + +<IN_MULTI_LINE_COMMENT> +SPECIAL_TOKEN : +{ + <MULTI_LINE_COMMENT: "*/" > : DEFAULT +} + +<IN_SINGLE_LINE_COMMENT,IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT> +MORE : +{ + < ~[] > +} + +/* RESERVED WORDS AND LITERALS */ + +TOKEN : +{ + < ABSTRACT: "abstract" > +| < ASSERT: "assert" > +| < 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" > +| < ENUM: "enum" > +| < 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" > +| < STRICTFP: "strictfp" > +| < 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: + <DECIMAL_LITERAL> (["l","L"])? + | <HEX_LITERAL> (["l","L"])? + | <OCTAL_LITERAL> (["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"])* (<EXPONENT>)? (["f","F","d","D"])? + | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])? + | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])? + | (["0"-"9"])+ (<EXPONENT>)? ["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> (<LETTER>|<DIGIT>)* > +| + < #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: "." > +| < AT: "@" > +} + +/* OPERATORS */ + +TOKEN : +{ + < ASSIGN: "=" > +| < 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: "<<" > +| < PLUSASSIGN: "+=" > +| < MINUSASSIGN: "-=" > +| < STARASSIGN: "*=" > +| < SLASHASSIGN: "/=" > +| < ANDASSIGN: "&=" > +| < ORASSIGN: "|=" > +| < XORASSIGN: "^=" > +| < REMASSIGN: "%=" > +| < LSHIFTASSIGN: "<<=" > +| < RSIGNEDSHIFTASSIGN: ">>=" > +| < RUNSIGNEDSHIFTASSIGN: ">>>=" > +| < ELLIPSIS: "..." > +} + +/* >'s need special attention due to generics syntax. */ +TOKEN : +{ + < RUNSIGNEDSHIFT: ">>>" > + { + matchedToken.kind = GT; + ((Token.GTToken)matchedToken).realKind = RUNSIGNEDSHIFT; + input_stream.backup(2); + } +| < RSIGNEDSHIFT: ">>" > + { + matchedToken.kind = GT; + ((Token.GTToken)matchedToken).realKind = RSIGNEDSHIFT; + input_stream.backup(1); + } +| < GT: ">" > +} + + +/***************************************** + * THE JAVA LANGUAGE GRAMMAR STARTS HERE * + *****************************************/ + +/* + * Program structuring syntax follows. + */ + +void CompilationUnit(StringBuffer sb): +{} +{ + {sb.append(getToken(1).specialToken.image).append("\n");} + [ PackageDeclaration(sb) ] + + {sb.append("import java.awt.Image;\n"); + sb.append("import java.io.File;\n"); + sb.append("import java.io.PrintStream;\n"); + sb.append("import java.util.List;\n"); + sb.append("import java.util.Map;\n"); + sb.append("import java.net.URL;\n\n"); + sb.append("import net.sourceforge.jwebunit.api.IElement;\n"); + sb.append("import net.sourceforge.jwebunit.api.ITestingEngine;\n"); + sb.append("import net.sourceforge.jwebunit.exception.TestingEngineResponseException;\n"); + sb.append("import net.sourceforge.jwebunit.html.Table;\n"); + sb.append("import net.sourceforge.jwebunit.util.TestContext;\n\n");} + + ( ImportDeclaration(sb) )* + + {sb.append("/**\n"); + sb.append(" * Utility class for JUnit 4 tests which provides web application navigation and \n"); + sb.append(" * JUnit assertions. This class uses and is generated from {@link net.sourceforge.jwebunit.junit.WebTester}.\n"); + sb.append(" * \n"); + sb.append(" * @author JavaCC\n"); + sb.append(" */\n");} + + ( TypeDeclaration(sb) )* + <EOF> +} + +void PackageDeclaration(StringBuffer sb): +{String name;} +{ + "package" name=Name() ";" + {sb.append("package ").append(name).append(";\n\n");} + +} + +void ImportDeclaration(StringBuffer sb): +{} +{ + "import" [ "static" ] Name() [ "." "*" ] ";" +} + +/* + * Modifiers. We match all modifiers in a single rule to reduce the chances of + * syntax errors for simple modifier mistakes. It will also enable us to give + * better error messages. + */ + +int Modifiers(): +{ + int modifiers = 0; +} +{ + ( + LOOKAHEAD(2) + ( + "public" { modifiers |= ModifierSet.PUBLIC; } + | + "static" { modifiers |= ModifierSet.STATIC; } + | + "protected" { modifiers |= ModifierSet.PROTECTED; } + | + "private" { modifiers |= ModifierSet.PRIVATE; } + | + "final" { modifiers |= ModifierSet.FINAL; } + | + "abstract" { modifiers |= ModifierSet.ABSTRACT; } + | + "synchronized" { modifiers |= ModifierSet.SYNCHRONIZED; } + | + "native" { modifiers |= ModifierSet.NATIVE; } + | + "transient" { modifiers |= ModifierSet.TRANSIENT; } + | + "volatile" { modifiers |= ModifierSet.VOLATILE; } + | + "strictfp" { modifiers |= ModifierSet.STRICTFP; } + | + Annotation() + ) + )* + + { + return modifiers; + } +} + +/* + * Declaration syntax follows. + */ +void TypeDeclaration(StringBuffer sb): +{ + int modifiers; +} +{ + ";" +| + modifiers = Modifiers() + ( + ClassOrInterfaceDeclaration(modifiers, sb) + | + EnumDeclaration(modifiers) + | + AnnotationTypeDeclaration(modifiers) + ) +} + + +void ClassOrInterfaceDeclaration(int modifiers, StringBuffer sb): +{ + boolean isInterface = false; +} +{ + ( "class" | "interface" { isInterface = true; } ) + <IDENTIFIER> + [ TypeParameters() ] + [ ExtendsList(isInterface) ] + [ ImplementsList(isInterface) ] + {sb.append("public class JWebUnit ");} + ClassOrInterfaceBody(isInterface, sb) +} + +void ExtendsList(boolean isInterface): +{ + boolean extendsMoreThanOne = false; +} +{ + "extends" ClassOrInterfaceType() + ( "," ClassOrInterfaceType() { extendsMoreThanOne = true; } )* + { + if (extendsMoreThanOne && !isInterface) + throw new ParseException("A class cannot extend more than one other class"); + } +} + +void ImplementsList(boolean isInterface): +{} +{ + "implements" ClassOrInterfaceType() + ( "," ClassOrInterfaceType() )* + { + if (isInterface) + throw new ParseException("An interface cannot implement other interfaces"); + } +} + +void EnumDeclaration(int modifiers): +{} +{ + "enum" <IDENTIFIER> + [ ImplementsList(false) ] + EnumBody() +} + +void EnumBody(): +{} +{ + "{" + EnumConstant() ( "," EnumConstant() )* + [ ";" ( ClassOrInterfaceBodyDeclaration(false, null) )* ] + "}" +} + +void EnumConstant(): +{} +{ + <IDENTIFIER> [ Arguments() ] [ ClassOrInterfaceBody(false, null) ] +} + +void TypeParameters(): +{} +{ + "<" TypeParameter() ( "," TypeParameter() )* ">" +} + +void TypeParameter(): +{} +{ + <IDENTIFIER> [ TypeBound() ] +} + +void TypeBound(): +{} +{ + "extends" ClassOrInterfaceType() ( "&" ClassOrInterfaceType() )* +} + +void ClassOrInterfaceBody(boolean isInterface, StringBuffer sb): +{} +{ {sb.append("{\n"); + sb.append(" private static InheritableThreadLocal<WebTester> tester = new InheritableThreadLocal<WebTester>() {\n"); + sb.append(" @Override\n"); + sb.append(" protected WebTester childValue(WebTester parentValue) {\n"); + sb.append(" //Create a new web tester for each child thread\n"); + sb.append(" WebTester webTester = new WebTester();\n"); + sb.append(" //But initialize it with parent TestContext\n"); + sb.append(" webTester.setTestContext(parentValue.getTestContext());\n"); + sb.append(" return webTester;\n"); + sb.append(" }\n"); + sb.append(" };\n\n"); + sb.append(" private JWebUnit() {\n"); + sb.append(" //This class should not be instanciated, but instead used statically\n"); + sb.append(" }\n\n"); + + sb.append(" /**\n"); + sb.append(" * Get internal WebTester.\n"); + sb.append(" */\n"); + sb.append(" public static WebTester getTester() {\n"); + sb.append(" if (tester.get() == null) {\n"); + sb.append(" tester.set(new WebTester());\n"); + sb.append(" }\n"); + sb.append(" return tester.get();\n"); + sb.append(" }\n\n"); + + sb.append(" /**\n"); + sb.append(" * Set a custom WebTester (for example your own subclass).\n"); + sb.append(" */\n"); + sb.append(" public static void setCustomTester(WebTester tester) {\n"); + sb.append(" JWebUnit.tester.set(tester);\n"); + sb.append(" }\n\n");} + + "{" ( ClassOrInterfaceBodyDeclaration(isInterface, sb) )* "}" + {sb.append("}\n");} +} + +void ClassOrInterfaceBodyDeclaration(boolean isInterface, StringBuffer sb): +{ + boolean isNestedInterface = false; + int modifiers; + String comment; +} +{ + LOOKAHEAD(2) + Initializer() + { + if (isInterface) + throw new ParseException("An interface cannot have initializers"); + } +| + {comment=getToken(1).specialToken!=null?getToken(1).specialToken.image:"";} + modifiers = Modifiers() // Just get all the modifiers out of the way. If you want to do + // more checks, pass the modifiers down to the member + ( + ClassOrInterfaceDeclaration(modifiers, sb) + | + EnumDeclaration(modifiers) + | + LOOKAHEAD( [ TypeParameters() ] <IDENTIFIER> "(" ) + ConstructorDeclaration() + | + LOOKAHEAD( Type() <IDENTIFIER> ( "[" "]" )* ( "," | "=" | ";" ) ) + FieldDeclaration(modifiers) + | + MethodDeclaration(modifiers, sb, comment) + ) +| + ";" +} + +void FieldDeclaration(int modifiers): +{} +{ + // Modifiers are already matched in the caller + Type() VariableDeclarator() ( "," VariableDeclarator() )* ";" +} + +void VariableDeclarator(): +{} +{ + VariableDeclaratorId() [ "=" VariableInitializer() ] +} + +String VariableDeclaratorId(): +{String result; + Token t;} +{ + t=<IDENTIFIER> {result=t.image;} ( "[" "]" {result+="[]";} )* + {return result;} +} + +void VariableInitializer(): +{} +{ + ArrayInitializer() +| + Expression() +} + +void ArrayInitializer(): +{} +{ + "{" [ VariableInitializer() ( LOOKAHEAD(2) "," VariableInitializer() )* ] [ "," ] "}" +} + +void MethodDeclaration(int modifiers, StringBuffer sb, String comment): +{ boolean append; + String resultType; + List params; + String throwsList; + boolean isVoid;} +{ + // Modifiers already matched in the caller! + { append = (modifiers & ModifierSet.PUBLIC) != 0;} + { if (append && comment!=null) sb.append(" ").append(comment).append("\n");} + { if (append) sb.append(" public static ");} + [ TypeParameters() ] + isVoid=ResultType(append, sb) + params=MethodDeclarator(append, sb) [ "throws" throwsList=NameList() {if (append) sb.append("throws "+throwsList);} ] + ( Block() | ";" ) + {if (append) { + sb.append(" {\n"); + sb.append(" "); + if (!isVoid) sb.append("return "); + sb.append("getTester().").append(params.remove(0)).append("("); + for (Iterator i = params.iterator(); i.hasNext();) { + i.next(); + sb.append(i.next()); + if (i.hasNext()) sb.append(", "); + } + sb.append(");\n"); + sb.append(" }\n\n"); + }} +} + +List MethodDeclarator(boolean append, StringBuffer sb): +{Token t; +List result;} +{ + t=<IDENTIFIER> {if(append) sb.append(t.image);} result=FormalParameters(append, sb) ( "[" "]" )* + {result.add(0, t.image); return result;} +} + +List FormalParameters(boolean append, StringBuffer sb): +{List result = new LinkedList(); + List tmp;} +{ + "(" {if(append) sb.append("(");} [ tmp=FormalParameter() {result.add(tmp.get(0)); result.add(tmp.get(1)); if (append) {sb.append(tmp.get(0)).append(" ").append(tmp.get(1));}} + ( ","{if(append) sb.append(", ");} tmp=FormalParameter() {result.add(tmp.get(0)); result.add(tmp.get(1)); if (append) {sb.append(tmp.get(0)).append(" ").append(tmp.get(1));}} )* ] ")" {if(append) sb.append(")");} + {return result;} +} + +List FormalParameter(): +{List result = new ArrayList(); + String tmp;} +{ + [ "final" ] tmp=Type() {result.add(tmp);} [ "..." ] tmp=VariableDeclaratorId() {result.add(tmp);} + {return result;} +} + +void ConstructorDeclaration(): +{} +{ + [ TypeParameters() ] + // Modifiers matched in the caller + <IDENTIFIER> FormalParameters(false, null) [ "throws" NameList() ] + "{" + [ LOOKAHEAD(ExplicitConstructorInvocation()) ExplicitConstructorInvocation() ] + ( BlockStatement() )* + "}" +} + +void ExplicitConstructorInvocation(): +{} +{ + LOOKAHEAD("this" Arguments() ";") + "this" Arguments() ";" +| + [ LOOKAHEAD(2) PrimaryExpression() "." ] "super" Arguments() ";" +} + +void Initializer(): +{} +{ + [ "static" ] Block() +} + + +/* + * Type, name and expression syntax follows. + */ + +String Type(): +{String s;} +{ + (LOOKAHEAD(2) s=ReferenceType() + | + s=PrimitiveType()) + {return s;} +} + +String ReferenceType(): +{String result;} +{ + (result=PrimitiveType() ( LOOKAHEAD(2) "[" "]" {result+="[]";} )+ + | + ( result=ClassOrInterfaceType() ) ( LOOKAHEAD(2) "[" "]" {result+="[]";} )*) + {return result;} +} + +String ClassOrInterfaceType(): +{String result=""; + String result2=""; + Token t;} +{ + t=<IDENTIFIER> {result=t.image;} [ LOOKAHEAD(2) result2=TypeArguments() ] + ( LOOKAHEAD(2) "." <IDENTIFIER> [ LOOKAHEAD(2) TypeArguments() ] )* + {return result+result2;} +} + +String TypeArguments(): +{String resultTmp; + StringBuffer sb = new StringBuffer();} +{ + "<" {sb.append("<");} resultTmp=TypeArgument() {sb.append(resultTmp);} ( "," {sb.append(",");} resultTmp=TypeArgument() {sb.append(resultTmp);} )* ">" {sb.append(">");} + {return sb.toString();} +} + +String TypeArgument(): +{String resultTmp = ""; + StringBuffer sb = new StringBuffer();} +{ + (resultTmp=ReferenceType() {sb.append(resultTmp);} + | + "?" {sb.append("?");} [ resultTmp=WildcardBounds() {sb.append(resultTmp);} ]) + {return sb.toString();} +} + +String WildcardBounds(): +{String resultTmp = ""; + StringBuffer sb = new StringBuffer();} +{ + "extends" {sb.append("extends");} resultTmp=ReferenceType() {sb.append(resultTmp);} + | + "super" {sb.append("super");} resultTmp=ReferenceType() {sb.append(resultTmp);} + {return sb.toString();} +} + + +String PrimitiveType(): +{} +{ + "boolean" {return "boolean";} +| + "char" {return "char";} +| + "byte" {return "byte";} +| + "short" {return "short";} +| + "int" {return "int";} +| + "long" {return "long";} +| + "float" {return "float";} +| + "double" {return "double";} +} + +boolean ResultType(boolean append, StringBuffer sb): +{String result;} +{ + "void" {if (append) sb.append("void "); return true;} +| + result=Type() {if (append) sb.append(result+" "); return false;} +} + +String Name(): +/* + * A lookahead of 2 is required below since "Name" can be followed + * by a ".*" when used in the context of an "ImportDeclaration". + */ +{String name = ""; +Token t;} +{ + t=<IDENTIFIER> + {name+=t.image;} + ( LOOKAHEAD(2) "." t=<IDENTIFIER> {name+="."+t.image;} )* + {return name;} +} + +String NameList(): +{String result, tmp;} +{ + result=Name() ( "," tmp=Name() {result+=", "+tmp;} )* + {return result;} +} + + +/* + * 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() + [ + LOOKAHEAD(2) + AssignmentOperator() Expression() + ] +} + +void AssignmentOperator(): +{} +{ + "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | ">>>=" | "&=" | "^=" | "|=" +} + +void ConditionalExpression(): +{} +{ + ConditionalOrExpression() [ "?" Expression() ":" Expression() ] +} + +void ConditionalOrExpression(): +{} +{ + ConditionalAndExpression() ( "||" ConditionalAndExpression() )* +} + +void ConditionalAndExpression(): +{} +{ + InclusiveOrExpression() ( "&&" InclusiveOrExpression() )* +} + +void InclusiveOrExpression(): +{} +{ + ExclusiveOrExpression() ( "|" ExclusiveOrExpression() )* +} + +void ExclusiveOrExpression(): +{} +{ + AndExpression() ( "^" AndExpression() )* +} + +void AndExpression(): +{} +{ + EqualityExpression() ( "&" EqualityExpression() )* +} + +void EqualityExpression(): +{} +{ + InstanceOfExpression() ( ( "==" | "!=" ) InstanceOfExpression() )* +} + +void InstanceOfExpression(): +{} +{ + RelationalExpression() [ "instanceof" Type() ] +} + +void RelationalExpression(): +{} +{ + ShiftExpression() ( ( "<" | ">" | "<=" | ">=" ) ShiftExpression() )* +} + +void ShiftExpression(): +{} +{ + AdditiveExpression() ( ( "<<" | RSIGNEDSHIFT() | RUNSIGNEDSHIFT() ) AdditiveExpression() )* +} + +void AdditiveExpression(): +{} +{ + MultiplicativeExpression() ( ( "+" | "-" ) MultiplicativeExpression() )* +} + +void MultiplicativeExpression(): +{} +{ + UnaryExpression() ( ( "*" | "/" | "%" ) UnaryExpression() )* +} + +void UnaryExpression(): +{} +{ + ( "+" | "-" ) UnaryExpression() +| + PreIncrementExpression() +| + PreDecrementExpression() +| + UnaryExpressionNotPlusMinus() +} + +void PreIncrementExpression(): +{} +{ + "++" PrimaryExpression() +} + +void PreDecrementExpression(): +{} +{ + "--" PrimaryExpression() +} + +void UnaryExpressionNotPlusMinus(): +{} +{ + ( "~" | "!" ) 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("(" Type() "[") + "(" Type() "[" "]" +| + "(" Type() ")" ( "~" | "!" | "(" | <IDENTIFIER> | "this" | "super" | "new" | Literal() ) +} + +void PostfixExpression(): +{} +{ + PrimaryExpression() [ "++" | "--" ] +} + +void CastExpression(): +{} +{ + LOOKAHEAD("(" PrimitiveType()) + "(" Type() ")" UnaryExpression() +| + "(" Type() ")" UnaryExpressionNotPlusMinus() +} + +void PrimaryExpression(): +{} +{ + PrimaryPrefix() ( LOOKAHEAD(2) PrimarySuffix() )* +} + +void MemberSelector(): +{} +{ + "." TypeArguments() <IDENTIFIER> +} + +void PrimaryPrefix(): +{} +{ + Literal() +| + "this" +| + "super" "." <IDENTIFIER> +| + "(" Expression() ")" +| + AllocationExpression() +| + LOOKAHEAD( ResultType(false, null) "." "class" ) + ResultType(false, null) "." "class" +| + Name() +} + +void PrimarySuffix(): +{} +{ + LOOKAHEAD(2) + "." "this" +| + LOOKAHEAD(2) + "." AllocationExpression() +| + LOOKAHEAD(3) + MemberSelector() +| + "[" Expression() "]" +| + "." <IDENTIFIER> +| + Arguments() +} + +void Literal(): +{} +{ + <INTEGER_LITERAL> +| + <FLOATING_POINT_LITERAL> +| + <CHARACTER_LITERAL> +| + <STRING_LITERAL> +| + BooleanLiteral() +| + NullLiteral() +} + +void BooleanLiteral(): +{} +{ + "true" +| + "false" +} + +void NullLiteral(): +{} +{ + "null" +} + +void Arguments(): +{} +{ + "(" [ ArgumentList() ] ")" +} + +void ArgumentList(): +{} +{ + Expression() ( "," Expression() )* +} + +void AllocationExpression(): +{} +{ + LOOKAHEAD(2) + "new" PrimitiveType() ArrayDimsAndInits() +| + "new" ClassOrInterfaceType() [ TypeArguments() ] + ( + ArrayDimsAndInits() + | + Arguments() [ ClassOrInterfaceBody(false, null) ] + ) +} + +/* + * The third LOOKAHEAD specification below is to parse to PrimarySuffix + * if there is an expression between the "[...]". + */ +void ArrayDimsAndInits(): +{} +{ + LOOKAHEAD(2) + ( LOOKAHEAD(2) "[" Expression() "]" )+ ( LOOKAHEAD(2) "[" "]" )* +| + ( "[" "]" )+ ArrayInitializer() +} + + +/* + * Statement syntax follows. + */ + +void Statement(): +{} +{ + LOOKAHEAD(2) + LabeledStatement() +| + AssertStatement() +| + Block() +| + EmptyStatement() +| + StatementExpression() ";" +| + SwitchStatement() +| + IfStatement() +| + WhileStatement() +| + DoStatement() +| + ForStatement() +| + BreakStatement() +| + ContinueStatement() +| + ReturnStatement() +| + ThrowStatement() +| + SynchronizedStatement() +| + TryStatement() +} + +void AssertStatement(): +{} +{ + "assert" Expression() [ ":" Expression() ] ";" +} + +void LabeledStatement(): +{} +{ + <IDENTIFIER> ":" Statement() +} + +void Block(): +{} +{ + "{" ( BlockStatement() )* "}" +} + +void BlockStatement(): +{} +{ + LOOKAHEAD([ "final" ] Type() <IDENTIFIER>) + LocalVariableDeclaration() ";" +| + Statement() +| + ClassOrInterfaceDeclaration(0, null) +} + +void LocalVariableDeclaration(): +{} +{ + [ "final" ] Type() VariableDeclarator() ( "," VariableDeclarator() )* +} + +void EmptyStatement(): +{} +{ + ";" +} + +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() + [ + "++" + | + "--" + | + AssignmentOperator() Expression() + ] +} + +void SwitchStatement(): +{} +{ + "switch" "(" Expression() ")" "{" + ( SwitchLabel() ( BlockStatement() )* )* + "}" +} + +void SwitchLabel(): +{} +{ + "case" Expression() ":" +| + "default" ":" +} + +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" "(" Expression() ")" Statement() [ LOOKAHEAD(1) "else" Statement() ] +} + +void WhileStatement(): +{} +{ + "while" "(" Expression() ")" Statement() +} + +void DoStatement(): +{} +{ + "do" Statement() "while" "(" Expression() ")" ";" +} + +void ForStatement(): +{} +{ + "for" "(" + + ( + LOOKAHEAD(Type() <IDENTIFIER> ":") + Type() <IDENTIFIER> ":" Expression() + | + [ ForInit() ] ";" [ Expression() ] ";" [ ForUpdate() ] + ) + + ")" Statement() +} + +void ForInit(): +{} +{ + LOOKAHEAD( [ "final" ] Type() <IDENTIFIER> ) + LocalVariableDeclaration() +| + StatementExpressionList() +} + +void StatementExpressionList(): +{} +{ + StatementExpression() ( "," StatementExpression() )* +} + +void ForUpdate(): +{} +{ + StatementExpressionList() +} + +void BreakStatement(): +{} +{ + "break" [ <IDENTIFIER> ] ";" +} + +void ContinueStatement(): +{} +{ + "continue" [ <IDENTIFIER> ] ";" +} + +void ReturnStatement(): +{} +{ + "return" [ Expression() ] ";" +} + +void ThrowStatement(): +{} +{ + "throw" Expression() ";" +} + +void SynchronizedStatement(): +{} +{ + "synchronized" "(" Expression() ")" Block() +} + +void TryStatement(): +/* + * Semantic check required here to make sure that at least one + * finally/catch is present. + */ +{} +{ + "try" Block() + ( "catch" "(" FormalParameter() ")" Block() )* + [ "finally" Block() ] +} + +/* We use productions to match >>>, >> and > so that we can keep the + * type declaration syntax with generics clean + */ + +void RUNSIGNEDSHIFT(): +{} +{ + ( LOOKAHEAD({ getToken(1).kind == GT && + ((Token.GTToken)getToken(1)).realKind == RUNSIGNEDSHIFT} ) + ">" ">" ">" + ) +} + +void RSIGNEDSHIFT(): +{} +{ + ( LOOKAHEAD({ getToken(1).kind == GT && + ((Token.GTToken)getToken(1)).realKind == RSIGNEDSHIFT} ) + ">" ">" + ) +} + +/* Annotation syntax follows. */ + +void Annotation(): +{} +{ + LOOKAHEAD( "@" Name() "(" ( <IDENTIFIER> "=" | ")" )) + NormalAnnotation() + | + LOOKAHEAD( "@" Name() "(" ) + SingleMemberAnnotation() + | + MarkerAnnotation() +} + +void NormalAnnotation(): +{} +{ + "@" Name() "(" [ MemberValuePairs() ] ")" +} + +void MarkerAnnotation(): +{} +{ + "@" Name() +} + +void SingleMemberAnnotation(): +{} +{ + "@" Name() "(" MemberValue() ")" +} + +void MemberValuePairs(): +{} +{ + MemberValuePair() ( "," MemberValuePair() )* +} + +void MemberValuePair(): +{} +{ + <IDENTIFIER> "=" MemberValue() +} + +void MemberValue(): +{} +{ + Annotation() + | + MemberValueArrayInitializer() + | + ConditionalExpression() +} + +void MemberValueArrayInitializer(): +{} +{ + "{" MemberValue() ( LOOKAHEAD(2) "," MemberValue() )* [ "," ] "}" +} + + +/* Annotation Types. */ + +void AnnotationTypeDeclaration(int modifiers): +{} +{ + "@" "interface" <IDENTIFIER> AnnotationTypeBody() +} + +void AnnotationTypeBody(): +{} +{ + "{" ( AnnotationTypeMemberDeclaration() )* "}" +} + +void AnnotationTypeMemberDeclaration(): +{ + int modifiers; +} +{ + modifiers = Modifiers() + ( + LOOKAHEAD(Type() <IDENTIFIER> "(") + Type() <IDENTIFIER> "(" ")" [ DefaultValue() ] ";" + | + ClassOrInterfaceDeclaration(modifiers, null) + | + EnumDeclaration(modifiers) + | + AnnotationTypeDeclaration(modifiers) + | + FieldDeclaration(modifiers) + ) + | + ( ";" ) +} + +void DefaultValue(): +{} +{ + "default" MemberValue() +} Deleted: trunk/jwebunit-webtestcase-generator/src/main/javacc/Java1.5.jj =================================================================== --- trunk/jwebunit-webtestcase-generator/src/main/javacc/Java1.5.jj 2010-10-20 09:17:31 UTC (rev 868) +++ trunk/jwebunit-webtestcase-generator/src/main/javacc/Java1.5.jj 2010-10-20 10:02:51 UTC (rev 869) @@ -1,1605 +0,0 @@ - -/* - * 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. - */ - -options { - JAVA_UNICODE_ESCAPE = true; - ERROR_REPORTING = false; - STATIC = false; -} - -PARSER_BEGIN(WebTestCaseGenerator) -package net.sourceforge.jwebunit.javacc; - -import java.io.*; -import java.util.*; - -/** - * Grammar to parse Java version 1.5 - * @author Sreenivasa Viswanadha - Simplified and enhanced for 1.5 - */ -public class WebTestCaseGenerator -{ - /** - * Class to hold modifiers. - */ - static public final class ModifierSet - { - /* Definitions of the bits in the modifiers field. */ - public static final int PUBLIC = 0x0001; - public static final int PROTECTED = 0x0002; - public static final int PRIVATE = 0x0004; - public static final int ABSTRACT = 0x0008; - public static final int STATIC = 0x0010; - public static final int FINAL = 0x0020; - public static final int SYNCHRONIZED = 0x0040; - public static final int NATIVE = 0x0080; - public static final int TRANSIENT = 0x0100; - public static final int VOLATILE = 0x0200; - public static final int STRICTFP = 0x1000; - - /** A set of accessors that indicate whether the specified modifier - is in the set. */ - - public boolean isPublic(int modifiers) - { - return (modifiers & PUBLIC) != 0; - } - - public boolean isProtected(int modifiers) - { - return (modifiers & PROTECTED) != 0; - } - - public boolean isPrivate(int modifiers) - { - return (modifiers & PRIVATE) != 0; - } - - public boolean isStatic(int modifiers) - { - return (modifiers & STATIC) != 0; - } - - public boolean isAbstract(int modifiers) - { - return (modifiers & ABSTRACT) != 0; - } - - public boolean isFinal(int modifiers) - { - return (modifiers & FINAL) != 0; - } - - public boolean isNative(int modifiers) - { - return (modifiers & NATIVE) != 0; - } - - public boolean isStrictfp(int modifiers) - { - return (modifiers & STRICTFP) != 0; - } - - public boolean isSynchronized(int modifiers) - { - return (modifiers & SYNCHRONIZED) != 0; - } - - public boolean isTransient(int modifiers) - { - return (modifiers & TRANSIENT) != 0; - } - - public boolean isVolatile(int modifiers) - { - return (modifiers & VOLATILE) != 0; - } - - /** - * Removes the given modifier. - */ - static int removeModifier(int modifiers, int mod) - { - return modifiers & ~mod; - } - } - - public WebTestCaseGenerator(String fileName) - { - this(System.in); - try { ReInit(new FileInputStream(new File(fileName))); } - catch(Exception e) { e.printStackTrace(); } - } - - public static void main(String args[]) { - WebTestCaseGenerator parser; - StringBuffer sb = new StringBuffer(); - String webTesterPath; - String webTestCasePath; - File inputFile; - File outputFile; - FileOutputStream output; - if (args.length == 2) { - webTesterPath = args[0] + File.separator + "net" + File.separator + "sourceforge" + File.separator + "jwebunit" + File.separator + "junit" + File.separator + "WebTester.java"; - webTestCasePath = args[1] + File.separator + "net" + File.separator + "sourceforge" + File.separator + "jwebunit" + File.separator + "junit" + File.separator + "JWebUnit.java"; - inputFile = new File(webTesterPath); - if (inputFile.exists()) { - System.out.println("WebTestCaseGenerator: Reading from file " + webTesterPath + " . . ."); - } else { - System.out.println("WebTestCaseGenerator: [ERROR] File " + webTesterPath + " not found . . ."); - return; - } - - try { - parser = new WebTestCaseGenerator(new java.io.FileInputStream(inputFile)); - } catch (java.io.FileNotFoundException e) { - System.out.println("WebTestCaseGenerator: [ERROR] File " + webTesterPath + " not found . . ."); - return; - } - outputFile = new File(webTestCasePath); - if (!outputFile.getParentFile().exists() && !outputFile.getParentFile().mkdirs()) { - System.out.println("WebTestCaseGenerator: [ERROR] Can not create output directory " + outputFile.getParentFile() + "."); - return; - } - try { - output = new java.io.FileOutputStream(outputFile); - } catch (java.io.FileNotFoundException e) { - System.out.println("WebTestCaseGenerator: File " + webTestCasePath + " can not be opened."); - return; - } - - } else { - System.out.println("WebTestCaseGenerator: Usage is :"); - System.out.println(" java WebTestCaseGenerator dir_to_WebTester.java output_dir_for_WebTestCase.java"); - return; - } - try { - - parser.CompilationUnit(sb); - System.out.println("WebTestCaseGenerator: WebTester.java parsed successfully."); - } catch (ParseException e) { - System.out.println(e.getMessage()); - System.out.println("WebTestCaseGenerator: Encountered errors during parse."); - } - try { - output.write(sb.toString().getBytes("UTF-8")); - output.close(); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - -} - -PARSER_END(WebTestCaseGenerator) - -/* WHITE SPACE */ - -SKIP : -{ - " " -| "\t" -| "\n" -| "\r" -| "\f" -} - -/* COMMENTS */ - -MORE : -{ - "//" : IN_SINGLE_LINE_COMMENT -| - <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT -| - "/*" : IN_MULTI_LINE_COMMENT -} - -<IN_SINGLE_LINE_COMMENT> -SPECIAL_TOKEN : -{ - <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" > : DEFAULT -} - -<IN_FORMAL_COMMENT> -SPECIAL_TOKEN : -{ - <FORMAL_COMMENT: "*/" > : DEFAULT -} - -<IN_MULTI_LINE_COMMENT> -SPECIAL_TOKEN : -{ - <MULTI_LINE_COMMENT: "*/" > : DEFAULT -} - -<IN_SINGLE_LINE_COMMENT,IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT> -MORE : -{ - < ~[] > -} - -/* RESERVED WORDS AND LITERALS */ - -TOKEN : -{ - < ABSTRACT: "abstract" > -| < ASSERT: "assert" > -| < 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" > -| < ENUM: "enum" > -| < 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" > -| < STRICTFP: "strictfp" > -| < 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: - <DECIMAL_LITERAL> (["l","L"])? - | <HEX_LITERAL> (["l","L"])? - | <OCTAL_LITERAL> (["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"])* (<EXPONENT>)? (["f","F","d","D"])? - | "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])? - | (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])? - | (["0"-"9"])+ (<EXPONENT>)? ["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> (<LETTER>|<DIGIT>)* > -| - < #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: "." > -| < AT: "@" > -} - -/* OPERATORS */ - -TOKEN : -{ - < ASSIGN: "=" > -| < 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: "<<" > -| < PLUSASSIGN: "+=" > -| < MINUSASSIGN: "-=" > -| < STARASSIGN: "*=" > -| < SLASHASSIGN: "/=" > -| < ANDASSIGN: "&=" > -| < ORASSIGN: "|=" > -| < XORASSIGN: "^=" > -| < REMASSIGN: "%=" > -| < LSHIFTASSIGN: "<<=" > -| < RSIGNEDSHIFTASSIGN: ">>=" > -| < RUNSIGNEDSHIFTASSIGN: ">>>=" > -| < ELLIPSIS: "..." > -} - -/* >'s need special attention due to generics syntax. */ -TOKEN : -{ - < RUNSIGNEDSHIFT: ">>>" > - { - matchedToken.kind = GT; - ((Token.GTToken)matchedToken).realKind = RUNSIGNEDSHIFT; - input_stream.backup(2); - } -| < RSIGNEDSHIFT: ">>" > - { - matchedToken.kind = GT; - ((Token.GTToken)matchedToken).realKind = RSIGNEDSHIFT; - input_stream.backup(1); - } -| < GT: ">" > -} - - -/***************************************** - * THE JAVA LANGUAGE GRAMMAR STARTS HERE * - *****************************************/ - -/* - * Program structuring syntax follows. - */ - -void CompilationUnit(StringBuffer sb): -{} -{ - {sb.append(getToken(1).specialToken.image).append("\n");} - [ PackageDeclaration(sb) ] - - {sb.append("import java.awt.Image;\n"); - sb.append("import java.io.File;\n"); - sb.append("import java.io.PrintStream;\n"); - sb.append("import java.util.List;\n"); - sb.append("import java.util.Map;\n"); - sb.append("import java.net.URL;\n\n"); - sb.append("import net.sourceforge.jwebunit.api.IElement;\n"); - sb.append("import net.sourceforge.jwebunit.api.ITestingEngine;\n"); - sb.append("import net.sourceforge.jwebunit.exception.TestingEngineResponseException;\n"); - sb.append("import net.sourceforge.jwebunit.html.Table;\n"); - sb.append("import net.sourceforge.jwebunit.util.TestContext;\n\n");} - - ( ImportDeclaration(sb) )* - - {sb.append("/**\n"); - sb.append(" * Utility class for JUnit 4 tests which provides web application navigation and \n"); - sb.append(" * JUnit assertions. This class uses and is generated from {@link net.sourceforge.jwebunit.junit.WebTester}.\n"); - sb.append(" * \n"); - sb.append(" * @author JavaCC\n"); - sb.append(" */\n");} - - ( TypeDeclaration(sb) )* - <EOF> -} - -void PackageDeclaration(StringBuffer sb): -{String name;} -{ - "package" name=Name() ";" - {sb.append("package ").append(name).append(";\n\n");} - -} - -void ImportDeclaration(StringBuffer sb): -{} -{ - "import" [ "static" ] Name() [ "." "*" ] ";" -} - -/* - * Modifiers. We match all modifiers in a single rule to reduce the chances of - * syntax errors for simple modifier mistakes. It will also enable us to give - * better error messages. - */ - -int Modifiers(): -{ - int modifiers = 0; -} -{ - ( - LOOKAHEAD(2) - ( - "public" { modifiers |= ModifierSet.PUBLIC; } - | - "static" { modifiers |= ModifierSet.STATIC; } - | - "protected" { modifiers |= ModifierSet.PROTECTED; } - | - "private" { modifiers |= ModifierSet.PRIVATE; } - | - "final" { modifiers |= ModifierSet.FINAL; } - | - "abstract" { modifiers |= ModifierSet.ABSTRACT; } - | - "synchronized" { modifiers |= ModifierSet.SYNCHRONIZED; } - | - "native" { modifiers |= ModifierSet.NATIVE; } - | - "transient" { modifiers |= ModifierSet.TRANSIENT; } - | - "volatile" { modifiers |= ModifierSet.VOLATILE; } - | - "strictfp" { modifiers |= ModifierSet.STRICTFP; } - | - Annotation() - ) - )* - - { - return modifiers; - } -} - -/* - * Declaration syntax follows. - */ -void TypeDeclaration(StringBuffer sb): -{ - int modifiers; -} -{ - ";" -| - modifiers = Modifiers() - ( - ClassOrInterfaceDeclaration(modifiers, sb) - | - EnumDeclaration(modifiers) - | - AnnotationTypeDeclaration(modifiers) - ) -} - - -void ClassOrInterfaceDeclaration(int modifiers, StringBuffer sb): -{ - boolean isInterface = false; -} -{ - ( "class" | "interface" { isInterface = true; } ) - <IDENTIFIER> - [ TypeParameters() ] - [ ExtendsList(isInterface) ] - [ ImplementsList(isInterface) ] - {sb.append("public class JWebUnit ");} - ClassOrInterfaceBody(isInterface, sb) -} - -void ExtendsList(boolean isInterface): -{ - boolean extendsMoreThanOne = false; -} -{ - "extends" ClassOrInterfaceType() - ( "," ClassOrInterfaceType() { extendsMoreThanOne = true; } )* - { - if (extendsMoreThanOne && !isInterface) - throw new ParseException("A class cannot extend more than one other class"); - } -} - -void ImplementsList(boolean isInterface): -{} -{ - "implements" ClassOrInterfaceType() - ( "," ClassOrInterfaceType() )* - { - if (isInterface) - throw new ParseException("An interface cannot implement other interfaces"); - } -} - -void EnumDeclaration(int modifiers): -{} -{ - "enum" <IDENTIFIER> - [ ImplementsList(false) ] - EnumBody() -} - -void EnumBody(): -{} -{ - "{" - EnumConstant() ( "," EnumConstant() )* - [ ";" ( ClassOrInterfaceBodyDeclaration(false, null) )* ] - "}" -} - -void EnumConstant(): -{} -{ - <IDENTIFIER> [ Arguments() ] [ ClassOrInterfaceBody(false, null) ] -} - -void TypeParameters(): -{} -{ - "<" TypeParameter() ( "," TypeParameter() )* ">" -} - -void TypeParameter(): -{} -{ - <IDENTIFIER> [ TypeBound() ] -} - -void TypeBound(): -{} -{ - "extends" ClassOrInterfaceType() ( "&" ClassOrInterfaceType() )* -} - -void ClassOrInterfaceBody(boolean isInterface, StringBuffer sb): -{} -{ {sb.append("{\n"); - sb.append(" private static InheritableThreadLocal<WebTester> tester = new InheritableThreadLocal<WebTester>() {\n"); - sb.append(" @Override\n"); - sb.append(" protected WebTester childValue(WebTester parentValue) {\n"); - sb.append(" //Create a new web tester for each child thread\n"); - sb.append(" WebTester webTester = new WebTester();\n"); - sb.append(" //But initialize it with parent TestContext\n"); - sb.append(" webTester.setTestContext(parentValue.getTestContext());\n"); - sb.append(" return webTester;\n"); - sb.append(" }\n"); - sb.append(" };\n\n"); - sb.append(" private JWebUnit() {\n"); - sb.append(" //This class should not be instanciated, but instead used statically\n"); - sb.append(" }\n\n"); - - sb.append(" /**\n"); - sb.append(" * Get internal WebTester.\n"); - sb.append(" */\n"); - sb.append(" public static WebTester getTester() {\n"); - sb.append(" if (tester.get() == null) {\n"); - sb.append(" tester.set(new WebTester());\n"); - sb.append(" }\n"); - sb.append(" return tester.get();\n"); - sb.append(" }\n\n"); - - sb.append(" /**\n"); - sb.append(" * Set a custom WebTester (for example your own subclass).\n"); - sb.append(" */\n"); - sb.append(" public static void setCustomTester(WebTester tester) {\n"); - sb.append(" JWebUnit.tester.set(tester);\n"); - sb.append(" }\n\n");} - - "{" ( ClassOrInterfaceBodyDeclaration(isInterface, sb) )* "}" - {sb.append("}\n");} -} - -void ClassOrInterfaceBodyDeclaration(boolean isInterface, StringBuffer sb): -{ - boolean isNestedInterface = false; - int modifiers; - String comment; -} -{ - LOOKAHEAD(2) - Initializer() - { - if (isInterface) - throw new ParseException("An interface cannot have initializers"); - } -| - {comment=getToken(1).specialToken!=null?getToken(1).specialToken.image:"";} - modifiers = Modifiers() // Just get all the modifiers out of the way. If you want to do - // more checks, pass the modifiers down to the member - ( - ClassOrInterfaceDeclaration(modifiers, sb) - | - EnumDeclaration(modifiers) - | - LOOKAHEAD( [ TypeParameters() ] <IDENTIFIER> "(" ) - ConstructorDeclaration() - | - LOOKAHEAD( Type() <IDENTIFIER> ( "[" "]" )* ( "," | "=" | ";" ) ) - FieldDeclaration(modifiers) - | - MethodDeclaration(modifiers, sb, comment) - ) -| - ";" -} - -void FieldDeclaration(int modifiers): -{} -{ - // Modifiers are already matched in the caller - Type() VariableDeclarator() ( "," VariableDeclarator() )* ";" -} - -void VariableDeclarator(): -{} -{ - VariableDeclaratorId() [ "=" VariableInitializer() ] -} - -String VariableDeclaratorId(): -{String result; - Token t;} -{ - t=<IDENTIFIER> {result=t.image;} ( "[" "]" {result+="[]";} )* - {return result;} -} - -void VariableInitializer(): -{} -{ - ArrayInitializer() -| - Expression() -} - -void ArrayInitializer(): -{} -{ - "{" [ VariableInitializer() ( LOOKAHEAD(2) "," VariableInitializer() )* ] [ "," ] "}" -} - -void MethodDeclaration(int modifiers, StringBuffer sb, String comment): -{ boolean append; - String resultType; - List params; - String throwsList; - boolean isVoid;} -{ - // Modifiers already matched in the caller! - { append = (modifiers & ModifierSet.PUBLIC) != 0;} - { if (append && comment!=null) sb.append(" ").append(comment).append("\n");} - { if (append) sb.append(" public static ");} - [ TypeParameters() ] - isVoid=ResultType(append, sb) - params=MethodDeclarator(append, sb) [ "throws" throwsList=NameList() {if (append) sb.append("throws "+throwsList);} ] - ( Block() | ";" ) - {if (append) { - sb.append(" {\n"); - sb.append(" "); - if (!isVoid) sb.append("return "); - sb.append("getTester().").append(params.remove(0)).append("("); - for (Iterator i = params.iterator(); i.hasNext();) { - i.next(); - sb.append(i.next()); - if (i.hasNext()) sb.append(", "); - } - sb.append(");\n"); - sb.append(" }\n\n"); - }} -} - -List MethodDeclarator(boolean append, StringBuffer sb): -{Token t; -List result;} -{ - t=<IDENTIFIER> {if(append) sb.append(t.image);} result=FormalParameters(append, sb) ( "[" "]" )* - {result.add(0, t.image); return result;} -} - -List FormalParameters(boolean append, StringBuffer sb): -{List result = new LinkedList(); - List tmp;} -{ - "(" {if(append) sb.append("(");} [ tmp=FormalParameter() {result.add(tmp.get(0)); result.add(tmp.get(1)); if (append) {sb.append(tmp.get(0)).append(" ").append(tmp.get(1));}} - ( ","{if(append) sb.append(", ");} tmp=FormalParameter() {result.add(tmp.get(0)); result.add(tmp.get(1)); if (append) {sb.append(tmp.get(0)).append(" ").append(tmp.get(1));}} )* ] ")" {if(append) sb.append(")");} - {return result;} -} - -List FormalParameter(): -{List result = new ArrayList(); - String tmp;} -{ - [ "final" ] tmp=Type() {result.add(tmp);} [ "..." ] tmp=VariableDeclaratorId() {result.add(tmp);} - {return result;} -} - -void ConstructorDeclaration(): -{} -{ - [ TypeParameters() ] - // Modifiers matched in the caller - <IDENTIFIER> FormalParameters(false, null) [ "throws" NameList() ] - "{" - [ LOOKAHEAD(ExplicitConstructorInvocation()) ExplicitConstructorInvocation() ] - ( BlockStatement() )* - "}" -} - -void ExplicitConstructorInvocation(): -{} -{ - LOOKAHEAD("this" Arguments() ";") - "this" Arguments() ";" -| - [ LOOKAHEAD(2) PrimaryExpression() "." ] "super" Arguments() ";" -} - -void Initializer(): -{} -{ - [ "static" ] Block() -} - - -/* - * Type, name and expression syntax follows. - */ - -String Type(): -{String s;} -{ - (LOOKAHEAD(2) s=ReferenceType() - | - s=PrimitiveType()) - {return s;} -} - -String ReferenceType(): -{String result;} -{ - (result=PrimitiveType() ( LOOKAHEAD(2) "[" "]" {result+="[]";} )+ - | - ( result=ClassOrInterfaceType() ) ( LOOKAHEAD(2) "[" "]" {result+="[]";} )*) - {return result;} -} - -String ClassOrInterfaceType(): -{String result=""; - String result2=""; - Token t;} -{ - t=<IDENTIFIER> {result=t.image;} [ LOOKAHEAD(2) result2=... [truncated message content] |