oz grep原始碼分析

2021-10-04 07:21:37 字數 2840 閱讀 6497

oz grep原始碼分析

今天在筆記本上折騰ubuntu18,真是很好玩。

配置低的本上,裝ubuntu,真划算。原來4g跑win10總是慢得不行,現在跑linux,感覺還是很快的。

我在本子上讀regex.c這個檔案,乙個地方卡住了。

for (p = pat; *p; p++)

break;

case '$':               /* match endofline.. */

if (!*(p+1))

store(eol);

else

break;

case '[':               /* match char class..*/

store(ccl);

if (*++p == '^')

else

mask = 0;

if (*p == '-')        /* real dash */

chset(*p++);

if (*p == ']')        /* real brac */

chset(*p++);

while (*p && *p != ']')

#ifdef extend

else if (*p == '\\' && *(p+1))

#endif

else

chset(*p++);

}if (!*p)

return badpat("missing ]");

for (n = 0; n < bitblk; bittab[n++] = (char) 0)

store(mask ^ bittab[n]);

break;

這是在re_comp中進行編譯,把正規表示式翻譯成中間碼。此處,把'[1-9]'翻譯成

'123456789',但你看呀,

如果p指向[,此時,先儲存「ccl」,接著,判斷

*++p,此時,p指向1,所以下面兩個判斷不用做,因為不是-,也不是],那就來到了

while (*p && *p != ']')

#ifdef extend

else if (*p == '\\' && *(p+1))

#endif

else

chset(*p++);

}此時,p指向'[1-9]'中的1,所以執行迴圈中第三分支

else

chset(*p++);

把1儲存進去。接著p++,此時p指向-

那好,接著迴圈,因為*p=='-'所以執行第一分支

if (*p == '-' && *(p+1) && *(p+1) != ']')

此分支,完成的是就是把23456789這幾個字元儲存好。

此時,用話不好說,請看**中注釋。這個分支做完後,p指向],因此,要跳出迴圈。

做下一步處理

for (n = 0; n < bitblk; bittab[n++] = (char) 0)

store(mask ^ bittab[n]);

也就是把16位元組的位置儲存到中間**陣列中去。

此時,p指向],那程式如何處理]的呢?

程式只有如下分支

case .

case $

case [

case *

case +

....

如果不是這些字元,它是:

default :               /* an ordinary char  */

store(chr);

store(*p);

break;

可是,中間**編譯結果中根據沒有儲存]呀,況且儲存了也沒意義。你看:

yang@desktop-v9hs3b6:~/grep$ echo "12345" | ./ogrep '[1-9]+'

pattern: [1-9]+

nfacode:

ccl [123456789]

closure ccl [123456789]

看到沒,正規表示式翻譯的結果中根據沒有】

我想呀想,不停地翻**。總是不得勁。

後來,忽然想,不對,這裡有個break,就是

case [

把[1-9]變成ccl 123456789儲存到中間碼,此時p指向],

break

結束本次迴圈後,到哪了?

for (p = pat; *p; p++) {//此處有p++,哈哈,我明白了。原來在這裡!!!

lp = mp;

switch(*p) {

case '.':         

看到我的注釋沒?p本來指向],這是沒錯的,但break後,p++,就跳過了]

通過讀程式,發現自己的程式功底還是有欠缺。

同樣的錯誤犯了兩次。前一次,看**

for (n = 0; n < bitblk; bittab[n++] = (char) 0)

store(mask ^ bittab[n]);

這裡,是把16位元組的點陣圖儲存到中間**結果中去。當時我曾想,你把bittab儲存進去了,你下次使用是,要初始化吧,那在哪兒初始化呢???

我找呀找!

你肯定要初始化的,不然如果這樣寫正規表示式'[a-z'] hello [1-9]'那如何搞?

前面使用的位置如果不初始化,後面且不是變成了[a-z1-9]。當時是用kindle讀**,想呀想,後來明白了。

for (n = 0; n < bitblk; bittab[n++] = (char) 0)//此處有bittab[n++] = (char)

store(mask ^ bittab[n]);

作者在for的最後做了。

**要經常讀,太好了。

spring原始碼分析 spring原始碼分析

1.spring 執行原理 spring 啟動時讀取應用程式提供的 bean 配置資訊,並在 spring 容器中生成乙份相應的 bean 配置登錄檔,然後根據這張登錄檔例項化 bean,裝配好 bean 之間的依賴關係,為上 層應用提供準備就緒的執行環境。二 spring 原始碼分析 1.1spr...

思科VPP原始碼分析(dpo機制原始碼分析)

vpp的dpo機制跟路由緊密結合在一起。路由表查詢 ip4 lookup 的最後結果是乙個load balance t結構。該結構可以看做是乙個hash表,裡面包含了很多dpo,指向為下一步處理動作。每個dpo都是新增路由時的乙個path的結果。dpo標準型別有 dpo drop,dpo ip nu...

redux原始碼分析(三) 原始碼部分

下面是每個部分的一些解讀 createstore apicreatestore reducer,initialstate enhancer 曾經非常好奇這個函式的第二個引數到底是initialstate還是enhancer,因為見過兩種寫法都有的,以為是版本問題。看了原始碼才發現,都可以的。如果你不...