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.
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Samstag 10. Februar 2007, 15:57

Danke, Danke...

nichts desto trotz, werde ich mir deinen gesamten Code ma durchschauen... werde ihn analysieren und schauen, ob ich was davon brauchen kann.

Der Ansatz ist jedenfalls sehr gut.

Die Generierung von BBCode aus der dauCMS-Wiki-Syntax gefällt mir ebenso sehr gut.

Wenn ich mich reingefitzt habe werde ich ma schaun, ob ich was dazu beitragen kann.

Es ist jedenfalls mehr geworden, als ich gedacht habe :D


Herzlichen Dank, von meiner Seite aus. Und führe das bitte weiter... das verspricht etwas sehr interessantes zu werden :D

MfG EnTeQuAk
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Samstag 10. Februar 2007, 16:32

EnTeQuAk hat geschrieben: nichts desto trotz, werde ich mir deinen gesamten Code ma durchschauen... werde ihn analysieren und schauen, ob ich was davon brauchen kann.
Aber keinen Schock kriegen. Bin leider nicht dazu gekommen den Code zu dokumentieren was ich bereue, da es stellenweise doch ziemlich Strange ist :D
EnTeQuAk hat geschrieben: Der Ansatz ist jedenfalls sehr gut.
In der Entwurfsphasen gefiel mir mein Code auch gut, aber nun nicht mehr so. Mit der Möglichkeit der Ableitung von ``BasisLexer`` um neue Lexer zu implemnetieren die das gleiche Interface nutzen, finde ich persönlich gut, aber den ganzen AST kram ist echt nicht so gewordene wie erhofft und auch überflüssig :-/ -- Ich werde mir demnächst mal doch das Drachenbuch kaufen :D
EnTeQuAk hat geschrieben: Die Generierung von BBCode aus der dauCMS-Wiki-Syntax gefällt mir ebenso sehr gut.
Danke. Dient aber nur als Beispiel, da ich nun nicht nicht nachschlagen wollte für HTML (HTML und XHTML ist schon sehr lange her und BBC habe ich im Kopf ^^). Da sich aber die tags eigentlich fast ähneln, kann man das auch leicht anpassen. EDIT: Aber es ist so konzipiert das es in jedes beliebige Textformat überführt werden kann, das mindestens gleich mächtig ist wie daucms-Wiki-Syntax.
EnTeQuAk hat geschrieben: Herzlichen Dank, von meiner Seite aus. Und führe das bitte weiter... das verspricht etwas sehr interessantes zu werden :D
Auf jedenfall :) Ich werde wenn ich wider Zeit habe einen neune Ansatz versuchen der sauberer ist als mein jetziger. Aber dazu muss ich mich mehr mit regex beschäftigen :D

Aber als nächstes kommt erstmal Ubuntu auf meine Kiste, das wird mich erstmal die nächste Wochen genug beschäftigen ;)

...

Seid ihr eigentlich nun dabei daucms mit pylucid zu fusionieren und beide Wiki-Syntaxen zusammenzuführen?

Und noch eine Frage: Mir ist aufgefallen das ihr auch [[[ fobar ]]]-Tags habt. Sind die dafür da um Listen zu erzeugen?

lg
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Samstag 10. Februar 2007, 17:04

Seid ihr eigentlich nun dabei daucms mit pylucid zu fusionieren und beide Wiki-Syntaxen zusammenzuführen?
Im Moment nein. Eine Direkte Fusionierung wird es meiner Meinung nach nicht geben.
Es wird später mal ein Plugin für PyLucid geben, um es wie dauCMS benutzen zu können. Also Lokal den Content erstellen und diesen in HTML überführen und dann via FTP etc. hochladen.

Allerdings erst später, da zumindest ich, für meinen Teil gerne erstmal eine Stabile Version erreichen möchte.
Und noch eine Frage: Mir ist aufgefallen das ihr auch [[[ fobar ]]]-Tags habt. Sind die dafür da um Listen zu erzeugen?
Die sind nur so zum Spaß da ;)
Die sind Übergangsweise da... unser Listenparser ist noch nicht fertig... um die Dokumentation aber ansehnlicher zu gestalten haben wir diese Tags eingefügt... sie werden aber entfernt, sobald wir offiziell Listen unterstützen.

MfG EnTeQuAk
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Samstag 10. Februar 2007, 18:05

oke.-... das erste, was schonmal nicht ganz ohne Probleme klappt...

Ich habe folgende Regex:

Code: Alles auswählen

scan_re = re.compile(
            r"(?:"
            +  r"(?P<bold>\*\*)"
            +  r"|(?P<italic>\/\/)"
            +  r"|(?P<underline>__)"
            +  r"|(?P<headline>(={1,6})(.*)\1)"
            +  r"|(?P<url>(http|ftp|nntp|news|mailto)\:[^\s'\"]+\S)"
            +  r"|(?P<dauurl>#link\["
            +      r"((?:(?:https?|ftp|nntp|news|mailto)\:[^\s'\"])?(?:www.)?"
            +          r"(?:.*)"
            +      r"(?:\.[a-z]{2}){1,2}(?:[a-zA-Z0-9\/\\\.]*))"
            +      r"(\s[a-zA-Z0-9-_.:\/\\\s]*)?\])"
            +  r"|(?P<email>[-\w._+]+\@[\w.-]+)"
            +  r"|(?P<pre>(\{\{\{|\}\}\}))"
            + r")")
Er trifft alles wunderbar... mit ausnahme der Überschriften (gruppe 'headline')
Warum? Das ist die gleiche Regex, die ich immer verwendet habe...

Hat da jemand eine Idee?

MfG EnTeQuAk

EDIT:
oke... ich habe es gefunden. Die '\1' ist falsch... müsste anders lauten... '\5' oder so... nur da kommt nur quatsch raus ;)
Habe nun einiges verbessert... aber so richtig funktionieren tut es net...
http://daucms.de/trac/browser/dauCMS/tr ... py?rev=206
Benutzeravatar
Luzandro
User
Beiträge: 87
Registriert: Freitag 21. April 2006, 17:03

Samstag 10. Februar 2007, 18:23

oke... ich habe es gefunden. Die '\1' ist falsch... müsste anders lauten... '\5' oder so... nur da kommt nur quatsch raus ;)
Du kannst der Gruppe mit den = auch einen Namen geben (sinnvolleren als hier) und diesen bei der Rückreferenz verwenden
EnTeQuAk hat geschrieben:

Code: Alles auswählen

            +  r"|(?P<headline>(?P<foo>={1,6})(.*)(?P=foo)"
[url=http://www.leckse.net/artikel/meta/profilieren]Profilieren im Netz leicht gemacht[/url]
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Samstag 10. Februar 2007, 18:48

achsoooo geht das :D

Na dann haben wir das nun gefixed :D

Herzlichen Dank!

Und weiter gehts, neue Sachen einzubauen.

@sape:

habe mich in deinen Parser/Lexer schonmal ein wenig reingearbeitet... ist auch ganz angenehm zu benutzen... nur die Doku ist wirklich etwas arg :D

Aber es funktioniert jedenfalls schon einmal.

MfG EnTeQuAk
BlackJack

Samstag 10. Februar 2007, 19:05

Das "innere" der <dauurl> finde ich unnötig einschränkend. Diese ganzen Tests auf verschiedene Protokolle und ob da nun `www.` am Anfang steht oder nicht ist doch alles völlig egal. Das `#link` sagt aus, dass in den eckigen Klammern eine URL steht, das reicht doch vollkommen aus. Ist so ähnlich wie Typprüfung vs. "duck typing", Du schliesst damit alle URLs und Protokolltypen aus, an die Du jetzt gerade mal nicht gedacht hast. `aim:`, `icq:`, `telnet:`, `sftp:`, `sip:` und so weiter.
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Samstag 10. Februar 2007, 19:31

Habs geändert... da hast du natürlich Recht :D

War schwachsinnig... Aber na ja... kommt vor.

Danke!

MfG EnTeQuAk
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Samstag 10. Februar 2007, 19:54

EnTeQuAk hat geschrieben: @sape:

habe mich in deinen Parser/Lexer schonmal ein wenig reingearbeitet... ist auch ganz angenehm zu benutzen...
Ja der Zugriff ist relatiev Simple. Aber sobald du dich mit den Interna vom AST-Kram beschäftigst, kriegst du genau wie ich das grauen :D (€: Muss man ja aber auch nicht. Dafür gibt es ja ``ast_to_token_stream(ast)`` ^^)
EnTeQuAk hat geschrieben: nur die Doku ist wirklich etwas arg :D
Um nicht zu sagen richtig beschießen, da nicht vorhanden :D

BTW: Ehm Sorry, was ich noch vergessen hab zu erwähnen. Wenn tags nicht geschlossen werden, findet in irgend einem Abschnitt vom Lexer ``assert``s statt. Da gehören eigentlich exceptions, die ich nicht eingebaut hatte. Also nicht wundern :mrgreen: -- Saubere wäre aber eine Interpretierung als Literal, wie es bei BBC auch gemacht wird.

Also:
``basis.py`` Zeile 191 wird ``assert stack[-1] == None`` ausgelöst falls der stack nicht leer ist, was halt durch nicht geschlossene Tags zu Stande kommt. Wenn das der Fall ist, ist ebenfalls ``lexer_stream_line`` nicht leer und in dem befinden sich seit dem betreffenden offenen Tag alle tokens.

Das könnte z.B: so aussehen.

Code: Alles auswählen

[('MarkupBold', '**'), ('Literal', ' test'), ('MarkupLinebreak', '\n'), ('Literal', '    test2')]
Nun, müsste man diesen Inhalt komplett als Literal behandeln, so wie es in BBC auch gemacht wird.

Hier, der Patch. Damit wird dann falls der stack voll ist, der Inhalt von ``lexer_stream_line`` als Literal in `` self._lexer_stream`` hinzugefügt:
Zeile 191 löschen und dann folgendes einfügen:

Code: Alles auswählen

        if stack[-1] is not None:
            tmp = list()
            for token in lexer_stream_line:
                tmp.append(token[1])
            lexer_stream_line = [(TT.LITERAL, "".join(tmp))]
            self._lexer_stream.append(lexer_stream_line)
Den Rest bin ich auch nochmal durchgegangen und sollte alles soweit ohne Bugs sein.

Ich mache mich nun auch mal dran, ne neue und sauberere Version zu Progen ;D

lg
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Sonntag 11. Februar 2007, 14:45

Klappt ganz gut... ;) Danke, für den Fix.


nebenbei bastel ich an meiner Variante weiter... und komme nicht weiter.

Die Datei schaut so aus: http://paste.pocoo.org/show/949/


Immo funktioniert das ganze schon nicht so schlecht... nur habe ich ein Problem, mit der 'noparser' Syntax... also die stellen, die gar nicht erst durch den Parser laufen sollen... ich weiß net, wie ich die aussortieren soll.

Ich hatte es schonmal mit einer Umgebungsvariablen 'self.in_noparse' probiert... so, wie bei 'self.is_b' usw... aber das hat nicht so ganz funktioniert.

Habt ihr da ne Idee?

MfG EnTeQuAk

EDIT:
Habe es nun hinbekommen...
Fertige Datei: http://daucms.de/trac/browser/dauCMS/tr ... order=name
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Dienstag 13. Februar 2007, 18:07

So, ich hab mal aus dem SVN die letzte Version genommen und bearbeitet:
http://paste.pocoo.org/reply/949/
diff: http://paste.pocoo.org/compare/969/

Ich habe damit die Trennung der Syntax vom eigentlichen Parser gemacht. Nun könnte ich eine eigene Syntax-Klasse für PyLucid bauen und benutzten. Ich denke das ist sauberer, als das selbe über erben zu machen, oder?

EDIT: Generell werden aber die Absätze nicht gut gemacht :( Alles wird über ein "<br />" gemacht. Die normalen "<p>"-Tags werden nicht genutzt. Das ist unschön.
In tinyTextile bilde ich die Absätzte mit einem blocks = re.split("\n{2,}", txt) siehe:
http://pylucid.net/trac/browser/trunk/P ... v=824#L195

Dadurch hat man sauberen HTML-Code.

z.B.:

Code: Alles auswählen

Eine Zeile
zweite Zeile

Nächster Block.
Und bla...
wird dann mit tinyTextile zu:

Code: Alles auswählen

<p>Eine Zeile<br />
zweite Zeile</p>

<p>Nächster Block.<br />
Und bla...</p>
in dauCMS dürfte das ungefähr so aussehen:

Code: Alles auswählen

Eine Zeile<br />
zweite Zeile<br />
<br />
Nächster Block.<br />
Und bla...
Ist per Hand "generiert" ;)

EDIT2: Ach... Irgendwie verstehe ich es nicht, was es mit dem self.is_ auf sich hat.

EDIT3: Zum thema paragraphs: http://www.python-forum.de/post-18944.html#18944
Zuletzt geändert von jens am Dienstag 13. Februar 2007, 18:28, insgesamt 1-mal geändert.

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 14. Februar 2007, 10:12

Ich hab den reST Kram mal abgetrennt: http://www.python-forum.de/topic-9498.html

Leider ist ein Beitrag von EnTeQuAk mit rausgetrennt worden. Deswegen diesen hier nochmal als Full-Quote:
EnTeQuAk hat geschrieben:Danke sape ;)

@ Jens:

Ich schau mir deine Lösung mal nachher genauer an.
€dit:schaut supa aus ;) Danke -- :D Passt perfekt zum PluginSystem für dauCMS :D (womit später mehrere Syntaxen ermöglicht werden... Syntax-Module sozusagen)

Das wegen den '<p>' 's ist mir auch schon aufgefallen... und war bisher nicht böse gemeint ;)

Es wird demnächst aber implementiert.


MfG EnTeQuAK

EDIT:
EDIT2: Ach... Irgendwie verstehe ich es nicht, was es mit dem self.is_ auf sich hat.
Damit werden z.B. zwischen '//' als öffnendes 'italic'-Tag und '//' als schließendes 'italic'-Tag unterschieden.
Dadurch wird aus der Liste, was _bold_replacer() etc. zurückgeben das richtige ausgewählt... (stelle 1 oder stelle 0)
Die self.is_ Sache durchblicke ich noch nicht so ganz. Aber vielleicht muß ich mir dazu nochmal den Quellentext ansehen.
Aber was anderes: Warum dieser Name "is_" ??? Sehr untypisch!

Und noch was anderes: Ich denke man sollte zwischen Block und Inline Sachen unterscheiden und das evtl. trennen.
Block-Teile sind für mich z.B.:
  • - Überschriften
    - Text-Absätzte (Also das was man in <p> Einschließen kann)
    - noparse-Areas
    - Listen
Mit Inline meine ich z.B.:
  • - bold
    - italic
    - URLs
Ich denke erst durch diese Trennung kann man saubere Absätze mit <p>-Tags erstellen.

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Mittwoch 14. Februar 2007, 10:18

Grundlegend ist der parser noch nicht das perfekte (gut, das gibet net aber egal...).

Er schaut halt immo nur Zeile für Zeile nach --> Da muss noch das Nachschauen für nächste Zeilen her ;)

Daran arbeite ich bereits ;) Mit deiner Standalone-Variante ist dann auch schon eine gute Trennung zwischen Syntax und Parser ansich getan.

Nur brauche ich jetzt erstmal einen Cache... ach na ja ;) Heute wird jedenfalls net so viel gemacht ;) Heut, Vallendienstag... lass ich mich verwöhnen ;) B-Day hat man ja net immer :D -- :=)

MfG EnTeQuAK
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 14. Februar 2007, 10:24

Cache im Parser??? Das würde ich erstmal komplett außer acht lassen.

tinyTextile geht auch Zeilenweise den Text durch. Ist aber eigentlich sehr dumm, z.B. bei noparse Areas und Escape-Areas. Diese besonderen Blocks sollte man IMHO vorab heraus extrahieren. Evtl. so wie hier http://www.python-forum.de/post-18944.html#18944 mit extract und assamble...
Ich frage mich allerdings ob man nicht besser erst einmal die Block-Teile mit re.split auftrennen sollte. Dann hat man eine Liste mit den einzelnen Blocks. Über diese iteriert man dann und erledigt den Rest.

Mich würde interessieren, wie es pygments mit dem RegexLexer macht. Ich hatte da ja mal mit rumprobiert: http://www.python-forum.de/topic-9408.html

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Mittwoch 14. Februar 2007, 12:16

Das mit dem Zeilenweisen durchgehen ist ansich ja kein Problem, für meinen Parser.

Ich muss solch Sachen wie noparse gar nicht mal im Vorhinein aussortieren. Sondern habe dafür meine Zustandsvariable 'self.in_noparse'. Damit weiß ich Parser dann, das er sämtliche Formatierungen überspringen soll, solange diese Variable gesetzt ist.

Ich finde, das ist eine ganz simple und funktionierende Lösung. ;)

Immo funktioniert es jedenfalls sehr gut und sehr perfomant obendrein... :)


MfG EnTeQuAk
Antworten