From 0fb5c7850dcf343b3b5929e9fe916125e771f916 Mon Sep 17 00:00:00 2001 From: dennis Date: Fri, 22 Nov 2019 15:17:48 +0800 Subject: [PATCH] (fix) issue #177, parser bug --- .../aviator/code/OptimizeCodeGenerator.java | 31 ++----------------- .../aviator/parser/ExpressionParser.java | 31 ++++++++++++++++++- .../test/function/GrammarUnitTest.java | 5 +++ 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/googlecode/aviator/code/OptimizeCodeGenerator.java b/src/main/java/com/googlecode/aviator/code/OptimizeCodeGenerator.java index 932c35fa..5f10bfd1 100644 --- a/src/main/java/com/googlecode/aviator/code/OptimizeCodeGenerator.java +++ b/src/main/java/com/googlecode/aviator/code/OptimizeCodeGenerator.java @@ -42,6 +42,7 @@ import com.googlecode.aviator.lexer.token.Token.TokenType; import com.googlecode.aviator.lexer.token.Variable; import com.googlecode.aviator.parser.AviatorClassLoader; +import com.googlecode.aviator.parser.ExpressionParser; import com.googlecode.aviator.parser.Parser; import com.googlecode.aviator.runtime.FunctionArgument; import com.googlecode.aviator.runtime.LambdaFunctionBootstrap; @@ -236,32 +237,6 @@ private boolean isLiteralOperand(final Token token, final TokenType tokenType } - private boolean isLiteralToken(final Token token) { - switch (token.getType()) { - case Variable: - return token == Variable.TRUE || token == Variable.FALSE || token == Variable.NIL; - case Char: - case Number: - case Pattern: - case String: - return true; - default: - return false; - } - } - - private boolean isConstant(final Token token) { - switch (token.getType()) { - case Number: - case Pattern: - case String: - return true; - default: - return false; - } - } - - /** * Get token from executing result * @@ -372,7 +347,7 @@ public Expression getResult() { Set> constants = new HashSet<>(); for (Token token : this.tokenList) { - if (isConstant(token)) { + if (ExpressionParser.isConstant(token)) { constants.add(token); } @@ -424,7 +399,7 @@ public Expression getResult() { exp = new LiteralExpression(this.instance, null, new ArrayList(variables.keySet())); } else { final Token lastToken = this.tokenList.get(0); - if (isLiteralToken(lastToken)) { + if (ExpressionParser.isLiteralToken(lastToken)) { exp = new LiteralExpression(this.instance, getAviatorObjectFromToken(lastToken).getValue(null), new ArrayList(variables.keySet())); diff --git a/src/main/java/com/googlecode/aviator/parser/ExpressionParser.java b/src/main/java/com/googlecode/aviator/parser/ExpressionParser.java index 7f0b2d88..aea904c8 100644 --- a/src/main/java/com/googlecode/aviator/parser/ExpressionParser.java +++ b/src/main/java/com/googlecode/aviator/parser/ExpressionParser.java @@ -457,8 +457,12 @@ public void unary() { factor(); } - // FIXME: it's a parser bug here + while (expectChar('[') || expectChar('(')) { + if (isConstant(this.prevToken)) { + break; + } + if (expectChar('[')) { // (...)[index] arrayAccess(); @@ -893,4 +897,29 @@ private void ensureDepthState() { } } + public static boolean isConstant(final Token token) { + switch (token.getType()) { + case Number: + case Pattern: + case String: + return true; + default: + return false; + } + } + + public static boolean isLiteralToken(final Token token) { + switch (token.getType()) { + case Variable: + return token == Variable.TRUE || token == Variable.FALSE || token == Variable.NIL; + case Char: + case Number: + case Pattern: + case String: + return true; + default: + return false; + } + } + } diff --git a/src/test/java/com/googlecode/aviator/test/function/GrammarUnitTest.java b/src/test/java/com/googlecode/aviator/test/function/GrammarUnitTest.java index e29c06dd..31b279f2 100644 --- a/src/test/java/com/googlecode/aviator/test/function/GrammarUnitTest.java +++ b/src/test/java/com/googlecode/aviator/test/function/GrammarUnitTest.java @@ -64,6 +64,11 @@ public void testIssue162() { assertEquals(new BigInteger("-2017122615550747128008704"), val); } + @Test(expected = ExpressionSyntaxErrorException.class) + public void testIssue177() { + AviatorEvaluator.compile("$age >30 ($age < 20)"); + } + @Test public void testIssue175() { Map env = new HashMap<>();