parsing - 从使用 Scala Parser Combinators 编写的解析器返回有意义的错误消息

标签 parsing scala error-handling combinators

我尝试使用解析器组合器在 Scala 中编写解析器。如果我递归匹配,

def body: Parser[Body] =
("begin" ~> statementList  )  ^^ {
     case s => {   new Body(s); }
}

def statementList : Parser[List[Statement]] = 
  ("end" ^^ { _ => List() } )|
  (statement ~ statementList ^^ { case statement ~ statementList => statement :: statementList  })

然后,每当语句中出现错误时,我都会收到很好的错误消息。
然而,这是丑陋的长代码。所以我想写这个:
def body: Parser[Body] =
("begin" ~> statementList <~ "end"  )  ^^ {
   case s => {   new Body(s); }
}

def statementList : Parser[List[Statement]] = 
    rep(statement)

此代码有效,但仅在 FIRST 语句中存在错误时才打印有意义的消息。如果它在后面的语句中,消息变得非常不可用,因为解析器希望看到整个错误语句被“结束”标记替换:
Exception in thread "main" java.lang.RuntimeException: [4.2] error: "end" expected but "let" found

 let b : string = x(3,b,"WHAT???",!ERRORHERE!,7 ) 

 ^ 

我的问题:有没有办法让 rep 和 repsep 与有意义的错误消息结合工作,将插入符号放在正确的位置而不是重复片段的开头?

最佳答案

您可以通过结合“自制”来做到这一点rep具有非回溯内部语句的方法。例如:

scala> object X extends RegexParsers {
     |   def myrep[T](p: => Parser[T]): Parser[List[T]] = p ~! myrep(p) ^^ { case x ~ xs => x :: xs } | success(List())
     |   def t1 = "this" ~ "is" ~ "war"
     |   def t2 = "this" ~! "is" ~ "war"
     |   def t3 = "begin" ~ rep(t1) ~ "end"
     |   def t4 = "begin" ~ myrep(t2) ~ "end"
     | }
defined module X

scala> X.parse(X.t4, "begin this is war this is hell end")
res13: X.ParseResult[X.~[X.~[String,List[X.~[X.~[String,String],String]]],String]] =
[1.27] error: `war' expected but ` ' found

begin this is war this is hell end
                          ^

scala> X.parse(X.t3, "begin this is war this is hell end")
res14: X.ParseResult[X.~[X.~[String,List[X.~[X.~[String,String],String]]],String]] =
[1.19] failure: `end' expected but ` ' found

begin this is war this is hell end
                  ^

关于parsing - 从使用 Scala Parser Combinators 编写的解析器返回有意义的错误消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4418975/

相关文章:

c++ - 解析 sstream

oop - Math Parser/Lexer - Token接口(interface)设计

javascript 正则表达式多行选择器 bbcode

scala - 如何在运行应用程序或测试用例时将JVM选项传递给SBT以使用?

Scala:通用隐式转换器?

error-handling - _Unwind_Backtrace 用于 FreeRTOS 上的不同上下文

javascript - 使用 JSONStream 读取大型 JSON 文件

scala - 如何使用 Spark 函数将日期从 yyyy-mm-dd 更改为 dd-mm-yyy

java - 如何删除输出中的最后一个 “-”?

c# - Azure Webjob在0秒后重新启动。为什么?