Seite 1 von 1
Problem: Hänge das Ergebnis des rekursiven Aufrufs...
Verfasst: Samstag 21. Januar 2006, 14:38
von Gisi
Hi,
bin mal wieder am Verzweifeln. Folgender Pseudocode
http://www.cl.uni-heidelberg.de/kurs/ws ... pseudo.pdf
soll die Lösung der zweiten Aufgabe dieses Blattes
http://www.cl.uni-heidelberg.de/kurs/ws ... latt10.pdf
sein. Bisher sieht mein nicht funktionierender Code so aus:
Code: Alles auswählen
import operator
import re
def parseBracketStructure(tokens):
result = []
liste = tokenize(tokens)
while len(liste) > 0:
element = liste.pop(0)
if element == "<":
result.append(parseBracketStructure(tokens))
if element == ">":
return result
else:
result.append(element)
return result
def tokenize(text):
return map(str.strip,
filter(operator.truth, re.split("([<>])", text)))
Ich glaube zu wissen, dass das Problem in der Zeile:
[code = py]if element == "<":
result.append(parseBracketStructure(tokens))[/code]
liegt. Lasse ich nämlich als tokens zB "hallo" oder auch "hallo>" laufen, funktioniert das ganze. Nur sobald ein "<" in tokens auftaucht, kommt ein RuntimeError.
Kann mir da wer helfen?
besten dank,
Gisi
[/code]
Verfasst: Samstag 21. Januar 2006, 15:37
von Joghurt
Beim rekursiven Aufruf darfst du nur den rest der Liste übergeben, nicht wieder dieselben Daten, die du schon bekommen hast, das führt nämlich zu einer Endlosschleife:
Besser (ungetestet):
Code: Alles auswählen
def parseBracketStructure(tokens):
result = []
while len(tokens) > 0:
element = tokens.pop(0)
if element == "<":
result.append(parseBracketStructure(tokens))
if element == ">":
return result
else:
result.append(element)
return result
Aufruf dann mit
parseBracketStructure(tokenize(text))
Verfasst: Samstag 21. Januar 2006, 15:43
von Mad-Marty
Da waren mehrere Fehler, ich habs mal gelöst inkl. Zusatz .
Richtig wäre:
Code: Alles auswählen
import operator
import re
def parseBracketStructure(liste):
result = []
while len(liste) > 0:
element = liste.pop(0)
if element == "<":
result.append(parseBracketStructure(liste))
elif element == ">":
return result
else:
result.append(element)
return result
def tokenize(text):
if text.count("<") != text.count(">"):
print "Warning, not all parantheses closed !"
return map(str.strip,
filter(operator.truth, re.split("([<>])", text)))
tokens = tokenize("<a <b c> d<ef> g")
print parseBracketStructure(tokens)
#print parseBracketStructure(tokenize("<a <b c> d<ef> g")) ---> [['a', ['b c'], 'd', ['ef'], 'g']]
Verfasst: Samstag 21. Januar 2006, 21:31
von BlackJack
Eine "Lösung" mit `pyparsing`:
Code: Alles auswählen
from pyparsing import Suppress, OneOrMore, CharsNotIn, Forward, Group, \
StringEnd, ParseException
OPEN = Suppress('<')
CLOSE = Suppress('>')
data = OneOrMore(CharsNotIn('<>'))
mylist = Forward()
mylist << OneOrMore(data | Group(OPEN + mylist + CLOSE))
parser = mylist + StringEnd()
#
# Test
#
tests = ('<a <b c> d<ef> g',
'<a <b c> d<ef> g>',
'<<der><hund>><<beisst><<den><mann>>>',
'<<der><hund>><<beisst><<den><mann>>>>')
for i, test in enumerate(tests):
print '-' * 40
print 'Test %d: %s' % (i + 1, test)
try:
result = parser.parseString(test)
print result.asList()
except ParseException, error:
print 'Error:'
print error.pstr
print ' ' * (error.loc - 1), '^'
print error.msg
Ist natürlich keine Lösung der Hausaufgabe weil dort ja gelernt werden soll wie man einen rekursiven Parser selber schreibt, aber das kann ich schon.

Verfasst: Samstag 21. Januar 2006, 21:39
von Gisi
Geniel, besten Dank euch beiden. Mein Problem war, dass ich nicht gesehen habe, dass auf dem Aufgabenblatt die Beispiele schon mit der tokenize Funktion in die Eingabe geschrieben wurden. Deshalb hab ich immer versucht, das in die parseBracketStructure Funktion einzubauen. Wäre aber ohne eure Hilfe nicht drauf gekommen, also herzlichen Dank nochmal.
Die von Mad-Marty gelöste Zusatzaufgabe kann ich nachvollziehen. Nur sollte das ganze dann abbrechen, momentan wird ja zwar die Fehlermeldung ausgegeben, das ganze läuft aber weiter und gibt eine Liste zurück. Mit der Fehlermeldung sollte dann aber Schluss ein.
Aber daran probier ich mich jetzt selber noch
Gruß,
Gisi
Verfasst: Sonntag 22. Januar 2006, 01:38
von Mad-Marty
kleiner tip, es fängt mit "raise" an

Verfasst: Sonntag 22. Januar 2006, 01:48
von Gast
Hi,
habs jetzt gelöst, indem ich die tokenize Funktion zuerst verändert habe:
Code: Alles auswählen
def tokenize(text):
if text.count("<") != text.count(">"):
print "Warning, not all parantheses closed !"
return None
else:
return map(str.strip,
filter(operator.truth, re.split("([<>])", text)))
und dann oben noch eingefügt habe:
...der ganze Kram also nur dann ausgeführt wird, wenn auch wirklich von tokenize was zurückgegeben wird.
Und wie sähe das mit raise aus?
Gisi
Edit by Gerold: Code-Tags gesetzt
Verfasst: Sonntag 22. Januar 2006, 10:38
von Mad-Marty
Schau dir das an, um zu sehen wie du Exceptions raise'st.
(Ich schreibs jetzt absichtlich nicht fertig hin, für deine extrapunkte sollst du schonmal da reinschauen. )
http://docs.python.org/tut/node10.html# ... 0000000000