bug-bison
[Top][All Lists]
Advanced

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

Re: symbol_type::token () removed?


From: Frank Heckenbach
Subject: Re: symbol_type::token () removed?
Date: Thu, 02 Jan 2020 23:48:07 +0100

Akim Demaille wrote:

> > and I think my use case is legitimate.
> > 
> > [...]
> > So I have things like:
> > 
> >     Lexer lex("12345");
> >     symbol_type t = lex.nextToken();
> >     assert(t.token() == token::INTLIT);
> >     assert(t.value.as<int>() == 12345);
> 
> which gives me the impression that the real use case would be something like
> 
> assert(t == token::make_INTLIT(12345))

That was my first thought as well when I read the original message ...

> WDYT?  Hum.  That would require operator==, which would generate a lot
> of code.  And it would require the value types to support ==, which so
> far we do not require.

... and that was my second thought. ;)

It might be possible to SFINAE check if all value types support
"==", as Wolfgang suggests. But what if only some do, and one only
cares about those? E.g., suppose all of your (Wolfgang) types
currently do and you rewrite your tests like above. But later you
need to add another type somewhere in the parser that has no obvious
"==" operator. You'd have to add a fake one (never to be called,
possibly just calling abort() -- declaring without defining won't
do), just to keep your test using int working. This might turn
unrelated compile-time problems into runtime aborts, also not nice.

With some more SFINAE, one could check each type individually and
always return false if it has no "==" operator. But that also seems
error-prone.

So while I originally thought it was a good idea to make the value
type comparable, the more I think about it, the more doubts I have.

On the other hand, I wouldn't mind keeping it similar to
std::variant generally. std::variant does declare "==", but makes it
UB if "==" does not yield a valid expression returning a type
convertible to bool, for any type
(https://en.cppreference.com/w/cpp/utility/variant/operator_cmp).
In practice, it seems to give a compile-time error if any type does
not have "==", but it might be runtime UB if it exists and returns
non-bool.

However, std::variant is a template, so if the "==" operator is not
used, it won't get instantiated, so there's no problem, whereas
Bison's value type is not a template, so implementing a "==" that
requires all semantic types to have one would cause compilation of
the parser to fail even if "==" isn't actually used, so as Wolfgang
wrote:

> It could be another %define option, and then static_assert the presence
> of operator== for the value types.

It pretty much would have to be another option then to avoid
breaking other parsers (or turning it into a template, just for this
purpose, and maybe similar ones in the future). Whereas
static_assert doesn't seem necessary -- compilation would just fail
anyway if some type doesn't have "==".

Another question is if "==" should include equality of locations (if
enabled) or ignore them. Either choice could be confusing to someone
who assumes the other (or doesn't consider locations), so at least
it must be documented clearly.

Regards,
Frank



reply via email to

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