überschreibt ctypewchar_t

8

Ich schreibe einen Lambda-Kalkül-Interpreter für Spaß und Übung. Ich habe Iostreams, um Bezeichner richtig zu tokenisieren, indem ich eine ctype -Facette hinzufüge, die Interpunktion als Whitespace definiert:

%Vor%

( classic_table() wäre wahrscheinlich sauberer, aber das funktioniert nicht unter OS X!)

Und dann tauschen Sie die Facette aus, wenn ich einen Identifikator treffe:

%Vor%

Es scheint erstaunlich wenig Lambda-Kalkül-Code im Web zu geben. Das meiste, was ich bisher gefunden habe, ist voller Unicode λ -Zeichen. Also habe ich versucht, Unicode-Unterstützung hinzuzufügen.

Aber ctype<wchar_t> funktioniert völlig anders als ctype<char> . Es gibt keine Haupttabelle; Es gibt vier Methoden do_is x2, do_scan_is und do_scan_not . Also habe ich das gemacht:

%Vor%

(Entschuldigung für die flache Formatierung; die Vorschau hat die Registerkarten anders konvertiert.)

Der Code ist weniger elegant. Ich drücke besser die Vorstellung aus, dass nur Satzzeichen zusätzliche Leerzeichen sind, aber das wäre im Original gut gewesen, hätte ich classic_table gehabt.

Gibt es einen einfacheren Weg, dies zu tun? Brauche ich wirklich all diese Überladungen? (Das Testen hat gezeigt, dass do_scan_not hier irrelevant ist, aber ich denke weiter.) Benutzt ich an erster Stelle Facetten? Ist das obige sogar richtig? Wäre es besser, weniger Logik zu implementieren?

    
Potatoswatter 26.02.2010, 05:00
quelle

2 Antworten

3

(Es war ein Jahr ohne substantielle Antwort, und ich habe in der Zwischenzeit viel über Iostreams gelernt ...)

Die benutzerdefinierte Facette existiert ausschließlich für den String-Extraktionsoperator in >> token . Dieser Operator wird in use_facet< ctype< wchar_t > >( in.getloc() ).is( ios::space, c ) "für das nächste verfügbare Eingabezeichen c definiert." (§21.3.7.9) ctype::is ist einfach ein Stub für ctype::do_is , es scheint also, dass do_is ausreichend ist.

Dennoch implementieren aktuelle Versionen der GCC-Standardbibliothek operator>> in scan_is . Der Catch ist, dass do_scan_is dann als eine Reihe von Aufrufen an do_is , virtueller Versand und alle implementiert wird. Die Header-Datei beschreibt do_scan_is als einen Haken für die Benutzeroptimierung.

Es scheint also, dass die Als-Ob-Regel eine Implementierung schützt, die nur die erste Überschreibung bietet.

Beachten Sie, dass die zweite Überschreibung, die Maskenwerte abruft, eine ungerade ist. Es könnte in Bezug auf das erste implementiert werden, indem die Maske Bit für Bit ineffizient aufgebaut wird. In GCC wird es in Form von Systemaufrufen implementiert, wodurch die Maske Bit für Bit mit 15 Aufrufen pro Zeichen ineffizient aufgebaut wird. Dies scheint sowohl die Leistung als auch die Kompatibilität zu beeinträchtigen. Zum Glück scheint es niemand benutzt es.

Wie auch immer, das ist alles gut und gut, aber einfach einen Tokenizer mit streambuf_iterator<wchar_t> zu schreiben ist einfacher, viel erweiterbarer und vereinfacht die Ausnahmebehandlung.

    
Potatoswatter 05.07.2011, 06:56
quelle
2

IMHO der Code, den Sie gepostet haben, ist in Ordnung. Sie könnten einige der Methoden mit anderen implementieren, wenn Sie einfacheren Code wollten (vielleicht auf Kosten der Effizienz), aber die Art, wie Sie es getan haben, ist in Ordnung.

Die Disparität basiert auf der Tatsache, dass Menschen nicht mehrere Megabyte-Tabellen in ihren UNICODE-Programmen haben wollen.

    
jpalecek 25.03.2010 00:22
quelle

Tags und Links