问题
With Bison, I figured out how to get everything into one long string as follows:
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 that I will then have to split up $2 in the second rule again to parse it. Is there a way to populate an array instead of just using concatenation? Am I going about this the wrong way?
If I need to build something like a linked list that could make sense, just not sure what would be the proper way to bind to arg_list, and then clean up the memory.
回答1:
If you have an array type with a push_front operation, this is trivially:
arg_list:
WORD arg_list { $$ = $2.push_front($1); }
WORD { $$ = new Array<string>($1); }
without that, it requires more work. You can use a vector and add the strings on the end (which will be in the reversed order). Or you can use a linked list (which is easier if you're using straight 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:
%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;
}
;
%%
来源:https://stackoverflow.com/questions/1429794/how-to-build-an-array-with-bison-yacc-and-a-recursive-rule