【问题标题】:Parsing parentheses on search expression - Scala parser combinator解析搜索表达式上的括号 - Scala 解析器组合器
【发布时间】:2019-07-31 03:27:03
【问题描述】:

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

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)
    }
  }
}

【问题讨论】:

  • 你的compareExp 规则对我来说看起来很奇怪。它允许x &lt; 5 &gt; 1,但不允许1 &lt; x &lt; 5。我不确定这是否是您的本意。
  • 感谢您的评论。我实际上不需要任何表达式,因为应该只允许二项式。我相应地改变了我的语法。

标签: scala parsing lexer


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    正如@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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多