C语言写正则表达式的编译器

看了一个题目,关于正则表达式的编译,反正无业在家,无聊,不如写一个。

思路:1.循环是不现实的,因为要加数量限制,且代码重复率太高,基于语言的发展,也没有可扩充性。

2,递归是可以实现一般功能的,但只是一重递归显然是无法实现的,比如 3 *(2+5.0)/3,。

3.双重递归---我们知道,对于正则表达式,只是一串字符串。任何编译器都是先将表达式的一部分做二元运算,也就 + - * / %....结果会存在堆区,再继续计算。由此可见,双重递归足以满足要求。

 

思路有了,开始行动:

首先要清楚优先级,在c语言中,各种运算符都有优先级排行,我们可以直接引用,先定义一个优先级字符指针二维数组

char *priority[32 ][32] = {

"(", "[", ".", "->" ;                            //便于分析不多添加

"*", "/", "%";

"&&", "&";

"+", "-";

NULL;

}

假设传进来一个正则表达式: char *expression = "((i+3.0)*4-5)-3/(x+6)"

有个浮点数3.0,这里的点操作数怎样判断呢,大家都知道c语言变量名规则,只能以字母和下划线开头,那么判断方法就是,如果.操作数的前边首字母是数字,就是一个浮点数,如果不是,就是一个变量,对于变量,要参照声明类或结构来读取其值。

表达则没有空格间隙,如果有,先写个函数去除它。

int digui(char *pression) {

   for (int i=0;i<32;i++) {

        for (intj=0;j<32;j++) {

              先用strstr对比pression和priority[i][j]是否有自动符存在,如果有,再判断属于哪个操作符

                 在有操作符存在的时候:

                       if ((i==0) && (j==0))          //成立时说明是个"("操作符

                       {

                              再往下找"(",如果没有,说明没有嵌套括号,直接找")"

                              如果再往下找有"(",说明嵌套了括号,可以写个递归去找,也可以通过计数"("与")"的对应数量,找最里层"("和对应的")"

                              完成后截取"("与")"中间的字符串做递归,比如这个字符串截取成*pression_child

                               digui(pression_child);       //第一次递归后上面的算式被这样带入了 (i+3.0)*4-5,多次递归后没有了括号,成了i+3.0,这样就需要用到"+"操作符了

                        }

                        如果是"+"操作符参见上面数组,i==3,j==0

 

                    找不到任何操作符的时候,说明二元运算结束了,值通过递归返回,return;

   }

}

看似容易,做起来还是相当有难度和复杂性的,核心思想就是:将一个正则表达式的字串,通过优先级运算符截取出来,递归运算,再把值返回,还是构成一个正则表达式字串,最底层的递归就是二元运算,将值做为字串返回,和上一层再构成一个字串,再分析,再递归,直到所以运算符被计算完

如: (3*3)/4.0+((2-1)*3)=> 6/4.0+((2-1)*3)=>6/4.0+(1*3)=>6/4.0+3=>1.5+3=>4.5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值