1

我正在使用以下 lex 文件将数字转换为标记。但是,该程序无法正确解析浮点数。为了调试,我添加了 printf 语句,它们表明 strtof 函数无法正确解析数字。因此,给我输入 4.2 给我输出 0。

%{
#include <stdlib.h>
void yyerror(char *);
#include "y.tab.h"
char *p = NULL;
%}

%%

[0-9]+\.[0-9]+  {
            printf("%s", yytext);
            yylval = strtof(yytext, &p);
            printf("%f has been read\n", yylval);
            return FLOAT;   
        }
[0-9]+      {       yylval = atoi(yytext);
            printf("%d (int) has been read\n", yylval); 
                return INTEGER;
        }

[-+*/\n]    {   printf("%s has been read", yytext);
            return *yytext;
        }

[ \t]       ;   /* skip whitespace */
.               {
            printf("Invalid character %s", yytext);
            yyerror("invalid character");
        }
%%

int yywrap(void) {
return 1;
}

任何想法上面代码中的问题在哪里?我使用了具有相同输入的 strtof 函数(在 lex 之外),它似乎工作得很好。

谢谢

4

1 回答 1

1

为了调试,我添加了 printf 语句,它们表明 strtof 函数无法正确解析数字。

可悲的是没有。这些printf语句表明,yylval如果解释为浮点数,则使用 format 打印为 0 %f。它没有说明strtof.

独立于lex,以下两个语句不能有意义地出现在C程序的同一范围内:

printf("%f has been read\n", yylval);

printf("%d (int) has been read\n", yylval); 

yylval是 anint或 a double,或两者都不是,但不能两者兼有。请注意,格式printf相当于一个承诺:如果你使用%f,你承诺printf你会传递一个double. 它无法验证这一点,因此它会接受你的话并将它得到的任何参数解释为double. 如果你撒谎printf,你将得到无意义的输出。如果您以合理的警告级别(-Wallon gccclang)编译程序,编译器会警告您明显的违规行为。我强烈建议您这样做。

请注意,默认情况下yylvalint. 如果你没有做任何事情来改变它,那么这就是你所拥有的。

于 2012-12-10T00:45:10.957 回答