资源描述
试验二 语法分析程序设计和实现
一、试验目标
任选一个有代表性语法分析方法,如算符优先法、递归下降法、LL(1)、SLR(1)、LR(1)等,经过设计、编制、调试实现一个经典语法分析程序,对试验一所得扫描器提供单词序列进行语法检验和结构分析,实现并深入掌握常见语法分析方法。
二、基础试验内容和要求
选择对多种常见高级程序设计语言全部较为通用语法结构——算术表示式一个简化子集——作为分析对象,依据以下描述其语法结构BNF定义G2[<算术表示式>],任选一个学过语法分析方法,针对运算对象为无符号常数和变量四则运算,设计并实现一个语法分析程序。
G2[<算术表示式>]:
<算术表示式> → <项> | <算术表示式>+<项> | <算术表示式>-<项>
<项> → <因式> | <项>*<因式> | <项>/<因式>
<因式> → <运算对象> | (<算术表示式>)
若将语法范围<算术表示式>、<项>、<因式>和<运算对象>分别用E、T、F和i代表,则G2可写成:
G2[E]:E → T | E+T | E-T T → F | T*F | T/F F → i | (E)
输入:由试验一输出单词串,比如:UCON,PL,UCON,MU,ID ······
输出:若输入源程序中符号串是给定文法句子,则输出“RIGHT”,而且给出每一步分析过程;若不是句子,即输入串有错误,则输出“ERROR”,而且显示分析至此所得中间结果,如分析栈、符号栈中信息等,和必需犯错说明信息。
要求:
1、确定语法分析程序步骤图,同时考虑对应数据结构,编写一个语法分析源程序。
2、将词法、语法分析合在一起组成一个完整程序,并调试成功。
3、 供测试例子应包含符合语法规则语句,及分析程序能判别若干错例。对于所输入字符串,不管对错,全部应有明确信息输出。
三、问题分析及源程序
LL1文法:
改写文法为:
E- >TG e
G> +TG g
T- >FS t
F- >-TG g1
G- >^ g2
S- >*FS s
T- >/FS s1
S- >^ s2
F- >(E) f
G- >i f1
分析表:
i
+
-
*
/
(
)
#
E
e
e
G
g
g1
g2
g2
T
t
t
S
s2
s2
s
s1
s2
s2
F
f1
f
LL1源程序
#include<iostream.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char A[30]; /*分析栈*/
char B[30]; /*剩下串*/
char v1[20]={'i','+','-','*','/','(',')','#'}; /*终止符*/
char v2[20]={'E','G','T','S','F'}; /*非终止符*/
int j=0,b=0,top=0,l; /*L为输入串长度*/
class type /*产生式类型定义*/
{public:
char origin; /*大写字符*/
char array[5]; /*产生式右边字符 */
int length; /*字符个数*/
};
type e,t,g,g1,g2,s,s1,s2,f,f1; /*类对象*/
type C[10][10]; /*估计分析表*/
void print() /*输出分析栈*/
{
int a;
for(a=0;a<=top+1;a++)
cout<<A[a];
cout<<"\t\t";
}
void print1() /*输出剩下串*/
{
int j;
for(j=0;j<b;j++) /*输出对齐符*/
cout<<" ";
for(j=b;j<=l;j++)
cout<<B[j];
cout<<"\t\t\t";
}
void main()
{
int m,n,k=0,flag=0,finish=0;
char ch,x;
type cha; /*用来接收C[m][n]*/
/*把文法产生式赋值结构体*/
e.origin='E';
strcpy(e.array,"TG");
e.length=2;
t.origin='T';
strcpy(t.array,"FS");
t.length=2;
g.origin='G';
strcpy(g.array,"+TG");
g.length=3;
g1.origin='G';
strcpy(g1.array,"-TG");
g1.length=3;
g2.origin='G';
g2.array[0]='^';
g2.length=1;
s.origin='S';
strcpy(s.array,"*FS");
s.length=3;
s1.origin='S';
strcpy(s1.array,"/FS");
s1.length=3;
s2.origin='S';
s2.array[0]='^';
s2.length=1;
f.origin='F';
strcpy(f.array,"(E)");
f.length=3;
f1.origin='F';
f1.array[0]='i';
f1.length=1;
for(m=0;m<=4;m++) /*初始化分析表*/
for(n=0;n<=7;n++)
C[m][n].origin='N'; /*全部赋为空*/
/*填充足析表*/
C[0][0]=e;C[0][5]=e;
C[1][1]=g;C[1][2]=g1;C[1][6]=g2;C[1][7]=g2;
C[2][0]=t;C[2][5]=t;
C[3][1]=s2;C[3][2]=s2;C[3][3]=s;C[3][4]=s1;C[3][6]=s2;C[3][7]=s2;
C[4][0]=f1;C[4][5]=f;
cout<<"提醒:本程序只能对由'i','+','-','*','/','(',')'组成以'#'结束字符串进行分析,\n";
cout<<"请输入要分析字符串:";
do/*读入分析串*/
{
cin>>ch;
if ((ch!='i') &&(ch!='+')&&(ch!='-')&&(ch!='*')&&(ch!='/')&&(ch!='(')&&(ch!=')')&&(ch!='#'))
{
cout<<"输入串中有非法字符\n";
exit(1); //强制退出程序
}
B[j]=ch;
j++;
}while(ch!='#');
l=j;/*分析串长度*/
ch=B[0];/*目前分析字符*/
A[top]='#'; A[++top]='E';/*'#','E'进栈*/
cout<<"步骤\t\t分析栈 \t\t剩下字符 \t\t所用产生式 \n";
do
{
x=A[top--];/*x为目前栈顶字符*/
cout<<k++;
cout<<"\t\t";
for(j=0;j<=7;j++)/*判定是否为终止符*/
if(x==v1[j])
{
flag=1;
break;
}
if(flag==1)/*假如是终止符*/
{
if(x=='#')
{
finish=1;/*结束标识*/
cout<<"acc!"<<endl;/*接收 */
getchar();
exit(1); //退出程序
}/*if*/
if(x==ch)
{
print();
print1();
cout<<"匹配"<<endl;
ch=B[++b];/*下一个输入字符*/
flag=0;/*恢复标识*/
}
else/*犯错处理*/
{
print();
print1();
cout<<"犯错"<<endl;/*输出犯错终止符*/
exit(1);
}
}
else/*非终止符处理*/
{
for(j=0;j<=4;j++)
if(x==v2[j])
{
m=j;/*行号*/
break;
}
for(j=0;j<=7;j++)
if(ch==v1[j])
{
n=j;/*列号*/
break;
}
cha=C[m][n];
if(cha.origin!='N')/*判定是否为空*/
{
print();
print1();
cout<<cha.origin<<"->"; /*输出产生式*/
for(j=0;j<cha.length;j++)
cout<<cha.array[j];
cout<<"\n";
for(j=(cha.length-1);j>=0;j--) /*产生式逆序入栈*/
A[++top]=cha.array[j];
if(A[top]=='^')/*为空则不进栈*/
top--;
}
else/*犯错处理*/
{
print();
print1();
cout<<"犯错"<<endl;/*输出犯错非终止符*/
exit(1);
}
}
}while(finish==0);
}
运行结果:
展开阅读全文