G->id++
X->id>c
Y->id––
H->id1=id2+id3
H->id1=id2+c
H->id1=c+id2
其中c表示常数const,f表示关键字for,id表示一般标识符。
for循环体内部的表达式一般为算术表达式,而算术表达式转换为四元式的方法在第一部分已给出,此处H只考虑比较简单的情况。
语句的LR(0)分析表如下:
3.基本算法流程:
本算法定义声明了两个结构体:
一个是Node结构体,其中char型的type中存储当前符号的类型,CString型的sValue中存储的为当前符号,int型的eValue只有在符号类型为数字的情况下才进行存储,存储数字的大小;另一个为stack结构体,这个结构体是实现语法分析中的符号栈和状态栈使用的,并未这两个栈分别定义了各自的pop函数和push函数。
除此之外,本算法中的LR(0)分析表通过二维数组存储。
其中分为action表和goto表。
action表中的状态转换符号,用2-44表示,规约的符号,用101-110表示。
具体的算法流程图如下:
(三)while语句转换为四元式
语句的文法如下:
(1)S->while(B){E}
(2)E->AE
(3)E->A
(4)A->iPA
(5)A->i
(6)B->iTi
(7)B->i
其中while、(、)、{、}、P、T、;和i均为终结符,而S、A、B、E这些大写字母均为非终结符。
T表示比较运算符,P表示算术运算符,i表示合法标识符。
语句的LR(0)分析表如下:
3.基本算法流程:
本算法的基本思想与for语句转换成四元式的思想比较相似,都是对读入的语句进行词法分析,后再通过LR(0)分析表对语句进行语法分析,并同时输出四元式。
与for语句转换成四元式不同的是,while语句转换为四元式在结构体定义等方面做了改进。
首先是LR(0)分析表的存储方式进行了改进,本算法中为LR(0)分析表定义了一个table的结构体,将action和goto两个部分全部存入table的结构体中,是查表的时候更加方便。
除此之外,还定义了obj结构体,此结构体主要是为了存储所要输出的四元式,定义了此结构体之后,程序的调理变得更为清晰了。
本算法中符号栈以及状态栈的部分主要调用了c++中原有的stack结构体,使用其本身定义的pop函数以及push函数,简化的代码。
以下为算法的流程图:
(四)输入、输出以及界面设计
1.输入:
本程序的输入均为语句或表达式,若每次测试程序均输入表达式,则会输入大量式子,浪费时间。
所以本程序采用文件读入的形式,只需要在指定位置输入文件名即可。
2.输出:
本程序输出的四元式全部在MFC界面的文本框中显示。
可以复制,方便之后的使用。
3.界面设计:
本程序为了方便使用以及界面美观,使用了MFC中的TabControl控件,界面设计如下:
图中当前标签为“while语句”,显示的界面为“while语句转换为四元式”。
通过若点击其他标签按钮,界面也会切换到相应的界面。
每个界面都是一个对话框,如下图所示:
(1)作为主要的文件,去调用其他的对话框。
首先对每一个对话框(IDD_DIALOG1-3)进行设置,样式:
下层;边框:
无。
如下图所示:
(2)后在文件中添加每个对话框的头文件,以及申明每个对话框,代码如下:
#include""
#include""
#include""
CDlg1page1;
CDlg2page2;
CDlg3page3;
(3)在初始化函数CCompilerDesignDlg:
:
OnInitDialog()中编写相关代码:
(0,"算术表达式");
(1,"for语句");
(2,"while语句");
(IDD_DIALOG1,&m_tabCtrl);
(IDD_DIALOG2,&m_tabCtrl);
(IDD_DIALOG3,&m_tabCtrl);
CRectrc;
(&rc);
+=22;
-=3;
+=2;
-=3;
ype;
if(st[i]=='f')
{
GetDlgItemText(IDC_CF,str_cf);
CStringtemp_str3="关键字:
for\r\n";
SetDlgItemText(IDC_CF,str_cf+temp_str3);
}
elseif(st[i]=='i')
{
CStringtemp_str3=node[i].sValue;
str_i=str_i+temp_str3+"";
}
elseif(st[i]=='c')
{
CStringtemp_str3=node[i].sValue;
str_c=str_c+temp_str3+"";
number[count++]=node[i].sValue;
}
}
GetDlgItemText(IDC_CF,str_cf);
SetDlgItemText(IDC_CF,str_cf+"符号:
"+str_i+"\r\n"+"常数:
"+str_c+"\r\n");
for(i=0;iah[i]=node[i].sValue;ct_0[k]=='s'){
introw=();
(row,"");
ct_1[k];
tmp_n=strlen(fuhao)-1;
fuhao[++tmp_n]=shuru[i++];
CStringstr00="";
for(l=0;lCStringtemp_str1;
("%d",Tai[l]);
str00=str00+temp_str1;
}
(row,0,str00);
CStringstr11=fuhao;
(row,1,str11);
CStringstr22="";
for(l=i;lCStringtemp_str2=shuru[l];
str22=str22+temp_str2;
}
(row,2,str22);
}
elseif(action[j].act_0[k]=='r'){
introw=();
(row,"");
X=strlen(W[action[j].act_1[k]])-1;
len-=X;
for(m=len;mfuhao[m]='\0';
fuhao[len]=W[action[j].act_1[k]][0];
switch(W[action[j].act_1[k]][0]){
case'S':
l=0;
break;
case'E':
l=1;
break;
case'B':
l=2;
break;
case'A':
l=3;
break;
}
len+=1;
Tai[len-1]=action[Tai[len-2]].go[l];
CStringstr00="";
for(l=0;lCStringtemp_str1;
("%d",Tai[l]);
str00=str00+temp_str1;
}
(row,0,str00);
CStringstr11=fuhao;
(row,1,str11);
CStringstr22="";
for(l=i;l{
CStringtemp_str2=shuru[l];
str22=str22+temp_str2;
}
(row,2,str22);
}
elseif(action[j].act_0[k]=='Z'){
break;
}
else{
}
}
}
函数:
主要用于操作符号栈,并且输出四元式。
voidCDlg3:
:
produce_obj(charc[],intcount)
{
stacksf;
stacks1;
stacks;
inti,j=0;
(';');
chart[5]={"ABCD"};
for(i=0;i{
if(isalnum(c[i]))
(c[i]);
elseif(c[i]==';')
{
while()!
=';')
{