JavaScript-Parser in Python?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

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
Benutzeravatar
Whitie
User
Beiträge: 217
Registriert: Sonntag 4. Juni 2006, 12:39
Wohnort: Schulzendorf

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
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

PLY gefällt mir. Ist halt ähnlich zu den lex und yacc.
MfG
HWK
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Whitie hat geschrieben:ich fand LEPL sehr ansprechend.
Interessant. Packrat-Parser, der Linksrekursion beherrscht.

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]
Stefan
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

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.
Leonidas
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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Leonidas hat geschrieben:Naja, PLY ist Lex/Yacc-like und das ist sma sicher zu altmodisch, so wie ich ihn kenne :)
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.

Stefan
Benutzeravatar
snafu
User
Beiträge: 6881
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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'))
Antworten