一、课程设计(综合实验)的目的与要求
通过设计、编写和调试词法分析程序,了解词法扫描器的组成结构、不同种类单词的识别方法,掌握由单词的词法规则出发,利用程序实现词法扫描器的方法。通过设计、编写和调试语法分析程序,了解语法分析器的组成结构以及对文法的要求,掌握基于LL(1)文法和算符优先文法的语法分析程序的实现方法。通过设计、编写和调试语法制导翻译程序,掌握从语句的语法出发,构造相应的语义子程序,实现自定义语言的语法制导翻译。
二、设计(实验)正文
第二,定义了3个vector
第三,定义了两个数组int v3[100][2],v4[100][2],来存放词法表和符号表。其中符号表第二位不存储符号具体的值,而是存放符号在v5中的位置,读取时通过位置从v5中找到具体的符号。
第四,定义了5个整数int point1=0,point2=0,head1=1,head2=101,whichone=1。其中point1指向v3数组中要新增一行的位置。point2是指向v4数组要新增一行的位置。head1是符号表中下一标识符应在的位置,head2是符号表中下一数字应在的位置。 whichone是在读取到数字时根据其中是否有小数点定义值,供后续判断。
第一,打开文件按字符读文件,每次读一个,在未读取到终结符前循环执行。每次读取一个字符,先判断此处是否为注释,若存在连续的两个‘/’‘/’符号表示此处往后一行都是注释,循环读完此行,不写入数组。其他情况将字符依次写入数组v1。
第二,从数组v1中依次读一个字符,当未读完时,循环执行。读出一个后首先判断是否为字母,如果是字母则接着连续判断接下来是否为字母或数字或下划线,当不是其中之一时停止。停止前读取的字符都进入v2存储,停止后,将v2转为字符串后清空。调用子函数判断该字符串是否为关键字,若是关键字则更新词法表,若不是关键字则是标识符,更新符号表v4和词法表v3和v5。然后循环到开头。
第三,如果从v1中读到的字符不是字母,但该字符是数字则接着判断接下来是否为连续的数字或小数点,判断到不是其中之一时停止,其中读到小数点时将whichone置2。停止前所有读到的字符都进入v2。将v2转为字符串然后清空。通过whichone判断该数字为整形还是实型,然后判断词法表中是否已存在,更新词法表v4,符号表v3和v5。然后循环到开头读字符。
第四,如果从v1中读取的字符不是字母也不是数字,但为算符或界符,则接着判断是否为双字符算符,将得到的算符或界符更新词法表v3。然后循环到开头读字符。
第五,如果从v1中读到的字符不是字母,不是数字,也不是算符或界符,则为无效字符,忽略,指针加一,直接循环到开头读字符。
第六,当v1中的字符操作完时,将词法表v3中的内容写入token.txt文件中,通过符号表v4第二列找到v5中对应的具体符号或数字,结合符号表v4写入symbol.txt文件。整个程序结束。
第一,定义了一个node结构,有name和addr两个属性,分别存放词法表每行的单词名和地址。
第一,对Program语法单位,有3条语法,对应程序中3个函数。void Program()方法实现<程序>对应的语法,开始先point加4,跳过main,(,),{四个字符,然后递归调用StateList()函数,表示递归分析了<语句列表>语法,接下来如果下一个字符是}则表示识别到完整Program语法单位,point加1然后写入文件Program语法单位,否则输出错误标志。同理,void State()函数对应<语句列表>这条语法,先递归调用SingleSta(),表示递归分析了<单语句>语法结构,接着判断下一字符如果不是}则表明程序未结束,递归调用自身。void SingleSta()函数对应<单语句>对应的语法,根据下一个读到的单词来判断调用哪个函数。其他函数同理实现递归分析。
第一,定义了3个结构体:node,MyE,MyS。node结构同实验二。MyE结构对应课本表6-14中的E,有两个属性vector
第二,定义了一个vector
第三,定义了三个int类型的变量point=0,nowpoint=1,pointtemp=201。Point指向当前arr数组读到的位置。nowpoint相当于课本中的nextquad,来指向语义数组中下一条存放的位置。pointtemp指向下一个生成的临时变量序号,从201开始。
第一,将一些函数由void类型改为int或MyE或MyS类型。这样在递归调用函数时返回的就是int,MyE,MyS类型的变量,进而实现属性的传递。
第二,在函数中增加了并链和属性的传递,以<布尔项>函数举例,在语义分析时,需要设置E.true=merge(E1.true,E2.true),E.false=E2.false。通过循环将E1.True数组中的内容和E2.True数组中的内容加入E.True数组中,实现并链。通过循环将E2属性E2.False数组中的内容加入E.False数组中,实现属性的传递。其他函数同理实现并链和属性传递。
第三,在函数中加入了回填。以<布尔项>函数举例,在语义分析时,需要实现backpatch(E.false,M.quad),此时以循环的方式读出E.False数组中的每一个E.False[i],并将arr数组中对应的arr[E.False[i]][3]更改为Mq,实现回填。其他函数同理实现回填。
第四,在函数中加入了表达式的生成。以<关系式>函数举例,在语义分析时需要实现emit(‘j’relop.op’,’id1.place’,’id2.place’,’’0’),emit(‘j,_,_,0’)。通过函数返回值找到arg1,arg2,op,然后设置arr1[nowpoint][0]=op, arr1[nowpoint][1]=arg1, arr1[nowpoint][2]=arg2, arr1[nowpoint][3]=0来实现一条四元式的添加,第二条同理。其他函数同理生成四元式。
三、课程设计(综合实验)总结或结论
四、参考文献
附录(设计流程图、程序、表格、数据等)