tags:

views:

309

answers:

1

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  A: 

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; }
Chris Dodd
This is all straight C, the second one mostly makes sense, but I haven't gotten to the part where $$ has members, know what I might google exactly to find that?
Kyle Brandt
Got your second example working, thank you.
Kyle Brandt
$$ is just a variable of the type declared in the %type declaration of this rule, or of YYSTYPE if there is no %type declaration. Commonly, that will be a 'struct list *' for arg_list, so '$$->next' and '$$->val' will be elements of the pointed-to list object. In the C++ case its much more complex, depending on how you've defined things with potential references and whatnot.
Chris Dodd