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