具体实现: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;
}