我在编译器中使用lex进行独立研究。由于某些原因,我无法打印字符串标识符。除了IDENTIFIER之外,所有其他令牌的字元都打印出来。我想可能是我的。lex文件中的malloc。我希望有人能发现我的错误。我已经包含了相关的代码,所以没有进一步的延迟:
Malloc在scanner.lex:
[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;}
Union/Struct in token.h:
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:
相关打印语句 case IDENTIFIER:
printf("Token: %s Line Number: %d Lexeme: %c Token Number: %dn", tokenName(token),
yylval.string_value.line_number,
yylval.string_value.value, token);
break;
我尝试的是使用
%s
不是%c
来设置printf的格式,当然这并没有改变什么。我确实在.lex文件和main.c中引用了token.h文件。我认为这可能是我使用malloc,虽然我没有得到任何编译错误。
在标识符的扫描器操作中,您可以:
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
特性来计算行数。