不到1000行的正则表达式源码分析05

不到1000行的正则表达式源码分析05
写程序真需要安静。心情要宁静,另外,外面要尽量安静。
也即,最好外部安静,内心也安静,这样,才能随着程序一步步走,在网上花心血购了降噪耳机,感觉真爽。价钱也真是贵,但效果还真是好。
今天上午看代码,中午睡觉,一觉醒来,感觉神清爽,午睡后,一天可当两天用。
首先看grep.c其中最让我烦的是字符串的资源分析,在《程序设计实践之路》中,有专门一章,讲资源分析,反正我没看懂。在grep中也有。
main()
{
    char str[512];

    if () {
        while((n=load(str,f)) !=EOF)
            …………
    }
}
其中,load定义如下
load(char *s,FILE *f)
{
    while()
        *s++=c;
    *s=(char)0;
}
看到没,在load函数中,对参数s的内容进行了填充,在main中,就使用这些字串。因为C语言,对参数是传值,用指针可以改变指针指向的值,让外面的函数使用。
这个很巧妙。

今天接着细看程序,发现上回发现不理解的,这次理解了。
象"[0-9]"处理成
"[0123456789]"是如何实现的呢?
while () {
    if (*p=='-' && .......) {

    }
    else if () {

    }
    else 
        chset(*p++);
}
当p指向[0-9]中的0时,应该执行else分支,此时,已经把0写进bitset了,再次再循环时,p指向-,此时,进行if第一分支,所以只要
c1=*(p-2)+1
c2=*p++
while(c1<=c2)
     chset((CHAR)c1++)
看到没,因为0在上一次循环中,已经写入了,所以这次只要从1,2,3,4,5,6,7,8,9写到bitset中即可。
我发现作者写的程序思路相当清晰,真是佩服。思路清晰,表达明白。真是佳作。
在这里,接下来是:
for(n=0; n<BITBLK;bittab[n++]=(char)0)
    store(mask ^ bittab[n]);

这个循环,其中bittab数组保存了[0-9]展开后的[0123456789],那如何保存的呢,因为这个bitset用过后,要初始化,如
./grep "fo[0-9]"  a.txt
./grep "ab[a-z]"  b.txt
第一次用过后,bittab中,有了值,下次使用之前,要清空,那如何实现的呢?
我开始想了很久,后来,才知道奥秘在for语句中的
for(...;...;bittab[n++]=(char)0)
看到没,先是使用,使用完了,再清空。通过读程序,发现自己的C语言,用得不熟悉。
re_comp的思路很好理解,其中对如何把[0-9a-z]与入bitset这一步,我没有理解。我知道是用16个整数,共16*8=128个位来表示128个字符,但具体如何表示,还是不明白。<<,>>|等操作,让我晕了。
看完,re_comp再看,re_exec,感觉很好懂。
在re_exec中调用了,re_pmatch,其中有一处,写得相当有技巧。


 

猜你喜欢

转载自blog.csdn.net/woshiyilitongdouzi/article/details/86305828