2

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.

DmitryU
  • 31
  • 4

1 Answers1

1

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

Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Yeah, so, are there some mechanisms, that runs like semantic actions, but without backtrack-run effect? – DmitryU Jun 20 '16 at 06:53
  • 1
    Only if you post process your AST after parsing – sehe Jun 20 '16 at 09:02
  • @sehe how would you instantiate elements of your ast with boost then? What i was checking now involved using semantic actions (you've seen the topic https://stackoverflow.com/questions/53320015/virtual-classes-as-ast-nodes-with-spirit/53329882#53329882). Is there any adviced way? (p.s. the ast is executed separately from the parsing, pretty much like "compiling" in instances owning each other in a resulting tree, and then executing. – Barnack Nov 18 '18 at 17:00