1、编译原理实验一实验一 编译程序的分析与验证一、实验目的了解编译程序中LR分析表的作用以及语义加工程序的功能二、实验内容(1) 验证下述程序的正确性while (a=n then a:=a+1 else if ji then i=i+j else while k=h do x:=x+2;m:=n+m+x+y+n*m+x*yend#三、编译程序理解输入文件名,取一个字符,程序扫描,词法分析结果打印,变量名表打印,语句分析栈初始化,符号栈初始化,四元式空白初始化,状态栈加工过程及归约顺序,读结果缓冲区中字符到当前字符中,语句分析,四元式分析结果打印,程序运行结束。具体函数功能介绍:char ch=0
2、;/可用于存放读出的一个字符 int count=0;/词法分析结果缓冲区计数器 static char spelling10=;/存放是别的字 static char line81=;/一行字符缓冲区 char *pline;/line的指针 static char ntab110010;/变量类型名表 struct ntab int tc;/真 int fc;/假 ntab2200;/用于存放布尔表达式的值 int label=0;/指向ntab2的指针 struct rwords char sp10;int sy; ;/匹配表结构体 struct rwordsreswords10=if,
3、sy_if, do,sy_do, else,sy_else, while,sy_while, then,sy_then, begin,sy_begin, end,sy_end, and,op_and, or,op_or, not,op_not;/初始化匹配表 ,用于关键字的匹配 struct aa int sy1;/存放变量的类型名 int pos;/存放该变量在自己表中的位置 buf1000,/词法分析结果缓冲区 n,/存放二元式当前字符 n1,/表达式当前的字符 E,/非终结符 sstack100,/算术表达式和布尔表达式的符号栈ibuf100,/算术表达式和布尔表达式的缓冲区 stack
4、1000;/语法分析的符号栈struct aa oth;/四元式中没有填写的空白位置 struct fourexp/四元式结构体 char op10; struct aa arg1; struct aa arg2; int result;fexp200;int ssp=0;/指向 sstack的指针 struct aa *pbuf=buf;/词法分析结果缓冲区的指针 int nlength=0;/词法分析中记录单词的长度 int lnum=0;/行数计数源程序 int tt1=0;/变量类型名表的指针 FILE *c源程序文件 /*/int newt=0;/临时变量计数器 int nxq=10
5、0;/总是指向下一个要形成的四元式 每次执行gen() int lr;/用于存放action1中的当前状态 int lr1;/用于存放action2,3中的当前状态 int sp=0;/LR分析表栈顶指针 int stack1100;/状态栈1 int sp1=0;/状态栈的指针 int num=0;/算术表达式或布尔表达式的指针 struct ll int nxq1;/指向下一条四元式的指针 int tc1;/真值链 int fc1;/假值链 labelmark10;/记录嵌套中每层布尔表达式e的首地址 int labeltemp10;/记录每层else之前四元式的地址 int pointm
6、ark=-1,pointtemp=-1;/labelmark的指针,labelmark的指针 int sign=0;/ sign=1 赋值语句,sign=2 while语句,sign=3 if语句构造程序语句的LR分析表算术表达式的LR分析表布尔表达式的LR分析表readline()/读一行 char ch1;pline=line; ch1=fgetc(c从文件中取一个 while(ch1!=n)&(ch1!=EOF)/把字符缓冲区填满 *pline=ch1;pline+; ch1=fgetc(cfile); *pline=0;/结尾终结符 pline=line;/字符缓冲区指针重新回到字符缓
7、冲区的第一个字符位置 /*从缓冲区读取一个字符*/readch()/读一个 if(ch=0)/读到尾姐再来一行,行数加一 readline();lnum+; ch=*pline;/从行缓冲区读取一个字符pline+;/字符缓冲区指针后移 /*标识符和关键字的识别*/find(char spel)/在变量表中查询 int ss1=0;/ 是否查到的变量的标志(1为查到,0为没查到) int ii=0;/记录查到变量表第几条 while(ss1=0)&(ii=a)&(ch=0)&(ch=9);/数字或小写字母 pline-;/取字时多加的一个,-1可使 *pline指向字符缓冲区行尾 spelli
8、ngk=0; while(ss=0)&(iii10) if(!strcmp(spelling,reswordsiii.sp)/在关键字表中查询 ss=1;/查到标志置1 iii+; /*关键字匹配*/ if(ss=1)/在关键字表中查到 bufcount.sy1=reswordsiii-1.sy;/关键字名字放入结果缓冲区 else/没查到 bufcount.sy1=ident;/将变量名置入结果缓冲区 j=find(spelling);/变量表查询 ,查到就把变量在变量表的地址赋给j if(j=-1)/没查到就新建一个变量 bufcount.pos=tt1;/将其在变量表中的地址放入结果缓冲
9、区中的地址栏 strcpy(ntab1tt1,spelling);/将识别的变量名放入变量名表 tt1+;nlength+;/变量名表长加一 else bufcount.pos=j;/查到后,将变量名表中变量的地址放入结果缓冲区该变量的地址栏中 count+;/指向结果缓冲区下一位置 for(k=0;k=0)&(ch=9);bufcount.sy1=intconst;/常量名存入结果缓冲区bufcount.pos=ivalue;/该常量地址存入结果缓冲区 count+;/ 向结果缓冲区下一位置 pline-;/指向行缓冲区尾字符 scan()/扫描主程序readnu()/读取当前结果缓冲区的二
10、元式存入struct aa n中 ,pbuf指向结果缓冲区中下一位置的指针newtemp()/返回目前临时变量数gen(char op1,struct aa arg11,struct aa arg22,int result1)/op1算符,arg11操作数1,arg22操作数2, result1结果merg(int p1,int p2)/ 将链首“指针”分别为p1和p2的两条链合并为一条,并返回新链的链首“指针”(此处的“指针”实际上是四元式的序号,应为整型值)backpatch(int p,int t)/用四元式序号t回填以p为首的链,将链中每个四元式的Result域改写为t的值。chang
11、e1(int chan)/action1的符号查找排序(i,+,*,(,),#,E,-,/)change2(int chan)/action2的符号查找排序lrparse1(int num)/算数表达式语义分析lrparse2(int num)/ 布尔表达式的分析test(int value)/ 测试字符是否为表达式中的值(不包括:)lrparse()/程序语句分析disp1()/打印词法分析结果disp2()/打印四元式分析结果disp3()/打印变量表名main()/主函数四、A语言程序分析与验证五、源码(带注释)#include stdio.h#include string.h#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_e
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1