%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 ExampleHere 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; yyparseThis is, of course, the infamous calculator example. To users of yacc/bison observe that taccle has $_ instead of $$. Further differences are described in the README file[3].There are some things taccle cannot handle. These are on my TODO list:- inherited attributes (synthesized attributes are easy, inherited not so)
Downloadstaccle 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.
Bezoar 2015 Dec13Links to tar.gz files are dead. However Jason has put his taccle and fickle projects in git hub taccle[4]Download taccle from below:
- taccle 1.1 at http://tcl.jtang.org/taccle/taccle-1.1.tar.gz
(also from here [5] - direct link [6]) - taccle 1.0 at http://tcl.jtang.org/taccle/taccle-1.0.tar.gz

- taccle 0.4 at http://tcl.jtang.org/taccle/taccle-0.4.tar.gz

- taccle 0.3 at http://tcl.jtang.org/taccle/taccle-0.3.tar.gz

- taccle 0.2 at http://tcl.jtang.org/taccle/taccle-0.2.tar.gz

- taccle 0.1 at http://tcl.jtang.org/taccle/taccle-0.1.tar.gz

foo: foo 'x' ; bar: 'y' baz ; baz: 'z' bar ;taccle version 1.0 is the first official release:
- comments now TclDoc friendly
- operator precedence (%left, %right, %nonassoc, and %prec)
- new command line flags -w and --version
- fixed error when calculating first and follow sets for certain recursive rules
- corrected epsilon transitions; they should work for 99.99% of all cases now
- embedded (i.e., "mid-rule") actions
- preliminary epsilon transitions (doesn't work yet for all conditions)
- error recovery with the error token
- rename all variables with -p option
Another ExampleI was asked to provide a non-calculator example. This one parses some simple English sentences. (Handling all of English is difficult to impossible; that requires a doctorate in natural language parsing. See NLP for a Knowledge Database as an attempt do so.) First is the grammar; save this as english_parser.tac:
%{
source english_scanner.tcl
%}
%token NOUN VERB ADJECTIVE ARTICLE PREPOSITION
%%
sentence: subject VERB direct_object '.'
{ puts "subject: $1\nverb: $2\ndirect object: $3" }
| subject VERB '.'
{ puts "subject: $1\nverb: $2" }
;
subject: noun_phrase { set _ $1 }
;
noun_phrase: ARTICLE ADJECTIVE NOUN { set _ [list $1 $2 $3] }
| ARTICLE NOUN { set _ [list $1 $2] }
| ADJECTIVE NOUN { set _ [list $1 $2] }
| NOUN { set _ [list $1] }
;
direct_object: PREPOSITION noun_phrase { set _ "$1 $2" }
| noun_phrase { set _ $1 }
;
%%
yyparseNext is the scanner, english_scanner.fcl:%{
source "english_grammar.tab.tcl"
%}
%option interactive caseless
%%
bob|john|sue|jane { set ::yylval $yytext; return $::NOUN }
ball|box|brick|bag { set ::yylval $yytext; return $::NOUN }
red|blue|green|big { set ::yylval $yytext; return $::ADJECTIVE }
a|an|the { set ::yylval $yytext; return $::ARTICLE }
kick|hit|took|gave { set ::yylval $yytext; return $::VERB }
jumped|leapt|flew { set ::yylval $yytext; return $::VERB }
over|under|around { set ::yylval $yytext; return $::PREPOSITION }
\s # ignore whitespace
. { set ::yylval $yytext; return $yytext }Here is a Makefile; you'll need to modify the paths to match your system: TCL=tclsh
FICKLE=~/fickle/fickle.tcl
TACCLE=~/taccle/taccle.tcl
all: english_grammar.tcl english_scanner.tcl
%.tcl: %.fcl
$(TCL) $(FICKLE) $<
%.tcl: %.tac
$(TCL) $(TACCLE) -d -w $<And some example runs:$ echo "Big Bob jumped over the red ball." | tclsh english_grammar.tcl subject: Big Bob verb: jumped direct object: over the red ball $ echo "Sue took the green box." | tclsh english_grammar.tcl subject: Sue verb: took direct object: the green box $ echo "The brick flew under a blue bag." | tclsh english_grammar.tcl subject: The brick verb: flew direct object: under the blue bag $ echo "Jane jumped." | tclsh english_grammar.tcl subject: Jane verb: jumped
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 code into version 0.4.[Paul Doerwald] I was told that my regexps were "excellent" and "worthy of worship by Perl monks" *blush* and thus encouraged to post here. This is a fickle script that takes a fulltext of some sort (like a New York Times article) and looks through it for names of people and companies. There are lots of false positives but that's life, and in the application they didn't matter.
%{
#!/usr/bin/tclsh
%}
%%
[ \t] puts -nonewline "$yytext"
((([[:upper:]]')?[[:upper:]]+[&.]?[[:lower:]]*),?[ ]?(and|&)*[ ]+)+(([[:upper:]]')?[[:upper:]]+[[:lower:]]*)+ |
(((([[:upper:]]')?[[:upper:]]+\.?[[:lower:]]*)[ ]+)+(of|the|and|for|&)*[ ]*)+(([[:upper:]]')?[[:upper:]]+[[:lower:]]*)+ |
([[:upper:]]('[[:upper:]])?[[:alpha:].-]+[ ])+([[:upper:]]'?[[:alpha:].-]+) |
[[:upper:]]('[A-Z])?[[:alpha:].-]+ |
[[:upper:]]('[[:upper:]])?[[:alpha:]-]+ |
[[:upper:]]('[[:upper:]])?[[:alpha:]]+ puts -nonewline "<$yytext>"
[[:alpha:]]+ puts -nonewline "$yytext"
.|\n puts -nonewline "$yytext"
%%
yylexReturn to Jason Tang

