我正在尝试查明这些错误消息,但即使我移动代码,错误也会显示在同一行。
另外为什么我仍然得到"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);
}
下面是一个会产生double
到std::string*
错误的地方:
assignment : identifier '=' exp {$$ = vars[*$1] = $3; delete $1; }
assignment
的类型是<index>
,即std::string*
。exp
的类型是<num>
,即double
。所以在上面的动作中,$$
是一个std::string*
,$3
是一个double
(vars[*$1]
也是如此)。
我最好的猜测是你不打算<index>
语义类型的assignment
。
至于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++
抱怨野牛模板不是C++干净的,因为它将字符串文本(这是一个const char*
)分配给没有强制转换的char*
变量。较新的野牛版本会避免警告。