How to build an array with Bison / Yacc and recursive rule

With Bison, I figured out how to nest everything in one long line like this:

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

      

and

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

      

But the problem is I will have to split $ 2 again in the second rule to parse it. Is there a way to populate an array and not just use concatenation? Am I going about this wrong?

If I need to build something like a linked list that might make sense, I'm just not sure what would be the correct way to bind to arg_list, then clear the memory.

+2


source to share


2 answers


If you have an array type with a push_front operation, this is trivial:

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

      



without it, more work is required. You can use a vector and add lines at the end (which will be in reverse order). Or you can use a linked list (which is easier if you are using direct 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; }

      

+6


source


%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;
    }
  ;
%%

      



+2


source







All Articles