Ich könnte einen JavaScript bzw. ECMAScript-Parser in Python gebrauchen, da ich gerne damit experimentieren würde, Varianten von JavaScript in JavaScript zu übersetzen. Gibt es da schon etwas Fertiges?
Für ANTLR gibt es wohl eine ECMAScript-3-Grammatik, die man wohl irgendwie auch in Python übersetzen könnte. Aber das ist mir eigentlich zu viel Aufwand, da ich ANTLR-Grammatiken nicht gerade einfach lesbar finde.
Nebenbei: Welchen Parsergenerator würdet ihr warum empfehlen? Ich persönlich bin ja ein Fan von PEG bzw. Packrat-Parsern, habe jedoch noch keinen guten für Python gesehen. Pyparsing missfällt mir schon aufgrund der werbeüberfluteten hässlichen Homepage und der IMHO nicht ideomatischen Benennung. Zudem sieht der Quelltext wüst aus, wenn man da näher hineinschaut.
Stefan
JavaScript-Parser in Python?
Hallo sma,
ich fand LEPL sehr ansprechend. Hab allerdings bis jetzt nur mal das Tutorial durchgearbeitet.
Mich hat vor allem angesprochen, dass diverse Operatoren überladen werden und somit (in meinen Augen) ansehnlicher und nachvollziehbarer Code entsteht. Außerdem wird die Hauptentwicklung für Python 3.x gemacht (läuft aber auch unter 2.6).
Gruß
Whitie
ich fand LEPL sehr ansprechend. Hab allerdings bis jetzt nur mal das Tutorial durchgearbeitet.
Mich hat vor allem angesprochen, dass diverse Operatoren überladen werden und somit (in meinen Augen) ansehnlicher und nachvollziehbarer Code entsteht. Außerdem wird die Hauptentwicklung für Python 3.x gemacht (läuft aber auch unter 2.6).
Gruß
Whitie
Interessant. Packrat-Parser, der Linksrekursion beherrscht.Whitie hat geschrieben:ich fand LEPL sehr ansprechend.
Kann man aber hier noch erkennen, dass das ein Parser für JSON-Ausdrücke ist? Dabei fehlt noch die Logik, dass die Pair, Object und Array-Knoten in native Python-Datenstrukturen konvertiert werden. Das ich offenbar jedes Stück Syntax in `Drop` einschließen muss, stört mich auch.
Code: Alles auswählen
from lepl import *
class Pair(Node): pass
class Object(Node): pass
class Array(Node): pass
def none(s): return None
def string(s): return s[1:-1].decode("string-escape")
value = Delayed()
const = Literal("true") >> bool | Literal("false") >> bool | Literal("null") >> none
number = Digit()[1:,...] >> float > 'number'
string = Regexp(r'"(?:\u[0-9a-fA-F]{4}|\["\/bfnrt]|[^"])*"') >> string > 'string'
spaces = Drop(Regexp(r'\s*'))
with Separator(spaces):
pair = string & Drop(":") & value > Pair
members = pair & (Drop(",") & pair)[:]
obj = "{" & members[:1] & "}" > Object
elements = value & (Drop(",") & value)[:]
ary = "[" & elements[:1] & "]" > Array
value += const | number | string | obj | ary
print value.parse_string('[1, "2", {"c": true, "d": "\\r\\n"}]')[0]
Was hast du denn gegen PLY? Es gefällt mir von den libs, die ich zum Thema Lexer/Parser angeguckt habe (ca. 5), am besten. Es ist nicht sehr elegant, den Docstring einer Funktion zu "missbrauchen", aber eine schönere Möglichkeit habe ich bisher nicht gesehen.
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Naja, PLY ist Lex/Yacc-like und das ist sma sicher zu altmodisch, so wie ich ihn kenne
Allerdings muss ich sagen, dass es ziemlich brauchbar ist, ich finds intuitiver als diese Pyparsing-Seltsamkeiten.
LEPL erinnert ein wenig an boost.spirit, wollts mal antesten aber dann hab ich das Vorhaben erstmal auf Eis gelegt.

LEPL erinnert ein wenig an boost.spirit, wollts mal antesten aber dann hab ich das Vorhaben erstmal auf Eis gelegt.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Lex/Yacc habe ich schon vor 15 Jahren in C benutzt. Also langweilig :) Die Idee mit den Doc-Strings ist aber in der Tat nett und ich hatte hier auch schon mal so ein Beispiel für einen selbstgeschriebenen PEG gepostet. Ich finde PEGs und Parserkombinatoren einfach zur Zeit spannender.Leonidas hat geschrieben:Naja, PLY ist Lex/Yacc-like und das ist sma sicher zu altmodisch, so wie ich ihn kenne :)
Stefan
Vielleicht interessiert dich ja auch pynarcissus, ein Python-Port von Mozillas Narcissus. Du kannst damit sogar den geparsten Baum in S-Expressions umwandeln:
Code: Alles auswählen
In [1]: import jsparser, sexp
In [2]: js = "alert('hello world');"
In [3]: tree = jsparser.parse(js)
In [4]: print sexp.convert(tree)
------> print(sexp.convert(tree))
(SCRIPT
(CALL alert 'hello world'))