@Override public BigInteger visitArithmeticBinary(ArithmeticBinaryContext ctx) { BigInteger left = visit(ctx.left); BigInteger right = visit(ctx.right); switch (ctx.operator.getType()) { case PLUS: return left.add(right); case MINUS: return left.subtract(right); case ASTERISK: return left.multiply(right); case SLASH: return left.divide(right); default: throw new IllegalStateException("Unsupported binary operator " + ctx.operator.getText()); } }
@Override public BigInteger visitArithmeticUnary(ArithmeticUnaryContext ctx) { BigInteger value = visit(ctx.expression()); switch (ctx.operator.getType()) { case PLUS: return value; case MINUS: return value.negate(); default: throw new IllegalStateException("Unsupported unary operator " + ctx.operator.getText()); } }
@Override public BigInteger visitBinaryFunction(BinaryFunctionContext ctx) { BigInteger left = visit(ctx.left); BigInteger right = visit(ctx.right); switch (ctx.binaryFunctionName().name.getType()) { case MIN: return left.min(right); case MAX: return left.max(right); default: throw new IllegalArgumentException("Unsupported binary function " + ctx.binaryFunctionName().getText()); } }
@Override public OptionalLong visitArithmeticBinary(ArithmeticBinaryContext ctx) { OptionalLong left = visit(ctx.left); OptionalLong right = visit(ctx.right); if (!left.isPresent() || !right.isPresent()) { return OptionalLong.empty(); } switch (ctx.operator.getType()) { case PLUS: return OptionalLong.of(left.getAsLong() + right.getAsLong()); case MINUS: return OptionalLong.of(left.getAsLong() - right.getAsLong()); case ASTERISK: return OptionalLong.of(left.getAsLong() * right.getAsLong()); case SLASH: return OptionalLong.of(left.getAsLong() / right.getAsLong()); default: throw new IllegalStateException("Unsupported binary operator " + ctx.operator.getText()); } }
@Override public BigInteger visitArithmeticBinary(ArithmeticBinaryContext ctx) { BigInteger left = visit(ctx.left); BigInteger right = visit(ctx.right); switch (ctx.operator.getType()) { case PLUS: return left.add(right); case MINUS: return left.subtract(right); case ASTERISK: return left.multiply(right); case SLASH: return left.divide(right); default: throw new IllegalStateException("Unsupported binary operator " + ctx.operator.getText()); } }
@Override public OptionalLong visitBinaryFunction(BinaryFunctionContext ctx) { OptionalLong left = visit(ctx.left); OptionalLong right = visit(ctx.right); if (!left.isPresent() || !right.isPresent()) { return OptionalLong.empty(); } switch(ctx.binaryFunctionName().name.getType()) { case MIN: return OptionalLong.of(Math.min(left.getAsLong(), right.getAsLong())); case MAX: return OptionalLong.of(Math.max(left.getAsLong(), right.getAsLong())); default: throw new IllegalArgumentException("Unsupported binary function " + ctx.binaryFunctionName().getText()); } }
@Override public OptionalLong visitArithmeticUnary(ArithmeticUnaryContext ctx) { OptionalLong value = visit(ctx.expression()); if (!value.isPresent()) { return OptionalLong.empty(); } switch (ctx.operator.getType()) { case PLUS: return value; case MINUS: return OptionalLong.of(-value.getAsLong()); default: throw new IllegalStateException("Unsupported unary operator " + ctx.operator.getText()); } }
public static OptionalLong calculateLiteralValue( String calculation, Map<String, OptionalLong> inputs, boolean allowComplexExpression) { try { ParserRuleContext tree = parseTypeCalculation(calculation); if (!allowComplexExpression && !isSimpleExpression(tree)) { throw new IllegalArgumentException(format("Complex expressions not allowed, but got [%s]", calculation)); } return new CalculateTypeVisitor(inputs).visit(tree); } catch (StackOverflowError e) { throw new ParsingException("Type calculation is too large (stack overflow while parsing)"); } }
@Override public BigInteger visitBinaryFunction(BinaryFunctionContext ctx) { BigInteger left = visit(ctx.left); BigInteger right = visit(ctx.right); switch (ctx.binaryFunctionName().name.getType()) { case MIN: return left.min(right); case MAX: return left.max(right); default: throw new IllegalArgumentException("Unsupported binary function " + ctx.binaryFunctionName().getText()); } }
public static Long calculateLiteralValue( String calculation, Map<String, Long> inputs) { try { ParserRuleContext tree = parseTypeCalculation(calculation); CalculateTypeVisitor visitor = new CalculateTypeVisitor(inputs); BigInteger result = visitor.visit(tree); return result.longValueExact(); } catch (StackOverflowError e) { throw new ParsingException("Type calculation is too large (stack overflow while parsing)"); } }
@Override public BigInteger visitArithmeticUnary(ArithmeticUnaryContext ctx) { BigInteger value = visit(ctx.expression()); switch (ctx.operator.getType()) { case PLUS: return value; case MINUS: return value.negate(); default: throw new IllegalStateException("Unsupported unary operator " + ctx.operator.getText()); } }
@Override public OptionalLong visitTypeCalculation(TypeCalculationContext ctx) { return visit(ctx.expression()); }
@Override public OptionalLong visitParenthesizedExpression(ParenthesizedExpressionContext ctx) { return visit(ctx.expression()); } }
@Override public BigInteger visitTypeCalculation(TypeCalculationContext ctx) { return visit(ctx.expression()); }
@Override public BigInteger visitParenthesizedExpression(ParenthesizedExpressionContext ctx) { return visit(ctx.expression()); } }
public static Long calculateLiteralValue( String calculation, Map<String, Long> inputs) { try { ParserRuleContext tree = parseTypeCalculation(calculation); CalculateTypeVisitor visitor = new CalculateTypeVisitor(inputs); BigInteger result = visitor.visit(tree); return result.longValueExact(); } catch (StackOverflowError e) { throw new ParsingException("Type calculation is too large (stack overflow while parsing)"); } }
@Override public BigInteger visitTypeCalculation(TypeCalculationContext ctx) { return visit(ctx.expression()); }
@Override public BigInteger visitParenthesizedExpression(ParenthesizedExpressionContext ctx) { return visit(ctx.expression()); } }