Concatenate enums?

Ö

Öö Tiib

By "concatenate" I mean creating a new enum which will act as a superset of any given enum.

No.

You can write some class that behaves as enum and manages conversions
from the sub-enums to it and back but you need to be careful with
that. Enumerators convert implicitly to int and so cause sometimes
hard to detect bugs already.

Why you need it?
 
R

Rui Maciel

Öö Tiib said:
No.

You can write some class that behaves as enum and manages conversions
from the sub-enums to it and back but you need to be careful with
that. Enumerators convert implicitly to int and so cause sometimes
hard to detect bugs already.

Fair enough.

Why you need it?

I was dealing with a lexer function which I intended to use in a LL parser. In order to build the
parser table it was necessary to have a complete list of that parser's symbols, both terminal and
non-terminal. If it was possible to define a new enum which was a proper superset of the lexer's
enum then it would be terribly easy to do this sort of stuff.


Rui Maciel
 
R

Richard

[Please do not mail me a copy of your followup]

Rui Maciel <[email protected]> spake the secret code
I was dealing with a lexer function which I intended to use in a LL
parser. In order to build the
parser table it was necessary to have a complete list of that parser's
symbols, both terminal and
non-terminal. If it was possible to define a new enum which was a
proper superset of the lexer's
enum then it would be terribly easy to do this sort of stuff.

If you are writing a lexer/parser for a simple language, you may wish
to consider the Spirit library from boost.
<http://boost-spirit.com/home/>

Now that I've learned how to write lexers and parsers in Spirit, I
honestly just can't imagine going back to lex/yacc style table based
parsers.
 
A

AnonMail2005

Fair enough.


I was dealing with a lexer function which I intended to use in a LL parser.  In order to build the
parser table it was necessary to have a complete list of that parser's symbols, both terminal and
non-terminal.  If it was possible to define a new enum which was a proper superset of the lexer's
enum then it would be terribly easy to do this sort of stuff.

Rui Maciel

If two seperate enums have mutually exclusive values you can define a
new enum and simply set the values of the superset enums to the values
of the oringal enums.

You can make you original enums have mutually exclusive values by
setting aside a range for each one. For example you can do the
following:

// starts at 0
enum FIRST
{
FIRST_A = 0,
FIRST_B
};

// starts at 1000
enum SECOND
{
SECOND_A = 1000,
SECOND_B
};

// superset enum
enum SUPERSET
{
SS_FIRST_A = FIRST_A,
SS_FIRST_B = FIRST_B,
SS_SECOND_A = SECOND_A,
SS_SECOND_B = SECOND_B
};

HTH
 
R

Rui Maciel

Richard said:
If you are writing a lexer/parser for a simple language, you may wish
to consider the Spirit library from boost.
<http://boost-spirit.com/home/>

Now that I've learned how to write lexers and parsers in Spirit, I
honestly just can't imagine going back to lex/yacc style table based
parsers.

I can't access boost's docs on the spirit parser right now (the connection keeps timing out), so I
can't look into it at this moment. Yet, honestly I don't see myself adopting Spirit in favor of my
hand-carved, re2c-based parsers anytime soon. Although they most certainly take longer to develop,
they tend to be a bit more flexible, they are (at least to me) usually far easier to debug and,
probably the main selling point, it doesn't tie me down to a particular library or even programming
language.

And lex/yacc is truly a real pain in the neck.


Rui Maciel
 
R

Rui Maciel

If two seperate enums have mutually exclusive values you can define a
new enum and simply set the values of the superset enums to the values
of the oringal enums.

You can make you original enums have mutually exclusive values by
setting aside a range for each one. For example you can do the
following:

// starts at 0
enum FIRST
{
FIRST_A = 0,
FIRST_B
};

// starts at 1000
enum SECOND
{
SECOND_A = 1000,
SECOND_B
};

// superset enum
enum SUPERSET
{
SS_FIRST_A = FIRST_A,
SS_FIRST_B = FIRST_B,
SS_SECOND_A = SECOND_A,
SS_SECOND_B = SECOND_B
};

Thanks for the tip. I was exploring that idea before starting this thread but I couldn't find any
reference to any guarantee that it was possible to infer the largest value used by an enum. If
there was any guarantee on that then it would be possible to do something of this sort:

<code>
// starts at 0
enum FIRST
{
FIRST_A = 0,
FIRST_B,
FIRST_END
};

enum SECOND
{
SECOND_A = FIRST_END,
SECOND_B
};
</code>


This solution wouldn't earn any points on being pretty but it would do the job quite nicely.


Rui Maciel
 
F

Francesco S. Carta

Thanks for the tip. I was exploring that idea before starting this thread but I couldn't find any
reference to any guarantee that it was possible to infer the largest value used by an enum. If
there was any guarantee on that then it would be possible to do something of this sort:

<code>
// starts at 0
enum FIRST
{
FIRST_A = 0,
FIRST_B,
FIRST_END
};

enum SECOND
{
SECOND_A = FIRST_END,
SECOND_B
};
</code>


This solution wouldn't earn any points on being pretty but it would do the job quite nicely.

At least on my implementation you actually can do that, here are the
results:

FIRST_A == 0
FIRST_B == 1
SECOND_A == FIRST_END == 2
SECOND_B == 3

though, I don't know if it is guaranteed to work in the same exact way
along all implementations.
 
F

Francesco S. Carta

At least on my implementation you actually can do that, here are the
results:

FIRST_A == 0
FIRST_B == 1
SECOND_A == FIRST_END == 2
SECOND_B == 3

though, I don't know if it is guaranteed to work in the same exact way
along all implementations.

Actually, reading how enums work, I believe you are assured it will work
on any implementation - but no, I cannot prove it, I'd have to wade
through the standard and dissect the relative sections, something I
don't feel brave enough to do by now.

Not about the maximum used value, but about the valid range of an enum,
I've read on TC++PL 3rd edition that you can compute it exactly - but my
version is in Italian and I don't dare translating that part.

I think that the section cited in this thread is correct, though:
(the citation comes from a different book)

http://www.cplusplus.com/forum/beginner/25802/

I still believe you can do what you did above without worrying about the
range of potential values, though.

Hope that helps.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,146
Messages
2,570,831
Members
47,374
Latest member
anuragag27

Latest Threads

Top