Compilation principle 编译原理

编译原理是计算机专业的一门重要专业课,旨在介绍编译程序构造的一般原理和基本方法。内容包括语言和文法、词法分析、语法分析、语法制导翻译、中间代码生成、存储管理、代码优化和目标代码生成。

词汇分析
编译器中的词法分析可以与汇编程序中的相同方式执行。通常在HLL中有更多的标记被识别 – 各种关键字(例如,for,while,if,else等),标点符号(例如,逗号,分号,大括号等),运算符(如算术运算符,逻辑运算符等),标识符等。使用lex或flex等工具创建词法分析器。
语法分析
语法分析涉及根据为HLL定义的已知语法规则集识别输入程序的结构。这是HLL与汇编语言等低级语言明显不同的最重要方面。在汇编语言中,语法规则很简单,大致要求程序应该是一系列语句,并且每个语句应该基本上包含一个助记符,后跟零或多个操作数,具体取决于助记符。可选地,在助记符之前还可以存在标识符。在HLL的情况下,语法规则要复杂得多。在大多数HLL中,语句本身的概念非常灵活,并且通常允许递归,使嵌套结构有效。这些语言通常支持多种数据类型,并且通常允许程序员定义要在程序中使用的abstruct数据类型。与汇编语言编程相比,这些和许多其他此类功能使得创建软件的过程更容易且更不容易出错。但是,另一方面,这些特征使得编译过程变得复杂。
需要使用一些合适的符号巧妙地指定HLL的非平凡语法规则,以便可以在编译器程序中对它们进行编码。为此目的,一种常用的形式主义是Context Free Grammar(CFG)。CFG是一种比常规语法更强大的形式(用于编写正则表达式来描述词法分析器中的标记)。递归是大多数HLL结构中的常见特征,可以使用CFG以简洁的方式定义,而常规语法则无法这样做。需要注意的是,某些结构无法使用CFG进行充分描述,并且可能需要其他更强大的形式,例如上下文敏感语法(CSG)。用于编写CFG或CSG规则的常用符号是 BNF(Backus Naur表格)。

在语法分析期间,编译器尝试应用使用BNF给出的输入HLL的语法规则,以识别输入程序的结构。这称为解析,执行此任务的模块称为解析器。从一个抽象的角度来看,这个阶段的输出是一个解析树,描述了如何重复应用语法的各种规则来识别输入程序。如果解析器不能为某个给定的输入程序创建解析树,则输入程序根据HLL的语法无效。

CFG形式主义和BNF符号的健全性使得创建不同类型的有效解析器以根据给定语言识别输入成为可能。这些解析器可以大致分为自上而下的解析器和自下而上的解析器。递归下降解析器 和Predictive解析器是自上而下解析器的两个示例。SLR解析器和LALR解析器是自下而上解析器的两个示例。对于某些简单的上下文无关语言(可以使用CFG定义的语言),可以编写更简单的自下而上解析器。例如,为了识别数学表达式,可以创建运算符优先级解析器。

在创建编译器时,解析器通常使用yacc和bison等工具构建 。为此,输入语言的CFG以BNF表示法编写,并作为工具的输入(以及其他详细信息)。

Photo by Christopher Robin Ebbinghaus / Unsplash
中间代码生成
将给定的输入程序识别为有效后,编译器会尝试使用目标环境的语言创建等效程序。在汇编程序的情况下,由于输入程序中每个语句中的助记符操作码所暗示的操作,这种转换稍微简单一些,因此存在一些等效的机器操作码。适用于机器语言中每个操作的操作数数量与相应的汇编语言助记符操作码所允许的数量相同。因此,对于汇编语言,每个语句的翻译几乎可以独立于程序的其余部分完成。但是,在HLL的情况下,尝试将单个机器操作码与输入语言的每个语句相关联是徒劳的。其中一个原因是,如上所述,语句的范围并不总是固定的,可能包含递归。此外,与目标执行环境可能直接支持的内容相比,HLL程序中的数据引用可以假设显着级别的抽象。将意义(在机器可支持的原始操作方面)与程序的程序或段相关联的任务称为语义处理。
虽然将目标语言操作与HLL程序中的语句相关联并不是完全直接的,但HLL的CFG允许人们将各种语法规则的语义动作(或含义)联系起来。因此,在广泛的翻译任务中,当解析输入程序时,编译器还尝试执行与最终应用的各种句法规则相对应的某些语义动作。但是,大多数HLL包含某些语法特征,对于这些特征,将使用一些附加信息(例如符号表的内容)来确定语义动作。因此,构建和使用诸如符号表之类的数据结构是由编译器执行的语义动作的重要部分。

在执行语义处理时,获得更易管理的等效形式的输入程序。这是使用一些中间代码表示来存储(表示),这使得进一步处理变得容易。在此表示中,编译器通常必须引入几个临时变量来存储各种操作的中间结果。用于中间代码的语言通常不是任何特定的机器语言,但是可以有效地转换为所需的机器语言(可以考虑某种形式的汇编语言用于这种用途)。

代码优化
以中间代码形式表示的程序通常在存储空间以及预期输出程序的运行时效率方面包含很多优化范围。有时输入程序本身包含这样的范围。除此之外,生成中间代码表示的过程通常为这种优化留下很大空间。因此,编译器通常实现显式步骤来优化中间代码。
代码生成
最后,编译器将中间代码表示中的(优化的)程序转换为所需的机器语言。需要注意的是,如果编译器正在翻译的程序实际上依赖于某些外部模块,则必须对编译器的输出执行链接。这些活动与输入程序是HLL还是汇编语言无关。
运行时存储管理

幽灵代写提供此课程的代写服务,查看所有CS代写内容!

代写语言:C语言、java、伪代码等