编译原理实验一.docx

上传人:b****2 文档编号:1330484 上传时间:2022-10-20 格式:DOCX 页数:43 大小:88.93KB
下载 相关 举报
编译原理实验一.docx_第1页
第1页 / 共43页
编译原理实验一.docx_第2页
第2页 / 共43页
编译原理实验一.docx_第3页
第3页 / 共43页
编译原理实验一.docx_第4页
第4页 / 共43页
编译原理实验一.docx_第5页
第5页 / 共43页
点击查看更多>>
下载资源
资源描述

编译原理实验一.docx

《编译原理实验一.docx》由会员分享,可在线阅读,更多相关《编译原理实验一.docx(43页珍藏版)》请在冰豆网上搜索。

编译原理实验一.docx

编译原理实验一

实验一编译程序的分析与验证

一、实验目的

了解编译程序中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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 人力资源管理

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1