Возвращение "неинтеров" из yylex - PullRequest
4 голосов
/ 26 сентября 2010

У меня есть сгенерированный сканер из flex, выход которого не используется yacc или bison.yylex () должен возвращать указатель на структуру памяти типа токена, а не int, указывающий тип токена.

// example definition from foo.l
[A-Za-z_][A-Za-z0-9_]* { return scanner_token(T_IDENTIFIER); }

// example implementation of scanner_token
token *scanner_token(name) {
    token *t = (token *)calloc(1, sizeof(token));
    t->name = name;
    t->lexeme = (char *)calloc(yyleng + 1, 1);
    if (t->lexeme == NULL) {
        perror_exit("calloc");
    }
    memmove(t->lexeme, yytext, yyleng);
    return t;
}

// example invocation of yylex
token *t;
t = (token *)yylex();

Конечно, компиляция предупреждает меня return возвращает целое число из указателя безприведение.

Я прочитал на страницах руководства по гибкому оборудованию, что YY_DECL контролирует, как объявляется процедура сканирования:

YY_DECL контролирует, как объявляется процедура сканирования,По умолчанию это «int yylex()» или, если используются прототипы, «int yylex(void)».Это определение можно изменить, переопределив макрос "YY_DECL".

Когда я пытаюсь переопределить YY_DECL, результирующий файл C не удается скомпилировать.

#undef YY_DECL
#define YY_DECL (token *)yylex()

Как правильно выполнить то, что я пытаюсь сделать?

Ответы [ 2 ]

8 голосов
/ 26 сентября 2010

Обычный синтаксис:

#define YY_DECL token *yylex(void)

Этот минимальный исходный файл Flex показывает, как:

%{
typedef struct token { int tok; } token;
#define YY_DECL token *yylex(void)
token t;
%}
%%
. { t.tok = 1; return &t; }
%%

Он компилируется для меня.

3 голосов
/ 26 сентября 2010

yylex должен возвращать int. Сохраните это поведение и оберните вызов в вспомогательную функцию. Помощник возвращает ваш токен. Не связывайтесь с YY_DECL.

[A-Za-z_][A-Za-z0-9_]* { return T_IDENTIFIER; }

token *scanner_token() {
    token *t;
    int name;
    if ((name = yylex()) == 0)
        return 0;
    else {
        t = (token *)calloc(1, sizeof(token));
        t->name = name;
        t->lexeme = (char *)calloc(yyleng + 1, 1);
        if (t->lexeme == NULL)
            perror_exit("calloc");
        memmove(t->lexeme, yytext, yyleng);
        return t;
    }
}

token *t = scanner_token();
...