Lexer 是否应即时返回令牌列表或令牌

问题描述

我正在为一个项目实现一个词法分析器,并且对它应该如何将标记返回给解析器感到困惑。词法分析器是否应该急切地准备一个标记列表以在声明时提供给解析器,还是解析器应该调用一个函数来即时返回下一个标记?另外,像 lex/flex 这样的工具是如何做到的?

解决方法

(f)lex 生成的扫描器旨在每次调用时生成一个令牌,这与其他常用的扫描器生成器完全相同。经验表明,这是最容易使用的界面。它还最大限度地减少了不必要的动态内存管理。

然而,(f)lex 生成的扫描器不限于此模型。规则操作不必返回任何内容。它可以将令牌推送到令牌列表的末尾,或者调用增量令牌消费者(“推送”解析器),或者只是将令牌放在地板上(如通常使用空白令牌所做的那样)。

所以 (f)lex 不会限制可能性。但是它没有提供支持累积令牌数组所需的内存管理的功能。如果出于某种原因您觉得这样的数组是必要的,那么您有责任实施它。

需要标记数组的解析器并不常见,部分原因是在许多语言中,有时标记化取决于解析器的状态(所谓的“词法反馈”)。但它不是未知的。例如,GCC c++ 编译器使用令牌数组,既便于预处理,又简化了前瞻和回退的频繁使用。

但是对于介绍性的解析项目,我绝对建议使用通用接口(按需词法分析)。事实上,我建议从 flex 或等效的开始,因为在学习如何实现一个词法分析器之前先学习如何使用更有用。