0

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

这是一个例子:

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

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

  1. /mypath[text() != '']
  2. def f(a) {a * 2}
  3. ,

我期望用参数得到一个函数树:

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

这里的问题是单引号在我的代码中表示一个字符串,但在该字符串中有时我们有额外的单引号,如下所示:

/mypath[文本() != '' ]

所以,在我的情况下,我不能使用CharPred(_ != '\'')

我们在字符串中也有一个逗号,就像在第三个参数中一样

这是使用 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}'
','
4

0 回答 0