[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Bison C++ mid-rule value lost with variants
From: |
Frank Heckenbach |
Subject: |
Re: Bison C++ mid-rule value lost with variants |
Date: |
Mon, 18 Jun 2018 15:26:24 +0200 |
Akim Demaille wrote:
> 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).
AFAIK, that's the only purpose of the $<> syntax in Bison which has
been around for I don't know how long. So claiming it has no reason
to work now seems a bit odd to me.
> 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).
I don't think so. C unions involve a hidden cast only when accessing
a different member than was set, but that's not the case here.
C++ variants would throw in this case, and Bison's variants would
assert or UB in this case.
Apparently (and reasonably) this case is not supposed to work with
$<>, so WRT whether or not to support $<> at all, I see no
fundamental difference between C and C++, so if dropping support in
C++, it would only be consequent to do it in C as well, and that
might be nearly impossible due to backward-compatibility (or perhaps
even Yacc compatibility, I don't know).
> 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++.
As I wrote sometime before, I currently don't use any
semantic-valued mid-rule actions, so I'm basically neutral on this
proposal. In principle, I think a properly declared type for them
seems reasonable, I just think this proposal is a few decades late.
What's more important for me, and the reason I worked on this, are
other features, most importantly move semantics. Of course, they
also require modern C++ (i.e., C++11 or newer), so if that's a
problem, I'll have to keep my own fork anyway.
Regards,
Frank