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

📄 ll1_analyser.cpp

📁 pl0编译器
💻 CPP
字号:
//LL1_Analyser.cpp

#include "stdafx.h"
#include "LL1_Analyser.h"
//计算并集
template <class T> inline
set<T> Set_Union (const set<T> &lset, const set<T> &rset)
{
	set<T> temp;
	insert_iterator< set<T> > pos(temp, temp.begin());
	set_union (lset.begin(), lset.end(), rset.begin(), rset.end(), pos);
	return temp;
}
//计算差集
template <class T> inline
set<T> Set_Difference (const set<T> &lset, const set<T> &rset)
{
	set<T> temp;
	insert_iterator< set<T> > pos(temp, temp.begin());
	set_difference (lset.begin(), lset.end(), rset.begin(), rset.end(), pos);
	return temp;
}
//看value是否属于集合Set
template <class T> inline
bool Is_Attribute (const T &value, const set<T> &Set)
{
	return (Set.find(value) != Set.end());
}


LL1_Analyser::LL1_Analyser(const Grammar &grammar):g(grammar) 
{
	//首先删除所有文法中的动作符号
	for(int i=0; i < g.productions.size();i++)
		for(int j=0; j<g.productions[i].rhs.size(); j++)
			if (g.productions[i].rhs[j].first == Action) g.productions[i].rhs.erase(&(g.productions[i].rhs[j])); 
	g.actions.clear();
	cout<<"Analysing the grammar..."<<endl<<endl;
	//一步一步从FIRST集求到LL1分析表
	mark_lambda();
	fill_first_set(); 
	fill_follow_set();
	fill_predict_set();
	fill_LL_Table();
	show_LL_Table();
};

void LL1_Analyser::show_first_set()
{
	cout<<"First set:"<<endl;
	map< symbol, set<symbol> >::iterator pos=first.begin();
	for(; pos != first.end(); pos++)
	{
		cout<<g.GetStr(pos->first)<<" :  ";
		for(set<symbol>::iterator s_it=pos->second.begin(); s_it != pos->second.end(); s_it++)
			cout<<g.GetStr(*s_it)<<' ';
		cout<<endl;
	}
}

void LL1_Analyser::show_follow_set()
{
	cout<<"Follow set:"<<endl;
	map< symbol, set<symbol> >::iterator pos=follow.begin();
	for(; pos != follow.end(); pos++)
	{
		cout<<g.GetStr(pos->first)<<" :  ";
		for(set<symbol>::iterator s_it=pos->second.begin(); s_it != pos->second.end(); s_it++)
			cout<<g.GetStr(*s_it)<<' ';
		cout<<endl;
	}
}

void LL1_Analyser::show_predict_set()
{
	cout<<"Predict set:"<<endl;
	vector< set<symbol> >::iterator pos=predict.begin();
	for(; pos != predict.end(); pos++)
	{
		cout<<"Production "<<distance(predict.begin(),pos)+1<<" :  ";
		for(set<symbol>::iterator s_it=pos->begin(); s_it != pos->end(); s_it++)
			cout<<g.GetStr(*s_it)<<' ';
		cout<<endl;
	}
}

void LL1_Analyser::show_LL_Table()
{
	cout<<"LL1 Analyse Table:"<<endl;
	map< pair<nonterminal,terminal>, int >::iterator pos=LL_Table.begin();
	for(; pos != LL_Table.end(); pos++)
		cout<<g.GetStr(pos->first.first)<<' '<<g.GetStr(pos->first.second)<<" -> "<<pos->second+1<<endl;
	cout<<endl;
}

void LL1_Analyser::show_derives_lambda()
{
	cout<<"The following nonterminals can derive lambda."<<endl;
	map< symbol, bool >::iterator pos=derives_lambda.begin();
	for(; pos != derives_lambda.end(); pos++)
		if (pos->second == true) cout<<g.GetStr(pos->first)<<' ';
	cout<<endl;
}
//算法大意:从每个符号在产生式的左部出发,一步步向下推导出是否为空,直到该集合derives_lambda收敛为止
void LL1_Analyser::mark_lambda()
{
	bool changes;
	bool rhs_derives_lambda;
	symbol v;
	int i,j;
	//初始化,规定每个符号都推不出空
	symbols::iterator s_it=g.nonterminals.begin();
	for (;s_it != g.nonterminals.end(); s_it++)
		derives_lambda[s_it->second] = false;
	s_it=g.terminals.begin();
	for (;s_it != g.terminals.end(); s_it++)
		derives_lambda[s_it->second] = false;

	do
	{
		changes = false; //判定是否收敛,如果为false为收敛
		for (i=0; i < g.productions.size(); i++)
		{
			production &p=g.productions[i];
			if ( !derives_lambda[p.lhs] ) 
			{
				//如果产生式右部只有空则一定能推导出空
				if ( p.rhs.size() == 1 && p.rhs[0].first == $ )
				{
					changes = true;
					derives_lambda[p.lhs] = true;
					continue;
				};
				rhs_derives_lambda = derives_lambda[p.rhs[0]];
				//否则继续向下推导(即在原集合中查找右部能否推出空)
				for (j=1; j<p.rhs.size(); j++)
					rhs_derives_lambda = rhs_derives_lambda && derives_lambda[p.rhs[j]];
				if (rhs_derives_lambda) { changes=true; derives_lambda[p.lhs]=true; }
			}
		}
	} while (changes); //不收敛就循环
}
//算法大意:见公式
set<symbol> LL1_Analyser::compute_first (const vector<symbol> &right)
{
	int i,k=right.size();
	symbol n=make_pair($,0);
	set<symbol> temp,temp1;
	set<symbol> nl;
	nl.insert(n);
	set<symbol> result;
	if (k == 0) return result;
	else
	{
		result=Set_Union(result,first[right[0]]);
		for (i=1; i<k && ( Is_Attribute(n,first[right[i-1]]) ); i++)
			result=Set_Union(result,Set_Difference(first[right[i]],nl));
		if ( i==k && Is_Attribute(n,first[right[k-1]]) )
			result.insert(n);
	}
	return result;
}

bool LL1_Analyser::_find_production(const nonterminal &vn, const terminal &vt)
{
	vector<production>::iterator pos = g.productions.begin();
	while ( pos != g.productions.end() )
	{
		if (pos->lhs == vn && pos->rhs[0] == vt) return true;
		pos++;
	}
	return false;
}
//算法大意:见公式
void LL1_Analyser::fill_first_set ()
{
	nonterminal A;
	terminal a;
	production p;
	bool changes;
	int temp;
	nonterminal n=make_pair($,0);
	symbols::iterator s_it=g.nonterminals.begin();
	for (; s_it != g.nonterminals.end(); s_it++)
	{
		A = s_it->second;
		if (derives_lambda[A]) first[A].insert(n);
		else first[A].clear();
	}
	for (s_it=g.terminals.begin(); s_it != g.terminals.end(); s_it++)
	{
		a = s_it->second;
		if ( (a.first == Id || a.first == Intc) && (a.second != -1) ) continue;
		first[a].insert(a);
		for (symbols::iterator s_it1=g.nonterminals.begin(); s_it1 != g.nonterminals.end(); s_it1++)
		{
			A = s_it1->second;
			if( _find_production(A,a) ) 
				first[A].insert(a);
		}
	}
	do
	{
		changes = false;
		for (vector<production>::iterator pos=g.productions.begin(); pos != g.productions.end(); pos++)
		{
			p=*pos;
			temp=first[p.lhs].size();
			first[p.lhs]=Set_Union(first[p.lhs],compute_first(p.rhs));
			if ( temp != first[p.lhs].size() ) changes=true;
		}
	} while (changes);

}

//算法大意:见公式
void LL1_Analyser::fill_follow_set()
{
	nonterminal A,B;
	int i;
	bool changes;
	symbol n=make_pair($,0);
	set<symbol> temp_set;
	vector<symbol> follow_string;
	vector<symbol> temp1;
	vector<symbol>::iterator pos1;

	for (symbols::iterator s_it=g.nonterminals.begin(); s_it != g.nonterminals.end(); s_it++)
	{
		A = s_it->second;
		follow[A].clear();
	}
	follow[g.start_symbol].insert(n);
	
	do
	{
		changes = false;
		s_it=g.nonterminals.begin();
		for (; s_it != g.nonterminals.end(); s_it++)
		{
			B = s_it->second;
			i=follow[B].size();
			for (vector<production>::iterator pos=g.productions.begin(); pos != g.productions.end(); pos++)
			{
				pos1=find(pos->rhs.begin(),pos->rhs.end(),B);
				while( pos1 != pos->rhs.end() )
				{
					temp1.clear();
					temp1.insert(temp1.begin(),pos1+1,pos->rhs.end());
					temp_set=compute_first(temp1);
					if( Is_Attribute(n,temp_set) || (temp_set.size() == 0 && find(pos->rhs.begin(),pos->rhs.end(),B) != pos->rhs.end() ) )
					{
						temp_set.erase(n);
						follow[B]=Set_Union(follow[B],temp_set);
						follow[B]=Set_Union(follow[B],follow[pos->lhs]);
					}
					else 
						follow[B]=Set_Union(follow[B],temp_set);
					pos1=find(pos1+1,pos->rhs.end(),B);
				}
			}
			if (i != follow[B].size()) changes = true;
		}
	} while (changes);
}

//算法大意:见公式
void LL1_Analyser::fill_predict_set()
{
	symbol n=make_pair($,0);
	set<symbol> temp_set;
	for (vector<production>::iterator pos=g.productions.begin(); pos != g.productions.end(); pos++)
	{
		temp_set.clear();
		temp_set=compute_first(pos->rhs);
		if ( Is_Attribute(n,temp_set) || temp_set.size() == 0)
		{
			if ( Is_Attribute(n,temp_set) ) temp_set.erase(n);
			temp_set=Set_Union(temp_set,follow[pos->lhs]);
		}
		predict.push_back(temp_set);
	}
}

//算法大意:见公式
void LL1_Analyser::fill_LL_Table()
{
	pair<nonterminal,terminal> p_temp;
	set<symbol>::iterator s_it;
	symbol sym;
	for (int i=0; i<g.productions.size();i++)
	{
		sym=g.productions[i].lhs;
		s_it=predict[i].begin();
		while( s_it != predict[i].end() )
		{
			p_temp=make_pair(sym,*s_it);
			if ( LL_Table.find(p_temp) != LL_Table.end() )
			{
				cerr<<"The grammar isn't LL(1) grammar! because of "<<g.GetStr(p_temp.first)<<" and "<<g.GetStr(p_temp.second)<<endl;
				return;
			}
			LL_Table[p_temp]=i;
			s_it++;
		}
	}
}


⌨️ 快捷键说明

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