代码之家  ›  专栏  ›  技术社区  ›  Kyle Brandt

如何使用bison/yacc和递归规则构建数组

  •  2
  • Kyle Brandt  · 技术社区  · 15 年前

    有了野牛,我就知道如何把所有的东西都串成一个长串,如下所示:

    arg_list:
        WORD arg_list { strcat( $1, "IFS" ); $$ = strcat($1, $2); }  |
        WORD
        ;
    

    还有:

    WORD arg_list { printf("%s, %s\n", $1, $2); }
    

    但问题是,我将不得不在第二个规则中再次拆分$2来解析它。有没有一种方法来填充数组而不只是使用串联?我是不是走错了路?

    如果我需要构建一个有意义的链表之类的东西,只是不确定绑定到arg_列表的正确方法,然后清理内存。

    2 回复  |  直到 14 年前
        1
  •  6
  •   Chris Dodd    15 年前

    如果您有一个带有前推操作的数组类型,那么这是非常简单的:

    arg_list:
        WORD arg_list { $$ = $2.push_front($1); }
        WORD { $$ = new Array<string>($1); }
    

    如果没有这些,就需要更多的工作。您可以使用向量并在末尾添加字符串(将按相反的顺序)。或者,您可以使用链接列表(如果您使用的是直C,则更容易):

    arg_list:
        WORD arg_list { $$ = malloc(sizeof(struct list_elem));
                        $$->next = $2;
                        $$->val = $1; }
        WORD          { $$ = malloc(sizeof(struct list_elem));
                        $$->next = 0;
                        $$->val = $1; }
    
        2
  •  2
  •   AyeAye    14 年前
    %union {
      char *char_ptr;
    }
    %token STRING
    %type <char_ptr> STRING string
    %%
    ...
    string:
        STRING        /* Lexic analyzer return STRING and set yylval = yytext; */
      | string STRING
        { char *str = (char*) malloc(strlen($1) + strlen($2) + 1);
          strcpy(str, $1);
          strcat(str, $2);
          free($2);
          free($1);
          $$ = str;
        }
      ;
    %%