词法分析器 return 应该是令牌列表还是动态令牌
Should a Lexer return a list of tokens or a token on the fly
我正在为一个项目实现一个词法分析器,我对它应该如何 return 一个解析器的标记感到困惑。词法分析器是否应该在声明时急切地准备一个标记列表以提供给解析器,或者解析器是否应该调用一个函数来懒惰地 return 动态地发送下一个标记?另外,像 lex/flex 这样的工具是怎么做到的?
(f)lex 生成的扫描器被设计为在每次调用时生成一个标记,这与其他所有常用的扫描器生成器完全相同。经验表明这是最容易使用的界面。它还最大限度地减少了不必要的动态内存管理。
但是,(f)lex 生成的扫描器不限于此模型。规则操作不必 return 任何东西。它可以将令牌推到令牌列表的末尾,或调用增量令牌消费者(“推送”解析器)或只是将令牌放在地板上(通常使用空白令牌)。
所以 (f)lex 不限制可能性。但它不提供支持累积令牌数组所需的内存管理的功能。如果出于某种原因您发现需要这样的数组,那么您有责任实现它。
很少看到需要标记数组的解析器,部分原因是在许多语言中,有时标记化取决于解析器的状态(所谓的“词法反馈”)。但这并不是未知的。例如GCC c++编译器使用token数组,既方便了预处理,也简化了lookahead和fallback的频繁使用。
但是对于介绍性的解析项目,我肯定会建议使用通用接口(按需词法分析)。事实上,我建议从 flex 或等效的开始,因为在学习如何实现一个词法分析器之前学习如何使用更有用。
我正在为一个项目实现一个词法分析器,我对它应该如何 return 一个解析器的标记感到困惑。词法分析器是否应该在声明时急切地准备一个标记列表以提供给解析器,或者解析器是否应该调用一个函数来懒惰地 return 动态地发送下一个标记?另外,像 lex/flex 这样的工具是怎么做到的?
(f)lex 生成的扫描器被设计为在每次调用时生成一个标记,这与其他所有常用的扫描器生成器完全相同。经验表明这是最容易使用的界面。它还最大限度地减少了不必要的动态内存管理。
但是,(f)lex 生成的扫描器不限于此模型。规则操作不必 return 任何东西。它可以将令牌推到令牌列表的末尾,或调用增量令牌消费者(“推送”解析器)或只是将令牌放在地板上(通常使用空白令牌)。
所以 (f)lex 不限制可能性。但它不提供支持累积令牌数组所需的内存管理的功能。如果出于某种原因您发现需要这样的数组,那么您有责任实现它。
很少看到需要标记数组的解析器,部分原因是在许多语言中,有时标记化取决于解析器的状态(所谓的“词法反馈”)。但这并不是未知的。例如GCC c++编译器使用token数组,既方便了预处理,也简化了lookahead和fallback的频繁使用。
但是对于介绍性的解析项目,我肯定会建议使用通用接口(按需词法分析)。事实上,我建议从 flex 或等效的开始,因为在学习如何实现一个词法分析器之前学习如何使用更有用。