C ++ Boost qi rekursive Regelkonstruktion

[Meine Erklärungen und Erwartungen scheinen überhaupt nicht klar zu sein, daher habe ich am Ende des Beitrags präzisiert, wie ich die Funktion verwenden möchte.]

Ich arbeite derzeit an Grammatiken mit Boost-Qi. Ich hatte eine Schleifenkonstruktion für eine Regel, weil ich sie aus den Elementen eines Vektors erstellen musste. Ich habe es mit einfachen Typen umgeschrieben und es sieht so aus:

#include <string>

// using boost 1.43.0
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_eps.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace bqi = boost::spirit::qi;

typedef const char* Iterator;

// function that you can find [here][1]
template<typename P> void test_phrase_parser(char const* input, P const& p, bool full_match = true);

int main()
{
    // my working rule type:
    bqi::rule<Iterator, std::string()> myLoopBuiltRule;
    std::vector<std::string> v;
    std::vector<std::string>::const_iterator iv;

    v.push_back("abc");
    v.push_back("def");
    v.push_back("ghi");
    v.push_back("jkl");

    myLoopBuiltRule = (! bqi::eps);
    for(iv = v.begin() ; iv != v.end() ; iv++)
    {
        myLoopBuiltRule =
                myLoopBuiltRule.copy()  [ bqi::_val = bqi::_1 ]
                | bqi::string(*iv)      [ bqi::_val = bqi::_1 ]
                ;
    }
    debug(myLoopBuiltRule);

    char s[] = "  abc ";

    test_phrase_parser(s, myLoopBuiltRule);
}

(Sieht aus wieHier will nicht durch entsprechenden Hyperlink ersetzt werden, deshalb hier die Adresse zur Suche nach der Funktion test_phrase_parser ():http://www.boost.org/doc/libs/1_43_0/libs/spirit/doc/html/spirit/qi/reference/basics.html)

Alles war zum Besten im Besten aller Welten ... bis ich ein Argument an diese Regel weitergeben musste. Hier ist der neue Regeltyp:

    // my not-anymore-working rule type:
    bqi::rule<Iterator, std::string(int*)> myLoopBuiltRule;

Der Typ 'int *' ist nur ein Beispiel, mein echter Zeiger spricht eine viel komplexere Klasse an ... aber immer noch ein bloßer Zeiger.

Ich habe meine 'for'-Schleife entsprechend geändert, d. H .:

    for(iv = v.begin() ; iv != v.end() ; iv++)
    {
        myLoopBuiltRule =
                myLoopBuiltRule.copy()(bqi::_r1)    [ bqi::_val = bqi::_1 ]
                | bqi::string(*iv)      [ bqi::_val = bqi::_1 ]
                ;
    }

Ich musste eine neue Regel hinzufügen, da test_phrase_parser () nicht erraten kann, welcher Wert dem int-Zeiger zugewiesen werden soll:

bqi::rule<Iterator> myInitialRule;

Und ändern Sie alles, was der for-Schleife folgte:

myInitialRule = myLoopBuiltRule((int*)NULL);

debug(myLoopBuiltRule);

char s[] = "  abc ";

test_phrase_parser(s, myInitialRule);

Dann ist alles abgestürzt:

/home/sylvain.darras/software/repository/software/external/include/boost/boost_1_43_0/boost/spirit/home/qi/nonterminal/rule.hpp:199: error: no matching function for call to ‘assertion_failed(mpl_::failed************ (boost::spirit::qi::rule<Iterator, T1, T2, T3, T4>::operator=(const Expr&)

Dann wurde ich verrückt und versuchte:

myLoopBuiltRule =
        myLoopBuiltRule.copy(bqi::_r1)  [ bqi::_val = bqi::_1 ]
        | bqi::string(*iv)      [ bqi::_val = bqi::_1 ]

->

error: no matching function for call to ‘boost::spirit::qi::rule<const char*, std::string(int*), boost::fusion::unused_type, boost::fusion::unused_type, boost::fusion::unused_type>::copy(const boost::phoenix::actor<boost::spirit::attribute<1> >&)’

Dann wurde ich sauer und schrieb:

myLoopBuiltRule =
        myLoopBuiltRule(bqi::_r1)   [ bqi::_val = bqi::_1 ]
        | bqi::string(*iv)      [ bqi::_val = bqi::_1 ]

Was kompiliert, weil es syntaktisch perfekt ist, aber welches großartig überläuft, weil es sich glücklich, nett, rekursiv zu Tode ruft ...

Dann verlor ich meinen Verstand und tippte:

myLoopBuiltRule =
        jf jhsgf jshdg fjsdgh fjsg jhsdg jhg sjfg jsgh df

Was, wie Sie wahrscheinlich erwarten, nicht kompiliert werden konnte.

Sie stellen sich vor, dass ich vor dem Schreiben des obigen Romans im Internet nachgesehen habe, aber nichts in Bezug auf copy () und Argumente herausgefunden habe, die gleichzeitig weitergegeben wurden. Hat jemand dieses Problem schon erlebt? Habe ich etwas verpasst

Seien Sie versichert, dass jede Hilfe wirklich sehr geschätzt wird.

PS: Vielen Dank an hkaiser, der, ohne es zu wissen, viele meiner Probleme mit boost :: qi über google beantwortet hat (aber dieses hier).

Weitere Informationen:

Der Zweck meines Parsers besteht darin, Dateien zu lesen, die in einer bestimmten Sprache L geschrieben sind. Der Zweck meines Posts besteht darin, meinen "Kontext" zu verbreiten (d. H .: Variablendefinitionen und insbesondere konstante Werte, damit ich Ausdrücke berechnen kann).

Die Anzahl der Variablentypen, die ich verarbeite, ist gering, aber sie werden immer größer. Daher behalte ich diese Typen in einer Containerklasse. Ich kann diese verwalteten Typen als Schleife verwenden.

Betrachten wir also einen Pseudo-Algorithmus für das, was ich erreichen möchte:

LTypeList myTypes;
LTypeList::const_iterator iTypes;

bqi::rule<Iterator, LType(LContext*)> myLoopBuiltRule;

myLoopBuiltRule = (! bqi::eps);
for(iTypes = myTypes.begin() ; iTypes != myTypes.end() ; iTypes++)
{
    myLoopBuiltRule =
        myLoopBuiltRule.copy()(bqi::_r1)    [ bqi::_val = bqi::_1 ]
        | iTypes->getRule()(bqi::_r1)           [ bqi::_val = bqi::_1 ]
}

Dies geschieht während der Initialisierung und dann wird myLoopBuiltRule verwendet und mit verschiedenen LContext * wiederverwendet, wobei mehrere Typen analysiert werden. Und da einige L-Typen Grenzen haben können, bei denen es sich um ganzzahlige Ausdrücke handelt, und diese ganzzahligen Ausdrücke Konstanten aufweisen können, brauche ich (glaube ich) mein geerbtes Attribut, um meinen LContext zu verschieben und den Ausdruckswert berechnen zu können.

Hoffe, ich war klarer in meinen Absichten.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage