从yylex返回“non-int”

时间:2010-09-26 04:31:08

标签: c flex-lexer

我有一个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会在没有强制转换的情况下从指针生成整数。

我在flex手册页中读到YY_DECL控制如何声明扫描例程:

  

YY_DECL控制扫描方式   例程被宣布。默认情况下,它   是“int yylex()”,或者,如果   正在使用原型,“int yylex(void)”。这个定义可能是   通过重新定义“YY_DECL”而改变   宏。

当我尝试重新定义YY_DECL时,生成的C文件无法编译。

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

完成我想要的东西的正确方法是什么?

2 个答案:

答案 0 :(得分:8)

正常的语法是:

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

它为我编译。

答案 1 :(得分:3)

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();