private FormulaNode call(Token functionToken) { FormulaFunction function = function(functionToken); expect(TokenType.PAREN_START); List<FormulaNode> arguments = new ArrayList<>(); while(true) { if (!lexer.hasNext()) { throw new FormulaSyntaxException("Unexpected end of formula"); } TokenType nextToken = lexer.peek().getType(); if (nextToken == TokenType.COMMA) { // Consume comma and parse next argument lexer.next(); continue; } if (nextToken == TokenType.PAREN_END) { // consume paren and complete argument list Token closingParen = lexer.next(); return new FunctionCallNode(function, arguments, new SourceRange(functionToken, closingParen)); } // Otherwise parse the next argument arguments.add(expression()); } }
private FormulaNode primary() { switch (lexer.peek().getType()) { case SYMBOL: if(lexer.peek().getString().matches("t\\d{10}")) { return enumLiteral(); } else { return symbolOrCall(); } case NUMBER: return number(); case BOOLEAN_LITERAL: return booleanLiteral(); case STRING_LITERAL: return stringLiteral(); case PAREN_START: Token openToken = lexer.next(); FormulaNode e = expression(); Token closeToken = expect(TokenType.PAREN_END); return new GroupNode(e, new SourceRange(openToken, closeToken)); default: throw new FormulaSyntaxException(new SourceRange(lexer.peek()), "Expected a symbol, a number, a string, or '('"); } }