这是编译课程设计时做的一个小小的语法分析程序,程序有些冗余.实现的功能还不全,只能通过输入文法的分析表才能给出分析过程.对于求任意文法的first集和follow集还没实现.
/*
* 文件名称: 语法分析.h
* 摘 要: 对任意输入LL(1)文法的分析表及字符串,本程序能自动判断所给字符串是
* 否为该文法的句子,并能给出分析过程。
*/
#include
#include
#include
#include"ctype.h"
class string;
class stack
{
char stck[100];
int top;
public:
void init()
{top=0;}
void push(char ch);
char pop();
void showstck(); //显示栈中元素
};
class string{
int length;
char *ptr;
public:
string();
~string()
{ }
string(char *s);
int getlength();
int getlength(char *s);
char &operator[](int);
string &operator=(const string &ob);
bool operator== (const string& pw);
friend ostream& operator<<(ostream&,const string&);
friend istream& operator>>(istream&,string&);
};
void stack::push(char ch) //入栈
{
stck[top]=ch;
top++;
}
char stack::pop()
{
if(top==0)
{
cout<<"stack is empty!";
return 0;
}
top--;
return stck[top];
}
void stack::showstck()
{
int i;
for(i=0;i
cout<
}
string::string()
{ length=1;
ptr=new char[1];
*ptr='/0';
}
string::string(char *s)
{ ptr=new char[getlength(s)+1];
strcpy(ptr,s);
length=getlength(s)+1;
}
int string::getlength()
{
int len;
len=getlength(ptr);
return len;
}
int string::getlength(char *s)
{ int i=0;
while(s[i]!='/0')
{i++;
}
return i;
}
char &string::operator[](int j)
{
return ptr[j];
}
string &string::operator =(const string &ob) //重载‘=’运算符
{if(this==&ob)
return *this;
delete ptr;
ptr=new char[getlength(ob.ptr)+1];
length=getlength(ob.ptr)+1;
strcpy(ptr,ob.ptr);
return *this;
}
bool string::operator== (const string &pw)
{
if(*ptr==*pw.ptr)
return true;
else
return false;
}
ostream& operator<<(ostream&s,const string&ob)
{
s<
return s;
}
istream& operator>>(istream&in,string&ob)
{
in>>ob.ptr ;
return in;
}
bool find(char c,char array[] ) //查找函数,返回布尔值
{
int i;
bool flag=false;
for(i=0;i<100;i++)
{
if(c==array[i])
flag=true;
}
return flag;
}
int location(char c,char array[]) //定位函数,指出字符所在位置
{
int i;
for(i=0;i<100;i++)
{
if(c==array[i])
return i;
}
}
void error()
{
cout<<" 出错!"<
}
void analyse(char Vn[],char Vt[],string M[100][100])
{
int i,j,m,p,q,length,t,h;
char w,X;
string str;
opt0:
cin>>str;
for(i=0;i
{
if(!find(str[i],Vt))
{ cout<<"输入字符串有误!请重新输入!"<
goto opt0;
break;}
}
stack st;
st.init(); //初始化
st.push('#');
st.push(Vn[0]); //#与识别符号入栈
j=0;
h=1;
w=str[0];
cout<<"步骤 "<<"分析栈 "<<"剩余输入串 "<<" 所用产生式"<
opt1:
cout<
<<"??????????????? 显示步骤
j++;
w=str[j];
goto opt1;
}
else
error();
}
else
{
if(X=='#')
{
if(X==w)
{
cout<<" "<<"接受!"<
<
}
else
error();
}
else
{
p=location(X,Vn);
q=location(w,Vt);
string S("NULL");
if(M[p][q]==S) //查找二维数组中的产生式
error();
else
{
string str0=M[p][q];
cout<<" "<
<<"-->"<
<
if(str0=="$")
goto opt1;
else
{length=str0.getlength(); //逆序进栈
for(m=length-1;m>=0;m--)
{
st.push(str0[m]);
}
goto opt1;
}
}
}
}
}
main()
{
int i,k,n,r;
char Vn[100],Vt[100],select;
string M[100][100];
cout<<"* 文件名称: 语法分析"<
cout<<"* 摘 要: 对任意输入LL(1)文法的分析表及字符串,本程序能自动判断所给字符串是"<
cout<<"* 否为该文法的句子,并能给出分析过程。"<
cout<<"*--------------------------------------------------------------------*"<
cout<
<
opt2:
cout<<"请输入非终结符个数:";
cin>>n;
cout<<"请输入终结符(#号表示结束)Vt:";
for(i=0;i<100;i++)
{
cin>>Vt[i];
if(Vt[i]=='#')
{
r=i;
break;
}
}
for (i=0;i
{
cout<<"请输入非终结符Vn["<
<<"]Vn:";
<<"]Vn:";
cin>>Vn[i];
cout<<"请输入此非终结符对应各终结符的产生式右部,$表示空串:";
for(k=0;k<=r;k++)
{
cin>>M[i][k];
}
}
opt3:
cout<<"请输入要分析的字符串,且以#结束:";
analyse(Vn, Vt, M);
cout<<" ************************请选择***********************"<
cout<<" 1: 输入字符串" <
cout<<" 2: 输入新分析表" <
cout<<" 0: 退 出" <
opt4:
cin>>select;
switch(select)
{
case '1': {goto opt3;break;}
case '2': {goto opt2;}
case '0': {break;}
default: {cout<<"输入错误!请重新选择:"<
goto opt4;
break;}
}
return 0;
}