我尝试在 flex 和 bison C 文件中编译 g++ 文件,但收到错误:“yylex”未在此范围内声明。与“yyerror”相同。
我尝试将这样的行放入词法分析器、解析器或 C++ 文件中,但没有成功。
extern "C" {
int yylex(void);
int yyerror(char *s);
}
编辑:
/* parser */
%{
#include <stdio.h>
%}
/* declare tokens */
%token NUMBER
%token ADD SUB MUL DIV ABS
%token EOL
%%
calclist: /* nothing */
| calclist exp EOL { printf("= %d\n", $1); }
;
exp: factor
| exp ADD factor { $$ = $1 + $3; }
| exp SUB factor { $$ = $1 - $3; }
;
factor: term
| factor MUL term { $$ = $1 * $3; }
| factor DIV term { $$ = $1 / $3; }
;
term: NUMBER
| ABS term { $$ = $2 >= 0? $2 : - $2; }
;
%%
int yyerror(char *s) {
fprintf(stderr, "error: %s\n", s);
return 1;
}
/* lexer */
%{
enum yytokentype {
NUMBER = 258,
ADD = 259,
SUB = 260,
MUL = 261,
DIV = 262,
ABS = 263,
EOL = 264
};
int yylval;
%}
%option nounput
%%
"+" { return ADD; }
"-" { return SUB; }
"*" { return MUL; }
"/" { return DIV; }
"|" { return ABS; }
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
\n { return EOL; }
[ \t] { /* ignore whitespace */ }
. { printf("Mystery character %c\n", *yytext); }
%%
C++ 源代码包含一个“执行”函数,我在其中调用 yyparse(),首先包括解析器生成的标头。
要编译 bison 生成的文件,您需要在 bison 源文件中声明 yylex:
最简单的方法是将以下内容添加到您的 .y 文件中: %{ int yylex(); %}
但是,如果您使用具有递归功能的解析器,或者启用了位置,则需要将其声明为 yylex 原型的一部分。请注意,当您组合多个解析器和词法分析器时(例如,当生成 C 语言编译器时,而不是将预处理器和代码解析器组合到单个程序中),这会变得更加复杂,因为每个配对的解析器和词法分析器对于要执行的操作有不同的想法。令牌类型是)。
这个问题的很多变体在已解决的主题c++扫描仪中提到了flex和bison对yylex和yytext的未定义引用
我用
int yylex();
解决了这个问题,在两个文件 extern
和 .y
中没有
.l