/* * 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. * * Author: Sreenivasa Viswanadha * Author: Sriram Sankar * Author: Aslak Helles�y (XJavaDoc additions) * Author: Adamansky Anton (XJavaDoc additions for java 1.5) * */ options { JAVA_UNICODE_ESCAPE = true; ERROR_REPORTING = false; STATIC = false; } PARSER_BEGIN(@parser-class@) package xjavadoc; import java.lang.reflect.Modifier; import java.util.*; import java.io.*; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class @parser-class@ implements JavaParser { private static final Log log = LogFactory.getLog(@parser-class@.class); /** * Class to hold modifiers. */ static public final class ModifierSet { /* Definitions of the bits in the modifiers field. */ public static final int PUBLIC = 1; public static final int PROTECTED = (1 << 1); public static final int PRIVATE = (1 << 2); public static final int ABSTRACT = (1 << 3); public static final int STATIC = (1 << 4); public static final int FINAL = (1 << 5); public static final int SYNCHRONIZED = (1 << 6); public static final int NATIVE = (1 << 7); public static final int TRANSIENT = (1 << 8); public static final int VOLATILE = (1 << 9); public static final int STRICTFP = (1 << 10); /** 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; } } //EOF ModifierSet private static class Parameter { public String type; public String name; public int dimension; } //EOF Parameter private XJavaDoc _xJavaDoc; private XTagFactory _tagFactory; private String _packageName = ""; private SourceClass _sourceClass; // The class we're currently parsing private Stack _sourceClassStack = new Stack(); // Flag that tells us if the main class/interface has been parsed. private boolean _hasParsedMain = false; // Needed to support more than one "outer" class in one source. private Parameter _parameter; private Token _firstDeclToken; private final void updateJavaDoc(AbstractProgramElement element) { if (element == null) { log.warn("Update javadoc for null element!"); return; } if (log.isDebugEnabled()) { log.debug("updateJavaDoc() for=" + element.getClass() + " FtEl=" + _firstDeclToken + " CT=" + getToken(0)); } if (_firstDeclToken != null) { element.setToken(_firstDeclToken); _firstDeclToken = null; } } private static final String printModifiers(int modifiers) { StringBuffer sb = new StringBuffer(); String eline = System.getProperty("line.separator"); if ((modifiers & ModifierSet.PUBLIC) != 0) { sb.append(eline); sb.append("PUBLIC"); } if ((modifiers & ModifierSet.PROTECTED) != 0) { sb.append(eline); sb.append("PROTECTED"); } if ((modifiers & ModifierSet.PRIVATE) != 0) { sb.append(eline); sb.append("PRIVATE"); } if ((modifiers & ModifierSet.ABSTRACT) != 0) { sb.append(eline); sb.append("ABSTRACT"); } if ((modifiers & ModifierSet.FINAL) != 0) { sb.append(eline); sb.append("FINAL"); } if ((modifiers & ModifierSet.STRICTFP) != 0) { sb.append(eline); sb.append("STRICTFP"); } if ((modifiers & ModifierSet.NATIVE) != 0) { sb.append(eline); sb.append("NATIVE"); } if ((modifiers & ModifierSet.VOLATILE) != 0) { sb.append(eline); sb.append("VOLATILE"); } if ((modifiers & ModifierSet.SYNCHRONIZED) != 0) { sb.append(eline); sb.append("SYNCHRONIZED"); } if ((modifiers & ModifierSet.TRANSIENT) != 0) { sb.append(eline); sb.append("TRANSIENT"); } if ((modifiers & ModifierSet.STATIC) != 0) { sb.append(eline); sb.append("STATIC"); } return sb.toString(); } private static final void updateModifiers(int modifiers, AbstractProgramElement element) { if (element == null) { log.warn("Update modifiers for null element!"); return; } if ((modifiers & ModifierSet.PUBLIC) != 0) element.addModifier(Modifier.PUBLIC); if ((modifiers & ModifierSet.PROTECTED) != 0) element.addModifier(Modifier.PROTECTED); if ((modifiers & ModifierSet.PRIVATE) != 0) element.addModifier(Modifier.PRIVATE); if ((modifiers & ModifierSet.ABSTRACT) != 0) element.addModifier(Modifier.ABSTRACT); if ((modifiers & ModifierSet.FINAL) != 0) element.addModifier(Modifier.FINAL); if ((modifiers & ModifierSet.STRICTFP) != 0) element.addModifier(Modifier.STRICT); if ((modifiers & ModifierSet.NATIVE) != 0) element.addModifier(Modifier.NATIVE); if ((modifiers & ModifierSet.VOLATILE) != 0) element.addModifier(Modifier.VOLATILE); if ((modifiers & ModifierSet.SYNCHRONIZED) != 0) element.addModifier(Modifier.SYNCHRONIZED); if ((modifiers & ModifierSet.TRANSIENT) != 0) element.addModifier(Modifier.TRANSIENT); if ((modifiers & ModifierSet.STATIC) != 0) element.addModifier(Modifier.STATIC); } /** * Should be called before UnmodifiedClassDeclaration or UnmodifiedInterfaceDeclaration */ private SourceClass pushAndGet() { // Push a source class onto the stack. If the stack is empty, // push the outer class. Otherwise, instantiate a new (inner) class // and push that instead. SourceClass clazz = null; if( _sourceClassStack.isEmpty() ) { // It's an outer class. In rare cases there is more than one outer classes // in one source. handle that here. if( !_hasParsedMain ) { // the usual case clazz = _sourceClass; } else { // the source contains more than one classes clazz = new SourceClass(_sourceClass, 0, _tagFactory); } } else { clazz = new SourceClass(currentClass(), _tagFactory); } _sourceClassStack.push(clazz); return clazz; } /** * Should be called after UnmodifiedClassDeclaration or UnmodifiedInterfaceDeclaration */ private void popAndAddInner() { SourceClass clazz = (SourceClass) _sourceClassStack.pop(); if( clazz.getContainingClass() != null ) { // Add the class as an inner class if (log.isDebugEnabled()) log.debug("popAndAddInner(): addInnerClass=" + clazz); currentClass().addInnerClass(clazz); _xJavaDoc.addSourceClass(clazz); } } private SourceClass currentClass() { return (SourceClass)_sourceClassStack.peek(); } /** * This constructor was added to allow the re-use of parsers. * The normal constructor takes a single argument which * an InputStream. This simply creates a re-usable parser * object, we satisfy the requirement of an InputStream * by using a newline character as an input stream. */ public @parser-class@( XJavaDoc xJavaDoc, XTagFactory tagFactory ) { this(new ByteArrayInputStream("\n".getBytes())); _xJavaDoc = xJavaDoc; _tagFactory = tagFactory; } /** * This was also added to allow parsers to be * re-usable. Normal JavaCC use entails passing an * input stream to the constructor and the parsing * process is carried out once. We want to be able * to re-use parsers: we do this by adding this * method and re-initializing the lexer with * the new stream that we want parsed. */ public void populate(SourceClass sourceClass) throws ParseException { _sourceClass = sourceClass; // Reset state _sourceClassStack.clear(); _packageName = ""; _parameter = new Parameter(); try { // now reinit the Parser with this CharStream // ReInit(sourceClass.getReader()); // Start the parsing. CompilationUnit( sourceClass ); } catch (TokenMgrError tme) { throw new ParseException("Lexical error: " + tme.toString()); } } } PARSER_END(@parser-class@) /* WHITE SPACE */ SPECIAL_TOKEN : { " " | "\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" > | < 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: (["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: [ // all chars for which Character.isIdentifierStart is true "$", "A"-"Z", "_", "a"-"z", "\u00a2"-"\u00a5", "\u00aa", "\u00b5", "\u00ba", "\u00c0"-"\u00d6", "\u00d8"-"\u00f6", "\u00f8"-"\u021f", "\u0222"-"\u0233", "\u0250"-"\u02ad", "\u02b0"-"\u02b8", "\u02bb"-"\u02c1", "\u02d0"-"\u02d1", "\u02e0"-"\u02e4", "\u02ee", "\u037a", "\u0386", "\u0388"-"\u038a", "\u038c", "\u038e"-"\u03a1", "\u03a3"-"\u03ce", "\u03d0"-"\u03d7", "\u03da"-"\u03f3", "\u0400"-"\u0481", "\u048c"-"\u04c4", "\u04c7"-"\u04c8", "\u04cb"-"\u04cc", "\u04d0"-"\u04f5", "\u04f8"-"\u04f9", "\u0531"-"\u0556", "\u0559", "\u0561"-"\u0587", "\u05d0"-"\u05ea", "\u05f0"-"\u05f2", "\u0621"-"\u063a", "\u0640"-"\u064a", "\u0671"-"\u06d3", "\u06d5", "\u06e5"-"\u06e6", "\u06fa"-"\u06fc", "\u0710", "\u0712"-"\u072c", "\u0780"-"\u07a5", "\u0905"-"\u0939", "\u093d", "\u0950", "\u0958"-"\u0961", "\u0985"-"\u098c", "\u098f"-"\u0990", "\u0993"-"\u09a8", "\u09aa"-"\u09b0", "\u09b2", "\u09b6"-"\u09b9", "\u09dc"-"\u09dd", "\u09df"-"\u09e1", "\u09f0"-"\u09f3", "\u0a05"-"\u0a0a", "\u0a0f"-"\u0a10", "\u0a13"-"\u0a28", "\u0a2a"-"\u0a30", "\u0a32"-"\u0a33", "\u0a35"-"\u0a36", "\u0a38"-"\u0a39", "\u0a59"-"\u0a5c", "\u0a5e", "\u0a72"-"\u0a74", "\u0a85"-"\u0a8b", "\u0a8d", "\u0a8f"-"\u0a91", "\u0a93"-"\u0aa8", "\u0aaa"-"\u0ab0", "\u0ab2"-"\u0ab3", "\u0ab5"-"\u0ab9", "\u0abd", "\u0ad0", "\u0ae0", "\u0b05"-"\u0b0c", "\u0b0f"-"\u0b10", "\u0b13"-"\u0b28", "\u0b2a"-"\u0b30", "\u0b32"-"\u0b33", "\u0b36"-"\u0b39", "\u0b3d", "\u0b5c"-"\u0b5d", "\u0b5f"-"\u0b61", "\u0b85"-"\u0b8a", "\u0b8e"-"\u0b90", "\u0b92"-"\u0b95", "\u0b99"-"\u0b9a", "\u0b9c", "\u0b9e"-"\u0b9f", "\u0ba3"-"\u0ba4", "\u0ba8"-"\u0baa", "\u0bae"-"\u0bb5", "\u0bb7"-"\u0bb9", "\u0c05"-"\u0c0c", "\u0c0e"-"\u0c10", "\u0c12"-"\u0c28", "\u0c2a"-"\u0c33", "\u0c35"-"\u0c39", "\u0c60"-"\u0c61", "\u0c85"-"\u0c8c", "\u0c8e"-"\u0c90", "\u0c92"-"\u0ca8", "\u0caa"-"\u0cb3", "\u0cb5"-"\u0cb9", "\u0cde", "\u0ce0"-"\u0ce1", "\u0d05"-"\u0d0c", "\u0d0e"-"\u0d10", "\u0d12"-"\u0d28", "\u0d2a"-"\u0d39", "\u0d60"-"\u0d61", "\u0d85"-"\u0d96", "\u0d9a"-"\u0db1", "\u0db3"-"\u0dbb", "\u0dbd", "\u0dc0"-"\u0dc6", "\u0e01"-"\u0e30", "\u0e32"-"\u0e33", "\u0e3f"-"\u0e46", "\u0e81"-"\u0e82", "\u0e84", "\u0e87"-"\u0e88", "\u0e8a", "\u0e8d", "\u0e94"-"\u0e97", "\u0e99"-"\u0e9f", "\u0ea1"-"\u0ea3", "\u0ea5", "\u0ea7", "\u0eaa"-"\u0eab", "\u0ead"-"\u0eb0", "\u0eb2"-"\u0eb3", "\u0ebd", "\u0ec0"-"\u0ec4", "\u0ec6", "\u0edc"-"\u0edd", "\u0f00", "\u0f40"-"\u0f47", "\u0f49"-"\u0f6a", "\u0f88"-"\u0f8b", "\u1000"-"\u1021", "\u1023"-"\u1027", "\u1029"-"\u102a", "\u1050"-"\u1055", "\u10a0"-"\u10c5", "\u10d0"-"\u10f6", "\u1100"-"\u1159", "\u115f"-"\u11a2", "\u11a8"-"\u11f9", "\u1200"-"\u1206", "\u1208"-"\u1246", "\u1248", "\u124a"-"\u124d", "\u1250"-"\u1256", "\u1258", "\u125a"-"\u125d", "\u1260"-"\u1286", "\u1288", "\u128a"-"\u128d", "\u1290"-"\u12ae", "\u12b0", "\u12b2"-"\u12b5", "\u12b8"-"\u12be", "\u12c0", "\u12c2"-"\u12c5", "\u12c8"-"\u12ce", "\u12d0"-"\u12d6", "\u12d8"-"\u12ee", "\u12f0"-"\u130e", "\u1310", "\u1312"-"\u1315", "\u1318"-"\u131e", "\u1320"-"\u1346", "\u1348"-"\u135a", "\u13a0"-"\u13f4", "\u1401"-"\u166c", "\u166f"-"\u1676", "\u1681"-"\u169a", "\u16a0"-"\u16ea", "\u1780"-"\u17b3", "\u17db", "\u1820"-"\u1877", "\u1880"-"\u18a8", "\u1e00"-"\u1e9b", "\u1ea0"-"\u1ef9", "\u1f00"-"\u1f15", "\u1f18"-"\u1f1d", "\u1f20"-"\u1f45", "\u1f48"-"\u1f4d", "\u1f50"-"\u1f57", "\u1f59", "\u1f5b", "\u1f5d", "\u1f5f"-"\u1f7d", "\u1f80"-"\u1fb4", "\u1fb6"-"\u1fbc", "\u1fbe", "\u1fc2"-"\u1fc4", "\u1fc6"-"\u1fcc", "\u1fd0"-"\u1fd3", "\u1fd6"-"\u1fdb", "\u1fe0"-"\u1fec", "\u1ff2"-"\u1ff4", "\u1ff6"-"\u1ffc", "\u203f"-"\u2040", "\u207f", "\u20a0"-"\u20af", "\u2102", "\u2107", "\u210a"-"\u2113", "\u2115", "\u2119"-"\u211d", "\u2124", "\u2126", "\u2128", "\u212a"-"\u212d", "\u212f"-"\u2131", "\u2133"-"\u2139", "\u2160"-"\u2183", "\u3005"-"\u3007", "\u3021"-"\u3029", "\u3031"-"\u3035", "\u3038"-"\u303a", "\u3041"-"\u3094", "\u309d"-"\u309e", "\u30a1"-"\u30fe", "\u3105"-"\u312c", "\u3131"-"\u318e", "\u31a0"-"\u31b7", "\u3400"-"\u4db5", "\u4e00"-"\u9fa5", "\ua000"-"\ua48c", "\uac00"-"\ud7a3", "\uf900"-"\ufa2d", "\ufb00"-"\ufb06", "\ufb13"-"\ufb17", "\ufb1d", "\ufb1f"-"\ufb28", "\ufb2a"-"\ufb36", "\ufb38"-"\ufb3c", "\ufb3e", "\ufb40"-"\ufb41", "\ufb43"-"\ufb44", "\ufb46"-"\ufbb1", "\ufbd3"-"\ufd3d", "\ufd50"-"\ufd8f", "\ufd92"-"\ufdc7", "\ufdf0"-"\ufdfb", "\ufe33"-"\ufe34", "\ufe4d"-"\ufe4f", "\ufe69", "\ufe70"-"\ufe72", "\ufe74", "\ufe76"-"\ufefc", "\uff04", "\uff21"-"\uff3a", "\uff3f", "\uff41"-"\uff5a", "\uff65"-"\uffbe", "\uffc2"-"\uffc7", "\uffca"-"\uffcf", "\uffd2"-"\uffd7", "\uffda"-"\uffdc", "\uffe0"-"\uffe1", "\uffe5"-"\uffe6" ] > | < #PART_LETTER: [ // all chars for which Character.isIdentifierPart is true "\u0000"-"\u0008", "\u000e"-"\u001b", "$", "0"-"9", "A"-"Z", "_", "a"-"z", "\u007f"-"\u009f", "\u00a2"-"\u00a5", "\u00aa", "\u00b5", "\u00ba", "\u00c0"-"\u00d6", "\u00d8"-"\u00f6", "\u00f8"-"\u021f", "\u0222"-"\u0233", "\u0250"-"\u02ad", "\u02b0"-"\u02b8", "\u02bb"-"\u02c1", "\u02d0"-"\u02d1", "\u02e0"-"\u02e4", "\u02ee", "\u0300"-"\u034e", "\u0360"-"\u0362", "\u037a", "\u0386", "\u0388"-"\u038a", "\u038c", "\u038e"-"\u03a1", "\u03a3"-"\u03ce", "\u03d0"-"\u03d7", "\u03da"-"\u03f3", "\u0400"-"\u0481", "\u0483"-"\u0486", "\u048c"-"\u04c4", "\u04c7"-"\u04c8", "\u04cb"-"\u04cc", "\u04d0"-"\u04f5", "\u04f8"-"\u04f9", "\u0531"-"\u0556", "\u0559", "\u0561"-"\u0587", "\u0591"-"\u05a1", "\u05a3"-"\u05b9", "\u05bb"-"\u05bd", "\u05bf", "\u05c1"-"\u05c2", "\u05c4", "\u05d0"-"\u05ea", "\u05f0"-"\u05f2", "\u0621"-"\u063a", "\u0640"-"\u0655", "\u0660"-"\u0669", "\u0670"-"\u06d3", "\u06d5"-"\u06dc", "\u06df"-"\u06e8", "\u06ea"-"\u06ed", "\u06f0"-"\u06fc", "\u070f"-"\u072c", "\u0730"-"\u074a", "\u0780"-"\u07b0", "\u0901"-"\u0903", "\u0905"-"\u0939", "\u093c"-"\u094d", "\u0950"-"\u0954", "\u0958"-"\u0963", "\u0966"-"\u096f", "\u0981"-"\u0983", "\u0985"-"\u098c", "\u098f"-"\u0990", "\u0993"-"\u09a8", "\u09aa"-"\u09b0", "\u09b2", "\u09b6"-"\u09b9", "\u09bc", "\u09be"-"\u09c4", "\u09c7"-"\u09c8", "\u09cb"-"\u09cd", "\u09d7", "\u09dc"-"\u09dd", "\u09df"-"\u09e3", "\u09e6"-"\u09f3", "\u0a02", "\u0a05"-"\u0a0a", "\u0a0f"-"\u0a10", "\u0a13"-"\u0a28", "\u0a2a"-"\u0a30", "\u0a32"-"\u0a33", "\u0a35"-"\u0a36", "\u0a38"-"\u0a39", "\u0a3c", "\u0a3e"-"\u0a42", "\u0a47"-"\u0a48", "\u0a4b"-"\u0a4d", "\u0a59"-"\u0a5c", "\u0a5e", "\u0a66"-"\u0a74", "\u0a81"-"\u0a83", "\u0a85"-"\u0a8b", "\u0a8d", "\u0a8f"-"\u0a91", "\u0a93"-"\u0aa8", "\u0aaa"-"\u0ab0", "\u0ab2"-"\u0ab3", "\u0ab5"-"\u0ab9", "\u0abc"-"\u0ac5", "\u0ac7"-"\u0ac9", "\u0acb"-"\u0acd", "\u0ad0", "\u0ae0", "\u0ae6"-"\u0aef", "\u0b01"-"\u0b03", "\u0b05"-"\u0b0c", "\u0b0f"-"\u0b10", "\u0b13"-"\u0b28", "\u0b2a"-"\u0b30", "\u0b32"-"\u0b33", "\u0b36"-"\u0b39", "\u0b3c"-"\u0b43", "\u0b47"-"\u0b48", "\u0b4b"-"\u0b4d", "\u0b56"-"\u0b57", "\u0b5c"-"\u0b5d", "\u0b5f"-"\u0b61", "\u0b66"-"\u0b6f", "\u0b82"-"\u0b83", "\u0b85"-"\u0b8a", "\u0b8e"-"\u0b90", "\u0b92"-"\u0b95", "\u0b99"-"\u0b9a", "\u0b9c", "\u0b9e"-"\u0b9f", "\u0ba3"-"\u0ba4", "\u0ba8"-"\u0baa", "\u0bae"-"\u0bb5", "\u0bb7"-"\u0bb9", "\u0bbe"-"\u0bc2", "\u0bc6"-"\u0bc8", "\u0bca"-"\u0bcd", "\u0bd7", "\u0be7"-"\u0bef", "\u0c01"-"\u0c03", "\u0c05"-"\u0c0c", "\u0c0e"-"\u0c10", "\u0c12"-"\u0c28", "\u0c2a"-"\u0c33", "\u0c35"-"\u0c39", "\u0c3e"-"\u0c44", "\u0c46"-"\u0c48", "\u0c4a"-"\u0c4d", "\u0c55"-"\u0c56", "\u0c60"-"\u0c61", "\u0c66"-"\u0c6f", "\u0c82"-"\u0c83", "\u0c85"-"\u0c8c", "\u0c8e"-"\u0c90", "\u0c92"-"\u0ca8", "\u0caa"-"\u0cb3", "\u0cb5"-"\u0cb9", "\u0cbe"-"\u0cc4", "\u0cc6"-"\u0cc8", "\u0cca"-"\u0ccd", "\u0cd5"-"\u0cd6", "\u0cde", "\u0ce0"-"\u0ce1", "\u0ce6"-"\u0cef", "\u0d02"-"\u0d03", "\u0d05"-"\u0d0c", "\u0d0e"-"\u0d10", "\u0d12"-"\u0d28", "\u0d2a"-"\u0d39", "\u0d3e"-"\u0d43", "\u0d46"-"\u0d48", "\u0d4a"-"\u0d4d", "\u0d57", "\u0d60"-"\u0d61", "\u0d66"-"\u0d6f", "\u0d82"-"\u0d83", "\u0d85"-"\u0d96", "\u0d9a"-"\u0db1", "\u0db3"-"\u0dbb", "\u0dbd", "\u0dc0"-"\u0dc6", "\u0dca", "\u0dcf"-"\u0dd4", "\u0dd6", "\u0dd8"-"\u0ddf", "\u0df2"-"\u0df3", "\u0e01"-"\u0e3a", "\u0e3f"-"\u0e4e", "\u0e50"-"\u0e59", "\u0e81"-"\u0e82", "\u0e84", "\u0e87"-"\u0e88", "\u0e8a", "\u0e8d", "\u0e94"-"\u0e97", "\u0e99"-"\u0e9f", "\u0ea1"-"\u0ea3", "\u0ea5", "\u0ea7", "\u0eaa"-"\u0eab", "\u0ead"-"\u0eb9", "\u0ebb"-"\u0ebd", "\u0ec0"-"\u0ec4", "\u0ec6", "\u0ec8"-"\u0ecd", "\u0ed0"-"\u0ed9", "\u0edc"-"\u0edd", "\u0f00", "\u0f18"-"\u0f19", "\u0f20"-"\u0f29", "\u0f35", "\u0f37", "\u0f39", "\u0f3e"-"\u0f47", "\u0f49"-"\u0f6a", "\u0f71"-"\u0f84", "\u0f86"-"\u0f8b", "\u0f90"-"\u0f97", "\u0f99"-"\u0fbc", "\u0fc6", "\u1000"-"\u1021", "\u1023"-"\u1027", "\u1029"-"\u102a", "\u102c"-"\u1032", "\u1036"-"\u1039", "\u1040"-"\u1049", "\u1050"-"\u1059", "\u10a0"-"\u10c5", "\u10d0"-"\u10f6", "\u1100"-"\u1159", "\u115f"-"\u11a2", "\u11a8"-"\u11f9", "\u1200"-"\u1206", "\u1208"-"\u1246", "\u1248", "\u124a"-"\u124d", "\u1250"-"\u1256", "\u1258", "\u125a"-"\u125d", "\u1260"-"\u1286", "\u1288", "\u128a"-"\u128d", "\u1290"-"\u12ae", "\u12b0", "\u12b2"-"\u12b5", "\u12b8"-"\u12be", "\u12c0", "\u12c2"-"\u12c5", "\u12c8"-"\u12ce", "\u12d0"-"\u12d6", "\u12d8"-"\u12ee", "\u12f0"-"\u130e", "\u1310", "\u1312"-"\u1315", "\u1318"-"\u131e", "\u1320"-"\u1346", "\u1348"-"\u135a", "\u1369"-"\u1371", "\u13a0"-"\u13f4", "\u1401"-"\u166c", "\u166f"-"\u1676", "\u1681"-"\u169a", "\u16a0"-"\u16ea", "\u1780"-"\u17d3", "\u17db", "\u17e0"-"\u17e9", "\u180b"-"\u180e", "\u1810"-"\u1819", "\u1820"-"\u1877", "\u1880"-"\u18a9", "\u1e00"-"\u1e9b", "\u1ea0"-"\u1ef9", "\u1f00"-"\u1f15", "\u1f18"-"\u1f1d", "\u1f20"-"\u1f45", "\u1f48"-"\u1f4d", "\u1f50"-"\u1f57", "\u1f59", "\u1f5b", "\u1f5d", "\u1f5f"-"\u1f7d", "\u1f80"-"\u1fb4", "\u1fb6"-"\u1fbc", "\u1fbe", "\u1fc2"-"\u1fc4", "\u1fc6"-"\u1fcc", "\u1fd0"-"\u1fd3", "\u1fd6"-"\u1fdb", "\u1fe0"-"\u1fec", "\u1ff2"-"\u1ff4", "\u1ff6"-"\u1ffc", "\u200c"-"\u200f", "\u202a"-"\u202e", "\u203f"-"\u2040", "\u206a"-"\u206f", "\u207f", "\u20a0"-"\u20af", "\u20d0"-"\u20dc", "\u20e1", "\u2102", "\u2107", "\u210a"-"\u2113", "\u2115", "\u2119"-"\u211d", "\u2124", "\u2126", "\u2128", "\u212a"-"\u212d", "\u212f"-"\u2131", "\u2133"-"\u2139", "\u2160"-"\u2183", "\u3005"-"\u3007", "\u3021"-"\u302f", "\u3031"-"\u3035", "\u3038"-"\u303a", "\u3041"-"\u3094", "\u3099"-"\u309a", "\u309d"-"\u309e", "\u30a1"-"\u30fe", "\u3105"-"\u312c", "\u3131"-"\u318e", "\u31a0"-"\u31b7", "\u3400"-"\u4db5", "\u4e00"-"\u9fa5", "\ua000"-"\ua48c", "\uac00"-"\ud7a3", "\uf900"-"\ufa2d", "\ufb00"-"\ufb06", "\ufb13"-"\ufb17", "\ufb1d"-"\ufb28", "\ufb2a"-"\ufb36", "\ufb38"-"\ufb3c", "\ufb3e", "\ufb40"-"\ufb41", "\ufb43"-"\ufb44", "\ufb46"-"\ufbb1", "\ufbd3"-"\ufd3d", "\ufd50"-"\ufd8f", "\ufd92"-"\ufdc7", "\ufdf0"-"\ufdfb", "\ufe20"-"\ufe23", "\ufe33"-"\ufe34", "\ufe4d"-"\ufe4f", "\ufe69", "\ufe70"-"\ufe72", "\ufe74", "\ufe76"-"\ufefc", "\ufeff", "\uff04", "\uff10"-"\uff19", "\uff21"-"\uff3a", "\uff3f", "\uff41"-"\uff5a", "\uff65"-"\uffbe", "\uffc2"-"\uffc7", "\uffca"-"\uffcf", "\uffd2"-"\uffd7", "\uffda"-"\uffdc", "\uffe0"-"\uffe1", "\uffe5"-"\uffe6", "\ufff9"-"\ufffb" ] > } /* 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(SourceClass sourceClass): {} { [ PackageDeclaration() ] ( ImportDeclaration() )* ( TypeDeclaration() )* { // sourceClass must know about the CompilationUnit node // if it wants to mutate or print the code @set-compilation-unit@ if( _sourceClassStack.size() != 0 ) { throw new IllegalStateException("There should be no more classes on the stack: " + _sourceClassStack.size()); } } } void PackageDeclaration(): {} { "package" _packageName=Name() ";" { _sourceClass.setContainingPackage(_packageName); } } void ImportDeclaration(): { String importedElement; boolean isPackage = false; } { "import" [ "static" ] importedElement=Name() [ "." "*" { isPackage = true; } ] ";" { if(isPackage) { if (log.isDebugEnabled()) log.debug("addImportedPackage=" + importedElement + " for class=" + _sourceClass.getClass()); _sourceClass.addImportedPackage(importedElement); } else { if (log.isDebugEnabled()) log.debug("addImportedClass=" + importedElement + " for class=" + _sourceClass.getClass()); _sourceClass.addImportedClass(importedElement); } } } /* * 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; _firstDeclToken = getToken(1); //log.debug("_firstDeclToken=" + _firstDeclToken + " NT=" + getToken(1)); } { ( LOOKAHEAD(2) ( "public" { modifiers |= ModifierSet.PUBLIC; /*if (log.isDebugEnabled()) log.debug("Set mods=\"PUBLIC\"");*/ } | "static" { modifiers |= ModifierSet.STATIC; /*if (log.isDebugEnabled()) log.debug("Set mods=\"STATIC\"");*/ } | "protected" { modifiers |= ModifierSet.PROTECTED; /*if (log.isDebugEnabled()) log.debug("Set mods=\"PROTECTED\"");*/ } | "private" { modifiers |= ModifierSet.PRIVATE; /*if (log.isDebugEnabled()) log.debug("Set mods=\"PRIVATE\"");*/ } | "final" { modifiers |= ModifierSet.FINAL; /*if (log.isDebugEnabled()) log.debug("Set mods=\"FINAL\"");*/ } | "abstract" { modifiers |= ModifierSet.ABSTRACT; /*if (log.isDebugEnabled()) log.debug("Set mods=\"ABSTRACT\"");*/ } | "synchronized" { modifiers |= ModifierSet.SYNCHRONIZED; /*if (log.isDebugEnabled()) log.debug("Set mods=\"SYNCHRONIZED\"");*/ } | "native" { modifiers |= ModifierSet.NATIVE; /*if (log.isDebugEnabled()) log.debug("Set mods=\"NATIVE\"");*/ } | "transient" { modifiers |= ModifierSet.TRANSIENT; /*if (log.isDebugEnabled()) log.debug("Set mods=\"TRANSIENT\"");*/ } | "volatile" { modifiers |= ModifierSet.VOLATILE; /*if (log.isDebugEnabled()) log.debug("Set mods=\"VOLATILE\"");*/ } | "strictfp" { modifiers |= ModifierSet.STRICTFP; /*if (log.isDebugEnabled()) log.debug("Set mods=\"STRICTFP\"");*/ } | Annotation() ) )* { return modifiers; } } /* * Declaration syntax follows. */ void TypeDeclaration(): { int modifiers; } { ";" | modifiers = Modifiers() ( ClassOrInterfaceDeclaration(modifiers) { _hasParsedMain = true; } | EnumDeclaration(modifiers) | AnnotationTypeDeclaration(modifiers) ) } void ClassOrInterfaceDeclaration(int modifiers): { boolean isInterface = false; SourceClass sourceClass = pushAndGet(); Token name = null; } { ( "class" | "interface" { isInterface = true; sourceClass.addModifier(Modifier.INTERFACE); } ) { if (_firstDeclToken == null) { _firstDeclToken = getToken(0); } sourceClass.setInterface(isInterface); updateModifiers(modifiers, sourceClass); updateJavaDoc(sourceClass); } name= { if (log.isDebugEnabled()) log.debug("ClassOrInterface name=" + name); if (sourceClass.isInner()) { if (log.isDebugEnabled()) log.debug("Inner sourceClass.setName=" + name.image); sourceClass.setName(name.image); _xJavaDoc.addPackageMaybe( _packageName ).addClass(sourceClass); _xJavaDoc.addSourceClass( sourceClass ); } else { if (log.isDebugEnabled()) log.debug("sourceClass.setQName=" + Util.getQualifiedNameFor(_packageName, name.image)); sourceClass.setQualifiedName(Util.getQualifiedNameFor(_packageName, name.image)); _xJavaDoc.addPackageMaybe(_packageName).addClass(sourceClass); _xJavaDoc.addSourceClass(sourceClass); sourceClass.resolveImportedClasses(); _xJavaDoc.addSourceClass(sourceClass); // we're adding to xjavadoc in case we're an "extra" class (XJD-8). } } [ TypeParameters() ] [ ExtendsList(isInterface) ] [ ImplementsList(isInterface) ] { if (sourceClass.getSuperclass() == null) sourceClass.setSuperclass("java.lang.Object"); } ClassOrInterfaceBody(isInterface) { popAndAddInner(); } } void ExtendsList(boolean isInterface): { boolean extendsMoreThanOne = false; SourceClass sourceClass = currentClass(); String name = null; } { "extends" name=ClassOrInterfaceType() ( "," name=ClassOrInterfaceType() { extendsMoreThanOne = true; } )* { if (extendsMoreThanOne && !isInterface) throw new ParseException("A class cannot extend more than one other class"); } { //System.err.println("setSuperclass name=" + (name != null ? name : "java.lang.Object")); sourceClass.setSuperclass(name != null ? name : "java.lang.Object"); } } void ImplementsList(boolean isInterface): { SourceClass sourceClass = currentClass(); String name = null; } { "implements" name=ClassOrInterfaceType() { if (log.isDebugEnabled()) log.debug("Add interface name=" + name + " for=" + sourceClass); sourceClass.addInterface(name); } ( "," name=ClassOrInterfaceType() {sourceClass.addInterface(name);} )* { if (isInterface) throw new ParseException("An interface cannot implement other interfaces"); } } void EnumDeclaration(int modifiers): { Token name = null; SourceClass sourceClass = pushAndGet(); sourceClass.setInterface(false); } { "enum" name= { if (log.isDebugEnabled()) log.debug("Push enum class=" + name.image); if (sourceClass.isInner()) { sourceClass.setName(name.image); _xJavaDoc.addPackageMaybe(_packageName ).addClass(sourceClass); _xJavaDoc.addSourceClass(sourceClass); } else { if (log.isDebugEnabled()) log.debug("sourceClass.setQName=" + Util.getQualifiedNameFor(_packageName, name.image)); sourceClass.setQualifiedName(Util.getQualifiedNameFor(_packageName, name.image)); _xJavaDoc.addPackageMaybe(_packageName).addClass(sourceClass); _xJavaDoc.addSourceClass(sourceClass); sourceClass.resolveImportedClasses(); _xJavaDoc.addSourceClass(sourceClass); // we're adding to xjavadoc in case we're an "extra" class (XJD-8). } } [ ImplementsList(false) ] EnumBody() { if (log.isDebugEnabled()) log.debug("Pop enum class=" + name.image); popAndAddInner(); } } void EnumBody(): {} { "{" [ EnumConstant() ( LOOKAHEAD(2) "," EnumConstant() )* ] [ "," ] [ ";" ( ClassOrInterfaceBodyDeclaration(false) )* ] "}" } void EnumConstant(): { Token name = null; SourceClass sourceClass = null; } { name= [ Arguments() ] [ { sourceClass = pushAndGet(); sourceClass.setName(name.image); _xJavaDoc.addSourceClass(sourceClass); if (log.isDebugEnabled()) log.debug("Push enum const class=" + name.image); } ClassOrInterfaceBody(false) { popAndAddInner(); if (log.isDebugEnabled()) log.debug("Pop enum const class=" + name.image); } ] } void TypeParameters(): {} { "<" TypeParameter() ( "," TypeParameter() )* ">" } void TypeParameter(): {} { [ TypeBound() ] } void TypeBound(): {} { "extends" ClassOrInterfaceType() ( "&" ClassOrInterfaceType() )* } void ClassOrInterfaceBody(boolean isInterface): {} { "{" ( ClassOrInterfaceBodyDeclaration(isInterface) )* "}" } void ClassOrInterfaceBodyDeclaration(boolean isInterface): { boolean isNestedInterface = false; int modifiers; } { LOOKAHEAD(2) Initializer() { if (isInterface) throw new ParseException("An interface cannot have initializers"); } | 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) | EnumDeclaration(modifiers) | LOOKAHEAD( [ TypeParameters() ] "(" ) ConstructorDeclaration(modifiers) | LOOKAHEAD( Type() ( "[" "]" )* ( "," | "=" | ";" ) ) FieldDeclaration(modifiers) | MethodDeclaration(modifiers) ) | ";" } void FieldDeclaration(int modifiers): { SourceClass sourceClass = currentClass(); FieldImpl fieldImpl = null; fieldImpl = new FieldImpl(sourceClass, _tagFactory); updateModifiers(modifiers, fieldImpl); updateJavaDoc(fieldImpl); } { // Modifiers are already matched in the caller //Type() VariableDeclarator() ( "," VariableDeclarator() )* ";" FieldType(fieldImpl) FieldDeclarator(fieldImpl) ( "," { FieldImpl badProgrammingStyleFieldImpl = new FieldImpl(sourceClass, _tagFactory); badProgrammingStyleFieldImpl.setType(fieldImpl.getTypeAsString()); } FieldDeclarator(badProgrammingStyleFieldImpl) { sourceClass.addField(badProgrammingStyleFieldImpl); } )* ";" { // we must add the field after parsing the field because the name must be set sourceClass.addField(fieldImpl); } } void FieldType(FieldImpl fieldImpl) : { Token typeToken; String type; } { ( typeToken=PrimitiveType() { if( fieldImpl != null ) { fieldImpl.setType(typeToken.image); } } | type=ClassOrInterfaceType() { if( fieldImpl != null ) { fieldImpl.setType(type); } } ) ( "[" "]" { if( fieldImpl != null ) { fieldImpl.setDimension(fieldImpl.getDimension() + 1); } } )* } void FieldDeclarator(FieldImpl fieldImpl) : {} { FieldVariableDeclaratorId(fieldImpl) [ "=" VariableInitializer() ] } void FieldVariableDeclaratorId(FieldImpl fieldImpl) : { Token t = null; } { t= ( "[" "]" { fieldImpl.setDimension(fieldImpl.getDimension() + 1); } )* { fieldImpl.setName(t.image); } } void VariableDeclarator(): {} { VariableDeclaratorId() [ "=" VariableInitializer() ] } void VariableDeclaratorId(): {} { ( "[" "]" )* } void VariableInitializer(): {} { ArrayInitializer() | Expression() } void ArrayInitializer(): {} { "{" [ VariableInitializer() ( LOOKAHEAD(2) "," VariableInitializer() )* ] [ "," ] "}" } void MethodDeclaration(int modifiers): { SourceClass sourceClass = currentClass(); //this may remain null for anonymous inner classes (sourceClass==null), not a problem because we're not going to access class structure of an anonymous inner class MethodImpl methodImpl = null; if(sourceClass != null) { methodImpl = new MethodImpl(sourceClass, _tagFactory); updateModifiers(modifiers, methodImpl); updateJavaDoc(methodImpl); } } { // Modifiers already matched in the caller! [ TypeParameters() ] ResultType(methodImpl) MethodDeclarator(methodImpl) [ "throws" MethodThrowsNameList(methodImpl) ] ( Block() | ";" ) { // we must add the method after the fields are in, because the // signature must be complete when adding sourceClass.addMethod(methodImpl); } } void MethodDeclarator(MethodImpl methodImpl): { Token t = null; } { t= { if (methodImpl != null) { methodImpl.setName(t.image); } } FormalParameters(methodImpl) ("[" "]" { if (methodImpl != null) { methodImpl.setReturnDimension( methodImpl.getReturnType().getDimension() + 1 ); } })* } void FormalParameters(AbstractExecutableMember member): {} { "(" [ FormalParameter(member) ( "," FormalParameter(member) )* ] ")" } void FormalParameter(AbstractExecutableMember member): { if(member != null) { // reset the _parameter helper's dimension _parameter.dimension = 0; } } { [ "final" ] ParameterType() [ "..." { _parameter.dimension++; } ] ParameterVariableDeclaratorId() { if( member != null ) { member.addParameterData(_parameter.type, _parameter.name, _parameter.dimension); } } } void ParameterVariableDeclaratorId() : { Token t = null; } { t= ( "[" "]" { _parameter.dimension++; } )* { _parameter.name = t.image; } } void ConstructorDeclaration(int modifiers): { SourceClass sourceClass = currentClass(); ConstructorImpl constructor = new ConstructorImpl(sourceClass, _tagFactory); updateModifiers(modifiers, constructor); updateJavaDoc(constructor); } { [ TypeParameters() ] // Modifiers matched in the caller FormalParameters(constructor) [ "throws" MethodThrowsNameList(constructor) ] "{" [ LOOKAHEAD(ExplicitConstructorInvocation()) ExplicitConstructorInvocation() ] ( BlockStatement() )* "}" { // we must add the method after the fields are in, because the signature must be complete when adding sourceClass.addConstructor(constructor); } } void ExplicitConstructorInvocation(): {} { LOOKAHEAD("this" Arguments() ";") "this" Arguments() ";" | [ LOOKAHEAD(2) PrimaryExpression() "." ] "super" Arguments() ";" } void Initializer(): {} { [ "static" ] Block() } /* * Type, name and expression syntax follows. */ void ParameterType() : { Token primitive; String name; } { ( primitive=PrimitiveType() { _parameter.type = primitive.image; } | name=ClassOrInterfaceType() { _parameter.type = name; } ) ( "[" "]" { _parameter.dimension++; } )* } void Type(): {} { LOOKAHEAD(2) ReferenceType() | PrimitiveType() } String ReferenceType(): { Token primitive; StringBuffer sb = new StringBuffer(); String clazz = ""; } { (primitive=PrimitiveType() { sb.append(primitive.image); } ( LOOKAHEAD(2) "[" "]" { sb.append("[]"); } )+ | ( clazz = ClassOrInterfaceType() { sb.append(clazz); } ) ( LOOKAHEAD(2) "[" "]" { sb.append("[]"); } )* ) { return sb.toString(); } } String ClassOrInterfaceType(): { StringBuffer sb = new StringBuffer(); Token t = null; String generics = ""; } { t= { sb.append(t.image); } [ LOOKAHEAD(2) generics = TypeArguments() { sb.append(generics); } ] ( LOOKAHEAD(2) "." t= { sb.append(".").append(t.image); } [ LOOKAHEAD(2) generics = TypeArguments() ] { sb.append(generics); } )* { return sb.length() > 0 ? sb.toString() : null; } } String TypeArguments(): { String ret = ""; StringBuffer sb = new StringBuffer(); } { "<" ret = TypeArgument() { sb.append("<").append(ret); } ( "," ret = TypeArgument() { sb.append(ret); } )* ">" { sb.append(">"); } { return sb.toString(); } } String TypeArgument(): { String ret = ""; } { (ret = ReferenceType() [ WildcardBounds() ]) { return ret; } | ("?" [ WildcardBounds() ]) { return ret; } } void WildcardBounds(): { } { "extends" ReferenceType() | "super" ReferenceType() } Token PrimitiveType(): { Token t = null; } { t="boolean" { return t; } | t="char" { return t; } | t="byte" { return t; } | t="short" { return t; } | t="int" { return t; } | t="long" { return t; } | t="float" { return t; } | t="double" { return t; } } void ResultType(MethodImpl methodImpl): { Token tt = null; } { (tt="void" { if( methodImpl != null ) { methodImpl.setReturnType( "void" ); methodImpl.setReturnDimension(0); } }) | (MethodType(methodImpl) { if( methodImpl != null ) { } }) } void MethodType(MethodImpl methodImpl): { Token tt; String type = null; } { (tt=PrimitiveType() { if( methodImpl != null ) { methodImpl.setReturnType(tt.image); } } | type=ClassOrInterfaceType() { if( methodImpl != null ) { methodImpl.setReturnType(type); } } ) ( "[" "]" { if( methodImpl != null ) { methodImpl.setReturnDimension(methodImpl.getReturnType().getDimension() + 1); } } )* } String Name(): /* * A lookahead of 2 is required below since "Name" can be followed * by a ".*" when used in the context of an "ImportDeclaration". */ { StringBuffer sb = new StringBuffer(); Token t = null; } { t= { sb.append(t.image); } ( LOOKAHEAD(2) "." t= { sb.append(".").append(t.image); } )* { return sb.toString(); } } void MethodThrowsNameList(AbstractExecutableMember member): { List namesList = new ArrayList(); String name = null; } { name=Name() { namesList.add(name); } ( "," name=Name() { namesList.add(name); } )* { if (log.isDebugEnabled()) log.debug("Throws names list=" + namesList); if (member != null) { for (int i = 0; i < namesList.size(); ++i) { String exceptionName = (String) namesList.get(i); if (exceptionName == null || "".equals(exceptionName)) continue; if (log.isDebugEnabled()) log.debug("addThrownException=" + exceptionName); member.addThrownException(exceptionName); } } } } void NameList(): {} { Name() ( "," Name() )* } /* * Expression syntax follows. */ void Expression(): /* * This expansion has been written this way instead of: * Assignment() | ConditionalExpression() * for performance reasons. * However, it is a weakening of the grammar for it allows the LHS of * assignments to be any conditional expression whereas it can only be * a primary expression. Consider adding a semantic predicate to work * around this. */ {} { ConditionalExpression() [ 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() ")" ( "~" | "!" | "(" | | "this" | "super" | "new" | Literal() ) } void PostfixExpression(): {} { PrimaryExpression() [ "++" | "--" ] } void CastExpression(): {} { LOOKAHEAD("(" PrimitiveType()) "(" Type() ")" UnaryExpression() | "(" Type() ")" UnaryExpressionNotPlusMinus() } void PrimaryExpression(): {} { PrimaryPrefix() ( LOOKAHEAD(2) PrimarySuffix() )* } void MemberSelector(): {} { "." TypeArguments() } void PrimaryPrefix(): {} { Literal() | "this" | "super" "." | "(" Expression() ")" | AllocationExpression() | LOOKAHEAD( ResultType(null) "." "class" ) ResultType(null) "." "class" | Name() } void PrimarySuffix(): {} { LOOKAHEAD(2) "." "this" | LOOKAHEAD(2) "." "super" | LOOKAHEAD(2) "." AllocationExpression() | LOOKAHEAD(3) MemberSelector() | "[" Expression() "]" | "." | Arguments() } void Literal(): {} { | | | | BooleanLiteral() | NullLiteral() } void BooleanLiteral(): {} { "true" | "false" } void NullLiteral(): {} { "null" } void Arguments(): {} { "(" [ ArgumentList() ] ")" } void ArgumentList(): {} { Expression() ( "," Expression() )* } void AllocationExpression(): { String realisedClass = null; } { LOOKAHEAD(2) "new" PrimitiveType() ArrayDimsAndInits() | "new" realisedClass=ClassOrInterfaceType() [ TypeArguments() ] ( ArrayDimsAndInits() | Arguments() [ { // ANONYMOUS CLASS SourceClass containingClass = currentClass(); pushAndGet(); } ClassOrInterfaceBody(false) { currentClass().setName(containingClass.getNextAnonymousClassName()); currentClass().setRealised(realisedClass); popAndAddInner(); } ] ) } /* * 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(): {} { ":" Statement() } void Block(): {} { "{" ( BlockStatement() )* "}" } void BlockStatement(): {} { LOOKAHEAD([ "final" ] Type() ) LocalVariableDeclaration() ";" | Statement() | ClassOrInterfaceDeclaration(0) } 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( Modifiers() Type() ":" ) Modifiers() Type() ":" Expression() | [ ForInit() ] ";" [ Expression() ] ";" [ ForUpdate() ] ) ")" Statement() } void ForInit(): {} { LOOKAHEAD( [ "final" ] Type() ) LocalVariableDeclaration() | StatementExpressionList() } void StatementExpressionList(): {} { StatementExpression() ( "," StatementExpression() )* } void ForUpdate(): {} { StatementExpressionList() } void BreakStatement(): {} { "break" [ ] ";" } void ContinueStatement(): {} { "continue" [ ] ";" } 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(null) ")" 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() "(" ( "=" | ")" )) NormalAnnotation() | LOOKAHEAD( "@" Name() "(" ) SingleMemberAnnotation() | MarkerAnnotation() } void NormalAnnotation(): {} { "@" Name() "(" [ MemberValuePairs() ] ")" } void MarkerAnnotation(): {} { "@" Name() } void SingleMemberAnnotation(): {} { "@" Name() "(" MemberValue() ")" } void MemberValuePairs(): {} { MemberValuePair() ( "," MemberValuePair() )* } void MemberValuePair(): {} { "=" MemberValue() } void MemberValue(): {} { Annotation() | MemberValueArrayInitializer() | ConditionalExpression() } void MemberValueArrayInitializer(): {} { "{" MemberValue() ( LOOKAHEAD(2) "," MemberValue() )* [ "," ] "}" } /* Annotation Types. */ void AnnotationTypeDeclaration(int modifiers): { //Now annotations will be as simple interfaces //todo - hardcore annotations in xjavadoc Token name = null; SourceClass sourceClass = pushAndGet(); //pushAndGet as interface } { "@" "interface" name= { sourceClass.setQualifiedName(Util.getQualifiedNameFor(_packageName, name.image)); sourceClass.setInterface(true); _xJavaDoc.addPackageMaybe( _packageName ).addClass(sourceClass); _xJavaDoc.addSourceClass(sourceClass); } AnnotationTypeBody() { popAndAddInner(); } } void AnnotationTypeBody(): {} { "{" ( AnnotationTypeMemberDeclaration() )* "}" } void AnnotationTypeMemberDeclaration(): { int modifiers; } { modifiers = Modifiers() ( LOOKAHEAD(Type() "(") Type() "(" ")" [ DefaultValue() ] ";" | ClassOrInterfaceDeclaration(modifiers) | EnumDeclaration(modifiers) | AnnotationTypeDeclaration(modifiers) | FieldDeclaration(modifiers) ) | ( ";" ) } void DefaultValue(): {} { "default" MemberValue() }