//This BNF takes into consideration operator precedence: // expression ::= <relexpr> (('&' | '|') <relexpr>)* // relexpr ::= <addexpr> (('<' | '<=' | '>' | '>=' | '=' | '!=') <addexpr>)* // addexpr ::= <mulexpr> (('+' | '-') <mulexpr>)* // mulexpr ::= <term> (('*' | '/' | '%') <term>)* // term is defined as before, see ParseTerm; thanks to that definition, // unary operators have the highest precedence, as desired. private void ParseExpression() { //After this method completes, the code generator should have //available to it the result of the expression's evaluation (e.g. //on the stack or in a predefined register). ParseRelationalExpression(); while (IsNextTokenLogicalOp()) { Token logicalOp = NextToken(); ParseRelationalExpression(); switch (logicalOp.Value) { case "&": _codeGenerator.And(); break; case "|": _codeGenerator.Or(); break; default: ThrowCompilationException("Unexpected logical operator " + logicalOp.Value); break; } } }