编译原理实验一.docx
- 文档编号:1330484
- 上传时间:2022-10-20
- 格式:DOCX
- 页数:43
- 大小:88.93KB
编译原理实验一.docx
《编译原理实验一.docx》由会员分享,可在线阅读,更多相关《编译原理实验一.docx(43页珍藏版)》请在冰豆网上搜索。
编译原理实验一
实验一编译程序的分析与验证
一、实验目的
了解编译程序中LR分析表的作用以及语义加工程序的功能
二、实验内容
(1)验证下述程序的正确性
while(a<=b)do
begin
ifm>=nthena:
=a+1
else
ifj>itheni=i+j
else
whilek=hdox:
=x+2;
m:
=n+m+x+y+n*m+x*y
end#~
三、编译程序理解
输入文件名,取一个字符,程序扫描,词法分析结果打印,变量名表打印,语句分析栈初始化,符号栈初始化,四元式空白初始化,状态栈加工过程及归约顺序,读结果缓冲区中字符到当前字符中,语句分析,四元式分析结果打印,程序运行结束。
具体函数功能介绍:
charch='\0';//可用于存放读出的一个字符
intcount=0;//词法分析结果缓冲区计数器
staticcharspelling[10]={""};//存放是别的字
staticcharline[81]={""};//一行字符缓冲区
char*pline;//line的指针
staticcharntab1[100][10];//变量类型名表
structntab
{
inttc;//真
intfc;//假
}ntab2[200];//用于存放布尔表达式的值
intlabel=0;//指向ntab2的指针
structrwords
{
charsp[10];
intsy;
};//匹配表结构体
structrwordsreswords[10]={{"if",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}};//初始化匹配表,用于关键字的匹配
structaa
{
intsy1;//存放变量的类型名
intpos;//存放该变量在自己表中的位置
}buf[1000],//词法分析结果缓冲区
n,//存放二元式当前字符
n1,//表达式当前的字符
E,//非终结符
sstack[100],//算术表达式和布尔表达式的符号栈
ibuf[100],//算术表达式和布尔表达式的缓冲区
stack[1000];//语法分析的符号栈
structaaoth;//四元式中没有填写的空白位置
structfourexp//四元式结构体
{
charop[10];
structaaarg1;
structaaarg2;
intresult;
}fexp[200];
intssp=0;//指向sstack的指针
structaa*pbuf=buf;//词法分析结果缓冲区的指针
intnlength=0;//词法分析中记录单词的长度
intlnum=0;//行数计数源程序
inttt1=0;//变量类型名表的指针
FILE*c源程序文件
/********************************************************/
intnewt=0;//临时变量计数器
intnxq=100;//总是指向下一个要形成的四元式每次执行gen()
intlr;//用于存放action1中的当前状态
intlr1;//用于存放action2,3中的当前状态
intsp=0;//LR分析表栈顶指针
intstack1[100];//状态栈1
intsp1=0;//状态栈的指针
intnum=0;//算术表达式或布尔表达式的指针
structll
{
intnxq1;//指向下一条四元式的指针
inttc1;//真值链
intfc1;//假值链
}labelmark[10];//记录嵌套中每层布尔表达式e的首地址
intlabeltemp[10];//记录每层else之前四元式的地址
intpointmark=-1,pointtemp=-1;//labelmark的指针,labelmark的指针
intsign=0;//sign=1赋值语句,sign=2while语句,sign=3if语句
构造程序语句的LR分析表
算术表达式的LR分析表
布尔表达式的LR分析表
readline()//读一行
{
charch1;
pline=line;
ch1=fgetc(c从文件中取一个
while((ch1!
='\n')&&(ch1!
=EOF))//把字符缓冲区填满
{
*pline=ch1;
pline++;
ch1=fgetc(cfile);
}
*pline='\0';//结尾终结符
pline=line;//字符缓冲区指针重新回到字符缓冲区的第一个字符位置
}
/**********************从缓冲区读取一个字符*********************/
readch()//读一个
{
if(ch=='\0')//读到尾姐再来一行,行数加一
{
readline();
lnum++;
}
ch=*pline;//从行缓冲区读取一个字符
pline++;//字符缓冲区指针后移
}
/***********************标识符和关键字的识别********************/
find(charspel[])//在变量表中查询
{
intss1=0;//是否查到的变量的标志(1为查到,0为没查到)
intii=0;//记录查到变量表第几条
while((ss1==0)&&(ii { if(! strcmp(spel,ntab1[ii])) ss1=1; ii++; } if(ss1==1)//查到了 returnii-1;//返回在表量表的地址(-1的原因是上面的ii++最后多加了一次) elsereturn-1;//没查到,返回-1 } identifier()//关键字或变量或常量查询 { intiii=0,j,k;//iii关键字表中的指针位置 intss=0;//关键字是否匹配到的标识 k=0;//存放的识别的字的指针(spelling[k]) do//将取出的字符放入识别的字spelling数组中 { spelling[k]=ch; k++; readch();//取一个字符 }while(((ch>='a')&&(ch<='z'))||((ch>='0')&&(ch<='9')));//数字或小写字母 pline--;//取字时多加的一个,-1可使*pline指向字符缓冲区行尾 spelling[k]='\0'; while((ss==0)&&(iii<10)) { if(! strcmp(spelling,reswords[iii].sp))//在关键字表中查询 ss=1;//查到标志置1 iii++; } /*关键字匹配*/ if(ss==1)//在关键字表中查到 { buf[count].sy1=reswords[iii-1].sy;//关键字名字放入结果缓冲区 } else//没查到 { buf[count].sy1=ident;//将变量名置入结果缓冲区 j=find(spelling);//变量表查询,查到就把变量在变量表的地址赋给j if(j==-1)//没查到就新建一个变量 { buf[count].pos=tt1;//将其在变量表中的地址放入结果缓冲区中的地址栏 strcpy(ntab1[tt1],spelling);//将识别的变量名放入变量名表 tt1++; nlength++;//变量名表长加一 } elsebuf[count].pos=j;//查到后,将变量名表中变量的地址放入结果缓冲区该变量的地址栏中 } count++;//指向结果缓冲区下一位置 for(k=0;k<10;k++)spelling[k]='';//以识别的临时字符清空 } /**********************数字识别*************************/ number() { intivalue=0; intdigit; do { digit=ch-'0';//取出的字符转换为数字 ivalue=ivalue*10+digit;//数字地址从10后开始记录 readch();//取一个字符 }while((ch>='0')&&(ch<='9')); buf[count].sy1=intconst;//常量名存入结果缓冲区 buf[count].pos=ivalue;//该常量地址存入结果缓冲区 count++;//向结果缓冲区下一位置 pline--;//指向行缓冲区尾字符 } scan()//扫描主程序 readnu()//读取当前结果缓冲区的二元式存入structaan中,pbuf指向结果缓冲区中下一位置的指针 newtemp()//返回目前临时变量数 gen(charop1[],structaaarg11,structaaarg22,intresult1)//op1算符,arg11操作数1,arg22操作数2,result1结果 merg(intp1,intp2)//将链首“指针”分别为p1和p2的两条链合并为一条,并返回新链的链首“指针”(此处的“指针”实际上是四元式的序号,应为整型值) backpatch(intp,intt)//用四元式序号t回填以p为首的链,将链中每个四元式的Result域改写为t的值。 change1(intchan)//action1的符号查找排序(i,+,*,(,),#,E,-,/) change2(intchan)//action2的符号查找排序 lrparse1(intnum)//算数表达式语义分析 lrparse2(intnum)//布尔表达式的分析 test(intvalue)//测试字符是否为表达式中的值(不包括": ") lrparse()//程序语句分析 disp1()//打印词法分析结果 disp2()//打印四元式分析结果 disp3()//打印变量表名 main()//主函数 四、A语言程序分析与验证 五、源码(带注释) #include"stdio.h" #include"string.h" #defineACC-2 /**************************************/ #definesy_if0 #definesy_then1 #definesy_else2 #definesy_while3 #definesy_begin4 #definesy_do5 #definesy_e
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 实验