Frage zu boost::spirit



  • Hiho,

    ich habe folgenden Dateinamenaufbau

    "irgendwelche_zeichen_win32.dll"

    was immer gleich ist, ist das "_win32.dll" am Ende. Da ich noch mehr Sachen parsen muss, wollte ich auch das hier mit boost spirit machen.

    Jetzt hab ich folgende Regel:

    bool r = phrase_parse(
    		it,
    		end,
    
    		*char_[ref(m_modelName) += _1]
    		>> "_win32.dll",
    		space
    		);
    

    Problem: das *char_ frisst das "_win32.dll" mit auf. Gibt es in spirit Möglichkeiten, sowas zu handlen? Mir würde nur einfallen, den String von hinten an zu parsen, aber das ist ja auch eher ein Workaround.



  • Ich bin nciht 100%ig sicher, aber spirit müsste doch rekursive Definitionen erlauben. Dann würd ich das Ganze (in pseudo-EBNF notiert) quasi so schreiben:

    alnum := [a-z, A-Z, 0-9]
    
    fnamecomp := '_' >> (
                         "win32.dll" 
                        | (alnum[ref(m_modelName) += ('-' + _1)] >> fnamecomp)
                        )
    
    filename = alnum[ref(m_modelName) += _1] >> fnamecomp
    

    Wies in spirit-ebnf dann richtig auszusehen hat muss ich dir überlassen 😉


  • Administrator

    Frage: Probierst du hier nicht gerade ein Ei mit einem Vorschlaghammer zu öffnen?

    std::string name = "irgendwelche_zeichen_win32.dll";
    
    std::size_t pos = name.rfind('_');
    std::string x = name.substr(0, pos);
    

    Nur weil man Boost.Spirit einsetzt, muss man es ja nicht gleich für jede Kleinigkeit einsetzen.

    Ansonsten wenn du bei Boost.Spirit bleiben möchtest, dann ist das Problem hier eben, dass sich Boost.Spirit "greedy" verhält. Eine Regel wird so lange angewandt, wie es eben möglich ist und erst wenn diese fehlschlägt, wird probiert die nächste anzuwenden. In der alten Classic Version wurde das in der Dokumentation angesprochen:
    http://www.boost.org/doc/libs/1_35_0/libs/spirit/doc/rationale.html#exhaustive_rd

    Darin wird auch auf eine Technik verwiesen, wie man das Problem umgehen kann. Wie es in der neuen Version genau aussieht, weiss ich nicht.

    Grüssli



  • Pellaeon schrieb:

    Hiho,

    ich habe folgenden Dateinamenaufbau

    "irgendwelche_zeichen_win32.dll"

    was immer gleich ist, ist das "_win32.dll" am Ende. Da ich noch mehr Sachen parsen muss, wollte ich auch das hier mit boost spirit machen.

    Jetzt hab ich folgende Regel:

    bool r = phrase_parse(
    		it,
    		end,
    		
    		*char_[ref(m_modelName) += _1]
    		>> "_win32.dll",
    		space
    		);
    

    Problem: das *char_ frisst das "_win32.dll" mit auf. Gibt es in spirit Möglichkeiten, sowas zu handlen? Mir würde nur einfallen, den String von hinten an zu parsen, aber das ist ja auch eher ein Workaround.

    Da gibt es mehrere Möglichkeiten. Entweder man verwendet 'a - b', welches 'a' erkennt solange es nicht 'b' ist:

    *((char_ - "_win32")[ref(m_modelName) += _1])
    

    oder man verwendet Predikate:

    *(!lit("_win32") >> char_[ref(m_modelName) += _1])
    

    wobei !... die Eingabe testet, ohne vorwärts zu gehen.

    HTH
    Regards Hartmut



  • Dravere schrieb:

    Frage: Probierst du hier nicht gerade ein Ei mit einem Vorschlaghammer zu öffnen?

    Ja^^ Mich hat das Problem aber vom Prinzip her interessiert. Daher meine Frage. Und da ich später noch kompliziertere Sachen parsen muss als den Dateinamen, wollte ich es auch gerne für dieses einfache Beispiel wissen.

    Thx an alle für die Antworten 🙂

    MfG Pellaeon


Anmelden zum Antworten