编译原理中的正规表达式转NFA

来源:互联网 发布:后期软件 油画质感 编辑:程序博客网 时间:2024/04/27 04:02

编译原理老师布置了一次实习:给定一个正规表达式转化成NFA。虽然花了2、3天,但真正想出可行的算法时,也就是最后半天。。。


主要应用到了四个栈,一个保存所有状态,另外两个用来存储当有“|”时,首尾两个状态,还有一个用来弹出新的状态。部分代码:

//解析函数int solve(int t,char *a)  //t为初态{int x,y,sign=0,consist=0;stack<char> s;stack<int> start;stack<int> end;s.push(t);start.push(t);int l=strlen(a);for(int i=0;i<l;i++){//////////////第一类情况if(a[i]=='('){consist=consist+1;char b[100];int k=0;for(int j=i+1;j<l;j++){b[k++]=a[j];if(a[j+1]==')'){b[k]='\0';break;}}if(consist==1&&!start.empty()){y=solve(start.top(),b);s.push(y);if(sign>0&&(j+2==l||a[j+2]=='|')){m[num].x=s.top();m[num].y='$';m[num++].z=end.top();}}else {y=solve(s.top(),b);s.push(y);if(sign>0&&(a[j+2]=='|'||j+2==l)){m[num].x=s.top();m[num].y='$';m[num++].z=end.top();}}i=j+1;}/////////////第二类情况//sign>0表示有‘|’consist用来判断为第几位字符if(a[i]=='|'){sign=1;consist=0;end.push(y);continue;}////////////////////////////第三类情况if(a[i]>='a'&&a[i]<='z'){consist=consist+1;if(sign==1){//如果有或运算且紧挨着或符号,就从栈start中取,start中存储的是或运算左侧字符串的第一个状态x=start.top();sign++;//下次不取}else{//如果栈s为空,即刚开始判断字符串,则新生成状态xif(s.empty()){x=status.top();status.pop();}else{//否则从栈s中取x=s.top();}}if(a[i+1]=='|'&&!end.empty())y=end.top();//栈end用来存储字符串最后一个状态else{if(sign>0&&i+1==l&&!end.empty())y=end.top();else{y=status.top();status.pop();}}//记录x a[i] ym[num].x=x;m[num].y=a[i];if(i+1==l&&!end.empty())m[num++].z=end.top();else m[num++].z=y;s.push(x);s.push(y);if(consist==1)start.push(x);}//////////////////////////////第四类情况if(a[i]=='*'){if(sign==1&&consist==1){//表示此为‘|’后第一个‘*’x=start.top();//记录x $ xm[num].x=x;m[num].y='$';m[num++].z=x;consist=0;sign=1;//end.push(x);}else{x=s.top();s.pop();y=s.top();//记录x $ ym[num].x=x;m[num].y='$';m[num++].z=y;if((i+1==l||a[i+1]=='|')&&!end.empty()){//用来判断以‘*’结尾或‘*|’形式m[num].x=s.top();m[num].y='$';m[num++].z=end.top();}}}}int w;if(!end.empty()){w=end.top();while(!s.empty())s.pop();while(!start.empty())start.pop();while(!end.empty())end.pop();return w;}else{w=s.top();while(!s.empty())s.pop();while(!start.empty())start.pop();while(!end.empty())end.pop();return w;}}

分了四种情况,遇到括号调用该函数递归调用。。。

dos版:点击打开链接 MFC版:

0 0
原创粉丝点击