Boost::Spirit - Eine Einführung



  • Hallo bernd1,

    danke...

    Zu deiner Frage

    rule<> _SECTION
    

    wird wie folgt aufgedröselt...

    Der erste Buchstabe muss eine '[' sein dann können beliebige (*(anychar_p...) Zeichen kommen ausser ((... - chlit<char>(']')) eine ']'. Nach diesen Zeichen muss zwingend eine ']' kommen. Danach kann ein end of line kommen.

    Ich hoffe ich konnte dir weiterhelfen...

    Gruss
    Tobi



  • Hier nun das versprochene PDF zur Theoretischen Informatik
    Klick Mich



  • Hallo zusammen,

    anbei eine Berichtigung des PDF's

    kurz nach der Stelle

    linke Seite -> rechte Seite
    

    muss es heißen wie folgt heißen.

    Die linke Seite besteht aus mindestens einer Variablen und beliebigen Terminalsymbolen bestehen.

    Die Rechte Seite kann aus Variablen und Terminalsymbolen bestehen

    Gruss
    Tobi



  • Die Berichtigung ist jetzt auch im PDF zu finden

    Grüsse
    Tobi



  • cu



  • bzw. kannst du den ganzen source code deiner demos irgendwo hochladen?
    wäre nett!
    cu



  • hi

    warum ist die klasse rule eine template klasse? in einigen beispielen wurde ScannerT als typ verwenden...

    template<
            typename ScannerT = scanner<>,
            typename ContextT = parser_context<>,
            typename TagT = parser_address_tag>
        class rule;
    


  • @Justin:

    hallo Justin, momentan ist kein weiterer Artikel meinerseits geplant kommt aber vielleicht noch.

    Die Sourcen muss ich suchen. Wenn ich sie gefunden habe lade ich sie hoch.

    @cplusplus.:
    Hallo cplusplus. Die rule<> Klasse ist deshalb eine Templateklasse, weil du manchmal eben nicht mit einfachen plain vanilla parsern in der rule klar. Manchmal braucht man was "stärkers". 🙂
    Da gibt's noch Grammatiken, Parsebäume und vieles mehr wo die rule<> parametrisiert werden muss.

    Als einstieg googelst du dir vielleicht mal was zu Formalen Sprachen und Grammatiken.

    Danach ziehst du dir die Doku von Spirit noch einmal rein.
    Oder du gehst gleich in Richtung compiler bau (Drachenbuch)

    Ich hoffe ich konnte das ansatzweise klären

    Grüsse
    Tobi



  • Wie performant ist spirit eigentlich?
    Kann man einen kompletten Parser der die Syntaxanalyse für C++ durchführen soll damit realisieren oder sollte man lieber auf Lex und Yacc bzw. ANTLR zurückgreifen?

    Das Framework sieht echt sehr interessant aus.
    Guter Artikel...

    Gruß Patrick



  • Hallo Paddy82,

    man kann durchaus in einer akzeptablen Zeit die Syntaxanalyse von Codedateiten bewerkstelligen. Allerdings bläst sich der Parser ziemlich auf.

    Ich würde für solche Sachen mittlerweile wohl eher auf Lex und Yacc zurückgreifen.

    Grüsse
    Tobi



  • Habe mich mal an deinen Artikel versucht. Leider erhalte ich einen Compile-Error für das Debugout-Bsp. aus Abschnitt 6. Angemeckert wir die Zeile, in der _SECTION die DebugOut-Funktion übergeben bekommt:

    Spirit1.cpp(27) : error C2896: 'boost::spirit::action<DerivedT,ParserT> boost::spirit::parser<DerivedT>::operator [](const ActionT &) const': Funktionsvorlage 'void DebugOut(IteratorT,IteratorT)' kann nicht als Funktionsargument verwendet werden
    with
    [
    DerivedT=boost::spirit::rule<>
    ]
    Spirit1.cpp(27) : error C2676: Binärer Operator '[': 'boost::spirit::rule<>' definiert diesen Operator oder eine Konvertierung in einen für den vordefinierten Operator geeigneten Typ nicht

    Compiler: MSVC 7.1
    Spirit: 1.8.x aus Boost 1.33.1

    Laut MSDN ist Fehler C2896 so, das ein Funktionstemplate selbst kein Funktionstemplate verwenden kann. Hem...

    Hat jemand ebenfalls diesen Fehler?

    Wenn ich aus DebugOut keine Templatefunktion mache, funktioniert es, so wie es der Compiler haben will.



  • Du solltest einfach angeben, welche Spezialisierung deiner Template-Funkion verwendet werden soll (beachte das '_SECTION[&DebugOut**<const char>**]*' im Beispiel).



  • Das hatte ich ja gemacht, habe sogar vorsichtshalber den Source aus dem Artikel Copy&Paste gemacht. Meldung kam trotzdem.



  • So, hab es jetzt mal mit MinGW ausprobiert. Da funktioniert es anstandslos. Fragt sich jetzt, ob MSVC7.1 hier eine Standardlücke hat...



  • Tobias Gerg(offline) schrieb:

    @Justin:
    @cplusplus.:
    Hallo cplusplus. Die rule<> Klasse ist deshalb eine Templateklasse, weil du manchmal eben nicht mit einfachen plain vanilla parsern in der rule klar. Manchmal braucht man was "stärkers". 🙂
    Da gibt's noch Grammatiken, Parsebäume und vieles mehr wo die rule<> parametrisiert werden muss.

    brauchte man nicht auch einen anderen scanner, wenn man mit anderen typen als char oder wchar_t arbeiten wollte?



  • Hallo Artchi,

    ich check das noch mal gegen wenn ich den MSVC wieder mal zur Hand habe.

    Gruß
    Tobi

    Hallo otze,

    boah das ist ne gute Frage... Bin schon ziemlich lange wieder aus Spirit draußen... Daher bin ich mir nicht sicher... Ich probier das bei gelegenheit mal wieder...

    Gruß
    Tobi



  • der artikel ist btw in der CT 1/2008 im boost::spirit artikel als eine der (wenigen) referenzen angegeben 👍



  • Artchi schrieb:

    So, hab es jetzt mal mit MinGW ausprobiert. Da funktioniert es anstandslos. Fragt sich jetzt, ob MSVC7.1 hier eine Standardlücke hat...

    Hab zwar eine neuere Version, glaub ich, aber ich bekomm den gleichen Fehler, wäre mal echt geil, wenn hier jemand eine Lösung parat hätte.^^
    Möchte net wegen sowas direkt den Compiler wechseln...

    [e]
    K, hab es jetzt mit functoren probiert, die gehen, vielleicht sollte ich ich mal statt normalen Funktionen Funktionszeiger verwenden.
    [e2]
    So, wenn ich statt &f einfach einen Funktionszeiger auf die Funktion F verwende, dann funktionierts!

    typedef void (*fun)(const char*,const char*);
    
    void f(const char*,const char*);
    
    int
    main()
    {
    	fun _f = f; // funkt sowohl mit als auch ohne & vor f -> fun _f = &f
    	// func f;
    	rule<> r = *(real_p>>+(ch_p(',')));
    	//rule<> r2 = r[func()]; 
    	rule<> r2 = r[_f]; 
    	if(parse("1,2,3,4,5,",r2).full)
    		cout << "full" << endl;
    	_getch();
        return 0;
    }
    void f(const char* beg, const char* end)
    {
    	string str(beg,end);
    	cout << str << endl;
    }
    

Anmelden zum Antworten