天津理工大学编译原理实验3语义分析及中间代码生成Word文件下载.docx
《天津理工大学编译原理实验3语义分析及中间代码生成Word文件下载.docx》由会员分享,可在线阅读,更多相关《天津理工大学编译原理实验3语义分析及中间代码生成Word文件下载.docx(23页珍藏版)》请在冰豆网上搜索。
5.理解并处理语义分析中的异常和错误。
实验要求:
1.在实验二的基础上,实现语法制导翻译功能,输出翻译后所得四元式序列;
2.要求详细描述所选分析方法进行制导翻译的设计过程;
3.完成对所设计分析器的功能测试,并给出测试数据和实验结果;
4.为增加程序可读性,请在程序中进行适当注释说明;
5.整理上机步骤,总结经验和体会;
6.认真完成并按时提交实验报告。
【实验过程记录(源程序、测试用例、测试结果及心得体会等)】
#include<
iostream>
cstring>
#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,等等
//和该字符相关的中间变量的序号
}char_stack;
stringtable[19][13]={//+-*/^)#(iETFP
/*0*/"
err"
"
"
s5"
s6"
1"
2"
3"
4"
/*1*/"
s7"
s8"
acc"
/*2*/"
r3"
s9"
s10"
/*3*/"
r6"
/*4*/"
r8"
s11"
/*5*/"
c"
/*6*/"
r10"
/*7*/"
d"
/*8*/"
e"
/*9*/"
f"
/*10*/"
g"
/*11*/"
h"
/*12*/"
s18"
/*13*/"
r1"
/*14*/"
r2"
/*15*/"
r4"
/*16*/"
r5"
/*17*/"
r7"
/*18*/"
r9"
};
intgetLength(charstr[size])
inti=0;
while(str[i]!
='
\0'
)
i++;
returni;
}
intgetLengthc(char_stackstr[size])
while(str[i].content!
intgetstringLength(stringstr)
chargettop(charstack[size],inttop)
if(stack[top]!
returnstack[top];
else
return'
#'
;
}
voidpopstack(char*stack,int*pointer,inttimes)
intp;
for(inti=1;
i<
=times;
i++)
{
p=*pointer;
stack[p]='
(*pointer)--;
}
voidpopstackc(char_stack*stack,int*pointer,inttimes)
stack[p].content='
voidpushstack(char_stack*stack,int*pointer,char*stack_state,int*pointer_state,charstr,charsx,intx)
if(x==0)
cout<
<
"
\t\t\t状态"
sx<
进状态栈"
elseif(x==1)
状态"
if(str!
str<
进字符栈"
(*pointer)++;
stack[(*pointer)].content=str;
(*pointer_state)++;
stack_state[(*pointer_state)]=sx;
intgetcol(chartop)
switch(top)
case'
+'
:
return0;
-'
return1;
*'
return2;
/'
return3;
^'
return4;
)'
return5;
return6;
('
return7;
i'
return8;
E'
return9;
T'
return10;
F'
return11;
P'
return12;
default:
cout<
Error!
Thischaracterstringisnotthisgrammer`ssentence."
endl;
return-1;
intgetraw(charraw)
switch(raw)
0'
1'
2'
3'
4'
5'
6'
7'
8'
9'
a'
b'
c'
d'
return13;
e'
return14;
f'
return15;
g'
return16;
h'
return17;
return18;
chargetraw_content(stringstr)
if(str=="
elseif(str=="
i"
stringget_tx(intnum)
switch(num)
case1:
return"
t1"
case2:
t2"
case3:
t3"
case4:
t4"
case5:
t5"
case6:
t6"
case7:
t7"
case8:
t8"
case9:
t9"
case10:
t10"
case11:
t11"
case12:
t12"
case13:
t13"
case14:
t14"
case15:
t15"
case16:
t16"
//......本程序暂时用到这么多,等有时间编写合适的可以将数字转换为字符串的函数时,即可更改本函数
voidshow(charstr[size],intindex)
intlength=getLength(str);
if(index!
=-1)
\t"
for(inti=index+1;
length;
str[i];
voidshowc(char_stackstr[size],intindex)
intlength=getLengthc(str);
str[i].content;
voidswitch_method(char_stack*stack,int*pointer,char*state_stack,int*pointer_state,stringproduction,char*str,int*index)
step++;
cout<
\n"
step<
//显示步骤
show(state_stack,-1);
//显示状态栈
showc(stack,-1);
//显示符号站
str[(*index)]<
//显示当前字符
show(str,(*index));
//显示输入串
charc=str[(*index)];
if(production=="
return;
elseif(production=="
charsx='
(*index)++;
pushstack(stack,pointer,state_stack,pointer_state,c,sx,0);
)
{
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;
\t("
t[tsize].operate<
t[tsize].var1<
t[tsize].var2<
t"
t[tsize].num<
)"
intp=(*pointer_state);
p-=3;
charsecond=state_stack[p];
inti=getraw(second);
intj=getcol('
);
charc_out=getraw_content(table[i][j]);
\tr1:
用E-->
E+T规约且"
popstack(state_stack,pointer_state,3);
popstackc(stack,pointer,3);
charc='
//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规约的结果的变量保存至当前字符的终结符
//对应T
对应E
\tr2:
E-T规约且"
//把保存E-T规约的结果的变量保存至当前字符的终结符
strings=stack[(*pointer)].endchar;
//在规约之前记录下要规约的字符所代表的变量
p--;
charsecond=state_s