aboutsummaryrefslogtreecommitdiff
path: root/javaparser-core/src/main/javacc/java.jj
diff options
context:
space:
mode:
Diffstat (limited to 'javaparser-core/src/main/javacc/java.jj')
-rw-r--r--javaparser-core/src/main/javacc/java.jj2795
1 files changed, 2795 insertions, 0 deletions
diff --git a/javaparser-core/src/main/javacc/java.jj b/javaparser-core/src/main/javacc/java.jj
new file mode 100644
index 000000000..c68822878
--- /dev/null
+++ b/javaparser-core/src/main/javacc/java.jj
@@ -0,0 +1,2795 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+options {
+ STATIC=false;
+ COMMON_TOKEN_ACTION=true;
+ JDK_VERSION = "1.8";
+ TOKEN_EXTENDS ="TokenBase";
+ JAVA_TEMPLATE_TYPE = "modern";
+}
+
+PARSER_BEGIN(GeneratedJavaParser)
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser;
+import java.io.*;
+import java.util.*;
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import com.github.javaparser.utils.*;
+import javax.annotation.Generated;
+import static com.github.javaparser.JavaToken.INVALID;
+import static com.github.javaparser.ast.Node.Parsedness.UNPARSABLE;
+import static com.github.javaparser.utils.Utils.*;
+import static com.github.javaparser.ast.NodeList.*;
+import static com.github.javaparser.GeneratedJavaParser.*;
+import static com.github.javaparser.Range.*;
+import static com.github.javaparser.Position.*;
+import static com.github.javaparser.ast.type.ArrayType.*;
+import static com.github.javaparser.GeneratedJavaParserTokenManagerBase.*;
+
+@Generated("JavaCC")
+final class GeneratedJavaParser extends GeneratedJavaParserBase {
+ /* Returns the JavaParser specific token type of the last matched token */
+ JavaToken token() {
+ return token.javaToken;
+ }
+
+ /* Changes the amount by which the horizontal position is increased when a tab character is encountered.
+ One by default.*/
+ void setTabSize(int size) {
+ jj_input_stream.setTabSize(size);
+ }
+
+ @Override
+ GeneratedJavaParserTokenManager getTokenSource() {
+ return token_source;
+ }
+}
+
+PARSER_END(GeneratedJavaParser)
+
+/* WHITE SPACE */
+
+SPECIAL_TOKEN :
+{
+ <SPACE: [" ", "\t", "\f", "\u0085", "\u00A0", "\u1680", "\u180e", "\u2000", "\u2001", "\u2002", "\u2003", "\u2004", "\u2005",
+ "\u2006", "\u2007", "\u2008", "\u2009", "\u200a", "\u200b", "\u200c", "\u200d", "\u2028", "\u2029", "\u202f", "\u205f", "\u2060", "\u3000", "\ufeff"]>
+| <WINDOWS_EOL : "\r\n">
+| <UNIX_EOL: "\n">
+| <OLD_MAC_EOL: "\r">
+}
+
+TOKEN_MGR_DECLS :
+{
+ private List<JavaToken> tokens = new ArrayList<JavaToken>();
+ private CommentsCollection commentsCollection = new CommentsCollection();
+ private JavaToken homeToken;
+ private Stack<Token> tokenWorkStack = new Stack<Token>();
+ private boolean storeTokens;
+
+ void reset() {
+ tokens = new ArrayList<JavaToken>();
+ commentsCollection = new CommentsCollection();
+ homeToken = null;
+ }
+
+ List<JavaToken> getTokens() {
+ if(storeTokens) {
+ return tokens;
+ }
+ return null;
+ }
+
+ CommentsCollection getCommentsCollection() {
+ return commentsCollection;
+ }
+
+ /* Get the very first token in the file */
+ JavaToken getHomeToken() {
+ return homeToken;
+ }
+
+ /* Makes the parser keep a list of tokens */
+ public void setStoreTokens(boolean storeTokens) {
+ this.storeTokens = storeTokens;
+ }
+
+ private void CommonTokenAction(Token token) {
+ // Use an intermediary stack to avoid recursion, see issue 1003
+ do {
+ tokenWorkStack.push(token);
+ token = token.specialToken;
+ } while (token != null);
+
+ // The stack is now filled with tokens in left-to-right order. Process them.
+ while(!tokenWorkStack.empty()) {
+ token = tokenWorkStack.pop();
+ token.javaToken = new JavaToken(token, tokens);
+
+ if(storeTokens) {
+ tokens.add(token.javaToken);
+ }
+
+ if (homeToken == null) {
+ homeToken = token.javaToken;
+ }
+
+ if(TokenTypes.isComment(token.kind)) {
+ Comment comment = createCommentFromToken(token);
+ commentsCollection.addComment(comment);
+ }
+ }
+ }
+}
+
+/* COMMENTS */
+
+SPECIAL_TOKEN :
+{
+ <SINGLE_LINE_COMMENT: "//" (~["\n","\r"])* ("\n"|"\r"|"\r\n")? >
+}
+
+MORE :
+{
+ <ENTER_JAVADOC_COMMENT: "/**" ~["/"]> { input_stream.backup(1); } : IN_JAVADOC_COMMENT
+|
+ <ENTER_MULTILINE_COMMENT: "/*"> : IN_MULTI_LINE_COMMENT
+}
+
+<IN_JAVADOC_COMMENT>
+SPECIAL_TOKEN :
+{
+ <JAVADOC_COMMENT: "*/" > : DEFAULT
+}
+
+<IN_MULTI_LINE_COMMENT>
+SPECIAL_TOKEN :
+{
+ <MULTI_LINE_COMMENT: "*/" > : DEFAULT
+}
+
+<IN_JAVADOC_COMMENT, IN_MULTI_LINE_COMMENT>
+MORE :
+{
+ <COMMENT_CONTENT: ~[] >
+}
+
+/* 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" >
+| < REQUIRES: "requires" >
+| < TO: "to" >
+| < WITH: "with" >
+| < OPEN: "open" >
+| < OPENS: "opens" >
+| < USES: "uses" >
+| < MODULE: "module" >
+| < EXPORTS: "exports" >
+| < PROVIDES: "provides" >
+| < TRANSITIVE: "transitive" >
+}
+
+/* LITERALS */
+
+TOKEN :
+{
+ < LONG_LITERAL:
+ <DECIMAL_LITERAL> (["l","L"])
+ | <HEX_LITERAL> (["l","L"])
+ | <OCTAL_LITERAL> (["l","L"])
+ | <BINARY_LITERAL> (["l","L"])
+ >
+|
+ < INTEGER_LITERAL:
+ <DECIMAL_LITERAL>
+ | <HEX_LITERAL>
+ | <OCTAL_LITERAL>
+ | <BINARY_LITERAL>
+ >
+|
+ < #DECIMAL_LITERAL: ["0"-"9"]((["0"-"9","_"])*["0"-"9"])? >
+|
+ < #HEX_LITERAL: "0" ["x","X"] <HEX_DIGITS> >
+|
+ < #OCTAL_LITERAL: "0" ["0"-"7"]((["0"-"7","_"])*["0"-"7"])? >
+|
+ < #BINARY_LITERAL: "0" ["b","B"] ["0","1"]((["0","1","_"])*["0","1"])? >
+|
+ < FLOATING_POINT_LITERAL:
+ <DECIMAL_FLOATING_POINT_LITERAL>
+ | <HEXADECIMAL_FLOATING_POINT_LITERAL>
+ >
+|
+ < #DECIMAL_FLOATING_POINT_LITERAL:
+ <DECIMAL_LITERAL> "." (<DECIMAL_LITERAL>)? (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
+ | "." <DECIMAL_LITERAL> (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
+ | <DECIMAL_LITERAL> <DECIMAL_EXPONENT> (["f","F","d","D"])?
+ | <DECIMAL_LITERAL> (<DECIMAL_EXPONENT>)? ["f","F","d","D"]
+ >
+|
+ < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (<DECIMAL_LITERAL>)+ >
+|
+ < #HEXADECIMAL_FLOATING_POINT_LITERAL:
+ <HEX_LITERAL> (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
+ | "0" ["x","X"] (<HEX_DIGITS>)? "." <HEX_DIGITS> <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
+ >
+|
+ < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? <DECIMAL_LITERAL> >
+|
+ < #HEX_DIGITS: ["0"-"9","a"-"f","A"-"F"]((["0"-"9","a"-"f","A"-"F","_"])*["0"-"9","a"-"f","A"-"F"])? >
+|
+ < #UNICODE_ESCAPE:
+ "\\u"
+ ["0"-"9","A"-"F","a"-"f"]
+ ["0"-"9","A"-"F","a"-"f"]
+ ["0"-"9","A"-"F","a"-"f"]
+ ["0"-"9","A"-"F","a"-"f"] >
+|
+ < CHARACTER_LITERAL:
+ "'"
+ ( (~["'","\\","\n","\r"])
+ | ("\\"
+ ( ["n","t","b","r","f","\\","'","\""]
+ | ["0"-"7"] ( ["0"-"7"] )?
+ | ["0"-"3"] ["0"-"7"] ["0"-"7"]
+ )
+ )
+ | <UNICODE_ESCAPE>
+ )
+ "'"
+ >
+|
+ < STRING_LITERAL:
+ "\""
+ ( (~["\"","\\","\n","\r"])
+ | ("\\"
+ ( ["n","t","b","r","f","\\","'","\""]
+ | ["0"-"7"] ( ["0"-"7"] )?
+ | ["0"-"3"] ["0"-"7"] ["0"-"7"]
+ )
+ )
+ | ("\\u"
+ ["0"-"9","A"-"F","a"-"f"]
+ ["0"-"9","A"-"F","a"-"f"]
+ ["0"-"9","A"-"F","a"-"f"]
+ ["0"-"9","A"-"F","a"-"f"]
+ )
+ )*
+ "\""
+ >
+}
+
+/* IDENTIFIERS */
+
+TOKEN :
+{
+ < IDENTIFIER: <LETTER> (<PART_LETTER>)* >
+|
+ < #LETTER: [
+ "\u0024", "\u0041"-"\u005a", "\u005f", "\u0061"-"\u007a", "\u00a2"-"\u00a5", "\u00aa", "\u00b5",
+ "\u00ba", "\u00c0"-"\u00d6", "\u00d8"-"\u00f6", "\u00f8"-"\u02c1", "\u02c6"-"\u02d1", "\u02e0"-"\u02e4",
+ "\u02ec", "\u02ee", "\u0370"-"\u0374", "\u0376"-"\u0377", "\u037a"-"\u037d", "\u0386", "\u0388"-"\u038a",
+ "\u038c", "\u038e"-"\u03a1", "\u03a3"-"\u03f5", "\u03f7"-"\u0481", "\u048a"-"\u0527", "\u0531"-"\u0556",
+ "\u0559", "\u0561"-"\u0587", "\u058f", "\u05d0"-"\u05ea", "\u05f0"-"\u05f2", "\u060b", "\u0620"-"\u064a",
+ "\u066e"-"\u066f", "\u0671"-"\u06d3", "\u06d5", "\u06e5"-"\u06e6", "\u06ee"-"\u06ef", "\u06fa"-"\u06fc",
+ "\u06ff", "\u0710", "\u0712"-"\u072f", "\u074d"-"\u07a5", "\u07b1", "\u07ca"-"\u07ea", "\u07f4"-"\u07f5",
+ "\u07fa", "\u0800"-"\u0815", "\u081a", "\u0824", "\u0828", "\u0840"-"\u0858", "\u08a0", "\u08a2"-"\u08ac",
+ "\u0904"-"\u0939", "\u093d", "\u0950", "\u0958"-"\u0961", "\u0971"-"\u0977", "\u0979"-"\u097f",
+ "\u0985"-"\u098c", "\u098f"-"\u0990", "\u0993"-"\u09a8", "\u09aa"-"\u09b0", "\u09b2", "\u09b6"-"\u09b9",
+ "\u09bd", "\u09ce", "\u09dc"-"\u09dd", "\u09df"-"\u09e1", "\u09f0"-"\u09f3", "\u09fb", "\u0a05"-"\u0a0a",
+ "\u0a0f"-"\u0a10", "\u0a13"-"\u0a28", "\u0a2a"-"\u0a30", "\u0a32"-"\u0a33", "\u0a35"-"\u0a36",
+ "\u0a38"-"\u0a39", "\u0a59"-"\u0a5c", "\u0a5e", "\u0a72"-"\u0a74", "\u0a85"-"\u0a8d", "\u0a8f"-"\u0a91",
+ "\u0a93"-"\u0aa8", "\u0aaa"-"\u0ab0", "\u0ab2"-"\u0ab3", "\u0ab5"-"\u0ab9", "\u0abd", "\u0ad0",
+ "\u0ae0"-"\u0ae1", "\u0af1", "\u0b05"-"\u0b0c", "\u0b0f"-"\u0b10", "\u0b13"-"\u0b28", "\u0b2a"-"\u0b30",
+ "\u0b32"-"\u0b33", "\u0b35"-"\u0b39", "\u0b3d", "\u0b5c"-"\u0b5d", "\u0b5f"-"\u0b61", "\u0b71",
+ "\u0b83", "\u0b85"-"\u0b8a", "\u0b8e"-"\u0b90", "\u0b92"-"\u0b95", "\u0b99"-"\u0b9a", "\u0b9c",
+ "\u0b9e"-"\u0b9f", "\u0ba3"-"\u0ba4", "\u0ba8"-"\u0baa", "\u0bae"-"\u0bb9", "\u0bd0", "\u0bf9",
+ "\u0c05"-"\u0c0c", "\u0c0e"-"\u0c10", "\u0c12"-"\u0c28", "\u0c2a"-"\u0c33", "\u0c35"-"\u0c39",
+ "\u0c3d", "\u0c58"-"\u0c59", "\u0c60"-"\u0c61", "\u0c85"-"\u0c8c", "\u0c8e"-"\u0c90", "\u0c92"-"\u0ca8",
+ "\u0caa"-"\u0cb3", "\u0cb5"-"\u0cb9", "\u0cbd", "\u0cde", "\u0ce0"-"\u0ce1", "\u0cf1"-"\u0cf2",
+ "\u0d05"-"\u0d0c", "\u0d0e"-"\u0d10", "\u0d12"-"\u0d3a", "\u0d3d", "\u0d4e", "\u0d60"-"\u0d61",
+ "\u0d7a"-"\u0d7f", "\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"-"\u0edf", "\u0f00", "\u0f40"-"\u0f47", "\u0f49"-"\u0f6c", "\u0f88"-"\u0f8c", "\u1000"-"\u102a",
+ "\u103f", "\u1050"-"\u1055", "\u105a"-"\u105d", "\u1061", "\u1065"-"\u1066", "\u106e"-"\u1070",
+ "\u1075"-"\u1081", "\u108e", "\u10a0"-"\u10c5", "\u10c7", "\u10cd", "\u10d0"-"\u10fa", "\u10fc"-"\u1248",
+ "\u124a"-"\u124d", "\u1250"-"\u1256", "\u1258", "\u125a"-"\u125d", "\u1260"-"\u1288", "\u128a"-"\u128d",
+ "\u1290"-"\u12b0", "\u12b2"-"\u12b5", "\u12b8"-"\u12be", "\u12c0", "\u12c2"-"\u12c5", "\u12c8"-"\u12d6",
+ "\u12d8"-"\u1310", "\u1312"-"\u1315", "\u1318"-"\u135a", "\u1380"-"\u138f", "\u13a0"-"\u13f4",
+ "\u1401"-"\u166c", "\u166f"-"\u167f", "\u1681"-"\u169a", "\u16a0"-"\u16ea", "\u16ee"-"\u16f0",
+ "\u1700"-"\u170c", "\u170e"-"\u1711", "\u1720"-"\u1731", "\u1740"-"\u1751", "\u1760"-"\u176c",
+ "\u176e"-"\u1770", "\u1780"-"\u17b3", "\u17d7", "\u17db"-"\u17dc", "\u1820"-"\u1877", "\u1880"-"\u18a8",
+ "\u18aa", "\u18b0"-"\u18f5", "\u1900"-"\u191c", "\u1950"-"\u196d", "\u1970"-"\u1974", "\u1980"-"\u19ab",
+ "\u19c1"-"\u19c7", "\u1a00"-"\u1a16", "\u1a20"-"\u1a54", "\u1aa7", "\u1b05"-"\u1b33", "\u1b45"-"\u1b4b",
+ "\u1b83"-"\u1ba0", "\u1bae"-"\u1baf", "\u1bba"-"\u1be5", "\u1c00"-"\u1c23", "\u1c4d"-"\u1c4f",
+ "\u1c5a"-"\u1c7d", "\u1ce9"-"\u1cec", "\u1cee"-"\u1cf1", "\u1cf5"-"\u1cf6", "\u1d00"-"\u1dbf",
+ "\u1e00"-"\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", "\u2054", "\u2071", "\u207f", "\u2090"-"\u209c",
+ "\u20a0"-"\u20ba", "\u2102", "\u2107", "\u210a"-"\u2113", "\u2115", "\u2119"-"\u211d", "\u2124",
+ "\u2126", "\u2128", "\u212a"-"\u212d", "\u212f"-"\u2139", "\u213c"-"\u213f", "\u2145"-"\u2149",
+ "\u214e", "\u2160"-"\u2188", "\u2c00"-"\u2c2e", "\u2c30"-"\u2c5e", "\u2c60"-"\u2ce4", "\u2ceb"-"\u2cee",
+ "\u2cf2"-"\u2cf3", "\u2d00"-"\u2d25", "\u2d27", "\u2d2d", "\u2d30"-"\u2d67", "\u2d6f", "\u2d80"-"\u2d96",
+ "\u2da0"-"\u2da6", "\u2da8"-"\u2dae", "\u2db0"-"\u2db6", "\u2db8"-"\u2dbe", "\u2dc0"-"\u2dc6",
+ "\u2dc8"-"\u2dce", "\u2dd0"-"\u2dd6", "\u2dd8"-"\u2dde", "\u2e2f", "\u3005"-"\u3007", "\u3021"-"\u3029",
+ "\u3031"-"\u3035", "\u3038"-"\u303c", "\u3041"-"\u3096", "\u309d"-"\u309f", "\u30a1"-"\u30fa",
+ "\u30fc"-"\u30ff", "\u3105"-"\u312d", "\u3131"-"\u318e", "\u31a0"-"\u31ba", "\u31f0"-"\u31ff",
+ "\u3400"-"\u4db5", "\u4e00"-"\u9fcc", "\ua000"-"\ua48c", "\ua4d0"-"\ua4fd", "\ua500"-"\ua60c",
+ "\ua610"-"\ua61f", "\ua62a"-"\ua62b", "\ua640"-"\ua66e", "\ua67f"-"\ua697", "\ua6a0"-"\ua6ef",
+ "\ua717"-"\ua71f", "\ua722"-"\ua788", "\ua78b"-"\ua78e", "\ua790"-"\ua793", "\ua7a0"-"\ua7aa",
+ "\ua7f8"-"\ua801", "\ua803"-"\ua805", "\ua807"-"\ua80a", "\ua80c"-"\ua822", "\ua838", "\ua840"-"\ua873",
+ "\ua882"-"\ua8b3", "\ua8f2"-"\ua8f7", "\ua8fb", "\ua90a"-"\ua925", "\ua930"-"\ua946", "\ua960"-"\ua97c",
+ "\ua984"-"\ua9b2", "\ua9cf", "\uaa00"-"\uaa28", "\uaa40"-"\uaa42", "\uaa44"-"\uaa4b", "\uaa60"-"\uaa76",
+ "\uaa7a", "\uaa80"-"\uaaaf", "\uaab1", "\uaab5"-"\uaab6", "\uaab9"-"\uaabd", "\uaac0", "\uaac2",
+ "\uaadb"-"\uaadd", "\uaae0"-"\uaaea", "\uaaf2"-"\uaaf4", "\uab01"-"\uab06", "\uab09"-"\uab0e",
+ "\uab11"-"\uab16", "\uab20"-"\uab26", "\uab28"-"\uab2e", "\uabc0"-"\uabe2", "\uac00"-"\ud7a3",
+ "\ud7b0"-"\ud7c6", "\ud7cb"-"\ud7fb", "\ud800"-"\udfff", "\uf900"-"\ufa6d", "\ufa70"-"\ufad9",
+ "\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"-"\ufdfc", "\ufe33"-"\ufe34", "\ufe4d"-"\ufe4f", "\ufe69", "\ufe70"-"\ufe74",
+ "\ufe76"-"\ufefc", "\uff04", "\uff21"-"\uff3a", "\uff3f", "\uff41"-"\uff5a", "\uff66"-"\uffbe",
+ "\uffc2"-"\uffc7", "\uffca"-"\uffcf", "\uffd2"-"\uffd7", "\uffda"-"\uffdc", "\uffe0"-"\uffe1",
+ "\uffe5"-"\uffe6" ]
+ | <UNICODE_ESCAPE>
+ >
+|
+ < #PART_LETTER: [
+ "\u0000"-"\u0008", "\u000e"-"\u001b", "\u0024", "\u0030"-"\u0039", "\u0041"-"\u005a", "\u005f",
+ "\u0061"-"\u007a", "\u007f"-"\u009f", "\u00a2"-"\u00a5", "\u00aa", "\u00ad", "\u00b5", "\u00ba",
+ "\u00c0"-"\u00d6", "\u00d8"-"\u00f6", "\u00f8"-"\u02c1", "\u02c6"-"\u02d1", "\u02e0"-"\u02e4",
+ "\u02ec", "\u02ee", "\u0300"-"\u0374", "\u0376"-"\u0377", "\u037a"-"\u037d", "\u0386", "\u0388"-"\u038a",
+ "\u038c", "\u038e"-"\u03a1", "\u03a3"-"\u03f5", "\u03f7"-"\u0481", "\u0483"-"\u0487", "\u048a"-"\u0527",
+ "\u0531"-"\u0556", "\u0559", "\u0561"-"\u0587", "\u058f", "\u0591"-"\u05bd", "\u05bf", "\u05c1"-"\u05c2",
+ "\u05c4"-"\u05c5", "\u05c7", "\u05d0"-"\u05ea", "\u05f0"-"\u05f2", "\u0600"-"\u0604", "\u060b",
+ "\u0610"-"\u061a", "\u0620"-"\u0669", "\u066e"-"\u06d3", "\u06d5"-"\u06dd", "\u06df"-"\u06e8",
+ "\u06ea"-"\u06fc", "\u06ff", "\u070f"-"\u074a", "\u074d"-"\u07b1", "\u07c0"-"\u07f5", "\u07fa",
+ "\u0800"-"\u082d", "\u0840"-"\u085b", "\u08a0", "\u08a2"-"\u08ac", "\u08e4"-"\u08fe", "\u0900"-"\u0963",
+ "\u0966"-"\u096f", "\u0971"-"\u0977", "\u0979"-"\u097f", "\u0981"-"\u0983", "\u0985"-"\u098c",
+ "\u098f"-"\u0990", "\u0993"-"\u09a8", "\u09aa"-"\u09b0", "\u09b2", "\u09b6"-"\u09b9", "\u09bc"-"\u09c4",
+ "\u09c7"-"\u09c8", "\u09cb"-"\u09ce", "\u09d7", "\u09dc"-"\u09dd", "\u09df"-"\u09e3", "\u09e6"-"\u09f3",
+ "\u09fb", "\u0a01"-"\u0a03", "\u0a05"-"\u0a0a", "\u0a0f"-"\u0a10", "\u0a13"-"\u0a28", "\u0a2a"-"\u0a30",
+ "\u0a32"-"\u0a33", "\u0a35"-"\u0a36", "\u0a38"-"\u0a39", "\u0a3c", "\u0a3e"-"\u0a42", "\u0a47"-"\u0a48",
+ "\u0a4b"-"\u0a4d", "\u0a51", "\u0a59"-"\u0a5c", "\u0a5e", "\u0a66"-"\u0a75", "\u0a81"-"\u0a83",
+ "\u0a85"-"\u0a8d", "\u0a8f"-"\u0a91", "\u0a93"-"\u0aa8", "\u0aaa"-"\u0ab0", "\u0ab2"-"\u0ab3",
+ "\u0ab5"-"\u0ab9", "\u0abc"-"\u0ac5", "\u0ac7"-"\u0ac9", "\u0acb"-"\u0acd", "\u0ad0", "\u0ae0"-"\u0ae3",
+ "\u0ae6"-"\u0aef", "\u0af1", "\u0b01"-"\u0b03", "\u0b05"-"\u0b0c", "\u0b0f"-"\u0b10", "\u0b13"-"\u0b28",
+ "\u0b2a"-"\u0b30", "\u0b32"-"\u0b33", "\u0b35"-"\u0b39", "\u0b3c"-"\u0b44", "\u0b47"-"\u0b48",
+ "\u0b4b"-"\u0b4d", "\u0b56"-"\u0b57", "\u0b5c"-"\u0b5d", "\u0b5f"-"\u0b63", "\u0b66"-"\u0b6f",
+ "\u0b71", "\u0b82"-"\u0b83", "\u0b85"-"\u0b8a", "\u0b8e"-"\u0b90", "\u0b92"-"\u0b95", "\u0b99"-"\u0b9a",
+ "\u0b9c", "\u0b9e"-"\u0b9f", "\u0ba3"-"\u0ba4", "\u0ba8"-"\u0baa", "\u0bae"-"\u0bb9", "\u0bbe"-"\u0bc2",
+ "\u0bc6"-"\u0bc8", "\u0bca"-"\u0bcd", "\u0bd0", "\u0bd7", "\u0be6"-"\u0bef", "\u0bf9", "\u0c01"-"\u0c03",
+ "\u0c05"-"\u0c0c", "\u0c0e"-"\u0c10", "\u0c12"-"\u0c28", "\u0c2a"-"\u0c33", "\u0c35"-"\u0c39",
+ "\u0c3d"-"\u0c44", "\u0c46"-"\u0c48", "\u0c4a"-"\u0c4d", "\u0c55"-"\u0c56", "\u0c58"-"\u0c59",
+ "\u0c60"-"\u0c63", "\u0c66"-"\u0c6f", "\u0c82"-"\u0c83", "\u0c85"-"\u0c8c", "\u0c8e"-"\u0c90",
+ "\u0c92"-"\u0ca8", "\u0caa"-"\u0cb3", "\u0cb5"-"\u0cb9", "\u0cbc"-"\u0cc4", "\u0cc6"-"\u0cc8",
+ "\u0cca"-"\u0ccd", "\u0cd5"-"\u0cd6", "\u0cde", "\u0ce0"-"\u0ce3", "\u0ce6"-"\u0cef", "\u0cf1"-"\u0cf2",
+ "\u0d02"-"\u0d03", "\u0d05"-"\u0d0c", "\u0d0e"-"\u0d10", "\u0d12"-"\u0d3a", "\u0d3d"-"\u0d44",
+ "\u0d46"-"\u0d48", "\u0d4a"-"\u0d4e", "\u0d57", "\u0d60"-"\u0d63", "\u0d66"-"\u0d6f", "\u0d7a"-"\u0d7f",
+ "\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"-"\u0edf", "\u0f00", "\u0f18"-"\u0f19", "\u0f20"-"\u0f29", "\u0f35", "\u0f37", "\u0f39",
+ "\u0f3e"-"\u0f47", "\u0f49"-"\u0f6c", "\u0f71"-"\u0f84", "\u0f86"-"\u0f97", "\u0f99"-"\u0fbc",
+ "\u0fc6", "\u1000"-"\u1049", "\u1050"-"\u109d", "\u10a0"-"\u10c5", "\u10c7", "\u10cd", "\u10d0"-"\u10fa",
+ "\u10fc"-"\u1248", "\u124a"-"\u124d", "\u1250"-"\u1256", "\u1258", "\u125a"-"\u125d", "\u1260"-"\u1288",
+ "\u128a"-"\u128d", "\u1290"-"\u12b0", "\u12b2"-"\u12b5", "\u12b8"-"\u12be", "\u12c0", "\u12c2"-"\u12c5",
+ "\u12c8"-"\u12d6", "\u12d8"-"\u1310", "\u1312"-"\u1315", "\u1318"-"\u135a", "\u135d"-"\u135f",
+ "\u1380"-"\u138f", "\u13a0"-"\u13f4", "\u1401"-"\u166c", "\u166f"-"\u167f", "\u1681"-"\u169a",
+ "\u16a0"-"\u16ea", "\u16ee"-"\u16f0", "\u1700"-"\u170c", "\u170e"-"\u1714", "\u1720"-"\u1734",
+ "\u1740"-"\u1753", "\u1760"-"\u176c", "\u176e"-"\u1770", "\u1772"-"\u1773", "\u1780"-"\u17d3",
+ "\u17d7", "\u17db"-"\u17dd", "\u17e0"-"\u17e9", "\u180b"-"\u180d", "\u1810"-"\u1819", "\u1820"-"\u1877",
+ "\u1880"-"\u18aa", "\u18b0"-"\u18f5", "\u1900"-"\u191c", "\u1920"-"\u192b", "\u1930"-"\u193b",
+ "\u1946"-"\u196d", "\u1970"-"\u1974", "\u1980"-"\u19ab", "\u19b0"-"\u19c9", "\u19d0"-"\u19d9",
+ "\u1a00"-"\u1a1b", "\u1a20"-"\u1a5e", "\u1a60"-"\u1a7c", "\u1a7f"-"\u1a89", "\u1a90"-"\u1a99",
+ "\u1aa7", "\u1b00"-"\u1b4b", "\u1b50"-"\u1b59", "\u1b6b"-"\u1b73", "\u1b80"-"\u1bf3", "\u1c00"-"\u1c37",
+ "\u1c40"-"\u1c49", "\u1c4d"-"\u1c7d", "\u1cd0"-"\u1cd2", "\u1cd4"-"\u1cf6", "\u1d00"-"\u1de6",
+ "\u1dfc"-"\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", "\u200b"-"\u200f", "\u202a"-"\u202e", "\u203f"-"\u2040",
+ "\u2054", "\u2060"-"\u2064", "\u206a"-"\u206f", "\u2071", "\u207f", "\u2090"-"\u209c", "\u20a0"-"\u20ba",
+ "\u20d0"-"\u20dc", "\u20e1", "\u20e5"-"\u20f0", "\u2102", "\u2107", "\u210a"-"\u2113", "\u2115",
+ "\u2119"-"\u211d", "\u2124", "\u2126", "\u2128", "\u212a"-"\u212d", "\u212f"-"\u2139", "\u213c"-"\u213f",
+ "\u2145"-"\u2149", "\u214e", "\u2160"-"\u2188", "\u2c00"-"\u2c2e", "\u2c30"-"\u2c5e", "\u2c60"-"\u2ce4",
+ "\u2ceb"-"\u2cf3", "\u2d00"-"\u2d25", "\u2d27", "\u2d2d", "\u2d30"-"\u2d67", "\u2d6f", "\u2d7f"-"\u2d96",
+ "\u2da0"-"\u2da6", "\u2da8"-"\u2dae", "\u2db0"-"\u2db6", "\u2db8"-"\u2dbe", "\u2dc0"-"\u2dc6",
+ "\u2dc8"-"\u2dce", "\u2dd0"-"\u2dd6", "\u2dd8"-"\u2dde", "\u2de0"-"\u2dff", "\u2e2f", "\u3005"-"\u3007",
+ "\u3021"-"\u302f", "\u3031"-"\u3035", "\u3038"-"\u303c", "\u3041"-"\u3096", "\u3099"-"\u309a",
+ "\u309d"-"\u309f", "\u30a1"-"\u30fa", "\u30fc"-"\u30ff", "\u3105"-"\u312d", "\u3131"-"\u318e",
+ "\u31a0"-"\u31ba", "\u31f0"-"\u31ff", "\u3400"-"\u4db5", "\u4e00"-"\u9fcc", "\ua000"-"\ua48c",
+ "\ua4d0"-"\ua4fd", "\ua500"-"\ua60c", "\ua610"-"\ua62b", "\ua640"-"\ua66f", "\ua674"-"\ua67d",
+ "\ua67f"-"\ua697", "\ua69f"-"\ua6f1", "\ua717"-"\ua71f", "\ua722"-"\ua788", "\ua78b"-"\ua78e",
+ "\ua790"-"\ua793", "\ua7a0"-"\ua7aa", "\ua7f8"-"\ua827", "\ua838", "\ua840"-"\ua873", "\ua880"-"\ua8c4",
+ "\ua8d0"-"\ua8d9", "\ua8e0"-"\ua8f7", "\ua8fb", "\ua900"-"\ua92d", "\ua930"-"\ua953", "\ua960"-"\ua97c",
+ "\ua980"-"\ua9c0", "\ua9cf"-"\ua9d9", "\uaa00"-"\uaa36", "\uaa40"-"\uaa4d", "\uaa50"-"\uaa59",
+ "\uaa60"-"\uaa76", "\uaa7a"-"\uaa7b", "\uaa80"-"\uaac2", "\uaadb"-"\uaadd", "\uaae0"-"\uaaef",
+ "\uaaf2"-"\uaaf6", "\uab01"-"\uab06", "\uab09"-"\uab0e", "\uab11"-"\uab16", "\uab20"-"\uab26",
+ "\uab28"-"\uab2e", "\uabc0"-"\uabea", "\uabec"-"\uabed", "\uabf0"-"\uabf9", "\uac00"-"\ud7a3",
+ "\ud7b0"-"\ud7c6", "\ud7cb"-"\ud7fb", "\ud800"-"\udfff", "\uf900"-"\ufa6d", "\ufa70"-"\ufad9",
+ "\ufb00"-"\ufb06", "\ufb13"-"\ufb17", "\ufb1d"-"\ufb28", "\ufb2a"-"\ufb36", "\ufb38"-"\ufb3c",
+ "\ufb3e", "\ufb40"-"\ufb41", "\ufb43"-"\ufb44", "\ufb46"-"\ufbb1", "\ufbd3"-"\ufd3d", "\ufd50"-"\ufd8f",
+ "\ufd92"-"\ufdc7", "\ufdf0"-"\ufdfc", "\ufe00"-"\ufe0f", "\ufe20"-"\ufe26", "\ufe33"-"\ufe34",
+ "\ufe4d"-"\ufe4f", "\ufe69", "\ufe70"-"\ufe74", "\ufe76"-"\ufefc", "\ufeff", "\uff04", "\uff10"-"\uff19",
+ "\uff21"-"\uff3a", "\uff3f", "\uff41"-"\uff5a", "\uff66"-"\uffbe", "\uffc2"-"\uffc7", "\uffca"-"\uffcf",
+ "\uffd2"-"\uffd7", "\uffda"-"\uffdc", "\uffe0"-"\uffe1", "\uffe5"-"\uffe6", "\ufff9"-"\ufffb" ]
+ | <UNICODE_ESCAPE>
+ >
+}
+
+/* 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: "..." >
+| < ARROW: "->" >
+| < DOUBLECOLON: "::" >
+}
+
+/* >'s need special attention due to generics syntax. */
+TOKEN :
+{
+ < RUNSIGNEDSHIFT: ">>>" >
+ {
+ matchedToken.kind = GT;
+ matchedToken.realKind = RUNSIGNEDSHIFT;
+ input_stream.backup(2);
+ }
+| < RSIGNEDSHIFT: ">>" >
+ {
+ matchedToken.kind = GT;
+ matchedToken.realKind = RSIGNEDSHIFT;
+ input_stream.backup(1);
+ }
+| < GT: ">" >
+}
+
+TOKEN: { <CTRL_Z: "\u001A" /** ctrl+z char **/> }
+
+/*****************************************
+ * THE JAVA LANGUAGE GRAMMAR STARTS HERE *
+ *****************************************/
+
+/*
+ * Program structuring syntax follows.
+ */
+
+CompilationUnit CompilationUnit():
+{
+ PackageDeclaration pakage = null;
+ NodeList<ImportDeclaration> imports = emptyList();
+ ImportDeclaration in = null;
+ NodeList<TypeDeclaration<?>> types = emptyList();
+ ModifierHolder modifier;
+ TypeDeclaration tn = null;
+ ModuleDeclaration module = null;
+}
+{
+ try {
+ ( LOOKAHEAD(2)";" )*
+ [ LOOKAHEAD(PackageDeclaration()) pakage = PackageDeclaration() ]
+ (
+ in = ImportDeclaration() { imports = add(imports, in); }
+ |
+ (
+ modifier = Modifiers()
+ (
+ tn = ClassOrInterfaceDeclaration(modifier) { types = add(types, tn); }
+ |
+ tn = EnumDeclaration(modifier) { types = add(types, tn); }
+ |
+ tn = AnnotationTypeDeclaration(modifier) { types = add(types, tn); }
+ |
+ module = ModuleDeclaration(modifier)
+ |
+ ";"
+ )
+ )
+ )*
+ (<EOF> | <CTRL_Z>)
+ { return new CompilationUnit(range(token_source.getHomeToken(), token()), pakage, imports, types, module); }
+ } catch (ParseException e) {
+ recover(EOF, e);
+ final CompilationUnit compilationUnit = new CompilationUnit(range(token_source.getHomeToken(), token()), null, new NodeList<ImportDeclaration>(), new NodeList<TypeDeclaration<?>>(), null);
+ compilationUnit.setParsed(UNPARSABLE);
+ return compilationUnit;
+ }
+}
+
+PackageDeclaration PackageDeclaration():
+{
+ NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+ Name name;
+ JavaToken begin;
+}
+{
+ annotations = Annotations()
+ "package" {begin = token();} name = Name() ";"
+ { return new PackageDeclaration(range(begin, token()), annotations, name); }
+}
+
+
+ImportDeclaration ImportDeclaration():
+{
+ Name name;
+ boolean isStatic = false;
+ boolean isAsterisk = false;
+ JavaToken begin;
+}
+{
+ "import" {begin = token();}
+ [ "static" { isStatic = true; } ]
+ name = Name()
+ [ "." "*" { isAsterisk = true; } ] ";"
+ { return new ImportDeclaration(range(begin, token()), name, isStatic, isAsterisk); }
+}
+
+/*
+ * 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.
+ */
+
+ModifierHolder Modifiers():
+{
+ JavaToken begin = INVALID;
+ EnumSet<Modifier> modifiers = EnumSet.noneOf(Modifier.class);
+ NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+ AnnotationExpr ann;
+}
+{
+ (
+ LOOKAHEAD(2)
+ (
+ "public" { addModifier(modifiers, Modifier.PUBLIC); begin = orIfInvalid(begin, token()); }
+ |
+ "static" { addModifier(modifiers, Modifier.STATIC); begin = orIfInvalid(begin, token()); }
+ |
+ "protected" { addModifier(modifiers, Modifier.PROTECTED); begin = orIfInvalid(begin, token()); }
+ |
+ "private" { addModifier(modifiers, Modifier.PRIVATE); begin = orIfInvalid(begin, token()); }
+ |
+ "final" { addModifier(modifiers, Modifier.FINAL); begin = orIfInvalid(begin, token()); }
+ |
+ "abstract" { addModifier(modifiers, Modifier.ABSTRACT); begin = orIfInvalid(begin, token()); }
+ |
+ "synchronized" { addModifier(modifiers, Modifier.SYNCHRONIZED); begin = orIfInvalid(begin, token()); }
+ |
+ "native" { addModifier(modifiers, Modifier.NATIVE); begin = orIfInvalid(begin, token()); }
+ |
+ "transient" { addModifier(modifiers, Modifier.TRANSIENT); begin = orIfInvalid(begin, token()); }
+ |
+ "volatile" { addModifier(modifiers, Modifier.VOLATILE); begin = orIfInvalid(begin, token()); }
+ |
+ "strictfp" { addModifier(modifiers, Modifier.STRICTFP); begin = orIfInvalid(begin, token()); }
+ |
+ "transitive" { addModifier(modifiers, Modifier.TRANSITIVE); begin = orIfInvalid(begin, token()); }
+ |
+ "default" { addModifier(modifiers, Modifier.DEFAULT); begin = orIfInvalid(begin, token()); }
+ |
+ ann = Annotation() { annotations = add(annotations, ann); begin = orIfInvalid(begin, ann); }
+ )
+ )*
+
+ {
+ return new ModifierHolder(begin, modifiers, annotations);
+ }
+}
+
+/*
+ * Declaration syntax follows.
+ */
+
+ClassOrInterfaceDeclaration ClassOrInterfaceDeclaration(ModifierHolder modifier):
+{
+ boolean isInterface = false;
+ SimpleName name;
+ RangedList<TypeParameter> typePar = new RangedList<TypeParameter>(emptyList());
+ NodeList<ClassOrInterfaceType> extList = emptyList();
+ NodeList<ClassOrInterfaceType> impList = emptyList();
+ NodeList<BodyDeclaration<?>> members = emptyList();
+ JavaToken begin = modifier.begin;
+}
+{
+ ( "class" | "interface" { isInterface = true; } ) { begin = orIfInvalid(begin, token()); }
+ name = SimpleName()
+ [ typePar = TypeParameters() ]
+ [ extList = ExtendsList() ]
+ [ impList = ImplementsList() ]
+ members = ClassOrInterfaceBody()
+
+ { return new ClassOrInterfaceDeclaration(range(begin, token()), modifier.modifiers, modifier.annotations, isInterface, name, typePar.list, extList, impList, members); }
+}
+
+NodeList<ClassOrInterfaceType> ExtendsList():
+{
+ boolean extendsMoreThanOne = false;
+ NodeList<ClassOrInterfaceType> ret = new NodeList<ClassOrInterfaceType>();
+ ClassOrInterfaceType cit;
+}
+{
+ "extends" cit = AnnotatedClassOrInterfaceType() { ret.add(cit); }
+ ( "," cit = AnnotatedClassOrInterfaceType() { ret.add(cit); extendsMoreThanOne = true; } )*
+ { return ret; }
+}
+
+NodeList<ClassOrInterfaceType> ImplementsList():
+{
+ NodeList<ClassOrInterfaceType> ret = new NodeList<ClassOrInterfaceType>();
+ ClassOrInterfaceType cit;
+}
+{
+ "implements" cit = AnnotatedClassOrInterfaceType() { ret.add(cit); }
+ ( "," cit = AnnotatedClassOrInterfaceType() { ret.add(cit); } )*
+ { return ret; }
+}
+
+EnumDeclaration EnumDeclaration(ModifierHolder modifier):
+{
+ SimpleName name;
+ NodeList<ClassOrInterfaceType> impList = emptyList();
+ EnumConstantDeclaration entry;
+ NodeList<EnumConstantDeclaration> entries = emptyList();
+ BodyDeclaration<?> member;
+ NodeList<BodyDeclaration<?>> members = emptyList();
+ JavaToken begin = modifier.begin;
+}
+{
+ "enum" { begin = orIfInvalid(begin, token()); }
+ name = SimpleName()
+ [ impList = ImplementsList() ]
+ "{"
+ [
+ entry = EnumConstantDeclaration() { entries.add(entry); } ( LOOKAHEAD(2) "," entry = EnumConstantDeclaration() { entries.add(entry); } )*
+ ]
+ [ "," ]
+ [
+ ";" (
+ member = ClassOrInterfaceBodyDeclaration() { members = add(members, member); }
+ |
+ ";"
+ )*
+ ]
+ "}"
+
+ { return new EnumDeclaration(range(begin, token()), modifier.modifiers, modifier.annotations, name, impList, entries, members); }
+}
+
+
+EnumConstantDeclaration EnumConstantDeclaration():
+{
+ NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+ AnnotationExpr ann;
+ SimpleName name;
+ NodeList<Expression> args = emptyList();
+ NodeList<BodyDeclaration<?>> classBody = emptyList();
+ JavaToken begin = INVALID;
+}
+{
+ { }
+ ( ann = Annotation() { annotations = add(annotations, ann); begin = orIfInvalid(begin, ann); } )*
+ name = SimpleName() { begin = orIfInvalid(begin, token()); }
+ [ args = Arguments() ] [ classBody = ClassOrInterfaceBody() ]
+ {
+ return new EnumConstantDeclaration(range(begin, token()), annotations, name, args, classBody);
+ }
+}
+
+/**
+ * If the list inside the returned RangedList is null, there are no brackets.
+ * If it is empty, there are brackets, but nothing is in them <>.
+ * The normal case is that it contains TypeParameters, like <A, B, C>.
+ */
+RangedList<TypeParameter> TypeParameters():
+{
+ RangedList<TypeParameter> ret = new RangedList<TypeParameter>(new NodeList<TypeParameter>());
+ TypeParameter tp;
+ NodeList<AnnotationExpr> annotations;
+}
+{
+ "<" { ret.beginAt(token()); }
+ annotations = Annotations()
+ tp = TypeParameter(annotations) { ret.add(tp); annotations = null; }
+ ( ","
+ annotations = Annotations() tp = TypeParameter(annotations) { ret.add(tp); annotations = null; } )*
+ ">" { ret.endAt(token()); }
+ { return ret; }
+}
+
+TypeParameter TypeParameter(NodeList<AnnotationExpr> annotations):
+{
+ SimpleName name;
+ NodeList<ClassOrInterfaceType> typeBound = emptyList();
+ JavaToken begin;
+}
+{
+ name = SimpleName() { begin=token(); } [ typeBound = TypeBound() ]
+ { return new TypeParameter(range(begin, token()), name, typeBound, annotations); }
+}
+
+NodeList<ClassOrInterfaceType> TypeBound():
+{
+ NodeList<ClassOrInterfaceType> ret = emptyList();
+ ClassOrInterfaceType cit;
+}
+{
+ "extends" cit = AnnotatedClassOrInterfaceType() { ret.add(cit); }
+ ( "&" cit = AnnotatedClassOrInterfaceType() { ret.add(cit); } )*
+ { return ret; }
+}
+
+NodeList<BodyDeclaration<?>> ClassOrInterfaceBody():
+{
+ NodeList<BodyDeclaration<?>> ret = emptyList();
+ BodyDeclaration member;
+}
+{
+ "{" (
+ member = ClassOrInterfaceBodyDeclaration() { ret.add(member); }
+ |
+ ";"
+ )* "}"
+ { return ret; }
+}
+
+BodyDeclaration<?> ClassOrInterfaceBodyDeclaration():
+{
+ ModifierHolder modifier;
+ BodyDeclaration<?> ret;
+}
+{
+ (
+ LOOKAHEAD(2)
+ ret = InitializerDeclaration()
+ |
+ // Just get all the modifiers out of the way. If you want to do
+ // more checks, pass the modifiers down to the member
+ modifier = Modifiers()
+ (
+ ret = ClassOrInterfaceDeclaration(modifier)
+ | LOOKAHEAD("enum")
+ ret = EnumDeclaration(modifier)
+ | LOOKAHEAD("@" "interface")
+ ret = AnnotationTypeDeclaration(modifier)
+ | LOOKAHEAD( [ TypeParameters() ] Identifier() "(" )
+ ret = ConstructorDeclaration(modifier)
+ | LOOKAHEAD( Type() Identifier() ( ArrayBracketPair() )* ( "," | "=" | ";" ) )
+ ret = FieldDeclaration(modifier)
+ |
+ ret = MethodDeclaration(modifier)
+ )
+ )
+ { return ret; }
+}
+
+FieldDeclaration FieldDeclaration(ModifierHolder modifier):
+{
+ Type partialType;
+ NodeList<VariableDeclarator> variables = new NodeList<VariableDeclarator>();
+ VariableDeclarator val;
+}
+{
+ // Modifiers are already matched in the caller
+ partialType = Type(emptyList()) val = VariableDeclarator(partialType) { variables.add(val); }
+ ( "," val = VariableDeclarator(partialType) { variables.add(val); } )* ";"
+ {
+ JavaToken begin = orIfInvalid(modifier.begin, partialType);
+ return new FieldDeclaration(range(begin, token()), modifier.modifiers, modifier.annotations, variables);
+ }
+}
+
+VariableDeclarator VariableDeclarator(Type partialType):
+{
+ Pair<SimpleName, List<ArrayBracketPair>> id;
+ Expression init = null;
+}
+{
+ id = VariableDeclaratorId() [ "=" init = VariableInitializer() ]
+ { return new VariableDeclarator(range(id.a, token()), juggleArrayType(partialType, id.b), id.a, init); }
+}
+
+Pair<SimpleName, List<ArrayBracketPair>> VariableDeclaratorId():
+{
+ SimpleName name;
+ JavaToken begin;
+ ArrayBracketPair arrayBracketPair;
+ List<ArrayBracketPair> arrayBracketPairs = new ArrayList(0);
+}
+{
+ name = SimpleName() { begin=token();} ( arrayBracketPair = ArrayBracketPair(Origin.NAME) { arrayBracketPairs=add(arrayBracketPairs, arrayBracketPair); } )*
+ {
+ if(storeTokens) {
+ name.setTokenRange(name.getTokenRange().get().withEnd(token()));
+ }
+ return new Pair(name, arrayBracketPairs);
+ }
+}
+
+Expression VariableInitializer():
+{
+ Expression ret;
+}
+{
+ (
+ ret = ArrayInitializer()
+ |
+ ret = Expression()
+ )
+ { return ret;}
+}
+
+ArrayInitializerExpr ArrayInitializer():
+{
+ NodeList<Expression> values = emptyList();
+ Expression val;
+ JavaToken begin;
+}
+{
+ "{" {begin=token();} [ val = VariableInitializer() { values = add(values, val); } ( LOOKAHEAD(2) "," val = VariableInitializer() { values = add(values, val); } )* ] [ "," ] "}"
+ { return new ArrayInitializerExpr(range(begin, token()), values); }
+}
+
+MethodDeclaration MethodDeclaration(ModifierHolder modifier):
+{
+ RangedList<TypeParameter> typeParameters = new RangedList<TypeParameter>(emptyList());
+ Type type;
+ SimpleName name;
+ Pair<NodeList<Parameter>, ReceiverParameter> parameters = new Pair<NodeList<Parameter>, ReceiverParameter>(emptyList(), null);
+ ArrayBracketPair arrayBracketPair;
+ List<ArrayBracketPair> arrayBracketPairs = new ArrayList(0);
+ NodeList<ReferenceType> throws_ = emptyList();
+ BlockStmt body = null;
+ NodeList<AnnotationExpr> annotations;
+ JavaToken begin = modifier.begin;
+ ReferenceType throwType;
+}
+{
+ // Modifiers already matched in the caller!
+ [ typeParameters = TypeParameters() { begin = orIfInvalid(begin, typeParameters.range.getBegin()); } ]
+ annotations = Annotations() { modifier.annotations.addAll(annotations); begin = orIfInvalid(begin, nodeListBegin(annotations)); }
+ type = ResultType(emptyList()) { begin = orIfInvalid(begin, type); }
+ name = SimpleName() parameters = Parameters() ( arrayBracketPair = ArrayBracketPair(Origin.NAME) { arrayBracketPairs=add(arrayBracketPairs, arrayBracketPair); } )*
+ [ "throws" throwType = AnnotatedReferenceType() { throws_ = add(throws_, throwType); }
+ ("," throwType = AnnotatedReferenceType() { throws_ = add(throws_, throwType); } )* ]
+ ( body = Block() | ";" )
+ {
+ type = juggleArrayType(type, arrayBracketPairs);
+ return new MethodDeclaration(range(begin, token()), modifier.modifiers, modifier.annotations, typeParameters.list, type, name, parameters.a, throws_, body, parameters.b);
+ }
+}
+
+ReferenceType AnnotatedReferenceType():
+{
+ NodeList<AnnotationExpr> annotations;
+ ReferenceType type;
+}
+{
+ annotations = Annotations()
+ type = ReferenceType(annotations)
+ { return type; }
+}
+
+Type AnnotatedType():
+{
+ NodeList<AnnotationExpr> annotations;
+ Type type;
+}
+{
+ annotations = Annotations()
+ type = Type(annotations)
+ { return type; }
+}
+
+Pair<NodeList<Parameter>, ReceiverParameter> Parameters():
+{
+ NodeList<Parameter> ret = emptyList();
+ Parameter par;
+ ReceiverParameter rp = null;
+}
+{
+ "("
+ [
+ ( LOOKAHEAD(ReceiverParameter())
+ rp = ReceiverParameter()
+ |
+ par = Parameter() { ret = add(ret, par); }
+ )
+ ( "," par = Parameter() { ret = add(ret, par); } )*
+ ]
+ ")"
+ { return new Pair(ret, rp); }
+}
+
+NodeList<Parameter> LambdaParameters():
+{
+ NodeList<Parameter> ret = null;
+ Parameter par;
+}
+{
+ par = Parameter() { ret = add(ret, par); } ( "," par = Parameter() { ret = add(ret, par); } )*
+ { return ret; }
+}
+
+NodeList<Parameter> InferredLambdaParameters():
+{
+ NodeList<Parameter> ret = null;
+ Pair<SimpleName, List<ArrayBracketPair>> id;
+}
+{
+ id = VariableDeclaratorId() { ret = add(ret, new Parameter(range(id.a, id.a), EnumSet.noneOf(Modifier.class), emptyList(), new UnknownType(), false, emptyList(), id.a));}
+ (
+ "," id = VariableDeclaratorId() { ret = add(ret, new Parameter(range(id.a, id.a), EnumSet.noneOf(Modifier.class), emptyList(), new UnknownType(), false, emptyList(), id.a)); }
+ )*
+ { return ret; }
+}
+
+Parameter Parameter():
+{
+ ModifierHolder modifier;
+ Type partialType;
+ boolean isVarArg = false;
+ Pair<SimpleName, List<ArrayBracketPair>> id;
+ NodeList<AnnotationExpr> varArgAnnotations = emptyList();
+}
+{
+ modifier = Modifiers() partialType = Type(emptyList()) [ varArgAnnotations = Annotations() "..." { isVarArg = true;} ]
+ id = VariableDeclaratorId()
+ {
+ JavaToken begin = orIfInvalid(modifier.begin, partialType);
+ return new Parameter(range(begin, token()), modifier.modifiers, modifier.annotations, juggleArrayType(partialType, id.b), isVarArg, varArgAnnotations, id.a);
+ }
+}
+
+ReceiverParameter ReceiverParameter():
+{
+ Type partialType;
+ Name id;
+ NodeList<AnnotationExpr> annotations = emptyList();
+}
+{
+ annotations = Annotations()
+ partialType = Type(emptyList())
+ id = ReceiverParameterId()
+ {
+ return new ReceiverParameter(range(partialType, token()), annotations, partialType, id);
+ }
+}
+
+Name ReceiverParameterId():
+{
+ Name ret = null;
+ NodeList<AnnotationExpr> annotations;
+}
+{
+ [ LOOKAHEAD(Name()) ret = Name() "."] annotations=Annotations() "this"
+ { return new Name(tokenRange(), ret, token.image, annotations); }
+}
+
+ConstructorDeclaration ConstructorDeclaration(ModifierHolder modifier):
+{
+ RangedList<TypeParameter> typeParameters = new RangedList<TypeParameter>(emptyList());
+ SimpleName name;
+ Pair<NodeList<Parameter>, ReceiverParameter> parameters = new Pair<NodeList<Parameter>, ReceiverParameter>(emptyList(), null);
+ NodeList<ReferenceType> throws_ = emptyList();
+ ExplicitConstructorInvocationStmt exConsInv = null;
+ NodeList<Statement> stmts = emptyList();
+ JavaToken begin = modifier.begin;
+ JavaToken blockBegin = INVALID;
+ ReferenceType throwType;
+}
+{
+ [ typeParameters = TypeParameters() { begin = orIfInvalid(begin, typeParameters.range.getBegin()); } ]
+ // Modifiers matched in the caller
+ name = SimpleName() { begin = orIfInvalid(begin, typeParameters.range.getBegin()); begin = orIfInvalid(begin, token()); } parameters = Parameters() [ "throws" throwType = AnnotatedReferenceType() { throws_ = add(throws_, throwType); }
+ ("," throwType = AnnotatedReferenceType() { throws_ = add(throws_, throwType); })* ]
+ "{" { blockBegin=token(); }
+ [ LOOKAHEAD(ExplicitConstructorInvocation()) exConsInv = ExplicitConstructorInvocation() ]
+ stmts = Statements()
+ "}"
+
+ {
+ if (exConsInv != null) {
+ stmts = prepend(stmts, exConsInv);
+ }
+ return new ConstructorDeclaration(range(begin, token()), modifier.modifiers, modifier.annotations, typeParameters.list, name, parameters.a, throws_, new BlockStmt(range(blockBegin, token()), stmts), parameters.b);
+ }
+}
+
+ExplicitConstructorInvocationStmt ExplicitConstructorInvocation():
+{
+ boolean isThis = false;
+ NodeList<Expression> args;
+ Expression expr = null;
+ RangedList<Type> typeArgs = new RangedList<Type>(null);
+ JavaToken begin = INVALID;
+}
+{
+ (
+ LOOKAHEAD([ TypeArguments() ] <THIS> "(")
+ [ typeArgs = TypeArguments() { begin=typeArgs.range.getBegin(); } ]
+ <THIS> { begin = orIfInvalid(begin, token()); isThis = true; }
+ args = Arguments() ";"
+ |
+ [
+ LOOKAHEAD( PrimaryExpressionWithoutSuperSuffix() "." )
+ expr = PrimaryExpressionWithoutSuperSuffix() "."
+ { begin = orIfInvalid(begin, expr); }
+ ]
+ [ typeArgs = TypeArguments() { begin = orIfInvalid(begin, typeArgs.range.getBegin()); } ]
+ <SUPER> {begin = orIfInvalid(begin, token());}
+ args = Arguments() ";"
+ )
+ { return new ExplicitConstructorInvocationStmt(range(begin, token()),typeArgs.list, isThis, expr, args); }
+}
+
+NodeList<Statement> Statements():
+{
+ NodeList<Statement> ret = emptyList();
+ Statement stmt;
+}
+{
+ ( LOOKAHEAD(2) stmt = BlockStatement() { ret = add(ret, stmt); } )*
+ { return ret; }
+}
+
+InitializerDeclaration InitializerDeclaration():
+{
+ BlockStmt body;
+ JavaToken begin = INVALID;
+ boolean isStatic = false;
+}
+{
+ [ "static" { isStatic = true; begin=token();} ]
+ body = Block() {begin = orIfInvalid(begin, body);}
+ { return new InitializerDeclaration(range(begin, token()), isStatic, body); }
+}
+
+
+/*
+ * Type, name and expression syntax follows.
+ */
+
+Type Type(NodeList<AnnotationExpr> annotations):
+{
+ Type ret;
+}
+{
+ (
+ LOOKAHEAD(2) ret = ReferenceType(annotations)
+ |
+ ret = PrimitiveType(annotations )
+ )
+ { return ret; }
+}
+
+ReferenceType ReferenceType(NodeList<AnnotationExpr> annotations):
+{
+ Type type;
+ ArrayBracketPair arrayBracketPair;
+ List<ArrayBracketPair> arrayBracketPairs = new ArrayList(0);
+}
+{
+ (
+ type = PrimitiveType(annotations) ( LOOKAHEAD(Annotations() "[") arrayBracketPair = ArrayBracketPair(Origin.TYPE) { arrayBracketPairs=add(arrayBracketPairs, arrayBracketPair); } )+
+ |
+ type = ClassOrInterfaceType(annotations) ( LOOKAHEAD(Annotations() "[") arrayBracketPair = ArrayBracketPair(Origin.TYPE) { arrayBracketPairs=add(arrayBracketPairs, arrayBracketPair); } )*
+ )
+ { return (ReferenceType)wrapInArrayTypes(type, arrayBracketPairs); }
+}
+
+ArrayBracketPair ArrayBracketPair(Origin origin):
+{
+ NodeList<AnnotationExpr> annotations;
+ JavaToken begin = INVALID;
+}
+{
+ annotations = Annotations()
+ "[" { begin = orIfInvalid(begin, token()); } "]"
+ { return new ArrayBracketPair(range(begin, token()), origin, annotations); }
+}
+
+IntersectionType IntersectionType(NodeList<AnnotationExpr> annotations):
+{
+ JavaToken begin = INVALID;
+ ReferenceType elementType;
+ NodeList<ReferenceType> elements = emptyList();
+}
+{
+ elementType = ReferenceType(annotations) { begin = orIfInvalid(begin, elementType); elements = add(elements, elementType); }
+ "&" (elementType = AnnotatedReferenceType() { elements = add(elements, elementType); } )+
+ { return new IntersectionType(range(begin, token()), elements); }
+}
+
+ClassOrInterfaceType AnnotatedClassOrInterfaceType():
+{
+ NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+ ClassOrInterfaceType cit;
+}
+{
+ annotations = Annotations()
+ cit = ClassOrInterfaceType(annotations)
+ { return cit; }
+}
+
+ClassOrInterfaceType ClassOrInterfaceType(NodeList<AnnotationExpr> firstAnnotations):
+{
+ ClassOrInterfaceType ret;
+ SimpleName name;
+ RangedList<Type> typeArgs = new RangedList<Type>(null);
+ JavaToken begin;
+ NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+}
+{
+ name = SimpleName() {begin=token();}
+ [ LOOKAHEAD(2) typeArgs = TypeArguments() ]
+ {
+ ret = new ClassOrInterfaceType(range(begin, token()), null, name, typeArgs.list, firstAnnotations);
+ typeArgs = new RangedList<Type>(null);
+ }
+ (
+ LOOKAHEAD(2) "." annotations = Annotations() name = SimpleName()
+ [ LOOKAHEAD(2) typeArgs = TypeArguments() ]
+ {
+ ret = new ClassOrInterfaceType(range(begin, token()), ret, name, typeArgs.list, annotations);
+ typeArgs = new RangedList<Type>(null);
+ }
+ )*
+ { return ret; }
+}
+
+RangedList<Type> TypeArguments():
+{
+ RangedList<Type> ret = new RangedList<Type>(new NodeList<Type>());
+ Type type;
+}
+{
+ (
+ "<" { ret.beginAt(token()); }
+ (type = TypeArgument() { ret.add(type); } ( "," type = TypeArgument() { ret.add(type); } )*)?
+ ">" { ret.endAt(token()); }
+ )
+ { return ret; }
+}
+
+Type TypeArgument():
+{
+ Type ret;
+ NodeList<AnnotationExpr> annotations;
+}
+{
+ annotations = Annotations()
+ (
+ ret = Type(annotations)
+ |
+ ret = Wildcard(annotations)
+ )
+ { return ret; }
+}
+
+WildcardType Wildcard(NodeList<AnnotationExpr> firstAnnotations):
+{
+ ReferenceType ext = null;
+ ReferenceType sup = null;
+ JavaToken begin;
+ NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+}
+{
+ "?" {begin=token();}
+ [
+ "extends" annotations = Annotations() ext = ReferenceType(annotations)
+ |
+ "super" annotations = Annotations() sup = ReferenceType(annotations)
+ ]
+ {
+ return new WildcardType(range(begin, token()), ext, sup, firstAnnotations);
+ }
+}
+
+PrimitiveType PrimitiveType(NodeList<AnnotationExpr> annotations):
+{
+ PrimitiveType ret;
+}
+{
+(
+ "boolean" { ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.BOOLEAN, annotations); }
+|
+ "char" { ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.CHAR, annotations); }
+|
+ "byte" { ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.BYTE, annotations); }
+|
+ "short" { ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.SHORT, annotations); }
+|
+ "int" { ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.INT, annotations); }
+|
+ "long" { ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.LONG, annotations); }
+|
+ "float" { ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.FLOAT, annotations); }
+|
+ "double" { ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.DOUBLE, annotations); }
+)
+{ return ret; }
+}
+
+Type ResultType(NodeList<AnnotationExpr> annotations):
+{
+ Type ret;
+}
+{
+ (
+ "void" { ret = new VoidType(tokenRange()); }
+ |
+ ret = Type(annotations)
+ )
+ { return ret; }
+}
+
+Name Name():
+/*
+ * A lookahead is required below since "Name" can be followed
+ * by a ".*" when used in the context of an "ImportDeclaration".
+ */
+{
+ Name ret;
+ NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+}
+{
+ annotations=Annotations() Identifier() { ret = new Name(tokenRange(), null, token.image, annotations); }
+ ( LOOKAHEAD("." Annotations() Identifier())
+ "." annotations=Annotations() Identifier() { ret = new Name(range(ret, token()), ret, token.image, annotations); } )*
+ { return ret; }
+}
+
+SimpleName SimpleName():
+{
+ SimpleName ret;
+}
+{
+ Identifier() { ret = new SimpleName(tokenRange(), token.image); }
+ { return ret; }
+}
+
+
+String Identifier():
+{
+ String ret;
+}
+{
+ // Make sure the module info keywords don't interfere with normal Java parsing by matching them as normal identifiers.
+ (<MODULE> | <REQUIRES> | <TO> | <WITH> | <OPEN> | <OPENS> | <USES> | <EXPORTS> | <PROVIDES> | <TRANSITIVE> |
+ // Make sure older Java versions parse
+ <ENUM> | <STRICTFP> |
+ // An actual plain old identifier
+ <IDENTIFIER>) { ret = token.image; setTokenKind(IDENTIFIER);}
+ { return ret; }
+}
+
+/*
+ * Expression syntax follows.
+ */
+
+Expression 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. This is caught by a validation after parsing.
+ */
+{
+ Expression ret;
+ AssignExpr.Operator op;
+ Expression value;
+ Statement lambdaBody = null;
+ RangedList<Type> typeArgs = new RangedList<Type>(null);
+}
+{
+ ret = ConditionalExpression()
+ [
+ ( LOOKAHEAD(2)
+ op = AssignmentOperator() value = Expression() { ret = new AssignExpr(range(ret, token()), ret, value, op); }
+ |
+ "->" lambdaBody = LambdaBody()
+ {
+ if (ret instanceof CastExpr) {
+ ret = generateLambda(ret, lambdaBody);
+ } else if (ret instanceof ConditionalExpr) {
+ ConditionalExpr ce = (ConditionalExpr) ret;
+ if(ce.getElseExpr() != null) {
+ ce.setElseExpr(generateLambda(ce.getElseExpr(), lambdaBody));
+ }
+ } else {
+ ret = generateLambda(ret, lambdaBody);
+ }
+ }
+ |
+ "::" [typeArgs = TypeArguments() ] (Identifier() | "new") { ret = new MethodReferenceExpr(range(ret, token()), ret, typeArgs.list, token.image); }
+ )
+ ]
+
+ { return ret; }
+}
+
+AssignExpr.Operator AssignmentOperator():
+{
+ AssignExpr.Operator ret;
+}
+{
+ (
+ "=" { ret = AssignExpr.Operator.ASSIGN; }
+ | "*=" { ret = AssignExpr.Operator.MULTIPLY; }
+ | "/=" { ret = AssignExpr.Operator.DIVIDE; }
+ | "%=" { ret = AssignExpr.Operator.REMAINDER; }
+ | "+=" { ret = AssignExpr.Operator.PLUS; }
+ | "-=" { ret = AssignExpr.Operator.MINUS; }
+ | "<<=" { ret = AssignExpr.Operator.LEFT_SHIFT; }
+ | ">>=" { ret = AssignExpr.Operator.SIGNED_RIGHT_SHIFT; }
+ | ">>>=" { ret = AssignExpr.Operator.UNSIGNED_RIGHT_SHIFT; }
+ | "&=" { ret = AssignExpr.Operator.BINARY_AND; }
+ | "^=" { ret = AssignExpr.Operator.XOR; }
+ | "|=" { ret = AssignExpr.Operator.BINARY_OR; }
+ )
+ { return ret; }
+}
+
+Expression ConditionalExpression():
+{
+ Expression ret;
+ Expression left;
+ Expression right;
+}
+{
+ ret = ConditionalOrExpression()
+ [ "?" left = Expression() ":" right = ConditionalExpression() { ret = new ConditionalExpr(range(ret, token()), ret, left, right); } ]
+ { return ret; }
+}
+
+Expression ConditionalOrExpression():
+{
+ Expression ret;
+ Expression right;
+}
+{
+ ret = ConditionalAndExpression() ( "||" right = ConditionalAndExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, BinaryExpr.Operator.OR); } )*
+ { return ret; }
+}
+
+Expression ConditionalAndExpression():
+{
+ Expression ret;
+ Expression right;
+}
+{
+ ret = InclusiveOrExpression() ( "&&" right = InclusiveOrExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, BinaryExpr.Operator.AND); } )*
+ { return ret; }
+}
+
+Expression InclusiveOrExpression():
+{
+ Expression ret;
+ Expression right;
+}
+{
+ ret = ExclusiveOrExpression() ( "|" right = ExclusiveOrExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, BinaryExpr.Operator.BINARY_OR); } )*
+ { return ret; }
+}
+
+Expression ExclusiveOrExpression():
+{
+ Expression ret;
+ Expression right;
+}
+{
+ ret = AndExpression() ( "^" right = AndExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, BinaryExpr.Operator.XOR); } )*
+ { return ret; }
+}
+
+Expression AndExpression():
+{
+ Expression ret;
+ Expression right;
+}
+{
+ ret = EqualityExpression() ( "&" right = EqualityExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, BinaryExpr.Operator.BINARY_AND); } )*
+ { return ret; }
+}
+
+Expression EqualityExpression():
+{
+ Expression ret;
+ Expression right;
+ BinaryExpr.Operator op;
+}
+{
+ ret = InstanceOfExpression()
+ (
+ ( "==" { op = BinaryExpr.Operator.EQUALS; } |
+ "!=" { op = BinaryExpr.Operator.NOT_EQUALS; }
+ ) right = InstanceOfExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, op); }
+ )*
+ { return ret; }
+}
+
+Expression InstanceOfExpression():
+{
+ Expression ret;
+ ReferenceType type;
+ NodeList<AnnotationExpr> annotations;
+}
+{
+ ret = RelationalExpression() [ "instanceof" type = AnnotatedReferenceType() {
+ ret = new InstanceOfExpr(range(ret, token()), ret, type);
+ } ]
+ { return ret; }
+}
+
+Expression RelationalExpression():
+{
+ Expression ret;
+ Expression right;
+ BinaryExpr.Operator op;
+}
+{
+ ret = ShiftExpression()
+ (
+ ( "<" { op = BinaryExpr.Operator.LESS; } |
+ ">" { op = BinaryExpr.Operator.GREATER; } |
+ "<=" { op = BinaryExpr.Operator.LESS_EQUALS; } |
+ ">=" { op = BinaryExpr.Operator.GREATER_EQUALS; }
+ ) right = ShiftExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, op); }
+ )*
+ { return ret; }
+}
+
+Expression ShiftExpression():
+{
+ Expression ret;
+ Expression right;
+ BinaryExpr.Operator op;
+}
+{
+ ret = AdditiveExpression()
+ (
+ ( "<<" { op = BinaryExpr.Operator.LEFT_SHIFT; } |
+ RSIGNEDSHIFT() { op = BinaryExpr.Operator.SIGNED_RIGHT_SHIFT; } |
+ RUNSIGNEDSHIFT() { op = BinaryExpr.Operator.UNSIGNED_RIGHT_SHIFT; }
+ ) right = AdditiveExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, op); }
+ )*
+ { return ret; }
+}
+
+Expression AdditiveExpression():
+{
+ Expression ret;
+ Expression right;
+ BinaryExpr.Operator op;
+}
+{
+ ret = MultiplicativeExpression()
+ (
+ ( "+" { op = BinaryExpr.Operator.PLUS; } |
+ "-" { op = BinaryExpr.Operator.MINUS; }
+ ) right = MultiplicativeExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, op); }
+ )*
+ { return ret; }
+}
+
+Expression MultiplicativeExpression():
+{
+ Expression ret;
+ Expression right;
+ BinaryExpr.Operator op;
+}
+{
+ ret = UnaryExpression()
+ (
+ ( "*" { op = BinaryExpr.Operator.MULTIPLY; } |
+ "/" { op = BinaryExpr.Operator.DIVIDE; } |
+ "%" { op = BinaryExpr.Operator.REMAINDER; }
+ ) right = UnaryExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, op); }
+ )*
+ { return ret; }
+}
+
+Expression UnaryExpression():
+{
+ Expression ret;
+ UnaryExpr.Operator op;
+ JavaToken begin = INVALID;
+}
+{
+ (
+ ret = PreIncrementExpression()
+ |
+ ret = PreDecrementExpression()
+ |
+ ( "+" { op = UnaryExpr.Operator.PLUS; begin=token();} |
+ "-" { op = UnaryExpr.Operator.MINUS; begin=token();}
+ ) ret = UnaryExpression()
+ {
+ ret = new UnaryExpr(range(begin, token()), ret, op);
+ }
+ |
+ ret = UnaryExpressionNotPlusMinus()
+ )
+ { return ret; }
+}
+
+Expression PreIncrementExpression():
+{
+ Expression ret;
+ JavaToken begin = INVALID;
+}
+{
+ "++" {begin=token();} ret = UnaryExpression() { ret = new UnaryExpr(range(begin, token()), ret, UnaryExpr.Operator.PREFIX_INCREMENT); }
+ { return ret; }
+}
+
+Expression PreDecrementExpression():
+{
+ Expression ret;
+ JavaToken begin;
+}
+{
+ "--" {begin=token();} ret = UnaryExpression() { ret = new UnaryExpr(range(begin, token()), ret, UnaryExpr.Operator.PREFIX_DECREMENT); }
+ { return ret; }
+}
+
+Expression UnaryExpressionNotPlusMinus():
+{
+ Expression ret;
+ UnaryExpr.Operator op;
+ JavaToken begin = INVALID;
+}
+{
+ (
+ ( "~" { op = UnaryExpr.Operator.BITWISE_COMPLEMENT; begin=token(); } |
+ "!" { op = UnaryExpr.Operator.LOGICAL_COMPLEMENT; begin=token(); }
+ ) ret = UnaryExpression() { ret = new UnaryExpr(range(begin, token()), ret, op); }
+ |
+ LOOKAHEAD( CastExpression() )
+ ret = CastExpression()
+ |
+ ret = PostfixExpression()
+ )
+ { return ret; }
+}
+
+Expression PostfixExpression():
+{
+ Expression ret;
+ UnaryExpr.Operator op;
+}
+{
+ ret = PrimaryExpression()
+ [
+ LOOKAHEAD(2)
+ ( "++" { op = UnaryExpr.Operator.POSTFIX_INCREMENT; } |
+ "--" { op = UnaryExpr.Operator.POSTFIX_DECREMENT; }
+ ) { ret = new UnaryExpr(range(ret, token()), ret, op); }
+ ]
+ { return ret; }
+}
+
+Expression CastExpression():
+{
+ Expression ret;
+ ReferenceType referenceType;
+ PrimitiveType primitiveType;
+ JavaToken begin = INVALID;
+ NodeList<AnnotationExpr> annotations;
+ NodeList<ReferenceType> typesOfMultiCast = emptyList();
+}
+{
+ "(" {begin=token();}
+ annotations = Annotations()
+ (
+ LOOKAHEAD(2)
+ primitiveType = PrimitiveType(annotations) ")" ret = UnaryExpression() { ret = new CastExpr(range(begin, token()), primitiveType, ret); }
+ |
+ referenceType = ReferenceType(annotations) { typesOfMultiCast = add(typesOfMultiCast, referenceType); }
+ ( "&" referenceType = AnnotatedReferenceType() {
+ typesOfMultiCast = add(typesOfMultiCast, referenceType);
+ }
+ )*
+ ")" ret = UnaryExpressionNotPlusMinus() {
+ if (typesOfMultiCast.size() > 1) {
+ ret = new CastExpr(range(begin, token()), new IntersectionType(range(typesOfMultiCast.get(0), typesOfMultiCast.get(typesOfMultiCast.size() -1)), typesOfMultiCast), ret);
+ } else {
+ ret = new CastExpr(range(begin, token()), referenceType, ret);
+ }
+ }
+ )
+ { return ret; }
+}
+
+
+
+Expression PrimaryExpression():
+{
+ Expression ret;
+}
+{
+ ret = PrimaryPrefix() ( LOOKAHEAD(2) ret = PrimarySuffix(ret) )*
+ { return ret; }
+}
+
+Expression PrimaryExpressionWithoutSuperSuffix():
+{
+ Expression ret;
+}
+{
+ ret = PrimaryPrefix() ( LOOKAHEAD( PrimarySuffixWithoutSuper(null) ) ret = PrimarySuffixWithoutSuper(ret) )*
+ { return ret; }
+}
+
+Expression PrimaryPrefix():
+{
+ Expression ret = null;
+ SimpleName name;
+ RangedList<Type> typeArgs = new RangedList<Type>(null);
+ NodeList<Expression> args = emptyList();
+ NodeList<Parameter> params = emptyList();
+ boolean hasArgs = false;
+ boolean isLambda = false;
+ Type type;
+ JavaToken begin;
+ Parameter p = null;
+ SimpleName id = null;
+}
+{
+ (
+ ret = Literal()
+ |
+ <THIS> { ret = new ThisExpr(tokenRange(), null); }
+ |
+ <SUPER> { ret = new SuperExpr(tokenRange(), null); }
+ (
+ "."
+ [ typeArgs = TypeArguments() ]
+ name = SimpleName()
+ [ args = Arguments() {hasArgs=true;} ]
+ {
+ if (hasArgs) {
+ ret = new MethodCallExpr(range(ret, token()), ret, typeArgs.list, name, args);
+ } else {
+ ret = new FieldAccessExpr(range(ret, token()), ret, emptyList(), name);
+ }
+ }
+ |
+ "::" [typeArgs = TypeArguments() ] (Identifier() | "new")
+ {
+ ret = new MethodReferenceExpr(range(ret, token()), ret, typeArgs.list, token.image);
+ }
+ )
+ |
+ "(" {begin=token();}
+ (
+ ")" { ret = new LambdaExpr(range(begin, token()), params, new BlockStmt(), true); }
+ | LOOKAHEAD(Parameter())
+ params = LambdaParameters() ")" { ret = new LambdaExpr(range(begin, token()), params, new BlockStmt(), true); }
+ | LOOKAHEAD(VariableDeclaratorId() ",")
+ params = InferredLambdaParameters() ")" { ret = new LambdaExpr(range(begin, token()), params, new BlockStmt(), true); }
+ |
+ // This could still be a lambda expression, but this is handled after matching -> elsewhere
+ ret = Expression() ")" { ret = new EnclosedExpr(range(begin, token()), ret); }
+ )
+ |
+ ret = AllocationExpression(null)
+ |
+ LOOKAHEAD( ResultType() "." "class" )
+ type = ResultType(emptyList()) "." "class" { ret = new ClassExpr(range(type, token()), type); }
+
+ | LOOKAHEAD (AnnotatedType() "::" )
+ type = AnnotatedType() "::" [typeArgs = TypeArguments() ] (Identifier() | "new")
+ {
+ ret = new TypeExpr(range(type, type), type);
+ ret = new MethodReferenceExpr(range(ret, token()), ret, typeArgs.list, token.image);
+ }
+
+ |
+ name = SimpleName() { begin=token(); }
+ [ args = Arguments() { hasArgs=true; } ]
+ {
+ if (hasArgs) {
+ ret = new MethodCallExpr(range(begin, token()), null, null, name, args);
+ } else {
+ ret = new NameExpr(name);
+ }
+ }
+ )
+ { return ret; }
+}
+
+Expression PrimarySuffix(Expression scope):
+{
+ Expression ret;
+}
+{
+ (
+ LOOKAHEAD(2)
+ ret = PrimarySuffixWithoutSuper(scope)
+ |
+ "." "super" { ret = new SuperExpr(range(scope, token()), scope); }
+ )
+ { return ret; }
+}
+
+Expression PrimarySuffixWithoutSuper(Expression scope):
+{
+ Expression ret;
+ RangedList<Type> typeArgs = new RangedList<Type>(null);
+ NodeList<Expression> args = emptyList();
+ boolean hasArgs = false;
+ SimpleName name;
+}
+{
+ (
+ "."
+ (
+ "this" { ret = new ThisExpr(range(scope, token()), scope); }
+ |
+ ret = AllocationExpression(scope)
+ |
+ LOOKAHEAD( [ TypeArguments() ] Identifier() )
+ [ typeArgs = TypeArguments() ]
+ name = SimpleName()
+ [ args = Arguments() {hasArgs=true;} ]
+ {
+ if (hasArgs) {
+ ret = new MethodCallExpr(range(scope, token()), scope, typeArgs.list, name, args);
+ } else {
+ ret = new FieldAccessExpr(range(scope, token()), scope, typeArgs.list, name);
+ }
+ }
+ )
+ |
+ "["ret = Expression() "]" { ret = new ArrayAccessExpr(range(scope, token()), scope, ret); }
+ )
+ { return ret; }
+}
+
+Expression Literal():
+{
+ Expression ret;
+}
+{
+ (
+ <INTEGER_LITERAL> {
+ ret = new IntegerLiteralExpr(tokenRange(), token.image);
+ }
+ |
+ <LONG_LITERAL> {
+ ret = new LongLiteralExpr(tokenRange(), token.image);
+ }
+ |
+ <FLOATING_POINT_LITERAL> {
+ ret = new DoubleLiteralExpr(tokenRange(), token.image);
+ }
+ |
+ <CHARACTER_LITERAL> {
+ ret = new CharLiteralExpr(tokenRange(), token.image.substring(1, token.image.length()-1));
+ }
+ |
+ <STRING_LITERAL> {
+ ret = new StringLiteralExpr(tokenRange(), token.image.substring(1, token.image.length()-1));
+ }
+ |
+ ret = BooleanLiteral()
+ |
+ ret = NullLiteral()
+ )
+ { return ret; }
+}
+
+Expression BooleanLiteral():
+{
+ Expression ret;
+}
+{
+ (
+ "true" { ret = new BooleanLiteralExpr(tokenRange(), true); }
+ |
+ "false" { ret = new BooleanLiteralExpr(tokenRange(), false); }
+ )
+ { return ret; }
+}
+
+Expression NullLiteral():
+{}
+{
+ "null"
+ { return new NullLiteralExpr(tokenRange()); }
+}
+
+NodeList<Expression> Arguments():
+{
+ NodeList<Expression> ret = emptyList();
+}
+{
+ "(" [ ret = ArgumentList() ] ")"
+ { return ret; }
+}
+
+NodeList<Expression> ArgumentList():
+{
+ NodeList<Expression> ret = emptyList();
+ Expression expr;
+}
+{
+ expr = Expression() { ret.add(expr); } ( "," expr = Expression() { ret.add(expr); } )*
+ { return ret; }
+}
+
+Expression AllocationExpression(Expression scope):
+{
+ Expression ret;
+ Type type;
+ RangedList<Type> typeArgs = new RangedList<Type>(null);
+ NodeList<BodyDeclaration<?>> anonymousBody = null;
+ NodeList<Expression> args;
+ JavaToken begin = INVALID;
+ NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+}
+{
+ "new" { if(scope==null) {begin=token();} else {begin = orIfInvalid(begin, scope);} }
+
+ annotations = Annotations()
+ (
+ type = PrimitiveType(annotations)
+ ret = ArrayCreation(begin, type)
+ |
+ [ typeArgs = TypeArguments() ]
+ type = AnnotatedClassOrInterfaceType()
+ (
+ ret = ArrayCreation(begin, type)
+ |
+ args = Arguments() [ LOOKAHEAD(2) anonymousBody = ClassOrInterfaceBody() ]
+ { ret = new ObjectCreationExpr(range(begin, token()), scope, (ClassOrInterfaceType) type, typeArgs.list, args, anonymousBody); }
+ )
+ )
+ { return ret; }
+}
+
+ArrayCreationExpr ArrayCreation(JavaToken begin, Type type):
+{
+ Expression expr = null;
+ ArrayInitializerExpr arrayInitializerExpr = null;
+ NodeList<Expression> inits = emptyList();
+ List<NodeList<AnnotationExpr>> accum = new ArrayList<NodeList<AnnotationExpr>>();
+ NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+ JavaToken arrayCreationLevelStart = INVALID;
+ List<TokenRange> levelRanges = new ArrayList<TokenRange>();
+}
+{
+ ( LOOKAHEAD(2)
+ annotations = Annotations()
+ "[" { arrayCreationLevelStart = annotations.isEmpty() ? token() : orIfInvalid(arrayCreationLevelStart, annotations.get(0)); }
+ (expr = Expression())? { accum = add(accum, annotations); inits = add(inits, expr); annotations=null; expr=null; }
+ "]" { levelRanges.add(range(arrayCreationLevelStart, token())); }
+ )+
+ (arrayInitializerExpr = ArrayInitializer())?
+ {
+ return juggleArrayCreation(range(begin, token()), levelRanges, type, inits, accum, arrayInitializerExpr);
+ }
+}
+
+/*
+ * Statement syntax follows.
+ */
+
+Statement Statement():
+{
+ Statement ret;
+}
+{
+ try {
+ ( LOOKAHEAD(2)
+ ret = LabeledStatement()
+ |
+ ret = AssertStatement()
+ |
+ ret = Block()
+ |
+ ret = EmptyStatement()
+ |
+ ret = StatementExpression()
+ |
+ ret = SwitchStatement()
+ |
+ ret = IfStatement()
+ |
+ ret = WhileStatement()
+ |
+ ret = DoStatement()
+ |
+ ret = ForStatement()
+ |
+ ret = BreakStatement()
+ |
+ ret = ContinueStatement()
+ |
+ ret = ReturnStatement()
+ |
+ ret = ThrowStatement()
+ |
+ ret = SynchronizedStatement()
+ |
+ ret = TryStatement()
+ )
+ { return ret; }
+ } catch (ParseException e) {
+ TokenRange errorRange = recover(SEMICOLON, e);
+ return new UnparsableStmt(errorRange);
+ }
+}
+
+AssertStmt AssertStatement():
+{
+ Expression check;
+ Expression msg = null;
+ JavaToken begin;
+}
+{
+ "assert" {begin=token();} check = Expression() [ ":" msg = Expression() ] ";"
+ { return new AssertStmt(range(begin, token()), check, msg); }
+}
+
+LabeledStmt LabeledStatement():
+{
+ SimpleName label;
+ Statement stmt;
+ JavaToken begin;
+}
+{
+ label = SimpleName() {begin=token();} ":" stmt = Statement()
+ { return new LabeledStmt(range(begin, token()), label, stmt); }
+}
+
+BlockStmt Block():
+{
+ NodeList<Statement> stmts = emptyList();
+ JavaToken begin;
+}
+{
+ "{" {begin=token();}
+ try {
+ stmts = Statements()
+ "}"
+ { return new BlockStmt(range(begin, token()), stmts); }
+ } catch (ParseException e) {
+ recover(RBRACE, e);
+ BlockStmt block = new BlockStmt(range(begin, token()), new NodeList<Statement>());
+ block.setParsed(UNPARSABLE);
+ return block;
+ }
+}
+
+/*
+ * Classes inside body statements can only be abstract or final. The semantic must check it.
+ */
+Statement BlockStatement():
+{
+ Statement ret;
+ Expression expr;
+ ClassOrInterfaceDeclaration typeDecl;
+ ModifierHolder modifier;
+}
+{
+ try {
+ ( LOOKAHEAD( Modifiers() ("class" | "interface") )
+ modifier = Modifiers()
+ typeDecl = ClassOrInterfaceDeclaration(modifier) { ret = new LocalClassDeclarationStmt(range(typeDecl, token()), typeDecl); }
+ | LOOKAHEAD(VariableDeclarationExpression() )
+ expr = VariableDeclarationExpression() ";"
+ { ret = new ExpressionStmt(range(expr, token()), expr); }
+ |
+ ret = Statement()
+ )
+ { return ret; }
+ } catch (ParseException e) {
+ TokenRange errorRange = recover(SEMICOLON, e);
+ return new UnparsableStmt(errorRange);
+ }
+}
+
+VariableDeclarationExpr VariableDeclarationExpression():
+{
+ ModifierHolder modifier;
+ Type partialType;
+ NodeList<VariableDeclarator> variables = new NodeList<VariableDeclarator>();
+ VariableDeclarator var;
+}
+{
+ modifier = Modifiers() partialType = Type(emptyList()) var = VariableDeclarator(partialType) { variables.add(var); } ( "," var = VariableDeclarator(partialType) { variables.add(var); } )*
+ {
+ JavaToken begin=orIfInvalid(modifier.begin, partialType);
+ return new VariableDeclarationExpr(range(begin, token()), modifier.modifiers, modifier.annotations, variables);
+ }
+}
+
+EmptyStmt EmptyStatement():
+{}
+{
+ ";"
+ { return new EmptyStmt(tokenRange()); }
+}
+
+Statement LambdaBody():
+{
+ Expression expr;
+ Statement n = null;
+}
+{
+ (
+ expr = Expression() { n = new ExpressionStmt(range(expr, token()), expr); }
+ |
+ n = Block()
+ )
+ { return n; }
+}
+
+ExpressionStmt 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.
+ */
+{
+ Expression expr;
+ AssignExpr.Operator op;
+ Expression value;
+ RangedList<Type> typeArgs = new RangedList<Type>(null);
+ Statement lambdaBody;
+}
+{
+ ( LOOKAHEAD(2)
+ expr = PreIncrementExpression()
+ |
+ expr = PreDecrementExpression()
+ |
+ expr = PrimaryExpression()
+ [
+ "++" { expr = new UnaryExpr(range(expr, token()), expr, UnaryExpr.Operator.POSTFIX_INCREMENT); }
+ |
+ "--" { expr = new UnaryExpr(range(expr, token()), expr, UnaryExpr.Operator.POSTFIX_DECREMENT); }
+ |
+ op = AssignmentOperator() value = Expression() { expr = new AssignExpr(range(expr, token()), expr, value, op); }
+ ]
+ )
+ ";"
+ { return new ExpressionStmt(range(expr, token()), expr); }
+}
+
+SwitchStmt SwitchStatement():
+{
+ Expression selector;
+ SwitchEntryStmt entry;
+ NodeList<SwitchEntryStmt> entries = emptyList();
+ JavaToken begin;
+}
+{
+ "switch" {begin=token();} "(" selector = Expression() ")" "{"
+ ( entry = SwitchEntry() { entries = add(entries, entry); } )*
+ "}"
+
+ { return new SwitchStmt(range(begin, token()), selector, entries); }
+}
+
+SwitchEntryStmt SwitchEntry():
+{
+ Expression label = null;
+ NodeList<Statement> stmts;
+ JavaToken begin;
+}
+{
+ (
+ "case" {begin=token();} label = Expression()
+ |
+ "default" {begin=token();}
+ )
+ ":" stmts = Statements()
+
+ { return new SwitchEntryStmt(range(begin, token()),label, stmts); }
+}
+
+IfStmt 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.
+ */
+{
+ Expression condition;
+ Statement thenStmt;
+ Statement elseStmt = null;
+ JavaToken begin;
+}
+{
+ "if" {begin=token();} "(" condition = Expression() ")" {} thenStmt = Statement() [ LOOKAHEAD(1) "else" {} elseStmt = Statement() ]
+ {
+ return new IfStmt(range(begin, token()), condition, thenStmt, elseStmt);
+ }
+}
+
+WhileStmt WhileStatement():
+{
+ Expression condition;
+ Statement body;
+ JavaToken begin;
+}
+{
+ "while" {begin=token();} "(" condition = Expression() ")" body = Statement()
+ { return new WhileStmt(range(begin, token()),condition, body); }
+}
+
+DoStmt DoStatement():
+{
+ Expression condition;
+ Statement body;
+ JavaToken begin;
+}
+{
+ "do" {begin=token();} body = Statement() "while" "(" condition = Expression() ")" ";"
+ { return new DoStmt(range(begin, token()),body, condition); }
+}
+
+Statement ForStatement():
+{
+ VariableDeclarationExpr varExpr = null;
+ Expression expr = null;
+ NodeList<Expression> init = emptyList();
+ NodeList<Expression> update = emptyList();
+ Statement body;
+ JavaToken begin;
+}
+{
+ "for" {begin=token();} "("
+
+ (
+ LOOKAHEAD(VariableDeclarationExpression() ":")
+ varExpr = VariableDeclarationExpression() ":" expr = Expression()
+ |
+ [ init = ForInit() ] ";" [ expr = Expression() ] ";" [ update = ForUpdate() ]
+ )
+
+ ")" body = Statement()
+
+ {
+ if (varExpr != null) {
+ return new ForeachStmt(range(begin, token()),varExpr, expr, body);
+ }
+ return new ForStmt(range(begin, token()),init, expr, update, body);
+ }
+}
+
+NodeList<Expression> ForInit():
+{
+ NodeList<Expression> ret;
+ Expression expr;
+}
+{
+ (
+ LOOKAHEAD( Modifiers() Type() Identifier() )
+ expr = VariableDeclarationExpression() { ret = new NodeList<Expression>(); ret.add(expr); }
+ |
+ ret = ExpressionList()
+ )
+ { return ret; }
+}
+
+NodeList<Expression> ExpressionList():
+{
+ NodeList<Expression> ret = new NodeList<Expression>();
+ Expression expr;
+}
+{
+ expr = Expression() { ret.add(expr); } ( "," expr = Expression() { ret.add(expr); } )*
+
+ { return ret; }
+}
+
+NodeList<Expression> ForUpdate():
+{
+ NodeList<Expression> ret;
+}
+{
+ ret = ExpressionList()
+
+ { return ret; }
+}
+
+BreakStmt BreakStatement():
+{
+ SimpleName label = null;
+ JavaToken begin;
+}
+{
+ "break" {begin=token();} [ label = SimpleName() ] ";"
+ { return new BreakStmt(range(begin, token()), label); }
+}
+
+ContinueStmt ContinueStatement():
+{
+ SimpleName label = null;
+ JavaToken begin;
+}
+{
+ "continue" {begin=token();} [ label = SimpleName() ] ";"
+ { return new ContinueStmt(range(begin, token()), label); }
+}
+
+ReturnStmt ReturnStatement():
+{
+ Expression expr = null;
+ JavaToken begin;
+}
+{
+ "return" {begin=token();} [ expr = Expression() ] ";"
+ { return new ReturnStmt(range(begin, token()),expr); }
+}
+
+ThrowStmt ThrowStatement():
+{
+ Expression expr;
+ JavaToken begin;
+}
+{
+ "throw" {begin=token();} expr = Expression() ";"
+ { return new ThrowStmt(range(begin, token()),expr); }
+}
+
+SynchronizedStmt SynchronizedStatement():
+{
+ Expression expr;
+ BlockStmt body;
+ JavaToken begin;
+}
+{
+ "synchronized" {begin=token();} "(" expr = Expression() ")" body = Block()
+ { return new SynchronizedStmt(range(begin, token()),expr, body); }
+}
+
+TryStmt TryStatement():
+{
+ NodeList<Expression> resources = emptyList();
+ BlockStmt tryBlock;
+ BlockStmt finallyBlock = null;
+ NodeList<CatchClause> catchs = emptyList();
+ BlockStmt catchBlock;
+ ModifierHolder exceptModifier;
+ ReferenceType exceptionType;
+ NodeList<ReferenceType> exceptionTypes = emptyList();
+ Pair<SimpleName, List<ArrayBracketPair>> exceptId;
+ JavaToken begin;
+ JavaToken catchBegin;
+ JavaToken typesBegin;
+ JavaToken paramEnd;
+ Type type;
+}
+{
+ "try" {begin=token();}
+ (resources = ResourceSpecification())?
+ tryBlock = Block()
+ (
+ LOOKAHEAD(2)
+ (
+ "catch" {catchBegin=token();}
+ "(" { typesBegin=token(); }
+ exceptModifier = Modifiers() exceptionType = ReferenceType(emptyList()) { exceptionTypes.add(exceptionType); }
+ ( "|" exceptionType = AnnotatedReferenceType() { exceptionTypes.add(exceptionType); } )*
+ exceptId = VariableDeclaratorId() { paramEnd = token(); }
+ ")"
+
+ catchBlock = Block()
+ {
+ if (exceptionTypes.size() > 1) {
+ type = new UnionType(range(exceptionTypes.get(0), exceptionTypes.get(exceptionTypes.size() - 1)), exceptionTypes);
+ } else {
+ type = (Type)exceptionTypes.get(0);
+ }
+ Parameter catchType = new Parameter(range(type, paramEnd), exceptModifier.modifiers, exceptModifier.annotations, type, false, emptyList(), exceptId.a);
+ catchs = add(catchs, new CatchClause(range(catchBegin, token()), catchType, catchBlock));
+ exceptionTypes = emptyList(); }
+ )*
+ [ "finally" finallyBlock = Block() ]
+ |
+ "finally" finallyBlock = Block()
+ )
+ { return new TryStmt(range(begin, token()), resources, tryBlock, catchs, finallyBlock); }
+}
+
+
+NodeList<Expression> ResourceSpecification() :
+{
+ NodeList<Expression> variables;
+}
+{
+ "("
+ variables = Resources()
+ (LOOKAHEAD(2) ";")?
+ ")"
+ { return variables; }
+}
+
+
+NodeList<Expression> Resources() :
+{
+ NodeList<Expression> expressions = new NodeList<Expression>();
+ Expression expr;
+}
+{
+ expr = Resource() {expressions.add(expr);} (LOOKAHEAD(2) ";" expr = Resource() {expressions.add(expr);})*
+ { return expressions; }
+}
+
+Expression Resource() :
+{
+ Expression expr;
+}
+{
+ ( LOOKAHEAD( Modifiers() partialType = Type() VariableDeclarator(partialType))
+ /*this is a bit more lenient than we need to be, eg allowing access modifiers like private*/
+ expr = VariableDeclarationExpression()
+ |
+ expr = PrimaryExpression()
+ )
+ { return expr; }
+}
+
+
+/* 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 &&
+ getToken(1).realKind == RUNSIGNEDSHIFT} )
+ ">" ">" ">"
+ )
+}
+
+void RSIGNEDSHIFT():
+{}
+{
+ ( LOOKAHEAD({ getToken(1).kind == GT &&
+ getToken(1).realKind == RSIGNEDSHIFT} )
+ ">" ">"
+ )
+}
+
+/* Annotation syntax follows. */
+
+NodeList<AnnotationExpr> Annotations():
+{
+ NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+ AnnotationExpr annotation;
+}
+{
+ (LOOKAHEAD("@") annotation = Annotation() {annotations = add(annotations, annotation);} )*
+ { return annotations; }
+}
+
+AnnotationExpr Annotation():
+{
+ AnnotationExpr ret;
+ Name name;
+ NodeList<MemberValuePair> pairs = emptyList();
+ JavaToken begin;
+ Expression memberVal;
+}
+{
+ "@" { begin=token(); } name = Name()
+ (
+ LOOKAHEAD( "(" ( Identifier() "=" | ")" ))
+ "(" [ pairs = MemberValuePairs() ] ")"
+ { ret = new NormalAnnotationExpr(range(begin, token()), name, pairs); }
+ |
+ LOOKAHEAD( "(" )
+ "(" memberVal = MemberValue() ")"
+ { ret = new SingleMemberAnnotationExpr(range(begin, token()), name, memberVal); }
+ |
+ { ret = new MarkerAnnotationExpr(range(begin, token()), name); }
+ )
+ { return ret; }
+}
+
+NodeList<MemberValuePair> MemberValuePairs():
+{
+ NodeList<MemberValuePair> ret = new NodeList<MemberValuePair>();
+ MemberValuePair pair;
+}
+{
+ pair = MemberValuePair() { ret.add(pair); } ( "," pair = MemberValuePair() { ret.add(pair); } )*
+ { return ret; }
+}
+
+MemberValuePair MemberValuePair():
+{
+ SimpleName name;
+ Expression value;
+ JavaToken begin;
+}
+{
+ name = SimpleName() { begin=token();} "=" value = MemberValue()
+ { return new MemberValuePair(range(begin, token()),name, value); }
+}
+
+Expression MemberValue():
+{
+ Expression ret;
+}
+{
+ ( LOOKAHEAD("@")
+ ret = Annotation()
+ |
+ ret = MemberValueArrayInitializer()
+ |
+ ret = ConditionalExpression()
+ )
+ { return ret; }
+}
+
+Expression MemberValueArrayInitializer():
+{
+ NodeList<Expression> ret = emptyList();
+ Expression member;
+ JavaToken begin;
+}
+{
+ "{" {begin=token();}
+ ( member = MemberValue() { ret.add(member); } ( LOOKAHEAD(2) "," member = MemberValue() { ret.add(member); } )* )? [ "," ]
+ "}"
+ { return new ArrayInitializerExpr(range(begin, token()),ret); }
+}
+
+
+/* Annotation Types. */
+
+AnnotationDeclaration AnnotationTypeDeclaration(ModifierHolder modifier):
+{
+ SimpleName name;
+ NodeList<BodyDeclaration<?>> members = emptyList();
+ JavaToken begin = modifier.begin;
+}
+{
+ "@" { begin=orIfInvalid(begin, token()); }
+ "interface" name = SimpleName() members = AnnotationTypeBody()
+ {
+ return new AnnotationDeclaration(range(begin, token()), modifier.modifiers, modifier.annotations, name, members);
+ }
+}
+
+NodeList<BodyDeclaration<?>> AnnotationTypeBody():
+{
+ NodeList<BodyDeclaration<?>> ret = emptyList();
+ BodyDeclaration member;
+}
+{
+ "{" (
+ member = AnnotationBodyDeclaration() { ret = addWhenNotNull(ret, member); }
+ |
+ ";"
+ )* "}"
+ { return ret; }
+}
+
+BodyDeclaration<?> AnnotationBodyDeclaration():
+{
+ ModifierHolder modifier;
+ BodyDeclaration ret;
+}
+{
+ (
+ modifier = Modifiers()
+ (
+ LOOKAHEAD(Type() Identifier() "(")
+ ret = AnnotationTypeMemberDeclaration(modifier)
+ |
+ ret = ClassOrInterfaceDeclaration(modifier)
+ | LOOKAHEAD("enum")
+ ret = EnumDeclaration(modifier)
+ |
+ ret = AnnotationTypeDeclaration(modifier)
+ |
+ ret = FieldDeclaration(modifier)
+ )
+ )
+ { return ret; }
+}
+
+AnnotationMemberDeclaration AnnotationTypeMemberDeclaration(ModifierHolder modifier):
+{
+ Type type;
+ SimpleName name;
+ Expression defaultVal = null;
+}
+{
+ type = Type(emptyList()) name = SimpleName() "(" ")" [ defaultVal = DefaultValue() ] ";"
+
+ {
+ JavaToken begin = orIfInvalid(modifier.begin, type);
+ return new AnnotationMemberDeclaration(range(begin, token()), modifier.modifiers, modifier.annotations, type, name, defaultVal);
+ }
+}
+
+Expression DefaultValue():
+{
+ Expression ret;
+}
+{
+ "default" ret = MemberValue()
+ { return ret; }
+}
+
+/* Module syntax follows */
+
+
+ModuleStmt ModuleStmt():
+{
+ ModifierHolder modifiers;
+ Name name;
+ Name tmpName;
+ NodeList<Name> names=emptyList();
+ Type type;
+ Type tmpType;
+ NodeList<Type> types=emptyList();
+ JavaToken begin;
+ ModuleStmt stmt=new ModuleRequiresStmt();
+ JavaToken transitiveExceptionalToken;
+}
+{
+ (
+ // This is a hack for the edge case "requires transitive;" which is supposed to mean "require the module named 'transitive'"
+ LOOKAHEAD(<REQUIRES> <TRANSITIVE> ";")
+ <REQUIRES> {begin=token();} <TRANSITIVE> {transitiveExceptionalToken=token(); setTokenKind(IDENTIFIER);} ";" {stmt=new ModuleRequiresStmt(range(begin, token()), EnumSet.noneOf(Modifier.class), new Name(range(transitiveExceptionalToken, transitiveExceptionalToken), null, transitiveExceptionalToken.getText(), new NodeList<AnnotationExpr>()));}
+ |
+ <REQUIRES> {begin=token();} modifiers=Modifiers() name=Name() ";" {stmt=new ModuleRequiresStmt(range(begin, token()), modifiers.modifiers, name);}
+ |
+ <EXPORTS> {begin=token();} name=Name() [<TO> tmpName=Name() {names.add(tmpName);} ("," tmpName=Name(){names.add(tmpName);} )* ] ";" {stmt=new ModuleExportsStmt(range(begin, token()), name, names);}
+ |
+ <OPENS> {begin=token();} name=Name() [<TO> tmpName=Name() {names.add(tmpName);} ("," tmpName=Name(){names.add(tmpName);} )* ] ";" {stmt=new ModuleOpensStmt(range(begin, token()), name, names);}
+ |
+ <USES> { begin=token();} type=Type(emptyList()) ";" {stmt=new ModuleUsesStmt(range(begin, token()), type);}
+ |
+ <PROVIDES> { begin=token();} type=Type(emptyList()) <WITH> tmpType=Type(emptyList()) {types.add(tmpType);} ("," tmpType=Type(emptyList()) {types.add(tmpType);} )* ";" {stmt=new ModuleProvidesStmt(range(begin, token()), type, types);}
+ )
+ { return stmt; }
+}
+
+ModuleDeclaration ModuleDeclaration(ModifierHolder modifier):
+{
+ NodeList<ModuleStmt> statements = new NodeList<ModuleStmt>();
+ boolean open=false;
+ ModuleStmt st;
+ Name name;
+ JavaToken begin = modifier.begin;
+}
+{
+ [ <OPEN> {open=true; begin = orIfInvalid(begin, token());} ]
+ <MODULE> { begin = orIfInvalid(begin, token()); }
+ name = Name() "{"
+ ( st = ModuleStmt() { statements = add(statements, st); } )*
+ "}"
+ { return new ModuleDeclaration(range(begin, token()), modifier.annotations, name, open, statements); }
+}
+
+/* Rules for matching partial inputs.
+These rules are needed to properly terminate them -
+if we simply use the usual rules, they will ignore everything in the provider
+after they matched their desired input, which will lead to unexpected behaviour
+*/
+
+
+BlockStmt BlockParseStart():
+{ BlockStmt ret; }
+{ ret = Block() <EOF> { return ret; } }
+
+Statement BlockStatementParseStart():
+{ Statement ret; }
+{ (LOOKAHEAD(3) ret = BlockStatement()|ret = ExplicitConstructorInvocation()) <EOF> { return ret; } }
+
+ImportDeclaration ImportDeclarationParseStart():
+{ ImportDeclaration ret; }
+{ ret = ImportDeclaration() <EOF> { return ret; } }
+
+Expression ExpressionParseStart():
+{ Expression ret; }
+{ ret = Expression() <EOF> { return ret; } }
+
+AnnotationExpr AnnotationParseStart():
+{ AnnotationExpr ret; }
+{ ret = Annotation() <EOF> { return ret; } }
+
+BodyDeclaration<?> AnnotationBodyDeclarationParseStart():
+{ BodyDeclaration<?> ret; }
+{ ret = AnnotationBodyDeclaration() <EOF> { return ret; } }
+
+BodyDeclaration<?> ClassOrInterfaceBodyDeclarationParseStart():
+{ BodyDeclaration<?> ret; }
+{ ret = ClassOrInterfaceBodyDeclaration() <EOF> { return ret; } }
+
+ClassOrInterfaceType ClassOrInterfaceTypeParseStart():
+{ ClassOrInterfaceType ret; }
+{ ret = AnnotatedClassOrInterfaceType() <EOF> { return ret; } }
+
+Type ResultTypeParseStart():
+{ NodeList<AnnotationExpr> annotations; Type ret; }
+{ annotations = Annotations() ret = ResultType(annotations) <EOF> { return ret; } }
+
+VariableDeclarationExpr VariableDeclarationExpressionParseStart():
+{ VariableDeclarationExpr ret; }
+{ ret = VariableDeclarationExpression() <EOF> { return ret; } }
+
+ExplicitConstructorInvocationStmt ExplicitConstructorInvocationParseStart():
+{ ExplicitConstructorInvocationStmt ret; }
+{ ret = ExplicitConstructorInvocation() <EOF> { return ret; } }
+
+Name NameParseStart():
+{ Name ret; }
+{ ret = Name() <EOF> { return ret; } }
+
+SimpleName SimpleNameParseStart():
+{ SimpleName ret; }
+{ ret = SimpleName() <EOF> { return ret; } }
+
+Parameter ParameterParseStart():
+{ Parameter ret; }
+{ ret = Parameter() <EOF> { return ret; } }
+
+PackageDeclaration PackageDeclarationParseStart():
+{ PackageDeclaration ret; }
+{ ret = PackageDeclaration() <EOF> { return ret; } }