代码生成输入一般是注释分析树和信息较为完备的符号表,输出是目标代码。目标代码要求能在gcc编译器下正确编译,生成的可执行文件能够正确执行,在合法的输入下,得到正确的输出结果。
由于源语言和目标语言都是高级语言,所以我们直接生成目标代码,而不生成中间代码,否则会更加麻烦。借助经过了语义分析的抽象语法树和符号表,我们可以很轻松的进行目标代码生成。
接下来,我们从源语言的需求和目标语言的特点出发,通过对比来讨论代码生成的需求细节。
pascal主程序中的变量可以被所有的过程、函数体访问,具有全局作用域,因此对应于C语言中的全局变量。
pascal主程序头中包含了一个无类型的标识符列表。经查阅资料,这个标识符列表类似于c语言中main函数的参数列表,例如在命令行调用时可以指定这些参数。我们注意到在pascal的语法中,程序头对于这些标识符的声明没有类型的指示,而c语言有。这预示着在pascal中,我们仍需要定义这些标识符为具体的变量,才能使用,否则就属于未定义就引用的错误。input和output是两个特例,这两个标识符被隐含声明为程序参数且被隐含定义为文件变量,与标准输入,标准输出相关联。需要特别注意的是,程序标识符只能被定义为字符串、文件等类型,如果定义为其它类型,应忽略对应的参数(以避免一些类型错误,PASCAL编译器是这么做的),而我们并不考虑这些类型,所以我们暂时保留这个标识符列表,但在测试用例中并不涉及。如果后续我们有时间增加字符串等类型的支持再进行考虑。在PASCAL中使用命令行参数的一个较为方便的做法是利用paramcount和paramstr这两个变量,这与c语言中main函数的参数int argc, char **argv类似。但由于仍涉及字符串操作,我们仍不考虑。
对于常量定义,pascal中的const关键字作用域较大,不局限于下一个分号,而C语言中,每一分号隔出的部分都要单独使用一个const关键字。且pascal中的常量在定义时不需要指明类型,但是C语言需要。所以在我们需要在词法分析阶段完成对常量类型的自动识别,在目标代码生成时,指明对应的类型。
pascal在声明变量时,除了要说明类型,还要再前面加上var关键字,C语言中没有这样的关键字,只需要指明类型即可。var关键字的作用域与const关键字相同。
C语言中数组各维下标默认从0开始,而pascal中的范围可以任意指定,因此需要对数组下标进行相应的变换(在目标代码中需要新增定义临时变量以指明偏移量)。
PASCAL中函数返回值用 函数标识符:=表达式 表示,对应于C语言中的return语句。
PASCAL中如果函数或者过程没有参数,则无需包含空内容的括号,C语言中则需要。
PASCAL中多维数组的访问方法是在一个中括号内部,用逗号隔开各维索引,而C语言中则直接用中括号隔开各维索引。
C语言中一些基本的符号与PASCAL有所区别,例如C语言中的不等于用!=,而PASCAL中用<>。
PASCAL中的复合语句块用begin和end包括,而在C语言中用花括号包括。
代码生成的测试用例同整体测试,不再单独给出。