实验三语义分析.docx

上传人:b****1 文档编号:3218185 上传时间:2023-05-05 格式:DOCX 页数:21 大小:66.95KB
下载 相关 举报
实验三语义分析.docx_第1页
第1页 / 共21页
实验三语义分析.docx_第2页
第2页 / 共21页
实验三语义分析.docx_第3页
第3页 / 共21页
实验三语义分析.docx_第4页
第4页 / 共21页
实验三语义分析.docx_第5页
第5页 / 共21页
实验三语义分析.docx_第6页
第6页 / 共21页
实验三语义分析.docx_第7页
第7页 / 共21页
实验三语义分析.docx_第8页
第8页 / 共21页
实验三语义分析.docx_第9页
第9页 / 共21页
实验三语义分析.docx_第10页
第10页 / 共21页
实验三语义分析.docx_第11页
第11页 / 共21页
实验三语义分析.docx_第12页
第12页 / 共21页
实验三语义分析.docx_第13页
第13页 / 共21页
实验三语义分析.docx_第14页
第14页 / 共21页
实验三语义分析.docx_第15页
第15页 / 共21页
实验三语义分析.docx_第16页
第16页 / 共21页
实验三语义分析.docx_第17页
第17页 / 共21页
实验三语义分析.docx_第18页
第18页 / 共21页
实验三语义分析.docx_第19页
第19页 / 共21页
实验三语义分析.docx_第20页
第20页 / 共21页
亲,该文档总共21页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

实验三语义分析.docx

《实验三语义分析.docx》由会员分享,可在线阅读,更多相关《实验三语义分析.docx(21页珍藏版)》请在冰点文库上搜索。

实验三语义分析.docx

实验三语义分析

编译原理实验三语义分析

1.实验目的

通过实验掌握语法制导分析的翻译理论、原理和方法,为为代码优化、生成做准备。

2.实验内容:

选择所学过的语义分析技术之一实现下面文法G的语义分析程序。

文法G:

简单算术表达式的文法

E→T{+T|-T}

T→F{*F|/F}

F→(E)|a|b|c

简单算术表达式的运算分量只能是单词符号a、b、c

要求:

如果是文法正确句子,输出相应的四元组

输出是

Error不是文法正确句子

例如

输入a+b*c#输出(*,entry(b),entry(c),t1)

(+,entry(a),t1,t2)

输入a+c+b*c-a#输出(+,entry(a),entry(c),t1)

(*,entry(b),entry(c),t2)

(+,t1,t2,t3)

(-,t3,entry(a),t4)

输入d+f#输出error

输入a+b*+c#输出error

输入a(b)#输出error

3.实验要求:

(1)上机前编写完整的实验报告,报告中要体现分析设计实现等几个过程;如无实验报告,则取消本次上机资格,实验成绩以0分记。

(2)严禁相互抄袭,否则实验成绩以0分记;

(3)有完整的源代码,源码有规范的注释,无明显的语法错误;

4.实验步骤

(1)分析与设计

(2)

1设置语义过程

(1)emit(char*result,char*arg1,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);

}

(3)编码实现

//对字符的扫描

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')){

if((ch>='a'&&ch<='c')||(ch>='A'&&ch<='C')){

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;

}

}

}

else

cout<<"Error!

"<

}

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;

}

}

(4)系统调试

5.实验总结

通过试验结果可以看出,这个程序实现了输出为三地址指令形式的四元式序列。

通过上机实验,加深了对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法。

以及还复习了对vc的应用。

附完整源代码:

#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(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<

cout<<"("<

//cout<<"entry("<

}

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')){

if((ch>='a'&&ch<='c')||(ch>='A'&&ch<='C')){

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;

}

}

}

else

cout<<"Error!

"<

}

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();

//cout<<"SYN="<

if(syn==6){

scaner();

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

cout<<"success!

"<

}

/*else

{

if(kk!

=1)

cout<<"缺end!

"<

kk=1;

}*/

}

else

{

cout<<"Error!

"<

kk=1;

}

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());

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

schain=0;

/*}

else{

cout<<"缺少赋值符!

"<

kk=1;

}*/

return(schain);

break;

}

return(schain);

}

char*expression(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,"+");

else

strcpy(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);

scaner();

}

elseif(syn==11){

itoa(sum,fplace,10);

scaner();

}

elseif(syn==27){

scaner();

fplace=expression();

//调用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();

}

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

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2