tclparser, a component of Tcl Dev Kit written in C, parses Tcl scripts.


Tcl Dev Kit
repository , which is just tclparser.

See Also

pure-Tcl alternative, different API
Sses introspection to get a similar result


package require parser


The module originated in TclPro, whose source code is available from sourceforge CVS or


fossil clone tclparser.fossil
mkdir -p tclparser/build
cd tclparser
fossil open ../tclparser.fossil
cd build
../configure --prefix=/home/tcl --with-tcl=/home/tcl/lib
make all install

cvs -d:pserver:[email protected]:/cvsroot/tclpro login
cvs -z3 -d:pserver:[email protected]:/cvsroot/tclpro co tclparser
mkdir tclparser/build
cd tclparser/build
../configure --prefix=/home/tcl --with-tcl=/home/tcl/lib
make install

Despite CVS history showing no activity since 2007, this builds cleanly against 8.6.4. That's a stable interface!


As the manual explains, it exposes one command parse $type $text $range, which returns a structure similar to tcltest's testparser, but a bit more convenient for script manipulation. Like tcltest::testparser, this is a lightweight wrapper around functions in tclParse.c .

Parsing Expressions

A simple example to turn an expression into namespace evalable code:

package require parser 

proc expr2tcl {expr {parse ""}} {
    if {$parse eq ""} {
        set parse [parse expr $expr {0 end}]
    lassign $parse type range parts
    lassign $range min max
    incr max $min
    incr max -1
    set text [string range $expr $min $max]
    set result ""
    switch $type {
        subexpr {
            set result [join [lmap part $parts {expr2tcl $expr $part}] " "]
            if {[lindex $parts 0 0] eq "operator"} {
                return \[$result\]
            } else {
                return $result
        default {
            return $text

# % puts [expr2tcl {sin($x)+4*$x-$x**(pow($x,2))}]
# [- [+ [sin $x] [* 4 $x]] [** $x [pow $x 2]]]

Parsing Scripts and Commands

To parse a script, repeatedly call parse command. Its result is a 4-tuple {commentRange commandRange restRange parseTree}. parseTree is an interesting structure that breaks down the words in the command, and the rest are just index pairs as illustrated in the below work-alike of scriptSplit .

package require parser

proc stringRange {string start step} {
    tailcall string range $string $start [expr {$start+$step}]

proc ss {script} {
    set restRange {0 end}
    while {1} {
        lassign [parse command $script $restRange] commentRange commandRange restRange tree
        set comment [stringRange $script {*}$commentRange]
        set command [stringRange $script {*}$commandRange]
        if {$command eq ""} break
        #puts "Parsed a command {$tree} {$command}"
        lappend result $command
    return $result

Note that the command terminator (newline or semicolon) is included in commandRange. But only if it is present. This is discussed somewhere else.

APN: Minor comment on the above use of string range. The expr is not needed as string range arguments can include + and - arithmetic operators. Also, the use of tailcall here does nothing useful other than slow down the procedure.