Skip to content

Latest commit

 

History

History
123 lines (95 loc) · 4.63 KB

README.md

File metadata and controls

123 lines (95 loc) · 4.63 KB

$Id: README,v 1.5 2005/03/17 20:42:21 tang Exp $

Copyright

taccle itself is protected by the GNU General Public License. See the file COPYING for details. Of course, any code you generate using taccle is subject to whatever restrictions you place on it.

Availability

A wiki page for taccle may be found at http://mini.net/tcl/taccle. An archive of taccle files are available at http://tcl.jtang.org/taccle.

taccle README

taccle is another compiler compiler for the Tcl language. It takes as input a "taccle specification file"; from this taccle generates a Tcl file that implements an LALR(1) parser. The program brings to the Tcl language what yacc and bison do for C and C++.

This release of taccle implements nearly all features of yacc:

  • %token and %start declarations
  • epsilon transitions (i.e., "empty" rules)
  • embedded (mid-rule) actions
  • literal tokens
  • symbol values and synthesized attributes
  • the error token and error recovery
  • shift/reduce and reduce/reduce conflict notification
  • operator precedence with %left, %right, %nonassoc, and %prec
  • functions yyerror, YYABORT, YYACCEPT, and yyclearin
  • infinite recursion detection

Features currently missing in taccle are:

  • inherited attributes

Because taccle uses the lset command it requires Tcl 8.4 or greater.

Be aware of the following differences between taccle and yacc:

  1. taccle (and Tcl) has no concept of variable types. Thus %union and %type declarations are no longer needed.

  2. yacc uses variables $1, $2, etc for symbol values; it uses $$ for the synthesized attribute. Although both $1 and $$ are legal variable references in Tcl the latter is more awkward; the expression set $ foo' is not legal. Instead of $$ use the name '_', as in set _ foo'. These variables' scopes are valid only within the context of an action. See examples/simple_calculator.tac for an example.

    (The astute observer notes that using $_ for synthesized values is similar to Perl's use of the auto-variable $_.)

  3. taccle has error handling just like bison. It always declares the terminal `error' that is pushed onto the stack whenever it detects a syntax error. Although yyclearin is implemented neither YYRECOVERING nor yyerrok are. The example interactive_calculator.tac implements error handling.

  4. Like yacc, taccle requires a token generator. The examples use fickle (http://mini.net/tcl/fickle), though others are welcome.

  5. taccle calls a global function yylex to fetch the next token. This yylex function is expected to return the next token in the input stream, either a string or a number. Normally this poses no problem except for the case of a literal zero. Tcl makes no distinction between the integer zero and the string zero. Because zero is reserved for the end of input marker, taccle will refuse grammars that employ literal zeros. You can get around this by declaring `%token ZERO' and using that instead.

  6. Another literal that causes all sorts of problems is the open brace '{'. Because most things are represented internally as lists the presence of the brace breaks everything. Thus taccle will refuse to parse grammars with this literal; you'll have to use a %token instead.

Using the Examples

Execute taccle as if it were yacc:

$ tclsh ./taccle.tcl -d some_spec_file.tac

This will generate two files, some_spec_file.tcl and some_spec_file.tab.tcl. The first contains the actual parser code; execute it by calling yyparse. The latter file is file to be sourced by the lexer, much akin to yacc's y.tab.h file.

The Makefile in the examples subdirectory will generate two simple calculator programs. You will need a copy of fickle (available at http://mini.net/tcl/fickle) and may need to modify its location on line 4 of the Makefile. After filtering simple_calculator through ficcle and taccle execute it like so:

$ echo "6*9" | tclsh simple_calculator.tcl

If all goes well the program displays:

Result is 54

A more interesting example is interactive_calculator.tcl. This one is designed to handle any arbitrary number of commands. Upon errornous equations it recovers by discarding the rest of the buffer. Here is an example session of it:

$ tclsh interactive_calculator.tcl 6*9 = 54 1++2++3 = error 1 + 2 + 3 = 6

The final example, infix_calc.tcl, shows how to use operator precedence to resolve shift/reduce conflicts. It understands both left associative operators (addition et al) as well as right associative (exponentation). Here is an example use:

$ echo "2^2^2 - 10 * 2 + 6 / 3" | tclsh infix_calc.tcl -2