我在 C++ 中有一个手写的解析器,其中包含一个next_token()
方法,我想在里面使用它yylex()
(我已经用 Bison 的 C API 正确地做到了这一点,但想使用动态类型,所以转移到了 C++)。我阅读了文档的这些部分,阅读了示例并尝试了两个现有签名,但仍然无法正确执行...
解析器.yy:
%require "3.2"
%language "c++"
%define api.value.type variant
%define api.token.constructor
%define parse.assert
%code requires
{
#include <iostream>
#include <string>
}
%code{
yy::parser::symbol_type yy::parser::yylex();
void yy::parser::yyerror(const char *error);
}
%token VAR COL ITYPE
%token IDENTIFIER
%token INTEGER
%token EOL
%type <std::string> type PrimitiveType IDENTIFIER
%type <int> INTEGER
%%
program:
| program EOL
| program SimpleDeclaration { }
;
SimpleDeclaration: VariableDeclaration
;
VariableDeclaration: VAR IDENTIFIER COL type {std::cout<<"defined variable " << $2 << " with type " << $4 << std::endl; }
type: IDENTIFIER
| PrimitiveType
;
PrimitiveType: ITYPE { $$ = "int"; }
;
%%
void yy::parser::yyerror(const std::string& m)
{
std::cout << "syntax error" << std::endl;
}
// also 'yy::parser::symbol_type yy::parser::yylex(semantic_type* yylval)' does the same
int yy::parser::yylex(semantic_type* yylval)
{
return 0; // just returning a zero for now
}
int main()
{
yy::parser p;
return 0;
}
错误:
bison -d parser.ypp
g++ -std=c++17 -o foobar parser.tab.cpp
parser.ypp:14:29: error: no declaration matches ‘yy::parser::symbol_type yy::parser::yylex()’
14 | yy::parser::symbol_type yy::parser::yylex();
| ^~
parser.ypp:14:29: note: no functions named ‘yy::parser::symbol_type yy::parser::yylex()’
In file included from parser.tab.cpp:41:
parser.tab.hpp:193:9: note: ‘class yy::parser’ defined here
193 | class parser
| ^~~~~~
parser.ypp:15:10: error: no declaration matches ‘void yy::parser::yyerror(const char*)’
15 | void yy::parser::yyerror(const char *error);
| ^~
parser.ypp:15:10: note: no functions named ‘void yy::parser::yyerror(const char*)’
In file included from parser.tab.cpp:41:
parser.tab.hpp:193:9: note: ‘class yy::parser’ defined here
193 | class parser
| ^~~~~~
parser.tab.cpp: In member function ‘virtual int yy::parser::parse()’:
parser.tab.cpp:453:38: error: ‘yylex’ was not declared in this scope; did you mean ‘yylen’?
453 | symbol_type yylookahead (yylex ());
| ^~~~~
| yylen
parser.ypp: At global scope:
parser.ypp:45:6: error: no declaration matches ‘void yy::parser::yyerror(const string&)’
45 | void yy::parser::yyerror(const std::string& m)
| ^~
parser.ypp:45:6: note: no functions named ‘void yy::parser::yyerror(const string&)’
In file included from parser.tab.cpp:41:
parser.tab.hpp:193:9: note: ‘class yy::parser’ defined here
193 | class parser
| ^~~~~~
parser.ypp:50:5: error: no declaration matches ‘int yy::parser::yylex(yy::parser::semantic_type*)’
50 | int yy::parser::yylex(semantic_type* yylval)
| ^~
parser.ypp:50:5: note: no functions named ‘int yy::parser::yylex(yy::parser::semantic_type*)’
In file included from parser.tab.cpp:41:
parser.tab.hpp:193:9: note: ‘class yy::parser’ defined here
193 | class parser
| ^~~~~~
我也觉得很奇怪,即使没有覆盖,它似乎yylex
也在这里使用(即使我不尝试覆盖也会导致错误出现):
parser.tab.cpp: In member function ‘virtual int yy::parser::parse()’:
parser.tab.cpp:453:38: error: ‘yylex’ was not declared in this scope; did you mean ‘yylen’?
453 | symbol_type yylookahead (yylex ());
| ^~~~~
| yylen
我在这里做错了什么?提前致谢