📄 parsing.cpp
字号:
/*//此文件是分析Analyse类的定义,整个程序的核心,
//通过此类从Grammer类中得到开始符号,然后从Token类中取得token序列,进行匹配查表,
//找到下一步该做什么。记录栈的动作情况和错误情况,输出分析栈和错误信息。
class Analyse
{
private:
Token token;
LL_Table LL_table;
Grammer grammer;
AnalyseStack analyse_stack;
vector<string> vc_s;
string strAction;
ofstream tree_out;
ofstream error_out;
public:
Analyse(const char treefile,const char errorfile,
const char tokenfile[],
const char grammerfile[],
const char LLtablefile[])
:token(tokenfile),LL_table(LLtablefile),grammer(grammerfile),analyse_stack();
void makeAnalyseStack();
void push_to_Stack();
bool match(string s1,string s2);
~Analyse();
};*/
#include "main.h"
using namespace std;
Analyse::Analyse(const char treefile[],const char errorfile[])
{
tree_out.open(treefile,ios_base::out);
if(!tree_out)
{
cerr<<"open file"<<treefile<<"error\n";
exit(1);
}
}
//该函数是整个语法分析的主要函数,LL(1)文法的匹配过程
void Analyse::makeAnalyseStack(Token &token,Grammer &grammer,LL_Table &LL_TB,AnalyseStack &analyse_stack,Error &error)
{
bool can_get_token=true;
unsigned int Line=grammer.line;
TOKEN tokenbuff;
int i=0; //记录错无个数 当达到20个的时候就退出函数
this->vc_s.push_back(grammer.getProduce(0).leftLabel); //put the start label into the analyse_stack;
while(!vc_s.empty() && token.isHasToken()) //看栈顶和token是不是为空 空的话就退出循环
{
if(can_get_token)
this->evaluate(tokenbuff,token.getToken()); //获得token 并放在tokenbuff
if(tokenbuff.strName=="@") //检查token是不是到头
{
unsigned int pp;
pp=LL_TB.checkTable(vc_s[vc_s.size()-1],"@",Line);
if(pp>Line)
{
vc_s.pop_back();
cerr<<"error in the end\n";
continue;
}
GRAMMER gra;
this->evaluate(gra,grammer.getProduce(pp-1));
string ps;
vector<string>::iterator it=gra.vc_rightLable.begin();
while(it != gra.vc_rightLable.end())
{
ps+=*it+" ";
it++;
}
this->strAction=gra.leftLabel+"->"+ps;
this->push_to_Stack(analyse_stack);
this->vc_s.pop_back();
it=gra.vc_rightLable.end();
while(it > gra.vc_rightLable.begin())
{
it--;
if(*it!="@")
this->vc_s.push_back(*it);
}
}
else if(LL_TB.isTerminal(vc_s[vc_s.size()-1]))//如果是终极符号
{
if(vc_s[vc_s.size()-1]=="@")//检查是否结束
{
can_get_token=false; //就是能不能取token 的标志
this->strAction="match"; //状态匹配
this->push_to_Stack(analyse_stack); //状态进栈
this->vc_s.pop_back(); //分析栈pop栈顶元素
continue;
}
else if(tokenbuff.strType=="ID" || tokenbuff.strType=="NUM")//若是标识符或数字
{
if(this->match(vc_s[vc_s.size()-1],tokenbuff.strType))
{
this->strAction="match"; //状态匹配
can_get_token=true; //就是能不能取token 的标志
this->push_to_Stack(analyse_stack); //状态进栈
this->vc_s.pop_back();
}
else //error
{
i++;
can_get_token=true; //就是能不能取token 的标志
ERROR Er;
Er.line=tokenbuff.line;
Er.strError="the "+tokenbuff.strType+" "+tokenbuff.strName+" not right";
error.add_to_error(Er);
this->strAction="non_match"; //动作的描述
this->push_to_Stack(analyse_stack); //状态进栈
this->vc_s.pop_back();
}
}
else
{
if(this->match(vc_s[vc_s.size()-1],tokenbuff.strName))
{
this->strAction="match"; //状态匹配
can_get_token=true; //就是能不能取token 的标志
this->push_to_Stack(analyse_stack); //状态进栈
this->vc_s.pop_back();
}
else //error
{
i++;
ERROR Er;
can_get_token=true; //就是能不能取token 的标志
Er.line=tokenbuff.line;
Er.strError="the "+tokenbuff.strType+" "+tokenbuff.strName+" not right";
error.add_to_error(Er); //保存错误描述
this->strAction="non_match"; //动作的描述
this->push_to_Stack(analyse_stack); //状态进栈
this->vc_s.pop_back();
}
}
}
else if(LL_TB.isNonterminal(vc_s[vc_s.size()-1]))
{
can_get_token=false;
unsigned int pp;
if(tokenbuff.strType=="ID" || tokenbuff.strType=="NUM")
{
pp=LL_TB.checkTable(vc_s[vc_s.size()-1],tokenbuff.strType,Line);
if(pp>Line) //找不到产生式 出错
{
can_get_token=true;
ERROR Er;
i++;
Er.line=tokenbuff.line;
Er.strError="the "+tokenbuff.strType+" "+tokenbuff.strName+" not right";
error.add_to_error(Er); //保存错误描述
continue;
}
else
{
GRAMMER gra;
this->evaluate(gra,grammer.getProduce(pp-1)); //获得 产生式
string ps;
vector<string>::iterator it=gra.vc_rightLable.begin();
while(it != gra.vc_rightLable.end()) //获得 动作的描述
{
ps+=*it+" ";
it++;
}
this->strAction=gra.leftLabel+"->"+ps; //动作的描述
this->push_to_Stack(analyse_stack); //状态进栈
this->vc_s.pop_back(); //分析栈pop栈顶元素
it=gra.vc_rightLable.end();
while(it > gra.vc_rightLable.begin()) //放入得到的产生式的右边的
{
it--;
this->vc_s.push_back(*it);
}
}
}
else
{
pp=LL_TB.checkTable(vc_s[vc_s.size()-1],tokenbuff.strName,Line);
if(pp>Line) //error
{
can_get_token=true;
i++;//记录 错误个数
ERROR Er;
Er.line=tokenbuff.line;
Er.strError="the "+tokenbuff.strType+" "+tokenbuff.strName+" not right";
error.add_to_error(Er); //添加错误
continue;
}
else
{
GRAMMER gra;
this->evaluate(gra,grammer.getProduce(pp-1)); //获得 产生式
string ps;
vector<string>::iterator it=gra.vc_rightLable.begin();
while(it != gra.vc_rightLable.end()) //获得 动作的描述
{
ps+=*it+" ";
it++;
}
this->strAction=gra.leftLabel+"->"+ps; //动作的描述
this->push_to_Stack(analyse_stack); //状态进栈
this->vc_s.pop_back(); //分析栈pop栈顶元素
it=gra.vc_rightLable.end();
while(it > gra.vc_rightLable.begin()) //放入得到的产生式的右边的
{
it--;
this->vc_s.push_back(*it);
}
}
}
}
if(i>=20) break;
}
if(vc_s.empty() && !token.isHasToken())
{
cout<<"The analyse succeed !!!\n";
}
else //error
{
ERROR Er;
Er.line=-1;
i++;
Er.strError="there are errors in the end of this program";
error.add_to_error(Er); //添加错误
}
if(i!=0) cout<<"there are "<<i<<" error in you code\n";
analyse_stack.disPlay(tree_out); //输出栈记录到文件
error.disPathError(); //输出错误到文件
//system("PAUSE");
}
void Analyse::push_to_Stack(AnalyseStack &analyse_stack)
{
Stack st;
vector<string>::iterator it=vc_s.end();
while(--it >= vc_s.begin())
{
st.analyse_stack.push_back(*it);
}
st.action=strAction;
analyse_stack.push(st);
}
bool Analyse::match(std::string s1, std::string s2)
{
return s1==s2;
}
void Analyse::evaluate(TOKEN &to,TOKEN ac)
{
to.line=ac.line;
to.strName=ac.strName;
to.strType=ac.strType;
}
void Analyse::evaluate(GRAMMER &g,GRAMMER G)
{
g.leftLabel=G.leftLabel;
vector<string>::iterator it=G.vc_rightLable.begin();
while(it != G.vc_rightLable.end())
{
g.vc_rightLable.push_back(*it);
it++;
}
}
Analyse::~Analyse()
{
tree_out.close();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -