LL(1)文法分析是自顶向下的分析方法,也可以被看作是输入串的最左推导过程,LL(1)中1的意思就是可以根据可以根据当前输入串中的一个字符来判断是由哪一个产生式产生。
下面给出文法:
E->Te
e->Ate | # (#代表空集)
T->Ft
t->MFt | #
F->i | (E)
i-> 0|1|2|...|9
A->+|-
M->*|/
首先要构造first集合与follow集合,根据集合做出LL(1)分析表
然后将分析表存到程序中,给定输入的串,来输出最左推导的过程,算法在龙书的4.4.4节
下面给出程序:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <stack>
using namespace std;
#define MAX 100
char c[8]={'i','(','+','-','*','/',')','#'};
char w[7]={'E','e','T','t','F','A','M'};
char mapp[7][8][5]= {"Te","Te","%","%","%","%","%","%",
"%","%","ATe","ATe","%","%","#","#",
"Ft","Ft","%","%","%","%","%","%",
"%","%","#","#","MFt","MFt","#","#",
"i","(E)","%","%","%","%","%","%",
"%","%","+","-","%","%","%","%",
"%","%","%","%","*","/","%","%"};
int panduan(char ch)
{
for(int i=0;i<8;i++)
{
if(ch==c[i])
return 1;
}
return 0;
}
int findc(char ch)
{
if(ch>='0'&&ch<='9')
return 0;
for(int i=0;i<8;i++)
{
if(ch==c[i])
return i;
}
return 0;
}
int findw(char ch)
{
for(int i=0;i<7;i++)
{
if(ch==w[i])
return i;
}
return 0;
}
int main()
{
char str[MAX];
int ip;
stack <char> q;
cout<<"输入的格式为算数式后跟#号"<<endl;
cout<<"for example:"<<" 2+3*4#"<<endl;
cout<<"“e->#”此类产生式中的#号代表空集"<<endl;
cout<<"请输入你的表达式"<<endl;
cin>>str;
ip=0;
q.push('#');
q.push('E');
while(!q.empty())
{
char ch=q.top();
if(ch=='#')break;
int i=findw(ch);
int j=findc(str[ip]);
if(ch==str[ip])
{
q.pop();
cout<<"匹配"<<str[ip]<<endl;
ip++;
}
else if(str[ip]>='0'&&str[ip]<='9'&&ch=='i')
{
q.pop();
cout<<ch<<"->"<<str[ip]<<endl;
cout<<"匹配"<<str[ip]<<endl;
ip++;
}
else if(panduan(ch))
{
cout<<"error"<<endl;
return 0;
}
else if(mapp[i][j][0]=='%')
{
cout<<"error"<<endl;
return 0;
}
else if(mapp[i][j][0]=='#')
{
cout<<ch<<"->"<<"#"<<endl;
q.pop();
}
else
{
int n=strlen(mapp[i][j]);
q.pop();
for(int k=n-1;k>=0;k--)
{
q.push(mapp[i][j][k]);
}
cout<<ch<<"->"<<mapp[i][j]<<endl;
}
}
return 0;
}