public FormulaError(FormulaNode node, String message) { this(node.getSourceRange(), message); }
private FunctionCallNode binaryInfixCall(FormulaFunction op, FormulaNode left, FormulaNode right) { SourceRange source = new SourceRange(left.getSourceRange(), right.getSourceRange()); return new FunctionCallNode(op, Arrays.asList(left, right), source); }
private FieldType validateFunctionCall(FunctionCallNode call) { // If function calls are involved, this is no longer // a simple field reference this.simpleReference = false; List<FormulaNode> arguments = call.getArguments(); List<FieldType> argumentTypes = new ArrayList<>(); boolean validationFailed = false; for (FormulaNode formulaNode : arguments) { try { argumentTypes.add(validateExpr(formulaNode)); } catch (ValidationFailed e) { // Continue validating the other arguments. validationFailed = true; } } if(validationFailed) { throw new ValidationFailed(); } try { return call.getFunction().resolveResultType(argumentTypes); } catch (ArgumentException e) { errors.add(new FormulaError(arguments.get(e.getArgumentIndex()).getSourceRange(), e.getMessage())); throw new ValidationFailed(); } catch(FormulaException e) { errors.add(new FormulaError(call, e.getMessage())); throw new ValidationFailed(); } }
references.add(new FieldReference(formulaNode.getSourceRange(), match));
private FormulaNode unary() { // <unary> ::= + <unary> | - <unary> | <unary2> if(!lexer.hasNext()) { throw new FormulaSyntaxException("Unexpected end of formula"); } Token token = lexer.peek(); if(token.getType() == TokenType.OPERATOR) { if(token.getString().equals("-") || token.getString().equals("+")) { Token opToken = lexer.next(); FormulaFunction op = function(opToken); FormulaNode operand = unary(); SourceRange sourceRange = new SourceRange(opToken.getStart(), operand.getSourceRange().getEnd()); return new FunctionCallNode(op, singletonList(operand), sourceRange); } } return unary2(); }
private FormulaNode unary2() { if(!lexer.hasNext()) { throw new FormulaSyntaxException("Unexpected end of formula"); } Token token = lexer.peek(); if(token.getType() == TokenType.OPERATOR) { if(token.getString().equals("!")) { Token opToken = lexer.next(); FormulaFunction op = function(opToken); FormulaNode operand = primary(); SourceRange sourceRange = new SourceRange(opToken.getStart(), operand.getSourceRange().getEnd()); return new FunctionCallNode(op, singletonList(operand), sourceRange); } } return primary(); }
private FormulaNode compound(SymbolNode symbol) { FormulaNode result = symbol; while(lexer.hasNext() && lexer.peek().isDot()) { lexer.next(); SymbolNode field = symbol(); result = new CompoundExpr(result, field, new SourceRange(result.getSourceRange(), field.getSourceRange())); } return result; }
@Test public void symbolSourceRefs() { FunctionCallNode call = (FunctionCallNode) FormulaParser.parse("[A] + [B]"); assertThat(call.getSourceRange(), equalTo(new SourceRange(new SourcePos(0, 0), new SourcePos(0, 9)))); assertThat(call.getArgument(1).getSourceRange(), equalTo(new SourceRange(new SourcePos(0, 6), new SourcePos(0, 9)))); }