help-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Weird problem


From: Akim Demaille
Subject: Re: Weird problem
Date: Thu, 27 Jun 2013 12:06:00 +0200

Le 24 juin 2013 à 20:56, Valentin Tolmer <address@hidden> 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; }
> ;
> 
> _______________________________________________
> address@hidden https://lists.gnu.org/mailman/listinfo/help-bison




reply via email to

[Prev in Thread] Current Thread [Next in Thread]