我一直在考虑使用 Haskell 的 Parsec 解析库来解析 Java 的子集作为递归下降解析器,以替代更传统的解析器生成器解决方案,如 Happy。Parsec 似乎很容易使用,解析速度对我来说绝对不是一个因素。不过,我想知道是否有可能使用 Parsec 实现“备份”,这是一种通过依次尝试每一个来找到要使用的正确产品的技术。举一个简单的例子,考虑 JLS Java 语法的最开始:
Literal:
IntegerLiteral
FloatingPointLiteral
我想要一种不必弄清楚我应该如何订购这两个规则以使解析成功的方法。就目前而言,像这样的幼稚实现:
literal = do {
x <- try (do { v <- integer; return (IntLiteral v)}) <|>
(do { v <- float; return (FPLiteral v)});
return(Literal x)
}
不会工作......像“15.2”这样的输入会导致整数解析器首先成功,然后整个事情会在“。”上窒息。象征。当然,在这种情况下,很明显可以通过重新排序两个产品来解决问题。不过,在一般情况下,找到这样的事情将是一场噩梦,而且我很可能会错过一些案例。理想情况下,我想要一种方法让 Parsec 为我找出这样的东西。这是可能的,还是我只是想对图书馆做太多事情?Parsec 文档声称它可以“解析上下文相关的无限前瞻语法”,所以看起来我应该可以在这里做点什么。