Frage

Ich habe gerade angefangen in Boost zu graben :: Geist, neueste Version von jetzt - V2.4. Die essense meines Problems ist folgende:

Ich möchte Parse-Zeichenfolgen wie "1a2" oder "3b4". So ist die Regel, die ich verwendet wird:

  (double_ >> lit('b') >> double_)
| (double_ >> lit('a') >> double_);

Das Attribut der Regel muss "vector " sein. Und ich bin es in die Behälter zu lesen.

Der vollständige Code:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cstring>

int main(int argc, char * argv[])
{
    using namespace std;
    using namespace boost::spirit;
    using namespace boost::spirit::qi;
    using boost::phoenix::arg_names::arg1;

    char const * first = "1a2";
    char const * last  = first + std::strlen(first);
    vector<double> h;

    rule<char const *, vector<double>()> or_test;
    or_test %=    (double_ >> lit('b') >> double_) 
            | (double_ >> lit('a') >> double_);

    if (parse(first, last, or_test,h)) {
           cout << "parse success: "; 
           for_each(h.begin(), h.end(), (cout << arg1 << " "));
           cout << "end\n";
    } else cout << "parse error\n" << endl;
    return 0;
 }

Ich bin Kompilieren mit g ++ 4.4.3. Und es gibt "1 1 2". Während ich erwarte "1 2".

Soweit ich verstehe dies geschieht, weil Parser:

  • geht auf die erste Alternative
  • liest eine double_ und speichert sie in den Container
  • stoppt dann bei "a", während leuchtet erwartung ( "b")
  • geht in die zweite Alternative
  • liest zwei weitere Doppel

Meine Frage ist - Ist das ein korrektes Verhalten, und wenn ja - warum?

War es hilfreich?

Lösung

Das ist das erwartete Verhalten. Während Rückzieher Geist nicht ‚ungeschehen‘ Änderungen an Attributen. Daher sollten Sie die hold[] Direktive verwenden explizit den Parser zwingt zu einer Kopie des Attributs zu halten (so dass jede Attributänderung rückgängig zu machen):

or_test =    
        hold[double_ >> lit('b') >> double_)]
    |   (double_ >> lit('a') >> double_)
    ; 

Diese Direktive Anforderungen an alle Alternativen angewendet werden modifizieren das Attribut, mit Ausnahme des letzten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top