Ok, ich habe eine Reihe kleinerer Fragen zu diesem Projekt gestellt, aber ich habe immer noch nicht viel Vertrauen in die Designs, die ich mir ausgedacht habe, also werde ich eine breitere Frage stellen .Wie analysiere ich am besten eine einfache Grammatik?
Ich analysiere die erforderlichen Beschreibungen für einen Kurskatalog. Die Beschreibungen folgen fast immer einer bestimmten Form, was mich denken lässt, dass ich die meisten von ihnen analysieren kann.
Aus dem Text möchte ich eine Grafik der natürlich erforderlichen Beziehungen generieren. (Dieser Teil wird einfach sein, nachdem ich die Daten analysiert haben.)
Einige Beispiel Ein- und Ausgänge:
"CS 2110" => ("CS", 2110) # 0
"CS 2110 and INFO 3300" => [("CS", 2110), ("INFO", 3300)] # 1
"CS 2110, INFO 3300" => [("CS", 2110), ("INFO", 3300)] # 1
"CS 2110, 3300, 3140" => [("CS", 2110), ("CS", 3300), ("CS", 3140)] # 1
"CS 2110 or INFO 3300" => [[("CS", 2110)], [("INFO", 3300)]] # 2
"MATH 2210, 2230, 2310, or 2940" => [[("MATH", 2210), ("MATH", 2230), ("MATH", 2310)], [("MATH", 2940)]] # 3
Wenn die gesamte Beschreibung nur ein Kurs ist, ist es direkt ausgegeben.
Wenn die Kurse verbunden sind ("und"), sie alle Ausgaben in derselben Liste sind
Wenn der Kurs disjoined werden ("oder"), sie sind in separaten Listen
Hier haben wir beide "und" und "oder".
Eine Einschränkung, die es einfacher macht: es scheint, dass die Verschachtelung „und“/„oder“ Sätze nie größer als wie in Beispiel 3 gezeigt
Was ist der beste Weg, dies zu tun ? Ich habe mit PLY begonnen, aber ich konnte nicht herausfinden, wie man die Konflikte reduzieren/reduzieren kann. Der Vorteil von PLY ist, dass es leicht zu manipulieren, was jeder Parse-Regel generiert:
def p_course(p):
'course : DEPT_CODE COURSE_NUMBER'
p[0] = (p[1], int(p[2]))
Mit PyParse, es ist weniger klar, wie die Ausgabe von parseString()
zu ändern. Ich überlegte, ob ich auf der Idee von Alexander Martelli aufbauen sollte, den Zustand in einem Objekt zu halten und die Ergebnisse daraus zu entwickeln, aber ich bin mir nicht sicher, wie das am besten funktioniert.
def addCourse(self, str, location, tokens):
self.result.append((tokens[0][0], tokens[0][1]))
def makeCourseList(self, str, location, tokens):
dept = tokens[0][0]
new_tokens = [(dept, tokens[0][1])]
new_tokens.extend((dept, tok) for tok in tokens[1:])
self.result.append(new_tokens)
Zum Beispiel behandeln "oder" Fälle:
def __init__(self):
self.result = []
# ...
self.statement = (course_data + Optional(OR_CONJ + course_data)).setParseAction(self.disjunctionCourses)
def disjunctionCourses(self, str, location, tokens):
if len(tokens) == 1:
return tokens
print "disjunction tokens: %s" % tokens
Wie disjunctionCourses()
, die nicht wissen, kleinere Sätze abzutrennen? Alles, was es bekommt, ist Tokens, aber was bisher geparst wurde, ist in result
gespeichert. Wie kann die Funktion also mitteilen, welche Daten in result
welchen Elementen von token
entsprechen? Ich glaube, ich durch die Token suchen könnte, dann ein Element der result
mit den gleichen Daten finden, aber das Gefühl, gewundenen ...
Auch gibt es viele Beschreibungen, die misc Text enthalten, wie:
"CS 2110 or permission of instructor"
"INFO 3140 or equivalent experience"
"PYSCH 2210 and sophomore standing"
Aber es ist nicht kritisch, dass ich diesen Text analysiere.
Was ist ein besserer Weg, dieses Problem anzugehen?
Die Nummerierung in den Beispieleingängen und -ausgängen stimmt nicht mit der Nummerierung in Ihrer Beschreibung überein. –