编译原理实验二------基于LL(1)方法的语法分析程序

目的:设计、编制和调试一个典型的语法分析方法,进一步掌握常用的语法分析方法。

要求:

(1)根据LL(1)分析法编写一个语法分析程序,可根据自己实际情况,选择以下一项作为分析算法的输入:

a.直接输入根据已知文法构造的分析表M;

b.输入文法的FIRST(α)和FOLLOW(U)集合,由程序自动生成文法的分析表M;

c.输入已知文法,由程序自动构造文法的分析表M。

(2)程序具有通用性

所开发的程序可适用于不同的文法和任意输入串,且能判断该文法是否为LL(1)文法。

(3)有运行实例

 对于输入的文法和符号串,所编制的语法分析程序应能正确判断此串是否为文法的句子,并要求输出分析过程。

(4

#include
#include
#include
#include
#include
#include
#define filename "test.txt"
using namespace std;
ifstream input(filename);
map>first; //first集合
map>follow; //follow集合
map>first_temp;
map>follow_temp;
map>string_temp;
settable; //终结符号
setno_end; //非终结符
string s[10][10]; //分析表
mapxlab;
mapylab;
void First() {
	string temp;
	while (getline(input, temp)) {
		int len = temp.length();
		if (first.find(temp[0]) == first.end()) {
			int l = 5;
			while (temp[l] != '|'&&l < len) l++;
			if (!(temp[5] >= 'A'&&temp[5] <= 'Z'))
				first[temp[0]].insert(temp[5]);
			else
				first_temp[temp[0]].insert(temp[5]);
			if (l < len&&temp[l] == '|') {
				if (!(temp[l + 2] >= 'A'&&temp[l + 2] <= 'Z'))
					first[temp[0]].insert(temp[l + 2]);
				else first_temp[temp[0]].insert(temp[l + 2]);
			}
		}
	}
	map>::iterator it = first_temp.begin();
	while (first_temp.size() != 0) {
		set::iterator ij = it->second.begin();
		while (ij != it->second.end()) {
			if (first.find(*ij) != first.end()) {
				set::iterator ik = first[*ij].begin();
				while (ik != first[*ij].end())
					first[it->first].insert(*ik), ik++;
				it->second.erase(ij++);
			}
			else ij++;
		}
		if (it->second.size() == 0)
			first_temp.erase(it++);
		else
			it++;
		if (it == first_temp.end())
			it = first_temp.begin();
	}
	input.close();
}

void Follow() {
	input.open(filename);
	string temp;
	table.insert('$');
	while (getline(input, temp)) {
		int l = 5, len = temp.length();
		no_end.insert(temp[0]);
		while (l < len - 1 && temp[l + 1] != ' ') {
			if (!(temp[l] >= 'A'&&temp[l] <= 'Z') && temp[l] != 'e')
				table.insert(temp[l]);
			if (temp[l] >= 'A'&&temp[l] <= 'Z') {
				follow[temp[l]].insert('$');
				if (!(temp[l + 1] >= 'A'&&temp[l + 1] <= 'Z'))
					follow[temp[l]].insert(temp[l + 1]);
				else {
					int ok = 1;
					set::iterator it = first[temp[l + 1]].begin();
					while (it != first[temp[l + 1]].end()) {
						if (*it != 'e')
							follow[temp[l]].insert(*it);
						else ok = 0;
						it++;
						if (!ok)
							follow_temp[temp[l]].insert(temp[0]);
					}
				}

			}
			l++;
		}
		int k = 0;
		while (temp[k + 5] != '\0'&&temp[k + 5] != '|')
			k++;
		if (temp[k + 5] == '\0')
			string_temp[temp[0]].insert(temp.substr(5, k));
		else
			string_temp[temp[0]].insert(temp.substr(5, k - 1));
		if (temp[k + 5] == '|') {
			int y = 0;
			while (temp[k + 5 + y] != '\0')
				y++;
			string_temp[temp[0]].insert(temp.substr(k + 7, y));
		}
		if (l < len&&temp[l] >= 'A'&&temp[l] <= 'Z')
			follow_temp[temp[l]].insert(temp[0]);
		while (l < len) {
			if (!(temp[l] >= 'A'&&temp[l] <= 'Z') && temp[l] != ' '&&temp[l] != '|'&&temp[l] != 'e')
				table.insert(temp[l]);
			l++;
		}
	}
	map>::iterator it = follow_temp.begin();
	while (follow_temp.size() != 0) {
		set::iterator ij = it->second.begin();
		while (ij != it->second.end()) {
			if (follow.find(*ij) != follow.end()) {
				set::iterator ik = follow[*ij].begin();
				while (ik != follow[*ij].end())
					follow[it->first].insert(*ik), ik++;
				it->second.erase(ij++);
			}
			else
				ij++;
		}
		if (it->second.size() == 0)
			follow_temp.erase(it++);
		else
			it++;
		if (it == follow_temp.end())
			it = follow_temp.begin();
	}
	input.close();
}


void show_first() { //打印FIRST集合
	cout << "FIRST集合为:" << endl;
	map>::iterator it = first.begin();
	while (it != first.end()) {
		cout << "FIRST" << "(" << it->first << ")" << "={ ";
		set::iterator ij = it->second.begin();
		int l = 0, len = it->second.size();
		while (ij != it->second.end()) {
			cout << *ij; ij++;
			if (l <= len - 2)
				cout << " , ";
			l++;
		}
		it++;
		cout << " }" << endl;
	}
}

void show_follow() { //打印FOLLOW集合
	cout << "FOLLOW集合为:" << endl;
	map>::iterator it = follow.begin();
	while (it != follow.end()) {
		cout << "FOLLOW" << "(" << it->first << ")" << "={ ";
		set::iterator ij = it->second.begin();
		int l = 0, len = it->second.size();
		while (ij != it->second.end()) {
			cout << *ij; ij++;
			if (l <= len - 2)
				cout << " , ";
			l++;
		}
		it++;
		cout << " }" << endl;
	}
}

bool show_table() {  //打印并存储LL1分析表
	cout << "LL(1)分析表为:" << endl;
	cout << "---------------------------------------------------" << endl;
	cout << "        ";
	set::iterator it = table.begin();
	int k = 0;
	while (it != table.end()) {
		ylab[*it] = k++;
		cout << *it << "         "; it++;
	}
	cout << endl;
	it = no_end.begin();
	int l = 0;
	while (it != no_end.end()) {
		cout << *it << "       ";
		set::iterator ij = table.begin();
		int j = 0;
		while (ij != table.end()) {
			set::iterator ik = string_temp[*it].begin();
			int ok = 0;
			while (ik != string_temp[*it].end()) {
				string temp = *ik;
				if (first[temp[0]].count(*ij) != 0 || temp[0] == *ij) {
					if (s[l][j] != " ") {
						cout << endl;
						cout << "在第" << l + 1 << "行" << "第" << j + 1 << "列处发生冲突:";
						cout << *it << "->" << temp << " 与 " << *it << "->" << s[l][j] << endl;
						return 0;
					}
					ok = 1; cout << *it << "->" << temp;
					s[l][j] = temp;
					for (int x = temp.length() + 3; x < 10; x++) cout << " ";
				}
				if (first[temp[0]].count('e') != 0 || (*ik)[0] == 'e') {
					if (follow[*it].count(*ij) != 0) {
						if (s[l][j] != " ") {
							cout << endl;
							cout << "在第" << l + 1 << "行" << "第" << j + 1 << "列处发生冲突:";
							cout << *it << "->" << temp << " 与 " << *it << "->" << s[l][j] << endl;
							return 0;
						}
						ok = 1; cout << *it << "->" << temp;
						s[l][j] = temp;
						for (int x = temp.length() + 3; x < 10; x++)
							cout << " ";
					}
				}
				ik++;
			}
			if (!ok)
				cout << "          ", s[l][j] = " ";
			ij++;
			j++;
		}
		cout << endl;
		xlab[*it] = l;
		it++;
		l++;
	}
	return 1;
}

bool juge() {  //识别字符串
	cout << "请输入字符串:" << endl;
	string temp;
	cin >> temp;
	cout << "已匹配         ";
	cout << "栈             ";
	cout << "输入 ";
	cout << "动作           " << endl;
	string sta;
	sta += 'E';
	string match;
	string action;
	string act1 = "输出 ";
	string act2 = "匹配 ";
	string action1;
	int l = 0;
	while (sta.size() != 0) {
		if (temp[0] == 'e') temp.erase(0, 1);
		cout << match << " ";
		cout << setw(15 - match.length()) << sta << "$ ";
		cout << setw(15) << temp << "$ ";
		if (temp[0] == sta[0]) {
			action = act2 + temp[0];
			match = match + temp[0];
			temp.erase(0, 1);
			sta.erase(0, 1);
		}
		else if (temp.size() != 0 && (table.count(temp[0]) == 0 || s[xlab[sta[0]]][ylab[temp[0]]] == " ")) {
			cout << "error" << endl;
			return 0;
		}
		else {
			if (temp.size() != 0) {
				string act = s[xlab[sta[0]]][ylab[temp[0]]];
				action = act1 + sta[0] + "->" + act;
				sta.erase(0, 1);
				if (act[act.length() - 1] == ' ')
					act.erase(act.length() - 1, 1);
				if (act[0] != 'e')
					sta = act + sta;
			}
			else {
				action = act1 + sta[0] + "->" + 'e';
				sta.erase(0, 1);
			}
		}
		cout << action1 << endl;
		action1 = action;
		l++;
	}
	cout << match << " ";
	cout << setw(15 - match.length()) << sta << "$ ";
	cout << setw(15) << temp << "$ ";
	if (sta.size() == 0 && temp.size() != 0) {
		cout << "error" << endl;
		return 0;
	}
	cout << action1 << endl;
	return 1;
}
int main() {
	for (int x = 0; x < 10; x++)
		for (int y = 0; y < 10; y++)
			s[x][y] = " ";
	First(); //求first集合
	show_first(); //打印first集合
	Follow(); //求follow集合
	show_follow(); //打印follo集合
	if (!show_table()) {
		cout << "该文法不是LL(1)文法!!!" << endl;
		system("pause");
		return 0;
	}
	system("pause");
	if (juge())
		cout << "Accept!!!!" << endl;
	else
		cout << "error!!!!!!" << endl;
	system("pause");
}

)提交实验报告,报告内容参考“词法分析程序”

你可能感兴趣的:(编译原理实验二------基于LL(1)方法的语法分析程序)