我一直在考虑使用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文档声称它可以“解析上下文敏感的,无限的超前语法”,所以看起来我应该能够在这里做点什么。