gpt4 book ai didi

c++ - 在 Bison : Where to define the class? 中作为返回类型分类

转载 作者:行者123 更新时间:2023-11-30 01:16:42 25 4
gpt4 key购买 nike

我找到了三个教程,涵盖了使用 Bison 在 C++ 中编写解析器:here , here , 和 here .前两个不涉及如何使用类作为规则的返回类型。第三个确实涵盖了它,但似乎没有清楚地解释这些规定。

这是一个以这种方式使用类的简单 parser.yy 文件。

%{

#include <stdio.h>

extern FILE * yyin;
int yyerror(char *s)
{
fflush(stdout);
printf("error\n");
}

int yywrap(void) {
return 1;
}

int yyparse() { return 1; }

int main() {
yyparse();
return 1;
}

class myclass { int x; };

%}

%union {
int token;
myclass * mc;
}

%token <token> REGISTER
%type <mc> start_sym

%start start_sym

%%

start_sym :
REGISTER '+' { $$ = new myclass(); }
;

Bison 使用此输入运行时没有任何问题。我为 flex 定义了一个简单的输入来使用它。但是,当我尝试编译它时,出现错误:

$ g++ parser.tab.cc lex.yy.cc

In file included from lex.ll:11:0:
parser.yy:31:5: error: ‘myclass’ does not name a type
myclass * mc;
^

声明myclass的合适位置在哪里?

最佳答案

错误来自您的 lex 生成的文件,并且是您没有将您的类的定义放在 lex 生成的文件可以看到它的地方的结果。将定义放在一个单独的头文件中,并将该头文件同时包含在扫描器(flex)和解析器(bison)文件中是最简单的解决方案;此外,这是有道理的,因为可能还有其他编译单元(解析的使用者)也需要这些 header 。

如果您使用的是相对现代的 bison 版本,对于类型定义实际上只需要对扫描器和解析器可见而不需要其他组件的情况,可以让 bison 将定义插入到 header 中它通过将 %code requires block 放入您的序言中生成的文件:

%code requires {
class myclass {
// ...
};
}

(您也可以使用 %code provides block ,但通常您希望这些定义在定义语义类型 union 时可用,这是 %code 要求的位置。)

有关详细信息,请参阅 bison manual .

关于 extern "C" 问题,如果您在 bison 输入中包含 flex 生成的头文件,我会认为这是不必要的。您可能还想在 flex 输入中指定 %option noyywrap,除非您实际使用 yywrap-lfl 中包含的 yywrap 具有 "C" 链接,但据我所知,extern "C"yywrap 声明确实出现在 flex 生成的头文件中。

说了这么多,我需要承认我既不使用 bison 也不使用 flex 的 C++ API。我更喜欢只使用 C 接口(interface);可以使用 C++ 编译器(至少使用最新版本的 bison 和 flex 工具)干净地编译生成的文件,并且您可以毫无问题地在语义 union 中使用指向 C++ 对象的指针。

关于c++ - 在 Bison : Where to define the class? 中作为返回类型分类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25980281/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com