我正在使用lex在编译器中进行独立研究。由于某种原因,我无法打印字符串标识符。除了IDENTIFIER之外,所有其他令牌都会打印lexemes。我想在我的.lex文件中可能是我的malloc。我希望有人找到我的错误。我已经包含了相关的代码,所以没有进一步的延迟:
scan.lex中的Malloc:
[a-zA-Z][a-zA-Z0-9]* {yylval.string_value.line_number = current_line_number;
yylval.string_value.value = malloc(sizeof(char) *(strlen(yytext)+1));
return IDENTIFIER;}
token.h中的Union / Struct:
typedef union {
struct {
char * value;
int line_number;
} string_value;
struct {
int value;
int line_number;
} integer_value;
struct {
double value_1;
int line_number;
} real_value;
int line_number;
} YYSTYPE;
YYSTYPE yylval;
main.c中的相关print语句:
case IDENTIFIER:
printf("Token: %s Line Number: %d Lexeme: %c Token Number: %d\n", tokenName(token),
yylval.string_value.line_number,
yylval.string_value.value, token);
break;
我尝试过使用
%s
而不是
%c
用于printf的格式化,当然没有改变。我在.lex文件和main.c中引用了token.h文件。我认为可能是我使用malloc虽然我没有得到任何编译错误。我将不胜感激任何帮助和感谢。
答案 0 :(得分:2)
在标识符的扫描仪操作中,您可以:
yylval.string_value.line_number = current_line_number;
yylval.string_value.value = malloc(sizeof(char) *(strlen(yytext)+1));
return IDENTIFIER;
这些都不会将yytext
的值实际插入yylval
。
就个人而言,我会这样做:
yylval.string_value.line_number = current_line_number;
yylval.string_value.value = strdup(yytext);
return IDENTIFIER;
strdup
不是标准C库的一部分,但它在Posix中,它通常可用并且非常方便。否则,您可以利用yyleng
已设置为令牌长度的事实:
yylval.string_value.line_number = current_line_number;
char* id = malloc(yyleng + 1);
strncpy(id, yytext, yyleng);
yylval.string_value.value = id;
return IDENTIFIER;
在任何一种情况下,请不要忘记您需要free()
复制的标识符。
顺便说一下,您可能需要考虑使用flex的内置yylineno
功能来计算行数。