1、实验目的
设计、编制和调试一个典型的语法分析方法,进一步掌握常用的语法分析方法。
2、实验要求
(1) 根据LL(1)分析法编写一个语法分析程序,可根据自己实际情况,选择以下一项作为分析算法的输入:
a.直接输入根据已知文法构造的分析表M;
b.输入文法的FIRST(α)和FOLLOW(U)集合,由程序自动生成文法的分析表M;
c.输入已知文法,由程序自动构造文法的分析表M。
(2) 程序具有通用性
所开发的程序可适用于不同的文法和任意输入串,且能判断该文法是否为LL(1)文法。
(3) 有运行实例
对于输入的文法和符号串,所编制的语法分析程序应能正确判断此串是否为文法的句子,并要求输出分析过程。
(4) 提交实验报告,报告内容参考“词法分析程序”
以上为要求,当然,这么庞大的要求我们要慢慢来,慢慢来。
我们先完成给定一个固定的文法的预测分析表,然后判断一个符号串是否属于该文法。我们的思路是这样的
当然为了流畅实现上述三个重复的活动,需要一些函数的辅助。以下为我的代码,如有谬误,望指出
#include
#include
#include
using namespace std;
string E[6]={"TE'","","","TE'","",""};
string E1[6]={"","+TE'","","","ε","ε"};
string T[6]={"FT'","","","FT'","",""};
string T1[6]={"","ε","*FT'","","ε","ε"};
string F[6]={"i","","","(E)","",""};
bool invertStack(stack<string> &one_stack)
{
if (one_stack.empty())//if the stack is null,then don't invert it
{
return false;
}else
{
//init a stack to save the inverted stack
stack<string> invert;
while(!one_stack.empty())
{
invert.push(one_stack.top());
one_stack.pop();
}
//this moment the stack's inverted state is the stack invert ,so get it back
one_stack=invert;
return true;
}
}
void displayStack(stack<string> one_stack)
{
invertStack(one_stack);
while(!one_stack.empty())
{
cout<cout<<" ";
}
string configureProduction(stack<string> const &analyse,int char_index)
{
if (analyse.top()=="E")
{
if (E[char_index]!="")
{
return E[char_index];
}
}else if (analyse.top()=="E'")
{
if (E1[char_index]!="")
{
return E1[char_index];
}
}else if (analyse.top()=="T")
{
if (T[char_index]!="")
{
return T[char_index];
}
}else if (analyse.top()=="T'")
{
if (T1[char_index]!="")
{
return T1[char_index];
}
}else if (analyse.top()=="F")
{
if (F[char_index]!="")
{
return F[char_index];
}
}
return "error";
}
bool isMatching(stack<string> const &analyse,char odd_first_char)
{
if (analyse.top()[0]==odd_first_char)
{
return true;
}
return false;
}
int findTIndex(char some)//to find the Terminated char's index
{
switch (some)
{
case 'i':return 0;
case '+':return 1;
case '*':return 2;
case '(':return 3;
case ')':return 4;
case '#':return 5;
default:
cout<<"error";
return -1;
}
}
bool display(stack<string> &analyse,string &odd)
{
static int step=1;
if (step==1)//while the first step is clearly
{
cout<" ";
displayStack(analyse);
cout<" ";
int char_index=findTIndex(odd[0]);
if (char_index==-1)
{
return false;
}
string production=configureProduction(analyse,char_index);
cout<"->"<if (production=="error")
{
return false;
}
step++;
analyse.pop();//pop the top element
while(production.size()!=1)
{
if (production[production.length()-1]=='\'')
{
string temp=production.substr(production.length()-2,production.length()-1);
analyse.push(temp);
production=production.substr(0,production.length()-2);
}else
{
string temp=production.substr(production.length()-1,production.length()-1);
analyse.push(temp);
production=production.substr(0,production.length()-1);
}
}
analyse.push(production);
}
else
{
if (isMatching(analyse,odd[0]))
{
cout<" ";
displayStack(analyse);
cout<" ";
if (odd[0]=='#')
{
cout<<"接受"<return false;
}
cout<<"“"<0]<<"”匹配"<1,odd.length()-1);//if match odd string decrease
analyse.pop();
step++;
return true;
}else
{
cout<" ";
displayStack(analyse);
cout<" ";
int char_index=findTIndex(odd[0]);
if (char_index == -1)
{
return false;
}
string production=configureProduction(analyse,char_index);
cout<"->"<if (production=="error")
{
return false;
}
step++;
if (production=="ε")
{
analyse.pop();
return true;
}
analyse.pop();//pop the top element
while(production.size()!=1)
{
if (production[production.length()-1]=='\'')
{
string temp=production.substr(production.length()-2,production.length()-1);
analyse.push(temp);
production=production.substr(0,production.length()-2);
}else
{
string temp=production.substr(production.length()-1,production.length()-1);
analyse.push(temp);
production=production.substr(0,production.length()-1);
}
}
analyse.push(production);
}
}
}
int main()
{
cout<<"请输入符号串";
string inputstring;
cin>>inputstring;
//init a stack to analyse
stack<string> analyse_s;
analyse_s.push("#");
analyse_s.push("E");
//init a odd string
string odd =inputstring;
cout<<"步骤 "<<"分析栈 "<<"剩余输入串 "<<"推导所用产生式或匹配"<//the first step is succeed
while(!odd.empty()&&display(analyse_s,odd));
system("pause");
return 0;
}
因为机房里是VS2010所以注释是英文的,最后的代码会变成中文的注释。我们大概的分析过程出来了,那么下一步,我们从一个限定了格式的txt文件里面读出我们需要的预测分析表。