private boolean isSymbolChar(char c) { return c == '_' || isAlphabetic(c) || Character.isDigit(c); }
private Token readNumber() { while (!isEndOfInput() && isNumberPart(peekChar())) { consumeChar(); } return finishToken(TokenType.NUMBER); }
public List<Token> readAll() { List<Token> tokens = Lists.newArrayList(); while (!isEndOfInput()) { tokens.add(next()); } return tokens; }
private Token readWhitespace() { while (!isEndOfInput() && isWhitespace(peekChar())) { consumeChar(); } return finishToken(TokenType.WHITESPACE); }
private Token readSymbol(TokenType tokenType) { while (!isEndOfInput() && isSymbolChar(peekChar())) { consumeChar(); } return finishToken(tokenType); }
@Override public Token next() { char c = nextChar(); if (c == '(') { return finishToken(TokenType.PAREN_START); return finishToken(TokenType.PAREN_END); return readQuotedToken(TokenType.SYMBOL, '}'); return readQuotedToken(TokenType.SYMBOL, ']'); return finishToken(TokenType.COMMA); return finishToken(TokenType.DOT); return readQuotedToken(TokenType.STRING_LITERAL, DOUBLE_QUOTE); return readQuotedToken(TokenType.STRING_LITERAL, SINGLE_QUOTE); } else if (isWhitespace(c)) { return readWhitespace(); } else if (isNumberPart(c)) { return readNumber(); } else if (isOperator(c)) { return readOperator(c); } else if (isBooleanLiteral(c)) {
public static FormulaNode parse(String expression) { if(Strings.isNullOrEmpty(expression)) { return new ConstantNode((String)null); } FormulaLexer lexer = new FormulaLexer(expression); FormulaParser parser = new FormulaParser(lexer); return parser.parse(); } }
private Token readOperator(char c) { while (!isEndOfInput() && isOperator(peekChar())) { consumeChar(); } return finishToken(TokenType.OPERATOR); }
private void expect(String string, Token... tokens) { System.out.println("Tokenizing [" + string + "]"); FormulaLexer tokenizer = new FormulaLexer(string); int expectedIndex = 0; while (!tokenizer.isEndOfInput()) { String expectedString; Token expected; if(expectedIndex < tokens.length) { expected = tokens[expectedIndex]; expectedString = expected.toString(); } else { expected = null; expectedString = "<NOTHING>"; } Token actual = tokenizer.next(); System.out.println(String.format("Expected: %15s, got %s", expectedString, actual.toString())); if(expected != null) { assertEquals("tokenStart", expected.getTokenStartColumn(), actual.getTokenStartColumn()); assertEquals("text", expected.getString(), actual.getString()); assertEquals("type", expected.getType(), actual.getType()); if (!expected.equals(actual)) { System.err.println("Unexpected result!"); throw new AssertionError(); } } expectedIndex ++; } }
private Token readQuotedToken(TokenType type, char closingQuote) throws FormulaSyntaxException { while(true) { if (isEndOfInput()) { throw new FormulaSyntaxException("End of input reached while looking for closing '" + closingQuote + ""); } if (nextChar() == closingQuote) { return finishToken(type, string.substring(currentTokenStart+1, currentCharIndex-1)); } } }
@Override public boolean hasNext() { return !isEndOfInput(); }
private Token readBooleanLiteral(char c) { if (c == 't' || c == 'T') { consumeChars(Boolean.TRUE.toString().length() - 1); } else { consumeChars(Boolean.FALSE.toString().length() - 1); } return finishToken(TokenType.BOOLEAN_LITERAL); }
private void consumeChars(int count) { while(count > 0) { consumeChar(); count--; } }
private Token finishToken(TokenType type) { return finishToken(type, string.substring(currentTokenStart, currentCharIndex)); }
private FormulaNode parse(String string) { System.out.println("Parsing [" + string + "]"); FormulaLexer lexer = new FormulaLexer(string); FormulaParser parser = new FormulaParser(lexer); return parser.parse(); }
private char nextChar() { return consumeChar(); }
private String validateExpression(String value) { try { FormulaLexer lexer = new FormulaLexer(value); FormulaParser parser = new FormulaParser(lexer); FormulaNode expr = parser.parse(); // expr node is created, expression is parsable // try to check variable names List<SymbolNode> placeholderExprList = Lists.newArrayList(); gatherPlaceholderExprs(expr, placeholderExprList); List<String> existingIndicatorCodes = existingIndicatorCodes(); for (SymbolNode placeholderExpr : placeholderExprList) { if (!existingIndicatorCodes.contains(placeholderExpr.getName())) { return I18N.MESSAGES.doesNotExist(placeholderExpr.getName()); } } return null; } catch (FormulaSyntaxException e) { return e.getMessage(); } catch (Exception ignored) { return constants.calculationExpressionIsInvalid(); } }
@Test public void isAlphabetic() { assertThat(FormulaLexer.isAlphabetic('a'), Matchers.equalTo(true)); assertThat(FormulaLexer.isAlphabetic('A'), Matchers.equalTo(true)); assertThat(FormulaLexer.isAlphabetic('1'), Matchers.equalTo(true)); assertThat(FormulaLexer.isAlphabetic('4'), Matchers.equalTo(true)); assertThat(FormulaLexer.isAlphabetic('_'), Matchers.equalTo(false)); assertThat(FormulaLexer.isAlphabetic('*'), Matchers.equalTo(false)); }
private void evaluate(String exprString, boolean expectedValue) { FormulaLexer lexer = new FormulaLexer(exprString); FormulaParser parser = new FormulaParser(lexer); FormulaNode expr = parser.parse(); FieldValue result = expr.evaluate(EmptyEvalContext.INSTANCE); assertThat(exprString, Casting.toBoolean(result), equalTo(expectedValue)); }
private void validateExpression() { String expression = expressionTextBox.getValue(); if(Strings.isNullOrEmpty(expression)) { expressionGroup.setShowValidationMessage(false); expressionGroup.validationStateType(ValidationStateType.NONE); return; } try { FormulaLexer lexer = new FormulaLexer(expression); FormulaParser parser = new FormulaParser(lexer); FormulaNode expr = parser.parse(); } catch (Exception e) { expressionGroup.setShowValidationMessage(true); expressionGroup.setValidationMessage(I18N.CONSTANTS.calculationExpressionIsInvalid()); expressionGroup.validationStateType(ValidationStateType.ERROR); return; } // Ok expressionGroup.setShowValidationMessage(false); expressionGroup.validationStateType(ValidationStateType.SUCCESS); } }