normaler Text durch Python Java-kompatibel machen

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
Alicia_Carlos
User
Beiträge: 4
Registriert: Donnerstag 19. November 2009, 18:21

Hallo zusammen,

ich habe folgendes Problem :oops: :

ich will aus einem normalen Text einen Java_Quellcode mit Hilfe von Python generieren, d.h. ich soll ein Python-Skript erstellen, das eine Menge von Textdateien einliest und den darin sich befindenden Text Java-kompatibel machen soll.

Beispiel:

folgender Text wird eingelesen:

Code: Alles auswählen

public class HalloWelt 
public static void main(String[] args) 
System.out.println("Hallo Welt!")
und folgender Text soll nach Bearbeitung in der Datei stehen:

Code: Alles auswählen

public class HalloWelt {                                   # Klammer
     public static void main(String[] args) {        # erste Ebene eingerückt
     System.out.println("Hallo Welt!");
     }                                                              # Klammer zu
 }                                                                  # Ende erste Ebene und   
                                                                     # zurück auf Ebene 0
D.h. ich will Funktionen so einrichten dass sie nach Schlüsselwörtern wie "public class" etc. das Programm weiss, dass es in der nächsten Zeile in die nächste "Ebene" gehen muss, d.h. der Text in der nächsten Zeile also eingerückt werden muss. Und dies nicht nur für eine sondern viele Ebenen (zweite, dritte, etc.) und dabei die Klammern gesetzt werden müssen. Und ähnlich wenn die Klammer zugehen muss in die nächstuntere Ebene zurückgegangen werden muss (s.o.).

Danke euch :oops:

Alicia

Edit (BlackJack): Quelltext in Codetags gesetzt.
Alicia_Carlos
User
Beiträge: 4
Registriert: Donnerstag 19. November 2009, 18:21

Der Text oben muss natürlich eingerückt sein! Sorry :oops: Darum geht es ja eigentlich! Weiss nicht warum das nicht rausgekommen ist.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Code-Tags helfen. ;)
Alicia_Carlos hat geschrieben:

Code: Alles auswählen

public class HalloWelt {
    public static void main(String[] args) {
        System.out.println("Hallo Welt!");
    }
}
BlackJack

@Alicia_Carlos: Das was Du willst geht nicht. Nehmen wir mal folgende Eingabe:

Code: Alles auswählen

if (foo)
bar();
baz();
if (spam)
ham();
Das kann folgende drei Ausgaben bedeuten:

Code: Alles auswählen

if (foo) {
    bar();
}
baz();
if (spam) {
    ham();
}

// ------------------------------------

if (foo) {
    bar();
    baz();
}
if (spam) {
    ham();
}

// ------------------------------------

if (foo) {
    bar();
    baz();
    if (spam) {
        ham();
    }
}
Das gleiche Spielchen gibt's mit (inneren) Klassen und Schleifen. Wenn auch leere Blöcke erlaubt sind, gibt's noch mehr Möglichkeiten.
Alicia_Carlos
User
Beiträge: 4
Registriert: Donnerstag 19. November 2009, 18:21

Danke für eure Antworten erstmal! :)

@BlackJack: Du hast Recht! Ich hätte noch hinzufügen müssen: es handelt sich um "eindeutige" Schlüsselwörter, die im Text nicht 2-Mal vorkommen können. D.h. "if" kann nur einmal im Text vorkommen. Es geht vorzugsweise um die Einrückung und nicht direkt um den Inhalt des Textes. Danke dir :)
problembär

Wirst halt mit Deinen Dateien sehr viel rumprobieren müssen (im Prinzip ist alles möglich, was denklogisch möglich ist).
Hier mal ein kleines Beispiel zum Einstieg (das natürlich versagt, sobald der Ausgangscode ein bißchen komplizierter wird):

Code: Alles auswählen

#!/usr/bin/env python
#-*- coding: iso-8859-1 -*-

a = """public class HalloWelt
public static void main(String[] args)
System.out.println("Hallo Welt!")"""
a = a.split("\n")

il = 0
indent = 4

def isClassStart(line, il):

    if "class" in line and il == 0:
        return True
    else:
        return False

def isFuncStart(line, il):
    if line.startswith(il * indent * " " + "public static") and line.count("(") == 1 and line.count(")") == 1 and line.endswith(")"):
        return True
    else:
        return False

def closingBrackets(from_, to_):
    a = []
    for i in range(from_, to_, -1):
        a.append((i - 1) * indent * " " + "}")
    return a

for i in range(len(a)):

    a[i] = il * indent * " " + a[i]

    if isClassStart(a[i], il) and not "{" in a[i]:
        a[i] = a[i] + " {"
        il += 1

    elif isFuncStart(a[i], il) and not "{" in a[i]:
        a[i] = a[i] + " {"
        il += 1

    else:
        if not a[i].endswith(";"):
            a[i] += ";"

a.extend(closingBrackets(il, 0))

for i in a:
    print i
Gruß
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

@problembär

Deine Lösung ist vielerlei hinsicht nicht wirklich gut.

Die globale Verwendung von "il" auf Modulebene ist ganz grausam und sollte einem Anfänger nicht in einem Beispielcode vorgeführt werden.
Ich sehe nirgendwo das "il" wieder dekrementiert wird wenn man einen Block verlässt.
Dieses Beispiel wird schon versagen sobal ein Leerzeichen mehr oder weniger vorhanden ist.
So primitiv ist es nun einmal nicht zu lösen...
Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

Zap hat geschrieben:@problembär

Deine Lösung ist vielerlei hinsicht nicht wirklich gut.

Die globale Verwendung von "il" auf Modulebene ist ganz grausam und sollte einem Anfänger nicht in einem Beispielcode vorgeführt werden.
Ich sehe nirgendwo das "il" wieder dekrementiert wird wenn man einen Block verlässt.
Dieses Beispiel wird schon versagen sobal ein Leerzeichen mehr oder weniger vorhanden ist.
So primitiv ist es nun einmal nicht zu lösen...
Das sehe ich nicht so. Eigentlich ist es sogar schön gelöst, wie er die beiden Werte an die Funktionen übergibt. ;) Könnte man ja auch mit 'global' machen :lol: . Man könnte höchstens kritisieren, daß es sich ja praktisch um Konstanten handelt, sie also komplett großgeschrieben werden sollten.

Manchmal habe ich den Eindruck, daß es hier mehr um Erbsenzählereien geht, als um Problemlösungen.

Nachtrag: Ok, das 'il' dann in der Schleife tatsächlich manipuliert wird, ist mir durchgerutscht. Das ist tatsächlich unschön. Trotzdem bleibt bei mir der Eindruck, daß einige hier aus den Augen verlieren, daß es in erster Linie um die Lösung von Probleme geht, und erst in zweiter um "ästethische" Fragen.

Das man sich mit manchen dieser "ästethischen" Probleme später ganz schön ins Knie schießen kann, ist mir auch klar. Aber, um mal eine Erfahrung aus der Kinderziehung einzubringen: Manche Sachen muß man einfach auf die harte Tour lernen.
problembär

Danke, Pekh!
Pekh hat geschrieben:Nachtrag: Ok, das 'il' dann in der Schleife tatsächlich manipuliert wird, ist mir durchgerutscht.
Ja, das ist nicht so schön. Hatte aber nur begrenzte Zeit dafür. Da waren halt mehr Probleme, als ich zunächst gedacht hatte. Da wird man dann mal etwas nachlässig oder benutzt den einen oder anderen "Hack". Kann ja jeder mal besser machen. Soll der OP ja sowieso nur generell eine mögliche Richtung zeigen, "Kladde" sozusagen.
"il" ist natürlich "indentation_level". Kann man mit viel Zeit auch ausschreiben.

Gruß
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Code: Alles auswählen

def f(...):
    if <bool expression>:
        return True
    else:
        return False
Ist redudant:

Code: Alles auswählen

def f(...):
    return <bool expression>
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Aus der Aufgabenstellung und dem Beispiel kann man eigentlich keine Lösung bilden, denn es ist nicht ablesbar, wo das Ende eines Blocks ist. Dies ist aber zumindest ein Gerüst:

Code: Alles auswählen

s = """\
public class HalloWelt 
public static void main(String[] args) 
System.out.println("Hallo Welt!")
"""

level = 0

def out(s):
    print "  " * level + s

for line in s.splitlines():
    if line.startswith("public class") or line.startswith("public static void"):
        out(line + "{"); level += 1
    else: out(line)
level -= 1; out("}")
level -= 1; out("}")
Stefan
Antworten