天津理工大学编译原理实验3语义分析与中间代码生成.docx
《天津理工大学编译原理实验3语义分析与中间代码生成.docx》由会员分享,可在线阅读,更多相关《天津理工大学编译原理实验3语义分析与中间代码生成.docx(28页珍藏版)》请在冰豆网上搜索。
天津理工大学编译原理实验3语义分析与中间代码生成
实验报告
学院(系)名称:
计算机与通信工程学院
姓名
学号
专业
班级
实验项目
实验三:
语义分析与中间代码生成
课程名称
编译原理
课程代码
实验时间
实验地点
计算机软件实验室7-220
计算机软件实验室7-215
批改意见
成绩
教师签字:
实验内容:
可选择LL1分析法、算符优先分析法、LR分析法之一,实现如下表达式文法的语法制导翻译过程。
文法G[E]如下所示:
E→E+T|E-T|T
T→T*F|T/F|F
F→P^F|P
P→(E)|i
要求构造出符合语义分析要求的属性文法描述,并在完成实验二(语法分析)的基础上,进行语义分析程序设计,最终输出与测试用例等价的四元式中间代码序列。
实验目的:
1.掌握语法制导翻译的基本功能。
2.巩固对语义分析的基本功能和原理的认识。
3.能够基于语法制导翻译的知识进行语义分析。
4.掌握类高级语言中基本语句所对应的语义动作。
5.理解并处理语义分析中的异常和错误。
实验要求:
1.在实验二的基础上,实现语法制导翻译功能,输出翻译后所得四元式序列;
2.要求详细描述所选分析方法进行制导翻译的设计过程;
3.完成对所设计分析器的功能测试,并给出测试数据和实验结果;
4.为增加程序可读性,请在程序中进行适当注释说明;
5.整理上机步骤,总结经验和体会;
6.认真完成并按时提交实验报告。
【实验过程记录(源程序、测试用例、测试结果及心得体会等)】
#include
#include
#definesize1024
usingnamespacestd;
intstep=0;
typedefstructvariable_T
{
charoperate;//操作符
stringvar1;//变量1
stringvar2;//变量2
intnum;//第几个变量
}variable_T;
variable_Tt[size];//记录四元式变量的变量
inttsize=-1;//表示是第tsize+1个变量
typedefstructchar_stack
{
charcontent;//当前字符
stringendchar;//这个符号代表的中间变量可以是i,也可以是t1,t2,等等
intnum;//和该字符相关的中间变量的序号
}char_stack;
stringtable[19][13]={//+-*/^)#(iETFP
/*0*/"err","err","err","err","err","err","err","s5","s6","1","2","3","4",
/*1*/"s7","s8","err","err","err","err","acc","err","err","err","err","err","err",
/*2*/"r3","r3","s9","s10","err","r3","r3","err","err","err","err","err","err",
/*3*/"r6","r6","r6","r6","err","r6","r6","err","err","err","err","err","err",
/*4*/"r8","r8","r8","r8","s11","r8","r8","err","err","err","err","err","err",
/*5*/"err","err","err","err","err","err","err","s5","s6","c","2","3","4",
/*6*/"r10","r10","r10","r10","r10","r10","r10","err","err","err","err","err","err",
/*7*/"err","err","err","err","err","err","err","s5","s6","err","d","3","4",
/*8*/"err","err","err","err","err","err","err","s5","s6","err","e","3","4",
/*9*/"err","err","err","err","err","err","err","s5","s6","err","err","f","4",
/*10*/"err","err","err","err","err","err","err","s5","s6","err","err","g","4",
/*11*/"err","err","err","err","err","err","err","s5","s6","err","err","h","4",
/*12*/"s7","s8","err","err","err","s18","err","err","err","err","err","err","err",
/*13*/"r1","r1","s9","s10","err","r1","r1","err","err","err","err","err","err",
/*14*/"r2","r2","s9","s10","err","r2","r2","err","err","err","err","err","err",
/*15*/"r4","r4","r4","r4","err","r4","r4","err","err","err","err","err","err",
/*16*/"r5","r5","r5","r5","err","r5","r5","err","err","err","err","err","err",
/*17*/"r7","r7","r7","r7","err","r7","r7","err","err","err","err","err","err",
/*18*/"r9","r9","r9","r9","r9","r9","r9","err","err","err","err","err","err"};
intgetLength(charstr[size])
{
inti=0;
while(str[i]!
='\0')
i++;
returni;
}
intgetLengthc(char_stackstr[size])
{
inti=0;
while(str[i].content!
='\0')
i++;
returni;
}
intgetstringLength(stringstr)
{
inti=0;
while(str[i]!
='\0')
i++;
returni;
}
chargettop(charstack[size],inttop)
{
if(stack[top]!
='\0')
returnstack[top];
else
return'#';
}
voidpopstack(char*stack,int*pointer,inttimes)
{
intp;
for(inti=1;i<=times;i++)
{
p=*pointer;
stack[p]='\0';
(*pointer)--;
}
}
voidpopstackc(char_stack*stack,int*pointer,inttimes)
{
intp;
for(inti=1;i<=times;i++)
{
p=*pointer;
stack[p].content='\0';
(*pointer)--;
}
}
voidpushstack(char_stack*stack,int*pointer,char*stack_state,int*pointer_state,charstr,charsx,intx)
{
inti=0;
if(x==0)
cout<<"\t\t\t状态"<elseif(x==1)
cout<<"状态"<if(str!
='#')
{
cout<(*pointer)++;
stack[(*pointer)].content=str;
}
(*pointer_state)++;
stack_state[(*pointer_state)]=sx;
}
intgetcol(chartop)
{
switch(top)
{
case'+':
return0;
case'-':
return1;
case'*':
return2;
case'/':
return3;
case'^':
return4;
case')':
return5;
case'#':
return6;
case'(':
return7;
case'i':
return8;
case'E':
return9;
case'T':
return10;
case'F':
return11;
case'P':
return12;
default:
cout<<"Error!
Thischaracterstringisnotthisgrammer`ssentence."<return-1;
}
}
intgetraw(charraw)
{
switch(raw)
{
case'0':
return0;
case'1':
return1;
case'2':
return2;
case'3':
return3;
case'4':
return4;
case'5':
return5;
case'6':
return6;
case'7':
return7;
case'8':
return8;
case'9':
return9;
case'a':
return10;
case'b':
return11;
case'c':
return12;
case'd':
return13;
case'e':
return14;
case'f':
return15;
case'g':
return16;
case'h':
return17;
case'i':
return18;
default:
cout<<"Error!
Thischaracterstringisnotthisgrammer`ssentence."<return-1;
}
}
chargetraw_content(stringstr)
{
if(str=="1")
return'1';
elseif(str=="2")
return'2';
elseif(str=="3")
return'3';
elseif(str=="4")
return'4';
elseif(str=="c")
return'c';
elseif(str=="d")
return'd';
elseif(str=="e")
return'e';
elseif(str=="f")
return'f';
elseif(str=="g")
return'g';
elseif(str=="h")
return'h';
elseif(str=="i")
return'i';
}
stringget_tx(intnum)
{
switch(num)
{
case1:
return"t1";
case2:
return"t2";
case3:
return"t3";
case4:
return"t4";
case5:
return"t5";
case6:
return"t6";
case7:
return"t7";
case8:
return"t8";
case9:
return"t9";
case10:
return"t10";
case11:
return"t11";
case12:
return"t12";
case13:
return"t13";
case14:
return"t14";
case15:
return"t15";
case16:
return"t16";
//......本程序暂时用到这么多,等有时间编写合适的可以将数字转换为字符串的函数时,即可更改本函数
}
}
voidshow(charstr[size],intindex)
{
intlength=getLength(str);
if(index!
=-1)
cout<<"\t";
for(inti=index+1;icout<}
voidshowc(char_stackstr[size],intindex)
{
intlength=getLengthc(str);
if(index!
=-1)
cout<<"\t";
for(inti=index+1;icout<}
voidswitch_method(char_stack*stack,int*pointer,char*state_stack,int*pointer_state,stringproduction,char*str,int*index)
{
step++;
cout<<"\n"<show(state_stack,-1);//显示状态栈
cout<<"\t";
showc(stack,-1);//显示符号站
cout<<"\t"<show(str,(*index));//显示输入串
charc=str[(*index)];
if(production=="err")
{
cout<<"Error!
Thischaracterstringisnotthisgrammer`ssentence."<return;
}
elseif(production=="s5")
{
charsx='5';
(*index)++;
pushstack(stack,pointer,state_stack,pointer_state,c,sx,0);
}
elseif(production=="s6")
{
charsx='6';
(*index)++;
pushstack(stack,pointer,state_stack,pointer_state,c,sx,0);
}
elseif(production=="s7")
{
charsx='7';
(*index)++;
pushstack(stack,pointer,state_stack,pointer_state,c,sx,0);
}
elseif(production=="s8")
{
charsx='8';
(*index)++;
pushstack(stack,pointer,state_stack,pointer_state,c,sx,0);
}
elseif(production=="s9")
{
charsx='9';
(*index)++;
pushstack(stack,pointer,state_stack,pointer_state,c,sx,0);
}
elseif(production=="s10")
{
charsx='a';
(*index)++;
pushstack(stack,pointer,state_stack,pointer_state,c,sx,0);
}
elseif(production=="s11")
{
charsx='b';
(*index)++;
pushstack(stack,pointer,state_stack,pointer_state,c,sx,0);
}
elseif(production=="s18")
{
charsx='i';
(*index)++;
pushstack(stack,pointer,state_stack,pointer_state,c,sx,0);
}
elseif(production=="r1")
{
intpo=(*pointer);//用P规约该表达式,有效变量在E的endchar中,需要找到E的位置,即下面的操作
stringst=stack[po].endchar;//对应F
po-=2;
stringse=stack[po].endchar;//在规约之前记录下要规约的字符所代表的变量。
对应T
tsize++;//新增临时变量
t[tsize].num=tsize+1;//下面四个表达式是按照上面的规约式进行的赋值
t[tsize].operate='+';
t[tsize].var1=se;
t[tsize].var2=st;
cout<<"\t("<intp=(*pointer_state);
p-=3;
charsecond=state_stack[p];
inti=getraw(second);
intj=getcol('E');
charc_out=getraw_content(table[i][j]);
cout<<"\tr1:
用E-->E+T规约且";
popstack(state_stack,pointer_state,3);
popstackc(stack,pointer,3);
charc='E';//str[(*index)];
pushstack(stack,pointer,state_stack,pointer_state,c,c_out,1);
strings=get_tx(t[tsize].num);
stack[(*pointer)].endchar=s;//把保存E+T规约的结果的变量保存至当前字符的终结符
}
elseif(production=="r2")
{
intpo=(*pointer);//用P规约该表达式,有效变量在E的endchar中,需要找到E的位置,即下面的操作
stringst=stack[po].endchar;//对应T
po-=2;
stringse=stack[po].endchar;//在规约之前记录下要规约的字符所代表的变量。
对应E
tsize++;//新增临时变量
t[tsize].num=tsize+1;//下面四个表达式是按照上面的规约式进行的赋值
t[tsize].operate='-';
t[tsize].var1=se;
t[tsize].var2=st;
cout<<"\t("<intp=(*pointer_state);
p-=3;
charsecond=state_stack[p];
inti=getraw(second);
intj=getcol('E');
charc_out=getraw_content(table[i][j]);
cout<<"\tr2:
用E-->E-T规约且";
popstack(state_stack,pointer_state,3);
popstackc(stack,pointer,3);
charc='E';//str[(*index)];
pushstack(stack,pointer,state_stack,pointer_state,c,c_out,1);
strings=get_tx(t[tsize].num);
stack[(*pointer)].endchar=s;//把保存E-T规约的结果的变量保存至当前字符的终结符
}
elseif(production=="r3")
{
strings=stack[(*pointer)].endchar;//在规约之前记录下要规约的字符所代表的变量
intp=(*pointer_state);
p--;
charsecond=state_s