code optimierung und kompatibiliät zu python 1.5.2

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Martin Kalbfuß
User
Beiträge: 21
Registriert: Freitag 23. Mai 2008, 09:17

Hi,

Ich schreibe einen scanner für das SCons build system. Da SCons auf python 1.5.2 aufbaut will ich dies nicht untergraben in dem ich code für höhere versionen schreibe. Es wäre toll wenn jemand den folgenden Code studieren und falls sinnvoll Verbeseerungsvorschläge unterbreiten könnte.
Danke

Code: Alles auswählen

import re

def flatten(l):
    result = []
    for el in l:
        if hasattr(el, "__iter__") and not isinstance(el, basestring):
            result.extend(flatten(el))
        else:
            result.append(el)
    return result

def tokenize(l):
    result = []
    for el in l:
        result += el.split(', ')
    return result

module_string = open('TestProg.mod').read();
import_re = re.compile(r'^IMPORT\s+([^;]*)|^FROM\s+([^\s]*)', re.M)
imports = import_re.findall(module_string)
imports = flatten(imports)
imports = filter(lambda x: x != '', imports)
imports = tokenize(imports)
imports = map(lambda x: x.strip(), imports)
imports = map(lambda x: x + '.def', imports)
print imports
Eingabe:

Code: Alles auswählen

MODULE TestProg;

IMPORT ModulA;
IMPORT ModulB, ModulC;
FROM ModulD IMPORT FunctionA;
FROM ModulE IMPORT FunctionB, FunctionC;

       IMPORT    ModulF     ;
IMPORT
                ModulG  ,    ModulH,
                           ModulI    ;
FROM    ModulJ         IMPORT FunctionD ,         FunctionE      ;


BEGIN

END TestProg.
Ausgabe:

Code: Alles auswählen

['ModulA.def', 'ModulB.def', 'ModulC.def', 'ModulD.def', 'ModulE.def', 'ModulF.def', 'ModulG.def', 'ModulH.def', 'ModulI.def', 'ModulJ.def']
Einen fehler in meiner regex hab ich noch gefunden:

Wenn das IMPORT eines FROM IMPORT statements in einer neuen Zeile steht wird es als IMPORT interpretiert. Eine Idee?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Martin Kalbfuß hat geschrieben:Ich schreibe einen scanner für das SCons build system.
Was meinst du denn mit Scanner? Einen Parser/Lexer? Wenn ja, warum willst du dich dann auf die SCons-Versionen festnageln lassen, wenn das doch nichts mit SCons zu tun hat (abseits des Inputs).
Martin Kalbfuß hat geschrieben:Da SCons auf python 1.5.2 aufbaut will ich dies nicht untergraben in dem ich code für höhere versionen schreibe.
Ich verstehe das als _mindestens_ 1.5.2. 1.5.2 ist 10 (in worten: ZEHN) Jahre alt. Ich gehe nicht davon aus, dass das noch jemand einsetzt (und noch nicht verrueckt geworden ist).
Martin Kalbfuß
User
Beiträge: 21
Registriert: Freitag 23. Mai 2008, 09:17

Ein Scanner ist in diesem fall dazu gedacht Implizite Abhängigkeiten der Quelldateien aufzufinden um zu prüfen ob sie neu compiliert werden sollen. In diesem Fall sind das die importierten Definitionsmodule.

Scons hat aber nur Scanner für die CPP includes.
z.B #include <blabla.h>.

Also muss ich das SCons system erweitern und meinen eigenen Scanner schreiben.

Ich selbst benutzte ein neueres python. Aber ich will dass mein Code wenn er funkioniert in SCons integriert wird. Und deshalb muss ich kompatibel bleiben. Finde ja auch das die ruhig auf eine aktuellere Version umsteigen könnten.

Ich würde das ganze ja gerne nur mit einer regex durchführen. Bekomm es aber nicht hin. Wenn es denn überhaupt möglich ist.

Vielleicht noch ein paar infos über die Zielsetzung.
Der input ist ein Modula-2 Hauptmodul welches Definitionsmodule importiert.
Ich muss die namen der importierten Module aus dem Code auslesen.

Es gibt zwei Varianten:

IMPORT modulname {, modulname};
FROM modulname IMPORT identität {,identität};
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Martin Kalbfuß hat geschrieben: Ich schreibe einen scanner für das SCons build system. Da SCons auf python 1.5.2 aufbaut will ich dies nicht untergraben in dem ich code für höhere versionen schreibe.
Wie habe ich denn dann die Anmerkung "This release notably contains numerous fixes and minor enhancements including Python 2.6 portability fixes." für das Release von SCons 1.2.0 vom Ende letzten Jahres zu verstehen?
Martin Kalbfuß
User
Beiträge: 21
Registriert: Freitag 23. Mai 2008, 09:17

portability fixes Ich denke mal das das bedeuten soll, dass einige Probleme die bei der Verwendung von 2.6 auftraten gelöst wurden. Scons ist kompatibel zu >= 1.5.2.

In der Doku steht ganz klar 1.5.2 als minimal anforderung. Wenn mein Code also nicht compatibel zu 1.5.2 ist hat er nix in SCons verloren.

Ich hab mal auf der SCons Mailingliste angefragt um das klarzustellen. Könnte aber ein wenig dauern bis die Antwort ankommt. Es könnte ja sein das die Doku veraltet ist. Kommt ja des öfteren vor das die Doku von Projekten mit deren Entwicklung nicht mithält.

Vielleicht hat ja Jemand unabhängig von der verwendeten Version einen Verbesserungsvorschlag bezüglich der Regex.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Es sieht so aus, als ob die Modula-2-Imports einlesen willst. Allgemein ist es in solchen Fällen am besten, nicht einfach reguläre Ausdrücke zu benutzen, sondern einen Parser, dem ggf. ein Scanner vorgeschaltet ist. Die ist ein Ausschnitt der Modula-2-Grammatik:

Code: Alles auswählen

Import = ["FROM" ModuleName] "IMPORT" Identifier {"," Identifier} ";"
ModuleName = Identifier {"." Identifier} 
Mit regulären Ausdrücken würde ich's so machen:

Code: Alles auswählen

import re, string

imports = []
t = re.compile(r'(?ms)(?:FROM\s+(.*?)\s+)?IMPORT\s+(.*?)\s*;|(BEGIN)')
for g1, g2, g3 in t.findall(s):
    if g3: break
    if g1: imports.append(g1)
    else: imports.extend(map(string.strip, string.split(g2, ",")))
print imports;
Niemand zwingt den Modula-2-Programmierer, sein FROM oder IMPORT an den Zeilenanfang zu packen. Also kein "^". Außerdem kann die Modulliste über mehrere Zeilen gehen, daher nutze ich nicht nur "multiline" sondern auch "dotall". Um nicht zu viele "false positives" zu bekommen, wenn z.B. etwas, das wie ein IMPORT aussieht, in einem String steht, breche ich bei "BEGIN" mit der Suche ab.

Da Python 1.x noch keine String-Methoden kennt (glaube ich), brauche ich das "string"-Modul. Was mit `extend` und `append` ist, weiß ich nicht. `map` gab es jedenfalls auch da schon.

Stefan
Martin Kalbfuß
User
Beiträge: 21
Registriert: Freitag 23. Mai 2008, 09:17

Danke Stefan,

Dein Lösungsvorschlag sieht gut aus. Darf ich ihn so wie er dort steht verwenden?

Sieht ja so aus als ob du das schonmal gemacht hast. Darf ich fragen für was du das gebraucht hast?

Ich denke Ich werde mir einen 1.5.2 Interpreter installieren. Dann kann ich mir sicher sein, dass ich kompatibel bleibe. Oder gibt es so etwas wie einen Kompatibilitätsmodus?

Die SCons Mailingliste hat leider noch keine Antwort ausgespuckt. Diese Mailinglisten sind ja teilweise sowas von träge, leider aber oft die einzige Anlaufstelle.

Wenn ich hier so mit Python arbeite bekomm ich wieder lust auf Python programmierung. Ich denke wenn ich den Builder für den GNU-Modula-2 Compiler fertig habe werd ich schauen ob ich's hin bekomme ihn in ein Modula-2 Programm einzubetten.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Martin Kalbfuß hat geschrieben:Dein Lösungsvorschlag sieht gut aus. Darf ich ihn so wie er dort steht verwenden?
Klar. Sonst hätte ich's nicht geschrieben.
Martin Kalbfuß hat geschrieben: Sieht ja so aus als ob du das schonmal gemacht hast. Darf ich fragen für was du das gebraucht hast?
Nope. Mein einziger Kontakt mit Modula 2 war vor vielen Jahren als ich noch einen Amiga hatte. An der Uni sollten wir Pascal lernen, ich dachte aber, warum nicht gleich den Nachfolger lernen.

Parser und Scanner bauen ist aber aber Hobby von mir :)
Martin Kalbfuß hat geschrieben:Oder gibt es so etwas wie einen Kompatibilitätsmodus?
Nein. Ich hatte mal einen Python 1.5-Interpreter gebaut. Daher wusste ich das noch mit dem string-Modul. Auch wenn zwischen 1.x und 2.x nicht so viel verändert wurde, ist es tatsächlich wohl das beste, diesen antiken Interpreter zu installieren. Unter Unix/Mac kompiliert der Quelltext problemlos.
Martin Kalbfuß hat geschrieben:Die SCons Mailingliste hat leider noch keine Antwort ausgespuckt. Diese Mailinglisten sind ja teilweise sowas von träge, leider aber oft die einzige Anlaufstelle.
Vielleicht weil kaum einer dieses doch recht exotische Buildsystem benutzt?

Stefan
Antworten