LL(1)语法分析程序

来源:互联网 发布:edge网络是什么 编辑:程序博客网 时间:2024/06/05 06:59

LL(1)语法分析程序的设计思路还是很清晰的,按照教材上的算法公式去实现即可。

找出了以前在学校的时候写的一个实现,在VC6上编译的。当时写的比较稚嫩,程序也并不完美,有机会再完善下。


使用例子

输入产生式的个数:5请输入各产生式:说明:若有空产生式A->ε,则ε不必打出来;直接输入A->第1个产生式:E->iF第2个产生式:F->+E第3个产生式:F->第4个产生式:i->1第5个产生式:i->2请输入语句:        1+2+1分析过程如下所示:------------------------------------------------------------分析栈          │      Rest            │      产生式|匹配------------------------------------------------------------#E              |       1+2+1#          |       E->iF#Fi             |       1+2+1#          |       i->1#F1             |       1+2+1#          |       1 匹配#F              |       +2+1#           |       F->+E#E+             |       +2+1#           |       + 匹配#E              |       2+1#            |       E->iF#Fi             |       2+1#            |       i->2#F2             |       2+1#            |       2 匹配#F              |       +1#             |       F->+E#E+             |       +1#             |       + 匹配#E              |       1#              |       E->iF#Fi             |       1#              |       i->1#F1             |       1#              |       1 匹配#F              |       #               |       F->ε#               |       #               |       分析成功------------------------------------------------------------



#include <string.h>#include <iostream.h>#include <malloc.h>const int STACK_INIT_SIZE = 30;    //存储空间初始分配量const int STACKINCREMENT =  10;      //存储空间分配增量const int VTNUM = 10;const int VNNUM = 10;const int prNUM = 15;const int pLength = 9;const int MAXNUM = 25;int pnum;int vnum;char VT[VTNUM];// 终结符char VN[VNNUM];// 非终结符char pr[prNUM][pLength];// 产生式bool VEmpty[VNNUM];char VFirst[VNNUM][VTNUM + 1];char VFollow[VNNUM][VTNUM + 1];char VSelect[MAXNUM][VTNUM + 3];typedef char SElemType, ElemType;typedef struct  {SElemType * base;SElemType * top;int stacksize;}SqStack;bool InitStack (SqStack &S);SElemType GetTop (SqStack S);bool Push (SqStack &S, SElemType e);bool Pop (SqStack &S);bool InitStack (SqStack &S)   //       构建一个空栈 S{S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));if(!S.base) return false; //exit (OVERFLOW);  //    存储分配失败S.top = S.base;S.stacksize = STACK_INIT_SIZE;return true;}SElemType GetTop (SqStack S){                         //   若不为空,用e返回栈顶元素if(S.top == S.base)  // if(S.top = S.base) 错错错{return false;}SElemType e = *(S.top - 1);return e;}bool Push (SqStack &S, SElemType e)  // 入栈{                             //插入元素 e 为新的栈顶元素  if(S.top - S.base >= S.stacksize){S.base = (ElemType * )realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(ElemType));if(!S.base)  return false;//exit(OVERFLOW);S.top = S.base + S.stacksize;S.stacksize += STACKINCREMENT;}*S.top ++ = e;return true;}bool Pop (SqStack &S)  //        出栈{                //                    删除 S 栈顶元素if(S.top == S.base)  return false;--S.top;return true;}int StackEmpty(SqStack S){if(S.top == 0)   return 1;else  return 0;}void PrintStack(SqStack S){SElemType * p;p = S.top - 1;while (1 > 0){cout<<*p;if (p == S.base){return;}p--; ///}}void RePrintStack(SqStack S){SElemType *p;p = S.base;while (p != S.top){cout<<*p;p++;}}int IsVN(char ch){for (int i = 0; i < VNNUM, VN[i] != '\0'; i++){if (ch == VN[i]){return i;}}return -1;}int IsVT(char ch){for (int i = 0; i < VTNUM, VT[i] != '\0'; i++){if (ch == VT[i]){return i;}}return -1;}void GetVN(char a) // 从一条产生式中提取出 非终结符{for (int i = 0; i < VNNUM; i++){if (a == VN[i] || VN[i] == '\0'){break;}//VN[i] = a;}VN[i] = a;}void GetVT(char *p) // 从一条产生式中提取出 终结符{for (int j = 3; j <= pLength, p[j] != '\0'; j++){char a = p[j];if (IsVN(a) >= 0){continue; /////}for (int i = 0; i < VTNUM; i++){if (a == VT[i] || VT[i] == '\0'){break;}}if (a != 'ε') // ε不是终结符{VT[i] = a;}}}void MayEmpty(){int code, num, cc = 0;for (int i = 0; i < VNNUM; i++){VEmpty[i] = false;}for (int j = 1; j <= pnum; j++) // 初扫描{if (pr[j][3] == 'ε' || pr[j][3] == '\0'){code = IsVN(pr[j][0]);VEmpty[code] = true;}//VEmpty[code] = true;}while (1 < 5)  // 检查次数 有待进一步 确认{for (int i = 1; i <= pnum; i++){code = IsVN(pr[i][0]);if (VEmpty[code]){continue; //////////////////////////////////////}for (int j = 3; j < pLength, pr[i][j] != '\0'; j++){code = IsVN(pr[i][j]);if (code < 0){break;}if (!VEmpty[code]){break;}}if (pr[i][j] == '\0'){code = IsVN(pr[i][0]);VEmpty[code] = true;}}num = 0;for ( i = 0; i < VNNUM; i++){if (VEmpty[i] == true){num++;}}if (num == cc){return;}cc = num;}}void Addch(char *p, char *from) // 求并集 { // *p在增长,应该为一个数组int i = strlen(p);int j = strlen(from);int k = i;for (int a = 0; a < j; a++){for (int b = 0; b < i; b++){if (from[a] == p[b]){break;}}if (b == i){p[k++] = from[a];}}}void Addchar(char *to, char a){int i = strlen(to);for (int j = 0; j < i; j++){if (to[j] == a){break;}}if (j == i){to[i] = a;}}void First(char ch) // 求非终结符ch 的First集{int a, b, code;char c;code = IsVN(ch);for (int i = 1; i <= pnum; i++){if (pr[i][0] != ch ){continue;}int L = strlen( pr[i] );for (int k = 3; k < L; k++){c = pr[i][k];a = IsVT( pr[i][k] );b = IsVN( pr[i][k] );if ( b >= 0 ) // A->Bc A->BCD{Addch(VFirst[code], VFirst[b] );if ( !VEmpty[b] ) // 如果不能推出空{break;}}else  // A->c{Addchar( VFirst[code], c );break;}}}}void Follow(char vn) // A->aBc{int a, b, c;c = IsVN(vn);for (int i = 1; i <= pnum; i++){a = IsVN(pr[i][0] );int L = strlen( pr[i] );for (int j = 3; j < L; j++){if ( pr[i][j] == vn ){for (int k = j + 1; k < L; k++){//a = IsVT(pr[i][k] );b = IsVN(pr[i][k] );if (b < 0){Addchar(VFollow[c], pr[i][k] );break;}else{Addch(VFollow[c], VFirst[b] );if (!VEmpty[b] ){break;}}}if (k == L){Addch(VFollow[c], VFollow[a] );}}}}}void Select(int c) // 求第c条产生式的Select集{int a, b = IsVN(pr[c][0]);int L = strlen(pr[c] );for (int i = 3; i < L; i++){a = IsVN(pr[c][i] );if (a < 0){Addchar(VSelect[c], pr[c][i] );//i--; // break;}else{Addch(VSelect[c], VFirst[a] );if (!VEmpty[a]){break;}}}if (i == L) // 用来判断 for 循环时有无中断,如果for()顺利执行,则有 i == L{Addch(VSelect[c], VFollow[b] );}}void GetSelect(){for (int i = 1; i <= pnum; i++){Select(i);}}void GetFirst(){int a = 0, num = 0;while (1 > 0){for (int i = 0; i < vnum; i++){First(VN[i] );}num = 0;for (int c = 0; c < VNNUM; c++){for (int d = 0; d < VNNUM + 1; d++){if (VFirst[c][d] == '\0' ){continue;}num++;}}if (a == num){return;}a = num;}}void GetFollow(){int a = 0, num = 1;while (1 > 0){for (int i = 0; i < vnum; i++){Follow(VN[i] );}num = 0; /////////////////////////////////for (int c = 0; c < VNNUM; c++){for (int d = 0; d < VNNUM + 1; d++){if (VFirst[c][d] == '\0' ){continue;}num++;}}if (a == num){return;}a = num;}}void Inite(){cout<<"输入产生式的个数:";cin>>pnum;cin.get();cout<<"请输入各产生式:\n";cout<<"\n说明:若有空产生式A->ε,则ε不必打出来;直接输入A->\n\n";int i = 1;while ( i <= pnum ){cout<<"\n第"<<i<<"个产生式:";int k = 0;char a = cin.get();while (a != '\n'){if (a != ' '){pr[i][k++] = a;}a = cin.get();}pr[i][k++] = '\0';GetVN( pr[i][0] );i++;}// 提取出终结符for (int j = 1; j <= pnum; j++){GetVT( &pr[j][0] );VSelect[j][0] = pr[j][0];}for (j = 0; j < VNNUM; j++){if (VN[j] == '\0' ){break;}}vnum = j;VFollow[0][0] = '#';}void Predict(){SqStack see, sin;InitStack(see);InitStack(sin);char c = VN[0];Push(see, '#');Push(see, c);cout<<"\n请输入语句: \n";//cin.get();char a;char ch[29];int k = 0;while ((a = cin.get()) != '\n'){ch[k++] = a;}ch[k++] = '#';ch[k] = '\0';for (int i = k - 1; i >= 0; i--){Push(sin, ch[i]);}char seetop, sintop;int code;cout<<"分析过程如下所示:\n\n";cout<<"------------------------------------------------------------\n";cout<<"分析栈│Rest│产生式|匹配\n";cout<<"------------------------------------------------------------\n";while (!( (GetTop(see) == '#') && (GetTop(sin) == '#') )){seetop = GetTop(see);sintop = GetTop(sin);code = IsVN(seetop);RePrintStack(see); /// cout<<"|";PrintStack(sin);cout<<"|";if (code >= 0) // top是非终结符{for (i = 1; i <= pnum; i++) /////////////////////////////////////////////////{if ( VSelect[i][0] != seetop ){continue;}else{int L = strlen( VSelect[i] );for (int j = 1; j < L; j++){if ( VSelect[i][j] == sintop ){break;}}//break;if ( VSelect[i][j] == sintop ){break; // 避免用goto}}}if (i == pnum + 1){cout<<"错误";return;}Pop(see);int Le = strlen( pr[i] );for (int k = Le - 1; k >= 3; k--){if ( pr[i][k] != '\0' || pr[i][k] != 'ε' ){Push(see, pr[i][k] );}}cout<<pr[i];if ( pr[i][3] == '\0' ){cout<<"ε";}cout<<"\n";}//if (code >= 0) // top是非终结符else{if ( seetop != sintop ){cout<<"error";return;}else{cout<<sintop<<" 匹配"<<endl;Pop(see);Pop(sin);}}}// while (!( (GetTop(see) == '#') && (GetTop(sin) == '#') ))cout<<"#|#|分析成功\n";cout<<"------------------------------------------------------------\n";}int main(){Inite();MayEmpty();GetFirst();GetFollow();GetSelect();while (1 > 0){char c;Predict();cout<<"\n继续/停止(Y/N) ";cin>>c;cin.get();if (c == 'N' || c == 'n'){return 0;}}return 0;}



0 0
原创粉丝点击