Scala解析器组合器:如何解析“if(x)”,如果x可以包含“)”

时间:2010-05-23 21:12:48

标签: scala parser-combinators

我正试图让它发挥作用:

def emptyCond: Parser[Cond] = ("if" ~ "(") ~> regularStr <~ ")" ^^ { case s => Cond("",Nil,Nil) }

其中 regularStr 被定义为接受许多内容,包括“)”。当然,我希望这是一个可接受的输入: if(foo())。但对于任何 if(x),它将“)”作为 regularStr 的一部分,因此此解析器永远不会成功。

我错过了什么?

修改

regularStr不是正则表达式。因此定义如下:

  def regularStr = rep(ident | numericLit | decimalLit | stringLit | stmtSymbol) ^^ { case s => s.mkString(" ") }

,符号为:

  val stmtSymbol = "*" | "&" | "." | "::" | "(" | ")" | "*" | ">=" | "<=" | "=" | 
               "<" | ">" | "|" | "-" | "," | "^" | "[" | "]" | "?" | ":" | "+" |
               "-=" | "+=" | "*=" | "/=" | "&&" | "||" | "&=" | "|="

我不需要详尽的语言检查,只需要控制结构。所以我真的不在乎if()中的“()”内部是什么,我想接受任何标识符,符号等序列。所以,为了我的目的,即使 if()))也应该是有效的,其中“))”是if的“条件”。

2 个答案:

答案 0 :(得分:6)

正则表达式无法识别具有嵌套平衡构造的语言,例如(...)[...]{...}等。因此,您将需要使用更多上下文 - 免费制作(不是正则表达式)以匹配regularStr部分。

答案 1 :(得分:0)

好的,接受if()))并不是真正的要求,只是为了让我的解析尽可能便宜而愿意接受的一个例子,只是担心捕获控制结构。

然而,看起来我不能这么便宜,仍然有它的工作。因此,由于if()构造具有括号,我所要做的就是期望内部具有良好平衡的括号。关闭“)”,其中一个不被期望不能成为条件的一部分。

我这样做了:

  val regularNoParens = ident | numericLit | decimalLit | stringLit | stmtSymbol 
  def regularParens: Parser[String] = "(" ~ rep(regularNoParens | regularParens) ~ ")" ^^ { case l ~ s ~ r => l + s.mkString(" ") + r } 
  def regularStr = rep(regularNoParens | regularParens) ^^ { case s => s.mkString(" ") }

我从stmtSymbol中取出“(”和“)”。作品!

编辑:它不支持嵌套,修复它。