使用未转义字符解析字符串

时间:2017-05-23 16:53:51

标签: scala parsing fastparse

我有一个支持某种自定义语言的库。解析器是使用scala RegexParsers编写的。现在我尝试使用fastparse库重写我们的解析器以加速我们的引擎。 问题是:是否有可能在伪语言函数中正确解析params?

以下是一个例子:

$out <= doSomething('/mypath[text() != '']', 'def f(a) {a * 2}', ',') <= $in

这是一个带有3个参数的函数doSomething:

  1. / mypath [text()!=&#39;&#39;]
  2. def f(a){a * 2}
  3. 我希望用params得到一个函数树:

    Function(
        name = doSomething
        params = List[String](
            "/mypath[text() != '']",
            "def f(a) {a * 2}",
            ","
        )
    )
    

    我的所作所为:

    val ws = P(CharsWhileIn(" \r\n"))
    def wsSep(sep: String) = P(ws.? ~ sep ~ ws.?)
    val name = P(CharsIn('a' to 'z', 'A' to 'Z'))
    val param = P(ws.? ~ "'" ~ CharPred(_ != '\'').rep ~ "'" ~ ws.?)
    val params = P("(" ~ param.!.rep(sep = wsSep(",")) ~ ")")
    val function = P(name.! ~ params.?).map(case (name, params) => Function(name, params.getOrElse(List())))
    

    这里的问题是单引号代表我的代码中的String,但在该字符串中有时我们还有其他单引号,如下所示:

    / mypath [text()!= &#39;&#39; ]

    所以,我不能在我的案例中使用 CharPred(_!=&#39; \&#39;&#39;)

    我们在第3个参数中的字符串中也有逗号

    这是使用scala解析器以某种方式工作,但我无法使用fastparse解析相同的

    有没有人有想法如何让解析器正常工作?

    更新

    知道了! 主要的魔力在于 val param

    object X {
    
      import fastparse.all._
    
      case class Fn(name: String, params: Seq[String])
    
      val ws = P(CharsWhileIn(" \r\n"))
      def wsSep(sep: String) = P(ws.? ~ sep ~ ws.?)
      val name = P(CharIn('a' to 'z', 'A' to 'Z').rep)
      val param = P(ws.? ~ "'" ~ (!("'" ~ ws.? ~ ("," | ")")) ~ AnyChar).rep  ~ "'" ~ ws.?)
      val params = P("(" ~ param.!.rep(sep = wsSep(",")) ~ ")")
      val function = P(name.! ~ params.?).map{case (name, params) => Fn(name, params.getOrElse(Seq()))}
    }
    
    
    object Test extends App {
      val res = X.function.parse("myFunction('/hello[name != '']' , 'def f(a) {mytest}', ',')")
      res match {
        case Success(r, z) =>
          println(s"fn name: ${r.name}")
          println(s"params:\n {${r.params.mkString("\n")}\n}")
        case Failure(e, z, m) => println(m)
      }
    }
    

    出:

    name: myFunction
    params:
    '/hello[name != '']' 
    'def f(a) {mytest}'
    ','
    

0 个答案:

没有答案
相关问题