Wie baut man eigentlich einen Parser?
olleee
- programmiertechnik
0 suit0 Beat0 Christian S.0 ritschmanhard
hallo,
ich wollte eine texteingabe machen die etwa so eine syntax hat wie wikipedia weil ich ich sie fantastisch einfach finde.
ich habe mir mal deren parser.php angeschaut und nichts verstanden von dem was da drin steht. die dateien hat auch beinahe 5.000 zeilen. wobei ich denken würde das ein system ziemlich resurcenlastig sein müsste wenn bei jedem seitenaufruf erstmal 5.00 zeilen abgearbeitet werden müssen^^.
ich habe also mal versucht einen ähnlichen Parser zu bauen. das resultat gibt es hier:
http://loomarea.com/parser2.php
nun bin ich eher unerfahren mit php und erstrecht mit dieser art von technik. ich würde gerne wissen wie jemand sowas professionell anstellen würde. mein script besteht aus unzähligen if und else schleifen. der ganze text wird insgesagt 3 mal abgearbeitet und mir fehlen noch wichtige funktionen.
der parser kann bisher folgendes erzeuchen:
*verschiedene html sonderzeichen ersetzen
*überschirften (wie in wikipedia)
*absätze(p-tags)
*aufzählungen(ul und li)
*blockquotes(wenn ein absatz mit anführungszeichen beginnt und endet)
*fußnoten erzeugen (durch <ref>, wie bei wikipedia)
es fehlen noch hyperlinks und bilder. beides würde natürlich eine art datenbank erfordern.
kennt sich jemand damit aus?
kennt sich jemand damit aus?
für den anfang sollte es ein prozeduraler parser tun, später kann man da ganze auch in ein objekt auslagern
function parser($str) {
// do something
return $str;
}
echo parser('ich bin ein text der [b]gepased[/b] werden soll');
das // do something könnte zb mit einem regurlären ausdruck b[/b] gegen <strong>$1</strong> ersetzen
was dieser parser macht, hängt davon was er tun soll ;)
natürlich kann man der funktion noch mehrere parameter mitgeben - zb "erlaube html 0/1" oder "erlaube bb-code 0/1"
btw: zum parsen von bb-code oder html gibts bereits einige fertige klassen bzw module
Ein Parser ist immer abhängig von der Sprache, die er Parsen soll.
Bei mir können User im Formular Funktionen der Syntax [func:value] eingeben.
Die Funktionen erzeugen nicht nur HTML, sondern sind verschiedentlich mit Datenbank-Abfragen verbunden.
Das Prinzip dabei ist, das die Sprache in sich Konsistent bleiben muss. Sie soll aber den Autoren nicht daran hindern, normalen Text zu schreiben.
Wenn man mal keine Funktion schreiben will, gibt es dafür die Möglichkeit des Escapens. [ ].
Dadurch zwingt die meine Sprachsyntax viel weniger zu Linenoise als dies bei anderen Sprachen der Fall ist.
Ein kritisches Element ist meines Erachtens die die Abwägung zwischen Performance und Validierung.
Beispiel:
[paragraph:[head:Der Titel]]
würde invalides HTML erzeugen.
Die zweite Frage ist, ob ein Parser dauerhaft ersetzt, oder ob er das bei jeder Datanabfrage macht.
Während das erste sehr performant ist, ist das letztere sehr flexibel.
Bei mir wird letzteres angewendet.
Weil jedoch einige Berechnungen dermassen intensiv sein können (Zum Beispiel, wenn Bibelcodes Präsentiert werden), werden Ergebnisse gecacht.
mfg Beat
Hi,
ich habe mal einen Parser nachgebaut (nach einiger Inspiration im Internet), der mir Syntax gehighlightet hat.
Das Problem dort war, dass wenn man z.B. ein Keyword ersetzen wollte, wusste man ja nicht, ob sich dieses Keyword gerade innerhalb eines Strings befindet.
Das Konzept basiert auf reg. Ausdrücken, der etwa so aussieht:
/(String)|(Keyword)|(Comment)/
Das regex Engine macht das dann schon richtig. Wenn sie nämlich einen String findet, werden Keywords darin gar nicht mehr gematcht.
Das ganze ist noch ein bisschen komplizierter (mit dem Ersetzen z.B.).
Aber m.E. brauchst du sowas eh nicht für dein Problem. Dort würde wohl ein einfaches Ersetzen mit Regexp reichen.
Gruß
Christian
Hi!
Also, ich würde dir empfehlen, LEX zu verwenden (unter windows gabs da mal was von Bumblebee, Linux hat das Ding unter LEX).
Eine grundsätzliche Beschreibung und einen Link zu weiteren Infos findest du unter http://dinosaur.compilertools.net/lex/index.html
Natürlich kannst du, wenn dir LEX zu langweilig ist,auch mal YACC reinziehen - mir hat aber LEX gelangt...
(BTW LEX erzeugt C code - ob es ein LEX mit PHP output gibt, ist mir nicht bekannt).
Grüsse,
Richard