What is the proper way to deal with deep recursion in boost::spirit::qi grammar?
Asked Answered
O

1

7

I have a working grammar similar to the following:

stock_price = symbol_ >> date_ >> price_;
stock_prices_ = stock_price_ >> stock_prices_ | eps;
grammar_ = lit( "PRICES" ) >> stock_prices_ >> lit( "END" );

The problem is, when the list of stock prices_ gets too high (say around 1000 prices), the the parses seg-faults with a exc_bad_access. I can actually solve this by:

stock_prices_ = stock_price_ >> stock_price_ >> stock_price_ >> stock_price >> stock_prices_ |
                stock_price_ >> stock_prices_ |
                eps;

but I don't see this as an elegant solution. Is there a better solution?

Obadias answered 19/12, 2013 at 16:26 Comment(1)
Maybe go exponential on the probelm. 20 exponential patterns would restrict recursion depth to about 40 + 1 per million.Weathertight
E
5

I might be completely missing the problem here, but what wrong with the kleene star, plus parser and or list parser directives?

stock_prices_ = +stock_price_ | eps; // one or more stock_price_ or nothing

However, this looks to be exactly the semantics of just kleene star:

stock_price = symbol_ >> date_ >> price_;
grammar_    = "PRICES" >> *stock_price_ >> "END"; // zero or more stock_price_

Now, if you wanted them line-separated e.g., use1:

grammar_    = "PRICES" >> -(stock_price_ % eol) >> "END";

1 combine with e.g. the qi::blank skipper, which doesn't eat the newlines

Ey answered 19/12, 2013 at 23:37 Comment(2)
Thanks! This was pretty obvious, and I just didn't think of it. Fairly new to implementing grammars.Obadias
@Obadias Cheers :) I venture that either you come from a functional programming background, or you might like the paradigm :) Using recursion over iteration is paramount in pure functional programming.Ey

© 2022 - 2024 — McMap. All rights reserved.