Le 24 juin 2013 à 20:56, Valentin Tolmer <nitnela...@gmail.com> a écrit :
> Hello everyone, Hi! > I'm working on an addition to bison, and I have a small grammar problem... > I added something to the bison grammar, to understand statements such as > %prec OR '+' > '*' (for example) > > However when parsing a statement with several tokens as char, I have a > problem. The example I'm currently testing with is this: > > %prec '^' > OR '*' '/' '-' '+' > > which is read to me, for some reason, as > %prec '+' > OR '+' '+' '+' '+' This kind of symptom is probably the sign that you are keeping a pointer to a semantic value, instead of keeping the semantic value itself (which might require allocation, depending on its type). Be sure to read http://www.gnu.org/software/bison/manual/bison.html#Strings-are-Destroyed > What I mean is that every char is correctly read, the symbols are the right > ones, but somehow when creating the list, it screws up and replaces every > char with the last one read (not just +, the last one read). I test the lists > at the beginning of declare_precedence_relation, so none of my outside code > affects it. > > Here's the code, in parse-gram.y (the printf displays the right characters): > > > precedence_relation_declaration: > "%prec" precedence_relation_symbols precedence_relation_comparator > precedence_relation_symbols > { declare_precedence_relation ($2, $4, $3); } > ; > > precedence_relation_symbols: > precedence_symbol { $$ = $1; } > | precedence_relation_symbols precedence_symbol > { $$ = symbol_list_append ($1, $2); } > ; > > precedence_symbol: > string_or_id > { > if (is_prec_group ($1)) > $$ = expand_symbol_group (symgroup_from_uniqstr($1, &@1), @1); //not > called in this example > else > $$ = symbol_list_sym_new (symbol_from_uniqstr ($1, @1), @1); > } > | CHAR > { > printf ("char seen : %s\n", symbol_from_uniqstr(char_name ($1), @1)->tag); char is working on a private buffer: static char const * char_name (char c) { if (c == '\'') return "'\\''"; else { char buf[4]; buf[0] = '\''; buf[1] = c; buf[2] = '\''; buf[3] = '\0'; return quotearg_style (escape_quoting_style, buf); } } which results obviously in always the same address. You are calling symbol_from_uniqstr on something which is _not_ a uniqstr. uniqstr is the same type as char*, however, these strings are "internalized", i.e., a single copy of them is kept, which allows us to compare/hash strings by working on addresses instead of the characters. So here, since everything works on *addresses* and you have only one, of course latter symbol override former ones. Admittedly you should add a "uniqstr_assert" in symbol_from_uniqstr. Once it properly blows at your face, fix your code and use uniqstr_new from your char_name. > $$ = symbol_list_sym_new (symbol_from_uniqstr (char_name ($1), @1), @1); > } > ; > > string_or_id: > STRING { $$ = uniqstr_new (quotearg_style (c_quoting_style, $1)); } //not > called, I believe, in that example > | ID { $$ = $1; } > ; > > precedence_relation_comparator: > ">" { $$ = prec_superior; } > | "=" { $$ = prec_equal; } > | ">" ">" { $$ = prec_superior_strict; } > ; > > _______________________________________________ > help-bison@gnu.org https://lists.gnu.org/mailman/listinfo/help-bison _______________________________________________ help-bison@gnu.org https://lists.gnu.org/mailman/listinfo/help-bison