Tech Talk: Pyparsing Tobias Schlauch, DLR Simulations- und Softwaretechnik  11. März 2008 Folie
Motivation <ul><li>Problem </li></ul><ul><ul><li>Vereinfachung des DataFinder-API zur Suche in Metadaten erforderlich </li...
Pyparsing im Überblick <ul><li>Was ist Pyparsing? </li></ul><ul><ul><li>Klassenbibliothek zur Erstellung von Parsern (recu...
Was macht eigentlich ein Parser? (vereinfacht) |H|e|l|l|o|,|Wo|r|l|d|!| Syntaktisch korrekt? |Hello|,|World|!| „ Hello,Wor...
Grundlegende Vorgehensweise mit Pyparsing <ul><li>Definition der Grammatik (Token / Verknüpfungen) </li></ul><ul><ul><li>H...
Erstes Beispiel Hello World! <ul><li>Definition der Token / Muster </li></ul><ul><li>greeting = oneOf(&quot;Hello Hi&quot;...
Pyparsing Grundlagen Definition fester Token <ul><li>Literal / CaselessLiteral </li></ul><ul><ul><li>ifToken = Literal(&qu...
Pyparsing Grundlagen Definition variabler Token <ul><li>Word – Definition durch erlaubte Zeichen </li></ul><ul><ul><li>nam...
Pyparsing Grundlagen Verknüpfungen <ul><li>And (+) – Definition erforderlicher Ausdrücke in fester Reihenfolge </li></ul><...
Pyparsing Grundlagen Optionale Ausdrücke, Wiederholungen <ul><li>Optional </li></ul><ul><ul><li>Definition optionaler Ausd...
Pyparsing Grundlagen  Konvertierungen <ul><li>Upcase - Konvertierung in Großbuchstaben </li></ul><ul><li>Suppress - Unterd...
Pyparsing Grundlagen Rekursive Grammatiken <ul><li>Forward – Platzhalter zur Definition rekursiver Grammatiken </li></ul><...
Pyparsing Grundlagen Parseraktionen <ul><li>Erlaubt Änderung der erkannten Token während des Parsevorgangs </li></ul><ul><...
Pyparsing Grundlagen Parseraktionen - Beispiel <ul><li>Definition einer Aktion zur Konvertierung </li></ul><ul><li>def con...
Pyparsing Grundlagen Hilfsfunktionen (kleine Auswahl) <ul><li>oneOf – Vereinfachte Definition von Alternativen </li></ul><...
Pyparsing Grundlagen Verarbeitung von Ergebnissen <ul><li>Geparste Token werden in einer hierarchischen Struktur zurückgeg...
Pyparsing Grundlagen Verarbeitung von Ergebnissen - Beispiel <ul><li>Definition der Token / Muster </li></ul><ul><li>date ...
Pyparsing Grundlagen … <ul><li>Pyparsing enthält noch etliche Details, die aber den Rahmen dieses Vortrags sprengen, z.B.:...
Performance-Tuning <ul><li>Aktivierung von Packrat-Parsing ( enablePackrat ) </li></ul><ul><li>Verwendung von Psyco ( http...
Suchrestriktionen im DataFinder Definition der Grammatik (stark vereinfacht) <ul><li>literal = QuotedString( &quot;'&quot;...
Suchrestriktionen im DataFinder Anwendung <ul><li>Zentrale Grammatikdefinition wird genutzt für </li></ul><ul><ul><li>Tran...
Vielen Dank! Fragen?? <ul><li>Pyparsing Links </li></ul><ul><ul><li>News:  http://pyparsing.wikispaces.com/News </li></ul>...
Nächste SlideShare
Wird geladen in …5
×

Tech Talk: Pyparsing

1.484 Aufrufe

Veröffentlicht am

Veröffentlicht in: Technologie
0 Kommentare
1 Gefällt mir
Statistik
Notizen
  • Als Erste(r) kommentieren

Keine Downloads
Aufrufe
Aufrufe insgesamt
1.484
Auf SlideShare
0
Aus Einbettungen
0
Anzahl an Einbettungen
26
Aktionen
Geteilt
0
Downloads
12
Kommentare
0
Gefällt mir
1
Einbettungen 0
Keine Einbettungen

Keine Notizen für die Folie

Tech Talk: Pyparsing

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

×