gawk1.01源碼分析——各文件功能

gawk1.01源碼分析——各文件功能
今天就各個文件的基本功能談下我的理解。
一、awk.h頭文件
先列出數據結構
typedef struct hashnode HASHNODE;
struct hashnode {
  HASHNODE *next;
  char *name;
  int length;                                                                                                     NODE *value;                                                                                                  } *variables[HASHSIZE];

            
個人以爲*variables[HASHSIZE]存儲了程序中用到的變量。除哈希數組之外的都應該存儲在這裏。

typedef struct ahash AHASH;
struct ahash {
        AHASH *next;
        NODE    *name,                                                                                                          *symbol,
                *value;
};
這個數據結構存儲了哈希數組。但只是一個結構。具體的數據定義呢。我沒看到。

typedef struct exp_node {
  NODETYPE type;
  union {
        struct {
                struct exp_node *lptr;
                union {
                        struct exp_node *rptr;
                        struct exp_node *(* pptr)();
                        struct re_pattern_buffer *preg;
                        struct for_loop_header *hd;
                        struct ahash **av;
                        int r_ent;      /* range entered (jfw) */
                } r;
        } nodep;
        struct {
                struct exp_node **ap;
                int as;
        } ar;                                                                                                           struct {
                char *sp;
                short slen,sref;                                                                                        } str;                                                                                                          AWKNUM fltnum;
  } sub;
} NODE;
這個結構開始讓我頭痛無比,經常看,頭好像就不痛了。慢慢還看出一點名堂。這就是存儲語法分析樹的數據結構。作者後面定義了一些宏來進行簡化。關鍵是type,lptr,rptr等幾項。我想,要在debug.c中,把具體每個結點是如何存儲的,打印出來。就更容易理解了。
總體來講,awk.h定義了語法樹的存儲結構,也定義了程序中變量所存儲的地方。

二、接着談awk1.c
開始看這個文件,象讀天書。現在看得多了,就覺得這個文件看上去很親切。所以我費盡心思把gawk1.01這個版本要編譯成功。因爲我看這些代碼看熟悉了,就產生了感覺。

先把NF,NR,FS,RS等變量進行初始化
再分析命令行中命令選項
  -D 與調試相關
  -R 設計記錄分隔符RS
  -F 設置字段分隔符FS
  -f 把awk命令文件讀到指針lexptr中。
如果沒有-f選項,就從命令行中讀awk指令到lexptr中。
調bison進行語法分析
初始化字段變量,$0,$1,$2直到$30
從awk指令中找出BEGIN,END塊。
如果有BEGIN塊,就處理之(從這裏看出,此時沒有處理變量)
找出變量。如
【gawk -f a=1 b=2 book.txt
就是批出a=1 b=2並把a,b存儲到全局變量環境系統中去。】
如果要處理多個文件,對每個文件循環處理
  1、先打開文件
  2、循環讀取文件每一行,直到文件結束
    21、讀出文件中一行,並按FS設計$0,$1,$2等各字段變量的值
    22、如果有變量,就把變量存儲到環境系統中去
    23、把全部awk指令應用到當前行
  3、關閉打開的文件
如果有END塊,就處理END塊

三、awk2.c
我記得,有時給變量命名name1,name2,name3會挨領導的批評,說不規範。現在看到專家也這樣命名。看來,專家也是從小兵長大的。言歸正傳。
awk2.c中主要是對語法樹進行解析、執行。
interpret(tree)
  awk1.c中主要調用這個函數,實現語法樹解析執行。
  根據tree->type來處理
    如果是Node_rule_list
      沒看懂。
    如果是Node_statement_list
    Node_K_if
    Node_K_while
    Node_K_for
    Node_K_arrayfor
    Node_K_break
    Node_K_continue
    Node_K_print
    Node_K_printf
    Node_K_exit
    Node_K_next
其它幾個函數我都不想列了。因爲自己沒看懂。
四、awk3.c
這個文件我很喜歡。因爲其中寫的是一些內部函數的實現邏輯。而那些函數我會用呀。象int,index,exp,log,split等函數,我知道其功能後,就根據功能要求,來看源碼實現。這不會一件最快樂的事嗎。
作者在內部函數前都加了前綴do_,如do_int(),do_index()等。不過,do_sprintf函數太長,我都沒興趣看。此時,我的做法,就是按下光標鍵,讓代碼流水一樣的往下走。
五、debug.c這個文件是和調式相關的。
六、regex.c,regex.h
是和正則表達式相關的。grep中正則引擎nfa的我基本搞懂了。這裏好像用的是dfa,我看不懂。
七、obstack.c
和內存分配相關。沒看懂。
昨天睡之前,讀了一遍gawk1.01的源碼,今天早上又讀了一次。每次通讀,都能有收穫。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章