Skip to content
Permalink
master
Switch branches/tags
Go to file
 
 
Cannot retrieve contributors at this time
/*
* Copyright (C) 2007-2010 Júlio Vilmar Gesser.
* Copyright (C) 2011, 2013-2020 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.
*/
/*
* -- FILE STRUCTURE --
* https://javacc.github.io/javacc/documentation/grammar.html#file-structure
*
* <pre>{@code
* javacc_input ::= javacc_options
* "PARSER_BEGIN" "(" <IDENTIFIER> ")"
* java_compilation_unit
* "PARSER_END" "(" <IDENTIFIER> ")"
* ( production )*
* <EOF>
* }</pre>
*/
/*
* Available options are spread across:
* - https://javacc.github.io/javacc/documentation/cli.html
* - https://javacc.github.io/javacc/documentation/grammar.html#options
*/
options {
COMMON_TOKEN_ACTION = true;
ERROR_REPORTING = true;
JAVA_TEMPLATE_TYPE = "modern"; // FIXME: Warning: Bad option name "JAVA_TEMPLATE_TYPE". Option setting will be ignored.
JDK_VERSION = "1.8";
STATIC = false;
TOKEN_EXTENDS = "TokenBase";
}
/********************************************************
* This is the template for the generated file. *
* GeneratedJavaParser.java *
********************************************************/
PARSER_BEGIN(GeneratedJavaParser)
/*
* Copyright (C) 2007-2010 Júlio Vilmar Gesser.
* Copyright (C) 2011, 2013-2020 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 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.*;
import static com.github.javaparser.ast.stmt.SwitchEntry.Type.*;
@Generated("JavaCC")
final class GeneratedJavaParser extends GeneratedJavaParserBase {
/* Returns the JavaParser specific token type of the last matched token */
JavaToken token() {
return token.javaToken;
}
/* Returns the last matched token */
Token getCurrentToken() {
return token;
}
/* 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)
/*
* https://javacc.github.io/javacc/documentation/grammar.html#production
*
* <pre>{@code
* production ::= javacode_production
* | regular_expr_production
* | bnf_production
* | token_manager_decls
* }</pre>
*/
/***************************************************************************
* TOKEN DEFINITIONS START HERE *
* https://javacc.github.io/javacc/documentation/grammar.html#regexpr_kind *
* *
* <pre>{@code *
* regexpr_kind ::= "TOKEN" *
* | "SPECIAL_TOKEN" *
* | "SKIP" *
* | "MORE" *
* }</pre> *
***************************************************************************/
/* WHITE SPACE */
SPECIAL_TOKEN :
{
<SPACE: [ // TODO: Rename (or document) this as `WHITESPACE`?
" ", // regular space character
"\t", // tab character
"\f", // formfeed character
"\u0085", // 'NEXT LINE (NEL)' (U+0085)
"\u00A0", // 'NO-BREAK SPACE' (U+00A0)
"\u1680", // 'OGHAM SPACE MARK' (U+1680)
"\u180e", // 'MONGOLIAN VOWEL SEPARATOR' (U+180E)
"\u2000", // 'EN QUAD' (U+2000)
"\u2001", // 'EM QUAD' (U+2001)
"\u2002", // 'EN SPACE' (U+2002)
"\u2003", // 'EM SPACE' (U+2003)
"\u2004", // 'THREE-PER-EM SPACE' (U+2004)
"\u2005", // 'FOUR-PER-EM SPACE' (U+2005)
"\u2006", // 'SIX-PER-EM SPACE' (U+2006)
"\u2007", // 'FIGURE SPACE' (U+2007)
"\u2008", // 'PUNCTUATION SPACE' (U+2008)
"\u2009", // 'THIN SPACE' (U+2009)
"\u200a", // 'HAIR SPACE' (U+200A)
"\u200b", // 'ZERO WIDTH SPACE' (U+200B)
"\u200c", // 'ZERO WIDTH NON-JOINER' (U+200C)
"\u200d", // 'ZERO WIDTH JOINER' (U+200D)
"\u2028", // 'LINE SEPARATOR' (U+2028) // TODO: Investigate this being EOL?
"\u2029", // 'PARAGRAPH SEPARATOR' (U+2029) // TODO: Investigate this being EOL?
"\u202f", // 'NARROW NO-BREAK SPACE' (U+202F)
"\u205f", // 'MEDIUM MATHEMATICAL SPACE' (U+205F)
"\u2060", // 'WORD JOINER' (U+2060)
"\u3000", // 'IDEOGRAPHIC SPACE' (U+3000)
"\ufeff" // 'ZERO WIDTH NO-BREAK SPACE' (U+FEFF)
]>
| <WINDOWS_EOL : "\r\n">
| <UNIX_EOL: "\n">
| <OLD_MAC_EOL: "\r">
}
/*
* GeneratedJavaParserTokenManager.java is generated,
* based on the template within this TOKEN_MGR_DECLS block.
*/
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;
private boolean yieldSupported = false;
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;
}
public void setYieldSupported() {
yieldSupported = true;
}
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"])*>
}
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" >
| < RECORD: "record" >
| < 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" >
| < YIELD: "yield" > {if(!yieldSupported)matchedToken.kind=IDENTIFIER;}
| < REQUIRES: "requires" >
| < TO: "to" >
| < WITH: "with" >
| < OPEN: "open" >
| < OPENS: "opens" >
| < USES: "uses" >
| < MODULE: "module" >
| < EXPORTS: "exports" >
| < PROVIDES: "provides" >
| < TRANSITIVE: "transitive" >
}
/* LITERALS */
TOKEN :
{
/**
* Note that the JLS treats longs as an int followed by the letter {@code L} (upper or lowercase)
* Note that Javaparser differs, as it handles longs separately (as a {@code LONG_LITERAL})
*/
< LONG_LITERAL:
<DECIMAL_LITERAL> (["l","L"])
| <HEX_LITERAL> (["l","L"])
| <OCTAL_LITERAL> (["l","L"])
| <BINARY_LITERAL> (["l","L"])
>
|
/**
* Note that the JLS treats longs as an int followed by the letter {@code L} (upper or lowercase)
* Note that Javaparser differs, as it handles longs separately (as a {@code LONG_LITERAL})
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.10.1
* <pre>{@code
* IntegerLiteral:
* DecimalIntegerLiteral
* HexIntegerLiteral
* OctalIntegerLiteral
* BinaryIntegerLiteral
* DecimalIntegerLiteral:
* DecimalNumeral [IntegerTypeSuffix]
* HexIntegerLiteral:
* HexNumeral [IntegerTypeSuffix]
* OctalIntegerLiteral:
* OctalNumeral [IntegerTypeSuffix]
* BinaryIntegerLiteral:
* BinaryNumeral [IntegerTypeSuffix]
* IntegerTypeSuffix:
* (one of)
* l L
* }</pre>
* For convenience:
* <pre>{@code
* DecimalNumeral:
* 0
* NonZeroDigit [Digits]
* NonZeroDigit Underscores Digits
* NonZeroDigit:
* (one of)
* 1 2 3 4 5 6 7 8 9
* Digits:
* Digit
* Digit [DigitsAndUnderscores] Digit
* Digit:
* 0
* NonZeroDigit
* DigitsAndUnderscores:
* DigitOrUnderscore {DigitOrUnderscore}
* DigitOrUnderscore:
* Digit
* _
* Underscores:
* _ {_}
* }</pre>
* For convenience:
* <pre>{@code
* HexNumeral:
* 0 x HexDigits
* 0 X HexDigits
* HexDigits:
* HexDigit
* HexDigit [HexDigitsAndUnderscores] HexDigit
* HexDigit:
* (one of)
* 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F
* HexDigitsAndUnderscores:
* HexDigitOrUnderscore {HexDigitOrUnderscore}
* HexDigitOrUnderscore:
* HexDigit
* _
* }</pre>
* For convenience:
* <pre>{@code
* OctalNumeral:
* 0 OctalDigits
* 0 Underscores OctalDigits
* OctalDigits:
* OctalDigit
* OctalDigit [OctalDigitsAndUnderscores] OctalDigit
* OctalDigit:
* (one of)
* 0 1 2 3 4 5 6 7
* OctalDigitsAndUnderscores:
* OctalDigitOrUnderscore {OctalDigitOrUnderscore}
* OctalDigitOrUnderscore:
* OctalDigit
* _
* }</pre>
* For convenience:
* <pre>{@code
* BinaryNumeral:
* 0 b BinaryDigits
* 0 B BinaryDigits
* BinaryDigits:
* BinaryDigit
* BinaryDigit [BinaryDigitsAndUnderscores] BinaryDigit
* BinaryDigit:
* (one of)
* 0 1
* BinaryDigitsAndUnderscores:
* BinaryDigitOrUnderscore {BinaryDigitOrUnderscore}
* BinaryDigitOrUnderscore:
* BinaryDigit
* _
* }</pre>
*/
< 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"])? >
|
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.10.2
* <pre>{@code
* FloatingPointLiteral:
* DecimalFloatingPointLiteral
* HexadecimalFloatingPointLiteral
* DecimalFloatingPointLiteral:
* Digits . [Digits] [ExponentPart] [FloatTypeSuffix]
* . Digits [ExponentPart] [FloatTypeSuffix]
* Digits ExponentPart [FloatTypeSuffix]
* Digits [ExponentPart] FloatTypeSuffix
* ExponentPart:
* ExponentIndicator SignedInteger
* ExponentIndicator:
* (one of)
* e E
* SignedInteger:
* [Sign] Digits
* Sign:
* (one of)
* + -
* FloatTypeSuffix:
* (one of)
* f F d D
* }</pre>
* <pre>{@code
* HexadecimalFloatingPointLiteral:
* HexSignificand BinaryExponent [FloatTypeSuffix]
* HexSignificand:
* HexNumeral [.]
* 0 x [HexDigits] . HexDigits
* 0 X [HexDigits] . HexDigits
* BinaryExponent:
* BinaryExponentIndicator SignedInteger
* BinaryExponentIndicator:
* (one of)
* p P
* }</pre>
*/
< 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"])? >
|
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.3
* <pre>{@code
* UnicodeInputCharacter:
* UnicodeEscape
* RawInputCharacter
* UnicodeEscape:
* \ UnicodeMarker HexDigit HexDigit HexDigit HexDigit
* UnicodeMarker:
* u {u}
* HexDigit:
* (one of)
* 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F
* RawInputCharacter:
* any Unicode character
* }</pre>
*/
< #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"] >
|
/**
* TODO: Verify this.
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.10.4
* <pre>{@code
* CharacterLiteral:
* ' SingleCharacter '
* ' EscapeSequence '
* SingleCharacter:
* InputCharacter but not ' or \
* }</pre>
* <pre>{@code
* LineTerminator:
* the ASCII LF character, also known as "newline"
* the ASCII CR character, also known as "return"
* the ASCII CR character followed by the ASCII LF character
* InputCharacter:
* UnicodeInputCharacter but not CR or LF
* }</pre>
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.10.7
* <pre>{@code
* EscapeSequence:
* \ b (backspace BS, Unicode \u0008)
* \ s (space SP, Unicode \u0020)
* \ t (horizontal tab HT, Unicode \u0009)
* \ n (linefeed LF, Unicode \u000a)
* \ f (form feed FF, Unicode \u000c)
* \ r (carriage return CR, Unicode \u000d)
* \ LineTerminator (line continuation, no Unicode representation)
* \ " (double quote ", Unicode \u0022)
* \ ' (single quote ', Unicode \u0027)
* \ \ (backslash \, Unicode \u005c)
* OctalEscape (octal value, Unicode \u0000 to \u00ff)
* OctalEscape:
* \ OctalDigit
* \ OctalDigit OctalDigit
* \ ZeroToThree OctalDigit OctalDigit
* OctalDigit:
* (one of)
* 0 1 2 3 4 5 6 7
* ZeroToThree:
* (one of)
* 0 1 2 3
* }</pre>
*/
< CHARACTER_LITERAL:
"'"
// TODO: Could (and the duplicate code in STRING_LITERAL) this be extracted out?
(
(~["'","\\","\n","\r"])
|
// starts off with unicode backslash
("\\u005" ["c", "C"]
// regular escape sequences
(["n","t","b","r","f","\\","'","\""]
// escapes another unicode backslash
| ("\\u005" ["c", "C"])))
|
( // TODO: Could these escape sequences be extracted out?
"\\"
(
["n","t","b","r","f","\\","'","\""]
|
["0"-"7"] ( ["0"-"7"] )?
|
["0"-"3"] ["0"-"7"] ["0"-"7"]
)
)
|
<UNICODE_ESCAPE>
)
"'"
>
|
/**
* TODO: Verify this.
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.10.5
* <pre>{@code
* StringLiteral:
* " {StringCharacter} "
* StringCharacter:
* InputCharacter but not " or \
* EscapeSequence
* }</pre>
* <pre>{@code
* LineTerminator:
* the ASCII LF character, also known as "newline"
* the ASCII CR character, also known as "return"
* the ASCII CR character followed by the ASCII LF character
* InputCharacter:
* UnicodeInputCharacter but not CR or LF
* }</pre>
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.10.7
* <pre>{@code
* EscapeSequence:
* \ b (backspace BS, Unicode \u0008)
* \ s (space SP, Unicode \u0020)
* \ t (horizontal tab HT, Unicode \u0009)
* \ n (linefeed LF, Unicode \u000a)
* \ f (form feed FF, Unicode \u000c)
* \ r (carriage return CR, Unicode \u000d)
* \ LineTerminator (line continuation, no Unicode representation)
* \ " (double quote ", Unicode \u0022)
* \ ' (single quote ', Unicode \u0027)
* \ \ (backslash \, Unicode \u005c)
* OctalEscape (octal value, Unicode \u0000 to \u00ff)
* OctalEscape:
* \ OctalDigit
* \ OctalDigit OctalDigit
* \ ZeroToThree OctalDigit OctalDigit
* OctalDigit:
* (one of)
* 0 1 2 3 4 5 6 7
* ZeroToThree:
* (one of)
* 0 1 2 3
* }</pre>
*/
< STRING_LITERAL:
"\""
// TODO: Could (and the duplicate code in CHARACTER_LITERAL) this be extracted out?
(
(~["\"","\\","\n","\r"])
|
( // TODO: Could these escape sequences be extracted out?
"\\"
(
["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"]
)
)*
"\""
>
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.10.6
* <pre>{@code
* TextBlock:
* " " " {TextBlockWhiteSpace} LineTerminator {TextBlockCharacter} " " "
* TextBlockWhiteSpace:
* WhiteSpace but not LineTerminator
* TextBlockCharacter:
* InputCharacter but not \
* EscapeSequence
* LineTerminator
* }</pre>
* <pre>{@code
* WhiteSpace:
* the ASCII SP character, also known as "space"
* the ASCII HT character, also known as "horizontal tab"
* the ASCII FF character, also known as "form feed"
* LineTerminator
* LineTerminator:
* the ASCII LF character, also known as "newline"
* the ASCII CR character, also known as "return"
* the ASCII CR character followed by the ASCII LF character
* InputCharacter:
* UnicodeInputCharacter but not CR or LF
* UnicodeInputCharacter:
* UnicodeEscape
* RawInputCharacter
* UnicodeEscape:
* \ UnicodeMarker HexDigit HexDigit HexDigit HexDigit
* RawInputCharacter:
* any Unicode character
* }</pre>
*/
/* TEXT BLOCK LITERAL */
MORE: { <ENTER_TEXT_BLOCK: "\"\"\"" >: IN_TEXT_BLOCK }
<IN_TEXT_BLOCK> TOKEN : { <TEXT_BLOCK_LITERAL: "\"\"\"" >: DEFAULT }
// Need to recognize an escaped " to prevent it from parsing as "backslash doublequote" -
// which might match that doublequote with following doublequotes.
<IN_TEXT_BLOCK> MORE :{ <TEXT_BLOCK_CONTENT: ( "\\" "\"" | ~[] ) > }
/* 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", "\u037f", "\u0386",
"\u0388"-"\u038a", "\u038c", "\u038e"-"\u03a1", "\u03a3"-"\u03f5", "\u03f7"-"\u0481", "\u048a"-"\u052f",
"\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", "\u0860"-"\u086a", "\u08a0"-"\u08b4", "\u08b6"-"\u08bd", "\u0904"-"\u0939",
"\u093d", "\u0950", "\u0958"-"\u0961", "\u0971"-"\u0980", "\u0985"-"\u098c", "\u098f"-"\u0990",
"\u0993"-"\u09a8", "\u09aa"-"\u09b0", "\u09b2", "\u09b6"-"\u09b9", "\u09bd", "\u09ce", "\u09dc"-"\u09dd",
"\u09df"-"\u09e1", "\u09f0"-"\u09f3", "\u09fb"-"\u09fc", "\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", "\u0af9", "\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"-"\u0c39", "\u0c3d", "\u0c58"-"\u0c5a",
"\u0c60"-"\u0c61", "\u0c80", "\u0c85"-"\u0c8c", "\u0c8e"-"\u0c90", "\u0c92"-"\u0ca8", "\u0caa"-"\u0cb3",
"\u0cb5"-"\u0cb9", "\u0cbd", "\u0cde", "\u0ce0"-"\u0ce1", "\u0cf1"-"\u0cf2", "\u0d05"-"\u0d0c",
"\u0d0e"-"\u0d10", "\u0d12"-"\u0d3a", "\u0d3d", "\u0d4e", "\u0d54"-"\u0d56", "\u0d5f"-"\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"-"\u13f5",
"\u13f8"-"\u13fd", "\u1401"-"\u166c", "\u166f"-"\u167f", "\u1681"-"\u169a", "\u16a0"-"\u16ea",
"\u16ee"-"\u16f8", "\u1700"-"\u170c", "\u170e"-"\u1711", "\u1720"-"\u1731", "\u1740"-"\u1751",
"\u1760"-"\u176c", "\u176e"-"\u1770", "\u1780"-"\u17b3", "\u17d7", "\u17db"-"\u17dc", "\u1820"-"\u1877",
"\u1880"-"\u1884", "\u1887"-"\u18a8", "\u18aa", "\u18b0"-"\u18f5", "\u1900"-"\u191e", "\u1950"-"\u196d",
"\u1970"-"\u1974", "\u1980"-"\u19ab", "\u19b0"-"\u19c9", "\u1a00"-"\u1a16", "\u1a20"-"\u1a54",
"\u1aa7", "\u1b05"-"\u1b33", "\u1b45"-"\u1b4b", "\u1b83"-"\u1ba0", "\u1bae"-"\u1baf", "\u1bba"-"\u1be5",
"\u1c00"-"\u1c23", "\u1c4d"-"\u1c4f", "\u1c5a"-"\u1c7d", "\u1c80"-"\u1c88", "\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"-"\u20bf", "\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"-"\u312e", "\u3131"-"\u318e",
"\u31a0"-"\u31ba", "\u31f0"-"\u31ff", "\u3400"-"\u4db5", "\u4e00"-"\u9fea", "\ua000"-"\ua48c",
"\ua4d0"-"\ua4fd", "\ua500"-"\ua60c", "\ua610"-"\ua61f", "\ua62a"-"\ua62b", "\ua640"-"\ua66e",
"\ua67f"-"\ua69d", "\ua6a0"-"\ua6ef", "\ua717"-"\ua71f", "\ua722"-"\ua788", "\ua78b"-"\ua7ae",
"\ua7b0"-"\ua7b7", "\ua7f7"-"\ua801", "\ua803"-"\ua805", "\ua807"-"\ua80a", "\ua80c"-"\ua822",
"\ua838", "\ua840"-"\ua873", "\ua882"-"\ua8b3", "\ua8f2"-"\ua8f7", "\ua8fb", "\ua8fd", "\ua90a"-"\ua925",
"\ua930"-"\ua946", "\ua960"-"\ua97c", "\ua984"-"\ua9b2", "\ua9cf", "\ua9e0"-"\ua9e4", "\ua9e6"-"\ua9ef",
"\ua9fa"-"\ua9fe", "\uaa00"-"\uaa28", "\uaa40"-"\uaa42", "\uaa44"-"\uaa4b", "\uaa60"-"\uaa76",
"\uaa7a", "\uaa7e"-"\uaaaf", "\uaab1", "\uaab5"-"\uaab6", "\uaab9"-"\uaabd", "\uaac0", "\uaac2",
"\uaadb"-"\uaadd", "\uaae0"-"\uaaea", "\uaaf2"-"\uaaf4", "\uab01"-"\uab06", "\uab09"-"\uab0e",
"\uab11"-"\uab16", "\uab20"-"\uab26", "\uab28"-"\uab2e", "\uab30"-"\uab5a", "\uab5c"-"\uab65",
"\uab70"-"\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", "\u037f", "\u0386",
"\u0388"-"\u038a", "\u038c", "\u038e"-"\u03a1", "\u03a3"-"\u03f5", "\u03f7"-"\u0481", "\u0483"-"\u0487",
"\u048a"-"\u052f", "\u0531"-"\u0556", "\u0559", "\u0561"-"\u0587", "\u058f", "\u0591"-"\u05bd",
"\u05bf", "\u05c1"-"\u05c2", "\u05c4"-"\u05c5", "\u05c7", "\u05d0"-"\u05ea", "\u05f0"-"\u05f2",
"\u0600"-"\u0605", "\u060b", "\u0610"-"\u061a", "\u061c", "\u0620"-"\u0669", "\u066e"-"\u06d3",
"\u06d5"-"\u06dd", "\u06df"-"\u06e8", "\u06ea"-"\u06fc", "\u06ff", "\u070f"-"\u074a", "\u074d"-"\u07b1",
"\u07c0"-"\u07f5", "\u07fa", "\u0800"-"\u082d", "\u0840"-"\u085b", "\u0860"-"\u086a", "\u08a0"-"\u08b4",
"\u08b6"-"\u08bd", "\u08d4"-"\u0963", "\u0966"-"\u096f", "\u0971"-"\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"-"\u09fc", "\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", "\u0af9"-"\u0aff", "\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", "\u0c00"-"\u0c03", "\u0c05"-"\u0c0c", "\u0c0e"-"\u0c10",
"\u0c12"-"\u0c28", "\u0c2a"-"\u0c39", "\u0c3d"-"\u0c44", "\u0c46"-"\u0c48", "\u0c4a"-"\u0c4d",
"\u0c55"-"\u0c56", "\u0c58"-"\u0c5a", "\u0c60"-"\u0c63", "\u0c66"-"\u0c6f", "\u0c80"-"\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", "\u0d00"-"\u0d03", "\u0d05"-"\u0d0c", "\u0d0e"-"\u0d10",
"\u0d12"-"\u0d44", "\u0d46"-"\u0d48", "\u0d4a"-"\u0d4e", "\u0d54"-"\u0d57", "\u0d5f"-"\u0d63",
"\u0d66"-"\u0d6f", "\u0d7a"-"\u0d7f", "\u0d82"-"\u0d83", "\u0d85"-"\u0d96", "\u0d9a"-"\u0db1",
"\u0db3"-"\u0dbb", "\u0dbd", "\u0dc0"-"\u0dc6", "\u0dca", "\u0dcf"-"\u0dd4", "\u0dd6", "\u0dd8"-"\u0ddf",
"\u0de6"-"\u0def", "\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"-"\u13f5",
"\u13f8"-"\u13fd", "\u1401"-"\u166c", "\u166f"-"\u167f", "\u1681"-"\u169a", "\u16a0"-"\u16ea",
"\u16ee"-"\u16f8", "\u1700"-"\u170c", "\u170e"-"\u1714", "\u1720"-"\u1734", "\u1740"-"\u1753",
"\u1760"-"\u176c", "\u176e"-"\u1770", "\u1772"-"\u1773", "\u1780"-"\u17d3", "\u17d7", "\u17db"-"\u17dd",
"\u17e0"-"\u17e9", "\u180b"-"\u180e", "\u1810"-"\u1819", "\u1820"-"\u1877", "\u1880"-"\u18aa",
"\u18b0"-"\u18f5", "\u1900"-"\u191e", "\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", "\u1ab0"-"\u1abd",
"\u1b00"-"\u1b4b", "\u1b50"-"\u1b59", "\u1b6b"-"\u1b73", "\u1b80"-"\u1bf3", "\u1c00"-"\u1c37",
"\u1c40"-"\u1c49", "\u1c4d"-"\u1c7d", "\u1c80"-"\u1c88", "\u1cd0"-"\u1cd2", "\u1cd4"-"\u1cf9",
"\u1d00"-"\u1df9", "\u1dfb"-"\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", "\u2066"-"\u206f", "\u2071", "\u207f", "\u2090"-"\u209c", "\u20a0"-"\u20bf",
"\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"-"\u312e", "\u3131"-"\u318e",
"\u31a0"-"\u31ba", "\u31f0"-"\u31ff", "\u3400"-"\u4db5", "\u4e00"-"\u9fea", "\ua000"-"\ua48c",
"\ua4d0"-"\ua4fd", "\ua500"-"\ua60c", "\ua610"-"\ua62b", "\ua640"-"\ua66f", "\ua674"-"\ua67d",
"\ua67f"-"\ua6f1", "\ua717"-"\ua71f", "\ua722"-"\ua788", "\ua78b"-"\ua7ae", "\ua7b0"-"\ua7b7",
"\ua7f7"-"\ua827", "\ua838", "\ua840"-"\ua873", "\ua880"-"\ua8c5", "\ua8d0"-"\ua8d9", "\ua8e0"-"\ua8f7",
"\ua8fb", "\ua8fd", "\ua900"-"\ua92d", "\ua930"-"\ua953", "\ua960"-"\ua97c", "\ua980"-"\ua9c0",
"\ua9cf"-"\ua9d9", "\ua9e0"-"\ua9fe", "\uaa00"-"\uaa36", "\uaa40"-"\uaa4d", "\uaa50"-"\uaa59",
"\uaa60"-"\uaa76", "\uaa7a"-"\uaac2", "\uaadb"-"\uaadd", "\uaae0"-"\uaaef", "\uaaf2"-"\uaaf6",
"\uab01"-"\uab06", "\uab09"-"\uab0e", "\uab11"-"\uab16", "\uab20"-"\uab26", "\uab28"-"\uab2e",
"\uab30"-"\uab5a", "\uab5c"-"\uab65", "\uab70"-"\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"-"\ufe2f",
"\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 */
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.11
* Twelve tokens, formed from ASCII characters, are the separators (punctuators).
* <pre>{@code
* Separator:
* (one of)
* ( ) { } [ ] ; , . ... @ ::
* }</pre
*/
TOKEN :
{
< LPAREN: "(" >
| < RPAREN: ")" >
| < LBRACE: "{" >
| < RBRACE: "}" >
| < LBRACKET: "[" >
| < RBRACKET: "]" >
| < SEMICOLON: ";" >
| < COMMA: "," >
| < DOT: "." >
| < ELLIPSIS: "..." >
| < AT: "@" >
| < DOUBLECOLON: "::" >
}
/* OPERATORS */
/**
* Note that {@code >}'s need special attention due to generics syntax, thus are listed separately.
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.12
* 38 tokens, formed from ASCII characters, are the operators.
* <pre>{@code
* Separator:
* (one of)
* = > < ! ~ ? : ->
* == >= <= != && || ++ --
* + - * / & | ^ % << >> >>>
* += -= *= /= &= |= ^= %= <<= >>= >>>=
* }</pre
*/
TOKEN :
{
< ASSIGN: "=" >
// GT - see below
| < LT: "<" >
| < BANG: "!" >
| < TILDE: "~" >
| < HOOK: "?" >
| < COLON: ":" >
| < ARROW: "->" >
| < EQ: "==" >
| < GE: ">=" >
| < LE: "<=" >
| < NE: "!=" >
| < SC_AND: "&&" >
| < SC_OR: "||" >
| < INCR: "++" >
| < DECR: "--" >
| < PLUS: "+" >
| < MINUS: "-" >
| < STAR: "*" >
| < SLASH: "/" >
| < BIT_AND: "&" >
| < BIT_OR: "|" >
| < XOR: "^" >
| < REM: "%" >
| < LSHIFT: "<<" >
// RSIGNEDSHIFT - see below
// RUNSIGNEDSHIFT - see below
| < PLUSASSIGN: "+=" >
| < MINUSASSIGN: "-=" >
| < STARASSIGN: "*=" >
| < SLASHASSIGN: "/=" >
| < ANDASSIGN: "&=" >
| < ORASSIGN: "|=" >
| < XORASSIGN: "^=" >
| < REMASSIGN: "%=" >
| < LSHIFTASSIGN: "<<=" >
| < RSIGNEDSHIFTASSIGN: ">>=" >
| < RUNSIGNEDSHIFTASSIGN: ">>>=" >
}
/*
* Note that {@code >}'s need special attention due to generics syntax, thus are listed separately.
* TODO: Investigate (and comment) if the ordering matters, or if it's just that there's a code block associated with the token.
.*/
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 *
* *
* https://javacc.github.io/javacc/documentation/grammar.html#bnf-production *
* <pre>{@code *
* bnf_production ::= java_access_modifier java_return_type java_identifier "(" java_parameter_list ")" ":" *
* java_block *
* "{" expansion_choices "}" *
* }</pre> *
*************************************************************************************************************/
/*
* Program structuring syntax follows.
*/
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-7.html#jls-7.3
* <pre>{@code
* CompilationUnit:
* OrdinaryCompilationUnit
* ModularCompilationUnit
* OrdinaryCompilationUnit:
* [PackageDeclaration] {ImportDeclaration} {TypeDeclaration}
* ModularCompilationUnit:
* {ImportDeclaration} ModuleDeclaration
* }</pre>
* Note that {@code TypeDeclaration} is defined in the JLS as a class or interface.
* <ul>
* <li>A class is defined as a normal class or enum declaration.</li>
* <li>An interface declaration is defined as a normal interface or annotation declaration.</li>
* </ul>
* For that reason, within this grammar, we combine them.
*
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-7.html#jls-TypeDeclaration
* <pre>{@code
* TypeDeclaration:
* ClassDeclaration
* InterfaceDeclaration
* ;
* }</pre>
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-ClassDeclaration
* <pre>{@code
* TypeDeclaration:
* ClassDeclaration
* InterfaceDeclaration
* ;
* }</pre>
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-9.html#jls-InterfaceDeclaration
* <pre>{@code
* InterfaceDeclaration:
* NormalInterfaceDeclaration
* AnnotationTypeDeclaration
* }</pre>
*/
public CompilationUnit CompilationUnit():
{
PackageDeclaration packageDeclaration = null;
NodeList<ImportDeclaration> imports = emptyNodeList();
ImportDeclaration in = null;
NodeList<TypeDeclaration<?>> types = emptyNodeList();
ModifierHolder modifier;
TypeDeclaration<?> typeDeclaration = null;
ModuleDeclaration module = null;
}
{
try {
( LOOKAHEAD(2)";" )*
[ LOOKAHEAD(PackageDeclaration()) packageDeclaration = PackageDeclaration() ]
(
in = ImportDeclaration() { imports = add(imports, in); }
|
(
modifier = Modifiers()
(
typeDeclaration = ClassOrInterfaceDeclaration(modifier) { types = add(types, typeDeclaration); }
|
typeDeclaration = RecordDeclaration(modifier) { types = add(types, typeDeclaration); }
|
typeDeclaration = EnumDeclaration(modifier) { types = add(types, typeDeclaration); }
|
typeDeclaration = AnnotationTypeDeclaration(modifier) { types = add(types, typeDeclaration); }
|
module = ModuleDeclaration(modifier)
|
";"
)
)
)*
(<EOF> | <CTRL_Z>)
{ return new CompilationUnit(range(token_source.getHomeToken(), token()), packageDeclaration, 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;
}
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-7.html#jls-7.4.1
* <pre>{@code
* PackageDeclaration:
* {PackageModifier} package Identifier {. Identifier} ;
* PackageModifier:
* Annotation
* }</pre>
*/
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); }
}
/**
* Import declaration types are not differentiated in the class hierarchy.
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-7.html#jls-7.5
* <pre>{@code
* ImportDeclaration:
* SingleTypeImportDeclaration
* TypeImportOnDemandDeclaration
* SingleStaticImportDeclaration
* StaticImportOnDemandDeclaration
* }</pre>
* Note that the JLS terminology "On Demand" and JavaParser terminology "Asterisk" are equivalent
* <pre>{@code
* SingleTypeImportDeclaration:
* import TypeName ;
* TypeImportOnDemandDeclaration:
* import PackageOrTypeName . * ;
* SingleStaticImportDeclaration:
* import static TypeName . Identifier ;
* StaticImportOnDemandDeclaration:
* import static TypeName . * ;
* }</pre>
*/
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.
* Class Modifiers: https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.1.1
* <pre>{@code
* ClassModifier:
* (one of)
* Annotation public protected private
* abstract static final strictfp
* }</pre>
* Field Modifiers: https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.3.1
* <pre>{@code
* FieldModifier:
* (one of)
* Annotation public protected private
* static final transient volatile
* }</pre>
* Method Modifiers: https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.4.3
* <pre>{@code
* MethodModifier:
* (one of)
* Annotation public protected private
* abstract static final synchronized native strictfp
* }</pre>
* Constructor Modifiers: https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.8.3
* <pre>{@code
* ConstructorModifier:
* (one of)
* Annotation public protected private
* }</pre>
*/
ModifierHolder Modifiers():
{
JavaToken begin = INVALID;
NodeList<Modifier> modifiers = new NodeList<Modifier>();
NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
AnnotationExpr ann;
}
{
(
LOOKAHEAD(2)
(
"public" { add(modifiers, new Modifier(tokenRange(), Modifier.Keyword.PUBLIC)); begin = orIfInvalid(begin, token()); }
|
"static" { add(modifiers, new Modifier(tokenRange(), Modifier.Keyword.STATIC)); begin = orIfInvalid(begin, token()); }
|
"protected" { add(modifiers, new Modifier(tokenRange(), Modifier.Keyword.PROTECTED)); begin = orIfInvalid(begin, token()); }
|
"private" { add(modifiers, new Modifier(tokenRange(), Modifier.Keyword.PRIVATE)); begin = orIfInvalid(begin, token()); }
|
"final" { add(modifiers, new Modifier(tokenRange(), Modifier.Keyword.FINAL)); begin = orIfInvalid(begin, token()); }
|
"abstract" { add(modifiers, new Modifier(tokenRange(), Modifier.Keyword.ABSTRACT)); begin = orIfInvalid(begin, token()); }
|
"synchronized" { add(modifiers, new Modifier(tokenRange(), Modifier.Keyword.SYNCHRONIZED)); begin = orIfInvalid(begin, token()); }
|
"native" { add(modifiers, new Modifier(tokenRange(), Modifier.Keyword.NATIVE)); begin = orIfInvalid(begin, token()); }
|
"transient" { add(modifiers, new Modifier(tokenRange(), Modifier.Keyword.TRANSIENT)); begin = orIfInvalid(begin, token()); }
|
"volatile" { add(modifiers, new Modifier(tokenRange(), Modifier.Keyword.VOLATILE)); begin = orIfInvalid(begin, token()); }
|
"strictfp" { add(modifiers, new Modifier(tokenRange(), Modifier.Keyword.STRICTFP)); begin = orIfInvalid(begin, token()); }
|
"transitive" { add(modifiers, new Modifier(tokenRange(), Modifier.Keyword.TRANSITIVE)); begin = orIfInvalid(begin, token()); }
|
"default" { add(modifiers, new Modifier(tokenRange(), Modifier.Keyword.DEFAULT)); begin = orIfInvalid(begin, token()); }
|
ann = Annotation() { annotations = add(annotations, ann); begin = orIfInvalid(begin, ann); }
)
)*
{
return new ModifierHolder(begin, modifiers, annotations);
}
}
/*
* Declaration syntax follows.
*/
/**
* <strong>
* Note that this grammar is deliberately permissive. As a result, this grammar allows any combinations of
* class/interface and extends/implements (e.g. an interface implementing an interface).
* </strong>
* Validations of these combinations are handled at the same time as validating language features used.
* Also note that JavaParser handles the hierarchy/specialisations of classes, interfaces, and enums differently to the JLS.
* <ul>
* <li>This {@code ClassOrInterfaceDeclaration} refers to the {@code NormalClassDeclaration} and {@code NormalInterfaceDeclaration},</li>
* <li>while {@code AnnotationTypeDeclaration} and {@code EnumDeclaration} are handled separately within this grammar.</li>
* </ul>
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.1
* <pre>{@code
* ClassDeclaration:
* NormalClassDeclaration
* EnumDeclaration
* NormalClassDeclaration:
* {ClassModifier} class TypeIdentifier [TypeParameters] [Superclass] [Superinterfaces] ClassBody
* }</pre>
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-9.html#jls-9.1
* <pre>{@code
* InterfaceDeclaration:
* NormalInterfaceDeclaration
* AnnotationTypeDeclaration
* NormalInterfaceDeclaration:
* {InterfaceModifier} interface TypeIdentifier [TypeParameters] [ExtendsInterfaces] InterfaceBody
* }</pre>
*/
ClassOrInterfaceDeclaration ClassOrInterfaceDeclaration(ModifierHolder modifier):
{
boolean isInterface;
SimpleName name;
RangedList<TypeParameter> typePar = new RangedList<TypeParameter>(emptyNodeList());
NodeList<ClassOrInterfaceType> extList = emptyNodeList();
NodeList<ClassOrInterfaceType> impList = emptyNodeList();
NodeList<BodyDeclaration<?>> members = emptyNodeList();
JavaToken begin = modifier.begin;
}
{
(
"class" { isInterface = false; }
|
"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); }
}
/**
* https://openjdk.java.net/jeps/395#Java-grammar
* <pre>{@code
* RecordDeclaration:
* {ClassModifier} `record` TypeIdentifier [TypeParameters]
* RecordHeader [SuperInterfaces] RecordBody
*
* RecordHeader:
* `(` [RecordComponentList] `)`
*
* RecordComponentList:
* RecordComponent { `,` RecordComponent}
*
* RecordComponent:
* {Annotation} UnannType Identifier
* VariableArityRecordComponent
*
* VariableArityRecordComponent:
* {Annotation} UnannType {Annotation} `...` Identifier
*
* RecordBody:
* `{` {RecordBodyDeclaration} `}`
*
* RecordBodyDeclaration:
* ClassBodyDeclaration
* CompactConstructorDeclaration
*
* CompactConstructorDeclaration:
* {ConstructorModifier} SimpleTypeName ConstructorBody
* }</pre>
*/
RecordDeclaration RecordDeclaration(ModifierHolder modifier):
{
SimpleName name;
Pair<NodeList<Parameter>, ReceiverParameter> parameters;
RangedList<TypeParameter> typePar = new RangedList<TypeParameter>(emptyNodeList());
NodeList<ClassOrInterfaceType> impList = emptyNodeList();
NodeList<BodyDeclaration<?>> members = emptyNodeList();
JavaToken begin = modifier.begin;
}
{
// Note that BlockStatement and ClassOrInterfaceBodyDeclaration have extended lookaheads that should be maintained
// Note that `record` is a "restricted identifier", not a keyword - JLS 3.9 has more detail.
"record" { begin = orIfInvalid(begin, token()); }
name = SimpleName()
[ typePar = TypeParameters() ]
parameters = Parameters()
[ impList = ImplementsList() ]
members = RecordBody()
{ return new RecordDeclaration(range(begin, token()), modifier.modifiers, modifier.annotations, name, parameters.a, typePar.list, impList, members, parameters.b); }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.1.4
* <pre>{@code
* Superclass:
* extends ClassType
* }</pre>
* For convenience:
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-4.html#jls-4.3
* <pre>{@code
* ClassOrInterfaceType:
* ClassType
* InterfaceType
* ClassType:
* {Annotation} TypeIdentifier [TypeArguments]
* PackageName . {Annotation} TypeIdentifier [TypeArguments]
* ClassOrInterfaceType . {Annotation} TypeIdentifier [TypeArguments]
* InterfaceType:
* ClassType
* }</pre>
*/
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; }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.1.5
* <pre>{@code
* Superinterfaces:
* implements InterfaceTypeList
* InterfaceTypeList:
* InterfaceType {, InterfaceType}
* }</pre>
* For convenience:
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-4.html#jls-4.3
* <pre>{@code
* ClassOrInterfaceType:
* ClassType
* InterfaceType
* ClassType:
* {Annotation} TypeIdentifier [TypeArguments]
* PackageName . {Annotation} TypeIdentifier [TypeArguments]
* ClassOrInterfaceType . {Annotation} TypeIdentifier [TypeArguments]
* InterfaceType:
* ClassType
* }</pre>
*/
NodeList<ClassOrInterfaceType> ImplementsList():
{
NodeList<ClassOrInterfaceType> ret = new NodeList<ClassOrInterfaceType>();
ClassOrInterfaceType cit;
}
{
"implements" cit = AnnotatedClassOrInterfaceType() { ret.add(cit); }
( "," cit = AnnotatedClassOrInterfaceType() { ret.add(cit); } )*
{ return ret; }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.9
* <pre>{@code
* EnumDeclaration:
* {ClassModifier} enum TypeIdentifier [Superinterfaces] EnumBody
* }</pre>
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.9.1
* <pre>{@code
* EnumBody:
* { [EnumConstantList] [,] [EnumBodyDeclarations] }
* EnumConstantList:
* EnumConstant {, EnumConstant}
* EnumConstant:
* {EnumConstantModifier} Identifier [( [ArgumentList] )] [ClassBody]
* EnumConstantModifier:
* Annotation
* }</pre>
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.9.2
* <pre>{@code
* EnumBodyDeclarations:
* ; {ClassBodyDeclaration}
* }</pre>
*/
EnumDeclaration EnumDeclaration(ModifierHolder modifier):
{
SimpleName name;
NodeList<ClassOrInterfaceType> impList = emptyNodeList();
EnumConstantDeclaration entry;
NodeList<EnumConstantDeclaration> entries = emptyNodeList();
BodyDeclaration<?> member;
NodeList<BodyDeclaration<?>> members = emptyNodeList();
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); }
}
/**
* Note that the {@code EnumConstantModifier} is defined as an {@code Annotation}.
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.9.1
* <pre>{@code
* EnumConstant:
* {EnumConstantModifier} Identifier [( [ArgumentList] )] [ClassBody]
* EnumConstantModifier:
* Annotation
* }</pre>
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.9.2
* <pre>{@code
* EnumBodyDeclarations:
* ; {ClassBodyDeclaration}
* }</pre>
*/
EnumConstantDeclaration EnumConstantDeclaration():
{
NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
AnnotationExpr ann;
SimpleName name;
NodeList<Expression> args = emptyNodeList();
NodeList<BodyDeclaration<?>> classBody = emptyNodeList();
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>.
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.1.2
* <pre>{@code
* TypeParameters:
* < TypeParameterList >
* TypeParameterList:
* TypeParameter {, TypeParameter}
* }</pre>
* For Convenience:
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-4.html#jls-4.4
* <pre>{@code
* TypeParameter:
* {TypeParameterModifier} TypeIdentifier [TypeBound]
* TypeParameterModifier:
* Annotation
* TypeBound:
* extends TypeVariable
* extends ClassOrInterfaceType {AdditionalBound}
* AdditionalBound:
* & InterfaceType
* }</pre>
*/
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; }
}
/**
* Note that the {@code TypeParameterModifier} is defined as an {@code Annotation}.
* Note that the annotations are passed as a parameter to this grammar entry.
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-4.html#jls-4.4
* <pre>{@code
* TypeParameter:
* {TypeParameterModifier} TypeIdentifier [TypeBound]
* TypeParameterModifier:
* Annotation
* TypeBound:
* extends TypeVariable
* extends ClassOrInterfaceType {AdditionalBound}
* AdditionalBound:
* & InterfaceType
* }</pre>
*/
TypeParameter TypeParameter(NodeList<AnnotationExpr> annotations):
{
SimpleName name;
NodeList<ClassOrInterfaceType> typeBound = emptyNodeList();
JavaToken begin;
}
{
// Annotations are passed as a parameter to this grammar entry.
name = SimpleName() { begin=token(); }
[ typeBound = TypeBound() ]
{ return new TypeParameter(range(begin, token()), name, typeBound, annotations); }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-4.html#jls-4.4
* <pre>{@code
* TypeBound:
* extends TypeVariable
* extends ClassOrInterfaceType {AdditionalBound}
* AdditionalBound:
* & InterfaceType
* }</pre>
* For Convenience:
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-4.html#jls-4.3
* <pre>{@code
* ClassOrInterfaceType:
* ClassType
* InterfaceType
* ClassType:
* {Annotation} TypeIdentifier [TypeArguments]
* PackageName . {Annotation} TypeIdentifier [TypeArguments]
* ClassOrInterfaceType . {Annotation} TypeIdentifier [TypeArguments]
* InterfaceType:
* ClassType
* TypeVariable:
* {Annotation} TypeIdentifier
* }</pre>
*/
NodeList<ClassOrInterfaceType> TypeBound():
{
NodeList<ClassOrInterfaceType> ret = emptyNodeList();
ClassOrInterfaceType cit;
}
{
"extends" cit = AnnotatedClassOrInterfaceType() { ret.add(cit); }
(
"&"
cit = AnnotatedClassOrInterfaceType() { ret.add(cit); }
)*
{ return ret; }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.1.6
* <pre>{@code
* ClassBody:
* { {ClassBodyDeclaration} }
* ClassBodyDeclaration:
* ClassMemberDeclaration
* InstanceInitializer
* StaticInitializer
* ConstructorDeclaration
* ClassMemberDeclaration:
* FieldDeclaration
* MethodDeclaration
* ClassDeclaration
* InterfaceDeclaration
* ;
* }</pre>
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-9.html#jls-9.1.4
* <pre>{@code
* InterfaceBody:
* { {InterfaceMemberDeclaration} }
* InterfaceMemberDeclaration:
* ConstantDeclaration
* InterfaceMethodDeclaration
* ClassDeclaration
* InterfaceDeclaration
* ;
* }</pre>
*/
NodeList<BodyDeclaration<?>> ClassOrInterfaceBody():
{
NodeList<BodyDeclaration<?>> ret = emptyNodeList();
BodyDeclaration member;
}
{
"{"
(
member = ClassOrInterfaceBodyDeclaration() { ret.add(member); }
|
";"
)*
"}"
{ return ret; }
}
/**
* Everything that can go into a "regular" class or interface declaration,
* can also (usually) be included within a record.
* Exceptions to this are handled within the validators.
*
* Note: This is HEAVILY based on ClassOrInterfaceBody() and ClassOrInterfaceBodyDeclaration(),
* and there may be some scope/potential to optimise this and merge some parts together.
*
* https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-8.10.2
*/
NodeList<BodyDeclaration<?>> RecordBody():
{
NodeList<BodyDeclaration<?>> ret = emptyNodeList();
BodyDeclaration member;
}
{
"{"
(
member = RecordBodyDeclaration() { ret.add(member); }
|
";"
)*
"}"
{ return ret; }
}
/**
* Almost identical to ClassOrInterfaceBodyDeclaration, but:
* - with a CompactConstructorDeclaration
* As a result, there may be some scope/potential to optimize this and merge some parts together.
*
* https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-8.10.2
* <pre>{@code
* RecordBody:
* { {RecordBodyDeclaration} }
* RecordBodyDeclaration:
* ClassBodyDeclaration
* CompactConstructorDeclaration
* }</pre>
*
* For convenience:
* https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-8.10.2
* <pre>{@code
* ClassBodyDeclaration:
* ClassMemberDeclaration
* InstanceInitializer
* StaticInitializer
* ConstructorDeclaration
* ClassMemberDeclaration:
* FieldDeclaration
* MethodDeclaration
* ClassDeclaration
* InterfaceDeclaration
* ;
* }</pre>
*/
BodyDeclaration<?> RecordBodyDeclaration():
{
ModifierHolder modifiers;
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
modifiers = Modifiers()
(
ret = ClassOrInterfaceDeclaration(modifiers)
|
LOOKAHEAD("enum")
ret = EnumDeclaration(modifiers)
|
LOOKAHEAD("@" "interface")
ret = AnnotationTypeDeclaration(modifiers)
|
// Compact Record Constructors
LOOKAHEAD( [ TypeParameters() ] Identifier() "{" )
ret = CompactConstructorDeclaration(modifiers)
|
// "Normal" Record Constructors
LOOKAHEAD( [ TypeParameters() ] Identifier() "(" )
ret = ConstructorDeclaration(modifiers)
|
LOOKAHEAD( Type() Identifier() ( ArrayBracketPair() )* ( "," | "=" | ";" ) )
ret = FieldDeclaration(modifiers)
|
ret = MethodDeclaration(modifiers)
)
)
{ return ret; }
}
/**
* https://openjdk.java.net/jeps/359#Grammar
* <pre>{@code
* CompactConstructorDeclaration:
* {Annotation} {ConstructorModifier} [TypeParameters] SimpleTypeName
* [Throws] ConstructorBody
* }</pre>
*/
CompactConstructorDeclaration CompactConstructorDeclaration(ModifierHolder modifier):
{
RangedList<TypeParameter> typeParameters = new RangedList<TypeParameter>(emptyNodeList());
SimpleName name;
Pair<NodeList<Parameter>, ReceiverParameter> parameters = new Pair<NodeList<Parameter>, ReceiverParameter>(emptyNodeList(), null);
NodeList<ReferenceType> throws_ = emptyNodeList();
ExplicitConstructorInvocationStmt exConsInv = null;
NodeList<Statement> stmts = emptyNodeList();
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 CompactConstructorDeclaration(range(begin, token()), modifier.modifiers, modifier.annotations, typeParameters.list, name, throws_, new BlockStmt(range(blockBegin, token()), stmts));
}
}
/**
* Note that {@code ClassDeclaration} and {@code InterfaceDeclaration} (in the JLS) include enum and annotation declarations.
* Note that {@code InstanceInitializer} and {@code StaticInitializer} are treated as an {@code Initializer} with an
* optional {@code static} modifier in JavaParser.
* TODO: Investigate the {@code ClassBodyDeclaration} parts existing within an interface - is permitting this a potential problem?
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.1.6
* <pre>{@code
* ClassBody:
* { {ClassBodyDeclaration} }
* ClassBodyDeclaration:
* ClassMemberDeclaration
* InstanceInitializer
* StaticInitializer
* ConstructorDeclaration
* ClassMemberDeclaration:
* FieldDeclaration
* MethodDeclaration
* ClassDeclaration
* InterfaceDeclaration
* ;
* }</pre>
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-9.html#jls-9.1.4
* <pre>{@code
* InterfaceBody:
* { {InterfaceMemberDeclaration} }
* InterfaceMemberDeclaration:
* ConstantDeclaration
* InterfaceMethodDeclaration
* ClassDeclaration
* InterfaceDeclaration
* ;
* }</pre>
*/
BodyDeclaration<?> ClassOrInterfaceBodyDeclaration():
{
ModifierHolder modifiers;
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
modifiers = Modifiers()
(
ret = ClassOrInterfaceDeclaration(modifiers)
|
LOOKAHEAD("record" SimpleName() [ TypeParameters() ] Parameters() )
ret = RecordDeclaration(modifiers)
|
LOOKAHEAD("enum")
ret = EnumDeclaration(modifiers)
|
LOOKAHEAD("@" "interface")
ret = AnnotationTypeDeclaration(modifiers)
|
LOOKAHEAD( [ TypeParameters() ] Identifier() "(" )
ret = ConstructorDeclaration(modifiers)
|
LOOKAHEAD( Type() Identifier() ( ArrayBracketPair() )* ( "," | "=" | ";" ) )
ret = FieldDeclaration(modifiers)
|
ret = MethodDeclaration(modifiers)
)
)
{ return ret; }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.3
* <pre>{@code
* FieldDeclaration:
* {FieldModifier} UnannType VariableDeclaratorList ;
* VariableDeclaratorList:
* VariableDeclarator {, VariableDeclarator}
* VariableDeclarator:
* VariableDeclaratorId [= VariableInitializer]
* VariableDeclaratorId:
* Identifier [Dims]
* VariableInitializer:
* Expression
* ArrayInitializer
* }</pre>
*/
FieldDeclaration FieldDeclaration(ModifierHolder modifier):
{
Type partialType;
NodeList<VariableDeclarator> variables = new NodeList<VariableDeclarator>();
VariableDeclarator val;
}
{
// Modifiers are already matched in the caller
partialType = Type(emptyNodeList())
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);
}
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.3
* <pre>{@code
* VariableDeclarator:
* VariableDeclaratorId [= VariableInitializer]
* VariableDeclaratorId:
* Identifier [Dims]
* VariableInitializer:
* Expression
* ArrayInitializer
* }</pre>
*/
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); }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.3
* <pre>{@code
* VariableDeclaratorId:
* Identifier [Dims]
* }</pre>
* For convenience:
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-Identifier
* <pre>{@code
* Identifier:
* IdentifierChars but not a Keyword or BooleanLiteral or NullLiteral
* IdentifierChars:
* JavaLetter {JavaLetterOrDigit}
* JavaLetter:
* any Unicode character that is a "Java letter"
* JavaLetterOrDigit:
* any Unicode character that is a "Java letter-or-digit"
* }</pre>
* For convenience:
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-4.html#jls-Dims
* <pre>{@code
* Dims:
* {Annotation} [ ] {{Annotation} [ ]}
* }</pre>
*/
Pair<SimpleName, List<ArrayBracketPair>> VariableDeclaratorId():
{
SimpleName name;
JavaToken begin;
ArrayBracketPair arrayBracketPair;
List<ArrayBracketPair> arrayBracketPairs = new ArrayList<ArrayBracketPair>(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);
}
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.3
* <pre>{@code
* VariableInitializer:
* Expression
* ArrayInitializer
* }</pre>
*/
Expression VariableInitializer():
{
Expression ret;
}
{
(
ret = ArrayInitializer()
|
ret = Expression()
)
{ return ret; }
}
/**
* An array initializer is written as a comma-separated list of expressions, enclosed by braces { and }.
* A trailing comma may appear after the last expression in an array initializer and is ignored.
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-10.html#jls-10.6
* <pre>{@code
* ArrayInitializer:
* { [VariableInitializerList] [,] }
* VariableInitializerList:
* VariableInitializer {, VariableInitializer}
* }</pre>
* <pre>{@code
* VariableInitializer:
* Expression
* ArrayInitializer
* }</pre>
*/
ArrayInitializerExpr ArrayInitializer():
{
NodeList<Expression> values = emptyNodeList();
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);
}
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.4
* <pre>{@code
* MethodDeclaration:
* {MethodModifier} MethodHeader MethodBody
* MethodHeader:
* Result MethodDeclarator [Throws]
* TypeParameters {Annotation} Result MethodDeclarator [Throws]
* MethodDeclarator:
* Identifier ( [ReceiverParameter ,] [FormalParameterList] ) [Dims]
* ReceiverParameter:
* {Annotation} UnannType [Identifier .] this
* }</pre>
*/
MethodDeclaration MethodDeclaration(ModifierHolder modifier):
{
RangedList<TypeParameter> typeParameters = new RangedList<TypeParameter>(emptyNodeList());
Type type;
SimpleName name;
Pair<NodeList<Parameter>, ReceiverParameter> parameters = new Pair<NodeList<Parameter>, ReceiverParameter>(emptyNodeList(), null);
ArrayBracketPair arrayBracketPair;
List<ArrayBracketPair> arrayBracketPairs = new ArrayList<ArrayBracketPair>(0);
NodeList<ReferenceType> throws_ = emptyNodeList();
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(emptyNodeList()) { 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);
}
}
// TODO: JLS Has type and unannotated type, while JavaParser has type and annotated type.
ReferenceType AnnotatedReferenceType():
{
NodeList<AnnotationExpr> annotations;
ReferenceType type;
}
{
annotations = Annotations()
type = ReferenceType(annotations)
{ return type; }
}
// TODO: JLS Has type and unannotated type, while JavaParser has type and annotated type.
Type AnnotatedType():
{
NodeList<AnnotationExpr> annotations;
Type type;
}
{
annotations = Annotations()
type = Type(annotations)
{ return type; }
}
/**
* The JLS refers to parameters as {@code FormalParameter}.
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.4.1
* <pre>{@code
* FormalParameterList:
* FormalParameter {, FormalParameter}
* FormalParameter:
* {VariableModifier} UnannType VariableDeclaratorId
* VariableArityParameter
* VariableArityParameter:
* {VariableModifier} UnannType {Annotation} ... Identifier
* VariableModifier:
* Annotation
* final
* }</pre>
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.4
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-ReceiverParameter
* <pre>{@code
* MethodDeclarator:
* Identifier ( [ReceiverParameter ,] [FormalParameterList] ) [Dims]
* ReceiverParameter:
* {Annotation} UnannType [Identifier .] this
* }</pre>
*/
Pair<NodeList<Parameter>, ReceiverParameter> Parameters():
{
NodeList<Parameter> ret = emptyNodeList();
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); }
}
/**
* Note: Similar, but not identical to, {@code FormalParameter}.
* Note: Distinction between {@code LambdaParameters} and {@code InferredLambdaParameters} is presence of types.
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-15.27.1
* <pre>{@code
* LambdaParameters:
* ( [LambdaParameterList] )
* Identifier
* LambdaParameterList:
* LambdaParameter {, LambdaParameter}
* Identifier {, Identifier}
* LambdaParameter:
* {VariableModifier} LambdaParameterType VariableDeclaratorId
* VariableArityParameter
* LambdaParameterType:
* UnannType
* var
* }</pre>
* For Convenience:
* <pre>{@code
* VariableArityParameter:
* {VariableModifier} UnannType {Annotation} ... Identifier
* VariableModifier:
* Annotation
* final
* VariableDeclaratorId:
* Identifier [Dims]
* Dims:
* {Annotation} [ ] {{Annotation} [ ]}
* }</pre>
*/
NodeList<Parameter> LambdaParameters():
{
NodeList<Parameter> ret = null;
Parameter par;
}
{
par = Parameter() { ret = add(ret, par); }
( "," par = Parameter() { ret = add(ret, par); } )*
{ return ret; }
}
/**
* Note: Similar, but not identical to, {@code FormalParameter}.
* Note: Distinction between {@code LambdaParameters} and {@code InferredLambdaParameters} is presence of types.
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-15.27.1
* <pre>{@code
* LambdaParameters:
* ( [LambdaParameterList] )
* Identifier
* LambdaParameterList:
* LambdaParameter {, LambdaParameter}
* Identifier {, Identifier}
* LambdaParameter:
* {VariableModifier} LambdaParameterType VariableDeclaratorId
* VariableArityParameter
* LambdaParameterType:
* UnannType
* var
* }</pre>
* For Convenience:
* <pre>{@code
* VariableArityParameter:
* {VariableModifier} UnannType {Annotation} ... Identifier
* VariableModifier:
* Annotation
* final
* VariableDeclaratorId:
* Identifier [Dims]
* Dims:
* {Annotation} [ ] {{Annotation} [ ]}
* }</pre>
*/
NodeList<Parameter> InferredLambdaParameters():
{
NodeList<Parameter> ret = null;
Pair<SimpleName, List<ArrayBracketPair>> id;
}
{
id = VariableDeclaratorId() { ret = add(ret, new Parameter(range(id.a, id.a), new NodeList<Modifier>(), emptyNodeList(), new UnknownType(), false, emptyNodeList(), id.a)); }
(
"," id = VariableDeclaratorId() { ret = add(ret, new Parameter(range(id.a, id.a), new NodeList<Modifier>(), emptyNodeList(), new UnknownType(), false, emptyNodeList(), id.a)); }
)*
{ return ret; }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.4.1
* <pre>{@code
* FormalParameter:
* {VariableModifier} UnannType VariableDeclaratorId
* VariableArityParameter
* VariableArityParameter:
* {VariableModifier} UnannType {Annotation} ... Identifier
* VariableModifier:
* Annotation
* final
* }</pre>
*/
Parameter Parameter():
{
ModifierHolder modifier;
Type partialType;
boolean isVarArg = false;
Pair<SimpleName, List<ArrayBracketPair>> id;
NodeList<AnnotationExpr> varArgAnnotations = emptyNodeList();
}
{
modifier = Modifiers()
partialType = Type(emptyNodeList())
[
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);
}
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.4
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-ReceiverParameter
* <pre>{@code
* MethodDeclarator:
* Identifier ( [ReceiverParameter ,] [FormalParameterList] ) [Dims]
* ReceiverParameter:
* {Annotation} UnannType [Identifier .] this
* }</pre>
*/
ReceiverParameter ReceiverParameter():
{
Type partialType;
Name id;
NodeList<AnnotationExpr> annotations = emptyNodeList();
}
{
annotations = Annotations()
partialType = Type(emptyNodeList())
id = ReceiverParameterId()
{
return new ReceiverParameter(range(partialType, token()), annotations, partialType, id);
}
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.4
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-ReceiverParameter
* <pre>{@code
* MethodDeclarator:
* Identifier ( [ReceiverParameter ,] [FormalParameterList] ) [Dims]
* ReceiverParameter:
* {Annotation} UnannType [Identifier .] this
* }</pre>
*/
Name ReceiverParameterId():
{
Name ret = null;
}
{
[ LOOKAHEAD(Name()) ret = Name() "."] "this"
{ return new Name(tokenRange(), ret, token.image); }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.8
* <pre>{@code
* ConstructorDeclaration:
* {ConstructorModifier} ConstructorDeclarator [Throws] ConstructorBody
* ConstructorDeclarator:
* [TypeParameters] SimpleTypeName ( [ReceiverParameter ,] [FormalParameterList] )
* SimpleTypeName:
* TypeIdentifier
* }</pre>
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.8.7
* <pre>{@code
* ConstructorBody:
* { [ExplicitConstructorInvocation] [BlockStatements] }
* }</pre>
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.8.7.1
* <pre>{@code
* ExplicitConstructorInvocation:
* [TypeArguments] this ( [ArgumentList] ) ;
* [TypeArguments] super ( [ArgumentList] ) ;
* ExpressionName . [TypeArguments] super ( [ArgumentList] ) ;
* Primary . [TypeArguments] super ( [ArgumentList] ) ;
* }</pre>
*/
ConstructorDeclaration ConstructorDeclaration(ModifierHolder modifier):
{
RangedList<TypeParameter> typeParameters = new RangedList<TypeParameter>(emptyNodeList());
SimpleName name;
Pair<NodeList<Parameter>, ReceiverParameter> parameters = new Pair<NodeList<Parameter>, ReceiverParameter>(emptyNodeList(), null);
NodeList<ReferenceType> throws_ = emptyNodeList();
ExplicitConstructorInvocationStmt exConsInv = null;
NodeList<Statement> stmts = emptyNodeList();
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);
}
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.8.7.1
* <pre>{@code
* ExplicitConstructorInvocation:
* [TypeArguments] this ( [ArgumentList] ) ;
* [TypeArguments] super ( [ArgumentList] ) ;
* ExpressionName . [TypeArguments] super ( [ArgumentList] ) ;
* Primary . [TypeArguments] super ( [ArgumentList] ) ;
* }</pre>
* The same, but aligned on {@code super}, to emphasise how this grammar relates:
* <pre>{@code
* ExplicitConstructorInvocation:
* [TypeArguments] this ( [ArgumentList] ) ;
* [TypeArguments] super ( [ArgumentList] ) ;
* ExpressionName . [TypeArguments] super ( [ArgumentList] ) ;
* Primary . [TypeArguments] super ( [ArgumentList] ) ;
* }</pre>
*/
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); }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-14.html#jls-14.5
* <pre>{@code
* Statement:
* StatementWithoutTrailingSubstatement
* LabeledStatement
* IfThenStatement
* IfThenElseStatement
* WhileStatement
* ForStatement
* StatementNoShortIf:
* StatementWithoutTrailingSubstatement
* LabeledStatementNoShortIf
* IfThenElseStatementNoShortIf
* WhileStatementNoShortIf
* ForStatementNoShortIf
* StatementWithoutTrailingSubstatement:
* Block
* EmptyStatement
* ExpressionStatement
* AssertStatement
* SwitchStatement
* DoStatement
* BreakStatement
* ContinueStatement
* ReturnStatement
* SynchronizedStatement
* ThrowStatement
* TryStatement
* YieldStatement
* }</pre>
*/
NodeList<Statement> Statements():
{
NodeList<Statement> ret = emptyNodeList();
Statement stmt;
}
{
( LOOKAHEAD(2) stmt = BlockStatement() { ret = add(ret, stmt); } )*
{ return ret; }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.6
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.
* <pre>{@code
* InstanceInitializer:
* Block
* }</pre>
* <pre>{@code
* StaticInitializer:
* static Block
* }</pre>
*/
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.
*/
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-4.html#jls-4.1
* <pre>{@code
* Type:
* PrimitiveType
* ReferenceType
* }<pre>
*/
Type Type(NodeList<AnnotationExpr> annotations):
{
Type ret;
}
{
(
LOOKAHEAD(PrimitiveType(annotations) Annotations() "[" | ClassOrInterfaceType(annotations))
ret = ReferenceType(annotations)
|
ret = PrimitiveType(annotations)
)
{ return ret; }
}
/**
* // TODO: JLS Has type and unannotated type, while JavaParser has type and annotated type.
* Note that an array of primitives is considered a reference type.
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-4.html#jls-4.1
* <pre>{@code
* ReferenceType:
* ClassOrInterfaceType
* TypeVariable
* ArrayType
* ClassOrInterfaceType:
* ClassType
* InterfaceType
* ClassType:
* {Annotation} TypeIdentifier [TypeArguments]
* PackageName . {Annotation} TypeIdentifier [TypeArguments]
* ClassOrInterfaceType . {Annotation} TypeIdentifier [TypeArguments]
* InterfaceType:
* ClassType
* TypeVariable:
* {Annotation} TypeIdentifier
* ArrayType:
* PrimitiveType Dims
* ClassOrInterfaceType Dims
* TypeVariable Dims
* Dims:
* {Annotation} [ ] {{Annotation} [ ]}
* }<pre>
*/
ReferenceType ReferenceType(NodeList<AnnotationExpr> annotations):
{
Type type;
ArrayBracketPair arrayBracketPair;
List<ArrayBracketPair> arrayBracketPairs = new ArrayList<ArrayBracketPair>(0);
}
{
(
// Note that an array of primitives is considered a reference type.
type = PrimitiveType(annotations)
(
LOOKAHEAD(Annotations() "[")
arrayBracketPair = ArrayBracketPair(Origin.TYPE) { arrayBracketPairs=add(arrayBracketPairs, arrayBracketPair); }
)+ // MUST have one or more array bracket pairs to be considered a reference type.
|
type = ClassOrInterfaceType(annotations)
(
LOOKAHEAD(Annotations() "[")
arrayBracketPair = ArrayBracketPair(Origin.TYPE) { arrayBracketPairs=add(arrayBracketPairs, arrayBracketPair); }
)* // Optionally MAY have zero or more array bracket pairs.
)
{ return (ReferenceType)wrapInArrayTypes(type, arrayBracketPairs); }
}
/**
* Array bracket pairs is referred to as {@code Dims} within the JLS.
* <pre>{@code
* Dims:
* {Annotation} [ ] {{Annotation} [ ]}
* }</pre>
*
*/
ArrayBracketPair ArrayBracketPair(Origin origin):
{
NodeList<AnnotationExpr> annotations;
JavaToken begin = INVALID;
}
{
annotations = Annotations()
"[" { begin = orIfInvalid(begin, token()); }
"]"
{ return new ArrayBracketPair(range(begin, token()), origin, annotations); }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-4.html#jls-4.9
* <blockquote>
* An intersection type takes the form T1 & ... & Tn (n > 0), where Ti (1 ≤ i ≤ n) are types.
* </blockquote>
*/
IntersectionType IntersectionType(NodeList<AnnotationExpr> annotations):
{
JavaToken begin = INVALID;
ReferenceType elementType;
NodeList<ReferenceType> elements = emptyNodeList();
}
{
elementType = ReferenceType(annotations) { begin = orIfInvalid(begin, elementType); elements = add(elements, elementType); }
"&"
(elementType = AnnotatedReferenceType() { elements = add(elements, elementType); } )+
{ return new IntersectionType(range(begin, token()), elements); }
}
// TODO: JLS Has type and unannotated type, while JavaParser has type and annotated type.
ClassOrInterfaceType AnnotatedClassOrInterfaceType():
{
NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
ClassOrInterfaceType cit;
}
{
annotations = Annotations()
cit = ClassOrInterfaceType(annotations)
{ return cit; }
}
// TODO: JLS Has type and unannotated type, while JavaParser has type and annotated type.
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; }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-4.html#jls-4.5.1
* <pre>{@code
* TypeArguments:
* < TypeArgumentList >
* TypeArgumentList:
* TypeArgument {, TypeArgument}
* TypeArgument:
* ReferenceType
* Wildcard
* }<pre>
*/
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; }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-4.html#jls-4.5.1
* <pre>{@code
* TypeArguments:
* < TypeArgumentList >
* TypeArgumentList:
* TypeArgument {, TypeArgument}
* TypeArgument:
* ReferenceType
* Wildcard
* }<pre>
*/
Type TypeArgument():
{
Type ret;
NodeList<AnnotationExpr> annotations;
}
{
annotations = Annotations()
(
ret = Type(annotations)
|
ret = Wildcard(annotations)
)
{ return ret; }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-4.html#jls-4.5.1
* <pre>{@code
* Wildcard:
* {Annotation} ? [WildcardBounds]
* WildcardBounds:
* extends ReferenceType
* super ReferenceType
* }<pre>
*/
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);}
}
/**
* Note that {@code char} and {@code byte} are treated as an {@code IntegralType}, which is a subtype of {@code NumericType}.
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-4.html#jls-4.2
* <pre>{@code
* PrimitiveType:
* {Annotation} NumericType
* {Annotation} boolean
* NumericType:
* IntegralType
* FloatingPointType
* IntegralType:
* (one of)
* byte short int long char
* FloatingPointType:
* (one of)
* float double
* }<pre>
*/
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; }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-8.4.5
* <pre>{@code
* Result:
* UnannType
* void
* }<pre>
*/
Type ResultType(NodeList<AnnotationExpr> annotations):
{
Type ret;
}
{
(
"void" { ret = new VoidType(tokenRange()); }
|
ret = Type(annotations)
)
{ return ret; }
}
/**
* A {@code SimpleName} is just an identifier.
* A {@code Name} can be a {@code SimpleName} or a {@code SimpleName} with qualifiers (e.g. a class or object reference).
* Note that no disambiguation is made as to exactly what type of name it is - e.g. whether it is a package, subclass, or field. That happens within JavaParser, rather than the grammar.
*/
Name Name():
/*
* A lookahead is required below since "Name" can be followed
* by a ".*" when used in the context of an "ImportDeclaration".
*/
{
Name ret;
}
{
Identifier() { ret = new Name(tokenRange(), null, token.image); }
(
LOOKAHEAD(2)
"."
Identifier()
{ ret = new Name(range(ret, token()), ret, token.image); }
)*
{ return ret; }
}
/**
* A {@code SimpleName} is just an identifier.
* A {@code Name} can be a {@code SimpleName} or a {@code SimpleName} with qualifiers (e.g. a class or object reference).
* Note that no disambiguation is made as to exactly what type of name it is - e.g. whether it is a package, subclass, or field. That happens within JavaParser, rather than the grammar.
*/
SimpleName SimpleName():
{
SimpleName ret;
}
{
Identifier() { ret = new SimpleName(tokenRange(), token.image); }
{ return ret; }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.8
* <pre>{@code
* Identifier:
* IdentifierChars but not a Keyword or BooleanLiteral or NullLiteral
* IdentifierChars:
* JavaLetter {JavaLetterOrDigit}
* JavaLetter:
* any Unicode character that is a "Java letter"
* }</pre>
* For Convenience:
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.9
* <blockquote>
* 51 character sequences, formed from ASCII letters, are reserved for use as keywords and cannot be used as identifiers (§3.8).
* </blockquote>
* <pre>{@code
* Keyword:
* (one of)
*
* abstract continue for new switch
* assert default if package synchronized
* boolean do goto private this
* break double implements protected throw
* byte else import public throws
* case enum instanceof return transient
* catch extends int short try
* char final interface static void
* class finally long strictfp volatile
* const float native super while
* _ (underscore)
* }</pre>
*/
String Identifier():
{
String ret;
}
{
(
// TODO: Explain why these keywords are explicitly flagged up as "included", and why they're not already covered by {@code <IDENTIFIER>}.
// TODO: Explain how / where boolean and null literals are excluded.
// 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> | <YIELD> | <RECORD> |
// 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()
{
ret = generateLambda(ret, lambdaBody);
}
|
"::"
[typeArgs = TypeArguments()]
(Identifier() | "new") { ret = new MethodReferenceExpr(range(ret, token()), ret, typeArgs.list, token.image); }
)
]
{ return ret; }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-15.26
* <pre>{@code
* AssignmentExpression:
* ConditionalExpression
* Assignment
* Assignment:
* LeftHandSide AssignmentOperator Expression
* LeftHandSide:
* ExpressionName
* FieldAccess
* ArrayAccess
* AssignmentOperator:
* (one of)
* = *= /= %= += -= <<= >>= >>>= &= ^= |=
* }<pre>
*/
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; }
}
/**
* // TODO: Examine further re: missing(?) {@code LambdaExpression} or whether it is permissive enough to include it.
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-15.25
* <pre>{@code
* ConditionalExpression:
* ConditionalOrExpression
* ConditionalOrExpression ? Expression : ConditionalExpression
* ConditionalOrExpression ? Expression : LambdaExpression
* }<pre>
*/
Expression ConditionalExpression():
{
Expression ret;
Expression left;
Expression right;
}
{
ret = ConditionalOrExpression()
[
"?"
left = Expression()
":"
right = Expression()
// TODO: Examine further re: missing(?) {@code LambdaExpression} or whether it is permissive enough to include it.
{
ret = new ConditionalExpr(range(ret, token()), ret, left, right);
}
]
{ return ret; }
}
/**
* <strong>
* Note subtle distinctions between inclusive and exclusive expressions.
* </strong>
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-15.24
* <pre>{@code
* ConditionalOrExpression:
* ConditionalAndExpression
* ConditionalOrExpression || ConditionalAndExpression
* }<pre>
*/
Expression ConditionalOrExpression():
{
Expression ret;
Expression right;
}
{
// First consider a higher-precedence operator, before considering the token as the left-hand part of this expression.
ret = ConditionalAndExpression()
(
"||"
right = ConditionalAndExpression()
{ ret = new BinaryExpr(range(ret, token()), ret, right, BinaryExpr.Operator.OR); }
)*
{ return ret; }
}
/**
* <strong>
* Note subtle distinctions between inclusive and exclusive expressions.
* </strong>
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-15.23
* <pre>{@code
* ConditionalAndExpression:
* InclusiveOrExpression
* ConditionalAndExpression && InclusiveOrExpression
* }<pre>
* For Convenience:
* <pre>{@code
* AndExpression:
* EqualityExpression
* AndExpression & EqualityExpression
* ExclusiveOrExpression:
* AndExpression
* ExclusiveOrExpression ^ AndExpression
* InclusiveOrExpression:
* ExclusiveOrExpression
* InclusiveOrExpression | ExclusiveOrExpression
* }<pre>
*/
Expression ConditionalAndExpression():
{
Expression ret;
Expression right;
}
{
// First consider a higher-precedence operator, before considering the token as the left-hand part of this expression.
ret = InclusiveOrExpression()
(
"&&"
right = InclusiveOrExpression()
{ ret = new BinaryExpr(range(ret, token()), ret, right, BinaryExpr.Operator.AND); }
)*
{ return ret; }
}
/**
* <strong>
* Note subtle distinctions between inclusive and exclusive expressions.
* </strong>
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-15.22
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-InclusiveOrExpression
* <pre>{@code
* AndExpression:
* EqualityExpression
* AndExpression & EqualityExpression
* ExclusiveOrExpression:
* AndExpression
* ExclusiveOrExpression ^ AndExpression
* InclusiveOrExpression:
* ExclusiveOrExpression
* InclusiveOrExpression | ExclusiveOrExpression
* }<pre>
*/
Expression InclusiveOrExpression():
{
Expression ret;
Expression right;
}
{
// First consider a higher-precedence operator, before considering the token as the left-hand part of this expression.
ret = ExclusiveOrExpression()
(
"|"
right = ExclusiveOrExpression()
{ ret = new BinaryExpr(range(ret, token()), ret, right, BinaryExpr.Operator.BINARY_OR); }
)*
{ return ret; }
}
/**
* <strong>
* Note subtle distinctions between inclusive and exclusive expressions.
* </strong>
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-15.22
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-ExclusiveOrExpression
* <pre>{@code
* AndExpression:
* EqualityExpression
* AndExpression & EqualityExpression
* ExclusiveOrExpression:
* AndExpression
* ExclusiveOrExpression ^ AndExpression
* InclusiveOrExpression:
* ExclusiveOrExpression
* InclusiveOrExpression | ExclusiveOrExpression
* }<pre>
*/
Expression ExclusiveOrExpression():
{
Expression ret;
Expression right;
}
{
// First consider a higher-precedence operator, before considering the token as the left-hand part of this expression.
ret = AndExpression() (
"^"
right = AndExpression()
{ ret = new BinaryExpr(range(ret, token()), ret, right, BinaryExpr.Operator.XOR); }
)*
{ return ret; }
}
/**
* <strong>
* Note subtle distinctions between inclusive and exclusive expressions.
* </strong>
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-15.22
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-AndExpression
* <pre>{@code
* AndExpression:
* EqualityExpression
* AndExpression & EqualityExpression
* ExclusiveOrExpression:
* AndExpression
* ExclusiveOrExpression ^ AndExpression
* InclusiveOrExpression:
* ExclusiveOrExpression
* InclusiveOrExpression | ExclusiveOrExpression
* }<pre>
*/
Expression AndExpression():
{
Expression ret;
Expression right;
}
{
// First consider a higher-precedence operator, before considering the token as the left-hand part of this expression.
ret = EqualityExpression() (
"&"
right = EqualityExpression()
{ ret = new BinaryExpr(range(ret, token()), ret, right, BinaryExpr.Operator.BINARY_AND); }
)*
{ return ret; }
}
/**
* // Note that instanceof is a {@code RelationalExpression} within the JLS, which differs from JavaParser
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-15.21
* <pre>{@code
* EqualityExpression:
* RelationalExpression
* EqualityExpression == RelationalExpression
* EqualityExpression != RelationalExpression
* }<pre>
* For Convenience:
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-15.20
* <pre>{@code
* RelationalExpression:
* ShiftExpression
* RelationalExpression < ShiftExpression
* RelationalExpression > ShiftExpression
* RelationalExpression <= ShiftExpression
* RelationalExpression >= ShiftExpression
* RelationalExpression instanceof ReferenceType
* }<pre>
*/
Expression EqualityExpression():
{
Expression ret;
Expression right;
BinaryExpr.Operator op;
}
{
// First consider a higher-precedence operator, before considering the token as the left-hand part of this expression.
// Note that instanceof is a {@code RelationalExpression} within the JLS, which differs from JavaParser
ret = InstanceOfExpression()
(
(
"==" { op = BinaryExpr.Operator.EQUALS; }
|
"!=" { op = BinaryExpr.Operator.NOT_EQUALS; }
)
right = InstanceOfExpression()
{ ret = new BinaryExpr(range(ret, token()), ret, right, op); }
)*
{ return ret; }
}
/**
* https://openjdk.java.net/jeps/375
* The instanceof grammar is extended accordingly:
* <pre>{@code
* Pattern:
* ReferenceType Identifier
* }<pre>
*/
PatternExpr PatternExpression():
{
ReferenceType type;
SimpleName name;
}
{
type = AnnotatedReferenceType()
name = SimpleName()
{ return new PatternExpr(range(type, token()), type, name); }
}
/**
* // Note that instanceof is a {@code RelationalExpression} within the JLS, which differs from JavaParser
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-15.20
* <pre>{@code
* RelationalExpression:
* ShiftExpression
* RelationalExpression < ShiftExpression
* RelationalExpression > ShiftExpression
* RelationalExpression <= ShiftExpression
* RelationalExpression >= ShiftExpression
* RelationalExpression instanceof ReferenceType
* }<pre>
*/
Expression InstanceOfExpression():
{
Expression ret;
ReferenceType type;
NodeList<AnnotationExpr> annotations;
PatternExpr pattern;
}
{
ret = RelationalExpression()
[
"instanceof"
(
LOOKAHEAD(PatternExpression())
pattern = PatternExpression()
{ ret = new InstanceOfExpr(range(ret, token()), ret, pattern.getType(), pattern); }
|
type = AnnotatedReferenceType()
{ ret = new InstanceOfExpr(range(ret, token()), ret, type, null); }
)
]
{ return ret; }
}
/**
* // Note that instanceof is a {@code RelationalExpression} within the JLS, which differs from JavaParser
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-15.20
* <pre>{@code
* RelationalExpression:
* ShiftExpression
* RelationalExpression < ShiftExpression
* RelationalExpression > ShiftExpression
* RelationalExpression <= ShiftExpression
* RelationalExpression >= ShiftExpression
* RelationalExpression instanceof ReferenceType
* }<pre>
* // Note that JDK 13/14 introduce pattern Matching for instanceof
* https://openjdk.java.net/jeps/375
* The instanceof grammar is extended accordingly:
* <pre>{@code
* RelationalExpression:
* ...
* RelationalExpression instanceof ReferenceType
* RelationalExpression instanceof Pattern
*
* Pattern:
* ReferenceType Identifier
* }<pre>
*/
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; }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-15.19
* <pre>{@code
* ShiftExpression:
* AdditiveExpression
* ShiftExpression << AdditiveExpression
* ShiftExpression >> AdditiveExpression
* ShiftExpression >>> AdditiveExpression
* }<pre>
*/
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; }
}
/**
* https://docs.oracle.com/javase/specs/jls/se15/html/jls-15.html#jls-15.18
* <pre>{@code
* AdditiveExpression:
* MultiplicativeExpression
* AdditiveExpression + MultiplicativeExpression
* AdditiveExpression - MultiplicativeExpression
* }<pre>
*/
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; }
}