您的位置:首页 > 编程语言 > C语言/C++

C++:基于LL(1)方法的语法分析程序-1

2015-12-05 16:08 549 查看
1、实验目的

设计、编制和调试一个典型的语法分析方法,进一步掌握常用的语法分析方法。

2、实验要求

(1) 根据LL(1)分析法编写一个语法分析程序,可根据自己实际情况,选择以下一项作为分析算法的输入:

a.直接输入根据已知文法构造的分析表M;

b.输入文法的FIRST(α)和FOLLOW(U)集合,由程序自动生成文法的分析表M;

c.输入已知文法,由程序自动构造文法的分析表M。

(2) 程序具有通用性

所开发的程序可适用于不同的文法和任意输入串,且能判断该文法是否为LL(1)文法。

(3) 有运行实例

对于输入的文法和符号串,所编制的语法分析程序应能正确判断此串是否为文法的句子,并要求输出分析过程。

(4) 提交实验报告,报告内容参考“词法分析程序”

以上为要求,当然,这么庞大的要求我们要慢慢来,慢慢来。

我们先完成给定一个固定的文法的预测分析表,然后判断一个符号串是否属于该文法。我们的思路是这样的

不断判断分析栈的栈顶和剩余串的头是否一样

如果不同,则根据文法的预测分析表对分析栈栈顶进行推导

发生匹配后符号串减去头,栈弹出栈顶

当然为了流畅实现上述三个重复的活动,需要一些函数的辅助。以下为我的代码,如有谬误,望指出

#include <iostream>
#include <string>
#include<stack>
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<<one_stack.top();
one_stack.pop();
}
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<<step<<"       ";
displayStack(analyse);
cout<<odd<<"                ";
int char_index=findTIndex(odd[0]);
if (char_index==-1)
{
return false;
}
string production=configureProduction(analyse,char_index);
cout<<analyse.top()<<"->"<<production<<endl;
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<<step<<"       ";
displayStack(analyse);
cout<<odd<<"                ";
if (odd[0]=='#')
{
cout<<"接受"<<endl;
return false;
}
cout<<"“"<<odd[0]<<"”匹配"<<endl;
odd=odd.substr(1,odd.length()-1);//if match odd string decrease
analyse.pop();
step++;
return true;
}else
{
cout<<step<<"       ";
displayStack(analyse);
cout<<odd<<"                ";
int char_index=findTIndex(odd[0]);
if (char_index == -1)
{
return false;
}
string production=configureProduction(analyse,char_index);
cout<<analyse.top()<<"->"<<production<<endl;
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<<"步骤       "<<"分析栈     "<<"剩余输入串       "<<"推导所用产生式或匹配"<<endl;
//the first step is succeed
while(!odd.empty()&&display(analyse_s,odd));
system("pause");
return 0;
}


因为机房里是VS2010所以注释是英文的,最后的代码会变成中文的注释。我们大概的分析过程出来了,那么下一步,我们从一个限定了格式的txt文件里面读出我们需要的预测分析表。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  编译原理 c语言