JBR 9-13-2012 Here is a little example testing out my Operator precedence expression parser
source expression.tcl # Here is a little namespace to try out the parser. # namespace eval evaluate { proc add { args } { expr [join $args +] } proc sub { args } { expr [join $args -] } proc mul { args } { expr [join $args *] } proc div { args } { expr [join $args /] } proc assign { a b } { set ::$a $b } proc addasn { a b } { set ::$a [expr [set ::$a] + $b] } proc subasn { a b } { set ::$a [expr [set ::$a] - $b] } proc mulasn { a b } { set ::$a [expr [set ::$a] * $b] } proc divasn { a b } { set ::$a [expr [set ::$a] / $b] } proc inc { a } { incr ::$a } proc dec { a } { incr ::$a -1 } proc incu { a } { incr ::$a } proc decu { a } { incr ::$a -1 } proc uadd { a } { return [expr +$a] } proc usub { a } { return [expr -$a] } proc dolar { a } { set ::$a } proc call { args } { {*}$args } proc indx { args } { set ::[lindex $args 0]([join [lrange $args 1 end] ,]) } proc eval { op args } { return [$op {*}$args] } } # Process the operator table to create the string map table that suffices # for the lexical analyzer. # set tokens [expression::prep-tokens $expression::optable] # A little test proc. # proc ? { a b } { # Parse the expresson in $a by calling the evaluator on each subexpression # set result [expression::parse $a $::tokens $expression::optable evaluate::eval] if { $result ne $b } { puts "$a : $result != $b" } } ? xx xx ; # Simple string identity ? 4+5*7 39 ; # Some math ? 4+(5*7) 39 ? (4+5)*7 63 ? +4 4 ; # Unary ops ? -4 -4 ? 9+4+6 19 ? add(1,2,3) 6 ; # Function call ? add(1+2,2+2*3,3) 14 set x 1 set y 2 ? { x += $y } 3 ; # NB: The "$" is recognized as the "deref" ? { x -= $y } 1 ; # operator and handled in the evaluator. ? { x *= $y } 2 ? { x /= $y } 1 set a 3 ? {4 + a++} 8 set d(4) 8 set a d ? {($a)[4]} 8 # Check some errors # #catch { ? {$x .} rr. } reply; #if { $reply ne {parse error at: x _@_ . : unexpected token : x _@_ .} } { puts "fail : \$x . : $reply" } #catch { ? 4+8) xx } reply; #if { $reply ne {parse error at: 8 _@_ ) : unexpected ")" : 8 ) } } { puts "fail : unexpected \")\" : 8 ) : $reply" } namespace eval a {} set a::b(4) 5 #? { $a::b[4] } 5