taccle -- Taccle is Another Compiler Compiler
taccle is a complement to fickle in that it reads a taccle specification file to generate working LALR(1) parser. In other words, it is to Tcl what yacc (or bison) is to C/C++. taccle differs from yeti in that the grammar is written before hand as a straight text file rather than generated by procedure calls. taccle generates pure Tcl rather than incr tcl and has embedded actions. Unlike tyacc [L1 ] taccle is written in pure Tcl 8.4.
taccle spec files are structured nearly identical to those used by yacc. The following example (blantantly stolen from chapter 8 of lex & yacc[L2 ]) may be interpreted equally by the two:
%token A R %% start: x | y R; x: A R; y: A;
Incidentally both yacc and taccle would recognize the shift/reduce conflict above.
A Practical Example
Here is another example. The file has been compacted to make it better fit on the web page.
%{ #!/usr/bin/tclsh %} %token ID %start start %% start: E { puts "Result is $1" } ; E: E '+' T { set _ [expr {$1 + $3}] } | E '-' T { set _ [expr {$1 - $3}] } | T ; T: T '*' F { set _ [expr {$1 * $3}] } | T '/' F { set _ [expr {$1 / $3}] } | F ; F: '(' E ')' { set _ $2 } | ID { set _ $::yylval } ; %% source simple_scanner.tcl; yyparse
This is, of course, the infamous calculator example. Several new things are presented here:
New with taccle version 0.4 are:
With taccle version 0.3 are:
taccle version 0.2 has:
There are some things taccle cannot handle. These are on my TODO list:
Downloads
taccle is protected by the GNU General Public License. You should read the README file before use; a complete set of examples are in the examples subdirectory. Familiarity with the Dragon book as well as lex & yacc would also prove useful.
Download taccle from below:
Comments below:
FPX: Nice. At the time, I wanted to write a supplementary program for yeti to parse a yacc-like input file and produce a parser from that. I never got around to it. I wanted to write the program twice: Once, based on yeti primitives, and second, using itself -- the litmus test for every compiler is to compile itself ;)
27sep04 jcw - The following small change to taccle.tcl produces output files which are easier to examine, by breaking up potentially huge [array get ...] lines:
###################################################################### # handles actually writing parser to output files proc write_array {fd name values} { puts $fd "array set $name {" foreach {x y} $values { puts $fd " [list $x $y]" } puts $fd "}" } proc write_dest_file {} { puts $::dest " ###################################################################### # autogenerated taccle code below " write_array $::dest ::${::p}table [array get ::lalr1_parse] write_array $::dest ::${::p}rules [array get ::rule_table *l] write_array $::dest ::${::p}rules [array get ::rule_table *dc] write_array $::dest ::${::p}rules [array get ::rule_table *e] puts $::dest "
jt Thanks for the suggestion. I've incorporated your suggestion into version 0.4.
Return to Jason Tang