Pyparsing

2,429 views

Published on

Vorstellung des Moduls Pyparsing (Tobias Schlauch, Python User Group Köln, 14.05.2008)

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,429
On SlideShare
0
From Embeds
0
Number of Embeds
20
Actions
Shares
0
Downloads
21
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Pyparsing

  1. 1. Pyparsing Tobias Schlauch, DLR Simulations- und Softwaretechnik Python User Group Köln 14. Mai 2008 Folie 1
  2. 2. Motivation DataFinder Software zum Management wissenschaftlich-technischer Daten Implementierung in Python und Qt Problem Vereinfachung des DataFinder-API zur Suche in Metadaten erforderlich Anstatt Syntax mit Hilfe definierter Klassen abzubilden, soll einfache Verwendung von Zeichenketten ausreichen, wie z.B. projectName = quot;X-38quot; and author = quot;Schüttequot; Lösungvariante Reguläre Ausdrücke Schön… aber was macht das hier eigentlich??? quot;[-+]?(d+(.d*)?|.d+)([eE][-+]?d+)?quot; Alternativen…? Folie 2
  3. 3. Pyparsing im Überblick Was ist Pyparsing? Klassenbibliothek zur Erstellung von Parsern (recursive descent) Design auf einfache Erstellung und Aktualisierung ausgelegt Parser für regulären Sprachen und Teilmenge kontextfreier Sprachen (vgl. Chomsky-Hierarchie) Pure-Python, Python >= 2.3.2 MIT-Lizenz Gute Dokumentation Epydoc, Klassendiagramm, Beispiele, Wiki Folie 3
  4. 4. Was macht eigentlich ein Parser? (vereinfacht) Zeichenstrom |H|e|l|l|o|,|Wo|r|l|d|!| „Hello,World!“-Parser Syntaktisch korrekt? Abgeleitete Token |Hello|,|World|!| Folie 4
  5. 5. Grundlegende Vorgehensweise mit Pyparsing 1. Definition der Grammatik (Token / Verknüpfungen) Hierarchische Definition Optionale Definition von Ergebnisnamen und Parseraktionen 2. Aufruf von parseString oder scanString Standardmäßig werden Whitespaces ignoriert Anwendung definierter Parseraktionen 3. Verarbeitung des Ergebnisses als Liste oder unter Verwendung der definierter Namen Folie 5
  6. 6. Erstes Beispiel Hello World! Definition der Token / Muster greeting = oneOf(quot;Hello Hiquot;) + Literal(quot;,quot;) + Word(alphas) + Literal(quot;!quot;) Aufruf von parseString() print greeting.parseString(quot;Hello, World!quot;).asList() ['Hello', ',', 'World', '!'] print greeting.parseString(„Hi, SISTECquot;) pyparsing.ParseException: Expected quot;!quot; (at char 13), (line:1, col:14) Ups „!“ vergessen Folie 6
  7. 7. Pyparsing Grundlagen Definition fester Token Literal / CaselessLiteral ifToken = Literal(quot;ifquot;) Findet das Token in if(x=1) und in ifAndOnlyYouAndMe Keyword / CaselessKeyword ifToken = Keyword(quot;ifquot;) Findet das Token in if(x=1), aber nicht in ifAndOnlyYouAndMe Caseless-Varianten geben als Ergebnis immer die definierte Variante zurück, also hier if Folie 7
  8. 8. Pyparsing Grundlagen Definition variabler Token Word – Definition durch erlaubte Zeichen name = Word(quot;Tabiosquot;) name = Word(quot;Tquot;, quot;abiosquot;) CharsNotIn – Definition durch nicht erlaubter Zeichen name = CharsNotIn(quot;,;:-!quot;) Zusätzlich Spezifikation der Länge möglich (min, max, exakt) Regex Erwartet als Parameter einen regulären Ausdruck, wie für das Standardmodul re Vorher nach Pyparsing-Lösung suchen!!! Folie 8
  9. 9. Pyparsing Grundlagen Verknüpfungen And (+) – Definition erforderlicher Ausdrücke in fester Reihenfolge sentence = And([subject, verb, object]) sentence = subject + verb + object Each (&) – Definition erforderlicher Ausdrücke in beliebiger Reihenfolge identity = persNumber & name Or (^) – Definition alternativer Ausdrücke (Priorität: Zeichenkettenlänge) operator = Literal(quot;<quot;) ^ Literal(quot;<=quot;) MatchFirst (|) – Definition alternativer Ausdrücke (Priorität: Definitions- reihenfolge) operator = Literal(quot;<=quot;) | Literal(quot;<quot;) Folie 9
  10. 10. Pyparsing Grundlagen Optionale Ausdrücke, Wiederholungen Optional Definition optionaler Ausdrücke dateTime = day + quot;.quot; + month + quot;.quot; + year + Optional(time) ZeroOrMore Ähnlich zu Optional, aber erlaubt Wiederholungen logMsg = dateTime + ZeroOrMore(Word(alphas)) OneOrMore Ähnlich zu ZeroOrMore, aber erfordert mindestens einen Treffer logMsg = dateTime + OneOrMore(Word(alphas)) Folie 10
  11. 11. Pyparsing Grundlagen Konvertierungen Upcase - Konvertierung in Großbuchstaben Suppress - Unterdrückung von Token date = day + Suppress(quot;.quot;) + month + Suppress(quot;.quot;) + year print date.parseString(quot;11.03.2008quot;).asList() [quot;11quot;, quot;03quot;, quot;2008quot;] Combine – Verbindet einzelne Token zu einer Zeichenkette date = Combine(day + quot;.quot; + month + quot;.quot; + year) print date.parseString(quot;11.03.2008quot;).asList() [quot;11.03.2008quot;] anstatt [quot;11quot;, quot;.quot;, quot;03quot;, quot;.quot;, quot;2008quot;] (ohne Combine) Folie 11
  12. 12. Pyparsing Grundlagen Rekursive Grammatiken Forward – Platzhalter zur Definition rekursiver Grammatiken Beispiel Parsen einer Liste list = Forward() listItem = Word(alphas) list << (listItem + Suppress(Literal(quot;,quot;)) + list | listItem) print list.parseString(quot;Wert , Name, testquot;).asList() [quot;Wertquot;, quot;Namequot;, quot;testquot;] Klammerung beachten! (Operator | bindet stärker als <<) Überprüfung auf Endlosrekursion durch Aufruf von validate() Folie 12
  13. 13. Pyparsing Grundlagen Parseraktionen Erlaubt Änderung der erkannten Token während des Parsevorgangs Hinzufügen / Entfernen von Informationen Konvertierungen … 3 Schnittstellen f(t); t – Liste erkannter Token f(l, t); l – Position im zu parsenden String f(s, l, t); s – Zu parsender String Hilfsfunktionen replaceWith(replaceString) removeQuotes() … Folie 13
  14. 14. Pyparsing Grundlagen Parseraktionen - Beispiel Definition einer Aktion zur Konvertierung def convertNumValue(t): numValue = t.asList()[0] try: return int(numValue) except ValueError: return float(numValue) Anhängen der Aktion numValue.setParseAction(convertNumValue) oder numValue.addParseAction(convertNumValue) Ergebnis print numValue.parseString(quot;12340quot;).asList() [12340] anstatt [quot;12340quot;] Folie 14
  15. 15. Pyparsing Grundlagen Hilfsfunktionen (kleine Auswahl) oneOf – Vereinfachte Definition von Alternativen options = oneOf(quot;< > <= = >=quot;) delimitedList – Parsen von Listen list = delimitedList(Word(alphas), quot;,quot;) nestedExpr – Parsen von verschalteten Ausdrücken nested = nestedExpr(quot;(quot;, quot;)quot;, Word(alphas)) print nested.parseString(quot;(abc(def(gh)))quot;).asList() [[quot;abcquot;, [quot;defquot;, [quot;ghquot;]]]] operatorPrecedence – Parsen von Operatorrangfolgen (später mehr) Folie 15
  16. 16. Pyparsing Grundlagen Verarbeitung von Ergebnissen Geparste Token werden in einer hierarchischen Struktur zurückgegeben (ParsingResults) Verarbeitung der Token als Listen, XML, Dictionary oder über die Objekteigenschaften möglich Verarbeitung als Dictionary oder über Objekteigenschaften setzt Benennung der Ergebnisse bei der Definition voraus Überschaubarer Grammatiken -> Benennung nicht unbedingt erforderlich Komplexer Grammatiken -> Benennung empfohlen Folie 16
  17. 17. Pyparsing Grundlagen Verarbeitung von Ergebnissen - Beispiel Definition der Token / Muster date = day.setResultsName(quot;dayquot;) + quot;.quot; + month.setResultsName(quot;monthquot;) + quot;.quot; + year.setResultsName(quot;yearquot;) token = date.parseString(quot;11.03.2008quot;) Ausgaben print token.asList() [quot;11quot;, quot;.quot;, quot;03quot;, quot;.quot;, quot;2008quot;] print token.asXML() quot;<ITEM><day>11</day><ITEM>quot;.quot;</ITEM><month…quot; print token.asDict() {quot;dayquot;: quot;11quot;, quot;monthquot;: quot;03quot;, quot;yearquot;: quot;2008quot;} print token.day quot;11quot; Folie 17
  18. 18. Pyparsing Grundlagen … Pyparsing enthält noch etliche Details, die aber den Rahmen dieses Vortrags sprengen, z.B.: Ergebnisgruppierungen Group, Dict Weitere Hilfsfunktionen Verarbeitung XML, HTML Positionsabhängige Hilfsfunktionen Tokenkonstanten (z.B. für Kommentare) Folie 18
  19. 19. Performance-Tuning Aktivierung von Packrat-Parsing (enablePackrat) Verwendung von Psyco (http://psyco.sourceforge.net/) Verliog-Parser Python V2.4.1 Python V2.5 (lines parsed (lines parsed /second) /second) base 160.6 146.5 packrat 428.7 395.8 psyco 365.7 - n/a - packrat + psyco 614.4 - n/a - Quelle: http://pyparsing.wikispaces.com/News Folie 19
  20. 20. Suchrestriktionen im DataFinder Definition der Grammatik (stark vereinfacht) literal = QuotedString(quot;'quot;) propertyName = Word(alphas) comparisionTerm = propertyName + oneOf(quot;< > <= => =quot;) + literal searchRestriction = operatorPrecedence(comparisionTerm, [(quot;notquot;, 1, opAssoc.RIGHT), (quot;andquot;, 2, opAssoc.LEFT), (quot;orquot;, 2, opAssoc.LEFT)]) Beispiel myRestr = quot;a > 'test' and not(b < '3')quot; print searchRestriction.parseString(myRestr).asList() [[quot;aquot;, quot; >quot;, quot;testquot;, quot;andquot;, [quot;notquot;, quot;bquot;, quot;<quot;, quot;3quot;]]] Folie 20
  21. 21. Suchrestriktionen im DataFinder Anwendung Zentrale Grammatikdefinition wird genutzt für Transformation der geparsten Token auf Syntax der Bibliothek, welche intern zur Suchabfrage genutzt wird Syntax-Highlighting Folie 21
  22. 22. Vielen Dank! Fragen?? Pyparsing Links News: http://pyparsing.wikispaces.com/News Beispiele: http://pyparsing.wikispaces.com/Examples Download: http://sourceforge.net/project/showfiles.php?group_id=97203 Weiterführendes zum Thema: Compilerbau: http://de.wikipedia.org/wiki/Compilerbau Aho, Sethi, Ullman: Compilerbau, Tl. 1. Oldenbourg, 1999 Recursive Descent Parser: http://en.wikipedia.org/wiki/Recursive_descent_parser Packrat-Parsing: http://pdos.csail.mit.edu/~baford/packrat/ Alternative Python-Parsersysteme: http://pythonsource.com/open- source/parser-generators Folie 22

×