Posted to tcl by evilotto at Mon Jul 15 21:58:00 GMT 2013view pretty
driver: package require pt::peg::from::peg package require pt::peg::container package require pt::peg::interp package require pt::ast set f [open [lindex $argv 0]] set ldef [read $f] close $f set stream [open [lindex $argv 1]] pt::peg::container lang pt::peg::interp L lang deserialize = [pt::peg::from::peg convert $ldef] L use lang set ast [L parse $stream] seek $stream 0 set data [read $stream] proc exp_ast_nt {a} { if {[llength $a] == 3} { return [list [string range $::data [lindex $a 1] [lindex $a 2]]] } else { return [list {*}[lmap st [lrange $a 3 end] {exp_ast_nt $st}]] } } proc exp_ast {a} { if {[llength $a] == 3} { return [list [lindex $a 0] [string range $::data [lindex $a 1] [lindex $a 2]]] } else { return [list [lindex $a 0] {*}[lmap st [lrange $a 3 end] {exp_ast $st}]] } } foreach r [exp_ast $ast] { puts $r} puts "\nsimple:" foreach r [exp_ast_nt $ast] { puts $r} Grammar: PEG harzilein (command) command <- cmdname S* '{' S* operation? (S* ';' S* operation?)* '}' ; operation <- assignment / command ; assignment <- varname S* '=' S* multivalue ; multivalue <- assignment / value; leaf: cmdname <- ident ; leaf: varname <- ident ; leaf: value <- ident ; ident <- ('_' / <alnum>)+ ; void: S <- <space> ; END; Language test: command { foo = bar ; bar = baz ; nested_bar {foo=quux = quuuux}} Result: command cmdname command operation {assignment {varname foo} {multivalue {value bar}}} operation {assignment {varname bar} {multivalue {value baz}}} operation {command {cmdname nested_bar} {operation {assignment {varname foo} {multivalue {assignment {varname quux} {multivalue {value quuuux}}}}}}} simple: command {foo bar} {bar baz} {nested_bar {{foo {{quux quuuux}}}}}