gnu gawk1.0源码分析……大致看懂了
gnu gawk1.0源码分析……大致看懂了 最近过年,天天吃喝,没看代码,总觉得好象虚度了光阴。于是,今天又开始读源码。 gawk能编译成功后,读代码就容易了。但因为牵涉到bison,而bison又不熟悉。为此,先读awk.y,通过反复读这个文件,终于对awk的语法更熟悉了。因为awk.y写得太好了,其中如何进行语法分析,写得相当精彩。 start : program ; program : rule | program rule ; rule : pattern action ; 我看了许多遍后,终于对awk的语法有了些理解。并且产生了若干奇怪的想法,如可以出现多个BEGIN块吗?可以把BEGIN块不放在开头吗?等等。 接着分析awk1.c这个主程序,这个程序是入口,我说下我的理解。
先进行初始化 对命令行进行解析,没有调用getopt,而是自己手工解析 如果-d 进行调试 如果-R 设置参数RS 如果-f 打开awk命令文件,并读入lexptr字串中。 如果没有-f,就把写在命令行中的awk指令读入lexptr串中。 调yyparse()进行语法分析 init_fields()进行$1,$2,$3..$30的初始化。 找到BEGIN,END块,如果有多个BEGIN块,只取最后的一个。 查看,命令行中是否有程序中要处理的参数。如awk .... abc=10 file1 其中,abc是一个变量,要在awk程序中用到。 打开命令行中的数据文件,如果有多个就循环处理。 //具体的处理,还是用代码说话,用普通话说,太麻烦了。 if(inrec()==0) { //inrec()中读入一行,并设置字段变量 if(do_vars) { while(do_vars!=argv && *do_vars) { //找出命令行的变量 char *cp;
cp=index(*do_vars,=); *cp++= ; variable(*do_vars)->var_value=make_string(cp,strlen(cp)); do_vars++; } do_vars=0; } do obstack_free(&temp_strings, ob_dummy); while (interpret(expression_value) && inrec() == 0); //interpret(expression_value)中进行了awk命令的解析,然后再用 //inrec()读入下一行 } if(input_file!=stdin) fclose(input_file);//处理下一个文件 argv++; 终于把gawk文件读了一个半懂。也就是说,大概的流程知道了。但详细的细节,就要慢慢研读了。 awk中用到了正则表达式,用到了bison,而且awk是perl,ruby语言的先驱,感觉读了后,非常有收获。 下次,我就再慢慢的研读。