[Sarnold] 2009-09-20 - Yet another week-end fun project: parsing S-EXP to Tcl. Usage: lispy::parse string ====== % p "incr 'foo 3" incr foo 3 % p "lindex '(1 2 3) 1" lindex {1 2 3} 1 % p "add x y" add $x $y % p "+ w t" + $w $t ====== ---- package provide lispy 0.4 package provide lispy 0.3 namespace eval lispy {} proc lispy::hasescape string { foreach {regex token} { {\-?[0-9]+(\.[0-9]*)?([eE][+-]?[0-9]+)?} number {".*"} string {[a-zA-Z_:][A-Za-z0-9_:]*} var {\$[a-zA-Z_:][A-Za-z0-9_:]*} dvar {[+\-\*/\!=<>%\|&A-Aa-z_:\.][+\-\*/\!=<>%\|&A-Aa-z_:\.0-9]*} cmd {[+\-\*/\!=<>\|&A-Aa-z_:][+\-\*/\!=<>\|&A-Aa-z_:0-9]*} cmd {\?\(} expr {\)} close {;.*\n} comment {[\t ]+} blank } { if {[regexp ^$regex $code match]} { if {$token eq "string"} { return [list $token $match] } error "invalid syntax at: '$code'" } proc lispy::ismath x { proc parse-$name var [string map [list %body [list $body]] { upvar 1 code $var set res "" while {$code ne ""} { foreach {tag string} [lexeme $code] break set code [string range $code [string length $string] end] if {$tag eq "comment"} continue switch -- $tag %body } return $res }] } lispy::make-parser command { blank - number - string - dvar { blank - number - string - var - cmd { append res $string return "$res[parse-arguments code]" } var - cmd { append res [string range $string 1 end] return "$res[parse-arguments code]" } open { append res [parse-command code] append res \[[parse-command code]\] } close { return $res } } lispy::make-parser arguments { blank - number - string - cmd - dvar { blank - number - string - cmd { append res $string } tag { append res [string range $string 1 end] } var { append res \$$string } open { append res "\[[parse-command code]\]" append res \[[parse-command code]\] expr { return $res } list { append res [parse-list code] append res "{[parse-list code]}" begin { # math expressions lispy::make-parser list { blank - number - string - cmd - var - dvar { blank - number - string - cmd - var { append res $string } tag { append res [string range $string 1 end] } close { return \{$res\} return $res list - open { append res [parse-list code] append res "{[parse-list code]}" } interp alias "" p "" lispy::parse proc lispy::parse code { lispy::parse-command code } ====== <>Category Syntax | Category Language <>[Category Syntax] [Category Language]