Alle drei Male plus zusätzliche Ausgabe. Übersicht und Zusammenfassung des Hinzufügens von Post-Inkrement zu CPython [Ich habe versucht, CPython [Implementierung] ein Post-Inkrement hinzuzufügen (http://qiita.com/DOSS_INCREMENT/items/8b050847145f635211e2) Liste aller Änderungen, die durch Hinzufügen eines Post-Inkrements zu CPython vorgenommen wurden Zusätzliche Ausgabe zum Hinzufügen von Post-Inkrement zu CPython
Ursprünglich war das Inkrementieren eine Aufgabe zum Üben des Änderns der Listeneinschlussnotation. Die Implementierung war jedoch schwieriger als erwartet, auch weil das Inkrement nicht zum Designkonzept passte. Unabhängig vom Konzept kann das Ändern der Listeneinschlussnotation in etwa fünf Minuten abgeschlossen werden, wenn Sie über das bisherige Wissen verfügen.
Zunächst verwenden wir DOSS_HASKELL anstelle von DOSS_INCREMENT, um die Änderungen unabhängig zu machen. Daher ist die Konfiguration wie folgt.
CFLAGS="-O0 -g -DDOSS_INCREMENT=1 -DDOSS_HASKELL=1" ./configure --prefix="/home/denjo/piyothon_install"
Die aktuelle Listeneinschlussnotation von Python lautet wie folgt.
lst = [x for x in range(10) if x >= 5]
Auf der anderen Seite ist Haskell wie folgt.
lst = [x | x <- [0..9], x >= 5]
Das modifizierte Python kann wie folgt ausgedrückt werden.
lst = [x $ x <- range(10), x >= 5]
Außerdem hier|
nicht$
Wird genutzt|
Da es eine Operation als logische Summe hat, wird sie als solche erkannt.
Es gibt nur drei Änderungen:
Grammar
comp_iter: comp_for | comp_if
#ifdef DOSS_HASKELL
comp_for: ('for' | '$') exprlist ('in' | '<-') or_test [comp_iter]
#endif
comp_if: ('if' | ',') test_nocond [comp_iter]
token.h
#ifdef DOSS_INCREMENT
#define INCREMENT 58
#define PRE_INCREMENT 61
#endif
#ifdef DOSS_HASKELL
#define LARROW 59
#define DOLLAR 60
#endif
toknizer.c
case '<':
switch (c2) {
case '>': return NOTEQUAL;
case '=': return LESSEQUAL;
case '<': return LEFTSHIFT;
#ifdef DOSS_HASKELL
case '-': return LARROW;
#endif
}
break;
Am Ende habe ich nur die Grammatik neu geschrieben, um $, <-, ”,” anstelle von for, in, if zuzulassen und das Token zu registrieren. Übrigens können Sie damit auch unangenehm schreiben, z. B. "[x ** 2 $ x in Bereich (10), x% 2 == 0]". Es ist auch niedlich, dass die bedingten Ausdrücke nach "," durch "und" verbunden werden müssen, anstatt sie durch "," zu trennen.
F. Warum funktioniert es, obwohl ich die Bedeutung für und in nicht definiert habe? Ist es ein Alias für oder in?
A. Erstens ist die Bedeutung für und in nicht definiert. Für for ist das Token, das nach for kommt, eine Variable, die wiederholt verwendet wird, und das Token, das danach kommt, ist ... und die Grammatik ist nicht definiert. Denn ist nur ein Trennzeichen, und was mit den darauf folgenden Token zu tun ist, wird in der Grammatik als das definiert, was danach kommt, nicht für.
Grammar
comp_iter: comp_for | comp_if
comp_for: 'for' exprlist 'in' or_test [comp_iter]
comp_if: 'if' test_nocond [comp_iter]
Das Obige ist der Grammatikteil, der der Notation der Listeneinbeziehung vor dem Umschreiben entspricht. Wenn man sich "comp_for" ansieht, wird definiert, dass das Wort nach "for" als "exprlist" bezeichnet wird. Außerdem soll "or_test" nach "in" aufgerufen werden. Daher ist festgelegt, welche Definition (wie der Syntaxbaum erstellt wird und welcher Bytecode ausgeführt wird) für "exprlist", "or_test" und "comp_for" und nicht für und in festgelegt ist. Das kann man sagen
Wenn Sie einen neuen Operationscode UNARY_PRE_INCREMENT erstellen und die Stapelreihenfolge in ceval.c beachten, können Sie ihn in 30 Minuten erstellen.
Recommended Posts