【问题标题】:Semantic actions runs multiple times in boost::spirit parsing语义动作在 boost::spirit 解析中运行多次
【发布时间】:2016-06-19 21:20:12
【问题描述】:

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

例如,对于这样的输入字符串:“self.usedFoo(Bar).filter(self.baz > baz)”或“self.Foo.filter(true >)" AST 应该只用于粗体部分。

还有一个问题:解析器运行多次解析语法并调用语义操作(instatntiating 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)

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

    【讨论】:

    • 是的,那么,是否有一些机制可以像语义动作一样运行,但没有回溯运行效果?
    • 仅当您在解析后对 AST 进行后处理
    • @sehe 那么你将如何用 boost 实例化你的 ast 元素呢?我现在检查的内容涉及使用语义操作(您已经看到了主题stackoverflow.com/questions/53320015/…)。有什么建议的方法吗? (ps ast 与解析分开执行,很像在结果树中相互拥有的实例中“编译”,然后执行。
    猜你喜欢
    • 2013-02-06
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多