[Corrected per WBahn's response below.  (Thanks for spotting that in the textbook.)]
Since operator precedence is expressly undefined (9.2.5), you are free to parse expressions left to right in a loop:
    CompileExpression()
    {
        /* Compiles <expression> :=
                <term> (op <term)*
    
            ENTRY: Tokenizer positioned on the expression.
            EXIT:  Tokenizer positioned after the expression.
        */
        CompileTerm()
        while tokenizer.tokenType is TK_SYMBOL and tokenizer.symbol is one of "+-*/&|<>="
        {
            operator = tokenizer.symbol;
            tokenizer.NextToken()
            CompileTerm()
            CompileOperator(operator)
        }
    }
This will result in left-to-right operator precedence, except that the unary operators '-' and '~' will have precedence over the binary operators.
--Mark