1. SLR分析表的生成
仅列出定义及部分实现
/************************************************************************/
/* Author : 陈正
/* Time : 2005/06/24
/* Desc : 分析表
/************************************************************************/
#include "TypeDefine.h"
#include <string>
#include <deque>
using namespace std;
class ParseTable
{
class LR_Parser;
public:
ParseTable(void);
virtual ~ParseTable(void);
/* —— 2005/06/24 ——
* [返回开始状态]
* */
virtual int get_1st_state() = 0;
/* —— 2005/06/24 ——
* [生成SLR 分析表]
* */
virtual bool gen_table(ostream& error) = 0;
/* —— 2005/06/24 ——
* [返回GOTO值]
* */
virtual bool get_goto(int ,const Index& index, int& )const = 0;
/* —— 2005/06/24 ——
* [返回动作表]
* */
virtual bool get_action(int cur,const Index& index, Action& out_action)const = 0;
/* —— 2005/06/24 ——
* [字符串显示]
* */
virtual string ToString()const = 0;
/* —— 2005/06/27 ——
* [清空]
* */
virtual void clear() = 0;
/* —— 2005/06/27 ——
* [写数据]
* */
virtual void write_to(ostream& os) = 0;
};
#pragma once
/************************************************************************/
/* Author : 陈正
/* Time : 2005/06/24
/* Desc : SLR 分析表
/************************************************************************/
#include "Grammar.h"
#include "TypeDefine.h"
#include "First.h"
#include "Follow.h"
#include "ParseTable.h"
#include <deque>
#include <vector>
using namespace std;
class SLR_Table : public ParseTable
{
public:
typedef deque<map<string, Action > > TypeAction;
typedef deque<map<string, int > > TypeGoto;
public:
SLR_Table(const Grammar& m_grammar,const First& first,const Follow& follow);
~SLR_Table(void);
/* —— 2005/06/24 ——
* [生成SLR 分析表]
* */
bool gen_table(ostream& error);
/* —— 2005/06/24 ——
* [返回开始状态]
* */
int get_1st_state(){return 0;};
/* —— 2005/06/24 ——
* [返回GOTO值]
* */
bool get_goto(int ,const Index& index, int& )const;
/* —— 2005/06/24 ——
* [返回动作表]
* */
bool get_action(int cur,const Index& index, Action& out_action)const;
/* —— 2005/06/24 ——
* [设置动作表]
* */
bool add_to_action_s(int cur,const Index& index,int nxt);
bool add_to_action_r(int index_of_itemc,int index_of_item);
bool add_to_action_a(int cur);
/* —— 2005/06/24 ——
* [设置goto表]
* */
void add_to_goto(int index_of_itemc,const Index& index, int nxt);
/* —— 2005/06/24 ——
* [字符串显示]
* */
string ToString()const;
/* —— 2005/06/27 ——
* [清空]
* */
void clear();
/* —— 2005/06/27 ——
* [写数据]
* */
void write_to(ostream& os);
private:
const Grammar& m_grammar;
const First& m_first;
const Follow& m_follow;
TypeAction m_action_table;
TypeGoto m_goto_table;
};
部分实现
/*————————————————————————————————————————————/
* Desc: 生成SLR 分析表
* Parm
/————————————————————————————————————————————*/
bool SLR_Table::gen_table(ostream& error)
{
this->m_goto_table.resize(m_grammar.get_item_c_list().size());
this->m_action_table.resize(m_grammar.get_item_c_list().size());
for(unsigned int i=0; i<m_grammar.get_item_c_list().size(); i++)
{
const Item_c& itemc = m_grammar.get_item_c_list().GetElement(i);
/*
* (a) [如果[A->a。ab]在Ii中,并且goto(Ii, a) = Ij, 那么置action[i,a]为sj,含义是把a 和 状态 j进栈,a是终结符]
* (b) [如果[A->a。]在Ii中,那么对FOLLOW(A)中的所有b,置action[i,b]为rj,其中j表示A->a的编号,A不能为开始符号]
* (c) [如果是第一个项目在Ii中,那么置action[i,$] 为acc,表示接受]
* */
for(unsigned int j=0; j<itemc.size(); j++)
{
Index nxt_index;
int idx_item = itemc[j];
ItemType itype =
m_grammar.get_info_of_next_index(m_grammar.get_item(idx_item),nxt_index);
if(itype == IT_S )
// [移进 6/24/2005]
{
int nxt_state = m_grammar.get_dfa().get_next(i, nxt_index);
if(nxt_index.is_terminal())
{
if(!this->add_to_action_s(i, nxt_index,nxt_state))
{
error<<"在第 " + ToString::String(i) + "个项目集中发生冲突!";
return false;
}
}
else
{
this->add_to_goto(i,nxt_index,nxt_state);
}
}
else if(itype == IT_R)
// [规约 6/24/2005]
{
if(!this->add_to_action_r(i,idx_item))
{
error<<"在第 " + ToString::String(i) + "个项目集中发生冲突!";
return false;
}
}
else if(itype == IT_A)
// [接受 6/24/2005]
{
if(!this->add_to_action_a(i))
{
error<<"在第 " + ToString::String(i) + "个项目集中发生冲突!";
return false;
}
}
}
}
return true;
}