实验三语义分析.docx
《实验三语义分析.docx》由会员分享,可在线阅读,更多相关《实验三语义分析.docx(21页珍藏版)》请在冰豆网上搜索。
实验三语义分析
编译原理实验三语义分析
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();
}