/* * 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 : { | | | } TOKEN_MGR_DECLS : { private List tokens = new ArrayList(); private CommentsCollection commentsCollection = new CommentsCollection(); private JavaToken homeToken; private Stack tokenWorkStack = new Stack(); private boolean storeTokens; void reset() { tokens = new ArrayList(); commentsCollection = new CommentsCollection(); homeToken = null; } List 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 : { } MORE : { { input_stream.backup(1); } : IN_JAVADOC_COMMENT | : IN_MULTI_LINE_COMMENT } 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" > | < REQUIRES: "requires" > | < TO: "to" > | < WITH: "with" > | < OPEN: "open" > | < OPENS: "opens" > | < USES: "uses" > | < MODULE: "module" > | < EXPORTS: "exports" > | < PROVIDES: "provides" > | < TRANSITIVE: "transitive" > } /* LITERALS */ TOKEN : { < LONG_LITERAL: (["l","L"]) | (["l","L"]) | (["l","L"]) | (["l","L"]) > | < INTEGER_LITERAL: | | | > | < #DECIMAL_LITERAL: ["0"-"9"]((["0"-"9","_"])*["0"-"9"])? > | < #HEX_LITERAL: "0" ["x","X"] > | < #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: "." ()? ()? (["f","F","d","D"])? | "." ()? (["f","F","d","D"])? | (["f","F","d","D"])? | ()? ["f","F","d","D"] > | < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? ()+ > | < #HEXADECIMAL_FLOATING_POINT_LITERAL: (".")? (["f","F","d","D"])? | "0" ["x","X"] ()? "." (["f","F","d","D"])? > | < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? > | < #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"] ) ) | ) "'" > | < 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: [ "\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" ] | > | < #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" ] | > } /* 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: { } /***************************************** * THE JAVA LANGUAGE GRAMMAR STARTS HERE * *****************************************/ /* * Program structuring syntax follows. */ CompilationUnit CompilationUnit(): { PackageDeclaration pakage = null; NodeList imports = emptyList(); ImportDeclaration in = null; NodeList> 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) | ";" ) ) )* ( | ) { 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(), new NodeList>(), null); compilationUnit.setParsed(UNPARSABLE); return compilationUnit; } } PackageDeclaration PackageDeclaration(): { NodeList annotations = new NodeList(); 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 modifiers = EnumSet.noneOf(Modifier.class); NodeList annotations = new NodeList(); 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 typePar = new RangedList(emptyList()); NodeList extList = emptyList(); NodeList impList = emptyList(); NodeList> 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 ExtendsList(): { boolean extendsMoreThanOne = false; NodeList ret = new NodeList(); ClassOrInterfaceType cit; } { "extends" cit = AnnotatedClassOrInterfaceType() { ret.add(cit); } ( "," cit = AnnotatedClassOrInterfaceType() { ret.add(cit); extendsMoreThanOne = true; } )* { return ret; } } NodeList ImplementsList(): { NodeList ret = new NodeList(); ClassOrInterfaceType cit; } { "implements" cit = AnnotatedClassOrInterfaceType() { ret.add(cit); } ( "," cit = AnnotatedClassOrInterfaceType() { ret.add(cit); } )* { return ret; } } EnumDeclaration EnumDeclaration(ModifierHolder modifier): { SimpleName name; NodeList impList = emptyList(); EnumConstantDeclaration entry; NodeList entries = emptyList(); BodyDeclaration member; NodeList> 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 annotations = new NodeList(); AnnotationExpr ann; SimpleName name; NodeList args = emptyList(); NodeList> 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 . */ RangedList TypeParameters(): { RangedList ret = new RangedList(new NodeList()); TypeParameter tp; NodeList 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 annotations): { SimpleName name; NodeList typeBound = emptyList(); JavaToken begin; } { name = SimpleName() { begin=token(); } [ typeBound = TypeBound() ] { return new TypeParameter(range(begin, token()), name, typeBound, annotations); } } NodeList TypeBound(): { NodeList ret = emptyList(); ClassOrInterfaceType cit; } { "extends" cit = AnnotatedClassOrInterfaceType() { ret.add(cit); } ( "&" cit = AnnotatedClassOrInterfaceType() { ret.add(cit); } )* { return ret; } } NodeList> ClassOrInterfaceBody(): { NodeList> 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 variables = new NodeList(); 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> id; Expression init = null; } { id = VariableDeclaratorId() [ "=" init = VariableInitializer() ] { return new VariableDeclarator(range(id.a, token()), juggleArrayType(partialType, id.b), id.a, init); } } Pair> VariableDeclaratorId(): { SimpleName name; JavaToken begin; ArrayBracketPair arrayBracketPair; List 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 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 typeParameters = new RangedList(emptyList()); Type type; SimpleName name; Pair, ReceiverParameter> parameters = new Pair, ReceiverParameter>(emptyList(), null); ArrayBracketPair arrayBracketPair; List arrayBracketPairs = new ArrayList(0); NodeList throws_ = emptyList(); BlockStmt body = null; NodeList 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 annotations; ReferenceType type; } { annotations = Annotations() type = ReferenceType(annotations) { return type; } } Type AnnotatedType(): { NodeList annotations; Type type; } { annotations = Annotations() type = Type(annotations) { return type; } } Pair, ReceiverParameter> Parameters(): { NodeList 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 LambdaParameters(): { NodeList ret = null; Parameter par; } { par = Parameter() { ret = add(ret, par); } ( "," par = Parameter() { ret = add(ret, par); } )* { return ret; } } NodeList InferredLambdaParameters(): { NodeList ret = null; Pair> 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> id; NodeList 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 annotations = emptyList(); } { annotations = Annotations() partialType = Type(emptyList()) id = ReceiverParameterId() { return new ReceiverParameter(range(partialType, token()), annotations, partialType, id); } } Name ReceiverParameterId(): { Name ret = null; NodeList annotations; } { [ LOOKAHEAD(Name()) ret = Name() "."] annotations=Annotations() "this" { return new Name(tokenRange(), ret, token.image, annotations); } } ConstructorDeclaration ConstructorDeclaration(ModifierHolder modifier): { RangedList typeParameters = new RangedList(emptyList()); SimpleName name; Pair, ReceiverParameter> parameters = new Pair, ReceiverParameter>(emptyList(), null); NodeList throws_ = emptyList(); ExplicitConstructorInvocationStmt exConsInv = null; NodeList 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 args; Expression expr = null; RangedList typeArgs = new RangedList(null); JavaToken begin = INVALID; } { ( LOOKAHEAD([ TypeArguments() ] "(") [ typeArgs = TypeArguments() { begin=typeArgs.range.getBegin(); } ] { begin = orIfInvalid(begin, token()); isThis = true; } args = Arguments() ";" | [ LOOKAHEAD( PrimaryExpressionWithoutSuperSuffix() "." ) expr = PrimaryExpressionWithoutSuperSuffix() "." { begin = orIfInvalid(begin, expr); } ] [ typeArgs = TypeArguments() { begin = orIfInvalid(begin, typeArgs.range.getBegin()); } ] {begin = orIfInvalid(begin, token());} args = Arguments() ";" ) { return new ExplicitConstructorInvocationStmt(range(begin, token()),typeArgs.list, isThis, expr, args); } } NodeList Statements(): { NodeList 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 annotations): { Type ret; } { ( LOOKAHEAD(2) ret = ReferenceType(annotations) | ret = PrimitiveType(annotations ) ) { return ret; } } ReferenceType ReferenceType(NodeList annotations): { Type type; ArrayBracketPair arrayBracketPair; List 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 annotations; JavaToken begin = INVALID; } { annotations = Annotations() "[" { begin = orIfInvalid(begin, token()); } "]" { return new ArrayBracketPair(range(begin, token()), origin, annotations); } } IntersectionType IntersectionType(NodeList annotations): { JavaToken begin = INVALID; ReferenceType elementType; NodeList 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 annotations = new NodeList(); ClassOrInterfaceType cit; } { annotations = Annotations() cit = ClassOrInterfaceType(annotations) { return cit; } } ClassOrInterfaceType ClassOrInterfaceType(NodeList firstAnnotations): { ClassOrInterfaceType ret; SimpleName name; RangedList typeArgs = new RangedList(null); JavaToken begin; NodeList annotations = new NodeList(); } { name = SimpleName() {begin=token();} [ LOOKAHEAD(2) typeArgs = TypeArguments() ] { ret = new ClassOrInterfaceType(range(begin, token()), null, name, typeArgs.list, firstAnnotations); typeArgs = new RangedList(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(null); } )* { return ret; } } RangedList TypeArguments(): { RangedList ret = new RangedList(new NodeList()); 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 annotations; } { annotations = Annotations() ( ret = Type(annotations) | ret = Wildcard(annotations) ) { return ret; } } WildcardType Wildcard(NodeList firstAnnotations): { ReferenceType ext = null; ReferenceType sup = null; JavaToken begin; NodeList annotations = new NodeList(); } { "?" {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 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 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 annotations = new NodeList(); } { 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. ( | | | | | | | | | | // Make sure older Java versions parse | | // An actual plain old 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 typeArgs = new RangedList(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 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 annotations; NodeList 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 typeArgs = new RangedList(null); NodeList args = emptyList(); NodeList params = emptyList(); boolean hasArgs = false; boolean isLambda = false; Type type; JavaToken begin; Parameter p = null; SimpleName id = null; } { ( ret = Literal() | { ret = new ThisExpr(tokenRange(), null); } | { 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 typeArgs = new RangedList(null); NodeList 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; } { ( { ret = new IntegerLiteralExpr(tokenRange(), token.image); } | { ret = new LongLiteralExpr(tokenRange(), token.image); } | { ret = new DoubleLiteralExpr(tokenRange(), token.image); } | { ret = new CharLiteralExpr(tokenRange(), token.image.substring(1, token.image.length()-1)); } | { 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 Arguments(): { NodeList ret = emptyList(); } { "(" [ ret = ArgumentList() ] ")" { return ret; } } NodeList ArgumentList(): { NodeList 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 typeArgs = new RangedList(null); NodeList> anonymousBody = null; NodeList args; JavaToken begin = INVALID; NodeList annotations = new NodeList(); } { "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 inits = emptyList(); List> accum = new ArrayList>(); NodeList annotations = new NodeList(); JavaToken arrayCreationLevelStart = INVALID; List levelRanges = new ArrayList(); } { ( 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 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()); 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 variables = new NodeList(); 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 typeArgs = new RangedList(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 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 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 init = emptyList(); NodeList 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 ForInit(): { NodeList ret; Expression expr; } { ( LOOKAHEAD( Modifiers() Type() Identifier() ) expr = VariableDeclarationExpression() { ret = new NodeList(); ret.add(expr); } | ret = ExpressionList() ) { return ret; } } NodeList ExpressionList(): { NodeList ret = new NodeList(); Expression expr; } { expr = Expression() { ret.add(expr); } ( "," expr = Expression() { ret.add(expr); } )* { return ret; } } NodeList ForUpdate(): { NodeList 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 resources = emptyList(); BlockStmt tryBlock; BlockStmt finallyBlock = null; NodeList catchs = emptyList(); BlockStmt catchBlock; ModifierHolder exceptModifier; ReferenceType exceptionType; NodeList exceptionTypes = emptyList(); Pair> 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 ResourceSpecification() : { NodeList variables; } { "(" variables = Resources() (LOOKAHEAD(2) ";")? ")" { return variables; } } NodeList Resources() : { NodeList expressions = new NodeList(); 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 Annotations(): { NodeList annotations = new NodeList(); AnnotationExpr annotation; } { (LOOKAHEAD("@") annotation = Annotation() {annotations = add(annotations, annotation);} )* { return annotations; } } AnnotationExpr Annotation(): { AnnotationExpr ret; Name name; NodeList 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 MemberValuePairs(): { NodeList ret = new NodeList(); 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 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> 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> AnnotationTypeBody(): { NodeList> 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 names=emptyList(); Type type; Type tmpType; NodeList 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( ";") {begin=token();} {transitiveExceptionalToken=token(); setTokenKind(IDENTIFIER);} ";" {stmt=new ModuleRequiresStmt(range(begin, token()), EnumSet.noneOf(Modifier.class), new Name(range(transitiveExceptionalToken, transitiveExceptionalToken), null, transitiveExceptionalToken.getText(), new NodeList()));} | {begin=token();} modifiers=Modifiers() name=Name() ";" {stmt=new ModuleRequiresStmt(range(begin, token()), modifiers.modifiers, name);} | {begin=token();} name=Name() [ tmpName=Name() {names.add(tmpName);} ("," tmpName=Name(){names.add(tmpName);} )* ] ";" {stmt=new ModuleExportsStmt(range(begin, token()), name, names);} | {begin=token();} name=Name() [ tmpName=Name() {names.add(tmpName);} ("," tmpName=Name(){names.add(tmpName);} )* ] ";" {stmt=new ModuleOpensStmt(range(begin, token()), name, names);} | { begin=token();} type=Type(emptyList()) ";" {stmt=new ModuleUsesStmt(range(begin, token()), type);} | { begin=token();} type=Type(emptyList()) 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 statements = new NodeList(); boolean open=false; ModuleStmt st; Name name; JavaToken begin = modifier.begin; } { [ {open=true; begin = orIfInvalid(begin, token());} ] { 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() { return ret; } } Statement BlockStatementParseStart(): { Statement ret; } { (LOOKAHEAD(3) ret = BlockStatement()|ret = ExplicitConstructorInvocation()) { return ret; } } ImportDeclaration ImportDeclarationParseStart(): { ImportDeclaration ret; } { ret = ImportDeclaration() { return ret; } } Expression ExpressionParseStart(): { Expression ret; } { ret = Expression() { return ret; } } AnnotationExpr AnnotationParseStart(): { AnnotationExpr ret; } { ret = Annotation() { return ret; } } BodyDeclaration AnnotationBodyDeclarationParseStart(): { BodyDeclaration ret; } { ret = AnnotationBodyDeclaration() { return ret; } } BodyDeclaration ClassOrInterfaceBodyDeclarationParseStart(): { BodyDeclaration ret; } { ret = ClassOrInterfaceBodyDeclaration() { return ret; } } ClassOrInterfaceType ClassOrInterfaceTypeParseStart(): { ClassOrInterfaceType ret; } { ret = AnnotatedClassOrInterfaceType() { return ret; } } Type ResultTypeParseStart(): { NodeList annotations; Type ret; } { annotations = Annotations() ret = ResultType(annotations) { return ret; } } VariableDeclarationExpr VariableDeclarationExpressionParseStart(): { VariableDeclarationExpr ret; } { ret = VariableDeclarationExpression() { return ret; } } ExplicitConstructorInvocationStmt ExplicitConstructorInvocationParseStart(): { ExplicitConstructorInvocationStmt ret; } { ret = ExplicitConstructorInvocation() { return ret; } } Name NameParseStart(): { Name ret; } { ret = Name() { return ret; } } SimpleName SimpleNameParseStart(): { SimpleName ret; } { ret = SimpleName() { return ret; } } Parameter ParameterParseStart(): { Parameter ret; } { ret = Parameter() { return ret; } } PackageDeclaration PackageDeclarationParseStart(): { PackageDeclaration ret; } { ret = PackageDeclaration() { return ret; } }