开发者

Returning "non-ints" from yylex

开发者 https://www.devze.com 2023-01-17 09:52 出处:网络
I have a generated scanner from flex which the output from is not consumed by yacc or bison. yylex() needs to returns a pointer to a token-like structure memory instead of an int indicating the token-

I have a generated scanner from flex which the output from is not consumed by yacc or bison. yylex() needs to returns a pointer to a token-like structure memory instead of an int indicating the token-type.

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

Of course, the compilation warns me return makes integer from pointer without a cast.

I read in the flex man pages that YY_DECL controls how the scanning routine is declared:

YY_DECL controls how the scanning routine is declared. By default, it 开发者_如何转开发 is "int yylex()", or, if prototypes are being used, "int yylex(void)". This definition may be changed by redefining the "YY_DECL" macro.

When I try re-defining YY_DECL, the resulting C file fails to compile.

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

What is the proper way to accomplish what I am trying to?


The normal syntax would be:

#define YY_DECL token *yylex(void)

This minimal Flex source file shows how:

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

It compiles for me.


yylex should return an int. Keep this behavior, and wrap a call to it in a helper function. The helper returns your token. Don't mess with 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();
0

精彩评论

暂无评论...
验证码 换一张
取 消