code: private Expression parseBooleanExpression(Expression expr) {
      if (tokens.positiveLookahead(AND)) {
        tokens.consume();
        expr = new And(expr, parseSemVerExpression());
      } else if (tokens.positiveLookahead(OR)) {
        tokens.consume();
        expr = new Or(expr, parseSemVerExpression());
      }
      return expr;
    }
docs: Parses the {@literal <boolean-expr>} non-terminal.
  
  <pre>
  {@literal
  <boolean-expr> ::= <boolean-op> <semver-expr>
  | <epsilon>
  }
  </pre>
  
  @param expr
  the left-hand expression of the logical operators
  @return the expression AST