| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| |
| options |
| { |
| MULTI=true; |
| STATIC=false; |
| VISITOR=true; |
| NODE_SCOPE_HOOK=true; |
| NODE_CLASS="JexlNode"; |
| UNICODE_INPUT=true; |
| KEEP_LINE_COLUMN=true; |
| TRACK_TOKENS=true; |
| //DEBUG_PARSER=true; |
| //DEBUG_TOKEN_MANAGER=true; |
| } |
| |
| PARSER_BEGIN(Parser) |
| |
| package org.apache.commons.jexl3.parser; |
| |
| import java.util.Collections; |
| import java.util.LinkedList; |
| |
| import org.apache.commons.jexl3.JexlInfo; |
| import org.apache.commons.jexl3.JexlFeatures; |
| import org.apache.commons.jexl3.JexlException; |
| import org.apache.commons.jexl3.internal.Scope; |
| |
| public final class Parser extends JexlParser |
| { |
| public ASTJexlScript parse(JexlInfo jexlInfo, JexlFeatures jexlFeatures, String jexlSrc, Scope scope) { |
| JexlFeatures previous = getFeatures(); |
| try { |
| setFeatures(jexlFeatures); |
| // If registers are allowed, the default parser state has to be REGISTERS. |
| if (jexlFeatures.supportsRegister()) { |
| token_source.defaultLexState = REGISTERS; |
| } |
| // lets do the 'Unique Init' in here to be safe - it's a pain to remember |
| info = jexlInfo != null? jexlInfo : new JexlInfo(); |
| source = jexlSrc; |
| pragmas = null; |
| frame = scope; |
| branchScope = new BranchScope(); |
| ReInit(new java.io.StringReader(jexlSrc)); |
| ASTJexlScript script = jexlFeatures.supportsScript()? JexlScript(scope) : JexlExpression(scope); |
| script.jjtSetValue(info); |
| script.setPragmas(pragmas != null |
| ? Collections.<String,Object>unmodifiableMap(pragmas) |
| : Collections.<String,Object>emptyMap()); |
| return script; |
| } catch (TokenMgrError xtme) { |
| throw new JexlException.Tokenization(info, xtme).clean(); |
| } catch (ParseException xparse) { |
| throw new JexlException.Parsing(info, xparse).clean(); |
| } finally { |
| token_source.defaultLexState = DEFAULT; |
| cleanup(previous); |
| } |
| } |
| } |
| |
| PARSER_END(Parser) |
| |
| TOKEN_MGR_DECLS : { |
| /** |
| * A stack of 1 for keeping state to deal with dotted identifiers |
| */ |
| int dotLexState = DEFAULT; |
| |
| public void pushDot() { |
| dotLexState = curLexState; |
| curLexState = DOT_ID; |
| } |
| |
| public void popDot() { |
| if (curLexState == DOT_ID) { |
| curLexState = dotLexState; |
| dotLexState = defaultLexState; |
| } |
| } |
| |
| public void pushQ() { |
| dotLexState = curLexState; |
| curLexState = QUALIFIED; |
| } |
| |
| public void popQ() { |
| if (curLexState == QUALIFIED) { |
| curLexState = dotLexState; |
| dotLexState = defaultLexState; |
| } |
| } |
| |
| } |
| /*************************************** |
| * Skip & Number literal tokens |
| ***************************************/ |
| |
| <*> SKIP : /* WHITE SPACE */ |
| { |
| <"##" (~["\n","\r"])* ("\n" | "\r" | "\r\n")? > |
| | <"/*" (~["*"])* "*" ("*" | ~["*","/"] (~["*"])* "*")* "/"> |
| | <"//" (~["\n","\r"])* ("\n" | "\r" | "\r\n")? > |
| | " " |
| | "\t" |
| | "\n" |
| | "\r" |
| | "\f" |
| } |
| |
| <*> TOKEN : /* KEYWORDS */ |
| { |
| < IF : "if" > { popDot(); } |
| | < ELSE : "else" > { popDot(); } |
| | < FOR : "for" > { popDot(); } |
| | < WHILE : "while" > { popDot(); } |
| | < DO : "do" > { popDot(); } |
| | < SWITCH : "switch" > { popDot(); } |
| | < CASE : "case" > { popDot(); } |
| | < DCASE : "default" > { popDot(); } |
| | < TRY : "try" > { popDot(); } |
| | < CATCH : "catch" > { popDot(); } |
| | < FINALLY : "finally" > { popDot(); } |
| | < THROW : "throw" > { popDot(); } |
| | < ASSERT : "assert" > { popDot(); } |
| | < SYNCHRONIZED : "synchronized" > { popDot(); } |
| | < NEW : "new" > { popDot(); pushQ(); } /* Lexical state is now QUALIFIED */ |
| | < VAR : "var" > { popDot(); } /* Revert state to default if was DOT_ID. */ |
| | < FINAL : "final" > { popDot(); } |
| | < EMPTY : "empty" > { popDot(); } /* Revert state to default if was DOT_ID. */ |
| | < SIZE : "size" > { popDot(); } /* Revert state to default if was DOT_ID. */ |
| | < THIS : "this" > { popDot(); } |
| | < NULL : "null" | "\u2205" > { popDot(); } |
| | < TRUE : "true" > { popDot(); } |
| | < FALSE : "false" > { popDot(); } |
| | < RETURN : "return" > { popDot(); } |
| | < FUNCTION : "function" > { popDot(); } /* Revert state to default if was DOT_ID. */ |
| | < LAMBDA : "->" | "\u2192" > |
| | < LAMBDAE : "=>" | "\u21D2" > |
| | < BREAK : "break" > { popDot(); } |
| | < CONTINUE : "continue" > { popDot(); } |
| | < REMOVE : "remove" > { popDot(); } /* Revert state to default if was DOT_ID. */ |
| | < PRAGMA : "#pragma" > { pushQ(); } /* Lexical state is now QUALIFIED */ |
| } |
| |
| <*> TOKEN : { /* SEPARATORS */ |
| < LPAREN : "("> { popQ(); } /* Revert state to default. */ |
| | < RPAREN : ")"> { popQ(); } /* Revert state to default. */ |
| | < LCURLY : "{" > |
| | < RCURLY : "}" > |
| | < LBRACKET : "[" > { popQ(); } /* Revert state to default. */ |
| | < RBRACKET : "]" > |
| | < SEMICOL : ";" > { popQ(); } /* Revert state to default. */ |
| | < COLON : ":" > |
| | < DCOLON : "::" > |
| | < COMMA : "," > { popQ(); } /* Revert state to default. */ |
| | < DOT : "." > { pushDot(); } /* Lexical state is now DOT_ID */ |
| | < QDOT : "?." > { pushDot(); } /* Lexical state is now DOT_ID */ |
| | < QLBRACKET : "?[" > { popDot(); } /* Revert state to default */ |
| | < ELLIPSIS : "..." | "\u2026"> |
| | < HBRACKET : "#[" > |
| | < HCURLY : "#{" > |
| } |
| |
| <*> TOKEN : { /* PRIMITIVE TYPES */ |
| < CHAR : "char" > { popDot(); } |
| | < BYTE : "byte" > { popDot(); } |
| | < SHORT : "short" > { popDot(); } |
| | < INT : "int" > { popDot(); } |
| | < LONG : "long" > { popDot(); } |
| | < FLOAT : "float" > { popDot(); } |
| | < DOUBLE : "double" > { popDot(); } |
| | < BOOLEAN : "boolean" > { popDot(); } |
| } |
| |
| <*> TOKEN : { /* STREAMS */ |
| < DOTP : ".(" > |
| | < DOTB : ".[" > |
| | < DOTC : ".{" > |
| | < DOTS : ".@" > |
| } |
| |
| <*> TOKEN : { /* CONDITIONALS */ |
| < QMARK : "?" > |
| | < ELVIS : "?:" > |
| | < NULLP : "??" > |
| | < AND : "&&" | "\u2227" > |
| | < _AND : "and" > { popDot(); } |
| | < OR : "||" | "\u2228" > |
| | < _OR: "or" > { popDot(); } |
| } |
| |
| <*> TOKEN : { /* COMPARISONS */ |
| < eq : "==" | "\u2261"> |
| | < EQ : "eq" > { popDot(); } |
| | < ne : "!=" | "\u2260" > |
| | < NE : "ne" > { popDot(); } |
| | < req : "=~" | "\u2208" > // regexp equal |
| | < IN : "in" > { popDot(); } |
| | < rne : "!~" | "!in" | "\u2209" > // regexp not equal |
| | < is : "===" > // identitical |
| | < ni : "!==" > // not identitical |
| | < seq : "=^" > // starts equal |
| | < eeq : "=$" > // ends equal |
| | < sne : "!^" > // start not equal |
| | < ene : "!$" > // ends not equal |
| | < gt : ">" > |
| | < GT : "gt" > { popDot(); } |
| | < ge : ">=" | "\u2265" > |
| | < GE : "ge" > { popDot(); } |
| | < lt : "<" > |
| | < LT : "lt" > { popDot(); } |
| | < le : "<=" | "\u2264" > |
| | < LE : "le" > { popDot(); } |
| | < iof : "instanceof" > { popDot(); pushQ(); } |
| | < niof : "!instanceof" > { pushQ(); } |
| |
| } |
| |
| <*> TOKEN : { /* OPERATORS */ |
| < plus_assign : "+=" > |
| | < minus_assign : "-=" > |
| | < mult_assign : "*=" > |
| | < div_assign : "/=" > |
| | < mod_assign : "%=" > |
| | < and_assign : "&=" > |
| | < or_assign : "|=" > |
| | < xor_assign : "^=" > |
| | < shl_assign : "<<=" > |
| | < sar_assign : ">>=" > |
| | < shr_assign : ">>>=" > |
| |
| | < null_assign : "?=" > |
| | < assign : "=" > |
| | < increment : "++" > |
| | < decrement : "--" > |
| | < plus : "+" > |
| | < minus : "-" > |
| | < unary_minus : "\u2212" > |
| | < mult : "*" | "\u22C5" > |
| | < div : "/" > |
| | < DIV : "div" > { popDot(); } |
| | < mod : "%" > |
| | < MOD : "mod" > { popDot(); } |
| | < not : "!" | "\u00AC" > |
| | < NOT : "not" > { popDot(); } |
| | < and : "&" > |
| | < or : "|" > |
| | < xor : "^" > |
| | < shl : "<<" > |
| | < shr : ">>>" > |
| | < sar : ">>" > |
| |
| | < tilda : "~" > |
| | < range : ".." | "\u2025" > |
| } |
| |
| /*************************************** |
| * Identifier & String tokens |
| ***************************************/ |
| <*> TOKEN : /* NaN */ |
| { |
| < NAN_LITERAL : "NaN" > |
| } |
| |
| <*> TOKEN : /* ANNOTATION */ |
| { |
| < ANNOTATION: "@" ( [ "0"-"9", "a"-"z", "A"-"Z", "_", "$" ])+ > |
| } |
| |
| <DOT_ID> TOKEN : /* IDENTIFIERS */ |
| { |
| < DOT_IDENTIFIER: ( [ "0"-"9", "a"-"z", "A"-"Z", "_", "$", "@" ])+ > { popDot(); } /* Revert state to default. */ |
| } |
| |
| <DEFAULT, REGISTERS> TOKEN : /* IDENTIFIERS */ |
| { |
| < IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>|<ESCAPE>)* > { matchedToken.image = StringParser.unescapeIdentifier(matchedToken.image); } |
| | |
| < #LETTER: [ "a"-"z", "A"-"Z", "_", "$", "@" ] > |
| | |
| < #DIGIT: [ "0"-"9"] > |
| | |
| < #ESCAPE: "\\" [" ", "'", "\"", "\\"] > |
| } |
| |
| <QUALIFIED> TOKEN : /* IDENTIFIERS */ |
| { |
| < QUALIFIED_IDENTIFIER: <QNAME> ("." <QNAME>)* > { popQ(); } /* Revert state to default. */ |
| | |
| < #QNAME: [ "a"-"z", "A"-"Z", "_", "$", "@" ] ([ "a"-"z", "A"-"Z", "_", "$", "@", "0"-"9" ])* > |
| } |
| |
| <REGISTERS> TOKEN : /* REGISTERS: parser.ALLOW_REGISTER must be set to true before calling parse */ |
| { |
| < REGISTER: "#" (["0"-"9"])+ > |
| } |
| |
| <DEFAULT, REGISTERS> TOKEN : /* LITERALS */ |
| { |
| <INTEGER_LITERAL: |
| <DECIMAL_LITERAL> (<INT_SFX>)? |
| | <HEX_LITERAL> (<INT_SFX>)? |
| | <OCTAL_LITERAL> (<INT_SFX>)? |
| | <BINARY_LITERAL> (<INT_SFX>)? |
| > |
| | <#DECIMAL_LITERAL: ["1"-"9"] ((["0"-"9","_"])* <DIGIT> | (<DIGIT>)*) > |
| | <#HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"] (["0"-"9","a"-"f","A"-"F","_"])* ["0"-"9","a"-"f","A"-"F"] | (["0"-"9","a"-"f","A"-"F"])+) > |
| | <#BINARY_LITERAL: "0" ["b","B"] (["0"-"1"] (["0"-"1","_"])* ["0"-"1"] | (["0"-"1"])+) > |
| | <#OCTAL_LITERAL: "0" ((["0"-"7","_"])* ["0"-"7"] | (["0"-"7"])*) > |
| | <#INT_SFX : ["l","L","h","H"]> |
| | |
| <FLOAT_LITERAL: |
| <FLT_NUM> "." <FLT_NUM> (<FLT_SFX>)? |
| | <FLT_NUM> (".")? (<FLT_SFX>) |
| | "." <FLT_NUM> (<FLT_SFX>) |
| | "#NaN" |
| > |
| | <#FLT_NUM: (<DIGIT> (["0"-"9","_"])* <DIGIT> | (<DIGIT>)+) > |
| | <#EXPONENT: ["e","E"] (["+","-"])? <FLT_NUM> > |
| | <#FLT_CLS : ["f","F","d","D","b","B"]> |
| | <#FLT_SFX : <EXPONENT> (<FLT_CLS>)? | <FLT_CLS> > |
| } |
| |
| <*> TOKEN : |
| { |
| < STRING_LITERAL: |
| "\"" (~["\"","\\","\n","\r","\u2028","\u2029"] | "\\" ~["\n","\r","\u2028","\u2029"])* "\"" |
| | |
| "'" (~["'","\\","\n","\r","\u2028","\u2029"] | "\\" ~["\n","\r","\u2028","\u2029"])* "'" |
| > { popDot(); } /* Revert state to default if was DOT_ID. */ |
| } |
| |
| <*> TOKEN : |
| { |
| < JXLT_LITERAL: |
| "`" (~["`","\\"] | "\\" ~["\u0000"])* "`" |
| > { popDot(); } /* Revert state to default if was DOT_ID. */ |
| } |
| |
| <*> TOKEN : |
| { |
| < REGEX_LITERAL: |
| "~" "/" (~["/","\n","\r","\u2028","\u2029"] | "\\" "/" )* "/" |
| > { popDot(); } /* Revert state to default if was DOT_ID. */ |
| } |
| |
| /*************************************** |
| * Statements |
| ***************************************/ |
| |
| ASTJexlScript JexlScript(Scope frame) : { |
| jjtThis.setScope(frame); |
| } |
| { |
| (LOOKAHEAD(<PRAGMA>) Pragma())* |
| ( |
| LOOKAHEAD( LambdaLookahead() ) Lambda() (LOOKAHEAD(1) <SEMICOL>)? <EOF> { return jjtThis.script(); } |
| | |
| ( ( Statement() )*) <EOF> { return jjtThis.script(); } |
| ) |
| } |
| |
| ASTJexlScript JexlExpression(Scope frame) #JexlScript : { |
| jjtThis.setScope(frame); |
| } |
| { |
| ( Expression() )? <EOF> |
| { |
| return jjtThis.script(); |
| } |
| } |
| |
| void Annotation() #Annotation : |
| { |
| Token t; |
| } |
| { |
| t=<ANNOTATION> (LOOKAHEAD(<LPAREN>) Arguments() )? { jjtThis.setName(t.image); } |
| } |
| |
| void AnnotatedStatement() #AnnotatedStatement() : {} |
| { |
| (LOOKAHEAD(<ANNOTATION>) Annotation())+ (LOOKAHEAD(1) Block() | Statement()) |
| } |
| |
| void Statement() #void : {} |
| { |
| <SEMICOL> |
| | LOOKAHEAD(<ANNOTATION>) AnnotatedStatement() |
| | LOOKAHEAD(LabelledStatementLookahead()) LabelledStatement() |
| | LOOKAHEAD(Expression()) ExpressionStatement() |
| | Block() |
| | IfStatement() |
| | LOOKAHEAD(<FOR> <LPAREN> ForeachVar() <COLON>) ForeachStatement() |
| | ForStatement() |
| | WhileStatement() |
| | DoWhileStatement() |
| | LOOKAHEAD(<TRY> <LPAREN>) TryWithResourceStatement() |
| | TryStatement() |
| | ThrowStatement() |
| | AssertStatement() |
| | SynchronizedStatement() |
| | LOOKAHEAD(SwitchStatementLookahead()) SwitchStatement() |
| | LOOKAHEAD(MultipleIdentifier() <assign>) MultipleAssignmentStatement() |
| | ReturnStatement() |
| | Continue() |
| | Remove() |
| | Break() |
| | LOOKAHEAD(<VAR> <LPAREN> | <FINAL> <VAR> <LPAREN>) MultipleVar() |
| | Var() |
| } |
| |
| void LabelledStatementLookahead() #void() : {} |
| { |
| <IDENTIFIER> <COLON> ( <LCURLY> | <FOR> | <WHILE> | <DO> | <SWITCH> ) |
| } |
| |
| void LabelledStatement() #void : |
| { |
| Token t = null; |
| String label = null; |
| ASTLabelledStatement s; |
| } |
| { |
| t=<IDENTIFIER> { label = t.image; if (branchScope.breakSupported(label)) throwParsingException(null, t); } <COLON> |
| ( |
| LOOKAHEAD(<LCURLY>) { branchScope.pushBlockLabel(label); } s = Block() { s.setLabel(label); branchScope.popBlockLabel(); } |
| | |
| LOOKAHEAD(<FOR> <LPAREN> ForeachVar() <COLON>) { branchScope.pushForeachLabel(label); } s = ForeachStatement() { s.setLabel(label); branchScope.popForeachLabel(); } |
| | |
| { branchScope.pushLoopLabel(label); } s = ForStatement() { s.setLabel(label); branchScope.popLoopLabel(); } |
| | |
| { branchScope.pushLoopLabel(label); } s = WhileStatement() { s.setLabel(label); branchScope.popLoopLabel(); } |
| | |
| { branchScope.pushLoopLabel(label); } s = DoWhileStatement() { s.setLabel(label); branchScope.popLoopLabel(); } |
| | |
| { branchScope.pushBlockLabel(label); } s = SwitchStatement() { s.setLabel(label); branchScope.popBlockLabel(); } |
| | |
| { branchScope.pushBlockLabel(label); } s = IfStatement() { s.setLabel(label); branchScope.popBlockLabel(); } |
| | |
| { branchScope.pushBlockLabel(label); } s = SynchronizedStatement() { s.setLabel(label); branchScope.popBlockLabel(); } |
| | |
| LOOKAHEAD(<TRY> <LPAREN>) { branchScope.pushBlockLabel(label); } s = TryWithResourceStatement() { s.setLabel(label); branchScope.popBlockLabel(); } |
| | |
| { branchScope.pushBlockLabel(label); } s = TryStatement() { s.setLabel(label); branchScope.popBlockLabel(); } |
| ) |
| } |
| |
| ASTBlock Block() #Block : {} |
| { |
| <LCURLY> ( Statement() )* <RCURLY> |
| { return jjtThis; } |
| } |
| |
| void ExpressionStatement() : {} |
| { |
| Expression() (LOOKAHEAD(2) Expression() #Ambiguous(1))* (LOOKAHEAD(1) <SEMICOL>)? |
| } |
| |
| void MultipleAssignmentStatement() #MultipleAssignment : {} |
| { |
| MultipleIdentifier() <assign> Expression() |
| } |
| |
| void MultipleIdentifier() #MultipleIdentifier : {} |
| { |
| <LPAREN> Identifier(true) (<COMMA> Identifier(true))* <RPAREN> |
| } |
| |
| ASTIfStatement IfStatement() : {} |
| { |
| <IF> <LPAREN> Expression() <RPAREN> (LOOKAHEAD(1) Block() | Statement()) |
| ( LOOKAHEAD(1) <ELSE> (LOOKAHEAD(1) Block() | Statement()) )? |
| { return jjtThis; } |
| } |
| |
| ASTWhileStatement WhileStatement() : {} |
| { |
| <WHILE> <LPAREN> Expression() <RPAREN> { branchScope.loopCount += 1; } (LOOKAHEAD(1) Block() | Statement()) { branchScope.loopCount -= 1; } |
| { return jjtThis; } |
| } |
| |
| ASTDoWhileStatement DoWhileStatement() : {} |
| { |
| <DO> { branchScope.loopCount += 1; } (LOOKAHEAD(1) Block() | Statement()) <WHILE> <LPAREN> Expression() <RPAREN> { branchScope.loopCount -= 1; } |
| { return jjtThis; } |
| } |
| |
| ASTTryStatement TryStatement() : {} |
| { |
| <TRY> Block() ( (<CATCH> <LPAREN> TryVar() <RPAREN> Block() (<FINALLY> Block())?) | <FINALLY> Block() ) |
| { return jjtThis; } |
| } |
| |
| ASTTryWithResourceStatement TryWithResourceStatement() : {} |
| { |
| <TRY> <LPAREN> TryResource() <RPAREN> Block() ( (<CATCH> <LPAREN> TryVar() <RPAREN> Block() (<FINALLY> Block())?) | <FINALLY> Block() )? |
| { return jjtThis; } |
| } |
| |
| void TryResource() : {} |
| { |
| LOOKAHEAD(TryVar() <assign>) TryVar() <assign> Expression() |
| | |
| Expression() |
| } |
| |
| void TryVar() : {} |
| { |
| DeclareVar() |
| | |
| Identifier(true) |
| } |
| |
| void ThrowStatement() : {} |
| { |
| <THROW> Expression() |
| } |
| |
| void AssertStatement() : {} |
| { |
| <ASSERT> Expression() [ <COLON> Expression() ] |
| } |
| |
| ASTSynchronizedStatement SynchronizedStatement() : {} |
| { |
| <SYNCHRONIZED> <LPAREN> Expression() <RPAREN> (LOOKAHEAD(1) Block() | Statement()) |
| { return jjtThis; } |
| } |
| |
| void SwitchStatementLookahead() : {} |
| { |
| <SWITCH> <LPAREN> Expression() <RPAREN> <LCURLY> (<CASE> (Literal() | Identifier()) <COLON> | <DCASE> <COLON>) |
| } |
| |
| ASTSwitchStatement SwitchStatement() : {} |
| { |
| <SWITCH> <LPAREN> Expression() <RPAREN> { branchScope.switchCount += 1; } <LCURLY> SwitchStatementBlock() <RCURLY> { branchScope.switchCount -= 1; } |
| { return jjtThis; } |
| } |
| |
| void SwitchStatementBlock() #void : {} |
| { |
| SwitchStatementCase() (LOOKAHEAD(SwitchStatementBlock()) SwitchStatementBlock())* |
| | |
| SwitchStatementDefault() (LOOKAHEAD(SwitchStatementCase()) SwitchStatementCase())* |
| } |
| |
| void SwitchStatementCase() : {} |
| { |
| <CASE> (Literal() | Identifier()) <COLON> ((LOOKAHEAD(1) Block() | Statement()) )* |
| } |
| |
| void SwitchStatementDefault() : {} |
| { |
| <DCASE> <COLON> ((LOOKAHEAD(1) Block() | Statement()) )* |
| } |
| |
| void ReturnStatement() : {} |
| { |
| <RETURN> [ LOOKAHEAD(2) ExpressionStatement() ] |
| } |
| |
| void Continue() #Continue : |
| { |
| Token t = null; |
| } |
| { |
| <CONTINUE> (LOOKAHEAD(<IDENTIFIER>) t = <IDENTIFIER> { if (!branchScope.continueSupported(t.image)) throwParsingException(jjtThis); jjtThis.setLabel(t.image); } )? |
| { if (t == null && !branchScope.continueSupported()) { throwParsingException(jjtThis); } } |
| } |
| |
| void Remove() #Remove : |
| { |
| Token t = null; |
| } |
| { |
| <REMOVE> (LOOKAHEAD(<IDENTIFIER>) t = <IDENTIFIER> { if (!branchScope.removeSupported(t.image)) throwParsingException(jjtThis); jjtThis.setLabel(t.image); } )? |
| { if (t == null && !branchScope.removeSupported()) { throwParsingException(jjtThis); } } |
| } |
| |
| void Break() #Break : |
| { |
| Token t = null; |
| } |
| { |
| <BREAK> (LOOKAHEAD(<IDENTIFIER>) t = <IDENTIFIER> { if (!branchScope.breakSupported(t.image)) throwParsingException(jjtThis); jjtThis.setLabel(t.image); } )? |
| { if (t == null && !branchScope.breakSupported()) { throwParsingException(jjtThis); } } |
| } |
| |
| ASTForStatement ForStatement() : {} |
| { |
| <FOR> <LPAREN> ForInitializationNode() <SEMICOL> ForTerminationNode() <SEMICOL> ForIncrementNode() <RPAREN> { branchScope.loopCount += 1; } (LOOKAHEAD(1) Block() | Statement()) { branchScope.loopCount -= 1; } |
| { return jjtThis; } |
| } |
| |
| void ForInitializationNode() : {} |
| { |
| (Expression() | Var())? |
| } |
| |
| void ForTerminationNode() : {} |
| { |
| (ConditionalExpression())? |
| } |
| |
| void ForIncrementNode() : {} |
| { |
| (Expression())? |
| } |
| |
| ASTForeachStatement ForeachStatement() : {} |
| { |
| <FOR> <LPAREN> ForeachVar() <COLON> Expression() <RPAREN> { branchScope.foreachLoopCount += 1; } (LOOKAHEAD(1) Block() | Statement()) { branchScope.foreachLoopCount -= 1; } |
| { return jjtThis; } |
| } |
| |
| void ForeachVar() : {} |
| { |
| DeclareVar() (<COMMA> DeclareExtVar(false))? |
| | |
| Identifier(true) (<COMMA> Identifier(true))? |
| } |
| |
| void MultipleVar() #void : {} |
| { |
| (MultipleDeclareVar() <assign> Expression()) #MultipleInitialization() |
| } |
| |
| void MultipleDeclareVar() #MultipleIdentifier : |
| { |
| boolean isFinal = false; |
| } |
| { |
| ( <FINAL> { isFinal = true; jjtThis.setFinal(); } )? |
| <VAR> <LPAREN> DeclareExtVar(isFinal) (<COMMA> DeclareExtVar(isFinal))* <RPAREN> |
| } |
| |
| void Var() #void : {} |
| { |
| LOOKAHEAD(<FINAL> | <BYTE> | <SHORT> | <INT> | <LONG> | <CHAR> | <BOOLEAN> | <FLOAT> | <DOUBLE> | (<VAR> <and>)) |
| DeclareLocalVar() <assign> Expression() #Initialization(2) |
| | |
| DeclareLocalVar() (<assign> Expression() #Initialization(2))? |
| } |
| |
| void DeclareVar() #Var : |
| { |
| Token t; |
| } |
| { |
| <VAR> t=<IDENTIFIER> { declareVariable(jjtThis, t); } |
| } |
| |
| void DeclareLocalVar() #Var : |
| { |
| Token t; |
| } |
| { |
| ( <FINAL> { jjtThis.setFinal(); } )? |
| ( <VAR> ( <and> { jjtThis.setRequired(); } )? |
| | <INT> { jjtThis.setType(Integer.TYPE); } |
| | <LONG> { jjtThis.setType(Long.TYPE); } |
| | <SHORT> { jjtThis.setType(Short.TYPE); } |
| | <BYTE> { jjtThis.setType(Byte.TYPE); } |
| | <CHAR> { jjtThis.setType(Character.TYPE); } |
| | <BOOLEAN> { jjtThis.setType(Boolean.TYPE); } |
| | <FLOAT> { jjtThis.setType(Float.TYPE); } |
| | <DOUBLE> { jjtThis.setType(Double.TYPE); } |
| ) |
| t=<IDENTIFIER> { declareVariable(jjtThis, t); } |
| } |
| |
| void DeclareExtVar(boolean isFinal) #ExtVar : |
| { |
| Token t; |
| } |
| { |
| { if (isFinal) jjtThis.setFinal(); } |
| ( <and> { jjtThis.setRequired(); } )? |
| t=<IDENTIFIER> { declareVariable(jjtThis, t); } |
| } |
| |
| void Pragma() #void : |
| { |
| Token t; |
| Object value; |
| } |
| { |
| <PRAGMA> t=<QUALIFIED_IDENTIFIER> value=PragmaValue() { declarePragma(t.image, value); } |
| } |
| |
| Object PragmaValue() #void : |
| { |
| Token v; |
| } |
| { |
| LOOKAHEAD(1) v=<INTEGER_LITERAL> { return NumberParser.parseInteger(v.image); } |
| | LOOKAHEAD(1) v=<FLOAT_LITERAL> { return NumberParser.parseDouble(v.image); } |
| | LOOKAHEAD(1) v=<STRING_LITERAL> { return Parser.buildString(v.image, true); } |
| | LOOKAHEAD(1) v=<QUALIFIED_IDENTIFIER> { return v.image; } |
| | LOOKAHEAD(1) <TRUE> { return true; } |
| | LOOKAHEAD(1) <FALSE> { return false; } |
| | LOOKAHEAD(1) <NULL> { return null; } |
| | LOOKAHEAD(1) <NAN_LITERAL> { return Double.NaN; } |
| } |
| |
| |
| /*************************************** |
| * Expression syntax |
| ***************************************/ |
| |
| void Expression() #void : {} |
| { |
| AssignmentExpression() |
| } |
| |
| void AssignmentExpression() #void : {} |
| { |
| ConditionalExpression() |
| ( LOOKAHEAD(2) ( |
| <plus_assign> Expression() #SetAddNode(2) |
| | |
| <mult_assign> Expression() #SetMultNode(2) |
| | |
| <div_assign> Expression() #SetDivNode(2) |
| | |
| <mod_assign> Expression() #SetModNode(2) |
| | |
| <and_assign> Expression() #SetAndNode(2) |
| | |
| <or_assign> Expression() #SetOrNode(2) |
| | |
| <xor_assign> Expression() #SetXorNode(2) |
| | |
| <minus_assign> Expression() #SetSubNode(2) |
| | |
| <shl_assign> Expression() #SetShlNode(2) |
| | |
| <sar_assign> Expression() #SetSarNode(2) |
| | |
| <shr_assign> Expression() #SetShrNode(2) |
| | |
| <null_assign> Expression() #NullAssignment(2) |
| | |
| <assign> Expression() #Assignment(2) |
| ) )* |
| } |
| |
| /*************************************** |
| * Conditional & relational |
| ***************************************/ |
| |
| void ConditionalExpression() #void : {} |
| { |
| ConditionalOrExpression() |
| ( LOOKAHEAD(2) ( |
| <QMARK> TernaryExpression() |
| | |
| <ELVIS> Expression() #ElvisNode(2) |
| | |
| <NULLP> Expression() #NullpNode(2) |
| ) )? |
| } |
| |
| void TernaryExpression() #void : {} |
| { |
| LOOKAHEAD(Expression() <COLON>) Expression() <COLON> Expression() #TernaryNode(3) |
| | |
| Expression() #TernaryNode(2) |
| } |
| |
| void ConditionalOrExpression() #void : {} |
| { |
| ConditionalAndExpression() |
| ( LOOKAHEAD(2) ( |
| (<OR>|<_OR>) ConditionalAndExpression() #OrNode(2) |
| ) )* |
| } |
| |
| void ConditionalAndExpression() #void : {} |
| { |
| InclusiveOrExpression() |
| ( LOOKAHEAD(2) ( |
| (<AND>|<_AND>) InclusiveOrExpression() #AndNode(2) |
| ) )* |
| } |
| |
| void InclusiveOrExpression() #void : {} |
| { |
| ExclusiveOrExpression() |
| ( LOOKAHEAD(2) ( |
| <or> ExclusiveOrExpression() #BitwiseOrNode(2) |
| ) )* |
| } |
| |
| void ExclusiveOrExpression() #void : {} |
| { |
| AndExpression() |
| ( LOOKAHEAD(2) ( |
| <xor> AndExpression() #BitwiseXorNode(2) |
| ) )* |
| } |
| |
| void AndExpression() #void : {} |
| { |
| EqualityExpression() |
| ( LOOKAHEAD(2) ( |
| <and> EqualityExpression() #BitwiseAndNode(2) |
| ) )* |
| } |
| |
| void EqualityExpression() #void : {} |
| { |
| RelationalExpression() |
| ( LOOKAHEAD(2) ( |
| (<eq> | <EQ>) RelationalExpression() #EQNode(2) |
| | |
| (<ne> | <NE>) RelationalExpression() #NENode(2) |
| | |
| (<req> | <IN>) RelationalExpression() #ERNode(2) // equals regexp |
| | |
| <rne> RelationalExpression() #NRNode(2) // not equals regexp |
| | |
| <is> RelationalExpression() #ISNode(2) // identical |
| | |
| <ni> RelationalExpression() #NINode(2) // not identical |
| |
| ) )? |
| } |
| |
| void RelationalExpression() #void : {} |
| { |
| RangeExpression() |
| ( LOOKAHEAD(2) ( |
| (<lt> |<LT>) RangeExpression() #LTNode(2) |
| | |
| (<gt> | <GT>) RangeExpression() #GTNode(2) |
| | |
| (<le> | <LE>) RangeExpression() #LENode(2) |
| | |
| (<ge> | <GE>) RangeExpression() #GENode(2) |
| | |
| <seq> RangeExpression() #SWNode(2) // starts with |
| | |
| <sne> RangeExpression() #NSWNode(2) // not starts with |
| | |
| <eeq> RangeExpression() #EWNode(2) // ends with |
| | |
| <ene> RangeExpression() #NEWNode(2) // not ends with |
| | |
| <iof> TypeReference() #IOFNode(2) // instanceof |
| | |
| <niof> TypeReference() #NIOFNode(2) // not instanceof |
| |
| ) )? |
| } |
| |
| void RangeExpression() #void : {} |
| { |
| ShiftExpression() |
| ( LOOKAHEAD(2) ( |
| <range> ShiftExpression() #RangeNode(2) // range |
| ) )? |
| } |
| |
| /*************************************** |
| * Arithmetic |
| ***************************************/ |
| |
| void ShiftExpression() #void : {} |
| { |
| AdditiveExpression() |
| ( LOOKAHEAD(2) ( |
| <shl> AdditiveExpression() #ShiftLeftNode(2) |
| | |
| <shr> AdditiveExpression() #ShiftRightUnsignedNode(2) |
| | |
| <sar> AdditiveExpression() #ShiftRightNode(2) |
| ) )* |
| } |
| |
| void AdditiveExpression() #void : {} |
| { |
| MultiplicativeExpression() |
| ( LOOKAHEAD(2) ( |
| <plus> MultiplicativeExpression() #AddNode(2) |
| | |
| <minus> MultiplicativeExpression() #SubNode(2) |
| ) )* |
| } |
| |
| void MultiplicativeExpression() #void : {} |
| { |
| UnaryExpression() |
| ( LOOKAHEAD(2) ( |
| <mult> UnaryExpression() #MulNode(2) |
| | |
| (<div>|<DIV>) UnaryExpression() #DivNode(2) |
| | |
| (<mod>|<MOD>) UnaryExpression() #ModNode(2) |
| ) )* |
| } |
| |
| void UnaryExpression() #void : {} |
| { |
| <minus> UnaryExpression() #UnaryMinusNode(1) |
| | |
| <unary_minus> UnaryExpression() #UnaryMinusNode(1) |
| | |
| <plus> UnaryExpression() #UnaryPlusNode(1) |
| | |
| <increment> UnaryExpression() #IncrementNode(1) |
| | |
| <decrement> UnaryExpression() #DecrementNode(1) |
| | |
| <mult> UnaryExpression() #IndirectNode(1) |
| | |
| <tilda> UnaryExpression() #BitwiseComplNode(1) |
| | |
| (<not>|<NOT>) UnaryExpression() #NotNode(1) |
| | |
| LOOKAHEAD(<LPAREN> PrimitiveType() <RPAREN>) (<LPAREN> PrimitiveType() <RPAREN> UnaryExpression() #CastNode(2)) |
| | |
| <EMPTY> UnaryExpression() #EmptyFunction(1) |
| | |
| <SIZE> UnaryExpression() #SizeFunction(1) |
| | |
| <ELLIPSIS> EnumerationExpression() |
| | |
| PostfixExpression() |
| } |
| |
| void PostfixExpression() #void : {} |
| { |
| PointerExpression() |
| ( LOOKAHEAD(1) ( |
| <increment> #IncrementPostfixNode(1) |
| | |
| <decrement> #DecrementPostfixNode(1) |
| ) )* |
| } |
| |
| void PointerExpression() #void : {} |
| { |
| <and> ValueExpression() #PointerNode(1) |
| | |
| ValueExpression() |
| } |
| |
| void EnumerationExpression() #void : {} |
| { |
| ((IteratorExpression() (LOOKAHEAD(2) EnumerationAccess() )*) #EnumerationReference(>1) (LOOKAHEAD(<DOTS>) Reduction())?) #Reference(>1) |
| } |
| |
| void EnumerationAccess() #void : {} |
| { |
| LOOKAHEAD(<DOTB>) ArrayProjection() |
| | |
| LOOKAHEAD(<DOTC>) MapProjection() |
| | |
| LOOKAHEAD(<DOTP>) Selection() |
| } |
| |
| void Reduction() #ReductionNode : {} |
| { |
| <DOTS> <LPAREN> [LOOKAHEAD(Expression() <COLON>) Expression() <COLON>] Lambda() <RPAREN> |
| } |
| |
| void Selection() #SelectionNode : {} |
| { |
| <DOTP> ( |
| StopCountSelection() |
| | |
| StartCountSelection() |
| | |
| Lambda() |
| ) <RPAREN> |
| } |
| |
| void StopCountSelection() #StopCountNode : {} |
| { |
| (<lt> | <LT>) Expression() |
| } |
| |
| void StartCountSelection() #StartCountNode : {} |
| { |
| (<gt> | <GT>) Expression() |
| } |
| |
| void ArrayProjection() #ProjectionNode : {} |
| { |
| <DOTB> ProjectionExpression() ( LOOKAHEAD(2) <COMMA> ProjectionExpression() )* <RBRACKET> |
| } |
| |
| void MapProjection() #MapProjectionNode : {} |
| { |
| <DOTC> ProjectionExpression() <COLON> ProjectionExpression() <RCURLY> |
| } |
| |
| void ProjectionExpression() #void : {} |
| { |
| LOOKAHEAD( LambdaLookahead() ) Lambda() |
| | |
| (Identifier() ( LOOKAHEAD(2) ProjectionMemberExpression() )*) #Reference(>1) |
| } |
| |
| void ProjectionMemberExpression() #void : {} |
| { |
| LOOKAHEAD(ProjectionMethodCall()) ProjectionMethodCall() |
| | |
| ProjectionMemberAccess() |
| } |
| |
| void ProjectionMemberAccess() #void : {} |
| { |
| LOOKAHEAD(<LBRACKET>) ArrayAccess() |
| | |
| LOOKAHEAD(<QLBRACKET>) ArrayAccessSafe() |
| | |
| LOOKAHEAD(<DOT>) IdentifierAccess() |
| | |
| LOOKAHEAD(<QDOT>) IdentifierAccess() |
| } |
| |
| void ProjectionMethodCall() #void : {} |
| { |
| (ProjectionMemberAccess() (LOOKAHEAD(<LPAREN>) Arguments())+) #MethodNode(>1) |
| } |
| |
| void IteratorExpression() #void : {} |
| { |
| LOOKAHEAD(<LPAREN> Expression() <COLON>) <LPAREN> Expression() <COLON> Lambda() <RPAREN> #EnumerationNode(2) |
| | |
| ValueExpression() #EnumerationNode(1) |
| } |
| |
| void SwitchExpression() : {} |
| { |
| <SWITCH> <LPAREN> Expression() <RPAREN> <LCURLY> SwitchExpressionBlock() <RCURLY> |
| } |
| |
| void SwitchExpressionBlock() #void : {} |
| { |
| SwitchExpressionCase() (LOOKAHEAD(SwitchExpressionBlock()) SwitchExpressionBlock())* |
| | |
| SwitchExpressionDefault() (LOOKAHEAD(SwitchExpressionCase()) SwitchExpressionCase())* |
| } |
| |
| void SwitchExpressionCase() : {} |
| { |
| <CASE> SwitchExpressionCaseLabel() <LAMBDA> ((LOOKAHEAD(1) Block() | Statement()) )+ |
| } |
| |
| void SwitchExpressionCaseLabel() : {} |
| { |
| (Literal() | Identifier()) (<COMMA> (Literal() | Identifier()))* |
| } |
| |
| void SwitchExpressionDefault() : {} |
| { |
| <DCASE> <LAMBDA> ((LOOKAHEAD(1) Block() | Statement()) )+ |
| } |
| |
| /*************************************** |
| * Identifier & Literals |
| ***************************************/ |
| |
| void Identifier(boolean top) : |
| { |
| Token t; |
| } |
| { |
| t=<IDENTIFIER> { jjtThis.setSymbol(top? checkVariable(jjtThis, t.image) : t.image); if (top && isFinalVariable(t.image)) jjtThis.setFinal(); } |
| | |
| t=<REGISTER> { jjtThis.setSymbol(t.image); } |
| } |
| |
| void NamespaceIdentifier() #NamespaceIdentifier : |
| { |
| Token ns; |
| Token id; |
| } |
| { |
| ns=<IDENTIFIER> <COLON> id=<IDENTIFIER> { jjtThis.setNamespace(ns.image, id.image); } |
| } |
| |
| void StringIdentifier() #Identifier : |
| { |
| Token t; |
| } |
| { |
| t=<STRING_LITERAL> { jjtThis.setSymbol(Parser.buildString(t.image, true)); } |
| } |
| |
| void RemoveIdentifier() #Identifier : |
| { |
| Token t; |
| } |
| { |
| t=<REMOVE> { jjtThis.setSymbol(t.image); } |
| } |
| |
| void MethodReferenceIdentifier() #Identifier : |
| { |
| Token t; |
| } |
| { |
| t=<SIZE> { jjtThis.setSymbol(t.image); } |
| | |
| t=<EMPTY> { jjtThis.setSymbol(t.image); } |
| | |
| t=<REMOVE> { jjtThis.setSymbol(t.image); } |
| | |
| t=<NEW> { jjtThis.setSymbol(t.image); } |
| | |
| t=<FUNCTION> { jjtThis.setSymbol(t.image); } |
| | |
| t=<VAR> { jjtThis.setSymbol(t.image); } |
| | |
| t=<IDENTIFIER> { jjtThis.setSymbol(t.image); } |
| } |
| |
| void This() #void : {} |
| { |
| <THIS> #ThisNode |
| } |
| |
| void Literal() #void : |
| { |
| Token t; |
| } |
| { |
| IntegerLiteral() |
| | |
| FloatLiteral() |
| | |
| BooleanLiteral() |
| | |
| JxltLiteral() |
| | |
| StringLiteral() |
| | |
| RegexLiteral() |
| | |
| NaNLiteral() |
| } |
| |
| void NaNLiteral() #NumberLiteral : {} |
| { |
| <NAN_LITERAL> { jjtThis.setReal("NaN"); } |
| } |
| |
| void NullLiteral() : {} |
| { |
| <NULL> |
| } |
| |
| void BooleanLiteral() #void : {} |
| { |
| <TRUE> #TrueNode |
| | |
| <FALSE> #FalseNode |
| } |
| |
| void IntegerLiteral() #NumberLiteral : |
| { |
| Token t; |
| } |
| { |
| t=<INTEGER_LITERAL> |
| { jjtThis.setNatural(t.image); } |
| } |
| |
| void FloatLiteral() #NumberLiteral: |
| { |
| Token t; |
| } |
| { |
| t=<FLOAT_LITERAL> |
| { jjtThis.setReal(t.image); } |
| } |
| |
| void StringLiteral() : |
| { |
| Token t; |
| } |
| { |
| t=<STRING_LITERAL> |
| { jjtThis.setLiteral(Parser.buildString(t.image, true)); } |
| } |
| |
| void JxltLiteral() #JxltLiteral : |
| { |
| Token t; |
| } |
| { |
| t=<JXLT_LITERAL> |
| { jjtThis.setLiteral(Parser.buildString(t.image, true)); } |
| } |
| |
| void RegexLiteral() : |
| { |
| Token t; |
| } |
| { |
| t=<REGEX_LITERAL> |
| { jjtThis.setLiteral(Parser.buildRegex(t.image)); } |
| } |
| |
| void TypeReference() #ClassLiteral() : |
| { |
| Token t; |
| Class value; |
| } |
| { |
| (LOOKAHEAD(<LBRACKET>) <LBRACKET> <RBRACKET> { jjtThis.setArray(); })+ |
| | |
| ( |
| t=<QUALIFIED_IDENTIFIER> { value = Parser.resolveType(t.image); if (value == null) throwParsingException(jjtThis); jjtThis.setLiteral(value); } |
| | t=<INT> { jjtThis.setLiteral(Integer.TYPE); } |
| | t=<LONG> { jjtThis.setLiteral(Long.TYPE); } |
| | t=<SHORT> { jjtThis.setLiteral(Short.TYPE); } |
| | t=<BYTE> { jjtThis.setLiteral(Byte.TYPE); } |
| | t=<CHAR> { jjtThis.setLiteral(Character.TYPE); } |
| | t=<BOOLEAN> { jjtThis.setLiteral(Boolean.TYPE); } |
| | t=<FLOAT> { jjtThis.setLiteral(Float.TYPE); } |
| | t=<DOUBLE> { jjtThis.setLiteral(Double.TYPE); } |
| ) |
| (LOOKAHEAD(<LBRACKET>) <LBRACKET> <RBRACKET> { jjtThis.setArray(); })* |
| } |
| |
| void NewTypeReference() #ClassLiteral() : |
| { |
| Token t; |
| Class value; |
| } |
| { |
| t=<QUALIFIED_IDENTIFIER> |
| { value = Parser.resolveInstantiableType(t.image); if (value == null) throwParsingException(jjtThis); jjtThis.setLiteral(value); } |
| } |
| |
| void ArrayTypeReference() #void : {} |
| { |
| PrimitiveType() |
| | |
| ObjectType() |
| } |
| |
| void ObjectType() #ClassLiteral() : |
| { |
| Token t; |
| Class value; |
| } |
| { |
| t=<QUALIFIED_IDENTIFIER> |
| { value = Parser.resolveType(t.image); if (value == null) throwParsingException(jjtThis); jjtThis.setLiteral(value); } |
| } |
| |
| void InnerType() #Identifier() : |
| { |
| Token t; |
| } |
| { |
| t=<QUALIFIED_IDENTIFIER> { jjtThis.setSymbol(t.image); } |
| } |
| |
| void PrimitiveType() #ClassLiteral() : |
| { |
| Token t; |
| } |
| { |
| LOOKAHEAD(1) t=<INT> { jjtThis.setLiteral(Integer.TYPE); } |
| | LOOKAHEAD(1) t=<LONG> { jjtThis.setLiteral(Long.TYPE); } |
| | LOOKAHEAD(1) t=<SHORT> { jjtThis.setLiteral(Short.TYPE); } |
| | LOOKAHEAD(1) t=<BYTE> { jjtThis.setLiteral(Byte.TYPE); } |
| | LOOKAHEAD(1) t=<CHAR> { jjtThis.setLiteral(Character.TYPE); } |
| | LOOKAHEAD(1) t=<BOOLEAN> { jjtThis.setLiteral(Boolean.TYPE); } |
| | LOOKAHEAD(1) t=<FLOAT> { jjtThis.setLiteral(Float.TYPE); } |
| | LOOKAHEAD(1) t=<DOUBLE> { jjtThis.setLiteral(Double.TYPE); } |
| } |
| |
| void EmptyListLiteral() #ArrayLiteral() : {} |
| { |
| <LBRACKET> <ELLIPSIS> { jjtThis.setExtended(true); } <RBRACKET> |
| } |
| |
| void ArrayLiteral() : {} |
| { |
| <LBRACKET> |
| (Expression() (LOOKAHEAD(<COMMA> Expression()) <COMMA> Expression() )*)? (LOOKAHEAD(2) <COMMA> <ELLIPSIS> { jjtThis.setExtended(true); })? |
| <RBRACKET> |
| } |
| |
| void ImmutableArrayLiteral() #ArrayLiteral() : {} |
| { |
| <HBRACKET> (Expression() (LOOKAHEAD(<COMMA> Expression()) <COMMA> Expression() )*)? <RBRACKET> { jjtThis.setImmutable(true); } |
| } |
| |
| void MapLiteral() : {} |
| { |
| <LCURLY> |
| ( |
| <COLON> |
| | |
| MapElement() ( <COMMA> MapElement() )* |
| ) <RCURLY> |
| } |
| |
| void MapElement() #void : {} |
| { |
| LOOKAHEAD(<mult> <COLON> <ELLIPSIS>) <mult> <COLON> <ELLIPSIS> ValueExpression() #MapEnumerationNode(1) |
| | |
| MapEntry() |
| } |
| |
| void MapEntry() : {} |
| { |
| Expression() <COLON> Expression() |
| } |
| |
| void MapEntryLiteral() : {} |
| { |
| <LBRACKET> Expression() <COLON> Expression() <RBRACKET> |
| } |
| |
| void ImmutableMapLiteral() #MapLiteral() : {} |
| { |
| <HCURLY> |
| ( |
| <COLON> |
| | |
| MapElement() ( <COMMA> MapElement() )* |
| ) <RCURLY> { jjtThis.setImmutable(true); } |
| } |
| |
| void SetLiteral() : {} |
| { |
| <LCURLY> (Expression() ( <COMMA> Expression() )*)? <RCURLY> |
| } |
| |
| void ImmutableSetLiteral() #SetLiteral : {} |
| { |
| <HCURLY> (Expression() ( <COMMA> Expression() )*)? <RCURLY> { jjtThis.setImmutable(true); } |
| } |
| |
| /*************************************** |
| * Functions & Methods |
| ***************************************/ |
| |
| void Arguments() #Arguments : {} |
| { |
| <LPAREN> (Expression() (<COMMA> Expression())* )? <RPAREN> |
| } |
| |
| void FunctionCallLookahead() #void : {} |
| { |
| LOOKAHEAD(2) <IDENTIFIER> <COLON> <IDENTIFIER> <LPAREN> |
| | |
| LOOKAHEAD(2) <IDENTIFIER> <LPAREN> |
| | |
| LOOKAHEAD(2) <REGISTER> <LPAREN> |
| | |
| LOOKAHEAD(2) <REMOVE> <LPAREN> |
| } |
| |
| void FunctionCall() #void : {} |
| { |
| LOOKAHEAD(2) NamespaceIdentifier() Arguments() #FunctionNode(2) |
| | |
| LOOKAHEAD(2) Identifier(true) Arguments() #FunctionNode(2) |
| | |
| LOOKAHEAD(2) RemoveIdentifier() Arguments() #FunctionNode(2) |
| } |
| |
| void Constructor() #void : {} |
| { |
| <NEW> |
| ( |
| LOOKAHEAD(<LPAREN>) ForNameConstructor() |
| | |
| LOOKAHEAD(<QUALIFIED_IDENTIFIER> <LPAREN>) QualifiedConstructor() |
| | |
| LOOKAHEAD(ArrayTypeReference() <LBRACKET> <RBRACKET>) InitializedArrayConstructor() |
| | |
| LOOKAHEAD(ArrayTypeReference() <LBRACKET>) ArrayConstructor() |
| ) |
| } |
| |
| void ForNameConstructor() #ConstructorNode() : {} |
| { |
| <LPAREN> [ Expression() ( <COMMA> Expression() )* ] <RPAREN> |
| } |
| |
| void QualifiedConstructor() #QualifiedConstructorNode() : {} |
| { |
| NewTypeReference() Arguments() |
| } |
| |
| void ArrayConstructor() #ArrayConstructorNode() : {} |
| { |
| ArrayTypeReference() (LOOKAHEAD(2) ArrayQualifiedDimension())+ (LOOKAHEAD(2) ArrayOpenDimension())* |
| } |
| |
| void ArrayQualifiedDimension() #void : {} |
| { |
| <LBRACKET> Expression() <RBRACKET> |
| } |
| |
| void ArrayOpenDimension() : {} |
| { |
| <LBRACKET> <RBRACKET> |
| } |
| |
| void InitializedArrayConstructor() #InitializedArrayConstructorNode() : {} |
| { |
| ArrayTypeReference() <LBRACKET> <RBRACKET> InitializedArrayLiteral() |
| } |
| |
| void InitializedArrayLiteral() #void() : {} |
| { |
| <LCURLY> [ Expression() ( <COMMA> Expression() )* ] <RCURLY> |
| } |
| |
| void Parameter() #void : |
| { |
| Token t; |
| } |
| { |
| t=<IDENTIFIER> { declareParameter(t); } |
| } |
| |
| void VarParameter() #void : |
| { |
| Token t; |
| Class type = null; |
| boolean isFinal = false; |
| boolean isRequired = false; |
| } |
| { |
| ( <FINAL> { isFinal = true; } )? |
| ( <VAR> ( <and> { isRequired = true; } )? |
| | <INT> { type = Integer.TYPE; } |
| | <LONG> { type = Long.TYPE; } |
| | <SHORT> { type = Short.TYPE; } |
| | <BYTE> { type = Byte.TYPE; } |
| | <CHAR> { type = Character.TYPE; } |
| | <BOOLEAN> { type = Boolean.TYPE; } |
| | <FLOAT> { type = Float.TYPE; } |
| | <DOUBLE> { type = Double.TYPE; } |
| ) |
| t=<IDENTIFIER> { declareParameter(t, type, isFinal, isRequired); } |
| } |
| |
| void Parameters() #void : {} |
| { |
| <LPAREN> [ |
| (LOOKAHEAD(<FINAL> | <VAR> | <BYTE> | <SHORT> | <INT> | <LONG> | <FLOAT> | <DOUBLE> | <BOOLEAN> | <CHAR> ) VarParameter() (<COMMA> VarParameter())* |
| | |
| Parameter() (<COMMA> Parameter())*) |
| (<ELLIPSIS> { declareVarArgSupport(); })? |
| ] <RPAREN> |
| } |
| |
| void LambdaLookahead() #void() : {} |
| { |
| LOOKAHEAD(2) <FUNCTION> Parameters() |
| | |
| LOOKAHEAD(2) <FUNCTION> <LCURLY> |
| | |
| Parameters() ( <LAMBDA> | <LAMBDAE> ) |
| | |
| Parameter() ( <LAMBDA> | <LAMBDAE> ) |
| } |
| |
| void Lambda() #JexlLambda() : |
| { |
| pushFrame(); |
| } |
| { |
| LOOKAHEAD(2) <FUNCTION> Parameters() Block() |
| | |
| LOOKAHEAD(2) <FUNCTION> Block() |
| | |
| Parameters() ( <LAMBDA> Block() | <LAMBDAE> Expression() ) |
| | |
| Parameter() ( <LAMBDA> Block() | <LAMBDAE> Expression() ) |
| } |
| |
| |
| |
| /*************************************** |
| * References |
| ***************************************/ |
| |
| Token dotName() #void : |
| { |
| Token t ; |
| } |
| { |
| ( t = <DOT_IDENTIFIER> | t=<IF> | t=<ELSE> | t=<FOR> | t=<WHILE> | t=<DO> |
| | t=<TRY> | t=<CATCH> | t=<THROW> | t=<ASSERT> | t=<SYNCHRONIZED> | t=<REMOVE> | t=<THIS> |
| | t=<CHAR> | t=<BOOLEAN> | t=<BYTE> | t=<SHORT> | t=<INT> | t=<LONG> | t=<FLOAT> | t=<DOUBLE> |
| | t=<SWITCH> | t=<CASE> | t=<DCASE> | t=<FINAL> | t=<IN> | t=<iof> |
| | t=<NEW>| t=<EMPTY> | t=<SIZE> | t=<TRUE> | t=<FALSE> | t=<NULL> |
| | t=<_OR> | t=<_AND>| t=<NOT> | t=<NE> | t=<EQ> | t=<GT> | t=<GE> | t=<LT> | t=<LE> |
| | t=<VAR> | t=<FUNCTION> ) { return t ;} |
| } |
| |
| void IdentifierAccess() #void : |
| { |
| Token t; |
| } |
| { |
| <DOT> ( |
| t=dotName() { jjtThis.setIdentifier(t.image); } #IdentifierAccess |
| | |
| t=<STRING_LITERAL> { jjtThis.setIdentifier(Parser.buildString(t.image, true)); } #IdentifierAccess |
| | |
| t=<JXLT_LITERAL> { jjtThis.setIdentifier(Parser.buildString(t.image, true)); } #IdentifierAccessJxlt |
| ) |
| | |
| <QDOT> ( |
| t=dotName() { jjtThis.setIdentifier(t.image); } #IdentifierAccessSafe |
| | |
| t=<STRING_LITERAL> { jjtThis.setIdentifier(Parser.buildString(t.image, true)); } #IdentifierAccessSafe |
| | |
| t=<JXLT_LITERAL> { jjtThis.setIdentifier(Parser.buildString(t.image, true)); } #IdentifierAccessSafeJxlt |
| ) |
| } |
| |
| void ArrayAccess() : {} |
| { |
| <LBRACKET> Expression() ( <COMMA> Expression() )* <RBRACKET> |
| } |
| |
| void ArrayAccessSafe() : {} |
| { |
| <QLBRACKET> Expression() ( <COMMA> Expression() )* <RBRACKET> |
| } |
| |
| void ReferenceExpression() #MethodNode(>1) : {} |
| { |
| ( <LPAREN> ( |
| LOOKAHEAD(Expression()) Expression() | Block() |
| ) <RPAREN> #ReferenceExpression(1) ) ( LOOKAHEAD(<LPAREN>) Arguments() )* |
| } |
| |
| void PrimaryExpression() #void : {} |
| { |
| LOOKAHEAD( LambdaLookahead() ) Lambda() |
| | |
| LOOKAHEAD( <LCURLY> MapElement() ) MapLiteral() |
| | |
| LOOKAHEAD( <LCURLY> <COLON>) MapLiteral() |
| | |
| LOOKAHEAD( <HCURLY> MapElement() ) ImmutableMapLiteral() |
| | |
| LOOKAHEAD( <HCURLY> <COLON>) ImmutableMapLiteral() |
| | |
| LOOKAHEAD( <LCURLY> Expression() (<COMMA> | <RCURLY>)) SetLiteral() |
| | |
| LOOKAHEAD( <LCURLY> <RCURLY> ) SetLiteral() |
| | |
| LOOKAHEAD( <HCURLY> Expression() (<COMMA> | <RCURLY>)) ImmutableSetLiteral() |
| | |
| LOOKAHEAD( <HCURLY> <RCURLY> ) ImmutableSetLiteral() |
| | |
| LOOKAHEAD( EmptyListLiteral() ) EmptyListLiteral() |
| | |
| LOOKAHEAD( <LBRACKET> Expression() <COLON> ) MapEntryLiteral() |
| | |
| LOOKAHEAD( <LBRACKET> ) ArrayLiteral() |
| | |
| LOOKAHEAD( <HBRACKET> ) ImmutableArrayLiteral() |
| | |
| LOOKAHEAD( <NEW> ) Constructor() |
| | |
| LOOKAHEAD( <SWITCH> ) SwitchExpression() |
| | |
| LOOKAHEAD( FunctionCallLookahead() ) FunctionCall() |
| | |
| LOOKAHEAD( <LPAREN> ) ReferenceExpression() |
| | |
| Identifier(true) |
| | |
| This() |
| | |
| Literal() |
| } |
| |
| void MemberAccess() #void : {} |
| { |
| LOOKAHEAD(<LBRACKET>) ArrayAccess() |
| | |
| LOOKAHEAD(<QLBRACKET>) ArrayAccessSafe() |
| | |
| LOOKAHEAD(<DOT> | <QDOT>) IdentifierAccess() |
| | |
| LOOKAHEAD(<LCURLY>) InlinePropertyAssignment() |
| } |
| |
| void MethodCall() #void : {} |
| { |
| LOOKAHEAD(<DOT> <NEW>) (<DOT> <NEW> InnerType() Arguments()) #InnerConstructorNode() |
| | |
| (MemberAccess() (LOOKAHEAD(<LPAREN>) Arguments())+) #MethodNode(>1) |
| } |
| |
| void MemberExpression() #void : {} |
| { |
| LOOKAHEAD(MethodCall()) MethodCall() |
| | |
| MemberAccess() |
| } |
| |
| void MethodReference() : {} |
| { |
| <DCOLON> MethodReferenceIdentifier() |
| } |
| |
| void InlinePropertyAssignment() : {} |
| { |
| <LCURLY> (InlinePropertyBlock() ( <COMMA> InlinePropertyBlock() )* ) <RCURLY> |
| } |
| |
| void InlineMemberAccess() #void : {} |
| { |
| LOOKAHEAD(<LBRACKET>) ArrayAccess() |
| | |
| LOOKAHEAD(<DOT>) IdentifierAccess() |
| } |
| |
| void InlinePropertyBlock() #void : {} |
| { |
| LOOKAHEAD(InlinePropertyName() <COLON>) InlinePropertyEntry() |
| | |
| LOOKAHEAD(InlinePropertyName() <ELVIS>) InlinePropertyNullEntry() |
| | |
| LOOKAHEAD(<LBRACKET> Expression() <RBRACKET> <COLON>) InlinePropertyArrayEntry() |
| | |
| LOOKAHEAD(<LBRACKET> Expression() <RBRACKET> <ELVIS>) InlinePropertyArrayNullEntry() |
| | |
| ((LOOKAHEAD(<LBRACKET>) ArrayAccess() | Identifier()) (LOOKAHEAD(2) InlineMemberAccess() )* InlinePropertyAssignment()) #Reference() |
| } |
| |
| void InlinePropertyName() #void : {} |
| { |
| Identifier() |
| | |
| StringLiteral() |
| | |
| JxltLiteral() |
| } |
| |
| void InlinePropertyEntry() : {} |
| { |
| InlinePropertyName() <COLON> Expression() |
| } |
| |
| void InlinePropertyNullEntry() : {} |
| { |
| InlinePropertyName() <ELVIS> Expression() |
| } |
| |
| void InlinePropertyArrayEntry() : {} |
| { |
| <LBRACKET> Expression() <RBRACKET> <COLON> Expression() |
| } |
| |
| void InlinePropertyArrayNullEntry() : {} |
| { |
| <LBRACKET> Expression() <RBRACKET> <ELVIS> Expression() |
| } |
| |
| void ValueExpression() #void : {} |
| { |
| NullLiteral() |
| | |
| ( PrimaryExpression() ( LOOKAHEAD(2) MemberExpression() )* [LOOKAHEAD(2) MethodReference()] ) #Reference(>1) |
| } |