FIRST集和FOLLOW集

来源:互联网 发布:网口数据监控软件 编辑:程序博客网 时间:2024/05/18 00:11



           

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



0 0