gnu gawk1.01源码分析 编译

gnu gawk1.01源码分析 编译
我不停的在网上找gawk的分析文章,可惜硬是找不到了。前几天,就把gawk的使用进行系统的复习。基本上对gawk的使用算是入门了。
但原理呢?还是看代码,读《flex 与bison》后,对awk.y这个文件基本有了了解,更可喜的是,在一台神舟的笔记本上,把程序编译通过了,那个本子上装的是win7 64位,但C编译器装的好象是另一个gcc,我也迷糊,反正就折腾。
当时遇到bison编译不通过时,就把bison重新安装,发现就能使用了。真是奇怪。于是开始通读源码。其中regex.c这个文件使用的是DFA,我在网上找相关资料,可以没有。这个匹配没有使用递归算法,真是看不懂,碰到对*的解析时,我在想,前面的字符如何处理的呢?看不懂。于是进行调试,但结果也看不懂。还有什么快速模式,真是麻烦。
在regex.h这个文件中,定义了一个结构体,保存编译后的正则表达式。
struct re_pattern_buffer
  {
    char *buffer; /* Space holding the compiled pattern commands. */
    int allocated; /* Size of space that  buffer  points to */
    int used;  /* Length of portion of buffer actually occupied */
    char *fastmap; /* Pointer to fastmap, if any, or zero if none. */
   /* re_search uses the fastmap, if there is one,
      to skip quickly over totally implausible characters
指向 fastmap 的指针 (如果有) 或零 (如果没有)。/
/re_search 使用 fastmap, 如果有的话,
快速跳过完全不可信的字符    
     */
    char *translate; /* Translate table to apply to all characters before comparing.
      Or zero for no translation.
      The translation is applied to a pattern when it is compiled
      and to data when it is matched.
将表格转换为在比较前应用于所有字符。
或零, 没有翻译。
在编译时将转换应用于模式
和数据匹配时。    
     */
    char fastmap_accurate;
   /* Set to zero when a new pattern is stored,
      set to one when the fastmap is updated from it. */
    char can_be_null;   /* Set to one by compiling fastmap
      if this pattern might match the null string.
      It does not necessarily match the null string
      in that case, but if this is zero, it cannot.
      2 as value means can match null string
      but at end of range or before a character
      listed in the fastmap.  */
  };

struct re_pattern_buffer 中,关键是对fastmap不理解,真心不理解,好象是若出现
[0-9]就翻译成0123456789之类,再用到几个关键的过程,先是
extern char *re_compile_pattern ();
编译完后,再使用。
extern int re_search (), re_search_2 ();
那编译后的正则表达式是什么样的,定义了一个枚举类型的东西,如下所示:
enum regexpcode
  {
    unused,
    exactn,    /* followed by one byte giving n, and then by n literal bytes
后跟一个字节给 n, 然后由 n 个文本字节
  
   */
    begline,   /* fails unless at beginning of line */
    endline,   /* fails unless at end of line */
    …………
    };
关键是这个东西我理解不了,真不理解,原来介绍NFA时,那个网上介绍得真好,我可以读文档理解代码,而且较直观,这个东西,真不知他为何这样定义。搞了半天,看不懂,于是就跳过去。
心想,反正正则表达式的结果我知道,于是就跳过,开始读awk.h
这个文档可真有难,其中有意思的是:
typedef enum {
  /* illegal entry == 0 */
  Node_illegal,  /* 0 */
  /* binary operators  lnode and rnode are the expressions to work on
二进制运算符 lnode 和 rnode 是用于工作的表达式
   *
   * */
  Node_times,  /* 1 */
  Node_quotient, /* 2 */
  Node_mod, …………
}NODETYPE ;
这个enum定义了一个枚举类型,用来把程序中的一些运算符之类东西进行存储,然后定义了一个奇怪的结构体,我硬是没看懂:
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;
这个结构体很奇怪。于是接着往下看,知道大概是把程序编译后,保存到里面了。但如何构成一个链表呢?真是奇怪。
作者又定义了一系统的宏,来简化操作。如下:
#define lnode sub.nodep.lptr
#define rnode sub.nodep.r.rptr
#define subnode lnode
#define proc sub.nodep.r.pptr
而且再配套一系统的函数,进行结果的操作,如:
NODE *
newnode(ty)
NODETYPE ty;
{
 register NODE *r;
 r=(NODE *)malloc(sizeof(NODE));
 if(r==NULL)
  abort();
 r->type=ty;
 return r;
}
反正,作者就是以这个NODE作为核心数据结构。
在awk1.c 中,慢慢看代码,但我不知程序如何解释,不知程序的大致走向。其中有一个debug.c的文件,再找到,在其中倒有意思。
print_a_node(ptr)
NODE *ptr;
{
 NODE *p1;
 char *str,*str2;
 int n;
 HASHNODE *buc;
 if(!ptr) return; /* don't print null ptrs */
 switch(ptr->type) {
 case Node_number:
  printf("%g",ptr->numbr);
  return;
 case Node_string:
  printf("\"%.*s\"",ptr->stlen,ptr->stptr);
  return;
 case Node_times:
  str="*";
  goto pr_twoop;
看到没,作者根据结点类型,分别进行打印。我想还是慢慢调试时,再理解。读程序,真要调试才能读懂。
今天唯一有成就感的,在windows下,vim看C 代码,注释没有变色,于是网上搜索了很久,找到一句,
highlight Comment ctermfg=green guifg=green
但加到vimrc中没有效果,于是再到linux下折腾,发现linux下变色了,于是在linux下读代码。但linux下vim的代码,不容易拷出来,复制到windows下,于是又在windows下找到awk相关代码。读代码,真象在黑暗中瞎撞。想找人交流,在网上一搜,只看到我写的几篇烂文章,心想,我还是慢慢读吧。


猜你喜欢

转载自blog.csdn.net/woshiyilitongdouzi/article/details/80211617
GNU
今日推荐