我有一个支持某种自定义语言的库。解析器是使用scala RegexParsers编写的。现在我尝试使用fastparse库重写我们的解析器以加速我们的引擎。 问题是:是否有可能在伪语言函数中正确解析params?
以下是一个例子:
$out <= doSomething('/mypath[text() != '']', 'def f(a) {a * 2}', ',') <= $in
这是一个带有3个参数的函数doSomething:
我希望用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}'
','