编译器的阶段?
编译的哪个阶段是被识别的编程语言的关键字?编译器的阶段?
我
- 词法分析之间的某种困惑。
- 该程序的解析。
我曾经写过一个在C词法分析器使用正则表达式,但它在int main(void)
承认main()
也作为关键字。
在这些方面,我认为我们必须构建一个分析树来识别关键字。
今年我不得不建立一个简单的编译器作为我使用Java的项目。关键词的识别是在词法分析上进行的。在那个阶段,我会阅读输入语言,并创建一个类型的令牌(对于关键字类型是variable_declaration)及其值。对于每种情况,例如标识符,常量,乘法操作,添加操作等,我也有不同的类型。然后传递这些令牌到一个队列,然后进入一个解析器,它将检查语法并创建一个二叉树,然后用它来创建输出语言。
通常,汇编的词法分析阶段将输入文本分解成词汇序列,每个词汇都属于某个特定的记号类型,这在以后的分析中很有用。因此,关键词通常在词法分析过程中首先得到识别,以便更轻松地进行分析。由于解析器倾向于通过编写上下文无关的标记语法而不是词位来实现(即,词位的类别而非内容),因此在关键字时构建解析器显着更容易在练习中被标记。例如,如果我想有治疗解析器“如果”作为关键字,那么我可能需要一个规则,看起来像这样在我的CFG:
Statement ::= 'IF' Expr 'THEN' Expr
如果我不分类IF
和THEN
到他们自己的令牌类型中,那么我的解析器就不能写出类似上面的语句。
这将是词法分析。
有些语言具有“特殊”标识符以及关键字。这些通常被添加到标识符表并在解析开始之前分配已知的常量ID值,以便它们可以很容易地被发现。这些通常对解析器没有特别的意义 - 它们应该在解析后在抽象语法树(AST)中检测到。
例如,看一看的奥伯伦语言报表...
http://www-old.oberon.ethz.ch/oreport.html
不是一种语言建议 - 只是一个容易获得和简单的语言规范(非常Wirths风格)。
无论如何,“词汇和表示”部分包含“运营商和分隔符”列表,其中包括大多数人会将其识别为关键字的列表。这些将被词法分析器识别。
在“声明和范围规则”部分,有一个预定义标识符列表,如“ABS”和“BOOLEAN”。我对Oberon的确定程度并不熟悉,但是如果我要编写一个编译器,那么我很有可能只是预先初始化标准标识符表以包含这些预定义的标识符。
在C中,“main”在大多数方面只是另一个功能。编译器可能会或可能不会将其视为特殊的。关于它的唯一“特殊”事情可能是链接到最终可执行文件的启动代码调用该函数。
它很大程度上取决于定义,特别是您在扫描器,标记器,词法分析器和分析器之间绘制线条的位置。既然这是作业,而且只有你的教授才是正确的。说它是正确的:看看你的阅读材料中提供的定义。
关于main():你可以肯定地说main()和其他函数不是关键字,而是一个标记。标记器识别子字符串“main”是一个标记,解析器将其设置为与它的“(...)”和“{...}”部分有关。此外,对于main(),解析器将自动生成一个程序入口点。
只是一个说明:[正则表达式是可以嵌套的模式的不好选择](http://www.codinghorror.com/blog/2008/06/regular-expressions-now-you-have-two-problems的.html)。 – Mehrdad 2011-03-05 08:52:49
@Mehrdad:绝对正确,但对于标记(它不涉及任何嵌套任何细节;一个词法分析器只是返回一个扁平的标记流),它们很棒! – delnan 2011-03-05 08:53:17
@Mehrdad - 还有一些基于正则表达式的工具,这些工具添加了有限的嵌套处理能力 - 足以嵌套评论等.Ragel就是一个很好的例子。注意我说“基于”(我已经习惯了人们在这里跳来跳去的东西;-)),我知道一旦你支持任意深度嵌套,整体语法就不再是常规的了。 – Steve314 2011-03-05 09:02:00