Suche Informationen über -- Text - lexer - parser --

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.
cracki
User
Beiträge: 72
Registriert: Montag 25. Dezember 2006, 05:01

Beitragvon cracki » Freitag 2. Februar 2007, 14:09

implementier nen richtigen parser, samt statemachine und allem
...meh...
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Beitragvon EnTeQuAk » Freitag 2. Februar 2007, 14:12

Aber dieser muss die Syntax ja auch irgentwie treffen können oder? :D

Möchte ich übrigens auch...

oder ich warte erstma auf 'sape''s Lösung... mal schaun, wie seins ausschaut

MfG EnTeQuAk
Benutzeravatar
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Beitragvon mitsuhiko » Freitag 2. Februar 2007, 18:44

BlackJack hat geschrieben:So etwas wie BBCode oder XML/HTML ist recht einfach, weil man bei einem Start-Tag rekursiv absteigen kann und bei einem Ende-Tag wieder eine Ebene höher gehen kann.


XML ja, BBCode nein. Für BBCode parsen habe ich für pocoo doch einen relativ komplexen Lexer/Parser Verschnitt schreiben müssen. Probleme sind verschachtelte Quote/Code Blöcke, da geht mit Regex nichts mehr und code/list blöcke ansich, die kein BBCode in sich erlauben etc.

Wer sowas sucht: http://trac.pocoo.org/browser/pocoo/tru ... /bbcode.py
TUFKAB – the user formerly known as blackbird
cracki
User
Beiträge: 72
Registriert: Montag 25. Dezember 2006, 05:01

Beitragvon cracki » Freitag 2. Februar 2007, 20:30

kann so schwer ja nicht sein. tokenisieren, parsen, ausgeben...

hab schon mal nen PEG parser geschrieben. einziges problem ist wie ich aus dem baum dann was gescheites mache. das wuerde ich am liebsten ins grammar einarbeiten... da fehlt mir noch die breitsicht was da ne uebliche art ist das zu machen.

aber bbcode ist doch keine huerde, oder?
...meh...
BlackJack

Beitragvon BlackJack » Freitag 2. Februar 2007, 21:04

blackbird hat geschrieben:
BlackJack hat geschrieben:So etwas wie BBCode oder XML/HTML ist recht einfach, weil man bei einem Start-Tag rekursiv absteigen kann und bei einem Ende-Tag wieder eine Ebene höher gehen kann.


XML ja, BBCode nein. Für BBCode parsen habe ich für pocoo doch einen relativ komplexen Lexer/Parser Verschnitt schreiben müssen. Probleme sind verschachtelte Quote/Code Blöcke, da geht mit Regex nichts mehr und code/list blöcke ansich, die kein BBCode in sich erlauben etc.


Das "Nein" verstehe ich jetzt nicht? Wo widersprichst Du mir denn? Oder wo gibt's Probleme mit einem rekursiv absteigenden Parser?
Benutzeravatar
jens
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Freitag 2. Februar 2007, 21:17

Ich stecke zwar da nicht so tief in der Materie, aber mal eine generelle Frage...

cracki hat geschrieben:tokenisieren, parsen, ausgeben...

Dieser Aufbau wird doch immer wieder gemacht. Könnte man nicht eine Variante bauen, die allgemein Gültig ist?

Ich meine, das man nicht direkt die Regeln "wenn input = xy dann output =xy" festlegt, sondern das nochmals in einer weiteren Ebene.

Also das man einen Parser hat, bei den man die Syntax quasi per config definiert. So könnte man den Parser für verschiedene Markups gleichzeitig nutzten.

Im Grunde so wie pygments mit seinen verschiedenen Lexer.

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Freitag 2. Februar 2007, 22:12

jens hat geschrieben:
cracki hat geschrieben:tokenisieren, parsen, ausgeben...

Dieser Aufbau wird doch immer wieder gemacht. Könnte man nicht eine Variante bauen, die allgemein Gültig ist?

Klar, PyParsing und ZestyParser lassen grüßen.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Freitag 2. Februar 2007, 22:36

jens hat geschrieben:Also das man einen Parser hat, bei den man die Syntax quasi per config definiert. So könnte man den Parser für verschiedene Markups gleichzeitig nutzten.
Ja kann man. Daran versuche ich mich ja gerade.

Ansonsten, wer es richtig allgemein haben will kann ich nur PyParsing empfehlen. Damit habe ich mich einige Zeit beschäftigt und finde es Ziemlich Klasse gemacht.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Freitag 2. Februar 2007, 22:45

jens hat geschrieben:Also das man einen Parser hat, bei den man die Syntax quasi per config definiert.

Es gibt ja auch welche die EBNF als Config akzeptieren. Sieh dir mal als Beispiel dan guten alten yacc an, der versteht BNF.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Samstag 3. Februar 2007, 02:37

EnTeQuAk hat geschrieben:So... so soll das aber nicht erkannt werden... *grml* -- wie kann ich da besser vorgehen -- wie müsste ich über den Text iterieren, um Tokens anzufertigen, um solche Sachen auch "zuferlässig" zu treffen?


Einfach im Lexer den Text spliten:

Code: Alles auswählen

src = """{{{LITERAL_ALL_CHARS
}}}
**//test//**
"""   
regexp = re.compile(r'({{{|}}}|\*\*|//|__|)')
output = [x for x in regexp.split(src) if x != '']
print output


Code: Alles auswählen

['{{{', 'LITERAL_ALL_CHARS\n', '}}}', '\n', '**', '//', 'test', '//', '**', '\n']


Die einzelnen Tokens muss dann der Lexer mit den richtigen Typ versehen.

BTW: Wichtig ist das der ausdruck im re-teil in runden klammern eingeschlossen ist!!

r'({{{|}}}|\*\*|//|__|)' = OK
r'{{{|}}}|\*\*|//|__|' = Nicht OK weil dann sowas bei rauskommt:

Code: Alles auswählen

['LITERAL_ALL_CHARS\n', '\n', 'test', '\n']


lg
cracki
User
Beiträge: 72
Registriert: Montag 25. Dezember 2006, 05:01

Beitragvon cracki » Samstag 3. Februar 2007, 06:08

jens hat geschrieben:Könnte man nicht eine Variante bauen, die allgemein Gültig ist?

Ich meine, das man nicht direkt die Regeln "wenn input = xy dann output =xy" festlegt, sondern das nochmals in einer weiteren Ebene.

Also das man einen Parser hat, bei den man die Syntax quasi per config definiert. So könnte man den Parser für verschiedene Markups gleichzeitig nutzten.


genau sowas habe ich ja auch gemacht. der parser ist ein modul mit funktionen und klassen. das grammar ist ein grosses dict mit nonterminal -> grammar zuordnungen und alles ist mit funktionen modelliert. man muss das grammar selbst also nicht nochmal parsen, weils schon code ist.

alles was man dann noch macht, ist: "parse(input, grammar)" und raus kommt ein baum.

ich weiss, PEGs sind relativ starr und scheinbar auch nicht sehr fehlertolerant was den input angeht. und wie man den baum gescheit weiterverarbeitet (oder beim parsen gleich verarbeitet), das wissen fehlt mir noch.
...meh...
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Beitragvon sape » Samstag 3. Februar 2007, 09:48

cracki hat geschrieben:und wie man den baum gescheit weiterverarbeitet (oder beim parsen gleich verarbeitet), das wissen fehlt mir noch.
Wie man generell einen AST verarbeitet oder modellieren sollte um leichten Zugriff zu haben oder speziell von dem PEG?
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Beitragvon EnTeQuAk » Samstag 3. Februar 2007, 09:48

sape hat geschrieben:
EnTeQuAk hat geschrieben:So... so soll das aber nicht erkannt werden... *grml* -- wie kann ich da besser vorgehen -- wie müsste ich über den Text iterieren, um Tokens anzufertigen, um solche Sachen auch "zuferlässig" zu treffen?


Einfach im Lexer den Text spliten:

Code: Alles auswählen

src = """{{{LITERAL_ALL_CHARS
}}}
**//test//**
"""   
regexp = re.compile(r'({{{|}}}|\*\*|//|__|)')
output = [x for x in regexp.split(src) if x != '']
print output


Code: Alles auswählen

['{{{', 'LITERAL_ALL_CHARS\n', '}}}', '\n', '**', '//', 'test', '//', '**', '\n']


Die einzelnen Tokens muss dann der Lexer mit den richtigen Typ versehen.

BTW: Wichtig ist das der ausdruck im re-teil in runden klammern eingeschlossen ist!!

r'({{{|}}}|\*\*|//|__|)' = OK
r'{{{|}}}|\*\*|//|__|' = Nicht OK weil dann sowas bei rauskommt:

Code: Alles auswählen

['LITERAL_ALL_CHARS\n', '\n', 'test', '\n']


lg


Hey... das mit der Klammer wars :D Das werde ich gleich mal ausprobieren.

Herzlichen Dank! :)

MfG EnTeQuAk
cracki
User
Beiträge: 72
Registriert: Montag 25. Dezember 2006, 05:01

Beitragvon cracki » Samstag 3. Februar 2007, 12:02

sape hat geschrieben:Wie man generell einen AST verarbeitet oder modellieren sollte um leichten Zugriff zu haben oder speziell von dem PEG?

wie ich einen AST so bequem wie moeglich weiterverarbeite. dazu zaehlt z.b. baum stutzen, transformationen, solche geschichten. braucht dich aber nicht kuemmern, weil es geht ja, nur ists mir zu umstaendlich. hab auch das drachenbuch noch nicht gelesen, also...
...meh...
BlackJack

Beitragvon BlackJack » Samstag 3. Februar 2007, 12:43

Hier noch ein Versuch einen Parser für die dauCMS Syntax zu schreiben:

http://www.ubuntuusers.de/paste/7241/

Eigentlich habe ich den Parser weggelassen. Es gibt einen `Lexer` und einen `DirectXHTMLWriter` der den Tokenstrom direkt und inkrementell in ein HTML-Dokument überführt. Es gibt also keinen AST, sondern immer nur soviel Informationen im Speicher, wie für die Zerlegung einer einzelnen Eingabezeile und den Stack für offene XML-Tags benötigt wird.

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot], Brudi