Compiler construction GCC/clanglexer和解析器

Compiler construction GCC/clanglexer和解析器,compiler-construction,Compiler Construction,我很好奇C/C++词法分析器和解析器是如何协同工作的。我知道解析器通常需要至少提前查找一个令牌。但我的问题是,在生产编译器中,使用gcc或clang: 1首先运行lexer,对整个文件进行lex,然后让解析器生成AST。这意味着lexer将生成一个令牌列表 或 lexer是否只生成一小部分令牌,足以让解析器完成其工作。这意味着lexer和解析器轮流运行 我确信使用选项1是因为像C++这样的语言有时需要任意的前瞻,因为语法不是上下文无关的,但是这会占用很多内存。 < P>传统的答案接近于你的情况2

我很好奇C/C++词法分析器和解析器是如何协同工作的。我知道解析器通常需要至少提前查找一个令牌。但我的问题是,在生产编译器中,使用gcc或clang:

1首先运行lexer,对整个文件进行lex,然后让解析器生成AST。这意味着lexer将生成一个令牌列表

lexer是否只生成一小部分令牌,足以让解析器完成其工作。这意味着lexer和解析器轮流运行


我确信使用选项1是因为像C++这样的语言有时需要任意的前瞻,因为语法不是上下文无关的,但是这会占用很多内存。

< P>传统的答案接近于你的情况2,但不是完全一样。请注意,lexer和parser通常都实现为相对简单的状态机

lexing状态机可以通过以下任一方式驱动:

给我一个新的代币 显然需要获取输入代码并将其组装成令牌,或者:

这是一个新的输入字符 最终导致代币从lexer中脱落

解析器状态机可以从任意方向驱动:

给我一份分析报告 然后必须获得代币,直到找到完整的句子,或者:

这是一个新的代币 然后必须将标记组合成一个句子

如果我们使用的解析器算法是以这种方式驱动的,那么我们将编译一个包含以下内容的文件:

for all input characters:
    feed character to tokenizer
当标记从标记器中脱落时,它们将驱动解析器。整个过程将是自下而上的协同程序

传统上,在yacc、bison等生成的解析器中,以及在为它们提供服务的词法分析器中,我们运行的是自上而下的,即有人调用get me语句函数,该函数可以构建AST,或直接发出代码,或介于两者之间的某个函数,例如,为一个函数或声明构建一个AST,然后将其转换为中间代码,然后为另一个函数或声明等构建另一个AST,该AST驱动所有东西朝着从lexer拉入令牌的方向,但它仍然是相当协同的,因为解析器一次只请求一个令牌

这种方法也是手工编写递归下降解析器的一种明显方式:您的顶级函数是get me a句子或get me all句子或其他任何东西,最终导致一些函数调用get me a token。因此,在这两种情况下,算法的实际表达式都会对lexer进行重复的get me a token调用

GCC有一个手工编码的解析器和手工编码的词法分析器,它们以这种方式工作。我没有看过叮当的内脏,但我怀疑是一样的

对于C++,具体来说,它有一些非常讨厌的解析案例;看和看。一些编译器使用特别的方法来处理这个问题,例如,提供一个过度接受的语法,并尝试对最终的AST进行修补,或者通过黑客来控制语法。我看到C++编译器崩溃了:给它们提供语法上有效的令牌,使语义无意义,黑客也会失火。另一种可能更好的方法是使用GLR解析器;看


我很久没有做过任何语法分析器理论方面的工作了,在写这个答案时,我遇到了2011年的GLL语法分析器,这非常有趣。

这里有一些关于clang的信息:;更重要的是,您的选项2解析器从lexer请求令牌,但我还不太熟悉,无法实际回答。第1部分。有两件事:虽然语言C++不是上下文无关的,但是在使用之前,需要定义变量,用于解析语言的语法是上下文无关的。这怎么可能?例如,基于LALR1语法的解析器在执行约简时将执行语义操作。具体来说,当它识别变量声明时,它会将变量定义输入到符号表中。当它识别出一个使用变量的表达式时,它可以检查符号表以查看该变量是否存在。第2部分。通常,词法分析和解析与解析器并行运行,解析器根据需要调用下一个标记的词法分析器。但是,这可能涉及到词法分析器的大量读取和处理。考虑包含文件的处理,这些文件可以嵌套到多个级别并包含宏定义。我们知道,C/C++编译时开关之一是只预处理输入和输出新源文件而不编译的能力。但这不是解析器处理的实际令牌流。您仍然需要对此输出进行词法分析。1和2都不是。lexer根本不是“运行”的:每次解析器需要一个新的令牌时,解析器都会将其作为过程调用。lexer一次返回一个令牌。C++不需要任意的前瞻,语法不在上下文无关,这与此无关。非常感谢你的回应!这很有帮助:-!