Pratt解析器如何与其他解析器类型进行比较,为什么它们使用得如此之少?

Lla*_*don 20 parsing

我最近从这篇优秀的文章中了解了Pratt解析器,发现Pratt解析器比递归下降解析器更简单,更优雅.我试图找到更多关于他们如何与其他解析器类型进行比较的信息,但发现维基百科文章几乎不是存根,而且我可以找到的使用它的更大项目的数量等于两个.

为什么Pratt解析器使用得那么少?他们有任何我不知道的严重限制或缺点吗?它们与其他解析器类型的比较究竟如何?什么时候应该和什么时候不应该使用它们?

ric*_*ici 18

Pratt解析器和所谓的"分流码"解析器之间几乎没有什么区别(它附有更长的维基百科文章); 主要区别在于Pratt使用递归并因此使用堆栈,而Djikstra("调车场")保持显式堆栈.除此之外,它们的操作顺序完全相同.我认为由于recursophobia,Djikstra的算法表达更为常见.

使用程序堆栈有一些优点; 其中之一就是保持类型安全更容易,因为整个堆栈不必是一种类型.另一方面,许多表达式解析器只有一种类型.

Dragon Book包含一个algorthm,它将从语法生成运算符优先级表.正如它所指出的那样,算法成功的事实并不一定意味着运算符优先级解析器将完全解析相同的语言.那里有更多有趣的信息,我当然忘记了; 如果您对算法感兴趣,那就是您可以看到的地方之一.它包含了一个有趣的见解,即如果用显而易见的方式用<和>包围生产结果,可以通过查看派生来生成<和>优先关系运算符.

总的来说,我的经验是,大多数时候,当你发现一篇博客文章说"我的上帝,我只是偶然发现X而且这很好,为什么没有更多的人知道它?",回答是"请不要认为你的无知是普遍的." 但也许我今天只是处于愤世嫉俗的情绪中.

顺便说一句,Lua解析器是一个手工构建的递归下降解析器,它使用Pratt样式解析来解析表达式; 我认为这是一种非常常见的技术,您可能会在其他地方找到它,尽管您可能需要通过代码来查看模式.

  • @asmageddon,三元运算符看起来很像圆括号.`?`保持运算符的左优先级,`:`保持正确的优先级.当一个`?`位于堆栈的顶部时,它就像一个`(`除了它期望一个`:`;当`:`到达时,它取代了`?`.当`:`是弹出,它需要三个操作数.(有一个通用算法.)语句中的终端以相同的方式工作. (3认同)