我个人更喜欢 Parsec 在 Alex 的帮助下进行词法分析。
我更喜欢 Parsec 而不是 Happy,因为 1) Parsec 是一个库,而 Happy 是一个程序,如果您使用 Happy 然后用 Happy 编译,您将使用不同的语言编写。2) Parsec 凭借其一元接口为您提供上下文相关的解析能力。您可以使用额外的状态进行上下文相关的解析,然后根据该状态进行检查和决定。或者只是在之前查看一些解析值并决定下一个解析器等。(如a <- parseSomething; if test a then ... do ...
)当您不需要任何上下文相关信息时,您可以简单地使用应用样式并获得类似在 YACC 或类似工具中实现的实现。
作为 Parsec 的一个缺点,您永远不会知道您的 Parsec 解析器是否包含左递归,并且您的解析器将卡在运行时(因为 Parsec 基本上是一个自上而下的递归下降解析器)。你必须找到左递归并消除它们。YACC 风格的解析器可以为您提供 Parsec 无法获得的一些静态保证和信息(如移位/减少冲突、未使用的终端等)。
强烈建议使用 Alex 在这两种情况下进行词法分析(如果您决定继续使用 Happy,我认为您必须使用 Alex )。因为即使您使用 Parsec,它也确实简化了您的解析器实现,并且也捕获了大量错误(例如:将关键字解析为标识符是我在没有 Alex 的情况下使用 Parsec 时遇到的常见错误。这只是一个示例)。
你可以看看我在 Alex+Parsec 中实现的Lua 解析器,这是在 Parsec 中使用 Alex 生成的令牌的代码。
编辑:感谢您John L
的更正。显然,您也可以使用 Happy 进行上下文相关解析。此外,Happy 中不需要 Alex 进行词法分析,但建议这样做。