bug-bison
[Top][All Lists]
Advanced

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

Re: Bison C++ mid-rule value lost with variants


From: Rici Lake
Subject: Re: Bison C++ mid-rule value lost with variants
Date: Sun, 17 Jun 2018 09:33:08 -0500

I enthusiastically support this proposal.

I agree with the preference for prefix positioning. The `%type` keyword is
just noise, imho, and thus unnecessary.

I like the `name=<type>{ code }` syntax, too, but it's probably too late
for that. Perhaps `{ code }[<type>name]` would be a plausible alternative
syntax, although I'd still prefer `<type>` in prefix position.

Although unrelated to this proposal, I would also favour allowing

%%
<type> nonterminal: rhs

as an alternative to

%type <type> nonterminal
%%
nonterminal: rhs


Rici

On Sun, Jun 17, 2018, 09:02 Akim Demaille <address@hidden> wrote:

> Hi all,
>
> > Le 29 juin 2017 à 15:55, Piotr Marcińczyk <address@hidden> a écrit
> :
> >
> > I supposedly found a bug in lalr1.cc skeleton with variant semantic type.
> > When using mid-rule action { $<type>$ = value; } to return a value that
> > will be used in further semantic actions, it appears that the value on
> > stack becomes zero. Tested with Bison version 3.0.4.
>
> Piotr’s grammar file includes:
>
> %token <int> NUM
> %%
> expr:
>   NUM
> | expr { $<int>$ = 42; } '+' NUM { std::cout << $<int>2 << '\n'; };
>
> and one can see that when run, $<int>2 is not 42, but 0.
>
> My opinion on this is somewhat different from the ones that
> have been expressed so far.  IMHO, it has no good reason
> to work.
>
> Yes, it works with plain old unions.  But that’s unsafe, and
> that’s because you hide things from your tool (Bison).  I
> personally see these typed accesses to the semantical
> values ($<int>2) are no different from a cast (and actually,
> that’s exactly what they are with unions).
>
> Yes, it works with C++ variants, or even std::any, when
> used as a store for semantical values.  But we are still lying
> to the tool.
>
> I think this example shows that the design of mid-rules
> actions has some loopholes, and in particular something which is
> critically missing is the type of its semantical value.  Since,
> Bison does not know the type of the semantical value of a mid-rule
> action:
> - the user must use $<int>$, not $$
> - the destructor will not work
> - the printer won’t work either
> - the user must also be explicit when using the value in
>   the other actions ($<int>2).
>
> Sure, using std::variant or std::any we avoid the first three issues,
> but that’s still by hiding things from Bison and relying on
> magic on the language side.  And obviously that works only for
> C++, and actually modern C++.
>
> I think we should rather provide typed mid-rule actions.
>
> How about:
>
> expr:
>   NUM
> | expr %type<int>{ $$ = 42; } '+' NUM { std::cout << $2 << '\n'; };
>
> It’s not clear whether it should be prefix or postfix
>
> expr:
>   NUM
> | expr { $$ = 42; } %type<int> '+' NUM { std::cout << $2 << '\n'; };
>
> The regular use of %type is prefix (%type <int> expr), but the
> directives in rules are usually presented as postfix
> (exp: "if" exp exp %prec "then"), although it is not mandatory.
>
>
> Or go for a lighter syntax
>
> expr:
>   NUM
> | expr <int>{ $$ = 42; } '+' NUM { std::cout << $2 << '\n'; };
>
> or
>
> expr:
>   NUM
> | expr { $$ = 42; }<int> '+' NUM { std::cout << $2 << '\n'; };
>
>
> Personally, I prefer the prefix forms, but they don’t blend
> nicely with named references:
>
> expr:
>   NUM
> | expr <int>{ $$ = 42; }[val] '+' NUM { std::cout << $val << '\n'; };
>
> Thoughts?
>
>
>
>
>
> I wish we had chosen a prefix syntax for named references, say
>
> expr:
>   NUM
> | expr val={ $<int>$ = 42; } '+' NUM { std::cout << $<int>val << '\n'; };
>
> I think we discussed this with Joel E. Denny, but I don’t remember
> the details. We could have used
>
> expr:
>   NUM
> | expr val<int>={ $$ = 42; } '+' NUM { std::cout << $val << '\n'; };
>
>
>
>
>


reply via email to

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