Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
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.548 Aufrufe

Veröffentlicht am

Veröffentlicht in: Technologie
  • Als Erste(r) kommentieren

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>

×