package require starkit starkit::startup package require pt::peg::from::peg package require pt::peg::container package require pt::peg::interp set PEG { PEG myapp (Exp) IfKw <- 'i' 'f' ; ThenKw <- 't' 'h' 'e' 'n' ; ElseKw <- 'e' 'l' 's' 'e' ; OSp <- ('\t' / '\n' / ' ')? ; Sp <- ('\t' / '\n' / ' ')+ ; Block <- (Exp / 't') &';' ; Cond <- 'c' / 'o' ; If <- IfKw Sp Cond OSp ':' OSp Block ; Exp <- If ; END; } set CPEG [pt::peg::from::peg convert $PEG] pt::peg::container cont cont deserialize = $CPEG set src "if c: if o:t;" pt::peg::interp myint myint use cont puts [myint parset $src](I use startkit...)
This grammar is very simple (and non-realistic): it defines rules to parse nested 'if'-expression like this:
if c: if o: t;OR
if CONDITION: if CONDITION: BLOCK;where CONDITION is 'c' or 'o', BLOCK is another EXP (expression) or 't' followed by ';'; when blocks are nested, only one ';' is needed. Example has bugs (see Sp, OSp - Optional SPaces) but shows base tricks with PEG, for ex., PEG definition is loaded from variable, not imported from file, so you need for your App. not all Tcllib packages :) After running, you get:
c:\>tclkitsh.exe main.tcl Exp 0 11 {If 0 11 {IfKw 0 1} {Sp 2 2} {Cond 3 3} {OSp 4 3} {OSp 5 5} {Block 6 11 {Exp 6 11 {If 6 11 {IfKw 6 7} {Sp 8 8} {Cond 9 9} {OSp 10 9} {OSp 11 10} {Block 11 11}}}}}
Комментариев нет:
Отправить комментарий
Thanks for your posting!