Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::Bison中的共享\u ptr导致成员错误_C++_Bison_Smart Pointers_Flex Lexer - Fatal编程技术网

C++ std::Bison中的共享\u ptr导致成员错误

C++ std::Bison中的共享\u ptr导致成员错误,c++,bison,smart-pointers,flex-lexer,C++,Bison,Smart Pointers,Flex Lexer,我试图通过使用std::shared\u ptr使bison的内存效率更高。我不想使用原始指针。我使用一个节点系统作为解析树,所以我将YYTYPE定义为std::shared_ptr。在使用一些简单的语法运行它之后,我得到了编译错误: C2039“块节点”:不是“std::shared\u ptr”的成员 p>我发现这很奇怪,因为C++中运行的等效代码工作得很好, std::shared_ptr test=std::make_shared 我错过了什么 需要 %code requires {

我试图通过使用std::shared\u ptr使bison的内存效率更高。我不想使用原始指针。我使用一个节点系统作为解析树,所以我将YYTYPE定义为std::shared_ptr。在使用一些简单的语法运行它之后,我得到了编译错误:

C2039“块节点”:不是“std::shared\u ptr”的成员

<> p>我发现这很奇怪,因为C++中运行的等效代码工作得很好,

std::shared_ptr test=std::make_shared

我错过了什么

需要

%code requires {
    typedef void* yyscan_t;
    #include "node.h"
    #include <memory>
    #define YYSTYPE std::shared_ptr<Node>
}
联合

文法

%start program

%%

program : input { *result = $1; } // <- error here
        ;

input: '\n'      { $$ = std::make_shared<BlockNode>();} // <- error here
     ;

%%

Node.h

class Node /*: public std::enable_shared_from_this<Node>*/ {
public:
    std::string myString;
    Node() {}
    ~Node() { std::cout << "destoryed" << myString << std::endl; }
};

class BlockNode : public  Node {
public:
    BlockNode() {
        myString = "block node";
        std::cout << "created" << myString << std::endl;
    }

};


你应该知道的第一件事是这个设计不能工作。如果您为bison使用默认的C API,则不能使用不可复制的语义类型,因为如果需要重新分配堆栈,bison将按字节复制它的堆栈,我相信还有其他问题与在不调用析构函数的情况下覆盖字节有关。如果你想使用共享指针,你应该研究如何使用C++ API,我认为它已经达到某种程度的成熟,虽然我还没有使用它。你可能会对结果更满意

不管怎样,您的代码还有一些其他问题

首先,现代bison应用程序不应该定义YYSTYPE,甚至不应该在%代码块中定义。你应该改用

 %define api.value.type { /* SemanticType */ }
如果您这样做了,bison会告诉您不能同时使用%union声明和固定的api.value.type。如果语义类型是并集,那么它就是并集。它也不能是共享的\u指针。既然您似乎希望它是一个成员都是共享指针的联合体,那么它就是一个联合体,您不希望以其他方式定义它

如果您使用define YYSTYPE,并且还使用了%union,那么您将发现%union永远不会被应用union将YYSTYPE的默认定义插入为union YYSTYPE,但YYSTYPE的显式定义将覆盖该定义。但是bison不知道您已经这样做了-直到C编译器实际编译生成的代码才变得明显-因此它使用您在%类型声明中提供的标记重写语义值引用。换句话说,当您说%type input时,bison会通过添加字段引用自动将引用输入非终端实例的任何引用更改为$n,就像您编写了$n.blockNode一样,当然,您不能这样做,因为bison已经添加了字段引用。但是,定义重写YySype不是一个联合,它是一个SyrdPyPosits,并且SydDyPosil没有块节点成员,正如C++编译器错误消息所指示的那样。

类似地,在输入规则中,%类型声明导致bison发出代码,该代码将分配给不存在的blockNode成员

为了说明我的第一点——您不能将shared_指针用作C代码生成器的语义类型或联合成员——我通过应用上面的建议修复了您的代码,即删除define YYSTYPE,并进行了或多或少的更改,以避免其他bison和编译器错误,导致以下错误:

文件tom.yy
你应该知道的第一件事是这个设计不能工作。如果您为bison使用默认的C API,则不能使用不可复制的语义类型,因为如果需要重新分配堆栈,bison将按字节复制它的堆栈,我相信还有其他问题与在不调用析构函数的情况下覆盖字节有关。如果你想使用共享指针,你应该研究如何使用C++ API,我认为它已经达到某种程度的成熟,虽然我还没有使用它。你可能会对结果更满意

不管怎样,您的代码还有一些其他问题

首先,现代bison应用程序不应该定义YYSTYPE,甚至不应该在%代码块中定义。你应该改用

 %define api.value.type { /* SemanticType */ }
如果您这样做了,bison会告诉您不能同时使用%union声明和固定的api.value.type。如果语义类型是并集,那么它就是并集。它也不能是共享的\u指针。既然您似乎希望它是一个成员都是共享指针的联合体,那么它就是一个联合体,您不希望以其他方式定义它

如果您使用define YYSTYPE,并且还使用了%union,那么您将发现%union永远不会被应用union将YYSTYPE的默认定义插入为union YYSTYPE,但YYSTYPE的显式定义将覆盖该定义。但是bison不知道您已经这样做了-直到C编译器实际编译生成的代码才变得明显-因此它使用您在%类型声明中提供的标记重写语义值引用。换句话说,当您说%type input时,bison将通过添加字段引用自动将任何引用更改为$n,其中引用的是输入非终端的实例,就像您编写了$n.blockNode一样,当然,您不能这样做,因为 e bison已经添加了字段引用。但是,定义重写YySype不是一个联合,它是一个SyrdPyPosits,并且SydDyPosil没有块节点成员,正如C++编译器错误消息所指示的那样。

类似地,在输入规则中,%类型声明导致bison发出代码,该代码将分配给不存在的blockNode成员

为了说明我的第一点——您不能将shared_指针用作C代码生成器的语义类型或联合成员——我通过应用上面的建议修复了您的代码,即删除define YYSTYPE,并进行了或多或少的更改,以避免其他bison和编译器错误,导致以下错误:

文件tom.yy

这是C++中的联合的限制,一个联合的成员不能有构造函数。

union {
    std::shared_ptr<BlockNode> blockNode; //not allowed
    std::shared_ptr<Node> *testNode;      //allowed
}

这是C++中的联合的限制,一个联合的成员不能有构造函数。

union {
    std::shared_ptr<BlockNode> blockNode; //not allowed
    std::shared_ptr<Node> *testNode;      //allowed
}

我建议您查看生成的源,无论发生什么,都可能在那里完全清楚。需要注意的一点是,我不相信我曾经同时使用过重新定义的YYSTYPE和%union。我建议您查看生成的源代码,无论发生了什么,都可能在那里完全清楚。需要注意的一点是,我不相信我曾经同时使用过重新定义的YYSTYPE和%union。再次感谢您的伟大回答!是的,你所说的很有道理,我部分地遵循了我发现的一些非常古老的示例。因此,总结一下,我不能将%union与shared_ptr一起使用,因为它不是传统的语义类型,也不能将%define与shared_ptr一起使用,因为它没有成员,因此无法与派生节点类一起使用。也可以选择使用向下投射。在这种情况下,你认为管理记忆的最佳方法是什么?@Tom:这并不是说它不是一种传统的语义类型。这是因为C++不允许SyrdypTr成为联盟的成员。而且C++不允许与不具有可构造性的成员的默认构造。这和野牛没什么关系。您可以将%define与shared_ptr一起使用,但是您只能使用一种类型的共享指针no union来允许您使用多个指针,如果堆栈被重新分配,那么事情就会分崩离析;也就是说,数据类型在C中会有自己的感觉。如果你想释放C++超级大国,你需要使用C++ API。详见野牛手册。有很多细节。这是一个学习曲线,但是如果你觉得在C++中更自在,显然使用一个能生成真实C++的分析器生成器,而不是仅仅伪装成C++。野牛就是这样一个发电机,但你需要问你想要什么。你问我的个人意见,这是你在StackOverflow中必须小心的事情,在StackOverflow中,意见被认为是不允许的。但是,碰巧的是,我有一个。我会使用一个普通的C风格的指针,因为你正在构建一棵树,而一个共享的_指针将是巨大的过度使用。只要AST是一棵树,跟踪对象所有权就很简单。如果您以后想要执行公共子表达式消除或类似操作,那么您将需要一些其他内存管理机制。这可能涉及到共享指针。但是我,我会把这个留到以后,以防以后永远不会。再次感谢你的回答!是的,你所说的很有道理,我部分地遵循了我发现的一些非常古老的示例。因此,总结一下,我不能将%union与shared_ptr一起使用,因为它不是传统的语义类型,也不能将%define与shared_ptr一起使用,因为它没有成员,因此无法与派生节点类一起使用。也可以选择使用向下投射。在这种情况下,你认为管理记忆的最佳方法是什么?@Tom:这并不是说它不是一种传统的语义类型。这是因为C++不允许SyrdypTr成为联盟的成员。而且C++不允许与不具有可构造性的成员的默认构造。这和野牛没什么关系。您可以将%define与shared_ptr一起使用,但是您只能使用一种类型的共享指针no union来允许您使用多个指针,如果堆栈被重新分配,那么事情就会分崩离析;也就是说,数据类型在C中会有自己的感觉。如果你想释放C++超级大国,你需要使用C++ API。详见野牛手册。有很多细节。这是一个学习曲线,但是如果你觉得在C++中更自在,显然使用一个能生成真实C++的分析器生成器,而不是仅仅伪装成C++。野牛就是这样一个发电机,但你需要问你想要什么。你问我的个人意见,这是你必须小心的 我在StackOverflow里闲逛,那里不允许发表意见。但是,碰巧的是,我有一个。我会使用一个普通的C风格的指针,因为你正在构建一棵树,而一个共享的_指针将是巨大的过度使用。只要AST是一棵树,跟踪对象所有权就很简单。如果您以后想要执行公共子表达式消除或类似操作,那么您将需要一些其他内存管理机制。这可能涉及到共享指针。但是我,我会把它留到以后,以防以后永远不会。
$ bison -o tom.cc tom.yy
$ gcc -Wall -o tom tom.cc -ly
tom.cc:956:9: error: use of deleted function ‘YYSTYPE::YYSTYPE()’
 YYSTYPE yylval;
         ^~~~~~
tom.cc:104:7: note: ‘YYSTYPE::YYSTYPE()’ is implicitly deleted because the default definition would be ill-formed:
 union YYSTYPE
       ^~~~~~~
tom.yy:15:32: error: union member ‘YYSTYPE::blockNode’ with non-trivial ‘constexpr std::shared_ptr<_Tp>::shared_ptr() [with _Tp = BlockNode]’
     std::shared_ptr<BlockNode> blockNode;
                                ^~~~~~~~~
tom.yy:16:27: error: union member ‘YYSTYPE::testNode’ with non-trivial ‘constexpr std::shared_ptr<_Tp>::shared_ptr() [with _Tp = Node]’
     std::shared_ptr<Node> testNode;
                           ^~~~~~~~
tom.cc: In function ‘int yyparse()’:
tom.cc:985:30: error: use of deleted function ‘YYSTYPE::YYSTYPE()’
     YYSTYPE yyvsa[YYINITDEPTH];
                              ^
union {
    std::shared_ptr<BlockNode> blockNode; //not allowed
    std::shared_ptr<Node> *testNode;      //allowed
}
union {
    Node *testNode;      
}