我正在尝试查明这些错误消息,但即使我移动代码时错误显示在同一行。
为什么我仍然得到“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);
}
答案 0 :(得分:1)
以下是产生double
到std::string*
错误的地方:
assignment : identifier '=' exp {$$ = vars[*$1] = $3; delete $1; }
assignment
的类型为<index>
,即std::string*
。 exp
的类型为<num>
,即double
。因此,在上面的操作中,$$
是std::string*
,而$3
是double
(就像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*
变量。较新的野牛版本可以避免警告。