Rule equalityExpression() { return binary( relationalExpression(), Operator.EQUAL, Operator.DIFF ); }
Rule addition() { return binary( multiplication(), Operator.ADD, Operator.SUB ); }
Rule multiplication() { return binary( composition(), Operator.INT_DIV, Operator.INT_TIMES, Operator.TIMES, Operator.DIV, Operator.MOD ); }
Rule functionWithTwoWordsAsName() { return Sequence( variable(), variable(), push(new FunctionElement(popVariableName(1)+" "+popVariableName())), mandatory( Sequence( expression(), ((FunctionElement) peek(1)).add(pop()) ), new ParseException("Wrong function named with two words syntax") ) ); }
Rule isOperation() { return Sequence( primary(), push(new OperationBinary(simplify(pop()))), ZeroOrMore( operator(IS), popValue(), mandatory( Sequence( FirstOf( Sequence( operator(NOT), popValue(), ((OperationBinary) peek()).addOperator(Operator.IS_NOT) ), ((OperationBinary) peek()).addOperator(Operator.IS) ), FirstOf( functionWithBrackets(), functionWithTwoWordsAsName(), variable(), keywordAsVariable(NULL) ), ((OperationBinary) peek(1)).add(simplify(pop())) ), new ParseException("Wrong binary operation syntax") ) ) ); }
Rule binary(Rule first, Rule rest, Operator... operators) { return Sequence( first, push(new OperationBinary(simplify(pop()))), ZeroOrMore( firstOperatorOf(operators), ((OperationBinary) peek(1)).addOperator(((Constant<Operator>) pop()).getValue()), mandatory( Sequence( rest, ((OperationBinary) peek(1)).add(simplify(pop())) ), new ParseException("Wrong binary operation syntax") ) ) ); }
Rule enumeratedList() { return Sequence( symbol(OPEN_BRACKET), push(new ValueList()), mandatory( Sequence( Optional( expression(), ((ValueList) peek(1)).add(pop()), ZeroOrMore( symbol(COMMA), expression(), ((ValueList) peek(1)).add(pop()) ) ), symbol(CLOSE_BRACKET) ), new ParseException("Wrong list syntax") ) ); }
Rule ternaryOperation() { return Sequence( elementar(), push(new OperationTernary(pop())), symbol(QUESTION), mandatory( Sequence( expression(), ((OperationTernary) peek(1)).setIfTrueExpression(pop()), symbol(DIV), expression(), ((OperationTernary) peek(1)).setIfFalseExpression(pop()) ), new ParseException("Wring ternary operation syntax") ) ); }
Rule functionWithoutBrackets() { return Sequence( variable(), TestNot( basic.spacing(), basic.terminal(SUB.toString()) ), expression(), push(new FunctionElement(popVariableName(1), pop())) ); }
Rule map() { return Sequence( symbol(OPEN_CURLY_BRACKET), push(new ValueMap()), mandatory( Sequence( Optional( variable(), symbol(DIV), expression(), ((ValueMap) peek(2)).add(popVariableName(1), pop()), ZeroOrMore( symbol(COMMA), variable(), symbol(DIV), expression(), ((ValueMap) peek(2)).add(popVariableName(1), pop()) ) ), symbol(CLOSE_CURLY_BRACKET) ), new ParseException("Wrong map syntax") ) ); }
Rule selection() { return binary( isOperation(), FirstOf( functionWithBrackets(), mapEntry(), variable() ), SELECTION ); }
Rule composition() { return binary( selection(), FirstOf( functionWithBrackets(), variable() ), COMPOSITION ); }
public Rule expression() { return Sequence( specificJtwigOperators(), push(simplify(pop())) ); }
Rule operator(Operator operator) { return Sequence( TestNot( FirstOf( basic.closeCode(), basic.symbol(CLOSE_OUTPUT) ) ), basic.terminal(operator.toString()), conditionalSpace(operator.toString()), push(new Constant<Operator>(operator)), basic.spacing() ); }
Rule function() { return FirstOf( functionWithBrackets(), functionWithoutBrackets() ); }