如何在flex和bison中获取令牌的字符串值?

use*_*632 4 c bison flex-lexer

我的.lex文件中有这个令牌:

[a-zA-Z0-9]+    { yylval = yytext; return ALPHANUM; }
Run Code Online (Sandbox Code Playgroud)

和我的.y文件中的代码:

Sentence: "Sphere(" ALPHANUM ")."
{
FILE* file = fopen("C:/test.txt", "a+");
char st1[] = "polySphere -name ";
strcat(st1, $2);
strcat(st1, ";");
fprintf(file,"%s", st1);
fclose(file);
}
Run Code Online (Sandbox Code Playgroud)

我尝试编译时遇到此错误:

警告:传递'strcat'的参数2使得指针来自整数而没有强制转换

所以2美元是一个int,我怎么把它变成一个字符串?

例如:"Sphere(worldGlobe)." 我希望$ 2在这里有字符串值worldGlobe.

谢谢你的帮助

Aym*_*dou 7

在没有%union声明的情况下,bison定义YYSTYPE为int,因此所有符号值都是整数.事实上,你有一些解决这个问题的方法:

1)yylval | union解决方案(推荐):
您可能知道yylval是词法分析器用来存储yytext变量(yylval = yytext;)的全局变量,因此您应该告诉词法分析器您要存储哪些类型.您可以简单地将此行添加到你的YACC语法的标题:

#define YYSTYPE char *
Run Code Online (Sandbox Code Playgroud)

你将在这里只存储字符串值.

顺便说一下,如果你想存储不同的类型,你应该在你的yacc文件中指定:

%union {
    char *a;
    double d;
    int fn;
}
Run Code Online (Sandbox Code Playgroud)

然后在你的lex中你会有

[a-zA-Z0-9]+    { **yylval.a** = yytext; return ALPHANUM; }
Run Code Online (Sandbox Code Playgroud)

2)使用yytext:

建议:对于yacc i中规则之后的回调,个人更喜欢使用函数.不是你做的整个代码:)

这个解决方案非常简单.
Sentence: "Sphere("{callback_your_function(yytext);} ALPHANUM ")."

这里的yytext将具有您的ALPHANUM标记的值,因为它是下一个标记.

  • 我会小心地将原始yytext指针粘贴到yylval中.下次你拿东西时,缓冲区会被覆盖.如果你有一个解析器可以将几个这样的标记收集到一个规则中并且你同时用$ 1,$ 2引用它们,那么这不是一个合适的方法.如果你只是在一个循环中调用yylex()并逐个处理标记,这可能没问题. (11认同)