0

Problem : We have this following enum declaration :

enum yytokentype
  {
    ID = 258,
    SEMI = 259,
    NUMBER = 260,
    DECIMAL = 261,
    SENTENCE = 262,
    LETTER = 263,
    ASSIGN = 264,
    //etc... }

Now we get a string whose value can be "ID", "SEMI", "NUMBER" etc.. and we have to store the integer corresponding to that string in enum yytokentype in a separate integer array.I am not sure how to do this in C. There were some answers for C# but I require strictly C here. TIA.

shane
  • 449
  • 4
  • 17
  • Did you try bidimensional struct array? Example (pseudo code)` struct { char *item; int val; } Token; Token tokens[] = {"bla", 6 };` – Joel Mar 28 '16 at 17:48
  • We can do that, but this enum yytokentype has 26 entries and that will be a lot of typing(since we will have to set string and no. for each entry in enum yytokentype). This , of course, will be the last option. I was just wondering if there is a shorter way for it. – shane Mar 28 '16 at 17:51
  • use loops. Create the string array, pass it to the struct. – Joel Mar 28 '16 at 17:53
  • Also see http://stackoverflow.com/q/147267/2410359 – chux - Reinstate Monica Mar 28 '16 at 18:31

3 Answers3

3

So you want to map a string to an enumeration value? Then a simple array of structures with a string and the enumeration will do fine:

struct map_structure
{
    const char *name;
    enum yytokentype value;
} mapping[] = {
    { "ID", ID },
    { "SEMI", SEMI },
    .
    .
    .
};

Then if you have the string "ID" just iterate over the array mapping to find an entry with the same string and you have your value.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

You can avoid some typing by using preprocessor macros to #stringize the enumeration.

#define TOKEN(val) {#val, val}

struct ttable {
   const char* name;
   enum yytokentype value;
};
stuct ttable TheTable = {
  TOKEN(ID),
  TOKEN(SEMI),
  ...
} 

This still requires keeping the table in sync with the enumeration. If you want to only type the enumeration once, you can get even more tricky with the preprocessor. This technique makes a list of TOKEN items, then uses it twice, with a different definition of the TOKEN macro for each one.

#define TOKENSET   \
    TOKEN(ID,256), \
    TOKEN(SEMI,257)

#define TOKEN(n,v) n = v
enum tokentype {
    TOKENSET
};

#undef TOKEN
#define TOKEN(n,v) {#n, n}

struct table{
    const char* name;
    enum tokentype val;
} TheTable[] = {
    TOKENSET
};

Weigh very carefully the short term benefit of saving some extra typing vs. the likely confusion of next year's maintenance programmer, who may very well be you.

AShelly
  • 34,686
  • 15
  • 91
  • 152
0

Inasmuch as you appear to be using a yacc-style parser generator, the conventional way to convert input tokens to token numbers is to pair that with a lexical scanner created via lex or a work-alike such as flex. Such scanners use regular expressions to recognize tokens, and provide for you to insert code to report the correct token numbers (and token values) to the parser.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157