FIRST集和FOLLOW集



           

具体实现:first集根据第四点会出现递归求first集,当然在求first集时应判断文法是否成环,比如此文法A->A等等;

   follow应该注意是否重复求某一非终结符的follow集。

#include<iostream>
#include<string>
using namespace std;

class Node
{
public:
	char S;
	string P;
	Node *next;
	Node(char _S, string _P= "\0")
	{
		S = _S;
		P = _P;
		next = NULL;
	}
	~Node(){ }
};

class FF
{
private:
	Node **G;
	string ss;
	int num;
public:
	FF();
	~FF();
	void FIRST(char val , string& firval);
	bool FIRST(int index, string& firval);
	void FOLLOW(char v ,string &folval,string &over);
	void insert(char v , string val);
	void quicksort(int left ,int right);
	int partition(int left , int right);
	void sort();
	int find(char val);
	bool find(string val,char c);
	void test();
};

FF::FF()
{
	int _num = 0;
	cout << "产生式个数" << endl;
	cin >> _num;
	num = _num;
	G = new Node*[num];
	for (int i = 0; i < num; i++)
	{
		G[i] = NULL;
	}
}

void FF::insert(char v, string val)
{
	Node *ptr = new Node(v, val);
	Node *p = NULL;
	for (int i = 0; i <num; i++)
	{
		
		if (G[i] && G[i]->S == v)
		{
			/*cout << i << " " << ptr->P<< endl;*/
			p = G[i];
			while (p->next)
			{
				p = p->next;
			}
			p->next = ptr;
			break;
		}
		if (!G[i])
		{
			/*cout <<i<<" "<< ptr->P << endl;*/
			G[i] = ptr;
			break;
		}
	}
}

FF::~FF()
{
	Node *p, *q;
	for (int i = 0; i < num; i++)
	{
		p = G[i];
		while (p)
		{
			q = G[i]->next;
			delete p;
			p = q;

		}
	}
	delete []G;
}

int FF::partition(int left, int right)
{
	Node *bf = G[left];
	while (left < right)
	{
		while (right > left && G[right]->S >= bf->S)
		{
			right--;
		}
		G[left] = G[right];
		while ( right > left && G[left]->S <= bf->S)
		{
			left++;
		}
		G[right] = G[left];
	}
	G[left] = bf;
	return left;
}

void FF::quicksort(int left,int right)
{
	if (left < right)
	{
		int le = partition(left, right);
		quicksort(left, le - 1);
		quicksort(le + 1, right);
	}
}

void FF::sort()
{
	quicksort(0,num-1);
}

int FF::find(char val)
{
	int left = 0,right = num - 1,mid;
	while (left <= right)
	{
		mid = (left + right) / 2;
		if (G[mid]->S > val)
		{
			right = --mid;
		}
		else if (G[mid]->S < val)
		{
			left = ++mid;
		}
		else
		{
			return mid;
		}
	}
	return -1;

}

bool FF::FIRST(int index, string &firval)
{
	if (index <0)
	{
		return false;
	}
	int in = 1;
	Node *ptr = G[index];
	string sval = "\0";
	int flag = 0,num;
	while (ptr)
	{
		if (ptr->P[0]=='0')     //0代替空
		{
			flag = 1;
			ptr = ptr->next;
			continue;
		}
		num = find(ptr->P[0]);
		if (-1 == num)
		{
			if (!find(firval, ptr->P[0]))
			{
                firval += ptr->P[0];
			}
			
		}
		else
		{
			int val;
			while(FIRST(num, firval))
			{
				val = in++;
				if (ptr->P[val])             //
				{
					if (ptr->P[val] == '0')
					{
						break;
					}
                   num = find(ptr->P[val]);
				   if (-1 == num)
				   {
					   if (!find(firval, ptr->P[val]))
					   {
                            firval += ptr->P[val];
					   }
					  
					   break;
				   }
				}
				else
				{
					flag = 1;
					break;
				}
			}
		}
		ptr = ptr->next;
	}
	if (flag == 1)
	{
		return true;
	}
	else
	{
		return false;
	}
}

void FF::FOLLOW(char c, string& folval,string &over)
{
	Node *ptr;
	for (int i = 0; i < num; i++)
	{
		ptr = G[i];
		while (ptr)
		{
			/*cout << ptr->P << endl;*/
			for (int j = 0; ptr->P[j]; j++)
			{
				//cout << j << " " << endl;
				if (c == ptr->P[j])
				{
					/*cout << "hh" << endl;*/
					if (ptr->P[++j])
					{
						int index = find(ptr->P[j]);
						if (-1 == index )
						{
							if (!find(over, ptr->P[j]))
							{
                                  folval+=ptr->P[j];
							}
							
							break;
						}
						else
						{
							while(FIRST(index, folval))
							{
								/*cout << j << "[[[" <<ptr->P<< endl;*/
								if (ptr->P[++j])
								{
									index = find(ptr->P[j]);
									if (-1 == index)
									{
										if (!find(over, ptr->P[j]))
										{
											folval += ptr->P[j];
										}
										break;
									}
								}
								else
								{
									j--;
									if (!find(over,ptr->S))
									{
										over += ptr->S;
										FOLLOW(ptr->S, folval,over);
									}
									break;
								}
							}
						}	
					}
					else
					{
						/*cout << "jjjj" << endl;*/
						j--;
						if (!find(over,ptr->S))
						{
							over += ptr->S;
                           FOLLOW(ptr->S, folval,over);
						}
					}
				}
			}
			ptr = ptr->next;
		}
	}
}

void FF::test()
{
	for (int i = 0; i < num; i++)
	{
		Node *ptr = G[i];
		while (ptr)
		{
			cout << ptr->S << "  ";
			ptr = ptr->next;
		}
		cout << endl;
	}
}

bool FF::find(string val,char c)
{
	for (int i = 0; val[i]; i++)
	{
		if (c == val[i])
		{
			return true;
		}
	}
	return false;
}
#include"FIRST_FOLLOW.h"
int main()
{
	cout << "---------------用0表示空字符------------" << endl;
	FF *f = new FF;
	f->insert('A', "BCDE");
	f->insert('B', "aBA");
	f->insert('B', "0");
	f->insert('E', "0");
	f->insert('F', "d");
	f->insert('D', "0");
	f->insert('E', "e");
	f->insert('F', "0");
	f->insert('C', "F");
	f->insert('C', "0");
	f->insert('D', "b");
	f->insert('D', "c");
	//f->test();
	f->sort();
	//f->test();
	cout << "FIRST集:";
	cout << "输入:" << endl;
	char c;
	string str;
	cin >> c;
	int num = f->find(c);
	if ( num== -1)
	{
		cout << "非终结符" << endl;
	}
	else
	{
		if (f->FIRST(num, str))
		{
			str += "0";
		}
	}
	cout << str<<endl;
	//f->test();
	cout << "FOLOOW";
	cout << "输入:" << endl;
	char fo;
	cin >> fo;
	string fos;
	string over;
	over += fo;
	f->FOLLOW(fo, fos,over);
	if (fo!='0'&&f->find(fo) != -1)
	{
		fos += '$';
	}
	cout << fos;
}



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值