Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
337 views
in Technique[技术] by (71.8m points)

c++ - Semantic actions runs multiple times in boost::spirit parsing

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.

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.

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.

Simplicated source code:

grammar:

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

Instantiating node:

  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);
    }

input:

self.filter(1)

debug out:

   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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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).

See


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...