⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myyacc.h

📁 自己写的一个简易的YACC程序
💻 H
字号:
#include<vector>
#include<hash_set>
#include<hash_map>
#include<set>
#include<string>
#include<fstream>
#include<string>
#include<vector>
#include<iostream>
using namespace stdext;
using namespace std;
#define TOKENSTART 2000//我大概写的,估计应该够用了吧,不够再改,寒阿,这叫拆东墙补西墙
#define ERROR -1
#define EPSILON 1000
#define SEGMENT_DELIM 998
#define DEF_SEG_BEGIN 997
#define DEF_SEG_END 996
#define TOKEN 995
#define TYPE 994
#define UNION 993
#define LEFT 992
#define RIGHT 989
#define ENDMARK 984
#define BUFSIZE 400000
#define LSIZE 100
#define HSIZE 10000
#define NONASSOC 983 
//using namespace std;//remenber that the hash_set and hash_map is not contained in the C++ standard library
struct producer{
	int left;
	vector<int> right;
};
class item{	
public:
	item(int producerIndex,int pointPos){
		index=producerIndex;
		pp=pointPos;
		//end=false;
	};
	bool nextepsilon(producer*p){if(pp==p->right.size()-1)return true;else return false;};
	int getcurpath(vector<producer*>&);
	int getnextSym(vector<producer*>&);
	bool end(vector<producer*>&);//如果point位置在结尾,则为true;
	int pp;//point position;
	int index;//the index of production;
	hash_set<int> lookhead;//规约时需要用的
	int stateID;//这样加实在是浪费了空间,我估算了一下,浪费3*4*N B空间,但换来了时间的O(1)定位,其实我定义好结构也可以,来不及了啊
	
	
};
struct FAstate{
	FAstate(int id){stateID=id;};
	int stateID;
	hash_map<int,int> trans;
};
bool operator <(const item &it1,const item &it2)
{
	if(it1.index==it2.index)
	{
		if(it1.pp==it2.pp)
			return it1.lookhead<it2.lookhead;
		else return it1.pp<it2.pp;
	}
	else 
		return it1.index<it2.index;
}
bool operator!=(const item &it1,const item& it2)
{
	if(it1<it2||it2<it1)return true;
	else return false;
}
struct mycompare
{
	bool operator()(const item& it1,const item& it2)const
	{
		if(it1.index==it2.index)
			return it1.pp<it2.pp;
		else 
			return it1.index<it2.index;//这样定义为了closure节省了合并相同p和pp但lookhead不同的项
	}
};
typedef set<item,mycompare> ItemSet;
/*bool operator<(const ItemSet& itemSet1,const ItemSet& itemSet2)
{
	if(itemSet1.size()==itemSet2.size())
	{
		ItemSet::const_iterator i=itemSet1.begin();
		ItemSet::const_iterator j=itemSet2.begin();
		while(i!=itemSet1.end())
		{
			if((*i)<(*j))return true;
			
			++i;
			++j;
		}
		return false;
	}
			
	else
		return itemSet1.size()<itemSet2.size();
}*/

struct mycompare2
{
	bool operator()(const ItemSet& itemSet1,const ItemSet& itemSet2)const
	{
		if(itemSet1.size()==itemSet2.size())
		return itemSet1<itemSet2;
		else return itemSet1<itemSet2;
	}
};


class grammer{
private:
	int** table;
	int realstart;
	int tokenstart;
	vector<bool> isepsilon;//为了生成first时方便所以记录了生成epsilon的表达式
	//vector<itme*> items;
	ItemSet itemSet;//LR核生成时用到
	//map<int,ItemSet,mycompare2> stateToSet;
	vector<ItemSet> finalStateSet;
	vector<FAstate*> finalstates;
	set<ItemSet> stateSet;
	hash_map<int,ItemSet> statetoset;
	int curleft;
	hash_map<int,int> ptoindex;//将对应的left映射为在producers中的位置,第一个位置
	hash_map<int,int> ptosize;//将对应的left与其所拥有的producer的数量建立映射,可直接访问
	hash_map<string,int> lefts;//将读入的left的串声称为一个代表其的int字段
	hash_map<string,int> tokenmap;//将token的串映射到对应的值
	//hash_map<ItemSet,int> settostate;//临时加的,寒阿
	hash_set<int> terminals;
	hash_set<int> nonterminals;//将yacc文件中所有的终结符合非终结符的存下来,做first时用到 
	vector<hash_set<int>> myfirst;//这样映射很直接,我不想用太多的hash映射,能从最直接的最好

	//hash_map<int,ItemSet> pathtoset;//将path对应到itemSet去,为了找到已经存在的itemSet,move动作时用到
	vector<producer*> producers;
	int numofproducers;
	int numofleft;
	int nextStateID;
	bool* check;
	hash_map<int,int> toindex;//构造表时用,为了能将nonterminal和terminal与表的列下表对应上
public:
	grammer(){table=0;producers=vector<producer*>(0);tokenstart=TOKENSTART;};
	bool begin(ifstream&);
	bool dealproducer(int,string,int);
	void display();
	void erro(int linenumber){cout<<"erro happen in line: "<<linenumber<<endl;};
	int strtoint(string curstr);//将当前string转换为对应的int用来生成producer时用到
	bool dealunion(ifstream&);
	bool dealtoken(char*);
	bool dealleft(char*);
	bool dealright(char*);
	bool dealnonassoc(char*);
	bool dealtype(char*);
	void getabh();
	bool generatecode();
	//void creatLRK();
	//void creatLALR();
	bool creatLR();
	bool creattable();
	void closure(ItemSet& curSet);
	ItemSet& move(ItemSet& s,int trans);
	void findlook(item& curitem,hash_set<int>& tlook);
	bool recurfirst(int producerNumber,hash_set<int>&look,hash_set<int>& Nont);//递归去寻找某个left对应的某个producer所对应fisrt(left)
	//bool isterminal(int);
	bool isnonterminal(int);//写两个浪费了,但调试时方便,防止出现处理不到的整数值
	void first();//把所有的first处理好,以备在闭包时用
    void computefirst(int left);
	void displaytab();
	void displayfirst();
	void displayusetable();

};	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -