[cp] SLR分析表的生成 以及分析程序 (2)

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;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值