• 最初步的正则表达式引擎


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

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

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

      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]='';
     36         token[input_pointer]=0;
     37     }
     38     input_pointer=0;
     39     printf("please  type in you regex short phrase
    ");
     40     scanf("%s",reg_input);
     41     while(*(reg_input+input_pointer)!='')
     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
    ",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)
    ",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
    ",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]='';
    111                             break;
    112                         }
    113                         else
    114                         {
    115                             name_number++;
    116                             printf("name%d is  name%d or name%d
    ",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]='';
    122                             break;
    123                         }
    124                         
    125                     }
    126                 case '*':
    127                     //这个运算符优先级基本上是最高的,因此不需要入栈了,直接处理
    128                     name_number++;
    129                     printf("name%d is multiple of name%d
    ",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
    ",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
    ",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
    ",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
    ");
    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
    ",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
    ",reg_operator[0],token[0],token[1]);
    237         }
    238         else
    239         {
    240             name_number++;
    241             printf("name%d is name%d or name%d
    ",reg_operator[0],token[0],token[1]);
    242         }
    243     }
    244 }
    
  • 相关阅读:
    spring中@value注解需要注意
    mysql创建utf-8字符集数据库
    Access denied for user 'root'@'localhost' (using password:YES) 解决方案[转]
    MySql 5.7.20安装
    Shiro 登录认证源码详解
    为什么说Java匿名内部类是残缺的闭包
    Java中的闭包之实例一
    使用Eclipse的Working Set管理项目
    glibc下载安装
    Struts2 整合 Hibernate 框架
  • 原文地址:https://www.cnblogs.com/huangfeidian/p/3149667.html
Copyright © 2020-2023  润新知