docs: def expr(self):
          """
          expr    ::= term ((AND | OR) term)*
          term    ::= factor ((EQ | NE) factor)*
          factor  ::= func | const | LPAREN expr RPAREN
          func    ::= lit LPAREN expr (,expr)* RPAREN
          lit     ::= alphanum
          """
          node = self.term()
  
          while True:
              token = self.current_token
              if token.type == AND:
                  self.eat(AND)
              elif token.type == OR:
                  self.eat(OR)
              else:
                  break
              node = Op(op=token, children=[node, self.term()])
          return node