无法查明"cannot convert 'double' to 'std::string*' in assignment" yyparse() 和 yylex() 错误的位置



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

另外为什么我仍然得到"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

计算

%{
#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;}

计算

%{
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 %fn", $2);}
        | line assignment CR    {;}
        | line print exp CR     {printf("Printing %fn", $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, "%sn", s);
} 

下面是一个会产生doublestd::string*错误的地方:

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

assignment的类型是<index>,即std::string*exp的类型是<num>,即double。所以在上面的动作中,$$是一个std::string*$3是一个doublevars[*$1]也是如此)。

我最好的猜测是你不打算<index>语义类型的assignment

至于yyerror没有在calc.l中定义的事实,这显然是正确的。 yyerrorcalc.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++抱怨野牛模板不是C++干净的,因为它将字符串文本(这是一个const char*)分配给没有强制转换的char*变量。较新的野牛版本会避免警告。

最新更新