}
}
if(f==0)syntax();
else
{
td[t]='-1';
err(f);
}
}
4.中间代码形式及其序列的结构设计
中间代码是3地址码形式来表示,即4元式的变形。
三地址码由5个域构成:
中间代码地址标号,操作符,左操作数,右操作数,目的操作数
操作符:
=,+,>,<(文法仅定义这些操作);
左操作数,右操作数:
opt,opr;
目的操作数:
用来存放操作值的变量。
例如:
i=(0)
(0)=i+1
(1)=i
表示i=i+1。
5.简要分析与概要设计
5.1系统分析
5.1.1词法分析
输入源程序文本,对输入串进行预处理,然后从左至右逐个字符地对源程序进行扫(超前搜索法),产生一个一个的单词符号,在状态转换图的基础上,把作为字符串源程序改造成为单词符号串。
概要流程图见图1.3.2。
5.1.2语法分析
在完成词法分析的基础上对DO-WHILE循环语句进行语法分析,对状态栈、符号栈分别进行移进、规约(采用LL
(1)分析方法)、接受和出错处理四步操作,从而分析判定程序的语法结构是否符合语法规则。
概要流程图见1.3.3节。
5.1.3语义分析以及三地址码表示
当在栈中找到可归前缀后,进行规约时,根据相应产生式对应的语义子程序进行语法制导翻译(在语法的分析过程中,随着分析的步步进展,根据每一个产生式所对应的语义子程序进行翻译的方法).三地址指令很类似于四元式,这种中间表示通常称为三地址代码,三个地址即是两个为操作数,一个是操作符。
5.1.4LL
(1)语法分析中的出错处理
1)字符不匹配,转去出错处理。
2)字符没有出现在产生式终结符集VT[]中,转去出错处理
3)没有找到合适的候选产生式来做进一步推导,转去出错处理
5.2概要设计(系统总体描述)
6.详细的算法描述
详细的伪代码(源程序)
#include
#defineMAX35
charX,a;
charVN[11]={'K','L','P','S','E','G','T','R','F','Q','\0'};
charVT[15]={'i','=','<','>','+','-','*','/','(',')','d','w',';','#','\0'};
charp[18][6]={"dLwS\0","SP\0",";SP\0","\0","iQE\0","TG\0","+TG\0","-TG\0","\0","FR\0","*FR\0","/FR\0","\0","(E)\0","i\0","=\0","<\0",">\0"};
charstack[MAX];
charqueue[MAX];
intsp,front;
intM[10][14]={{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,-1,-1,-1},
{1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,3,2,-1},
{4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
{5,-1,-1,-1,-1,-1,-1,-1,5,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,6,7,-1,-1,-1,-1,-1,8,8,8},
{9,-1,-1,-1,-1,-1,-1,-1,9,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,12,12,10,11,-1,-1,-1,12,12,12},
{14,-1,-1,-1,-1,-1,-1,-1,13,-1,-1,-1,-1,-1},
{-1,15,16,17,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},
};
intf=0;
intcount=0;
intc=0;
chararr_i[MAX];
charvar[MAX];//表格管理
inttd[MAX];//输出产生式序列
intt=0;
intopd=-1;
intopr=-1;
intid=0;
//intptr[MAX];
intd=0;
chararr[MAX][5];//存放待输出的三地址
//charkeyword[2][7]={"do\0","while\0"};
intlen(charstr[])
{
inti=0;
while(str[i]!
='\0')i++;
returni;
}
intindex(charch,charstr[])
{
inti=0;
while(str[i]!
='\0')
{
if(ch!
=str[i])i++;
elsebreak;
}
if(str[i]=='\0')return-1;
returni;
}
voiderr(intn)
{
if(n==1)
cout<<"字符不匹配"<elseif(n==2)
cout<<"字符没有出现在产生式终结符集VT中"<elseif(n==3)
cout<<"没有找到合适的候选产生式来做进一步推导"<else
cout<<"该句子是文法语言的句子!
"<}
voidprint()
{
cout<<"(";
if(count<10)cout<<'0';
cout<inti;
for(i=0;i<=sp;i++)cout<for(;i<=20;i++)cout<<"";
for(i=0;ifor(;queue[i]!
='#';i++)cout<cout<for(;i<=20;i++)cout<<"";
}
voidsemantic()
{
if(VT[opr]=='=')
{
arr[d][0]=arr_i[opd];
arr[d][1]='=';
arr[d][2]=id;
arr[d][3]='';
arr[d][4]='';
id++;
}
elseif(opr==-2)
{
arr[d][0]=id-1;
arr[d][1]='=';
arr[d][2]=arr_i[opd];
arr[d][3]='';
arr[d][4]='';
}
else
{
if(VT[opr]!
='<'&&VT[opr]!
='>')
arr[d][0]=id-1;
else
arr[d][0]=id+1;
arr[d][1]='=';
arr[d][2]=arr_i[opd];
arr[d][3]='+';
arr[d][4]=id;
id++;
}
d++;
}
voidsyntax()
{
intn;
count++;
print();
X=stack[sp];
a=queue[front];
if(X=='#'&&a=='#')f=4;
if(X<'A'||X>'Z')
{
if(X==a)
{
sp--;
front++;
if(a!
='i')
{
if(a!
='d'&&a!
='w'&&a!
=';'&&a!
='#')
{
opr=index(a,VT);
semantic();
}
elseif(a==';'||a=='w'||a=='#')
{
opr=-2;
semantic();
}
cout<<'\t'<<'\''<}
else
{
opd=c;
//cout<cout<<'\t'<<'\''<}
}
elsef=1;//字符不匹配,转去出错处理
}
else
{
inttx=index(X,VN);
intta=index(a,VT);
n=M[tx][ta];
td[t++]=M[tx][ta];
if(ta==-1)
{
f=2;cout<}//字符没有出现在产生式终结符集VT中,转去出错处理
elseif(n==-1)f=3;//没有找到合适的候选产生式来做进一步推导,转去出错处理
else
{//用产生式M[tx][ta]来做进一步推导
sp--;
cout<<'\t'<";
if(len(p[n])!
=0)
{
for(inti=len(p[n])-1;i>=0;i--)
{
stack[++sp]=p[n][i];
cout<
}
cout<}
elsecout<<"空串"<}
}
if(f==0)syntax();
else
{
td[t]='-1';
err(f);
}
}
voidlexical()
{//do{m=m+i;i=i+1;}while(i<4);#
inti,j,d;
charch;
j=d=0;
for(i=0;var[i]!
='#';i++)
{
ch=var[i];
if(ch=='d'&&var[i+1]=='o')
{
cout<<"do"<<'\t'<<"keyword"<queue[j++]='d';i+=1;
}
elseif(ch=='w')
{
ch=var[i+1];
if(ch=='h')
{
ch=var[i+2];
if(ch=='i')
{
ch=var[i+3];
if(ch=='l')
{
ch=var[i+4];
if(ch=='e')
{
ch=var[i+5];
}
}
}
}
cout<<"while"<<'\t'<<"keyword"<queue[j++]='w';i+=4;
}
elseif(index(ch,VT)<=0)
{
if(ch!
='{'&&ch!
='}'&&ch!
='('&&ch!
=')')
{
cout<i["<arr_i[d-1]=ch;
queue[j++]='i';
}
elsecout<}
elseif(index(ch,VT)>0)
{
cout<queue[j++]=ch;
}
}
queue[j]='#';
for(i=0;queue[i]!
='#';i++)cout<cout<}
intmain()//主程序
{
inti=0;
charS='K';
sp=front=0;
stack[0]='#';
sp++;
stack[1]='K';
cout<<"LL
(1)文法如下:
"<cout<<"(0)K->dLwS\n
(1)L->SP\n
(2)P->;SP\n(3)P->ε\n(4)S->iQE\n(5)E->TG\n(6)G->+TG\n"<<"(7)G->-TG\n(8)G->ε\n(9)T->FR\n(10)R->*FR\n(11