无法精确定位“无法在赋值时将'double'转换为'std :: string *'”yyparse()和yylex()错误

时间:2014-11-18 01:09:19

标签: c++ bison yacc flex-lexer lex

我正在尝试查明这些错误消息,但即使我移动代码时错误显示在同一行。

为什么我仍然得到“calc.y:在函数'int yyparse()':”和“calc.l:在函数'int yylex()'中:”即使我在我的calc.y中有它

错误消息

flex calc.l
bison -d calc.y
g++ -o calc calc.tab.c lex.yy.c
calc.y: In function 'int yyparse()':
calc.y:35: error: cannot convert 'double' to 'std::string*' in assignment
calc.tab.c:1490: warning: deprecated conversion from string constant to 'char*'
calc.tab.c:1633: warning: deprecated conversion from string constant to 'char*'
calc.l: In function 'int yylex()':
calc.l:17: error: 'yyerror' was not declared in this scope

calc.l

%{
#include <cstdlib>
#include <string>
#include <string.h>
#include "calc.tab.h"


%}
%%
"print"                     {return print;}
"exit"                      {return exit_command;}
[0-9]+                      {yylval.num = atof(yytext); return number;}
[_[:alpha:]][_[:alnum:]]*   {yylval.index = new std::string(yytext); return identifier; }
[ \t]                       ;
[\n]                        {return(CR);}
[-()+*/;=]                  {return yytext[0];}
.                           {ECHO; yyerror ("unexpected character");}

%%
int yywrap (void) {return 1;}

calc.y

%{
void yyerror (char *s);
int yylex(void);
#include <stdio.h>     /* C declarations used in actions */
#include <stdlib.h>
#include <string>
#include <string.h>
#include <map>

static std::map<std::string, double> vars;
%}

%union {double num; std::string *index;}         /* Yacc definitions */
%start line
%token print
%token CR
%token exit_command
%token <num> number
%token <index> identifier
%type <num> line exp term 
%type <index> assignment

%%

/* descriptions of expected inputs     corresponding actions */

line    : assignment CR         {;}
        | exit_command CR       {exit(EXIT_SUCCESS);}
        | print exp CR          {printf("Printing %f\n", $2);}
        | line assignment CR    {;}
        | line print exp CR     {printf("Printing %f\n", $3);}
        | line exit_command CR  {exit(EXIT_SUCCESS);}
        ;

assignment : identifier '=' exp  {$$ = vars[*$1] = $3; delete $1; }
            ;
exp     : term                  {$$ = $1;}
        | exp '+' term          {$$ = $1 + $3;}
        | exp '-' term          {$$ = $1 - $3;}
        | exp '*' term          {$$ = $1 * $3;}
        | exp '/' term          {$$ = $1 / $3;}
        | '(' exp ')'           {$$ = $2;}
        ;
term    : number                {$$ = $1;}
        | identifier            {$$ = vars[*$1]; delete $1; } 
        ;

%%                    

int main (void) {


    return yyparse();
}

extern int yyparse();

void yyerror (char *s)
 {
    extern int yylineno;  // defined and maintained in lex
    extern char *yytext;  // defined and maintained in lex
    fprintf (stderr, "%s\n", s);
} 

1 个答案:

答案 0 :(得分:1)

以下是产生doublestd::string*错误的地方:

assignment : identifier '=' exp  {$$ = vars[*$1] = $3; delete $1; }

assignment的类型为<index>,即std::string*exp的类型为<num>,即double。因此,在上面的操作中,$$std::string*,而$3double(就像vars[*$1])。

我最好的猜测是,您并不打算assignment的语义类型为<index>

至于yyerror中没有定义calc.l的事实,这显然是正确的。 yyerror中定义了calc.y,声明也在calc.y中。由(f)lex和yacc / bison生成的C程序是不同的程序,它们是独立编译的,因此在yacc / bison生成的程序中声明yyerror的事实并不能使它的声明可见。 (f)lex生成的程序。如果你需要从(f)lex动作中使用它,你需要在两个文件中声明它。

这些警告:

calc.tab.c:1490: warning: deprecated conversion from string constant to 'char*'

建议您找到bison的更新版本。如果这是不可能的,你可以忽略它们; g++抱怨bison模板不是C ++ - 干净,因为它在没有强制转换的情况下将字符串文字(const char*)分配给char*变量。较新的野牛版本可以避免警告。