【发布时间】:2020-01-17 14:57:15
【问题描述】:
我很好奇 C/C++ 词法分析器和解析器如何协同工作。我知道解析器通常需要先行至少一个标记。不过我的问题是,在生产编译器中(比如 gcc 或 clang):
1) 词法分析器是否先运行,对整个文件进行词法分析,然后让解析器生成 AST。这意味着词法分析器会生成一个标记列表。
或
2) 词法分析器是否只生成一小组标记,足以让解析器完成其工作。这意味着词法分析器和解析器轮流运行。
我绝对认为使用选项 1,因为像 C++ 这样的语言有时需要任意前瞻,因为语法不是上下文无关的,但这会占用大量内存。
【问题讨论】:
-
这里有一些关于clang的信息:clang.llvm.org/docs/InternalsManual.html;这更像是您的选项 2(解析器从词法分析器请求令牌),但我还不够熟悉,无法实际回答。
-
第 1 部分。一些事情:虽然 C++ 语言确实不是上下文无关的(例如,需要在使用之前定义变量),但用于解析语言是上下文无关的。怎么会这样?例如,基于 LALR(1) 语法的解析器在执行归约时会执行语义操作。具体来说,当它识别出一个变量声明时,它会将变量定义输入到一个符号表中。当它识别出一个使用变量的表达式时,它可以检查符号表以查看该变量是否存在。
-
第 2 部分。通常,词法分析和解析与解析器并行运行,因为它需要“下一个标记”来调用词法分析器。但是,这可能涉及词法分析器的大量读取和处理。考虑包含文件的处理,这些文件可能嵌套到许多级别并包含宏定义。我们知道 C/C++ 编译时开关之一是能够只预处理输入并输出新的源文件而不编译。但这不是解析器处理的实际令牌流。您仍然需要对此输出进行词法分析。
-
既不是 (1) 也不是 (2)。词法分析器根本没有“运行”:每当解析器需要一个新的标记时,它就会被解析器作为一个过程调用。词法分析器一次返回一个标记。 C++ 不需要任意前瞻,而 at 的语法不是上下文无关的事实与此无关。