1. 程式人生 > >不到1000行的正則表示式原始碼分析05

不到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,其中有一處,寫得相當有技巧。