代码之家  ›  专栏  ›  技术社区  ›  Germán

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

  •  1
  • Germán  · 技术社区  · 14 年前

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

    常客 if(foo()) . 但对任何人来说 它将“)”作为 常客

    我错过了什么?

    编辑 :

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

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

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

    我不需要详尽的语言检查,只需要控制结构。所以我不在乎if()中的“()”里面是什么,我想接受任何标识符、符号等序列 if())) 应有效,其中“)”是if的“条件”。

    2 回复  |  直到 14 年前
        1
  •  7
  •   Randall Schulz    14 年前

    正则表达式无法识别具有嵌套、平衡结构的语言,例如 (...) [...] , {...} 所以您需要使用更多的上下文无关的产品(而不是正则表达式)来匹配 regularStr

        2
  •  0
  •   Germán    14 年前

    好吧,接受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中取出“(”And“)”。作品!

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