Pascal语言编译器的设计与实现我们设计的编译程序涉及到编译五个阶段中的三个,即词法分析器、语法分析器和中间代码生成器。
编译程序的输出结果包括词法分析后的二元式序列、变量名表、状态栈分析过程显示及四元式序列程序,整个编译程序分为三部分:(1) 词法分析部分(2) 语法分析处理及四元式生成部分(3) 输出显示部分一.词法分析器设计由于我们规定的程序语句中涉及单词较少,故在词法分析阶段忽略了单词输入错误的检查,而将编译程序的重点放在中间代码生成阶段。
词法分析器的功能是输入源程序,输出单词符号。
我们规定输出的单词符号格式为如下的二元式:(单词种别,单词自身的值)#define ACC -2#define sy_if 0#define sy_then 1#define sy_else 2#define sy_while 3#define sy_begin 4#define sy_do 5#define sy_end 6#define a 7#define semicolon 8#define e 9#define sharp 10#define S 11#define L 12#define tempsy 15#define EA 18 //E and#define EO 19 //E or#define plus 34#define subtract 35#define times 36#define divide 37#define becomes 38#define op_and 39#define op_or 40#define op_not 41#define rop 42#define lparent 48#define rparent 49#define ident 56#define intconst 57函数说明1.读取函数readline( )、readchar ( )词法分析包含从源文件读取字符的操作,但频繁的读文件操作会影响程序执行效率,故实际上是从源程序文件” PAS.dat ”中读取一行到输入缓冲区,而词法分析过程中每次读取一个字符时则是通过执行readchar ( )从输入缓冲区获得的;若缓冲区已被读空,则再执行readline( )从PAS.dat 中读取下一行至输入缓冲区。
2.扫描函数scan( )扫描函数scan( )的功能是滤除多余空格并对主要单词进行分析处理,将分析得到的二元式存入二元式结果缓冲区。
3.变量处理find()变量处理中首先把以字母开头的字母数字串存到spelling[ ]数组中,然后进行识别。
识别过程是先让它与保留关键字表中的所有关键字进行匹配,若获得成功则说明它为保留关键字,即将其内码值写入二元式结果缓冲区;否则说明其为变量,这时让它与变量名表中的变量进行匹配(变量匹配函数find ()),如果成功,则说明该变量已存在并在二元式结果缓冲区中标记为此变量(值填为该变量在变量名表中的位置),否则将该变量登记到变量名表中,再将这个新变量存入二元式缓存数组中。
4.数字识别number( )数字识别将识别出的数字填入二元式结果缓存数组。
5.显示函数显示函数的功能在屏幕上输出词法分析的结果(即二元式序列程序),同时给出二元式个数及源程序行数统计。
二.语法分析器设计语法分析器的核心是三张SLR 分析表以及针对这三张SLR 分析表进行语义加工的语义动作。
编译程序中语法分析处理及四元式生成部分主要是以二元式作为输入,并通过SLR 分析表对语法分析处理过程进行控制,使四元式翻译的工作有条不紊的进行,同时识别语法分析中的语法错误。
在处理if 和while 语句时,需要进行真值或假值的拉链和返填工作,以便转移目标的正确填入。
1. 控制语句的SLR 分析表1 设计过程如下:将扩展文法G’0)S’ S1)S if e then S else S2)S while e do S3)S begin L end4)S a5)L S6)L S;L用∈_CLOSURE方法构造LR(0)项目规范簇为:. I0:S’·SS ·if e then S else SS ·while e do SS ·begin L endS ·a ;I1: S’ S·I2: S if·e then S else SI3: S while ·e do SI4: S begin·L endL ·SL ·S;LS ·if e then S else SS ·while e do SS ·begin L endS ·aI5: S a·I6: S if e·then S else SI7: S while e·do SI8: S begin L·endI9: L S·L S·;LI10: S if e then ·S else SS ·if e then S else SS ·while e do SS ·begin L endI11: S while e do ·SS ·if e then S else SS ·while e do SS ·begin L endS ·aI12: S begin L end ·I13: L S; ·LL ·SL ·S;LS ·if e then S else SS ·while e do SS ·begin L endS ·aI14: S if e then S·else SI15: S while e do S·I16: L S;L·I17: S if e then S·else SS ·if e then S else SS ·while e do SS ·begin L endS ·aI18: S if e then S else S·构造文法G’中非终结符的FOLLOW集如下:FOLLOW(L) = { end }FOLLOW(S) = {else , ; ,end,#}在LR(0)项目规范簇中,只有I9有“移进――归约”冲突,L S·L S·L因为FOLLOW(L) ∩FIRST(L) = ∮所以可以用SLR方法解决以上冲突,最后我们得到的SLR分析表如下:ACTION GOTO If then else while begin do end a;e#S L 0S2S3S4S511ACC2S63S74S2S3S4S5985R4R3R4R46S107S118S129R5S1310S2S3S4S51411S2S3S4S51512R3R3R3R313S2S3S4S5916 14S1715R2R2R2R216R617S2S3S4S51818R1R1R1R1 static int action[19][13]=/*0*/ {{2,-1,-1,3,4,-1,-1,5,-1,-1,10,1,-1},/*1*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,ACC,-1,-1},/*2*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,6,-1,-1,-1},/*3*/ {-1,-1,-1,-1,-1,-1,-1,-1,-1,7,-1,-1,-1},/*4*/ {2,-1,-1,3,4,-1,-1,5,-1,-1,-1,9,8},/*5*/ {-1,-1,104,-1,-1,-1,104,-1,104,-1,104,-1,-1},/*6*/ {-1,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},/*7*/ {-1,-1,-1,-1,-1,11,-1,-1,-1,-1,-1,-1,-1},/*8*/ {-1,-1,-1,-1,-1,-1,12,-1,-1,-1,-1,-1,-1},/*9*/ {-1,-1,-1,-1,-1,-1,105,-1,13,-1,-1,-1,-1},/*10*/ {2,-1,-1,3,4,-1,-1,5,-1,-1,-1,14,-1},/*11*/ {2,-1,-1,3,4,-1,-1,5,-1,-1,-1,15,-1},/*12*/ {-1,-1,103,-1,-1,-1,103,-1,103,-1,103,-1,-1},/*13*/ {2,-1,-1,3,4,-1,-1,5,-1,-1,-1,9,16},/*14*/ {-1,-1,17,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},/*15*/ {-1,-1,102,-1,-1,-1,102,-1,102,-1,102,-1,-1},/*16*/ {-1,-1,-1,-1,-1,-1,106,-1,-1,-1,-1,-1,-1},/*17*/ {2,-1,-1,3,4,-1,-1,5,-1,-1,-1,18,-1},/*18*/ {-1,-1,101,-1,-1,-1,101,-1,101,-1,101,-1,-1}};其中,前9 列为action 值,后2 列为goto 值;0~16 表示17 个移进状态(即Si);-1表示出错;ACC 表示分析成功;而100~106 对应归约产生式:2. 算术表达式的LR 分析表2 设计如下:0)S’ E1) E E+E2) E E*E3) E (E)ACTION GOTO I+-*/()#E0S3S211S4S11S5S10ACC2S3S263R4R4R4R4R4R44S3S275S3S286S4S11S5S10S97R1R1S5S10R1R18R2R2R2R2R2R29R3R3R3R3R3R310S3S21211S3S21312R6R6R6R6R6R613R5R5S5S10R5R5static int action1[14][9]=/*0*/ {{3,-1,-1,-1,-1,2,-1,-1,1},/*1*/ {-1,4,11,5,10,-1,-1,ACC,-1},/*2*/ {3,-1,-1,-1,-1,2,-1,-1,6},/*3*/ {104,104,104,104,104,104,104,104,-1},/*4*/ {3,-1,-1,-1,-1,2,-1,-1,7},/*5*/ {3,-1,-1,-1,-1,2,-1,-1,8},/*7*/ {101,101,101,5,10,101,101,101,-1},/*8*/ {102,102,102,102,102,102,102,102,-1},/*9*/ {103,103,103,103,103,103,103,103,-1},/*10*/ {3,-1,-1,-1,-1,2,-1,-1,12},/*11*/ {3,-1,-1,-1,-1,2,-1,-1,13},/*12*/ {106,106,106,106,106,106,106,106,-1},/*13*/ {105,105,105,5,10,105,105,105,-1}};3.布尔表达式的SLR 分析表3 设计如下:(过程略)1)S’ B2) B i3) B i rop i4) B ( B )5) B NOT B6) A B AND7) B AB8)O B ORACTION GOTOi Rop()NOT AND OR#B A O 0S1S4S51378 1S2R1R1R1R12S33R2R2R2R24S1S4S51178 5S1S4S5678 6R4S9S10R47S1S4S51478 8S1S4S51578 9R5R5R510R7R7R711S12S9S1012R3R3R3R313S9S10ACC14R6S9S10R615R8S9S10R8static int action2[16][11]=/*0*/ {{1,-1,4,-1,5,-1,-1,-1,13,7,8},/*1*/ {-1,2,-1,101,-1,101,101,101,-1,-1,-1},/*2*/ {3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},/*3*/ {-1,-1,-1,102,-1,102,102,102,-1,-1,-1},/*4*/ {1,-1,4,-1,5,-1,-1,-1,11,7,8},/*6*/ {-1,-1,-1,104,-1,9,10,104,-1,-1,-1},/*7*/ {1,-1,4,-1,5,-1,-1,-1,14,7,8},/*8*/ {1,-1,4,-1,5,-1,-1,-1,15,7,8},/*9*/ {105,-1,105,-1,105,-1,-1,105,-1,-1,-1},/*10*/ {107,-1,107,-1,107,-1,-1,107,-1,-1,-1},/*11*/ {-1,-1,-1,12,-1,9,10,-1,-1,-1,-1},/*12*/ {-1,103,-1,103,-1,103,103,103,-1,-1,-1},/*13*/ {-1,-1,-1,-1,-1,9,10,ACC,-1,-1,-1},/*14*/ {-1,-1,-1,106,-1,9,10,106,-1,-1,-1},/*15*/ {-1,-1,-1,108,-1,9,10,108,-1,-1,-1}};LR 分析表控制语义加工的实现:当扫描LR 分析表的当前状态为归约状态时,则在调用与该状态对应的产生式进行归约的同时,调用相应的语义子程序进行有关的翻译工作。