您的位置:首页 > 其它

[cp] 预测分析表的生成

2005-04-28 19:44 369 查看
刚学编译原理,因为考研会考的原因加上觉得实践起来也比较有趣,于是打算把部分简单的给实践一下,首先当然是 自动机 的生成, 这个已经写完,还按照课本上说的实现了一个类似LEX的程序,不过代码有点乱,就先不说了, 而预测分析程序,就稍微简单点。 先把代码发一下~ 以后有空再说……不过也没什么好说的 HOHO
因为时间关系 刚把消除递归加上, 提取公共左因子还没加……
// [今天早上把提取公共左因子也加上了……]
后来发现了一个问题,就是一开始的存储方式不合理,我把非终结符和终结符都放到了一个集合中顺序的先保存非终结符然后到终结符,那时候还没考虑消除递归提取因子等,也没什么问题,不过最近把这两个加上,还有消除冗余的产生式时便遇到了一个本不应该考虑的问题,因为我的产生式保存的并不是具体的终结符或者非终结符,而是对应他们在集合中的下标,现在呢,要动态的加入新的产生式,新的非终结符,于是牵一发而动全身。只要加/减一个马上要更新产生式记录中的下标。 在类 Grammar 中有一个UpdateIndex 函数便是因此而加入(勉强搞定),不过实在不雅观……,以后有时间一定把它干掉…… 嘿嘿。
后来想了下应该这样存储产生式,同样保存下标,不过非终结符和终结符放在两个集合,下标被一个结构保存
struct Index
{
int flag : 1 如果是0表示非终结符,否则表示终结符
int index : 31 具体的下标(如果下标比这还大,那拒绝保存……HOHO)
}
#pragma once

#include "CustomCollection.h"
#include "Common/any.h"
#include <assert.h>
#include <deque>
/*
* [空字——基与方便直接用string来存储空字]
**/
const string g_c_emptyletter = "@";
/*
* [标记字符 # ,必须保证文法的终结符不包含该字符]
**/
const string g_c_flagletter = "#";
class Grammar
{
public:
/*
* [类型说明]
**/
typedef CustomCollection<string> TypeVN;
typedef CustomCollection<string> TypeVT;
typedef deque<int > TypeProductionItem;
typedef deque<TypeProductionItem > TypeProduction ;
typedef deque<TypeProduction> TypeProductionList;
typedef vector<vector<vector<string> > > TypeRightPartProfuction;
Grammar(void);
~Grammar(void);
public:
/*
* [读取文法]
**/
void ReadGrammar(istream& is);
/*
* [消除左递归]
**/
void Remove_LeftRecursice();
/*
* [提取公共左因子]
**/
void DistillCommonLeftGene();
/*
* [字符串显示]
**/
string ToString();
/*
* [get/set]
**/
bool is_start(int index)const;
bool is_nonterminal(int index)const;
bool is_nonterminal(const string& str)const;
bool is_terminal(int index)const ;
bool is_terminal(const string& str)const ;
bool is_contain_empty_letter_production(int index)const;
int get_index_of_emptyletter()const;
int get_index_of_flagletter()const;
int get_startIndex()const;
int get_terminal_count()const;
int get_nonterminal_count()const;
string get_nonterminal_label(int index)const;
string get_terminal_label(int index)const;
string get_label(int index)const;
string get_start()const;
const TypeProductionList& get_production_list()const;
TypeProductionList& get_production_list();
const TypeProduction& get_production(int index)const ;
TypeProduction& get_production(int index);
static string get_emptyletter();
static string get_flagletter();
protected:
/*
* [消除直接 | 非直接左递归 | 化简]
**/
void Remove_DirectLeftRecursice(int cur_vn_index);
void Remove_UnDirectLeftRecursice(int cur_vn_index, int relative_vn_index);
void Reduction();
/*
* [更新下标]
**/
void UpdateIndex(int new_non_terminate_index,int offset);
protected:
TypeProductionList m_production_list; // [产生式记录]
TypeVN m_vnRecord; // [非终结符记录]
TypeVT m_vtRecord; // [终结符记录]
string m_start; // [开始符号]
int m_startIndex; // [开始符号的下标]
/*
* [特殊终结符]
**/
static const string m_emptyletter ;
static const string m_flagletter ;
public:
};
/***********************************************************************************************************/
/* Author : cz
/* Time : 2005/03/30
/* Desc : 求First集
/* Name :
/***********************************************************************************************************/

#pragma once
#include "CustomCollection.h"
#include "Common/any.h"
#include "Grammar.h"
class First
{
public:
/*
* [类型说明]
**/
typedef Grammar::TypeVN TypeVN;
typedef Grammar::TypeVT TypeVT;
typedef Grammar::TypeProductionItem TypeProductionItem;
typedef Grammar::TypeProduction TypeProduction ;
typedef Grammar::TypeProductionList TypeProductionList;
typedef CustomCollection<int > TypeFirstCollection;
typedef vector<TypeFirstCollection > TypeFirstListCollection;
public:
First(const Grammar &_grammar);
~First(void);
public:
/*
* [计算规则的First集]
**/
void Calculate_First();
/*
* [字符串形式返回某个文法的First集]
**/
string ToString();
operator string();
/*
* [返回First集]
**/
const TypeFirstCollection& GetFirst(int 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;
protected:
/*
* [计算First]
**/
TypeFirstCollection& Calculate_First(const TypeProductionItem& gramar_itm, TypeFirstCollection& firstC);
TypeFirstCollection& Calculate_First(TypeProductionItem::const_iterator begin,
TypeProductionItem::const_iterator end,
TypeFirstCollection& firstC);
TypeFirstCollection& Calculate_First(const TypeProduction& gramar, TypeFirstCollection& firstC);
TypeFirstCollection& Calculate_First( int gramarIndex, TypeFirstCollection& firstC);
/*
* [全部都计算过了才能调用此函数,否则发生错误]
**/
TypeFirstCollection& Calculate_First(TypeProductionItem::const_iterator begin,
TypeProductionItem::const_iterator end,
TypeFirstCollection& firstC)const;
protected:
const Grammar &m_grammar;
TypeFirstListCollection m_firstList;
vector<bool > m_hasCalculated;
};

/***********************************************************************************************************/
/* Author : cz
/* Time : 2005/03/30
/* Desc : 求Follow集
/* Name :
/***********************************************************************************************************/
#pragma once
#include "Common/Collection.h"
#include "Common/any.h"
#include "First.h"
class Follow
{
public:
/*
* [类型说明]
**/
typedef Grammar::TypeVN TypeVN;
typedef Grammar::TypeVT TypeVT;
typedef Grammar::TypeProductionItem TypeProductionItem;
typedef Grammar::TypeProduction TypeProduction ;
typedef Grammar::TypeProductionList TypeProductionList;
typedef CustomCollection<int > TypeFollowCollection;
typedef vector<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;
/*
* [字符串方式返回Follow集]
**/
string ToString();
operator string();
protected:
/*
* [根据课本第2个规则计算Follow集]
**/
TypeFollowCollection& Calculate_Follow_2nd_rules(int vn_index,TypeFollowCollection& outC);
/*
* [根据第3个规则计算,注意必须先根据第2个规则计算后才能调用此函数]
**/
TypeFollowCollection& Calculate_Follow_3rd_rules(int vn_index,TypeFollowCollection& outC);
protected:
const First &m_first;
const Grammar &m_grammar;
TypeFollowListCollection m_followList;
// [标记]
bool m_hasCalFollow; // [判断是否已经计算过]
vector<CustomCollection<int> > m_helperRecord; // [在根据第三个条件求Follow集时辅助]
};

/***********************************************************************************************************/
/* Author : cz
/* Time : 2005/03/30
/* Desc : 预测分析表
/* Name :
/***********************************************************************************************************/
#pragma once
#include "Common/Collection.h"
#include "Common/any.h"
#include "Grammar.h"
#include "First.h"
#include "Follow.h"
#include <deque>
class ParseTable
{
public:
ParseTable(const Grammar& m_grammar,const First& _first,const Follow& _follow);
~ParseTable(void);
/*
* [类型说明]
**/
typedef Grammar::TypeVN TypeVN;
typedef Grammar::TypeVT TypeVT;
typedef Grammar::TypeProductionItem TypeProductionItem;
typedef Grammar::TypeProduction TypeProduction ;
typedef Grammar::TypeProductionList TypeProductionList;
typedef First::TypeFirstCollection TypeFirstCollection;
typedef First::TypeFirstListCollection TypeFirstListCollection;
typedef Follow::TypeFollowCollection TypeFollowCollection;
typedef Follow::TypeFollowListCollection TypeFollowListCollection;
typedef deque<deque<int> > TypeTableItem;
typedef deque< TypeTableItem > TypeTable;
public:
/*
* [根据终结符(下标),非终结符(下标),获得分析表中的产生式]
* [vn_index- 非终结符的下标]
* [vt_index- 终结符的下标]
* [out_production- 如果存在返回对应的产生式 ]
* [返回值: 如果非空返回 TF_OK]
[ 如果空但是字符在First集中返回 TF_FIRST]
[ 如果空但是字符在Follow集中返回 TF_FOLLOW]
[ 否则,匹配失败,返回 TF_ERROR]
**/
enum TABLE_FLAG
{
TF_ERROR = 0,
TF_OK ,
TF_FIRST,
TF_FOLLOW
};
static const int sc_first_flag = -1;
static const int sc_follow_flag = -2;
int GetProduction(int vn_index, int vt_index, TypeProductionItem& out_production);
/*
* [计算预测分析表]
**/
void CalculateTable();
/*
* [字符串形式返回]
**/
string ToString()const;
operator string()const{return ToString();}
protected:
TypeTable m_table;
const Grammar& m_grammar;
const First& m_first;
const Follow& m_follow;
};

#pragma once
#include "Common/Collection.h"
#include "Common/any.h"
#include "Grammar.h"
#include "First.h"
#include "Follow.h"
#include "ParseTable.h"
/***********************************************************************************************************/
/* Author : cz
/* Time : 2005/03/30
/* Desc : LL_1 分析
/* Name :
/***********************************************************************************************************/
class LL_1
{
public:
LL_1(void);
~LL_1(void);
/*
* [类型说明]
**/
typedef Grammar::TypeVN TypeVN;
typedef Grammar::TypeVT TypeVT;
typedef Grammar::TypeProductionItem TypeProductionItem;
typedef Grammar::TypeProduction TypeProduction ;
typedef Grammar::TypeProductionList TypeProductionList;

typedef First::TypeFirstCollection TypeFirstCollection;
typedef First::TypeFirstListCollection TypeFirstListCollection;
typedef Follow::TypeFollowCollection TypeFollowCollection;
typedef Follow::TypeFollowListCollection TypeFollowListCollection;
public:
/*
* [读取文法]
**/
void ReadGrammar(istream& is);
/*
* [计算规则的First集]
**/
void Calculate_First();
/*
* [计算规则的Follow集]
**/
void Calculate_Follow();
/*
* [计算预测分析表]
**/
void Calculate_ParseTable();
/*
* [字符传返回grammar | first | follow 集 以及 预测分析表]
**/
string grammar();
string first();
string follow();
string table();
protected:
Grammar m_grammar;
First m_first;
Follow m_follow;
ParseTable m_parseTable;
// [标记]
bool m_hasCalFirst;
bool m_hasCalFollow;
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: