Sinnvolles goto - Skipping von "escaped characters"
-
tntnet schrieb:
Wobei ich einfach einen stateful Parser schreiben würde.
!!!
Danke.
-
hustbaer: du kopierst zeichen herum. hat optimierungspotential
Leute, sagt mir bitte nicht dass mein Code langsam(er als ein anderer) ist, ohne es ausprobiert zu haben. Ich denke ich weiss im allgemeinen was ich tue. Das einzige was da optimiert gehört ist dass man a) sowieso keinen vector<string> verwenden sollte weil das schonmal ganz grob langsam ist, und b) den "buffer" irgendwo als member anlegen sollte, damit der nicht ständig neu angelegt und reallokiert wird.
Ansonsten ist single-pass im Allgemeinen schneller als multi-pass... sollte auch logisch sein.
-
ach jetzt seh ich das: du nimmst gleich die backslashes aus dem string mit weg... daran hab ich nicht gedacht.
-
Jupp

Wobei ich natürlich nicht behaupten will dass meine Version "optimal" sei -- nur komplett sinnlos kopiere ich auch nicht Daten durch die Gegend. Sozusagen
-
Irgendwie hatte ich wohl nen Blackout beim schreiben, hätte mir eigentlich auffallen sollen, dass man die Bedingung ja direkt dran hängen kann ohne irgendwelche unnötigen Vergleiche vorzunehmen.
Ich habs jetzt so:
else if( *it == '\"' ) //beginning of a string { std::string::const_iterator begin( ++it ); while( (it != end && *it != '\"') || ( *it == '\"' && *( it - 1 ) == '\\' ) ) { ++it; } argVec.push_back( std::string( begin, it++ ) ); boost::algorithm::replace_all( argVec[ argVec.size() - 1 ], "\\\"", "\"" ); }Irgendwelche aufwändigen Techniken sind hier wirklich nicht angebracht, ich hab so einen Parser der robust und fehlertorelant genug ist in knapp 50Zeilen mit viel whitespace.
Wenn es die Mühe wert wäre, würde ich einen richtigen Parser schreiben, der escape Sequenzen auch richtig beherrscht (tut der hier ja nicht).Danke c.rackwitz für den "Wink mit dem Zaunpfahl".
-
Ich möchte nur anmerken dass es nicht immer gut ist ultra-kompakten Code zu haben. Ich habe lieber Code der irgendwo zwischendrin ist (auf "kompakt" bezogen), dafür halbwegs gut lesbar und halbwegs gut verständlich, als Code der zwar ultra kompakt ist, dafür nicht so einfach verständlich.
Klar ist es gut "übersichtlich" zu programmieren, aber man kann es auch übertreiben finde ich. Ich lese lieber Code auf 2 Bildschirmseiten wo ich in 30 Sekunden verstehe was abgeht (und wie), als Code auf 1/2 Bildschirmseite wo ich nach 2 Minuten immer noch nicht 100% sicher bin warum das eigentlich funktioniert, bzw. im Extremfall: was der Code eigentlich tut, bzw. wie. Fehler Suchen in so einem Code macht garkeinen Spass.
Die "while Schleife mit gleich allem in der Bedingung" ist für mich schon nichtmehr Grenzwertig, sondern "zu kompakt". z.B. ist nicht auf den ersten Blick ersichtlich dass das "*(it - 1)" OK ist. Es ist zwar OK (it wird ja vorher incrementiert), aber man kann ohne weiteres mal ein paar Sekunden brauchen bis man das überzuckert.
-
in dem falle ist ein kommentar angebracht, um die verständlichkeit zu wahren
-
r0nny schrieb:
in dem falle ist ein kommentar angebracht, um die verständlichkeit zu wahren
Die Verständlichkeit, ja. Aber es geht auch darum ob ich einem Code "trauen" kann. Und da hilft auch das Kommentar nix. Da muss ich dann alle Randbedingungen durchgehen und ... ach, ich finde das einfach lästig mit so kompaktem Code

-
Die Kommentare hab ich rausgenommen.
Original sieht es so aus:while( (it != end && *it != '\"') || //a quote char start //skipping ( *it == '\"' && *( it - 1 ) == '\\' ) )//an escaped quote char { //continue skipping ++it; }Die Formatierung passt jetzt halt nimmer, deswegen hab ich sie auch rausgenommen.
Im Prinzip ist es aber sehr einfach zu verstehen, da durch das Oder zwei unterschiedliche Bedingungen getrennt werden, kann man sie sich auch getrennt
anschauen und dann seh ich da kein(e) Problem(e) beim Verständnis.
Beide Bedingungen für sich sind doch sehr einfach zu verstehen.Allerdings fällt mir gerade ein Fehler auf, die Bedingung it!=end muss für beide Kriterien gelten.
Und um das -1 kommt man nicht herum um das Zeichen das davor liegt zu prüfen.
Der Iterator wird ikrementiert, damit das anfängliche " nicht im string enthalten ist.
-
Ich weiß nicht ... bisher hat mich nichts überzeugt. Was ist eigentlich gegen einen stateful parser einzuwenden? Ist zwar länger, folgt aber einem festen Schema und ist beliebig erweiterbar.
bool parse_quoted_string(Iterator begin, Iterator end) { enum states { start, normal, quoted, complete, failure }; states state = start; for (Iterator it = begin; it != end and state != failure; ++it) { switch (state) { case start: if (*it == '"') state = normal; else state = failure; break; case normal: if (*it == '\\') state = quoted; else if (*it == '"') state = complete; else /* Zeichen verarbeiten */; break; case quoted: if (*it != '"') state = failure; else { state = normal; /* Zeichen verarbeiten */ } break; case complete: state = failure; break; } }; return state == complete; }