Pratt parsing is a black box

本文为原文前 6,000 字符的节选翻译,完整内容请查看原文。

Pratt parsing is a black box

Apr 24, 2026 Pratt parsing is a black box # Introduction It caught my attention that most of Pratt parsing tutorials that I’ve stumbled on spend almost all of their time explaining Pratt’s algorithm and none explaining the properties behind Pratt that actually matter.

2026年4月24日 Pratt解析是一个黑箱 # 引言 我注意到,我所接触到的大多数Pratt解析教程都把几乎所有时间花在解释Pratt算法本身,却完全没有解释Pratt背后真正重要的特性。

Pratt fits into just 9 lines of code if you’re programming in a high-level language such as Rhombus: fun expression(rbp = 0): let mutable t = token advance() let mutable left = t.nud() while rbp < token.lbp: t := token advance() left := t.led(left) left

如果你使用像Rhombus这样的高级语言编程,Pratt算法只需9行代码即可实现:fun expression(rbp = 0): let mutable t = token advance() let mutable left = t.nud() while rbp < token.lbp: t := token advance() left := t.led(left) left

And here’s a secret: that’s the least important thing you need to understand about Pratt’s. In fact, you don’t need to understand this piece at all! Imagine if you were only able to use quicksort if you understood its implementation. Imagine if you were only able to use files if you knew how to implement a filesystem from scratch. It’s the same logic here.

这里有个秘密:这其实是关于Pratt算法中最不重要的一点。事实上,你根本不需要理解这段代码!试想一下,如果你必须理解快速排序的实现才能使用它,或者必须从零开始实现文件系统才能使用文件,那会怎样?这里的逻辑是一样的。

If you lack the power to abstract, you’ll arrive nowhere in computer science because that’s how the whole field works. In fact, I wrote the backbone of a heavily Pratt-based parsing machinery for a compiler that I’ve been writing since last year w/o even bothering to understand the above snippet in any detail.

如果你缺乏抽象能力,你在计算机科学领域将一事无成,因为整个领域就是这样运作的。事实上,我为去年开始编写的一个编译器构建了基于Pratt解析机制的骨干代码,而我甚至没有费心去详细理解上述代码片段。

Not convinced? Think for a second on how they do in traditional parsing techniques: compiler compilers! They use code generators to spit the parsing algorithm because just a minuscule crowd bothers to learn what the parsing engine is actually doing. It’s no different with Pratt.

还不相信吗?想一想传统解析技术是如何处理的:编译器生成器!它们使用代码生成器来吐出解析算法,因为只有极少数人会去钻研解析引擎到底在做什么。Pratt算法也是如此。

However Pratt is so small that you can just copy’n’paste these 9 lines of code in your project and call it a day instead of adding a new complex dependency to your project. The algorithm hasn’t changed since 1973 and it’s not gonna change now.

然而,Pratt算法非常精简,你只需将这9行代码复制粘贴到你的项目中即可,无需为项目添加新的复杂依赖。该算法自1973年以来从未改变,现在也不会改变。

In this article I’ll go over what you actually need to keep in mind for Pratt parsing. The point won’t be about memorizing any of it though. The point is about acquiring a mindset. As long as you acquire the mindset you don’t need to even bother to remember even a single word of what I say here.

在本文中,我将介绍你在进行Pratt解析时真正需要牢记的内容。重点不在于背诵这些内容,而在于获得一种思维方式。只要你掌握了这种思维方式,你甚至不需要记住我在这里说的任何一个字。

Nuds & leds The only tutorial on Pratt parsing that I can firmly recommend to someone who has never been exposed to the topic is actually a talk that Douglas Crockford gave in the conference GOTO 2013¹. Douglas Crockford nailed it when he stated: Pratt takes parsing which is a really complicated thing and reduces it to one simple question: What do we expect to see to the left of a token? — Douglas Crockford, GOTO 2013

Nuds 和 leds 对于从未接触过该主题的人,我唯一能坚定推荐的Pratt解析教程是Douglas Crockford在GOTO 2013会议上的演讲。Douglas Crockford说得非常到位:Pratt将解析这一极其复杂的事情简化为一个简单的问题:我们期望在标记(token)的左侧看到什么?—— Douglas Crockford, GOTO 2013

At first glance it may look like a mystical statement devoid of meaning, but that’s the question that becomes the framework on how you face parsing problems and it’ll rewire your brain to internalize the Pratt parsing mindset. That’s the most important thing you need to understand.

乍一看,这可能像是一句毫无意义的玄学陈述,但正是这个问题成为了你面对解析问题的框架,它将重塑你的大脑,让你内化Pratt解析的思维方式。这是你需要理解的最重要的事情。

You register semantic actions for two categories: nuds and leds. A nud is a token that expects nothing to its left (nud stands for null denotation) while a led expects something (led stands for left denotation). Traditional parsing techniques register semantic actions to production rules.

你需要为两类对象注册语义动作:nuds 和 leds。nud 是指左侧不需要任何内容的标记(nud 代表 null denotation),而 led 则需要左侧有内容(led 代表 left denotation)。传统的解析技术将语义动作注册到产生式规则上。

The text between the braces is code that executes when the BNF-like grammar on the left matches. I’m gonna repeat myself because that’s really important: traditional parsing techniques register semantic actions to production rules (which by definition are non-terminal symbols). In contrast Pratt parsing registers semantic actions to the terminals themselves instead. That’s a fundamental shift on how you face parsing problems.

大括号之间的代码会在左侧的BNF类语法匹配时执行。我要重复一遍,因为这非常重要:传统的解析技术将语义动作注册到产生式规则(根据定义,这些是非终结符)上。相比之下,Pratt解析则是将语义动作直接注册到终结符本身。这是你面对解析问题时的一个根本性转变。