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的源码,今天早上又读了一次。每次通读,都能有收获。
 

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