Nach über drei Jahren hab ich's dank der Anregung eines Kollegen doch mal geschafft, meinen kleinen Parser-Generator in Python aufzuarbeiten und eine neue Version zu veröffentlichen. Diese bringt endlich rekursive Regeln und die Möglichkeit Regeln zu gruppieren. Außerdem sollte sie jetzt auch Python 3 kompatibel sein. Geblieben ist natürlich die einfache Definition von Parsern in Form einer (leicht abgewandelten) EBNF direkt in Python.
Weil Gelaber über Software ohne Beispiel immer doof ist hier ein Beispiel für das Parsen einer einfachen XML-ähnlichen Sprache:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
from yeanpypa import *
test = '<tag><inner attr="Just a test">plah</inner></tag>'
text = Word(alpha)
name = Combine(alpha + ZeroOrMore(alpha | digit))
value = Literal("\"").hide() + Word(alpha | AnyOf(" \t.,!?+-") | digit) + Literal("\"").hide()
attribute = name + Literal('=').hide() + value
opening_tag = Group(Literal('<').hide() + Word(alpha) + ZeroOrMore(attribute) + Literal('>').hide())
closing_tag = Group(Literal('').hide() + Word(alpha) + Literal('>').hide())
tag = Recursive()
tag.set(text | opening_tag + tag + closing_tag)
result = parse(tag, test)
print result.getTokens()
Die Ausgabe ist hierarchische Liste von Token sein (wobei alle, die mit .hide() markiert werden nicht enthalten sind):
[['tag'], [['inner', [['attr', ['Just a test']]]], 'plah', ['inner']], ['tag']]
Mittels semantischer Aktionen die an Teile der Regeln gehängt werden kann man komplexere Datenstrukturen on the fly aufbauen statt erst auf der endgültigen Tokenliste zu arbeiten. Bspw. könnte die Regel tag mittels einer semantischen Aktion ein Objekt einer Klasse Tag anlegen, welches strukturierten Zugriff auf die Bestandteile des Tags gibt. Semantische Aktionen sind Funktionen, die die Tokenliste, welche durch die Regel gematcht wurde als Parameter erhalten und darauf beliebige Aktionen ausführen können. Yeanpypa ist so konstruiert, dass der Rückgabewert einer semantischen Aktion anstelle der Token in das Ergebnis übernommen wird. So kann man hier also statt einer Liste von Token mittels einer semantischen Aktion gleich eine Liste von Tag-Objekten erhalten.
Die Software findet sich mit dem neuen Release auf bitbucket.org. Doku und Beispiele (auf Englisch) finden sich auf meiner snippets-Webseite. Wenn ich Zeit finde werde ich noch ein paar mehr Beispiele implementieren um die Fähigkeiten von yeanpypa umfassender zu demonstrieren.