语义动作在boost :: spirit解析中多次运行

时间:2016-06-19 21:20:13

标签: c++ boost boost-spirit boost-spirit-qi

我正在尝试使用语义规则创建AST,同时使用boost :: spirit进行语法分析。 AST必须仅为输入的一部分构建,输入的另一部分应该在没有sintax树的情况下进行解析。

例如,对于这样的输入字符串:“self.usedFoo(Bar).filter( self.baz> baz )”或“self.Foo.filter( true )“AST应该只为大胆的部分构建。

并且存在一个问题:解析器运行多次,解析语法并调用语义操作(实例化AST节点)也是多次,所以我的内存泄漏很可怕。

简化的源代码:

语法:

line = stmt | stmt >> "filter.(" >> filter >> ')';
filter %= (filterterm)
filterterm %= (filterfactor)
filterfactor = value [phoenix::bind(&ValueFilterSemanticNode::Instantiate, qi::_val, qi::_1)];

实例化节点:

  static void ValueFilterSemanticNode::Instantiate(QVariant &res, QVariant &value)
    {
        qDebug() << "   Creating new Value Node...";
        ValueFilterSemanticNode *n = new ValueFilterSemanticNode();
        qDebug() << "   " << n;

        n->value = QVariant(value.toInt());
        res = QVariant::fromValue(n);
    }

输入:

self.filter(1)

调试:

   Creating new Value Node...
    0x22fdfd0
   Creating new Value Node...
    0x22fe030
   Creating new Value Node...
    0x22fde50
   [...many many lines...]
   Creating new Value Node...
    0x22fe238
   Creating new Value Node...
    0x22fe218
Running Filter test
       Value node running... 0x22fe218
Check result =  QVariant(int, 1)

因此,正如您所看到的,节点实例化的次数过多会导致内存泄漏。

1 个答案:

答案 0 :(得分:1)

即使稍后有回溯,语义动作也会触发。

解析器表达式可能会抛出。

仅凭这些原因,在语义操作中进行动态分配并不是一个好主意。如果需要,请使用智能指针(尽管这仍然效率低下)。