c++ - 语义 Action 在 boost::spirit 解析中运行多次

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

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

例如,对于这样的输入字符串:“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++ - 语义 Action 在 boost::spirit 解析中运行多次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37911950/

相关文章:

c++ - 如何编写 boost::spirit::qi 解析器来执行 '?' 在正则表达式中所做的事情?

c++ - 从其他 .cpp 设置 WinMain?

c++ - 函数指针 typedef - 表达式必须是可修改的左值错误

c++ - boost 文件系统中的段错误?

c++ - 按值返回 boost ublas 矩阵仅在 vs2012 的发布配置中工作

c++ - Boost spirit x3 解析为结构,如果它为空则跳过成员

c++ - 使用 boost::spirit 在 C++ 中读取二维数组

c++ - 如何发现未定义的行为

c++ - 加载.dll时实例指针与vfptr不同

c++ - 为什么常量字符串在用于 variant<bool, std::string> 的输入时变成 bool?