每次我编写一个简单的词法分析器和解析器时,我都会偶然发现同一个问题:词法分析器和解析器应该如何通信?我看到四种不同的方法:
词法分析器急切地将整个输入字符串转换为标记向量。完成此操作后,将向量馈送到解析器,解析器将其转换为树。这是迄今为止实现的最简单的解决方案,但由于所有令牌都存储在内存中,因此浪费了大量空间。
每次词法分析器找到一个标记时,它都会调用解析器上的一个函数,传递当前标记。以我的经验,这只有在解析器可以自然地实现为像 LALR 解析器这样的状态机时才有效。相比之下,我认为它根本不适用于递归下降解析器。
每次解析器需要一个令牌时,它都会向词法分析器询问下一个令牌。由于
yield
关键字,这在 C# 中很容易实现,但在没有它的 C++ 中很难实现。词法分析器和解析器通过异步队列进行通信。这在“生产者/消费者”的标题下是众所周知的,它应该大大简化了词法分析器和解析器之间的通信。它是否也优于其他多核解决方案?还是词法太琐碎?
我的分析合理吗?还有其他我没有想到的方法吗?实际编译器中使用什么?如果像 Eric Lippert 这样的编译器作者能够对这个问题有所了解,那将是非常酷的。