2013-12-19 14 views
7

Ich habe eine Arbeits Grammatik ähnlich den folgenden:Was ist der richtige Weg, mit tiefer Rekursion in der boost :: spirit :: qi Grammatik umzugehen?

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

Das Problem ist, wenn die Liste der Lager prices_ zu hoch wird (sagen etwa 1000 Preise), die die Parsen seg-Fehler mit einem EXC_BAD_ACCESS. Ich kann das tatsächlich lösen durch:

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

aber ich sehe das nicht als eine elegante Lösung. Gibt es eine bessere Lösung?

+0

Vielleicht exponentiell auf das Problem gehen. 20 exponentielle Muster würden die Rekursionstiefe auf ungefähr 40 + 1 pro Million beschränken. – Yakk

Antwort

5

Ich könnte das Problem hier komplett fehlen, aber was ist falsch mit den kleene star, plus parser und oder list parser directive s?

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

Allerdings sieht dies genau zu sein, die Semantik von nur kleene Stern:

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

Nun, wenn man sie durch Zeilen getrennte zB 1 verwenden wollte:

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

1 kombinieren mit z.B. die qi::blank Skipper, die nicht die Zeilenumbrüche isst

+0

Danke! Das war ziemlich offensichtlich und ich habe einfach nicht daran gedacht. Ziemlich neu bei der Implementierung von Grammatiken. – statguy

+1

@statguy Prost :) Ich wage, dass _iteit_ Sie von einem funktionalen Programmierhintergrund kommen, _oder_ Ihnen könnte das Paradigma gefallen :) Die Verwendung von Rekursion über Iteration ist von größter Bedeutung bei der reinen funktionalen Programmierung. – sehe

Verwandte Themen