解析搜索表达式上的括号 - Scala 解析器组合器

Parsing parentheses on search expression - Scala parser combinator

我正在为搜索表达式编写解析器。 例如

a = "zyx" and ( b < 5 or c > 9)

我写了这个解析器,但它无法匹配括号,得到这个错误:

failure: identifier expected
a = "zyx" and ( b < 5 or c > 9)
              ^

我该怎么做才能匹配括号

class SearchQueryParser extends StandardTokenParsers {
  def expr: Parser[Expression] = orExp | "(" ~> orExp ~ ")"

  def orExp: Parser[Expression] = {
    andExp *("or" ^^^ {(a: Expression, b: Expression) => BoolExp("OR", (a, b))})
  }

  def andExp: Parser[Expression] = {
    compareExp *("and" ^^^ {(a: Expression, b: Expression) => BoolExp("AND", (a, b))})
  }

  def compareExp: Parser[Expression] = {
    identifier ~ rep(
      ("=" | "!=" | "<" | ">") ~ literal ^^ {
        case op ~ rhs => (op, rhs)
      }
    ) ^^ {
      case (acc, ("=", rhs: Expression)) => Binomial("=", acc, rhs)  
      case (acc, ("!=", rhs: Expression)) => Binomial("!=", acc, rhs)
      case (acc, ("<", rhs: Expression)) => Binomial("<", acc, rhs)
      case (acc, (">", rhs: Expression)) => Binomial(">", acc, rhs)
    }
  }
}

您当前的语法只允许在 expr 规则中使用括号,我认为这是您的主要规则,并且 expr 规则从未被任何其他规则使用。所以括号只能包含在整个表达式中。

你想要做的是将 "(" ~ expr ~ ")" 放在允许括号表达式的最低位置。据我了解你的语法,这可能意味着允许它作为 andExpcompareExp 的替代(假设你不想在 compareExps 中使用括号)。

如@sepp2k 所述,您需要将括号放在允许使用括号的最低位置。在你的情况下,它应该在 compareExp:

  def compareExp: Parser[Expression] = {
    "(" ~> expr <~ ")" | identifier ~ rep(
      ("=" | "!=" | "<" | ">") ~ literal ^^ {
        case op ~ rhs => (op, rhs)
      }
    ) ^^ {
      case (acc, ("=", rhs: Expression)) => Binomial("=", acc, rhs)  
      case (acc, ("!=", rhs: Expression)) => Binomial("!=", acc, rhs)
      case (acc, ("<", rhs: Expression)) => Binomial("<", acc, rhs)
      case (acc, (">", rhs: Expression)) => Binomial(">", acc, rhs)
    }
  }

exp 方法不应处理括号

 def expr: Parser[Expression] = orExp