1. First,Follow 集的生成
由于之前我已经完成了 LL1语法器的生成。这里仅是借鉴了之前的代码。下面是类的声明和部分实现
/************************************************************************/
/* Author : 陈正
/* Time : 2005/06/23
/* Desc : 计算文法的 First 集
/************************************************************************/
#include "TypeDefine.h"
#include "Grammar.h"
#include <hash_map>
#include <deque>
using namespace std;
class First
{
public:
typedef Grammar::TypeProductionItem TypeProductionItem;
typedef Grammar::TypeProduction TypeProduction ;
typedef Grammar::TypeProductionList TypeProductionList;
typedef CustomCollection<Index > TypeFirstCollection;
typedef deque<TypeFirstCollection > TypeFirstListCollection;
public:
First(const Grammar& grammar);
~First(void);
/*
* [计算规则的First集]
* */
void Calculate_First();
/*
* [返回First集]
* */
const TypeFirstCollection& GetFirst(const Index& index)const;
TypeFirstCollection& GetFirst(const TypeProductionItem&
grammar,TypeFirstCollection& outC)const;
TypeFirstCollection& GetFirst(const TypeProductionItem::const_iterator begin, const TypeProductionItem::const_iterator end,
TypeFirstCollection& outC)const;
/* —— 2005/06/24 ——
* [以字符串形式表示]
* */
string ToString();
protected:
/*
* [计算First]
* */
TypeFirstCollection& Calculate_First(const TypeProductionItem& pro_itm, TypeFirstCollection& firstC);
TypeFirstCollection& Calculate_First(TypeProductionItem::const_iterator begin,
TypeProductionItem::const_iterator end,
TypeFirstCollection& firstC);
TypeFirstCollection& Calculate_First(const TypeProduction& production, TypeFirstCollection& firstC);
TypeFirstCollection& Calculate_First(const Index& index, TypeFirstCollection& firstC);
TypeFirstCollection& Calculate_First(
TypeProductionItem::const_iterator begin,
TypeProductionItem::const_iterator end,
TypeFirstCollection& firstC)const;
protected:
const Grammar& m_grammar;
map<Index,bool> m_has_calculated;
TypeFirstListCollection m_first_of_nonterminal;
TypeFirstListCollection m_first_of_terminal;
};
/************************************************************************/
/* Author : 陈正
/* Time : 2005/06/23
/* Desc : 计算 follow 集
/************************************************************************/
#include "Grammar.h"
#include "First.h"
#include "CustomCollection.h"
#include <deque>
using namespace std;
class Follow
{
public:
typedef Grammar::TypeProductionItem TypeProductionItem;
typedef Grammar::TypeProduction TypeProduction ;
typedef Grammar::TypeProductionList TypeProductionList;
typedef CustomCollection<Index > TypeFollowCollection;
typedef deque<TypeFollowCollection > TypeFollowListCollection;
public:
Follow(const First& _first,const Grammar &_grammar);
~Follow(void);
public:
/*
* [计算规则的Follow集]
* */
void Calculate_Follow();
/*
* [返回某个非终结符的 Follow 集]
* */
const TypeFollowCollection& GetFollow(int vn_index)const;
/* —— 2005/06/24 ——
* [字符串显示]
* */
string ToString()const;
protected:
/*
* [根据课本第2个规则计算Follow集]
* */
TypeFollowCollection& Calculate_Follow_2nd_rules(const Index& vn_index,TypeFollowCollection& outC);
/*
* [根据第3个规则计算,注意必须先根据第2个规则计算后才能调用此函数]
* */
TypeFollowCollection& Calculate_Follow_3rd_rules(const Index& vn_index,TypeFollowCollection& outC);
protected:
const First& m_first;
const Grammar& m_grammar;
TypeFollowListCollection m_follow_of_nonterminal;
deque<CustomCollection<Index> > m_helper; // [在根据第三个条件求Follow集时辅助]
bool m_has_calculated;
};
部分实现:
/*————————————————————————————————————————————/
* Desc: 计算规则的First集
* Parm
/————————————————————————————————————————————*/
void First::Calculate_First()
{
/*
* [初始化first集大小]
**/
m_first_of_nonterminal.resize( m_grammar.get_str_nonterminals().size() );
m_first_of_terminal.resize(m_grammar.get_str_terminals().size());
/*
* [终结符的first集等于本身]
**/
for( unsigned int i=0; i < m_grammar.get_str_terminals().size(); i++)
{
this->m_first_of_terminal[i].Add( Index(i,true) );
this->m_has_calculated[ Index(i,true) ] = true;
}
/*
* [计算非终结符的first集]
**/
for( unsigned int i=0; i<m_grammar.get_str_nonterminals().size(); i++)
{
Calculate_First( Index(i,false), this->m_first_of_nonterminal[i]);
}
}
/*————————————————————————————————————————————/
* Desc: 根据(下标对应的规则|规则)计算First
* Parm
/————————————————————————————————————————————*/
First::TypeFirstCollection& First::Calculate_First(const TypeProduction& production, TypeFirstCollection& firstC)
{
for(unsigned int i=0; i < production.size(); i++)
{
const TypeProductionItem& pro_item = production[i];
assert(! pro_item.empty() );
Calculate_First(pro_item,firstC);
}
return firstC;
}
First::TypeFirstCollection& First::Calculate_First(const TypeProductionItem& pro_item, TypeFirstCollection& firstC)
{
return Calculate_First(pro_item.begin(),pro_item.end(),firstC);
}
First::TypeFirstCollection& First::Calculate_First(const Index& index, TypeFirstCollection& firstC)
{
/*
* [判断是否已经计算]
**/
if(m_has_calculated[index])
{
firstC = m_first_of_nonterminal[index];
return firstC;
}
m_has_calculated[index] = true;
Calculate_First(m_grammar.get_production(index.index),firstC);
return firstC;
}
First::TypeFirstCollection& First::Calculate_First(
TypeProductionItem::const_iterator begin,
TypeProductionItem::const_iterator end,
TypeFirstCollection& firstC)
{
/*
* [(1) 如果第一个字符是终结符]
* */
if(begin->is_terminal())
{
TypeFirstCollection tmp_c = ( m_first_of_terminal[ (*begin) ] );
firstC += tmp_c;
return firstC;
}
/*
* [如果第一个字符不是终结符]
* [(1) 把产生式最左边的非终符的 First 集 去掉空字 加到当前First集合]
* */
Calculate_First( *begin , m_first_of_nonterminal[ (*begin) ]) ;
{
TypeFirstCollection tmp_c = m_first_of_nonterminal[ (*begin) ];
tmp_c -= m_grammar.get_index_of_emptyletter();
firstC += ( tmp_c );
}
/*
* [(2) 如果产生式是这样的类型 X->Y1 Y2 Y3 …… Yk,并且从第1个到第j个的First集中包含空字]
* [ 则把第 j+1 个的First集去掉空字加到当前First中,特别的如果所有的都包含空字,则把空字加到当前First中]
* */
bool exist_emptyletter = true;
for(int i=0; begin != end ; begin ++, i++ )
{
Calculate_First( *begin , m_first_of_nonterminal[ (*begin) ]) ;
// [update 6/30/2005]
if(m_first_of_nonterminal[ (*begin) ].Exist(m_grammar.get_index_of_emptyletter()))
{
TypeProductionItem::const_iterator next = begin;
next ++;
if(next == end)
break;
TypeFirstCollection tmp_c = m_first_of_nonterminal[ (*next) ];
tmp_c -= m_grammar.get_index_of_emptyletter();
firstC += ( tmp_c );
}
else
{
exist_emptyletter = false;
break;
}
}
/*
* [如果所有的都包含空字 则加入空字]
* */
if(exist_emptyletter)
{
firstC += (m_grammar.get_index_of_emptyletter());
}
return firstC;
}
/*————————————————————————————————————————————/
* Desc: 根据第2个规则计算Follow集
* Parm
/————————————————————————————————————————————*/
Follow::TypeFollowCollection& Follow::Calculate_Follow_2nd_rules(const Index& vn_index,
TypeFollowCollection& followC)
{
const TypeProduction &production = m_grammar.get_production(vn_index);
for(unsigned int itm_index=0; itm_index<production.size(); itm_index++)
{
const TypeProductionItem &production_itm = production[itm_index];
/*
* [判断(2)条件,如果满足 A->a B b,则把First(b)-空字放到Follow(B)中]
**/
for(unsigned int id_index = 0; id_index < production_itm.size() - 1/*因为最后一个不满足*/; id_index ++ )
{
/*
* [如果为非终结符,才计算Follow集]
**/
Index cur_vn_index = production_itm[id_index];
Index next_vn_index = production_itm[id_index + 1];
if( !cur_vn_index.is_terminal() && !(cur_vn_index == next_vn_index))
{
First::TypeFirstCollection tmp_firstC ;
m_first.GetFirst( production_itm.begin()+id_index+1, production_itm.end() , tmp_firstC);
/*
* [除去空字,加到Follow集中]
**/
tmp_firstC -= m_grammar.get_index_of_emptyletter();
m_follow_of_nonterminal[cur_vn_index ] += (tmp_firstC);
}
}
}
return followC;
}
/*————————————————————————————————————————————/
* Desc: 根据第3个规则计算
* Parm
/————————————————————————————————————————————*/
Follow::TypeFollowCollection& Follow::Calculate_Follow_3rd_rules(const Index& vn_index,
TypeFollowCollection& followC)
{
const TypeProduction &production = m_grammar.get_production(vn_index);
for(unsigned int itm_index=0; itm_index<production.size(); itm_index++)
{
const TypeProductionItem &production_itm = production[itm_index];
/*
* [判断(3)条件,如果满足 A-> a B 或者A->a B b,b=>空字,则把Follow(A)加到Follow(B)中]
**/
/*
* [A->BCdDE 则最后一个直接把Follow(A)加到Follow(E)中,其他的比如D,先判断E是否有空字产生式]
* [如果有才把Follow(A)加到Follow(D)中,当遇到一个不属于此情况跳出循环]
**/
Index last_vn_index = production_itm.back();
if( !last_vn_index.is_terminal() // [非终结符条件]
&& !(last_vn_index == vn_index) // [不是同一个非终结符]
)
{
/*
* [记录该非终结符的变化会影响到的其他非终结符的下标]
**/
m_helper[vn_index].Add(last_vn_index);
m_follow_of_nonterminal[ last_vn_index ] += ( followC);
/*
* [更新所有会受last_vn_index下标所表示的非终结符影响的其他非终结符的Follow集合]
**/
for(unsigned int updateindex = 0;
updateindex < m_helper[last_vn_index].size();
updateindex++)
{
Index update_vn_index =
m_helper[last_vn_index].GetElement(updateindex);
m_follow_of_nonterminal[update_vn_index] += ( followC );
}
}
for(int id_index = (int)production_itm.size() - 2; id_index >= 0; id_index --)
{
/*
* [如果为非终结符,才计算Follow集]
**/
Index cur_vn_index = production_itm[id_index];
if(!cur_vn_index.is_terminal())
{
First::TypeFirstCollection tmp_firstC ;
m_first.GetFirst(production_itm.begin()+id_index+1, production_itm.end(),tmp_firstC);
if( cur_vn_index != vn_index &&
tmp_firstC.Exist(m_grammar.get_index_of_emptyletter())
)
{
/*
* [记录被影响的终结符号下标——解释同上]
**/
m_helper[vn_index].Add(cur_vn_index);
m_follow_of_nonterminal[cur_vn_index] += ( followC );
/*
* [解释同上]
**/
for( unsigned int updateindex = 0;
updateindex < m_helper[cur_vn_index].size();
updateindex++)
{
Index update_vn_index =
m_helper[cur_vn_index].GetElement(updateindex);
m_follow_of_nonterminal[update_vn_index] += ( followC );
}
}
}
}
}
return followC;
}