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

2023-07-18C/C++开发问题
2

本文介绍了语义动作在 boost::spirit 解析中多次运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

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

I am trying to create AST with semantic rules while parsing with boost::spirit. AST must be built only for piece of the input, another part of the input should be parsed without sintax tree.

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

For example, for such input strings: "self.usedFoo(Bar).filter(self.baz > baz)" or "self.Foo.filter(true)" AST should be build only for bold part.

还有一个问题:解析器运行多次解析语法并多次调用语义动作(实例化 AST 节点),所以我得到了可怕的内存泄漏.

And there is a problem: parser runs multimple times parsing grammar and calling semantic action (instatntiating AST nodes) multimple times too, so I got terrible memory leaks.

简单的源代码:

语法:

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)

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)

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

So, as you can see, nodes instantiating too many times that causes mem leaks.

推荐答案

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

Semantic actions fire even if there's backtracking later.

解析器表达式可能会抛出异常.

Parser expressions might throw.

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

For these reasons alone, it's not a good idea to do dynamic allocations in your semantic actions. If you need to, use smart pointers (though this will still be inefficient).

  • 提升精神:语义动作是邪恶的"?
  • 如何使用多态属性boost::spirit::qi 解析器?

这篇关于语义动作在 boost::spirit 解析中多次运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

The End

相关推荐

无法访问 C++ std::set 中对象的非常量成员函数
Unable to access non-const member functions of objects in C++ std::set(无法访问 C++ std::set 中对象的非常量成员函数)...
2024-08-14 C/C++开发问题
17

从 lambda 构造 std::function 参数
Constructing std::function argument from lambda(从 lambda 构造 std::function 参数)...
2024-08-14 C/C++开发问题
25

STL BigInt 类实现
STL BigInt class implementation(STL BigInt 类实现)...
2024-08-14 C/C++开发问题
3

使用 std::atomic 和 std::condition_variable 同步不可靠
Sync is unreliable using std::atomic and std::condition_variable(使用 std::atomic 和 std::condition_variable 同步不可靠)...
2024-08-14 C/C++开发问题
17

在 STL 中将列表元素移动到末尾
Move list element to the end in STL(在 STL 中将列表元素移动到末尾)...
2024-08-14 C/C++开发问题
9

为什么禁止对存储在 STL 容器中的类重载 operator&amp;()?
Why is overloading operatoramp;() prohibited for classes stored in STL containers?(为什么禁止对存储在 STL 容器中的类重载 operatoramp;()?)...
2024-08-14 C/C++开发问题
6