[PHP] Template parser regexp troubles

Pagina: 1
Acties:
  • 188 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 13-09 21:14
Goedemorgen allemaal,

Momenteel ben ik in PHP een eigen template parse ding aan het maken. Er zijn er genoeg, maar ik wil het gewoon zelf naar mijn smaak doen, dus vandaar. Ik ben inmiddels een heel eind, maar bekijk de volgende "template" eens :

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<h3>{systeem.omschrijving}</h3>

{systeem.componenten}

{@before}<form><table></@}
{@after}</table></form></@}

<tr><td>{naam}</td></tr>

{artikelen}
{@before}<select>{/@}
{@after}</select>{/@}

<option value="{id}">{omschrijving}</option>

{/artikelen}

{/systeem.componenten}


Hierin zijn twee "blokken" aanwezig, t.w. {systeem.componenten} en {artikelen}. Dmv de volgende regexp. trek ik alle blokken eruit, die ik vervolgens weer recursief "parse".

PHP:
1
preg_match_all ("/\{(.+?)\}(.*){\/\\1\}/ise", $work_string, $blocks, PREG_SET_ORDER );


Ook dit werkt zonder problemen. Het gaat fout met de {@before} dingen. Als ik het eerste blok verwerk ( {systeem.componenten} ), dan zoek ik met de volgende regel de {@} operators op :

PHP:
1
preg_match_all ("/\{@(.+?)\}(.*?){\/@}/ise", $work_string, $operator, PREG_SET_ORDER );


In principe werkt dit ook, behalve als er dus binnen een blok nog andere blokken aanwezig zijn ( in dit geval {artikelen} ). Hij vindt in dit geval ook de {@before} en {@after} in het tweede blok, die dus nog niet aan de beurt is. In mijn ogen zouden beide regexp-en dus gecombineerd moeten worden, zodat de tweede alle {@} eruit haalt, maar niet als ze binnen een ander blok zitten. Ik heb geprobeerd met de lookahead assertions iets in elkaar te zetten, maar dat werkt dus niet. En lookback assertions kunnen niet van een variabele lengte zijn dus ook daar kan ik niets mee aanvangen.

Wie brengt mij het licht, want ik weet toch bijna zeker dat het moet kunnen.

SIZE does matter.
"You're go at throttle up!"


Acties:
  • 0 Henk 'm!

  • Apollo_Futurae
  • Registratie: November 2000
  • Niet online
dit is een probleem wat je in een echte programmeertaal zou aanpakken met behulp een parser combinator (betere talen :p) of een parser generator (mindere talen ;)). dit doe je niet met regular expressions, die zijn hier niet voor bedoeld. er is vast wel een truukje te bedenken waarmee je probleem direct op te lossen is (dit is niet voor niets GoT :*)), maar als ik jou was zou ik op zoek gaan naar een parser generator voor php.

Pas de replâtrage, la structure est pourrie.


Acties:
  • 0 Henk 'm!

  • Nielsz
  • Registratie: Maart 2001
  • Niet online
En als je nou dit ervan maakt?
{@before}<form><table></@before}

Acties:
  • 0 Henk 'm!

Verwijderd

uhm je hebt </@before} terwijl je verder overal begint of sluit met } {

Acties:
  • 0 Henk 'm!

  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 13-09 21:14
Verwijderd schreef op 03 March 2003 @ 22:14:
uhm je hebt </@before} terwijl je verder overal begint of sluit met } {
Typo :)
Apollo_Futurae schreef op 03 March 2003 @ 20:19:
dit is een probleem wat je in een echte programmeertaal zou aanpakken met behulp een parser combinator (betere talen :p) of een parser generator (mindere talen ;)). dit doe je niet met regular expressions, die zijn hier niet voor bedoeld. er is vast wel een truukje te bedenken waarmee je probleem direct op te lossen is (dit is niet voor niets GoT :*)), maar als ik jou was zou ik op zoek gaan naar een parser generator voor php.
Een parser generator voor php. Inmiddels ben ik tien zoekopdrachten verder maar niet echt iets gevonden. Alles werkt behalve dit ene kleine (naja klein) ding. En voor mijn gevoel MOET het gewoon kunnen alleen zie ik het even (al een aantal dagen) niet.

SIZE does matter.
"You're go at throttle up!"


Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Wat je zou kunnen doen is zelf een stack-based parser maken, die enkel matcht op begin en sluittags afzonderlijk, zodat je "weet" of een bepaalde tag aan de beurt is. Wanneer je een match hebt op je stack kun je parsen.

code:
1
2
3
4
5
6
7
{start}         # push op stack  
   {start}      # push op stack
       {start}  # push op stack

       {/start} # match met (pop van stack)? ja -> parsen, nee -> "parse" (nesting) error
   {/start}     # match met (pop van stack)? ja -> parsen nee , etcetera
{/start}
da's even heel kort de bocht wat je zou kunnen proberen. Begin dan wel met een eenvoudige voorstelling van zaken, want je verliest gauw 't overzicht bij deze dingen.

Overigens zijn dergelijke dingen leuk voor de hobby, maar echt productief zijn ze niet :) Ik heb ook wel 's zoiets gemaakt, maar uiteindelijk kom je toch terug bij de beter uitgedachte systemen als xml/xslt combi's e.d. :) Met mooie template parsers loop je in die zin altijd een beetje achter de feiten aan :)
voordat chem en ACM hier gaan bleren: ja voor rml is 't wel handig :+

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 16:12

crisp

Devver

Pixelated

Je zou je functie ook zo kunnen schrijven dat je uiteindelijk eerst je {@xxx}..{/@} op het diepste niveau (in dit geval binnen {artikelen}) gaat parsen, dat weer teruggeeft en dan pas de {@xxx}..{/@} op het niveau daarvoor ({systeem.omschrijving}) parsed.

Pseudo-code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$output = parse_blocks($data);

function parse_blocks($work_string) {

  $output = '';

  // find all blocks in $work_string

  // for each block call parse_blocks recursively to find nested blocks and built $output with return data

  return parse_items($output);

}

function parse_items($work_string) {

  $output = '';

  // build $output by parsing the items in $work_string

  return $output;

}

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • MisterData
  • Registratie: September 2001
  • Laatst online: 29-08 20:29
Kijk op codebase voor de source van mijn (helaas beetje buggy) template parser voor PHP. Je kunt het parsen zelf hier testen: http://dev.trag.nl/ojc/include/tpltest.php . Hier zie je duidelijk dat de parser nesting errors herkent door een stack te gebruiken. Ik ga nog ooit een keer een versie twee van dit dingetje schrijven, maar ik ben er nu ook al vrij tevreden over :)

[ Voor 38% gewijzigd door MisterData op 04-03-2003 09:53 . Reden: damn.... slechte parser hier @ GoT :| ]


Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
Apollo_Futurae: dit is een probleem wat je in een echte programmeertaal zou aanpakken met behulp een parser combinator (betere talen :p) of een parser generator (mindere talen ;))
Laat je niet al te veel hersenspoelen door Haskell freaks (waarschijnlijk op de UU) >:) . Parser combinators zijn zeker niet onaardig, maar uiteindelijk moet alle parser technologie wat mij betreft wijken voor het parsen van talen met grammaticas in de volledige klasse van context-vrije grammatica's >:) . Je komt op het GLR parser algoritme. Er zijn verschillende implementaties zoals bijvoorbeeld SGLR (met SDF als grammatica taal).

http://www.cwi.nl/htbin/sen1/twiki/bin/view/SEN1/SDF2
http://www.cwi.nl/htbin/sen1/twiki/bin/view/SEN1/SGLR

Voor een overzichtje van parser (generators) gebaseerd op GLR (en andere) technologie:
http://www.cs.berkeley.edu/~smcpeak/elkhound/

Als je snel wilt weten waar dit allemaal over gaat:
http://www.stratego-langu...s/AQuickIntroductionToSDF

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


Acties:
  • 0 Henk 'm!

  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 13-09 21:14
Thanks voor alle replies.

Ik ga vandaag maar even die bijna 800 regels code van MisterData doornemen om te kijken hoe dat precies in elkaar steekt.

XML/XSLT heb ik ook nog aan gedacht, maar lijkt me voor dit projectje niet echt handig. Bovenal, het meeste werkt allemaal al (exact op de manier hoe ik het graag zie) en dus lijkt het me overdreven om al dat werk weer overnieuw te doen.

SIZE does matter.
"You're go at throttle up!"


Acties:
  • 0 Henk 'm!

Verwijderd

Ik vind die parser generators maar niks :)
Brouwen altijd van die gekke code; maak parsers toch liever zelf :->

Acties:
  • 0 Henk 'm!

  • Skinny
  • Registratie: Januari 2000
  • Laatst online: 13-09 21:14
Als je het niet erg vind, heb ik je zojuist even toegevoegd @ msn. Ik heb even wat vragen over het aldanniet commercieel gebruik van je code en wat kleine aanpassingen daarvan.

SIZE does matter.
"You're go at throttle up!"


Acties:
  • 0 Henk 'm!

  • Apollo_Futurae
  • Registratie: November 2000
  • Niet online
mbravenboer schreef op 04 March 2003 @ 10:03:
Laat je niet al te veel hersenspoelen door Haskell freaks (waarschijnlijk op de UU) >:) . Parser combinators zijn zeker niet onaardig, maar uiteindelijk moet alle parser technologie wat mij betreft wijken voor het parsen van talen met grammaticas in de volledige klasse van context-vrije grammatica's >:) . Je komt op het GLR parser algoritme. Er zijn verschillende implementaties zoals bijvoorbeeld SGLR (met SDF als grammatica taal).
op de uu kom ik zeer onregelmatig (ben er zegge en schrijve twee keer geweest :+) dus de slechte invloed daarvan kan mijn haskell-freakzijn niet verklaren :? :p.

ik ben zeer te spreken over de parser combinator Parsec: ik kan er alles mee parsen wat ik maar wil (vooralsnog geen problemen met ambigue grammatica's etc.) en het werkt lekker om parsers direct in je code te hebben (en dan ook nog zo geformuleerd, dat je direct ziet wat er geparsed wordt en waarin).

Pas de replâtrage, la structure est pourrie.

Pagina: 1