编译原理实验二zy.docx

上传人:b****6 文档编号:5245808 上传时间:2022-12-14 格式:DOCX 页数:13 大小:17.68KB
下载 相关 举报
编译原理实验二zy.docx_第1页
第1页 / 共13页
编译原理实验二zy.docx_第2页
第2页 / 共13页
编译原理实验二zy.docx_第3页
第3页 / 共13页
编译原理实验二zy.docx_第4页
第4页 / 共13页
编译原理实验二zy.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

编译原理实验二zy.docx

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

编译原理实验二zy.docx

编译原理实验二zy

实验二 语法分析及语义处理实验

专业:

13计算机一班学号:

20130610040109姓名:

赵宇

一、【实验目的】

加深对语法分析器工作过程的理解;能够采用一种编程语言实现简单的语义分析程序;能够使用自己编写的分析程序对简单的程序段进行语义分析,生成中间代码。

二、【实验内容】

1.掌握递归子程序(或过程)的设计方法。

2.掌握用递归子程序法设计语法分析的方法,从而加深对其他方法的理解。

3.掌握目标程序的运行方法,掌握各源程序语句的目标结构。

4.掌握以语法为主导的翻译方法。

5.用递归下降分析法编制语义分析程序。

三、【实验要求】

1.对语法规则有明确的定义;

2.编写的分析程序能够对输入算数表达式进行正确的语义分析;

3.对于遇到的语法、语义错误,能够做出简单的错误处理,给出简单的错误提示,保证语义分析过程;

4.实验报告要求用文法的形式对语义详细说明,说明语义分析程序的工作过程,说明相应翻译动作的实现。

四、【实验步骤】

1.定义语法规则;

2.设置语义过程,插入语义动作;

3.对遇到的语法、语义错误做出错误处理。

五、【算法思想】

1、算术表达式的定义

算术表达式的文法:

〈无符号整数〉∷=〈数字〉{〈数字〉}

〈标识符〉∷=〈字母〉{〈字母〉|〈数字〉}

〈表达式〉∷=〈项〉{〈加法运算符〉〈项〉}

〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉}

〈因子〉∷=〈标志符〉|〈无符号整数〉

〈加法运算符〉∷=+|-

〈乘法运算符〉∷=*|/

〈字母〉∷=a|b|…|z

〈数字〉∷=0|1|…|9

2、构造出相应的文法

E->TE~

E~->+TE~

E~->-TE~

E~->&

T->FT~

T~->*FT~

T~->\FT~

T~->&

F->(E)

F->n

F->z

n表示数字z表示字符

3、设置语义过程。

(1)emit(char*result,char*ag1,char*op,char*ag2)

该函数的功能是生成一个三地址语句送到四元式表中。

四元式表的结构如下:

struct

{charresult[8];

charag1[8];

charop[8];

charag2[8];

}quad[20];

(2)char*newtemp()

该函数回送一个新的临时变量名,临时变量名产生的顺序为T1,T2,…

char*newtemp(void)

{char*p;

charm[8];

p=(char*)malloc(8);

k++;

itoa(k,m,10);

strcpy(p+1,m);

p[0]=’t’;

return(p);

}

4、函数intlrparser()

在原来语法分析的基础上插入相应的语义动作:

将输入串翻译成四元式序列。

在实验中我们只对表达式、赋值语句进行翻译。

5、函数voidscaner()

扫描表达式进行词法分析

6、函数char*expression_r(void)

对加减法进行语义分析,调用term分析产生表达式计算的第一项eplace,调用term分析产生表达式计算的第二项ep2,调用newtemp产生临时变量tp存储计算结果,生成四元式送入四元式表。

7、函数char*term(void)

对乘除进行语义分析,调用factor()分析产生表达式计算的第一项eplace,调用factor分析产生表达式计算的第二项ep2,调用newtemp产生临时变量tp存储计算结果,生成四元式送入四元式表。

8、函数char*factor(void)

对于赋值语句进行语法分析,并返回对应表达式中三元式的地址。

六、【源程序代码】

#include

#include

#include

#include

struct

{

charresult[12];

charag1[12];

charop[12];

charag2[12];

}quad;

charprog[80],token[12];

charch;

intsyn,p,m=0,n,sum=0,kk;//p是缓冲区prog的指针,m是token的指针

char*rwtab[6]={"begin","if","then","while","do","end"};

voidscaner();

char*factor(void);

char*term(void);

char*expression_r(void);

intyucu();

voidemit(char*result,char*ag1,char*op,char*ag2);

char*newtemp();

intstatement();

intk=0;

voidemit(char*result,char*ag1,char*op,char*ag2)

{

strcpy(quad.result,result);

strcpy(quad.ag1,ag1);

strcpy(quad.op,op);

strcpy(quad.ag2,ag2);

cout<

}

char*newtemp()

{

char*p;

charm[12];

p=(char*)malloc(12);

k++;

itoa(k,m,10);

strcpy(p+1,m);

p[0]='t';

return(p);

}

voidscaner()

{

for(n=0;n<8;n++)

token[n]=NULL;

ch=prog[p++];

while(ch=='')

{

ch=prog[p];

p++;

}

if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))

{m=0;

while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))

{

token[m++]=ch;

ch=prog[p++];

}

token[m++]='\0';

p--;

syn=10;

for(n=0;n<6;n++)

if(strcmp(token,rwtab[n])==0){

syn=n+1;

break;

}

}

elseif((ch>='0'&&ch<='9'))

{

sum=0;

while((ch>='0'&&ch<='9')){

sum=sum*10+ch-'0';

ch=prog[p++];

}

p--;

syn=11;

if(sum>32767)

syn=-1;

}

elseswitch(ch)

{

case'<':

m=0;token[m++]=ch;

ch=prog[p++];

if(ch=='>'){

syn=21;

token[m++]=ch;

}

elseif(ch=='='){

syn=22;

token[m++]=ch;

}

else{

syn=23;

p--;

}

break;

case'>':

m=0;token[m++]=ch;

ch=prog[p++];

if(ch=='='){

syn=24;

token[m++]=ch;

}

else{

syn=20;

p--;

}

break;

case':

':

m=0;token[m++]=ch;

ch=prog[p++];

if(ch=='='){

syn=18;

token[m++]=ch;

}

else{

syn=17;

p--;

}

break;

case'*':

syn=13;token[0]=ch;break;

case'/':

syn=14;token[0]=ch;break;

case'+':

syn=15;token[0]=ch;break;

case'-':

syn=16;token[0]=ch;break;

case'=':

syn=25;token[0]=ch;break;

case';':

syn=26;token[0]=ch;break;

case'(':

syn=27;token[0]=ch;break;

case')':

syn=28;token[0]=ch;break;

case'#':

syn=0;token[0]=ch;break;

default:

syn=-1;break;

}

}

intlrparser()

{//cout<<"调用lrparser"<

intschain=0;

kk=0;

if(syn==1){

scaner();

schain=yucu();

if(syn==6){

scaner();

if(syn==0&&(kk==0))

cout<<"success!

"<

}

else{

if(kk!

=1)

cout<<"缺end!

"<

kk=1;

}

}

else

{cout<<"缺begin!

"<

return(schain);

}

intyucu()

{//cout<<"调用yucu"<

intschain=0;

schain=statement();

while(syn==26){

scaner();

schain=statement();

}

return(schain);

}

intstatement()

{//cout<<"调用statement"<

char*eplace,*tt;

eplace=(char*)malloc(12);

tt=(char*)malloc(12);

intschain=0;

switch(syn){

case10:

strcpy(tt,token);

scaner();

if(syn==18){

scaner();

strcpy(eplace,expression_r());

emit(tt,eplace,"","");

schain=0;

}

else{

cout<<"缺少赋值符!

"<

kk=1;

}

return(schain);

break;

}

return(schain);

}

char*expression_r(void)

{

char*tp,*ep2,*eplace,*tt;

tp=(char*)malloc(12);

ep2=(char*)malloc(12);

eplace=(char*)malloc(12);

tt=(char*)malloc(12);

strcpy(eplace,term());//调用term分析产生表达式的第一项eplace

while((syn==15)||(syn==16)){

if(syn==15)strcpy(tt,"+");

elsestrcpy(tt,"-");

scaner();

strcpy(ep2,term());//调用term分析产生表达式的第二项ep2

strcpy(tp,newtemp());//调用newtemp产生临时变量tp存储结果

emit(tp,eplace,tt,ep2);//生成四元式送入四元式表

strcpy(eplace,tp);

}

return(eplace);

}

char*term(void)

{//cout<<"调用term"<

char*tp,*ep2,*eplace,*tt;

tp=(char*)malloc(12);

ep2=(char*)malloc(12);

eplace=(char*)malloc(12);

tt=(char*)malloc(12);

strcpy(eplace,factor());

while((syn==13)||(syn==14)){

if(syn==13)strcpy(tt,"*");

elsestrcpy(tt,"/");

scaner();

strcpy(ep2,factor());/调用factor分析产生表达式的第二项ep2

strcpy(tp,newtemp());//调用newtemp产生临时变量tp存储结果

emit(tp,eplace,tt,ep2);//生成四元式送入四元式表

strcpy(eplace,tp);

}

return(eplace);

}

char*factor(void)

{

char*fplace;

fplace=(char*)malloc(12);

strcpy(fplace,"");

if(syn==10){

strcpy(fplace,token);//将标识符token的值赋给fplace

scaner();

}

elseif(syn==11){

itoa(sum,fplace,10);

scaner();

}

elseif(syn==27){

scaner();

fplace=expression_r();//调用expression分析返回表达式的值

if(syn==28)

scaner();

else{

cout<<"缺)错误!

"<

kk=1;

}

}

else{

cout<<"缺(错误!

"<

kk=1;

}

return(fplace);

}

voidmain()

{

p=0;

cout<<"**********语义分析程序**********"<

cout<<"Pleaseinputstring:

"<

do{

cin.get(ch);

prog[p++]=ch;

}

while(ch!

='#');

p=0;

scaner();

lrparser();

}

七、【结果验证】

(a)给定源程序

begina:

=2+3*4;x:

=(a+b)/cend#

输出结果

**********语义分析程序**********

Pleaseinputstring:

begina:

=2+3*4;x:

=(a+b)/cend#

t1=3*4

t2=2+t1

a=t2

t3=a+b

t4=t3/c

x=t4

success!

(b)源程序

begina:

=9;x:

=2*3-1;b:

=(a+x/2end#

输出结果

**********语义分析程序**********

Pleaseinputstring:

begina:

=9;x:

=2*3-1;b:

=(a+x/2end#

a=9

t1=2*3

t2=t1-1

x=t2

t3=x/2

t4=a+t3

缺)错误!

b=t4

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

当前位置:首页 > 高等教育 > 艺术

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

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