Wie wandelst du eine nicht angegebene Python-Funktion / Lambda in AST? 2.6

7

Es scheint, als sollte es einfach sein, aber ich kann die Antwort nirgendwo finden - und auch nicht in der Lage, eine selbst abzuleiten. Wie verwandelst du eine nicht notierte Python-Funktion / Lambda in eine AST?

Hier ist, was ich gerne tun könnte.

%Vor%     
Chris 23.09.2009, 21:34
quelle

5 Antworten

6

Wenn Sie nur auf die Funktion / Lambda zugreifen, haben Sie nur den kompilierten Python-Bytecode. Der genaue Python-AST kann nicht aus dem Bytecode rekonstruiert werden, da Informationsverlust im Kompilierungsprozess vorliegt. Aber Sie können den Bytecode analysieren und dafür ASTs erstellen. Es gibt einen solchen Analysator in GeniuSQL. Ich habe auch einen kleinen Proof of Concept, der Bytecode analysiert und daraus SQLAlchemy-Klauselelemente erstellt.

Der Prozess, den ich für die Analyse verwendet habe, ist folgender:

  1. Teilen Sie den Code in eine Liste von Opcodes mit möglichen Argumenten auf.
  2. Finden Sie die grundlegenden Blöcke im Code, indem Sie die Opcodes durchlaufen und für jeden Sprung eine Basisblockgrenze nach dem Sprung und vor dem Sprungziel erstellen
  3. Erstellen Sie ein Kontrollflussdiagramm aus den Basisblöcken.
  4. Gehen Sie durch alle grundlegenden Blöcke mit abstrakten Interpretationsverfolgungsstapel- und Variablenzuweisungen in SSA-Form.
  5. Um den Ausgabeausdruck zu erstellen, rufen Sie einfach den berechneten SSA-Rückgabewert ab.

Ich habe meinen Proof of Concept und Beispiel eingefügt Code verwendet . Dies ist ein nicht sauberer, schnell gehackter Code, aber Sie können darauf aufbauen, wenn Sie möchten. Hinterlassen Sie eine Notiz, wenn Sie etwas Nützliches daraus machen möchten.

    
Ants Aasma 24.09.2009, 08:52
quelle
10

Im Allgemeinen können Sie nicht. Zum Beispiel ist 2 + 2 ein Ausdruck - wenn Sie ihn jedoch an eine Funktion oder Methode übergeben, ist das übergebene Argument nur die Zahl 4 , also keine Möglichkeit, den berechneten Ausdruck wiederherzustellen. Der Funktionsquellcode kann manchmal wiederhergestellt werden (allerdings nicht für lambda ), aber "ein nicht angeführter Python-Ausdruck" wird evaluiert , also erhält man nur das Objekt, das den Wert des Ausdrucks hat.

Welches Problem versuchen Sie zu lösen? Es kann andere, tragfähige Ansätze geben.

Bearbeiten : tx an das OP zur Klärung. Es gibt keine Möglichkeit, dies für lambda oder einige andere Fälle zu tun, aber wie ich bereits erwähnt habe, kann der Quellcode manchmal wiederhergestellt werden ...:

%Vor%

inspect.getsource hebt IOError an, wenn es den Quellcode für das Objekt, an das Sie es übergeben, nicht erhalten kann. Ich schlage vor, dass Sie den Parsing- und Getsouce-Aufruf in eine Hilfsfunktion umwandeln, die eine Zeichenkette akzeptiert (und sie einfach analysiert) oder eine Funktion (und versucht, Quelltext darauf zu geben, was möglicherweise bessere Fehler in IOError ergibt).

    
Alex Martelli 23.09.2009 22:03
quelle
4

Die Meta-Bibliothek ermöglicht es Ihnen, die Quelle in vielen Fällen wiederherzustellen, mit einigen Ausnahmen wie Comprehensions und Lambdas.

> %Vor%     
dan 30.08.2012 19:23
quelle
1

Sie können AST nicht aus kompiliertem Bytecode generieren. Sie benötigen den Quellcode.

    
nosklo 23.09.2009 23:33
quelle
0

Ihr Lambda-Ausdruck ist eine Funktion, die viele Informationen enthält, aber ich glaube nicht, dass ihr Quellcode zugeordnet ist. Ich bin mir nicht sicher, ob du das bekommst, was du willst.

    
Ned Batchelder 23.09.2009 21:37
quelle

Tags und Links