最初步的正则表达式引擎

这里只是当作自己的代码版本管理器使用,并不去详细介绍代码,毕竟我的注释里面已经说明了很多。

欢迎大家测试,如果发现出错了,望在下面回复,多谢。

注意,当前的假定是输入自己不能有错误,而且*、(、)、.、|这几个操作符是保留字,其他的字符则当作其自身意思。当前不考虑转义字符及三元组,以及不考虑子表达式命名,因此只能处理一个长正则表达式。

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <malloc.h>
  4 //这里只处理最简单的正则表达式,即包括括号,星号运算,连接运算和分支运算,这里分支运算在压栈是是一个点号
  5 //其中括号优先级最大,其次是星号运算其次是连接运算最后是分支运算
  6 //当前版本只是把一个简单的正则表达式的优先级理清
  7 #define STRICT
  8 //strict 的意思就是不要求显示的写出.运算符 ,因为在缺少这个运算符的情况下,我们还是可以推断出来这个
  9 //运算符是存在的 ,例如 在)及 *及非运算符之后如果存在字母则是缺少连接符,我们可以自己加上去
 10 int is_operator(char for_in)
 11 {
 12     switch(for_in)
 13     {
 14     case'(':
 15     case')':
 16     case'.':
 17     case'*':
 18     case'|':
 19          return 1;
 20     default: return 0;
 21     }
 22 }
 23 int main(void)
 24 {
 25     int token[100];
 26     int token_pointer;
 27     char reg_operator[100];
 28     int reg_operator_pointer;
 29     int name_number;
 30     int input_pointer;
 31     char reg_input[20];
 32     reg_operator_pointer=name_number=token_pointer=0;
 33     for(input_pointer=0;input_pointer<100;input_pointer++)//初始化堆栈 
 34     {
 35         reg_operator[input_pointer]='\0';
 36         token[input_pointer]=0;
 37     }
 38     input_pointer=0;
 39     printf("please  type in you regex short phrase\n");
 40     scanf("%s",reg_input);
 41     while(*(reg_input+input_pointer)!='\0')
 42     {
 43         if(!is_operator(*(reg_input+input_pointer)))
 44         {
 45             name_number++;
 46             token[token_pointer++]=name_number;
 47             printf("name%d is %c\n",name_number,*(reg_input+input_pointer));
 48             input_pointer++;
 49 #ifndef STRICT
 50             if(!is_operator(*(reg_input+input_pointer)))
 51             {
 52                 reg_operator[reg_operator_pointer++]='.';
 53             }
 54             else
 55             {
 56                 if(*(reg_input+input_pointer)=='(')
 57                 {
 58                     reg_operator[reg_operator_pointer++]='.';
 59                 }
 60             }
 61 #endif 
 62 
 63         }
 64         else//如果是操作符
 65         {
 66             if(reg_operator_pointer!=0)//如果当前栈中有操作符,则需要考虑不同操作符的优先级了
 67             {
 68                 switch(*(reg_input+input_pointer))
 69                 {
 70                 case '('://括号直接入栈,不需要其他操作
 71                     reg_operator[reg_operator_pointer++]='(';
 72                     input_pointer++;
 73                     break;
 74                 case ')':
 75                     if(reg_operator[reg_operator_pointer-1]=='(')
 76                     //如果两个括号匹配,则从操作符和运算数栈中分别弹出一个,然后再生成另外一个运算数入栈
 77                     {
 78                         name_number++;
 79                         printf("name%d is (name%d)\n",name_number,token[token_pointer-1]);
 80                         token[token_pointer-1]=name_number;
 81                         reg_operator_pointer--;//弹出匹配的括号
 82                         input_pointer++;
 83 #ifndef STRICT
 84                         if(!is_operator(*(reg_input+input_pointer)))
 85                         {
 86                             reg_operator[reg_operator_pointer++]='.';
 87                         }
 88                         else
 89                         {
 90                             if(*(reg_input+input_pointer)=='(')
 91                             {
 92                                 reg_operator[reg_operator_pointer++]='.';
 93                             }
 94                         }
 95 #endif
 96                         break;
 97                     }
 98                     else//如果前面还有运算符,只有可能是连接和选择运算符
 99                     {
100                         //对于这两种运算符,处理都是差不多的,不过还要考虑括号内有多个运算符的情况
101                         //这时根据优先级只有可能是| .,不过第二个运算符我们留到第二次迭代的时候去处理
102                         if(reg_operator[reg_operator_pointer-1]=='.')
103                         {
104                             name_number++;
105                             printf("name%d is concat of name%d and name%d\n",name_number,token[token_pointer-1],token[token_pointer-2]);
106                             token[token_pointer-2]=name_number;
107                             token[token_pointer-1]=0;
108                             token_pointer--;
109                             reg_operator_pointer--;
110                             reg_operator[reg_operator_pointer]='\0';
111                             break;
112                         }
113                         else
114                         {
115                             name_number++;
116                             printf("name%d is  name%d or name%d\n",name_number,token[token_pointer-1],token[token_pointer-2]);
117                             token[token_pointer-2]=name_number;
118                             token[token_pointer-1]=0;
119                             token_pointer--;
120                             reg_operator_pointer--;
121                             reg_operator[reg_operator_pointer]='\0';
122                             break;
123                         }
124                         
125                     }
126                 case '*':
127                     //这个运算符优先级基本上是最高的,因此不需要入栈了,直接处理
128                     name_number++;
129                     printf("name%d is multiple of name%d\n",name_number,token[token_pointer-1]);
130                     token[token_pointer-1]=name_number;
131                     input_pointer++;
132 #ifndef STRICT
133                     if(!is_operator(*(reg_input+input_pointer)))
134                     {
135                         reg_operator[reg_operator_pointer++]='.';
136                     }
137                     else
138                     {
139                         if(*(reg_input+input_pointer)=='(')
140                         {
141                             reg_operator[reg_operator_pointer++]='.';
142                         }
143                     }
144 #endif
145 
146                     break;
147                 case '.':
148                     //由于*运算符已经被直接处理了,所以只需要考虑其他的三个运算符
149                     if(reg_operator[reg_operator_pointer-1]=='.')
150                         //如果前面的那个运算符跟当前优先级相同,则处理前面的那个运算符
151                         //这时字符栈要减一
152                     {
153                         name_number++;
154                         printf("name%d is concat of name%d and name%d\n",name_number,token[token_pointer-2],token[token_pointer-1]);
155                         token[token_pointer-2]=name_number;
156                         token_pointer--;
157                         reg_operator[reg_operator_pointer-1]='.';
158                         input_pointer++;
159                         break;
160                     }
161                     else
162                         //其他情况则直接入栈就行,留到下次来判断优先级处理
163                     {
164                         reg_operator[reg_operator_pointer++]='.';
165                         input_pointer++;
166                         break;
167                     }
168                 case '|':
169                     if(reg_operator[reg_operator_pointer-1]!='(')//括号另外说
170                     {
171                         name_number++;
172                         if(reg_operator[reg_operator_pointer-1]=='.')
173                             //如果前面的优先级比当前的高,则处理前面的优先级
174                         {
175                             printf("name%d is concat of name%d and name%d\n",name_number,token[token_pointer-2],token[token_pointer-1]);
176                         }
177                         else
178                             //这里处理的是相同优先级的情况,其实这里可以与前面的合并的,只不过打印信息不同
179                         {
180                             printf("name%d is  name%d or name%d\n",name_number,token[token_pointer-2],token[token_pointer-1]);
181                         }
182                         token[token_pointer-2]=name_number;
183                         token_pointer--;
184                         reg_operator[reg_operator_pointer-1]='|';
185                         input_pointer++;
186                         break;
187                     }
188                     else
189                     {
190                         reg_operator[reg_operator_pointer++]='|';
191                         input_pointer++;
192                         break;
193                     }
194                 default: 
195                     printf("error\n");
196                     break;
197                 }
198             }
199             else//在当前操作符栈中没有符号的时候
200             {
201                 if(reg_input[input_pointer]!='*')
202                     //由于*优先级最高,而且是左结合的,所以不需要入栈了
203                     //对于其他的操作符则需要入栈
204                 {
205                     reg_operator[reg_operator_pointer++]=reg_input[input_pointer++];
206 #ifndef STRICT
207                     if(!is_operator(*(reg_input+input_pointer)))
208                     {
209                         reg_operator[reg_operator_pointer++]='.';
210                     }
211                     else
212                     {
213                         if(*(reg_input+input_pointer)=='(')
214                         {
215                             reg_operator[reg_operator_pointer++]='.';
216                         }
217                     }
218 #endif
219 
220                 }
221                 else
222                 {
223                     name_number++;
224                     printf("name%d is the multiple of name%d\n",name_number,token[token_pointer-1]);
225                     token[token_pointer-1]=name_number;
226                     input_pointer++;
227                 }
228             }
229         }
230     }
231     if(reg_operator_pointer==1)//如果全部的输入都弄完了,可是 操作符栈中还有数据,则输出 
232     {
233         if(reg_operator[reg_operator_pointer]=='.')
234         {
235             name_number++;
236             printf("name%d is cancat of name%d and name%d\n",reg_operator[0],token[0],token[1]);
237         }
238         else
239         {
240             name_number++;
241             printf("name%d is name%d or name%d\n",reg_operator[0],token[0],token[1]);
242         }
243     }
244 }

 

posted @ 2013-06-22 12:49  huangnima  阅读(326)  评论(0编辑  收藏  举报