Scala FastParse库错误

时间:2016-08-14 04:11:20

标签: scala fastparse

我正在尝试学习scala快速解析库。为此,我写了以下代码

import fastparse.noApi._
import fastparse.WhitespaceApi

object FastParsePOC {

   val White = WhitespaceApi.Wrapper{
      import fastparse.all._
      NoTrace(" ".rep)
   }

   def print(input : Parsed[String]): Unit = {
      input match {
         case Parsed.Success(value, index) => println(s"Success: $value $index")
         case f @ Parsed.Failure(error, line, col) => println(s"Error: $error $line $col ${f.extra.traced.trace}")
      }
   }

   def main(args: Array[String]) : Unit = {
      import White._
      val parser = P("Foo" ~ "(" ~ AnyChar.rep(1).! ~ ")")
      val input1 = "Foo(Bar(10), Baz(20))"
      print(parser.parse(input1))
   }
}

但我收到错误

Error: ")" 21 Extra(Foo(Bar(10), Baz(20)), [traced - not evaluated]) parser:1:1 / (AnyChar | ")"):1:21 ...""

我的预期输出是" Bar(10),Baz(20)"。看来上面的解析器不喜欢结尾")"。

1 个答案:

答案 0 :(得分:4)

AnyChar.rep(1)在输入字符串的末尾还包含)符号,因此未达到)处的~ ")")结尾。 如果在Bar和Baz中未使用)符号,则可以通过从)中排除AnyChar来解决此问题:

val parser = P("Foo" ~ "(" ~ (!")" ~ AnyChar).rep(1).! ~ ")")
val input1 = "Foo(Bar(10*, Baz(20*)"

要使Bar和Baz使用)符号,您可以为每个符号定义单独的解析器(也不包括)中的AnyChar符号。以下解决方案更灵活一点它允许更多出现Bar和Baz,但我希望你明白这一点。

val bar = P("Bar" ~ "(" ~ (!")" ~ AnyChar).rep(1) ~ ")")
val baz = P("Baz" ~ "(" ~ (!")" ~ AnyChar).rep(1) ~ ")")
val parser = P("Foo" ~ "(" ~ (bar | baz).rep(sep = ",").! ~ ")")
val input1 = "Foo(Bar(10), Baz(20))"
print(parser.parse(input1))

结果:
Success: Bar(10), Baz(20) 21