附录一第二篇第5章语义分析中语义子程序的设计C型程序Word文档下载推荐.docx
《附录一第二篇第5章语义分析中语义子程序的设计C型程序Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《附录一第二篇第5章语义分析中语义子程序的设计C型程序Word文档下载推荐.docx(39页珍藏版)》请在冰豆网上搜索。
属性信息表[A]={A,U,"
Rsval,PRs,NE};
注释分析树[NE].属性信息链=Apointer({A,NULL});
void_3()/*{R1.i:
=R.i+T.val}*/
{NR1=分析栈[tops].结点序号;
U=注释分析树[NR1].文法符号序号;
NR=注释分析树[NR1].父结点;
NRi=search(NR,"
NTval=search(NT,"
PTval=Dpointer({NTval,NULL});
PRi=Dpointer({NRi,PTval});
R1ival=属性信息表[NRi].属性值+属性信息表[NTval].属性值;
,R1ival,PRi,NR1};
注释分析树[NR1].属性信息链=Apointer({A,NULL});
}
void_4()/*{R.s:
=R1.s}*/
{NR1=CurR;
NR1s=search(NR1,"
R1sval=属性信息表[NR1s].属性值;
PR1sval=Dpointer({NR1s,NULL});
NR=注释分析树[NR1].父结点序号;
CurR=NR;
U=注释分析树[NR].文法符号序号;
'
,R1sval,PR1sval,NR};
/*把属性信息表序号A链入注释分析树中结点NR的属性信息链*/
pA=Apointer({A,NULL});
/*指向属性结点*/
注释分析树[NR].属性信息链=
AppendAlink(pA,注释分析树[NR].属性信息链);
void_5()/*{R1.i:
=R.i-T.val}*/
NRi=search(NR,"
R1ival=属性信息表[NRi].属性值-属性信息表[NTval].属性值;
,R1ival,PRi,NR1};
void_6()/*R:
:
=ε{R.s:
=R.i}*/
{NR=注释分析树[N].父结点序号;
CurR=NR;
NRi=search(NR,"
Rsval=属性信息表[NRi].属性值;
PRi=Dpointer({NRi,NULL});
,Rsval,PRi,NR};
void_7()/*T:
=(E{T.val:
=E.val})*/
{NE=注释分析树[N].左兄结点序号;
NEval=search(NE,"
Eval=属性信息表[NEval].属性值;
PEval=Dpointer({NEval,NULL});
NT=注释分析树[NE].父结点序号;
U=注释分析树[NT].文法符号序号;
,Eval,PEval,NT};
注释分析树[NT].属性信息链=Apointer({A,NULL});
void_8()/*T:
=n{T.val:
=n.lexval}*/
{nval=STOI(Input[k]);
/*STOI进行数字字符串到整值的转换*/
U=n在VT中的序号;
A=A+1;
属性信息表[A]={A,U,"
lexval"
,nval,NULL,N};
NT=注释分析树[N].父结点;
U=注释分析树[NT].文法符号序号;
Pnval=Dpointer({A,NULL});
属性信息表[A]={A,U,"
,nval,Pnval,NT};
其中函数AppendAlink可定义如下:
属性结点类型*AppendAlink
(属性结点类型*back,属性结点类型*front)
{/*把属性信息链back链入front的最后结点之后*/
p=front;
q=NULL;
while(p!
=NULL)
{q=p;
p=p->
下一属性结点;
if(q)
q->
下一属性结点=back;
else
front=back;
returnfront;
实习题5.4赋值语句目标代码生成
赋值语句目标代码生成的C型伪代码程序如下:
void基于LR
(1)分析技术生成赋值语句目标代码()
{/*输入符号串在读入缓冲区Input中*/
置初值;
/*从输入符号串建立语法分析树末端结点符号串,并填属性信息表*/
m=0;
N=0;
for(j=1;
j<
=输入符号串长度;
j++)
{m=m+1;
N=N+1;
注释分析树[N]={N,Input[m]在VT中的序号,0,0,0,NULL};
/*实现参看实习题5.1,其中Input[m]在VT中的序号如下求得:
for(k=1;
k<
=VT中元素总数;
k++)
if(Input[m]==VT[k])
{Input[m]在VT中的序号=k;
break;
}*/
if(Input[m]是i)
{A=A+1;
属性信息表[A]=
{A,i在VT中的序号,"
name"
,'
S'
,Input[m],NULL,N};
/*实现参看实习题5.1*/
注释分析树[N].属性信息链=Apointer({A,NULL});
tops=0;
分析栈[tops]={状态0,#结点序号0};
/*#无相应结点*/
Scontinue=1;
/*true;
移入时继续*/
Rcontinue=1;
归约时继续*/
k=0;
/*k是输入符号串位置指针*/
while(Scontinue)
{k=k+1;
R=Input[k]在VT中的序号;
S=分析栈[tops].状态;
while(Rcontinue)/*Rwhile循环*/
{act=ACTION[S][R];
if(act==999)/*acc成功*/
{输出“成功结束,输出所生成的目标代码”;
Scontinue=0;
Rcontinue=0;
/*false*/
continue;
/*转向Rwhile循环开始处*/
if(act>
0)
{tops=tops+1;
分析栈[tops]={act,k};
/*由构造法,k即结点序号*/
Rcontinue=0;
/*false*/
/*转向Rwhile循环开始处*/
if(act==0)
{输出“出错,当前输入符号为:
”;
输出VT[R];
Rcontinue=0;
/*转向Rwhile循环开始处*/
/*act<
0归约*/
act=-act;
/*建立分支名字结点,并建立父子兄弟结点关系*/
U=翻译方案[act].左部符号序号;
m=翻译方案[act].右部长度;
/*若可能规则右部长度等于零,执行下列if语句*/
if(m==0)
{N=N+1;
注释分析树[N]={N,0,0,0,0,NULL};
tops=tops+1;
分析栈[tops]={0,N};
m=1;
右子结点序号=分析栈[tops].结点序号;
N=N+1;
/*分支名字结点*/
注释分析树[N]={N,U,0,0,右子结点序号,NULL};
bro=0;
=m;
j++)
{分支结点序号=分析栈[tops-(m-j)].结点序号;
注释分析树[分支结点序号].父结点序号=N;
注释分析树[分支结点序号].左兄结点序号=bro;
bro=分支结点序号;
语义子程序(act);
tops=tops-m;
NewS=GOTO[分析栈[tops].状态][U-100];
/*U=VN中序号+100*/
分析栈[tops]={NewS,N};
}/*Rcontinue;
}/*Scontinue*/
输出注释分析树;
按规则归约时所执行的语义子程序(C型)如下:
void语义子程序(intact)
{switch(act)
{case1:
_1();
case2:
_2();
case3:
_3();
case4:
_4();
case5:
_5();
case6:
_6();
各语义子程序可设计如下:
void_1()/*A:
=i=E*/
{NE=分析栈[tops].结点序号;
NEcode=search(NE,″code″);
Ecode=属性信息表[NEcode].属性值;
NEplace=search(NE,″place″);
if(Ecode==NULL)/*判E.code=″″*/
{Ntemp=Ntemp+1;
t="
r"
||ITOS(Ntemp);
/*||表示串并置(连接)运算符,实现如下行*/
/*strcpy(t,"
strcat(t,ITOS(Ntemp));
*/
Epalce=属性信息表[NEplace].属性值;
Ecode=
Ipointer({"
MOV"
||属性信息表[Eplace].属性值||t,NULL});
/*Ecode=(目标指令类型*)malloc(sizeof(目标指令类型));
strcpy(C.OP,"
strcpy(C.源,属性信息表[Eplace].属性值);
strcpy(C.目标,t);
Ecode→虚拟机指令=C;
Ecode->
下一目标指令=NULL;
strcpy(属性信息表[NEplace].属性值,t);
属性信息表[NEcode].属性值=Ecode;
Ni=分析栈[tops-2].结点序号;
Niplace=search(Ni,″name″);
Acode=copycode(Ecode,Acode);
C1=Ipointer({″MOV″||属性信息表[NEplace].属性值
||属性信息表[Niplace].属性值,NULL});
/*C1=(目标指令类型*)malloc(sizeof(目标指令类型));
strcpy(C.OP,"
strcpy(C.源,属性信息表[NEplace].属性值);
strcpy(C.目标,属性信息表[Niplace].属性值);
C1->
虚拟机指令=C;
Acode=AppendCode(C1,Acode);
PEcode=Dpointer({NEcode,NULL});
PEplace=Dpointer({NEplace,PEcode});
Piplace=Dpointer({Niplace,PEplace});
属性信息表[A]={A,U,″code″,′M′,Acode,Piplace,N};
/*实现参看实习题5.2*/
void_2()/*E:
=E1+E2*/
A=A+1;
属性信息表[A]={A,U,″place″,′S′,″r″||ITOS(Ntemp),NULL,N};
NEl=分析栈[tops-2].结点序号;
NE1code=search(NEl,″code″);
NE2=分析栈[tops].结点序号;
NE2code=search(NE2,″code″);
E1code=属性信息表[NE1code].属性值;
E2code=属性信息表[NE2code].属性值;
Ecode=copycode(E1code,Ecode);
Ecode=mergecode(E2code,Ecode);
NE1place=search(NEl,″place″);
NE2place=search(NE2,″place″);
C2=Ipointer({″ADD″||属性信息表[NE2place].属性值
||属性信息表[A].属性值,NULL});
C1=Ipointer({″MOV″||属性信息表[NE1place].属性值
||属性信息表[A].属性值,C2});
Ecode=AppendCode(C1,Ecode);
PE2place=Dpointer({NE2place,NULL});
PE1place=Dpointer({NE1place,PE2place});
PE2code=Dpointer({NE2code,PE1place});
PE1code=Dpointer({NE1code,PE2code});
PA1=Apointer({A,NULL});
属性信息表[A]={A,U,″code″,′M′,Ecode,PE1code,N};
注释分析树[N].属性信息链=Apointer({A,PA1});
void_3()/*E:
=E1*E2*/
NEl=分析栈[tops-2].结点序号;
NE2=分析栈[tops].结点序号;
E1code=属性信息表[NE1code].属性值;
C2=Ipointer({″MPY″||属性信息表[NE2place].属性值
||属性信息表[A].属性值,NULL});
||属性信息表[A].属性值,C2});
Ecode=AppendCode(C1,Ecode);
PE2place=Dpointer({NE2place,NULL});
PE2code=Dpointer({NE2code,PE1place});
属性信息表[A]={A,U,″code"
M'
,Ecode,PE1code,N};
void_4()/*E:
=-E1*/
NE1=分析栈[tops].结点序号;
NE1code=search(NE1,″code″);
Ecode=copycode(E1code,Ecode);
NE1place=search(NE1,″place″);
C2=Ipointer({″NEG″||属性信息表[A].属性值,NULL});
C1=Ipointer({"
||属性信息表[NE1place].属性值
||属性信息表[A].属性值,C2});
PE1place=Dpointer({NE1place,NULL});
PE1code=Dpointer({NE1code,PE1place});
PA1=Apointer({A,NULL});
属性信息表[A]={A,U,″code″,′M′,Ecode,PE1code,N};
void_5()/*E:
=(E1)*/
{NE1=分析栈[tops-1].结点序号;
NE1place=search(NE1,″place″);
{A,U,″place″,′S′,属性信息表[NE1place].属性值,PE1place,N};
NE1code=search(NE1,″code″);
PE1code=Dpointer({NE1code,NULL});
{A,U,″code″,′M′,属性信息表[NE1code].属性值,PE1code,N};
void_6()/*E:
=i*/
{Ni=分析栈[tops].结点序号;
Niplace=search(Ni,″name″);
Piplace=Dpointer({Niplace,NULL});
{A,U,″place″,′S′,属性信息表[Niplace].属性值,Piplace,N};
属性信息表[A]={A,U,″code″,′M′,NULL,NULL,N};
其中,函数ITOS可定义如下:
char*ITOS(intN)
{d=N;
k=0;
while(d!
=0)
{s[k++]=d%10+'
0'
;
d=d/10;
}
for(j=k-1;
j>
k/2;
j--)
{t=s[j];
s[j]=s[k-1-j];
s[k-1-j]=t;
s[k]='
\0'
returns;
实习题5.5条件语句目标代码生成
关于条件语句翻译方案的部分语义子程序_j(j=1,2,…,11)(C型)可设计如下:
void_1()/*S:
=if(B)S1elseS2*/
{Nlabel=Nlabel+1;
/*S.next:
=newlabel*/
属性信息表[A]={A,U,"
next"
S′,"
L″||ITOS(Nlabel),NULL,N};
PSnext=Dpointer({A,NULL});
/*指向依赖属性结点*/
/*指向属性结点*/
Nlabel=Nlabel+1;
NB=分析栈[tops-4].结点序号;
/*B.true:
=newlable*/
属性信息表[A]={A,注释分析树[NB].文法符号序号,″true″,
′S′,″L″||ITOS(Nlabel),NULL,NB};
PA=Apointer({A,NULL});
注释分析树[NB].属性信息链=
AppendAlink(PA,注释分析树[NB].属性信息链);
/*B.false:
属性信息表[A]={A,注释分析树[NB].文法符号序号,″false″,
NS1=分析栈[tops-2].结点序号;
/*S1.next:
=S.next*/
属性信息表[A]={A,注释分析树[NS1].文法符号序号,"
next″,
'
S′,属性信息表[A-3].属性值,PSnext,NS1};
注释