Chinaunix首页 | 论坛 | 博客
  • 博客访问: 263569
  • 博文数量: 52
  • 博客积分: 1379
  • 博客等级: 大尉
  • 技术积分: 525
  • 用 户 组: 普通用户
  • 注册时间: 2006-06-18 17:34
文章分类

全部博文(52)

文章存档

2011年(48)

2010年(4)

分类: C/C++

2011-03-05 22:06:27

  1. // 例子;
  2. // #define s ss
  3. // #define tt ttt
  4. // #define t tt
  5. // #define t1 t2
  6. // #define b(x) t + t1
  7. // #define a(d) d + s
  8. // a(b(x));
  9. //
  10. /* do macro substitution of current token with macro 's' and add
  11.    result to (tok_str,tok_len). 'nested_list' is the list of all
  12.    macros we got inside to avoid recursing. Return non zero if no
  13.    substitution needs to be done */
  14. static int macro_subst_tok(TokenString *tok_str,
  15.                            Sym **nested_list, Sym *s, struct macro_level **can_read_stream)
  16. {//
  17.     Sym *args, *sa, *sa1;
  18.     int mstr_allocated, parlevel, *mstr, t, t1, spc;
  19.     const int *p;
  20.     TokenString str;
  21.     char *cstrval;
  22.     CValue cval;
  23.     CString cstr;
  24.     char buf[32];
  25.     
  26.     /* if symbol is a macro, prepare substitution */
  27.     /* special macros */
  28.     if (tok == TOK___LINE__) {
  29.         snprintf(buf, sizeof(buf), "%d", file->line_num);
  30.         cstrval = buf;
  31.         t1 = TOK_PPNUM;
  32.         goto add_cstr1;
  33.     } else if (tok == TOK___FILE__) {
  34.         cstrval = file->filename;
  35.         goto add_cstr;
  36.     } else if (tok == TOK___DATE__ || tok == TOK___TIME__) {
  37.         time_t ti;
  38.         struct tm *tm;

  39.         time(&ti);
  40.         tm = localtime(&ti);
  41.         if (tok == TOK___DATE__) {
  42.             snprintf(buf, sizeof(buf), "%s %2d %d",
  43.                      ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900);
  44.         } else {
  45.             snprintf(buf, sizeof(buf), "%02d:%02d:%02d",
  46.                      tm->tm_hour, tm->tm_min, tm->tm_sec);
  47.         }
  48.         cstrval = buf;
  49.     add_cstr:
  50.         t1 = TOK_STR;
  51.     add_cstr1:
  52.         cstr_new(&cstr);
  53.         cstr_cat(&cstr, cstrval);
  54.         cstr_ccat(&cstr, '\0');
  55.         cval.cstr = &cstr;
  56.         tok_str_add2(tok_str, t1, &cval);
  57.         cstr_free(&cstr);
  58.     } else {
  59.         //s->d就宏a体的tok序列
  60.         //a(d) d + s
  61.     //对应 d, ' ', +, s四个tok
  62.         mstr = s->d;
  63.         mstr_allocated = 0;
  64.         if (s->type.t == MACRO_FUNC) {
  65.             //a : 是
  66.             /* NOTE: we do not use next_nomacro to avoid eating the
  67.                next token. XXX: find better solution */
  68.         redo:
  69.             //第一次, macro_ptr == 0
  70.             if (macro_ptr) {
  71.                 p = macro_ptr;
  72.                 while (is_space(t = *p) || TOK_LINEFEED == t)
  73.                     ++p;
  74.                 if (t == 0 && can_read_stream) {
  75.                     /* end of macro stream: we must look at the token
  76.                        after in the file */
  77.                     struct macro_level *ml = *can_read_stream;
  78.                     macro_ptr = NULL;
  79.                     if (ml)
  80.                     {
  81.                         macro_ptr = ml->p;
  82.                         ml->p = NULL;
  83.                         *can_read_stream = ml -> prev;
  84.                     }
  85.                     goto redo;
  86.                 }
  87.             } else {
  88.                 // 找 '('
  89.                 // 没处理如下这中情况
  90.                 // 好在没什么人在这种地方写注释
  91.                 // #define a() b
  92.                 // a /**/ ()
  93.                 /* XXX: incorrect with comments */
  94.                 ch = file->buf_ptr[0];
  95.                 while (is_space(ch) || ch == '\n')
  96.                     cinp();
  97.                 t = ch;
  98.             }
  99.             if (t != '(') /* no macro subst */
  100.                 return -1;
  101.                     
  102.             /* argument macro */
  103.             next_nomacro();
  104.             next_nomacro();
  105.             // tok = b
  106.             args = NULL;
  107.             sa = s->next; //第一个参数 d
  108.             /* NOTE: empty args are allowed, except if no args */
  109.             for(;;) {
  110.                 /* handle '()' case */
  111.                 if (!args && !sa && tok == ')')
  112.                     break;
  113.                 if (!sa)
  114.                     error("macro '%s' used with too many args",
  115.                           get_tok_str(s->v, 0));
  116.                 tok_str_new(&str);
  117.                 parlevel = spc = 0;
  118.                 /* NOTE: non zero sa->t indicates VA_ARGS */
  119.                 while ((parlevel > 0 || //参数包含括号, 期待结束右括号
  120.                         (tok != ')' && //或者可变参
  121.                          (tok != ',' || sa->type.t))) &&
  122.                        tok != -1) {
  123.                     if (tok == '(')
  124.                         parlevel++;
  125.                     else if (tok == ')')
  126.                         parlevel--;
  127.                     if (tok == TOK_LINEFEED)
  128.                         tok = ' ';
  129.                     if (!check_space(tok, &spc))
  130.                         tok_str_add2(&str, tok, &tokc);
  131.                     next_nomacro_spc();
  132.                 }
  133.                 str.len -= spc;
  134.                 tok_str_add(&str, 0);
  135.                 sa1 = sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, 0);
  136.                 sa1->d = str.str;
  137.                 //str: b(x)四个
  138.                 sa = sa->next;
  139.                 if (tok == ')') {
  140.                     /* special case for gcc var args: add an empty
  141.                        var arg argument if it is omitted */
  142.                     if (sa && sa->type.t && gnu_ext)
  143.                         continue;
  144.                     else
  145.                         break;
  146.                 }
  147.                 if (tok != ',')
  148.                     expect(",");
  149.                 next_nomacro();
  150.             }
  151.             if (sa) {
  152.                 error("macro '%s' used with too few args",
  153.                       get_tok_str(s->v, 0));
  154.             }

  155.             /* now subst each arg */
  156.      //参数已经由args提供了, args只有一个符号
  157.             //args->v=v_of_arg_d(sa->v), args->str=d(x)
  158.             //mstr: d + s
  159.             //args->d: d(x)需要替换吗? Y
  160.             mstr = macro_arg_subst(nested_list, mstr, args);
  161.             //返回结果
  162.             //mstr: ttt + t2
  163.             //当然,里面会有 macro_*递归调用,这个结果是最后的结果
  164.             
  165.             /* free memory */
  166.             sa = args;
  167.             while (sa) {
  168.                 sa1 = sa->prev;
  169.                 tok_str_free(sa->d);
  170.                 sym_free(sa);
  171.                 sa = sa1;
  172.             }
  173.             mstr_allocated = 1;
  174.         }
  175.         sym_push2(nested_list, s->v, 0, 0);
  176.         //最后我们将得到 ttt + t2 + ss
  177.         //其中mstr: ttt + t2 +s
  178.         //s->ss
  179.         macro_subst(tok_str, nested_list, mstr, can_read_stream);
  180.         /* pop nested defined symbol */
  181.         sa1 = *nested_list;
  182.         *nested_list = sa1->prev;
  183.         sym_free(sa1);
  184.         if (mstr_allocated)
  185.             tok_str_free(mstr);
  186.     }
  187.     return 0;
  188. }
阅读(3727) | 评论(0) | 转发(0) |
0

上一篇:next

下一篇:macro_arg_subst

给主人留下些什么吧!~~