Ik heb eens een beschrijving van de werking van mijn parser gemaakt, omdat ik ACM om raad vroeg. Die c/p ik hier wel ff:
--------------------------------------------------------
Mijn parser werkt volgens dit principe: de parse() functie roept 4 andere
functie's aan: _autoTags(), _buildTags(), _validateTags() en _replaceTags().
$returnstring _autoTags($str)
Deze functie zorgt dmv pcre regex'en voor de automagische tags, zoals een
url en emailadres. Ook vervangt hij bepaalde alternatieve tags, zoals
[ *].
$returnarray _buildTags($str)
Zoek de het eerste [ teken. Zoek de eerst daarop volgende [ en ]. Als [
eerder komt dan ], dan wordt de text in de array gedumpt als text, komt de ]
eerder dan wordt de functie makeTag() aangeroepen met de tussenliggende
text. Als __makeTag() false teruggeeft (geen geldige tag) dan wordt de text
als text in de array gedumpt, anders als tag. Verder wordt er door deze
functie ook nog gezorgd dat er niet 2 text elementen na elkaar in de array
kunnen staan, als dat zo is, dan worden ze aan elkaar geplakt.
Dit blijft zich herhalen met steeds een andere startpositie totdat de hele
string is doorlopen. De uiteindelijke array wordt gereturned.
$returnarray _validateTags($arr)
Deze functie doorloopt de hele array $arr.
Als het item een stuk van het type text betreft, dan wordt deze toegevoegd
aan de returnarray. Hier wordt ook weer gezorgd dat 2 stukken text elkaar
niet kunnen opvolgen.
Is het een openende tag dan wordt gekeken of'ie is toegestaan binnen de
huidige tag via de functie allowedTag(). Als'ie niet is toegestaan, dan
wordt het type op text gezet, en daarne wordt'ie toegevoegd aan de
returnarray. Als'ie wel is toegestaan dan wordt eerst nog gechecked of'ie
niet al een keer is geopened. Zoja, dan wordt'ie genegeerd, zonee, dan
wordt'ie toegevoegd aan de returnarray en aan de $opentags array.
Is de tag sluitend, dan wordt eerst weer allowedTag() aangeroepen. Geeft
deze false en is de huidige tag niet de laatst geopende, dan wordt het type
op text gezet, en wordt'ie toegevoegd aan de returnarray.
Is de tag wel toegestaan dan wordt er gekeken of'ie hetzelfde is als de
huidige openstaande (end($opentags)). Is dit het geval, dan wordt'ie
toegevoegd aan de returnarray en $opentags wordt eentje ingekort.
Is'ie niet hetzelfde als de huidige openstaande, maar komt'ie wel in de
$opentags array voor, dan worden eerst alle tussenliggende close tags
toegevoegd aan de returnarray, dan wordt de huidige tag toegevoegd, en dan
worden alle tussenliggende open tags weer toegevoegd.
Komt'ie niet de array $opentags voor, dan gebeurt er niets.
Na het doorlopen van de array worden alle tags uit $opentags nog afgesloten.
$returnstring _replaceTags($arr)
Weer de hele array $arr wordt doorlopen.
Is het type text, dan wordt de text toegevoegd aan de returnstring.
Ander wordt er met een simpele switch () gekeken met welke tag we te maken
hebben. De simpele (b,u,i,s,sub,sup) worden door strtr() afgehandeld ([]
wordt opgezet in <>. Bij de overige tags wordt per stuk bekeken wat er moet
gebeuren. Soms moet er 1 item vooruit wordeen gekeken (bij email
bijvoorbeeld) om de juiste waarde op te halen. Na het doorlopen van de array
wordt returnstring teruggegeven.
--------------------------------------------------------
Deze beschrijving is alweer een beetje achterhaald omdat ik m'n parser inmiddels weer heb herschreven, maar het idee is hetzelfde gebleven. Btw, dit is de url van de huidige versie van m'n parser:
http://sjr.dyndns.org/parser/parser.php. Hij's volgens mij ongeveer even snel als die van ACM (waarvan de source overigens op GoT te vinden is).