2016-03-28 3 views
0

Проблема: У нас это следующее перечисление декларации:получить значение перечисления из входной строки в C

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

Теперь мы получаем строку, значение которой может быть «ID», «SEMI», «ЧИСЛО» и т.д. и мы должны сохранить целое число, соответствующее этой строке в enum yytokentype, в отдельном целочисленном массиве. Я не уверен, как это сделать на C. Были некоторые ответы для C#, но мне требуется строго C здесь. ТИА.

+0

Вы пытались использовать двумерный массив структур? Пример (псевдокод) 'struct {char * item; int val; } Токен; Token tokens [] = {"bla", 6}; ' – Joel

+0

Мы можем это сделать, но этот enum yytokentype имеет 26 записей, и это будет много печатать (поскольку нам нужно будет установить строку и нет для каждой записи в enum yytokentype). Это, конечно, будет последним вариантом. Мне просто интересно, есть ли для этого более короткий путь. – shane

+0

использование петель. Создайте массив строк, передайте его структуре. – Joel

ответ

2

Итак, вы хотите отобразить строку в значение перечисления? Тогда простой массив структур с помощью строки и перечисления будет делать хорошо:

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

Тогда, если у вас есть строка "ID" просто перебрать массив mapping, чтобы найти запись с одной и той же строкой, и у вас есть значение.

0

Поскольку вы, кажется, с помощью yacc -style генератора парсеров, обычный способ преобразования входных лексем лексем номера заключается в том, что пару с лексическим сканером, созданный через lex или произведение, так, например, как flex. Такие сканеры используют регулярные выражения для распознавания токенов и предоставляют вам возможность вставлять код для сообщения правильных номеров токенов (и токенов) в парсер.

1

Вы можете избежать некоторых типизации, используя макросы препроцессора для #stringize перечисления.

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

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

Это все еще требует сохранения таблицы в синхронизации с перечислением. Если вы хотите только набирать перечисление один раз, вы можете стать еще более сложным с препроцессором. Этот метод составляет список TOKEN элементов, затем использует его дважды, с другим определением макроса TOKEN для каждого из них.

#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 
}; 

Взвесьте очень внимательно кратковременную пользу сохранения некоторой дополнительную типизации против вероятной путаницы обслуживания программиста в следующем году, который очень хорошо может быть вам.

Смежные вопросы