0 0 0 0 54 0 0 0 0 0 0 0 0
0 0 0 0 55 0 0 0 0 0 0 0 0
0 0 0 0 0 56 58 0 0 0 0 63 64
0 0 0 0 0 0 57 0 0 0 0 0 0
0 0 0 0 0 0 58 59 0 0 0 63 64
0 0 0 0 0 0 58 0 60 0 0 63 64
0 0 0 0 0 0 58 0 0 61 0 63 64
每个产生式大括号中的内容便是该产生式的select集合。可以看出同一产生式select集合不相交即为LL(1)文法。根据上述集合即可构造出LL(1)分析表,由于产生式数目较多, LL(1)分析器主要由LL(1)分析表和LL(1)控制程序两部分构成:LL(1)分析表是存储文法select集合的知识表,可通过预先设置的语法栈的栈顶符和当前扫描的单词来确定产生式的序号,从而进行下一步判断或者压栈操作。
37
其后的语法分析主函数便是根据上述所写的分析表,获取要分析单词,与堆栈区栈顶然后进入分析表,按照分析表所写进行入栈出栈,完成分析即认为语法无错误,否则则认为有错误,发现情况无法对应分析表时也认为是发生了错误。 3.3.5运行截图
可以直观地看出LL(1)的分析过程,可以看出对于一个稍微简单的文法,LL(1)分析过程需要多步才能判断完全。至此,LL(1)分析方法设计完成。
3.4符号表生成模块 (负责人:孙何奇) 3.4.1 功能 1.构建活动记录表 2.构建符号表 3.构建函数表 4.构建长度表
38
5.添加活动记录 6.添加变量表 7.符号表预处理 8.添加函数表 9.添加参数表
10.构建活动记录与变量表(二合一)
符号表是在目标代码生成中不可以缺少的提供查询服务的表,在其中记录了程序收集,记录于使用的源程序的语法符号的类型、特征等相关信息,信息集中反映了标识符的语义特征属性。在词法分析及语法在分析过程中不断积累和更新表中的信息,并在词法分析到代码生成的各阶段,按各自的需要从表中获取不同的属性信息。在本次课设中,符号表的作用和地位是重要关键的。
符号表是一个编译器的核心数据结构,它代表了标识符的动态语义词典,属于编译中语义分析的知识库。符号表中所登记的信息在编译的不同阶段都要用到,对于一个多遍扫描的编译程序,不同遍所用的符号表也往往各有不同,因为每遍所关心的信息各有差异。符号表的组织方式也决定了未来处理符号表内容时的效率。我所设计的符号表生成器能够在定义标识符时把对应的语义信息填入符号表中;当在语句中使用该标识符时,通过查找相应的表项来判断该标识符是否存在且使用正确。符号表常见的功能有定义和重定义检查、类型匹配校验、数据的越界和溢出检查、值单元存储分配信息和函数的参数传递与校验。由于时间有限,我设计的符号表系统只完成了上述功能中的一部分。 3.4.2 数据结构
在编译程序中,符号表项的组织传统上采用三种构造方法:
39
①线性组织
②排列组织及二分法 ③散列组织
线性表按符号扫描的顺序有序填入,但在查询时效率较低;排列表按
首字符大小来填写符号表,查询效率较高,但填写时实现较复杂。因此,散列表可以通过一定的散列函数来实现符号表的高效填写和查询。至此,我们可以写出符号表总体的数据结构: char variate[16][15] = {};/*变量表*/
enumTYP{in,real,ch,b,default1};/*类型,包括int,float,char,bool型*/
enumCAT{f,con,t,d,v,vn,vf,default2};/*种类,包括f函数,c常量,t类型,d域名,v变量,vn换名形参,vf,赋值形参*/
enumADDR{PFINFL,LENL,VALL,default3};/*地址表,包括函数表,活动记录表*/
int idlocate[16];/*记录标识符在代码中首次出现的位置*/structsymbol {/*符号表*/ };
structpfinfl {/*函数表*/
char name[15]; TYP type; CAT kind; ADDR addr;
int level; int off;
40
相关推荐: