合工大 编译原理 实验二

合工大 编译原理实验二 LL(1)文法

本实验为必做实验,使用C++开发,利用Windows API制作了简易的界面。
基本功能:

  1. 支持自定义文法
  2. 多个显示窗口,支持显示FIRST集、FOLLOW集、状态转换表、分析表
  3. 支持直接/间接左递归文法转化为LL(1)文法后识别

详细功能,示例截图、项目代码请见GitHub页面:LL(1)文法

部分核心代码如下:

  1. 消除直接/间接左递归
/******************************************************************************
*				函数名:		ChecktoEraseRecursion
*				函数功能:	计算是否文法含有直间接左递归,并得出消去左递归后的文法
*				传入参数:	void
*				传出参数:	result	ChecktoEraseRecursion_result
*******************************************************************************/
ChecktoEraseRecursion_result CheckLL1class::ChecktoEraseRecursion() {
	ChecktoEraseRecursion_result result;
																//非终结符集合
	std::map<std::string, std::string> CheckGrammarFormula;
	int stepcounter = 4000;
	result.isNeedToTransfer = false;
	result.CheckGrammarFormula.clear();

	CheckGrammarFormula.insert(GrammarFormula.begin(), GrammarFormula.end());

	bool record = 1;
	for (auto i = CheckGrammarFormula.begin(); i != CheckGrammarFormula.end(); i++) {
		VnSet.insert(i->second.at(0));
	}
	//auto mosti = VnSet.rend();																//最高终结符
	//mosti--;
	for (auto i = VnSet.rbegin(); i != VnSet.rend()/*mosti*/; i++) {										//按顺序排列非终结符,并指定一非终结符,消去其余非终结符,从而观察是否含有左递归
		if (*i == mostcharacter)
			continue;

		for (auto ii = CheckGrammarFormula.begin(); ii != CheckGrammarFormula.end() && stepcounter>0; ii++, stepcounter--) {
			std::string tmp="";
			int catchpos=(int)ii->first.find(*i);
			if (catchpos >= 0) {
				for (auto formulaofi = CheckGrammarFormula.begin(); formulaofi != CheckGrammarFormula.end() && stepcounter>0; stepcounter--) {
					
					if (formulaofi->second.at(0) == *i) {
						tmp = ii->first.substr(0, catchpos);
						tmp += formulaofi->first;
						tmp += ii->first.substr((int)catchpos + 1, tmp.length());
						CheckGrammarFormula.insert(std::make_pair(tmp,ii->second));

						//auto oldformulaofi = formulaofi;			//临时变量,要消除的变量
						formulaofi++;
						//CheckGrammarFormula.erase(oldformulaofi);
					}
					else {
						formulaofi++;
					}
				}
			}
		}
	}

	if (stepcounter <= 0) {
		return result;
	}

	auto i = VnSet.rbegin();
	for (; i != VnSet.rend()/*mosti*/; i++) {
		if (*i == mostcharacter)
			continue;

		for (auto ii = CheckGrammarFormula.begin(); ii != CheckGrammarFormula.end();) {	//删除含其他符号的多余表达式
			int thepos =ii->first.find(*i);
			if (thepos >= 0 || ii->second.at(0)==*i) {
				auto oldii = ii;
				ii++;
				CheckGrammarFormula.erase(oldii);
			}
			else {
				ii++;
			}
		}
	}

	char newchar;																					//新增的非终结符
	for (newchar = 'A'; newchar <= 'Z'; newchar++) {
		if (newchar != CheckGrammarFormula.begin()->second.at(0)) {
			break;
		}
	}
	
	for (auto i = CheckGrammarFormula.begin(); i != CheckGrammarFormula.end();) {	//查看是否含有左递归
		if (i->first.at(0) == i->second.at(0)) {
			result.isNeedToTransfer = true;
			std::string tmpstring = i->first.substr(1, i->first.length());
			tmpstring += newchar;

			result.CheckGrammarFormula.insert(std::make_pair(tmpstring, std::string{ newchar }));
			result.CheckGrammarFormula.insert(std::make_pair(std::string{ NULLCHARACTER }, std::string{ newchar }));
			auto oldi = i;
			i++;
			CheckGrammarFormula.erase(oldi);
		}
		else {
			std::string tmpstring = i->first;
			tmpstring += newchar;
			result.CheckGrammarFormula.insert(std::make_pair(tmpstring, i->second));
			auto oldi = i;
			i++;
			CheckGrammarFormula.erase(oldi);
		}

	}

	return result;
}
  1. FOLLOW集计算
/******************************************************************************
*				函数名:		getFOLLOWsets
*				函数功能:	获取FOLLOW集
*				传入参数:	void
*				传出参数:	void
*******************************************************************************/
void CheckLL1class::getFOLLOWsets() {

	std::set<std::string> tmptotalbuildsymbol;

	for (auto i = GrammarFormula.begin(); i != GrammarFormula.end(); i++) {
		tmptotalbuildsymbol.insert(i->second);
	}

	std::map<char, std::map<char, bool>> FirstLinear, FollowLinear;			//First集约束条件, Follow集约束条件

	for (auto i = GrammarFormula.begin(); i != GrammarFormula.end(); i++) {
		auto theend = i->first.rend();
		theend--;
		for (auto t = i->first.rbegin(); t != theend; t++) {
			if (tmptotalbuildsymbol.find(std::string{ *(t + 1) }) != tmptotalbuildsymbol.end()) {
				if(tmptotalbuildsymbol.find(std::string{ *(t) }) != tmptotalbuildsymbol.end())
					//FirstLinear[*t][*(t + 1)] = true;
					FOLLOWset[*(t + 1)].insert(FIRSTset[*t].begin(), FIRSTset[*t].end());
				else
					FOLLOWset[*(t+1)].insert(*t);
				FOLLOWset[*(t + 1)].erase(NULLCHARACTER);
			}	
		}
	}

	for (auto i = GrammarFormula.begin(); i != GrammarFormula.end(); i++) {
		for (auto t = i->first.rbegin(); t != i->first.rend(); t++) {
			if (tmptotalbuildsymbol.find(std::string{ *t }) != tmptotalbuildsymbol.end() || *t ==NULLCHARACTER) {
				if(*t != NULLCHARACTER && i->second.at(0) != *t)
					FollowLinear[i->second.at(0)][*t] = true;
				if (*t != NULLCHARACTER && FIRSTset[*t].find(NULLCHARACTER) == FIRSTset[*t].end()) {	//不包含空集
					break;
				}
			}
			else {
				break;
			}
		}
	}

	while (FollowLinear.size() > 0) {
		for (auto i = tmptotalbuildsymbol.begin(); i != tmptotalbuildsymbol.end();) {
			bool isOK = true;
			for (auto ii = FollowLinear.begin(); ii != FollowLinear.end(); ii++) {
				if (ii->second.find(i->at(0)) != ii->second.end()) {
					isOK = false;
				}
			}

			if (isOK == true) {
				//for (auto ii = FirstLinear[i->at(0)].begin(); ii != FirstLinear[i->at(0)].end(); ii++) {
				//		FOLLOWset[i->at(0)].insert(FIRSTset[ii->first].begin(), FIRSTset[ii->first].end());
				//}

				for (auto ii = FollowLinear[i->at(0)].begin(); ii != FollowLinear[i->at(0)].end(); ii++) {
					FOLLOWset[ii->first].insert(FOLLOWset[i->at(0)].begin(), FOLLOWset[i->at(0)].end());
				}

				auto tmp = i;
				i++;
				FollowLinear.erase(tmp->at(0));

			}
			else {
				i++;
			}
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wjh776a68

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值