yacker tool
authorLuc Moreau <l.moreau@ecs.soton.ac.uk>
Wed, 09 May 2012 23:20:21 +0100
changeset 2742 b93ae20cce4e
parent 2741 d1d9362b9cf7
child 2743 53f3877f60d0
yacker tool
model/grammar/Makefile
model/grammar/yack/Makefile
model/grammar/yack/perl/modules/W3C/Grammar/.cvsignore
model/grammar/yack/perl/modules/W3C/Grammar/CharacterRange.pm
model/grammar/yack/perl/modules/W3C/Grammar/LexGrammar.yp
model/grammar/yack/perl/modules/W3C/Grammar/Makefile.PL
model/grammar/yack/perl/modules/W3C/Grammar/Presenter.pm
model/grammar/yack/perl/modules/W3C/Grammar/SymbolParser.yp
model/grammar/yack/perl/modules/W3C/Grammar/YaccCompileTree.pm
model/grammar/yack/perl/modules/W3C/Grammar/YaccParser.pm
model/grammar/yack/perl/modules/W3C/Grammar/YaccParser.yp
model/grammar/yack/perl/modules/W3C/Grammar/YackerSymbolParser.pm
model/grammar/yack/perl/modules/W3C/Grammar/YackerSymbolParser.yp
model/grammar/yack/perl/modules/W3C/Grammar/YackerSymbolParser.yp.onDeck
model/grammar/yack/perl/modules/W3C/Grammar/YackerTraceParser.pm
model/grammar/yack/perl/modules/W3C/Grammar/bin/.cvsignore
model/grammar/yack/perl/modules/W3C/Grammar/bin/BNFTemplate
model/grammar/yack/perl/modules/W3C/Grammar/bin/YaccFooterTemplate
model/grammar/yack/perl/modules/W3C/Grammar/bin/YaccHeaderTemplate
model/grammar/yack/perl/modules/W3C/Grammar/bin/YappTemplate
model/grammar/yack/perl/modules/W3C/Grammar/bin/regTest
model/grammar/yack/perl/modules/W3C/Grammar/bin/scanTests
model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/CPPYacc/Langname_Parser.yy
model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/CPPYacc/Langname_Scanner.hh
model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/CPPYacc/Langname_Scanner.ll
model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/CPPYacc/Makefile
model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/CYacc/Langname_Enums.h
model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/CYacc/Langname_Parser.y
model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/CYacc/Langname_Scanner.l
model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/CYacc/Makefile
model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/PerlYapp/Langname_.yp
model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/PerlYapp/Makefile
model/grammar/yack/perl/modules/W3C/Grammar/bin/yacker
model/grammar/yack/perl/modules/W3C/Grammar/t/01basic.t
model/grammar/yack/perl/modules/W3C/Grammar/t/02yaml.t
model/grammar/yack/perl/modules/W3C/Grammar/t/lib/TestRunner.pm
model/grammar/yack/perl/modules/W3C/Util/Exception.pm
model/grammar/yack/perl/modules/W3C/Util/YappDriver.pm
model/grammar/yack/prov-n.bnf
model/grammar/yack/prov_n.html
model/grammar/yack/sample.in
model/grammar/yack/templates
model/grammar/yack/turtle.bnf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/Makefile	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,19 @@
+
+go.provn:
+	cd yack; PERL5LIB=perl/modules perl/modules/W3C/Grammar/bin/yacker -stubs -short -lang perl -o prov_n prov-n.bnf 
+	cd yack; $(MAKE)
+
+man.provn:
+	cd yack; perldoc prov_n.pm
+
+run.provn:
+	cd yack; perl -Mprov_n -e test < sample.in 3> sample.trace
+
+go.turtle:
+	cd yack; PERL5LIB=perl/modules perl/modules/W3C/Grammar/bin/yacker -stubs -lang perl -o turtle turtle.bnf 
+	cd yack; $(MAKE)
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/Makefile	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,7 @@
+PARSERS = prov_n.pm
+
+parsers: $(PARSERS)
+
+$(PARSERS): %.pm: %.yp
+	yapp -v -s -o $@ $<
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/.cvsignore	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,1 @@
+Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/CharacterRange.pm	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,344 @@
+# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
+# Copyright ©2004 W3C® (MIT, INRIA, Keio University),
+
+#Last update $Date: 2005-09-17 09:52:49 $ by $Author: eric $. $Revision: 1.4 $
+
+use strict;
+my $REVISION = '$Id: CharacterRange.pm,v 1.4 2005-09-17 09:52:49 eric Exp $';
+package W3C::Grammar::CharacterRange::FlatRangeList;
+use W3C::Util::Exception;
+sub new {
+    my ($proto) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = {Ordered => []};
+    bless ($self, $class);
+    return $self;
+}
+sub _ensureEntry {
+    my ($self, $character) = @_;
+    my $ret = [];
+    for (my $i = 0; $i < @{$self->{Ordered}}; $i++) {
+	if ($character == $self->{Ordered}[$i][0]) {
+	    return $self->{Ordered}[$i];
+	} elsif ($character < $self->{Ordered}[$i][0]) {
+	    splice (@{$self->{Ordered}}, $i, 0, $ret);
+	    return $ret;
+	}
+    }
+    push (@{$self->{Ordered}}, $ret);
+    return $ret;
+}
+sub addRange {
+    my ($self, $l, $r) = @_;
+    $l = ord($l);
+    $r = ord($r);
+    my $spot = $self->_ensureEntry($l);
+    if (@$spot && $spot->[1] >= $r) {
+	# there was already a sufficient range
+    } else {
+	$spot->[0] = $l;
+	$spot->[1] = $r;
+    }
+}
+sub getAscendingRanges {
+    my ($self) = @_;
+    return $self->{Ordered};
+}
+sub toString {
+    my ($self, %flags) = @_;
+    my @ret;
+    for (my $i = 0; $i < @{$self->{Ordered}}; $i++) {
+	my ($b, $t) = @{$self->{Ordered}[$i]};
+	my $entry = $b == $t ? $b : "$b - $t";
+	push (@ret, "$i: $entry\n");
+    }
+    return wantarray ? @ret : join("\n", @ret);
+}
+
+sub _substractRange { # static
+    my ($from, $excl) = @_;
+    my $exclI = 0;
+    my ($xB, $xT) = @{$excl->[$exclI]};
+  FROM:
+    for (my $fromI = 0; $fromI < @$from; $fromI++) {
+	my ($fB, $fT) = @{$from->[$fromI]};
+
+	# skip froms below the next excl
+	if ($xB > $fT) {
+	    next;
+	}
+
+	# skip exlcs below the next from
+	while ($fB > $xT) {
+	    if (++$exclI >= @$excl) {
+		last FROM;
+	    }
+	    ($xB, $xT) = @{$excl->[$exclI]};
+	}
+
+	# remove the current entry
+	splice(@$from, $fromI--, 1);
+
+	# add one below 
+	if ($xB-1 > $fB) {
+	    splice(@$from, ++$fromI, 0, [$fB, $xB-1]);
+	}
+
+	# add intermediates for next excls that fit in from range
+	while ($exclI < @$excl-1 && 		# there's another excl
+	       $fT > $excl->[$exclI+1][0]) {	# who's bottom < fromT
+	    my $lastTop = $xT;
+	    ($xB, $xT) = @{$excl->[++$exclI]};
+	    if ($xB-1 >= $lastTop+1) {
+		splice(@$from, ++$fromI, 0, [$lastTop+1, $xB-1]);
+	    }
+	}
+
+	# add one above 
+	if ($fT > $xT+1) {
+	    splice(@$from, ++$fromI, 0, [$xT+1, $fT]);
+	}
+    }
+}
+
+package W3C::Grammar::CharacterRange;
+
+sub compileUTF8range {
+    my ($bot, $top, $printChar) = @_;
+
+    my $utf8rules = 
+      [
+       [[    0x00,     0x7f], [0x00],  
+	[0x7f]], 
+       [[    0x80,    0x7ff], [0xc2, 0x80], 
+	[0xdf, 0xbf]], 
+       [[   0x800,    0xfff], [0xe0, 0xa0, 0x80], 
+	[0xe0, 0xbf, 0xbf]], 
+       [[  0x1000,   0xcfff], [0xe1, 0x80, 0x80],  
+	[0xec, 0xbf, 0xbf]], 
+       [[  0x1000,   0xcfff], [0xe1, 0x80, 0x80],  
+	[0xec, 0xbf, 0xbf]], 
+       [[  0xd000,   0xd7ff], [0xed, 0x80, 0x80],  
+	[0xed, 0x9f, 0xbf]], 
+       [[  0xe000,   0xffff], [0xee, 0x80, 0x80],  
+	[0xef, 0xbf, 0xbf]], 
+       [[ 0x10000,  0x3ffff], [0xf0, 0x90, 0x80, 0x80],  
+	[0xf0, 0xbf, 0xbf, 0xbf]], 
+       [[ 0x40000,  0xfffff], [0xf1, 0x80, 0x80, 0x80],  
+	[0xf3, 0xbf, 0xbf, 0xbf]], 
+       [[0x100000, 0x10ffff], [0xf4, 0x80, 0x80, 0x80],  
+	[0xf4, 0xbf, 0xbf, 0xbf]], 
+      ];
+
+    $printChar ||= sub {
+	my ($ch) = @_;
+	my $hex = sprintf ("%02X", $ch);
+	return "\\x$hex";
+    };
+
+    return _compileRange($utf8rules, $printChar, $bot, $top);
+}
+sub compileUTF16range {
+    my ($bot, $top, $printChar) = @_;
+
+    my $utf16rules = 
+    [
+     [[  0x0000,   0xffff], [0x0000],  # minus 0xD800 - 0xDFFF reserved for surrogates
+			    [0xffff]], 
+     [[ 0x10000, 0x10ffff], [0xd7c0, 0x0000],  
+			    [0xdbff, 0xdfff]], 
+    ];
+
+    $printChar ||= sub {
+	my ($ch) = @_;
+	my $hex = sprintf ("%04X", $ch);
+	return "\\x$hex";
+    };
+
+    return _compileRange($utf16rules, $printChar, $bot, $top);
+}
+
+# This algorithm is responsible for counting and transitions between different regions of contiguous encoding. The counting works on in an arbitrary sequence of bases...
+sub _compileRange {
+    my ($rules, $printChar, $bot, $top) = @_;
+    my $botRuleNo = &_find($rules, $bot);
+    my $topRuleNo = &_find($rules, $top);
+    my $ret;
+    if ($botRuleNo == $topRuleNo) {
+	$ret = &_expandRange($rules, $printChar, $botRuleNo, $bot, $top);
+    } else {
+	my $bRule = $rules->[$botRuleNo];
+	my $tRule = $rules->[$topRuleNo];
+
+	my @ranges;
+	my $t;
+
+	# Expand the bottom rule (including stair-steps)
+	(undef, undef, $t) = &_expandRange($rules, $printChar, $botRuleNo, $bot, chr($bRule->[0][1]));
+	push (@ranges, $t);
+
+	# Expland each rule in between the bottom and top.
+	for (my $i = $botRuleNo+1; $i < $topRuleNo; $i++) {
+	    (undef, undef, $t) = &_expandRange($rules, $printChar, $i, chr($rules->[$i][0][0]), chr($rules->[$i][0][1]));
+	    push (@ranges, $t);
+	}
+
+	# Expand the top rule.
+	(undef, undef, $t) = &_expandRange($rules, $printChar, $topRuleNo, chr($tRule->[0][0]), $top);
+	push (@ranges, $t);
+	$ret = join('|', @ranges);;
+    }
+    return $ret;
+}
+
+# Find which rule subsumes the codepoint.
+sub _find {
+    my ($rules, $point) = @_;
+    for (my $i = 0; $i < @$rules; $i++) {
+	if (ord($point) >= $rules->[$i][0][0] && 
+	    ord($point) <= $rules->[$i][0][1]) {
+	    return $i;
+	}
+    }
+    die;
+}
+
+# Expand the characters between $bot and $top. ruleNo must subsume both characters.
+sub _expandRange {
+    my ($rules, $printChar, $ruleNo, $bot, $top) = @_;
+    &utf8::encode($bot);
+    &utf8::encode($top);
+    my $botBytes = [unpack('C*', $bot)];
+    my $topBytes = [unpack('C*', $top)];
+    my $bytes = scalar @$botBytes;
+    my $rule = $rules->[$ruleNo];
+    return &_walk([@{$rule->[1]}], [@{$rule->[2]}], $botBytes, $topBytes, $printChar);
+}
+my $SEQ = '';
+sub _walk {
+    my ($bRules, $tRules, $botBytes, $topBytes, $printChar) = @_;
+    my $bRule = shift (@$bRules);
+    my $tRule = shift (@$tRules);
+    my $botByte = shift (@$botBytes);
+    my $topByte = shift (@$topBytes);
+    my $b = &$printChar($botByte);
+    my $t = &$printChar($topByte);
+    my $rb = &$printChar($bRule);
+    my $rt = &$printChar($tRule);
+
+    if (!@$bRules) {
+	return ($botByte != $bRule, $topByte != $tRule, $botByte == $topByte ? "$b" : "[$b-$t]");
+    }
+
+    # Do a tentative walk of remaining chars. Sets $splitB and $splitT.
+    my ($splitB, $splitT, $range) = &_walk([@$bRules], [@$tRules], [@$botBytes], [@$topBytes], $printChar);
+
+    if ($botByte == $topByte) {
+	return ($splitB, $splitT, "($b$SEQ$range)");
+    }
+
+    my @ret;
+    my $topStr = '';
+
+    if ($splitB) {
+	# Walk the bottom as if the top char is the top rule.
+	my (undef, undef, $bRange) = &_walk([@$bRules], [@$tRules], [@$botBytes], [@$tRules], $printChar);
+	push (@ret,"($b$SEQ$bRange)");
+	$botByte++;
+	$b = &$printChar($botByte);
+    } elsif ($botByte > $bRule) {
+	$splitB = 1; # our callers have to worry about stair-stepping
+    }
+
+    if ($splitT) {
+	# Walk the bottom as if the bottom char is the bottom rule.
+	my (undef, undef, $tRange) = &_walk([@$bRules], [@$tRules], [@$bRules], [@$topBytes], $printChar);
+	$topStr = "($t$SEQ$tRange)";
+	$topByte--;
+	$t = &$printChar($topByte);
+    } elsif ($topByte > $tRule) {
+	$splitT = 1; # our callers have to worry about stair-stepping
+    }
+
+    # Walk intermediate sub-rules.
+    if ($topByte > $botByte) {
+	my $r1 = &_walkFull([@$bRules], [@$tRules], $printChar);
+	push (@ret, "([$b-$t]$SEQ$r1)");
+    }
+    if ($topStr) {
+	push (@ret, $topStr);
+    }
+    return ($splitB, $splitT, join("|", @ret));
+}
+
+# Include all chars between $bot and $top .
+sub _walkFull {
+    my ($bot, $top, $printChar) = @_;
+    my $b = &$printChar(shift @$bot);
+    my $t = &$printChar(shift @$top);
+    my $ret = $b eq $t ? $b : "[$b-$t]";
+    if (@$bot) {
+	my $r = &_walkFull($bot, $top, $printChar);
+	return "$ret$SEQ$r";
+    } else {
+	return $ret;
+    }
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+W3C::Grammar::CharacterRange - Utilities for handling character classes.
+
+=head1 SYNOPSIS
+
+  use W3C::Grammar::CharacterRange;
+  $t = W3C::Grammar::CharacterRange::compileUTF8range($lc, $rc);
+
+
+=head1 DESCRIPTION
+
+
+This module is part of the W3C::Grammar CPAN module.
+
+=head1 METHODS
+
+=head2 CharacterRange:
+
+=head2 compileUTF8range(lower, upper)
+
+return a string expressing the range of the lower to the upper UTC codes expressed as UTF-8 validating byte sequences.
+
+=head2 immediateEvaluate($resultSet)
+
+Perform compile-time evaluations.
+
+no return value
+
+=head2 delayedEvaluate($resultSet)
+
+Perform post-compile-time (pass 2) evaluations. This is for query languages
+that require a second pass to do things like resolve namespace prefixes that
+are declared after a dependent qname is first used.
+
+no return value
+
+=head2 val($triple, $premise, $row)
+
+Perform the query evaluation. I don't remember what the hell the $premise is,
+but it sure looks important.
+
+returns an interned RDF Atom
+
+=head1 AUTHOR
+
+Eric Prud'hommeaux <eric@w3.org>
+
+=head1 SEE ALSO
+
+W3C::Rdf::Yacc2(1) W3C::Rdf::YaccParser(1) W3C::Rdf::Atom(1) perl(1).
+
+=cut
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/LexGrammar.yp	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,106 @@
+##### LEX PRODUCTIONS
+goal999		:  startlex sect2 endlex
+		;
+
+startlex	:
+{
+    $LexMode = 1;
+    &StartLex();
+}
+		;
+
+endlex		:
+{
+    $LexMode = 0;
+    &EndLex();
+}
+		;
+
+sect2		:  sect2 scon flexrule '\n'
+		|  sect2 scon '{' sect2 '}'
+		|
+		;
+
+flexrule	:  '^' L_rule
+		|  L_rule
+		|  EOF_OP # !! not suported
+		|  error
+			{ synerr( "unrecognized rule" ); }
+		;
+
+scon		:  '<' namelist2 '>'
+		|  '<' '*' '>'
+		|
+		;
+
+namelist2	:  namelist2 ',' sconname
+		|  sconname
+		|  error
+			{ synerr( "bad start condition list" ); }
+		;
+
+sconname	:  IDENT # was NAME
+		;
+
+L_rule		:  re2 re
+		|  re2 re '$'
+		|  re '$'
+		|  re
+		;
+
+
+re		:  re '|' series
+		|  series
+		;
+
+
+re2		:  re '/'
+		;
+
+series		:  series singleton
+		|  singleton
+		;
+
+singleton	:  singleton '*'
+		|  singleton '+'
+		|  singleton '?'
+		|  singleton '{' NUMBER ',' NUMBER '}'
+		|  singleton '{' NUMBER ',' '}'
+		|  singleton '{' NUMBER '}'
+		|  '.'
+		|  fullccl
+		|  PREVCCL # !! not supported
+		|  '"' string '"'
+		|  '(' re ')'
+		|  CHAR
+		;
+
+fullccl		:  '[' ccl ']'
+		|  '[' '^' ccl ']'
+		;
+
+ccl		:  ccl CHAR '-' CHAR
+		|  ccl CHAR
+		|  ccl ccl_expr
+		|
+		;
+
+ccl_expr:	   CCE_ALNUM
+		|  CCE_ALPHA
+		|  CCE_BLANK
+		|  CCE_CNTRL
+		|  CCE_DIGIT
+		|  CCE_GRAPH
+		|  CCE_LOWER
+		|  CCE_PRINT
+		|  CCE_PUNCT
+		|  CCE_SPACE
+		|  CCE_UPPER
+		|  CCE_XDIGIT
+		;
+
+string		:  string CHAR
+		|
+		;
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/Makefile.PL	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,56 @@
+# BEGIN {unshift@INC,('../..');}
+
+use ExtUtils::MakeMaker;
+use Config;
+use English;
+use strict;
+
+my $REVISION = '$Id: Makefile.PL,v 1.4 2007-01-22 19:37:34 eric Exp $ ';
+
+my @extras = ();
+
+push(@extras,
+     CAPI => 'TRUE')
+    if ($PERL_VERSION >= 5.005 and $OSNAME eq 'MSWin32'
+	and $Config{archname} =~ /-object\b/i);
+
+push(@extras,
+     ABSTRACT => "some handy tools work playing with yacc grammars",
+     AUTHOR   => 'Eric Prud\'hommeaux (eric@w3.org)')
+    if ($ExtUtils::MakeMaker::Version >= 5.4301);
+
+WriteMakefile(CONFIGURE => \ &configure);
+
+sub configure {
+    my $exes = [qw(bin/yacker)];
+
+    my $input = {PREREQS => {'Parse::Yapp' => 0, 'YAML' => 0}};
+
+    return {  NAME         => 'W3C::Grammar::Kit',
+              VERSION => 1.0,
+              PREREQ_PM    => $input->{PREREQS},
+              dist         => {COMPRESS => 'gzip', SUFFIX => '.gz'},
+	      EXE_FILES    => $exes,
+	      @extras};
+}
+
+sub MY::postamble {
+    return <<EOF;
+
+PARSERS = YaccParser.pm YackerSymbolParser.pm
+
+YAPPS := \$(patsubst \%.pm,\%.yp,\$(PARSERS))
+
+parsers: \$(PARSERS)
+
+\$(PARSERS): \%.pm: \%.yp Makefile
+	yapp -m W3C::Grammar::_\$(basename \$\@) -v -o \$\@ -b '/usr/bin/perl' \$\<
+	perl -pi -e "s/use Parse::Yapp::Driver;/# use Parse::Yapp::Driver; @@ replaced by W3C::Util::YappDriver/g" \$\@
+	perl -pi -e "s/^\\#line ([\\d+]) \\"\$<\\"/\\#line \\\\1 \\"..\\/\$<\\"/" \$@
+
+Makefile: Makefile.PL
+	perl Makefile.PL
+
+EOF
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/Presenter.pm	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,334 @@
+# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
+# Copyright ©2004 W3C® (MIT, INRIA, Keio University),
+
+#Last update $Date: 2007-12-21 09:35:46 $ by $Author: eric $. $Revision: 1.39 $
+
+use strict;
+my $REVISION = '$Id: Presenter.pm,v 1.39 2007-12-21 09:35:46 eric Exp $';
+package W3C::Grammar::PresenterException;
+@W3C::Grammar::PresenterException::ISA = qw(W3C::Util::Exception);
+$W3C::Grammar::PresenterException::REVISION = '$Id: Presenter.pm,v 1.39 2007-12-21 09:35:46 eric Exp $ ';
+
+package W3C::Grammar::Presenter;
+use CGI qw/:standard/;
+sub new {
+    my ($proto, $yackerRevision, $legalFileName) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = {Buffer => '', Warnings => '', 
+		YackerRevision => $yackerRevision, 
+		LegalFileName => $legalFileName};
+    bless ($self, $class);
+    return $self;
+}
+
+# Utility functions used by subclasses
+
+sub print {
+    my ($self, @printables) = @_;
+    $self->{Buffer} .= join('', @printables);
+}
+
+sub flush {$_[0]->{Buffer}}
+
+sub error {
+    my ($error) = @_;
+    print "Error: $error\n";
+    exit (1);
+}
+
+package W3C::Grammar::TextPresenter;
+@W3C::Grammar::TextPresenter::ISA = qw(W3C::Grammar::Presenter);
+use POSIX qw(ceil);
+use CGI qw/:standard/;
+use W3C::Util::Exception;
+
+package W3C::Grammar::XHTMLPresenter;
+@W3C::Grammar::XHTMLPresenter::ISA = qw(W3C::Grammar::Presenter);
+use POSIX qw(ceil);
+use utf8;
+use CGI qw/:standard/;
+use W3C::Util::Exception;
+
+sub ErrorHeader {
+    my ($self, $code, $text, $ct) = @_;
+    my $status = "$code $text";
+    $self->print("Status: $status\nContent-Type: $ct\n\n");
+}
+
+sub xmlEncode {
+    my ($d, $a) = @_;
+    $a =~ s/\&/\&amp;/g;
+    $a =~ s/\"/\&quot;/g;
+    $a =~ s/\</\&lt;/g;
+    $a =~ s/\>/\&gt;/g;
+    return $a;
+}
+
+sub getContentType {'text/html'}
+
+sub printDocumentHeader {
+    my ($self, $title, ) = @_;
+    $self->ErrorHeader(200, 'OK', 'text/html; charset=utf-8');
+    $self->print("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
+    \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
+<html xmlns=\"http://www.w3.org/1999/xhtml\">
+  <head>
+    <meta name=\"generator\" content=\"$0\" />
+    <title>$title</title>
+    <link rel=\"stylesheet\" href=\"http://www.w3.org/StyleSheets/base.css\" type=\"text/css\" />
+    <style type=\"text/css\">
+       h1 { text-align:center;}
+       .result { background: #bfb; color: #black; border: 1px solid black; }
+       p.result { font-family: monospace; font-size: 88%; }
+       .error { color: red }
+       .trace { margin: 40px; font-size: 88%; background: #eee; border: 1px solid black; }
+
+.grammar { text-align: left ; vertical-align: top ; 
+           font-family: monospace ; font-size:10pt ;}
+.token { color: #3f3f5f; font-size: 88%; /* text-transform: uppercase; */ }
+.production { font-family: monospace; font-style: italic; }
+.term { color: #3f3f5f; font-size: 88%;  }
+a.grammarRef:link { text-decoration: none; }
+a.grammarRef:visited { text-decoration: none; }
+a.grammarRef:hover { text-decoration: none; }
+a.grammarRef:active { text-decoration: none; }
+.comment { color: red; }
+
+    </style>
+    <meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
+  </head>
+  <body>
+    <div class=\"navbar\">
+      <a href=\"http://www.w3.org/\"><img src=\"http://www.w3.org/Icons/WWW/w3c_home\"alt=\"W3C\" style=\"border:none; \" /></a> | 
+      <a href=\"http://www.w3.org/1999/02/26-modules/User/Yacker\">learn about yacker</a>
+    </div>
+    <h1>$title</h1>\n$self->{Warnings}");
+}
+
+sub printDocumentFooter {
+    my ($self) = @_;
+    $self->print("    <hr />
+    <address><a href=\"http://www.w3.org/People/Eric/\">Eric Prud'hommeaux</a>
+      <tt><a href=\"mailto:eric+yacker\@w3.org\">&lt;eric+yacker\@w3.org&gt;</a></tt><br />
+$self->{YackerRevision}<br />
+$REVISION</address>
+    <p>
+      <a href=\"http://validator.w3.org/check?uri=referer\"><img
+          src=\"http://www.w3.org/Icons/valid-xhtml10\"
+          alt=\"Valid XHTML 1.0!\" height=\"31\" width=\"88\" /></a>
+    </p>
+  </body>
+</html>
+");
+}
+
+# ==================== dynamic HTML documents ====================
+sub promptCreateGrammar {
+    my ($self, $handler, $nextAction, $langs, $defaultName, $defaultReplace, $defaultLang, $defaultBNF) = @_;
+    $self->printDocumentHeader('yacker: Create a grammar');
+
+    my $checkedStr = $defaultReplace ? ' checked="checked"' : '';
+    $defaultBNF = $self->xmlEncode($defaultBNF);
+    my $langOpts = '';
+    foreach my $lang (@$langs) {
+	my ($value, $text) = @$lang;
+	my $selected = $value eq $defaultLang ? ' selected="selected"' : '';
+	$langOpts .= "            <option value=\"$value\"$selected>$text</option>\n";
+    }
+    $self->print("
+    <p>Input a grammar to test:</p>
+    <form id=\"grammar\" name=\"grammar\" action=\"\" method=\"post\">
+      <ol>
+        <li>Grammar name: <input name=\"name\" type=\"text\" value=\"$defaultName\"/> Overwrite existing grammar: <input type=\"checkbox\" name=\"replace\" value=\"1\"$checkedStr/> (Please be polite about changing grammars.) </li>
+        <li>Grammar BNF: <textarea name=\"bnf\" rows=\"13\" cols=\"100\">$defaultBNF</textarea> <input type=\"button\" value=\"clear BNF\" onclick=\"document.grammar.bnf.value=''\" /></li>
+        <li>generate grammar in <select name=\"lang\">
+            $langOpts</select>.</li>
+        <li>generate <select name=\"generate\"><option value=\"descriptive\">descriptive</option><option value=\"short\">terse</option></select> names.</li>
+        <li><input type=\"submit\" name=\"action\" value=\"$nextAction\" /></li>
+      </ol>
+    </form>
+    <p>or <a href=\"?action=list+grammars\">list existing parsers</a>.</p>
+");
+    $self->printDocumentFooter();
+}
+
+sub listGrammars {
+    my ($self, $uploads) = @_;
+    my $errors;
+    my $ls = $self->directoryListing('yacker', "$uploads", 'perl');
+
+    $self->printDocumentHeader("yacker grammars");
+    $self->print("
+    <p>$ls</p>\n");
+    $self->printDocumentFooter();
+}
+
+sub _markupFlavorBuffer { # static
+    my ($flavorBuffer) = @_;
+    my $markup = '';
+    my $errors = 0;
+    foreach my $entry ($flavorBuffer->contents()) {
+	my $classStr;
+	my $data = $entry->getData();
+	if (length($data) > 0) {
+	    my $flavor = $entry->getFlavor();
+	    if ($flavor eq 'stdout') {
+		$classStr = '';
+	    } elsif ($flavor eq 'stderr') {
+		$classStr = 'error';
+		$errors++;
+	    } else {
+		$classStr = 'unknown';
+	    }
+	    my $text = &xmlEncode(undef, $data);
+	    $markup .= "<span class=\"$classStr\">$text</span>";
+	}
+    }
+    return ($markup, $errors);
+}
+
+sub creationResults {
+    my ($self, $handler, $new, $uploads, $name, $lang, $results, $pResultsStr, $html) = @_;
+    my $actionStr = $new ? 'creat' : 'updat';
+    my $errors;
+    ($$pResultsStr, $errors) = &_markupFlavorBuffer($results);
+    my $ls = $self->directoryListing('yacker', "$uploads/$name", $lang);
+
+    $self->printDocumentHeader($errors ? "yacker: error ${actionStr}ing $name" : "yacker: ${actionStr}ed $name");
+    $self->print("
+    <p>${actionStr}ed <a href=\"yacker/$uploads/$name/bnf?markup=html\">$name</a>. See $ls</p>
+    <p>Compilation Results:</p>
+    <pre class=\"result\">$$pResultsStr</pre>\n");
+    $self->print("<p><a href=\"yacker/$uploads/$name?lang=$lang\">Try out this parser.</a></p>\n");
+    $self->print("<p><a href=\"yacker?name=$name&amp;replace=1&amp;lang=$lang\">Edit this grammar.</a></p>\n");
+    $self->print($html);
+    $self->printDocumentFooter();
+}
+
+sub promptValidateText {
+    my ($self, $handler, $actions, $generate, $uploads, $name, $lang, $text, $results, $error, $traceHtml, $html, $resultsMarkup, $seed, $limit, $asciiWeight) = @_;
+    $self->printDocumentHeader($results || $error ? "yacker: $name validation results" : "yacker: $name validator");
+
+    my $checkedStr = $html ? ' checked="checked"' : '';
+    my $grammarHiddenField = $html ? 
+      "<input name=\"markup\" type=\"hidden\" value=\"html\" />\n" : 
+	"";
+    my $grammarExpandLinkExcerpt = $html ? 
+      "&amp;markup=html" : 
+	"";
+    my $changeGrammarExpandLinkExcerpt = $html ? 
+      "" : 
+	"&amp;markup=html";
+    my $changeGrammarExpandLinkText = $html ? 
+      "Hide grammar." : 
+	"Show grammar.";
+    my $ls = $self->directoryListing('../../yacker', "$uploads/$name", $lang);
+    my $t2 = $text;
+    &utf8::encode($t2);
+    $text = $self->xmlEncode($t2);
+    if ($results) {
+	&utf8::encode($results);
+	$results = "    <p>Validation results:</p>\n<blockquote><pre class=\"result\">".$self->xmlEncode($results)."</pre></blockquote>\n";
+    }
+    if ($error) {
+	# already XML-encoded
+	$t2 = $error;
+	&utf8::encode($t2);
+	$error = $self->xmlEncode($t2);
+	$error = "    <p>Validation errors:</p>\n<pre class=\"results error\">".$error."</pre>\n";
+    }
+    if ($traceHtml) {
+	$traceHtml = "    <p>Trace:</p>\n<dl class=\"results trace\">".$traceHtml."</dl>\n";
+
+    }
+    my $actionsStr = join(' ', map {"<input type=\"submit\" name=\"action\" value=\"$_\" />"} @$actions);
+    $self->print("
+    <p>Validating against the <a href=\"$name/bnf?markup=html\">$name</a> grammar. See</p>
+$ls
+    $error$results$traceHtml<p>Input some text to test:</p>
+    <form id=\"language\" name=\"language\" action=\"\" method=\"get\">
+      <p>$grammarHiddenField<input name=\"lang\" type=\"hidden\" value=\"$lang\" /></p>
+      <ol>
+        <li><textarea name=\"text\" rows=\"13\" cols=\"100\">$text</textarea> <input type=\"button\" value=\"clear text\" onclick=\"document.language.text.value=''\" /></li>
+        <li>$actionsStr</li>
+      </ol>
+    </form>\n");
+    $self->print("<pre class=\"result\">$resultsMarkup</pre>\n");
+    $self->print("    <p><a href=\"../../yacker?name=$name&amp;replace=1&amp;lang=$lang\">Edit this grammar.</a></p>\n");
+    $self->print("    <!-- <a href=\"$name?lang=$lang${grammarExpandLinkExcerpt}&amp;action=$generate&amp;seed=0&amp;limit=50\">Generate Text.</a> or -->
+    <form id=\"genText\" action=\"\" method=\"get\">
+      <p><input type=\"submit\" name=\"action\" value=\"generate text\" />
+      with seed <input name=\"seed\" type=\"text\" size=\"3\" value=\"$seed\"/>.
+      with limit <input name=\"limit\" type=\"text\" size=\"3\" value=\"$limit\"/>.
+      and ascii weight <input name=\"asciiWeight\" type=\"text\" size=\"3\" value=\"$asciiWeight\"/> (0-100).
+      <input name=\"lang\" type=\"hidden\" value=\"$lang\" />
+    </p></form>\n");
+    $self->print("    <p><a href=\"$name?lang=$lang$changeGrammarExpandLinkExcerpt\">$changeGrammarExpandLinkText</a></p>\n$html");
+    $self->printDocumentFooter();
+}
+
+sub renderMarkup {
+    my ($self, $name, $lang, $markup, $markedup) = @_;
+    $self->printDocumentHeader("$name as $markup");
+    $self->print($markedup);
+    $self->print("<p><a href=\"../$name?lang=$lang\">Try out this parser.</a></p>\n");
+    $self->print("<p><a href=\"../../../yacker?name=$name&amp;replace=1&amp;lang=$lang\">Edit this grammar.</a></p>\n");
+    $self->printDocumentFooter();
+}
+
+# ==================== support functions ====================
+
+sub directoryListing {
+    my ($self, $base, $dir, $lang) = @_;
+    if (!opendir(DIR, $dir)) {
+	#$self->ErrorHeader(404, "File not found", 'text/plain');
+	$self->print("unable to open directory \"$dir\"\n");
+	print $self->flush();
+	exit (1);
+    }
+    my @ret;
+    foreach my $file (sort readdir(DIR)) {
+	if ($file =~ m/^$self->{LegalFileName}$/) {
+	    push (@ret, $file);
+	}
+    }
+    return "    <ul>\n".join('', map {"      <li><a href=\"$base/$dir/$_?lang=$lang\">$_</a></li>\n"} @ret)."    </ul>\n";
+}
+
+sub showFile {
+    my ($self, $fileName) = @_;
+    if (open(H, $fileName)) {
+	local $/ = undef;
+	$self->ErrorHeader(200, "OK", 'text/plain');
+	$self->print(<H>);
+	close(H);
+    } else {
+	$self->ErrorHeader(404, "File not found", 'text/plain');
+	print "unable to open file \"$fileName\"\n";
+	exit (1);
+    }
+}
+
+sub print_Exception {
+    my ($self, $exception) = @_;
+    my $m = $self->xmlEncode($exception->getMessage);
+    $self->print("<p><strong>$m</strong></p>\n");
+}
+
+sub warning {
+    my ($self, $message) = @_;
+    # $message = $self->xmlEncode($message);
+    $self->{Warnings} .= "<div class=\"warning\"><strong>Warning</strong>: $message</div>\n";
+}
+
+sub error {
+    my ($self, $error) = @_;
+    print $self->ErrorHeader(501, 'Vague Unpleasentness', 'text/html');
+    print "<html><head><title>Error</title></head><body>\n";
+    print "<h1>Error</h1>\n<pre>$error</pre>\n";
+    print "</body></html>\n";
+    exit (1);
+}
+
+1;
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/SymbolParser.yp	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,450 @@
+# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
+# (c) Copyright Francois Desarmenien 1998-2001, all rights reserved.
+# (see COPYRIGHT in Parse::Yapp.pm pod section for use and distribution rights)
+
+%{
+    #BEGIN {unshift@INC,('../..');}
+    use W3C::Util::YappDriver;
+    @ISA= qw (W3C::Util::YappDriver);
+
+    use W3C::Util::Exception;
+    use W3C::Grammar::YaccCompileTree qw($PassedTokensName);
+
+sub note {}
+%}
+
+%{
+# START TokenBlock
+my $IT__O = "_O";
+my $IT__S = "_S";
+my $IT__Star = "_Star";
+my $IT__Plus = "_Plus";
+my $IT__Opt = "_Opt";
+my $IT__Q = "_Q";
+my $IT__E = "_E";
+my $IT__L = "_L";
+my $IT__R = "_R";
+my $T_Name = "(?:(?:(?:[0-9A-Za-z])|(?:__)))+";
+my $PASSED_TOKENS = "eat me";
+my $Tokens = [[0, qr/$PASSED_TOKENS/, undef],
+              [0, qr/$IT__O/i, 'IT__O'],
+              [0, qr/$IT__S/i, 'IT__S'],
+              [0, qr/$IT__Star/i, 'IT__Star'],
+              [0, qr/$IT__Plus/i, 'IT__Plus'],
+              [0, qr/$IT__Opt/i, 'IT__Opt'],
+              [0, qr/$IT__Q/i, 'IT__Q'],
+              [0, qr/$IT__E/i, 'IT__E'],
+              [0, qr/$IT__L/i, 'IT__L'],
+              [0, qr/$IT__R/i, 'IT__R'],
+              [0, qr/$T_Name/, 'T_Name']];
+# END TokenBlock
+%}
+%%
+
+Disjunction:
+    Sequence _Q_L_Q_O_E_S_QSequence_E_R_EStar	
+{
+    my ($self, $Sequence, $_Q_L_Q_O_E_S_QSequence_E_R_EStar) = @_;
+    print TRACE "  Disjunction:\n      Sequence _Q_L_Q_O_E_S_QSequence_E_R_EStar\n";
+    &note("$Sequence $_Q_L_Q_O_E_S_QSequence_E_R_EStar");
+    return $_Q_L_Q_O_E_S_QSequence_E_R_EStar ? 
+	W3C::Grammar::YaccCompileTree::Disjunction::addRightBranch($Sequence, $_Q_L_Q_O_E_S_QSequence_E_R_EStar, $self) : 
+	$Sequence;
+};
+
+_L_Q_O_E_S_QSequence_E_R:
+    IT__O Sequence	
+{
+    my ($self, $_O, $Sequence) = @_;
+    print TRACE "  _L_Q_O_E_S_QSequence_E_R:\n      _O Sequence\n";
+    &note("$_O $Sequence");
+    return $Sequence;
+};
+
+_Q_L_Q_O_E_S_QSequence_E_R_EStar:
+    
+{
+    my ($self, ) = @_;
+    print TRACE "  _Q_L_Q_O_E_S_QSequence_E_R_EStar:\n      \n";
+    &note("");
+    return undef;
+}
+    | _Q_L_Q_O_E_S_QSequence_E_R_EStar _L_Q_O_E_S_QSequence_E_R	
+{
+    my ($self, $_Q_L_Q_O_E_S_QSequence_E_R_EStar, $_L_Q_O_E_S_QSequence_E_R) = @_;
+    print TRACE "  _Q_L_Q_O_E_S_QSequence_E_R_EStar:\n      _Q_L_Q_O_E_S_QSequence_E_R_EStar _L_Q_O_E_S_QSequence_E_R\n";
+    &note("$_Q_L_Q_O_E_S_QSequence_E_R_EStar $_L_Q_O_E_S_QSequence_E_R");
+    return $_Q_L_Q_O_E_S_QSequence_E_R_EStar ? 
+	new W3C::Grammar::YaccCompileTree::Sequence($_Q_L_Q_O_E_S_QSequence_E_R_EStar, $_L_Q_O_E_S_QSequence_E_R, $self) :
+	$_L_Q_O_E_S_QSequence_E_R;
+};
+
+Sequence:
+    modifiedelt _Q_L_Q_S_E_S_Qmodifiedelt_E_R_EStar	
+{
+    my ($self, $modifiedelt, $_Q_L_Q_S_E_S_Qmodifiedelt_E_R_EStar) = @_;
+    print TRACE "  Sequence:\n      modifiedelt _Q_L_Q_S_E_S_Qmodifiedelt_E_R_EStar\n";
+    &note("$modifiedelt $_Q_L_Q_S_E_S_Qmodifiedelt_E_R_EStar");
+    return $_Q_L_Q_S_E_S_Qmodifiedelt_E_R_EStar ? 
+	new W3C::Grammar::YaccCompileTree::Sequence($modifiedelt, $_Q_L_Q_S_E_S_Qmodifiedelt_E_R_EStar, $self) :
+	$modifiedelt;
+};
+
+_L_Q_S_E_S_Qmodifiedelt_E_R:
+    IT__S modifiedelt	
+{
+    my ($self, $_S, $modifiedelt) = @_;
+    print TRACE "  _L_Q_S_E_S_Qmodifiedelt_E_R:\n      _S modifiedelt\n";
+    &note("$_S $modifiedelt");
+    return $modifiedelt;
+};
+
+_Q_L_Q_S_E_S_Qmodifiedelt_E_R_EStar:
+    
+{
+    my ($self, ) = @_;
+    print TRACE "  _Q_L_Q_S_E_S_Qmodifiedelt_E_R_EStar:\n      \n";
+    &note("");
+    return undef;
+}
+    | _Q_L_Q_S_E_S_Qmodifiedelt_E_R_EStar _L_Q_S_E_S_Qmodifiedelt_E_R	
+{
+    my ($self, $_Q_L_Q_S_E_S_Qmodifiedelt_E_R_EStar, $_L_Q_S_E_S_Qmodifiedelt_E_R) = @_;
+    print TRACE "  _Q_L_Q_S_E_S_Qmodifiedelt_E_R_EStar:\n      _Q_L_Q_S_E_S_Qmodifiedelt_E_R_EStar _L_Q_S_E_S_Qmodifiedelt_E_R\n";
+    &note("$_Q_L_Q_S_E_S_Qmodifiedelt_E_R_EStar $_L_Q_S_E_S_Qmodifiedelt_E_R");
+    return $_Q_L_Q_S_E_S_Qmodifiedelt_E_R_EStar ? 
+	new W3C::Grammar::YaccCompileTree::Sequence($_Q_L_Q_S_E_S_Qmodifiedelt_E_R_EStar, $_L_Q_S_E_S_Qmodifiedelt_E_R, $self) :
+	$_L_Q_S_E_S_Qmodifiedelt_E_R;
+};
+
+modifiedelt:
+    modifiableelt	
+{
+    my ($self, $modifiableelt) = @_;
+    print TRACE "  modifiedelt:\n      modifiableelt\n";
+    &note("$modifiableelt");
+    return $modifiableelt;
+}
+    | modifiableelt IT__Star	
+{
+    my ($self, $modifiableelt, $_Star) = @_;
+    print TRACE "  modifiedelt:\n      modifiableelt _Star\n";
+    &note("$modifiableelt $_Star");
+    return new W3C::Grammar::YaccCompileTree::Star($modifiableelt, $_Star, $self);
+}
+    | modifiableelt IT__Plus	
+{
+    my ($self, $modifiableelt, $_Plus) = @_;
+    print TRACE "  modifiedelt:\n      modifiableelt _Plus\n";
+    &note("$modifiableelt $_Plus");
+    return new W3C::Grammar::YaccCompileTree::Plus($modifiableelt, $_Plus, $self);
+}
+    | modifiableelt IT__Opt	
+{
+    my ($self, $modifiableelt, $_Opt) = @_;
+    print TRACE "  modifiedelt:\n      modifiableelt _Opt\n";
+    &note("$modifiableelt $_Opt");
+    return new W3C::Grammar::YaccCompileTree::Opt($modifiableelt, $_Opt, $self);
+};
+
+modifiableelt:
+    Symb	
+{
+    my ($self, $Symb) = @_;
+    print TRACE "  modifiableelt:\n      Symb\n";
+    &note("$Symb");
+    return $Symb;
+}
+    | Group	
+{
+    my ($self, $Group) = @_;
+    print TRACE "  modifiableelt:\n      Group\n";
+    &note("$Group");
+    return new W3C::Grammar::YaccCompileTree::Group('(', $Group, $self)
+};
+
+Symb:
+    IT__Q T_Name IT__E	
+{
+    my ($self, $_Q, $T_Name, $_E) = @_;
+    print TRACE "  Symb:\n      _Q T_Name _E\n";
+    &note("$_Q $T_Name $_E");
+    return new W3C::Grammar::YaccCompileTree::Symb(
+	   new W3C::Grammar::YaccCompileTree::LLITERAL($T_Name, 0, $self), $self);
+};
+
+Group:
+    IT__L Disjunction IT__R	
+{
+    my ($self, $_L, $Disjunction, $_R) = @_;
+    print TRACE "  Group:\n      _L Disjunction _R\n";
+    &note("$_L $Disjunction $_R");
+    return $Disjunction;
+};
+%%
+
+my $LanguageName = 'SymbolParser';
+# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
+# START LexerBlock
+#
+# YappTemplate: used by yacker to create yapp input files.
+#
+# Use: yacker -l perl -s -n <name> <name>.txt
+#
+# to generate a yapp input module called Sparql.yp.
+
+#line 12 "YappTemplate"
+
+# $Id: SymbolParser.yp,v 1.1 2006-06-15 23:45:05 eric Exp $
+
+sub _Error {
+    my ($self) = @_;
+        exists $self->YYData->{ERRMSG}
+    and do {
+        print $self->YYData->{ERRMSG};
+        delete $self->YYData->{ERRMSG};
+        return;
+    };
+    my $pos = pos $self->YYData->{INPUT};
+    my $lastPos = $self->YYData->{my_LASTPOS};
+    my $excerpt = substr($self->YYData->{INPUT}, $lastPos, $pos - $lastPos);
+    my $expect = @{$self->{STACK}} ? join (' | ', sort {(!(lc $a cmp lc $b)) ? $b cmp $a : lc $a cmp lc $b} map {&_terminalString($_)} $self->YYExpect()) : 'INVALID INITIALIZER';
+    if (ref $expect) {
+	# Flag unexpected (by the author at this point) refs with '?ref'.
+	if (ref $expect eq 'HASH') {
+	    if (exists $expect->{NEXT}) {
+		$expect = $ {$expect->{NEXT}};
+	    } else {
+		$expect = "?ref {%$expect}";
+	    }
+	} elsif (ref $expect eq 'ARRAY') {
+	    $expect = "?ref [@$expect]";
+	} elsif (ref $expect eq 'SCALAR') {
+	    $expect = "?ref $$expect";
+	} elsif (ref $expect eq 'GLOB') {
+	    $expect = "?ref \**$expect";
+	} else {
+	    $expect = "?ref ??? $expect";
+	}
+    }
+    my $token = &_terminalString($self->YYData->{my_LASTTOKEN});
+    my $value = $self->YYData->{my_LASTVALUE};
+    die "expected \"$expect\", got ($token, $value) from \"$excerpt\" at offset $lastPos.\n";
+}
+
+sub _terminalString { # static
+    my ($token) = @_;
+    if ($token =~ m{^I_T_(.+)$}) {
+	$token = "'$1'";
+    } elsif ($token =~ m{^T_(.+)$}) {
+	if (my $base = $ARGV[0]) {
+	    $token = "&lt;<a href=\"${base}$token\">$1</a>&gt;";
+	} else {
+	    $token = "<$1>";
+	}
+    }
+    return $token;
+}
+
+my $AtStart;
+
+sub _Lexer {
+    my($self)=shift;
+
+    my ($token, $value) = ('', undef);
+
+  top:
+    if (defined $self->YYData->{INPUT} && 
+	pos $self->YYData->{INPUT} < length ($self->YYData->{INPUT})) {
+	# still some chars left.
+    } else {
+	return ('', undef);
+    }
+
+    $self->YYData->{my_LASTPOS} = pos $self->YYData->{INPUT};
+    my $startPos = pos $self->YYData->{INPUT};
+    my ($mText, $mLen, $mI, $mLookAhead) = ('', 0, undef, undef);
+    for (my $i = 0; $i < @$Tokens; $i++) {
+	my $rule = $Tokens->[$i];
+	my ($start, $regexp, $action) = @$rule;
+	if ($start && !$AtStart) {
+	    next;
+	}
+	eval {
+	    if ($self->YYData->{INPUT} =~ m/\G($regexp)/gc) {
+		my $lookAhead = length $2;
+		my $len = (pos $self->YYData->{INPUT}) - $startPos + $lookAhead;
+		if ($len > $mLen) {
+		    $mText = substr($self->YYData->{INPUT}, $startPos, $len - $lookAhead);
+		    $mLen = $len;
+		    $mI = $i;
+		    $mLookAhead = $lookAhead
+		}
+		pos $self->YYData->{INPUT} = $startPos;
+	    }
+	}; if ($@) {
+	    die "error processing $action: $@";
+	}
+    }
+    if ($mLen) {
+	my ($start, $regexp, $action) = @{$Tokens->[$mI]};
+	pos $self->YYData->{INPUT} += $mLen - $mLookAhead;
+	$AtStart = $mText =~ m/\z/gc;
+	($token, $value) = ($action, $mText);
+    } else {
+	my $excerpt = substr($self->YYData->{INPUT}, pos $self->YYData->{INPUT}, 40);
+	die "lexer couldn't parse at \"$excerpt\"\n";
+    }
+    if (!defined $token) {
+	# We just parsed whitespace or comment.
+	goto top;
+    }
+#    my $pos = pos $self->YYData->{INPUT};
+#    print "\n$pos,$token,$value\n";
+    $self->YYData->{my_LASTTOKEN} = $token;
+    $self->YYData->{my_LASTVALUE} = $value;
+    &utf8::encode($value);
+    print TRACE "shift ($token, $value)\n";
+    return ($token, $value);
+}
+
+sub parse {
+    my ($self, @args) = @_;
+    $self->YYData->{NEXT} = undef;
+    $self->YYData->{CreateNovelBNodes} = 0;
+    return $self->SUPER::parse(@args);
+}
+
+# Provide (one) chunk of text to parse.
+sub nextChunk {
+    my ($self) = @_;
+    #return shift (@{$self->YYData->{my_CHUNKS}});
+    #return shift (@ARGV);
+    return <STDIN>;
+}
+
+# Handy debugging wrapper for calling semantics actions.
+sub _wrap {
+    my ($self, $obj, $method, @args) = @_;
+    my @ret;
+    eval {
+	@ret = $obj->$method(@args);
+    }; if ($@) {if (my $ex = &catch('W3C::Util::CachedContextException')) {
+	&throw($ex);;
+    } elsif ($ex = &catch('W3C::Util::Exception')) {
+	my $newEx = new 
+	    W3C::Util::CachedContextException(-str => $self->YYData->{INPUT}, 
+					      -pos => $self->YYData->{my_LASTPOS}+1, 
+					      -errorMessage => $ex->toString);
+	$newEx->assumeStackTrace($ex);
+	&throw($newEx);
+    } else {
+	my $newEx = 
+	    new W3C::Util::CachedContextException(-str => $self->YYData->{INPUT}, 
+						  -pos => $self->YYData->{my_LASTPOS}+1, 
+						  -errorMessage => "$obj->$method: $@");
+	&throw($newEx);
+    }}
+    return wantarray ? @ret : $ret[-1];
+}
+
+sub printArgs {
+    my ($self) = @_;
+    return;
+    print ':';
+    foreach my $arg (@_) {
+	print " $arg";
+    }
+    print ' Curtok:',$self->YYCurtok;
+    print ' Curval:',$self->YYCurval;
+    print ' Expect:',$self->YYExpect;
+    print ' Lexer:',$self->YYLexer;
+    print ' Data:',$self->YYData;
+    print "\n";
+}
+
+# Used by -M invocation:
+#   perl -MW3C::Rdf::SparqlParser -e '(new W3C::Rdf::RLSparqlParser())->Run' '...'
+sub main {
+    my ($self) = @_;
+    $self->Run();
+}
+
+
+package W3C::Grammar::SymbolParser;
+@W3C::Grammar::SymbolParser::ISA = qw(W3C::Grammar::_SymbolParser);
+sub new {
+    my ($proto, $brqlString, $algae2, $location, %flags) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new();
+    $self->YYData->{INPUT} = $brqlString;
+    $self->YYData->{LOCATION} = $location;
+ 
+    $self->YYData->{ALGAE2} = $algae2;
+    $self->YYData->{QNAMES} = [];
+    $self->YYData->{FLAGS} = {%flags};
+    return $self;
+}
+
+sub nextChunk {
+    my ($self) = @_;
+    my $ret = $self->YYData->{SYMBOL_STRING};
+    $self->YYData->{SYMBOL_STRING} = undef;
+    return $ret;
+}
+
+# Interactive ReadLine parser -- under development
+
+# perl -MW3C::Rdf::SparqlParser -e '(new W3C::Rdf::RLSparqlParser())->Run' 'asdf'
+# b /usr/share/perl5/Parse/Yapp/Driver.pm:343
+
+##!/usr/bin/perl
+#BEGIN {unshift@INC,('../..');}
+#use W3C::Rdf::SparqlParser;
+#$p = new W3C::Rdf::RLSparqlParser();
+#$p->main;
+
+#./SparqlParser "(ask '(<ab:cd> (?asdf ?s ?o)) assert '(ef:gh (?a ?b ?c)))"
+
+1;
+
+__END__
+
+=head1 NAME
+
+W3C::Rdf::SparqlParser - a Parse::Yapp grammer for the SPARQL language
+
+=head1 SYNOPSIS
+
+  use W3C::Rdf::SparqlParser;
+  my $p = new W3C::Rdf::SparqlParser($brqlString, $query, "query.txt");
+  my $actions = $p->parse($debug);
+  foreach my $action (@$actions) {
+    $action->delayedEvaluate($self->{RESULT_SET});
+  }
+  return $self->getReport();
+
+=head1 DESCRIPTION
+
+The SparqlParser module binds a yapp grammar to semantic actions that build an
+AlgaeCompileTree. In general, client applicatiosn have no direct interaction
+with SparqlParser. Devlopers wishing to extend the SPARQL query language
+  http://www.w3.org/2001/sw/DataAccess/rq23/
+
+will need the perl yapp modules. The Makefile included with the W3C::Rdf CPAN
+module has a target to re-compile the SparqlParser grammar. Invoke this with
+  make SparqlParser.pm
+It is likely that someone extending the SparqlParser grammar will also want to
+extended AlgaeCompileTree.
+
+This module is part of the W3C::Rdf CPAN module.
+
+=head1 AUTHOR
+
+Eric Prud\'hommeaux <eric@w3.org>
+
+=head1 SEE ALSO
+
+W3C::Rdf::AlgaeCompileTree(3) W3C::Rdf::Algae2(3) perl(1).
+
+=cut
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/YaccCompileTree.pm	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,3703 @@
+#!/usr/bin/perl
+#Copyright Keio University, 2005.
+#Written by Eric Prud'hommeaux for the World Wide Web Consortium
+#This file is PUBLIC DOMAIN.
+
+# YaccCompileTree.pm -- Object definitions for populating an yacc parse tree.
+# 
+# $Id: YaccCompileTree.pm,v 1.110 2008-04-21 01:46:22 eric Exp $
+
+# Issues and dreams:
+#   encoding is distinct from escaping is distinct from parser language name:
+#     name   translator	encode	quoter
+#     perl	yapp	-	DQuoteRegexp
+#     c		lex/y	utf-8	LexQuote
+#     n3	llparse	utf-16*	N3Quote
+#     python	???	utf-16*	PyQuote
+#     java	javacc	-	<JavaCCQuoter>
+#     * no encoding necessary if running on the wide version of python
+
+use strict;
+package W3C::Grammar::YaccCompileTree;
+use W3C::Util::Exception;
+require Exporter;
+@W3C::Grammar::YaccCompileTree::ISA = qw(Exporter);
+
+use vars qw(@EXPORT_OK $Symbol2Name $Name2Symbol
+	    $DefaultPrecedence $MAX_PREC $LEFT $RIGHT
+	    $PassedTokensName $BASE_FILE $BASE_HTTP);
+@EXPORT_OK = qw($DefaultPrecedence $MAX_PREC $LEFT $RIGHT $PassedTokensName $Symbol2Name $Name2Symbol);
+
+($LEFT, $RIGHT) = (1, 2);
+$PassedTokensName = 'PASSED_TOKENS';
+my $PassedTokensName = $PassedTokensName;
+
+$MAX_PREC = 9;
+my $MAX_PREC = $MAX_PREC;
+$DefaultPrecedence = {
+    '||' => [9, $LEFT],
+    '^' => [8, $LEFT],
+    '.' => [7, $LEFT],
+    '&&' => [7, $LEFT],
+    '<' => [5, $LEFT],
+    '<=' => [5, $LEFT],
+    '>' => [5, $LEFT],
+    '>=' => [5, $LEFT],
+    '==' => [5, $LEFT],
+    '+' => [3, $RIGHT],
+    '-' => [3, $RIGHT],
+    '*' => [2, $LEFT],
+    '/' => [2, $LEFT],
+    '!' => [1, $RIGHT],
+    NEG => [1, $RIGHT],
+};
+my $DefaultPrecedence = $DefaultPrecedence;
+$Symbol2Name = {'||' => 'OR', 
+	       '&&' => 'AND', 
+	       ' ' => 'SPACECHAR', 
+		"\t" => 'TAB', 
+		"\r" => 'RETURN', 
+		"\n" => 'LINEFEED', 
+	       ',' => 'COMMA', 
+	       ':' => 'COLON', 
+	       ';' => 'SEMI', 
+	       # '=' => 'ASSIGN', 
+	       '=' => 'EQUAL', 
+	       "\\" => 'BACKSLASH', # '==' => 'EQUAL', 
+	       '!=' => 'NEQUAL', 
+	       '=~' => 'MATCH', 
+	       '~~' => 'MATCH2', 
+	       '!~' => 'NMATCH', 
+	       '^^' => 'DTYPE', 
+	       '^' => 'CARROT', 
+	       '+' => 'PLUS', 
+	       '-' => 'MINUS', 
+	       '*' => 'TIMES', 
+	       '/' => 'DIVIDE', 
+	       '%' => 'MODULO', 
+	       '~' => 'KINDA', 
+	       '!' => 'NOT', 
+	       '&' => 'AMP', 
+	       '|' => 'PIPE', 
+	       '@' => 'AT', 
+	       '[' => 'LBRACKET', 
+	       ']' => 'RBRACKET', 
+	       '{' => 'LCURLEY', 
+	       '}' => 'RCURLEY', 
+	       '(' => 'LPAREN', 
+	       ')' => 'RPAREN', 
+	       '<' => 'LT', 
+	       '>' => 'GT', 
+	       '<=' => 'LE', 
+	       '>=' => 'GE', 
+	       '<<' => 'LREIF', 
+	       '>>' => 'RREIF', 
+	       '.' => 'DOT', 
+	       '?' => 'OPT', 
+	       '#' => 'AT', 
+	       '' => 'NUTTIN', 
+	       '$' => 'DOLLAR', 
+	       '\\\\' => 'BACKSLASHS', 
+	       '\\\\p{' => 'PTHINGY', 
+	       '\\\\P{' => 'PTHINGY2', 
+	       '0' => 'DIGIT0', 
+	       '1' => 'DIGIT1', 
+	       '2' => 'DIGIT2', 
+	       '3' => 'DIGIT3', 
+	       '4' => 'DIGIT4', 
+	       '5' => 'DIGIT5', 
+	       '6' => 'DIGIT6', 
+	       '7' => 'DIGIT7', 
+	       '8' => 'DIGIT8', 
+	       '9' => 'DIGIT9', 
+	   };
+$Name2Symbol = {};
+foreach my $key (keys %$Symbol2Name) {
+    $Name2Symbol->{$Symbol2Name->{$key}} = $key;
+}
+
+sub NameMap {
+    my ($str) = @_;
+    my @ret;
+    my $len = length ($str);
+
+    # Traverse string looking for the widest token names.
+    for (my ($l, $w) = (0, $len); $l < $len;) {
+	my $substr = substr ($str, $l, $w);
+	if (defined (my $mapped = &_map($substr))) {
+	    push (@ret, $mapped);
+	    $l += $w;
+	    $w = $len - $l;
+	} else {
+	    if (!--$w) {
+		# &throw(new W3C::Util::Exception(-message => "no map for \"$substr\" in \"$str\""));
+		push(@ret, sprintf("H_%X_", ord($substr)));
+		$l += 1;
+		$w = $len - $l;
+	    }
+	}
+    }
+    return join ('_', @ret);
+}
+sub _map { # static
+    my ($str) = @_;
+    return ($str =~ m/^\w+$/) ? $str : $Symbol2Name->{$str};
+}
+
+sub format {
+    my ($in, $add) = @_;
+    my @lines = split("\n", $in);
+    return join ("\n", $lines[0], map {"$add$_"} @lines[1..@lines-1]);
+}
+sub main::_defaultPrec {
+    my ($ob, %flags) = @_;
+    if (!exists $flags{-parentPrec}) {
+	$flags{-parentPrec} = $MAX_PREC;
+    }
+    if (!exists $flags{-precTable}) {
+	$flags{-precTable} = $DefaultPrecedence;
+	$flags{-parentPrec} = $MAX_PREC+1;
+    }
+    return ($ob, %flags);
+}
+
+# forward declarations
+package W3C::Grammar::YaccCompileTree::Production;
+package W3C::Grammar::YaccCompileTree::RuleOptions;
+package W3C::Grammar::YaccCompileTree::Solution;
+package W3C::Grammar::YaccCompileTree::LiteralSolution;
+package W3C::Grammar::YaccCompileTree::CODE;
+
+# Output language specifiers
+package W3C::Grammar::GenSpec;
+use W3C::Util::Exception;
+sub new {
+    my ($proto, $la, $derivation, $tokens, $name, $expandTerminals) = @_;
+    my $class = ref($proto) || $proto;
+    $name || &throw();
+    my $self = {
+	Derivation => $derivation, 
+	LA => $la, 
+	Tokens => $tokens, 
+	Name => $name, 
+	Filename => '', 
+	HeadCode => [], 
+	TailCode => [], 
+	LexDecls => [], 
+	ProdDecls => [], 
+	Actions => undef, 
+	Productions => undef, 
+	Labels => undef, 
+	UnusedActions => undef, 
+	MissingActions => [], 
+	ExpandTerminals => $expandTerminals};
+    bless ($self, $class);
+    return $self;
+}
+sub LL {
+    my ($self) = @_;
+    return $self->{Derivation} eq 'LL';
+}
+sub LR {
+    my ($self) = @_;
+    return $self->{Derivation} eq 'LR';
+}
+sub getName {
+    my ($self) = @_;
+    return $self->{Name};
+}
+sub getFilename {
+    my ($self) = @_;
+    return $self->{Filename};
+}
+sub getExpandTerminals {
+    my ($self) = @_;
+    return $self->{ExpandTerminals}
+}
+sub toggleExpandTerminals {
+    my ($self) = @_;
+    $self->{ExpandTerminals} ^= 1;
+}
+sub read {
+    my ($self, $code, $filename) = @_;
+    $self->{Filename} = $filename;
+    $self->{Actions} = {};
+    $self->{Productions} = {};
+    $self->{Labels} = [];
+
+	my %flags = (LineNumbers => 0, 
+		     Types => 0, 
+		     OrigCode => 0, 
+		     Comments => 1, 
+		     Yacc => 1, 
+		     GenSpec => $self, 
+		     Stubs => $self, 
+		     Class => $filename);
+
+    $code->toString(%flags, AddActions => 1);
+    $self->{UnusedActions} = {map {$_ => undef} @{$self->{Labels}}};
+    foreach my $headCode (@{$code->getHead()}) {
+	if ($headCode->isa('W3C::Grammar::YaccCompileTree::HEADCODE')) {
+	    my $str = $self->_skipMyStuff('TokenBlock', $headCode->toString());
+	    if ($str !~ m/^\s$/) {
+		push (@{$self->{HeadCode}}, $str);
+	    }
+	}
+    }
+    my $tailCode = $self->_skipMyStuff('LexerBlock', $code->getTail());
+}
+sub _skipMyStuff {
+    my ($self, $target, $str) = @_;
+    while ($str =~ m/\G.*?\n([\# ]*START $target.*?\n)/gcs) {
+	my $start = (pos $str) - length($1);
+	if ($str !~ m/\G.*?\n([\# ]*END $target.*?\n)$/gcs) {
+	    &throw(new W3C::Util::Exception(-message => "end of $target at $start not found"));
+	}
+	my $end = (pos $str) - length($1);
+	my $before = substr($str, 0, $start);
+	my $after = substr($str, pos $str);
+	$str = "$before$after";
+	pos $str = $start;
+    }
+    return $str;
+}
+sub addProduction {
+    my ($self, $label, $seq) = @_;
+    if (my $first = $self->{Productions}{$label}) {
+	my $lineNo = $seq->getLineNo();
+	my $firstLineNo = $first->getLineNo();
+	my $ex = new W3C::Util::Exception(-message => "duplicate declaration of $label at line $lineNo, first at $firstLineNo");
+	warn($ex->getMessage());
+    } else {
+	$self->{Productions}{$label} = $seq;
+    }
+}
+sub addAction {
+    my ($self, $label, $code) = @_;
+    if (my $first = $self->{Actions}{$label}) {
+	my $lineNo = $code->getLineNo();
+	my $firstLineNo = $first->getLineNo();
+	&throw(new W3C::Util::Exception(-message => "duplicate action for $label at line $lineNo, first at $firstLineNo"));
+    }
+    $self->{Actions}{$label} = $code;
+    push (@{$self->{Labels}}, $label);
+}
+sub getAction {
+    my ($self, $name) = @_;
+    return $self->{Actions} ? $self->{Actions}{$name} : undef;
+}
+sub getUnusedActions {
+    my ($self) = @_;
+    return grep {exists $self->{UnusedActions}{$_}} @{$self->{Labels}};
+}
+sub getMissingActions {
+    my ($self) = @_;
+    return @{$self->{MissingActions}};
+}
+sub getActionStr {
+    my ($self, $productionName, $argNames, $particles, $startRule, $addLineDirective, $callConstructor, $ruleNo, $nests, $deleteRuleNo, $isaMultProd, $macros) = @_;
+
+    if (my $actions = $self->{Actions}) {
+	my $name = join(' ', map {"$_"} $productionName, @$particles);
+	if (my $action = $actions->{$name}) {
+	    delete $self->{UnusedActions}{$name};
+	    if (my $str = $action->toString()) {
+		my $lineDirective = $addLineDirective ? 
+		    $self->getLineDirective($action->getFilename(), $action->getLineNo()) : 
+		    '';
+		return "\n{${lineDirective}$str}";
+	    } else {
+		return "\n";
+	    }
+	} elsif (exists $self->{Productions}{$name}) {
+	    # There was a production for it but it had no code.
+	    # We don't warn about this common scenario.
+	} else {
+	    my $ret = $self->getEchoAction($argNames, $startRule, $productionName, $callConstructor);
+	    push (@{$self->{MissingActions}}, $name);
+	    $actions->{$name} = $ret;
+	    return $ret;
+	}
+    } else {
+	my $ruleSuffix = '';
+	my $deleteTail = 0;
+	if (defined $ruleNo) {
+	    $ruleSuffix = "_rule$ruleNo";
+	    $deleteTail = $ruleNo == $deleteRuleNo;
+	}
+	$self->manageParentRules($productionName, $callConstructor, $ruleNo, $nests, $deleteRuleNo, $isaMultProd, $ruleSuffix, $deleteTail, $macros);
+	return $self->getEchoAction($argNames, $startRule, $productionName, $callConstructor, $ruleSuffix, $deleteTail, $isaMultProd, $macros, $nests);
+    }
+}
+sub manageParentRules {}
+sub getLineDirective {
+    my ($self, $file, $lineNo) = @_;
+    return "";
+}
+sub addProductionDecl {
+    my ($self, $prod) = @_;
+    push (@{$self->{ProdDecls}}, $prod);
+}
+sub addLexDecl {
+    my ($self, $name, $fold, $macros) = @_;
+    push (@{$self->{LexDecls}}, [$name, $fold]);
+}
+sub clearLexDecls {
+    my ($self) = @_;
+    $self->{LexDecls} = [];
+}
+sub printCharPLAN {
+    my ($self, $ch) = @_;
+    return $self->{PrintChar}(chr($ch));
+}
+sub printRangePLAN {
+    my ($self, $b, $t) = @_;
+    return $self->{PrintRange}(chr($b), chr($t));
+}
+sub getTarget {
+    my ($self, $name) = @_;
+    return $name;
+}
+sub getCompileUTF8 {
+    return 0;
+}
+sub copyTemplates {
+    my ($self, $templateDir, $uploads, $macros) = @_;
+    opendir(TD, $templateDir) || &throw(new W3C::Util::FileOperationException(-filename => "$templateDir", -operation => 'openDir'));
+    foreach my $source (readdir(TD)) {
+	next if ($source eq '.' || $source eq '..');
+	my $target = ($source =~ m/^Langname_(.+)$/) ? "$macros->{'Langname'}$1" : $source;
+	open(SRC, "$templateDir/$source") || &throw(new W3C::Util::FileOperationException(-filename => "$templateDir/$source", -operation => 'open'));
+	open(TRG, ">$uploads/$target") || &throw(new W3C::Util::FileOperationException(-filename => "$uploads/$target", -operation => 'open for writing'));
+	local $/ = undef;
+	# Sustitute macros like [[some lead ${AMacro} some trail]].
+	my $body = <SRC>;
+	while ($body =~ m/\G(.*?)\$\{([a-zA-Z]+)\}/gcs) {
+	    my ($lead, $macro) = ($1, $2);
+	    my $value = exists $macros->{$macro} ? $macros->{$macro} : "!! no $macro macro found !!";
+	    print TRG $lead, $value;
+	}
+	# Copy remainder of template.
+	if ($body =~ m/\G(.*)\Z/gcs) {
+	    print TRG $1;
+	}
+	close SRC;
+	close TRG;
+    }
+}
+sub _templateStr {
+    my ($self, $templateFile, $substs) = @_;
+    if (!open(TEMPLATE, $templateFile)) {
+	&throw(new W3C::Util::FileOperationException(-filename => $templateFile, -operation => 'open'));
+    }
+    local $/ = undef;
+    my $template = <TEMPLATE>;
+    close(TEMPLATE);
+    foreach my $pair (@$substs) {
+	my ($from, $to) = @$pair;
+	$template =~ s/$from/$to/g;
+    }
+    return $template;
+}
+sub comment {
+    my ($self, $text) = @_;
+    return $self->startComment().$text.$self->endComment();
+}
+
+package W3C::Grammar::GenSpec::Perl;
+@W3C::Grammar::GenSpec::Perl::ISA = 'W3C::Grammar::GenSpec';
+use W3C::Util::Exception;
+sub new {
+    my ($proto) = @_;
+    my $class = ref($proto) || $proto;
+    return $class->SUPER::new('LA', 'LR', 1, 'perl', 0);
+}
+sub getLineDirective {
+    my ($self, $file, $lineNo) = @_;
+    $lineNo+=2;
+    return "\n#line $lineNo \"$file\"";
+}
+sub getEchoAction {
+    my ($self, $argNames, $startRule, $productionName, $callConstructor, $ruleSuffix, $deleteTail, $isaMultProd, $macros, $nests) = @_;
+    my $argsStr = join(', ', map {"\$$_->[1]"} @$argNames);
+    my $printStr = join(', ', map {"\$$_->[1]"} @$argNames);
+    my $lengthsStr = join(', ', map {"scalar \@\$$_->[1]"} @$argNames);
+    my $namesStr = join(' ', map {"$_->[1](%d)"} @$argNames);
+    my $constructor = $callConstructor ? "new $callConstructor($printStr)" : "[$printStr]";
+    my $retStr = $callConstructor ? "\$ret" : "\$ret";
+    my $dumpParmsStr = '';
+    foreach my $argName (@$argNames) {
+	$dumpParmsStr .= "    for(my \$_i = 0; \$_i < \@\$$argName->[1]; \$_i++) {\$self->trace(sprintf(\"    $argName->[1](\$_i): %s\", join(' ', \$${argName}->[\$_i]->toString)));}\n";
+    }
+    my $traceStr = join(', ', "'$productionName'", map {"'$_->[1]', \$$_->[1]"} @$argNames);
+    return "{\n    my (\$self, $argsStr) = \@_;\n    my \$ret = $constructor;\n    \$self->traceProduction($traceStr);\n    return $retStr;\n}";
+}
+sub getHeadCode {
+    my ($self, $productions, $productionList, $terminalPatterns, $startProduction, %flags) = @_;
+    foreach my $rule (@$terminalPatterns) {
+	my ($name, $index, $dependsOn, $str) = @$rule;
+	$flags{Macros}{TerminalTokens} .= $str;
+    }
+
+    my @classDecls;
+    foreach my $prod (@{$self->{ProdDecls}}) {
+	my $name = $prod->getIdent->getToken;
+	my $class = $prod->isa('W3C::Grammar::YaccCompileTree::GenProduction') ? '_GenProduction' : '_Production';
+	push (@classDecls, "\@${name}::ISA = qw($class);");
+	$flags{Macros}{ProductionClasses} .= "\@${name}::ISA = qw($class);\n";
+    }
+
+    foreach my $pair (@{$self->{LexDecls}}) {
+	my ($name, $fold) = @$pair;
+	my $foldStr = $fold ? 'i' : '';
+	$flags{Macros}{TerminalDeclarations} .= "              [0, qr/\$$name/$foldStr, '$name'],\n";
+	my $class = ($name =~ m/^[IG]T_/) ? '_Constant' : '_Terminal'; # @@@ hack -- get from caller
+	push (@classDecls, "\@${name}::ISA = qw($class);");
+	$flags{Macros}{TerminalClasses} .= "\@${name}::ISA = qw($class);\n";
+    }
+    $flags{Macros}{ProductionActions} = $productions;
+    return '';
+}
+sub getTarget {
+    my ($self, $name) = @_;
+    return "${name}.pm";
+}
+sub makeMakefile {
+    my ($self, $MAKE, $templateDir, $name, $g) = @_;
+    print $MAKE "PARSERS = ${name}.pm\n\n";
+    print $MAKE "parsers: \$(PARSERS)\n\n";
+    print $MAKE "\$(PARSERS): %.pm: %.yp
+	yapp -v -s -o \$\@ \$<\n\n";
+}
+sub getExecString {
+    my ($self, $path, $name) = @_;
+    return "perl -I$path -M$name -e test";
+}
+sub getTemplateDir {"templates/PerlYapp";}
+sub createGrammar {
+    my ($self, $g, $genNamesFunc, $uploads, $name, $templateDir, %flags) = @_;
+    $g->yaccify($genNamesFunc, $self);
+
+    my $macros = {};
+    my $ret = $g->toString(%flags, Macros => $macros,
+			   EndProductionString => ';');
+    # print LY $g->toString(%flags, EndProductionString => ';');
+    $macros->{'Langname'} = $name;
+#    $macros->{'TerminalDeclarations'} = join('', map {"              [0, qr/\$$_->[0]/i, '$_->[1]'],\n"} @{$self->{LexDecls}});
+    $self->copyTemplates($self->getTemplateDir(), $uploads, $macros);
+}
+sub startComment {'#'}
+sub endComment {''}
+
+package W3C::Grammar::GenSpec::Python;
+@W3C::Grammar::GenSpec::Python::ISA = 'W3C::Grammar::GenSpec';
+sub new {
+    my ($proto) = @_;
+    my $class = ref($proto) || $proto;
+    return $class->SUPER::new('', 'LL', 1, 'python', 1);
+}
+sub getEchoAction {
+    my ($self, $argNames, $startRule, $productionName, $callConstructor) = @_;
+    my $argsStr = join(', ', map {"\$$_->[1]"} @$argNames);
+    my $printStr = join('+', map {"$_->[1]"} @$argNames);
+#    return @$argNames ? "        {{return $printStr}}" : '';
+    return "        {{return $printStr}}";
+}
+sub getHeadCode {
+    my ($self, $productions, $productionList, $terminalPatterns, $startProduction, %flags) = @_;
+    my $ret;
+    foreach my $headCode (@{$self->{HeadCode}}) {
+	$ret .= "%{$headCode%}\n\n";
+    }
+    foreach my $rule (@$terminalPatterns) {
+	my ($name, $index, $dependsOn, $str) = @$rule;
+	$ret .= $str;
+    }
+    $ret .= "\n\n$productions";
+    return $ret;
+}
+sub makeMakefile {
+    my ($self, $MAKE, $templateDir, $name, $g) = @_;
+    my $startProductionName = $g->getStartProductionName();
+    print $MAKE "PARSERS = $name\n\n";
+    print $MAKE "parsers: \$(PARSERS)\n\n";
+    print $MAKE "\$(PARSERS): %: %.g
+	yapps \$< $name
+	sed \"s/>>sys.stderr, 'Args:  <rule> \\[<filename>\\]'/parse('$startProductionName', stdin.read())/1\"  <\$\@ >\$\@.t
+	mv \$\@.t \$\@\n\n";
+}
+sub getExecString {
+    my ($self, $path, $name) = @_;
+    return "python $path/$name";
+}
+sub createGrammar {
+    my ($self, $g, $genNamesFunc, $uploads, $name, $templateDir, %flags) = @_;
+    # Build the .yp file:
+    if (!open(LY, ">$uploads/$name.g")) {
+	&throw(new W3C::Util::FileOperationException(-filename => "$name.g", -operation => 'open'));
+    }
+    print LY "parser $name:\n";
+
+    # Start with the yacc-ified output.
+    print LY $g->toString(%flags, EndProductionString => '');
+
+    close (LY);
+}
+sub startComment {'#'}
+sub endComment {''}
+
+package W3C::Grammar::GenSpec::N3;
+@W3C::Grammar::GenSpec::N3::ISA = 'W3C::Grammar::GenSpec';
+sub new {
+    my ($proto) = @_;
+    my $class = ref($proto) || $proto;
+    return $class->SUPER::new('', 'LL', 1, 'n3', 1);
+}
+sub getEchoAction {
+    my ($self, $argNames, $startRule, $productionName, $callConstructor) = @_;
+    my $argsStr = join(' ', map {$_->[1]} @$argNames);
+    return " ( $argsStr ) "; # pass $argsStr
+}
+sub getHeadCode {
+    my ($self, $productions, $productionList, $terminalPatterns, $startProduction, %flags) = @_;
+    my $ret = "\n";
+    my $startProductionName = $startProduction->getIdent()->getToken();	    
+    foreach my $rule (@$terminalPatterns) {
+	my ($name, $index, $dependsOn, $str) = @$rule;
+	$ret .= $str;
+    }
+    $ret .= "$startProductionName cfg:tokens ( ".join ("\n              ", map {$_->[0]} @{$self->{LexDecls}})." ) . \n\n";
+    $ret .= "\n$productions%%\n\n";
+    return $ret;
+}
+sub makeMakefile {
+    my ($self, $MAKE, $templateDir, $name, $g) = @_;
+    my $startProductionName = $g->getStartProductionName();
+    print $MAKE "PARSERS = $name\n\n";
+    print $MAKE "parsers: \$(PARSERS)\n\n";
+    print $MAKE "\$(PARSERS): %: %.g
+	cwm blah blah blah \$< $name\n\n";
+}
+sub createGrammar {
+    my ($self, $g, $genNamesFunc, $uploads, $name, $templateDir, %flags) = @_;
+    $g->yaccify($genNamesFunc, $self);
+
+    # Build the .yp file:
+    if (!open(LY, ">$uploads/$name.n3")) {
+	&throw(new W3C::Util::FileOperationException(-filename => "$name.n3", -operation => 'open'));
+    }
+
+    # Start with the yacc-ified output.
+    print LY $g->toString(%flags, EndProductionString => ';');
+
+    # Set the name (for the constructor in the template).
+    print LY "my \$LanguageName = '$name';\n";
+
+    # Append the template
+    my $template = "$templateDir/YappTemplate";
+    if (open(TEMPLATE, $template)) {
+	local $/ = undef;
+	my $text = <TEMPLATE>;
+	if ($flags{SuppressLineDirectives}) {
+	    $text =~ s/^\#line [^\n]+\n//gm;
+	}
+	print LY $text;
+	close(TEMPLATE);
+    } else {
+	&throw(new W3C::Util::FileOperationException(-filename => $template, -operation => 'open'));
+    }
+}
+sub startComment {'"""'}
+sub endComment {'"""'}
+
+package W3C::Grammar::GenSpec::C_;
+@W3C::Grammar::GenSpec::C_::ISA = 'W3C::Grammar::GenSpec';
+use W3C::Util::Exception;
+
+sub new {
+    my ($proto) = @_;
+    my $class = ref($proto) || $proto;
+    return $class->SUPER::new('LA', 'LR', 1, 'c', 0);
+}
+sub _lexAction {
+    my ($self, $name, $terminal) = @_;
+    return "yylval.semval = constructTerminal(e_$terminal, yytext); return $terminal;"; # @@ ${name}_lval
+}
+sub getClassblock() {
+    my ($self) = @_;
+}
+sub getSemval() {
+    my ($self) = @_;
+}
+sub _rValue {
+    my ($self, $argNames) = @_;
+    if (@$argNames == 0) {
+	return 'makeBuf0()';
+    } elsif (@$argNames == 1) {
+	return '$1';
+    } else {
+	my $argIndex = 0;
+	my $argsStr = @$argNames ? 
+	    join(', ', scalar @$argNames, map {'$'.++$argIndex} @$argNames) : 
+	    '';
+	return "makeBuf($argsStr)";
+     }
+}
+sub getLineDirective {
+    my ($self, $file, $lineNo) = @_;
+    $lineNo+=2;
+    return "\n#line $lineNo \"$file\"";
+}
+sub getEchoAction {
+    my ($self, $argNames, $startRule, $productionName, $callConstructor, $ruleSuffix, $deleteTail, $isaMultProd, $macros, $nests) = @_;
+    $callConstructor ||= '_INVISIBLE_';
+    my $argIndex = 0;
+    my $argsStr = join(', ', "e_$callConstructor", scalar @$argNames, map {"\$".++$argIndex} @$argNames);
+    my $assign = $startRule ? $self->_getRootObject() : '$$';
+    return "{\n    $assign = constructProduction($argsStr);\n}\n";
+}
+sub _getRootObject { return 'StupidGlobal' }
+sub getHeadCode {
+    my ($self, $productions, $productionList, $terminalPatterns, $startProduction, %flags) = @_;
+    foreach my $rule (@$terminalPatterns) {
+	my ($name, $index, $dependsOn, $str) = @$rule;
+	my $encoded = $str;
+	$flags{Macros}{TerminalPatterns} .= $encoded;
+    }
+    foreach my $pair (@{$self->{LexDecls}}) {
+	my ($name, $fold) = @$pair;
+	my $match = "{$name}";
+	my $comment = '';
+	if (my $text = $self->{TerminalExpansions}{$name}) {
+	    $match = $text;
+	    $comment = " /* Work-around referenced look-ahead bug in flex++ */";
+	}
+	my $lexAction = $self->_lexAction($flags{Class}, $name);
+	$flags{Macros}{TerminalActions} .= "$match		{$lexAction}$comment\n";
+    }
+
+    $self->generateTokens($flags{Macros}, $flags{Grammar}, $productionList);
+    $flags{Macros}{ProductionActions} = $productions;
+    return '';
+}
+sub generateTokens {
+    my ($self, $macros, $g, $productionList) = @_;
+
+    my @classes;
+    push (@classes, "{\"_INVISIBLE_\", 0, 0}, \n", "{\"_TERMINAL_\", 0, 0}, \n");
+    for (my $i = 0; $i < @{$self->{ProdDecls}}; $i++) {
+	my $prodName = $self->{ProdDecls}[$i]->getIdent->getToken;
+	my $ctype = $self->{ProdDecls}[$i]->isa('W3C::Grammar::YaccCompileTree::GenProduction') ? '_GenProduction' : '_Production';
+	my $assign = $i == 0 ? ' = 2' : '';
+	$macros->{'ProductionClassDecls'} .= "  e_$prodName$assign,  \n";
+	my $size = length($prodName);
+	$macros->{'ProductionClasses'} .= "    {\"$prodName\", $size, $ctype}, \n";
+    }
+    for (my $i = 0; $i < @{$self->{LexDecls}}; $i++) {
+	my ($lexName, $fold) = @{$self->{LexDecls}[$i]};
+	my $comma = $i < @{$self->{LexDecls}}-1 ? ',' : '';
+	$macros->{'TerminalClassDecls'} .= "  e_$lexName$comma \n";
+	my $class = ($lexName =~ m/^[IG]T_/) ? '_Constant' : '_Terminal'; # @@@ hack -- get from caller
+	my $size = length($lexName);
+	$macros->{'TerminalClasses'} .= "    {\"$lexName\", $size, $class}, \n";
+    }
+    $main::cheat = "Class_t Classes[] = {\n    ".join('    ', @classes)."};\n";
+
+    foreach my $pair (@{$self->{LexDecls}}) {
+	my ($lexName, $fold) = @$pair;
+	$macros->{TerminalTokens} .=  "%token <semval> $lexName\n";
+    }
+
+    foreach my $production (@$productionList) {
+	$macros->{ProductionTypes} .= "%type <semval> $production\n";
+    }
+}
+sub makeMakefile { ##
+    my ($self, $MAKE, $templateDir, $name, $g) = @_;
+}
+sub getExecString {
+    my ($self, $path, $name) = @_;
+    return "$path/$name";
+}
+sub getCompileUTF8 {
+    return 1;
+}
+sub getTemplateDir {"templates/CYacc";}
+sub createGrammar {
+    my ($self, $g, $genNamesFunc, $uploads, $name, $templateDir, %flags) = @_;
+    $g->yaccify($genNamesFunc, $self);
+
+    my $macros = {};
+    my $ret = $g->toString(%flags, Macros => $macros,
+			   EndProductionString => ';');
+    $macros->{'Langname'} = $name;
+    $macros->{'Goalname'} = $self->{StartRuleType};
+    $macros->{'Startname'} = $g->getStartProductionName();
+    $macros->{'TerminalDeclarations'} = join('', map {"    $_->[0]* p_$_->[0];\n"} @{$self->{LexDecls}});
+    $macros->{'ProductionDeclarations'} = join('', map {'    '.($self->_getProdDecl($_, $g))} @{$self->{ProdDecls}});
+    $self->copyTemplates($self->getTemplateDir(), $uploads, $macros);
+}
+sub _getProdDecl { # static
+    my ($self, $production, $g) = @_;
+    my $m = $production->getIdent->getTokenName;
+    return "$m* p_$m;\n"					       
+}
+sub startComment {'/*'}
+sub endComment {'*/'}
+
+package W3C::Grammar::GenSpec::CPP;
+@W3C::Grammar::GenSpec::CPP::ISA = 'W3C::Grammar::GenSpec::C_';
+use W3C::Util::Exception;
+sub new {
+    my ($proto) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new();
+    $self->{Name} = 'cpp';
+    return $self;
+}
+sub _rValue {
+    my ($self, $argNames) = @_;
+    if (@$argNames == 0) {
+	return 'new Buf()';
+    } elsif (@$argNames == 1) {
+	return '$1';
+    } else {
+	my $argIndex = 0;
+	my $argsStr = @$argNames ? 
+	    join(', ', scalar @$argNames, map {'$'.++$argIndex} @$argNames) : 
+	    '';
+	return "new Buf($argsStr)";
+     }
+}
+sub _lexAction {
+    my ($self, $name, $lexName) = @_;
+    return "yylval->p_$lexName = new $lexName(yytext); return token::$lexName;";
+}
+sub getClassblock() {
+    my ($self) = @_;
+    return join('', (map {"class $_;\n"} @{$self->{ClassDecls}}), "\n", @{$self->{ClassDefns}});
+}
+sub getSemval() {
+    my ($self) = @_;
+    return 
+      "    /* Terminals */\n".join('', map {"    $_->[0]* p_$_->[0];\n"} @{$self->{LexDecls}}).
+      "    /* Productions */\n".join('', map {"    $_* p_$_;\n"} map {$_->getIdent->getTokenName} @{$self->{ProdDecls}});
+}
+sub makeMakefile { ##
+    my ($self, $MAKE, $templateDir, $name, $g) = @_;
+}
+sub getTemplateDir {"templates/CPPYacc";}
+sub manageParentRules {
+    my ($self, $productionName, $callConstructor, $ruleNo, $nests, $deleteRuleNo, $isaMultProd, $ruleSuffix, $deleteTail, $macros) = @_;
+    if (defined $ruleNo) {
+	my $ruleName = "$callConstructor$ruleSuffix";
+	push (@{$self->{RuleSubClasses}{$callConstructor}}, $ruleName);
+	if ($ruleNo == 0) {
+	    if (!$isaMultProd) {
+		$macros->{ProductionClassDecls} .= "class $callConstructor;\n";
+	    }
+	    my $defn;
+	    if ($isaMultProd) {
+		my $parmDecls = join(', ', map {"$_* p_$_"} ($productionName, $nests));
+		my $parmArgv = join(', ', 2, map {"p_$_"} $productionName, $nests);
+		$defn = '';
+		$macros->{ProductionDestructors} .= '';
+	    } else {
+		$defn = "class $productionName : public yacker::_GroupProduction {
+public:
+    $productionName () : yacker::_GroupProduction (\"$productionName\") {}
+};
+";
+	    }
+	    $macros->{ProductionClasses} .=  "$defn";
+	}
+	# push (@{$self->{ClassDecls}}, $ruleName); # @@@ symmetrical, but not needed
+    } else {
+	$macros->{ProductionClassDecls} .= "class $callConstructor;\n";
+    }
+}
+sub addLexDecl {
+    my ($self, $name, $fold, $macros) = @_;
+    push (@{$self->{LexDecls}}, [$name, $fold]);
+    $macros->{TerminalClassDecls} .= "class $name;\n";
+    my $word = ($name =~ m/^[IG]T_(.*)/) ? $1 : ''; # @@@ hack -- get from caller
+    my $defn = $word ? "class $name : public yacker::_Token {
+public:
+    $name (const char* text) : yacker::_Token(\"$word\", text) { trace(); }
+};
+" : "class $name : public yacker::_Terminal {
+public:
+    $name(const char* p_$name) : yacker::_Terminal(\"$name\", p_$name) { trace(); }
+};
+";
+    $macros->{TerminalClasses} .= $defn;
+}
+sub getEchoAction {
+    my ($self, $argNames, $startRule, $productionName, $callConstructor, $ruleSuffix, $deleteTail, $isaMultProd, $macros, $nests) = @_;
+    my $assign = '$$';
+    my $argIndex = 0;
+    my $argsStr = join(', ', map {"\$".++$argIndex} @$argNames);
+    if ($isaMultProd) {
+	if ($ruleSuffix =~ m/0$/) {
+	    return "{\n    $assign = new yacker::_ProductionVector<$nests*>(\"$productionName\", $argsStr);\n}\n";
+	} else {
+	    return "{\n    \$1->push_back(\$2);\n    $assign = \$1;\n}\n";
+	}
+    }
+    $callConstructor ||= '_INVISIBLE_';
+    if ($startRule) {
+	$assign = 'driver.root';
+	$self->{StartRuleType} = $productionName;
+    }
+    my $parmCount = scalar @$argNames;
+    my $parmDecls = join(', ', map {
+	$_->[2] && $_->[2]->isa('W3C::Grammar::YaccCompileTree::GenProduction_Multi') ? 
+	"yacker::_ProductionVector<$_->[2]{Nests}*>* p_$_->[2]{Nests}s" : 
+	"$_->[0]* p_$_->[1]"
+			 } @$argNames);
+    my $parmArgv = join(', ', map {
+	$_->[2] && $_->[2]->isa('W3C::Grammar::YaccCompileTree::GenProduction_Multi') ? 
+	"&m_$_->[2]{Nests}s" : 
+	"&m_$_->[1]"
+			} @$argNames);
+    my $baseClass = $ruleSuffix ? $callConstructor : 'yacker::_Production';
+    my $destructorDecl = "    ~$productionName$ruleSuffix();\n";
+    my $delMembers = $isaMultProd ? '' : join('', map {
+	$_->[2] && $_->[2]->isa('W3C::Grammar::YaccCompileTree::GenProduction_Multi') ? 
+	"    delete m_$_->[2]{Nests}s;\n" : 
+	"    delete m_$_->[1];\n"
+					      } @$argNames);
+    $macros->{ProductionDestructors} .= "$productionName${ruleSuffix}::~$productionName$ruleSuffix () {\n$delMembers}\n";
+    my $getProdName = $ruleSuffix ? '' : "    virtual const char* getProductionName () { return \"$productionName\"; }\n";
+    my $memberDecls = $isaMultProd ? '' : join('', map {
+	$_->[2] && $_->[2]->isa('W3C::Grammar::YaccCompileTree::GenProduction_Multi') ? 
+	"    yacker::_ProductionVector<$_->[2]{Nests}*>* m_$_->[2]{Nests}s;\n" : 
+	"    $_->[0]* m_$_->[1];\n"
+					       } @$argNames);
+    my $privates = $memberDecls || $getProdName ? "private:\n    _Base** _members[$parmCount];\n$memberDecls$getProdName" : '';
+    my $baseArgs = join(', ', map {"p_$_->[1]"} @$argNames);
+    my $baseConstructor = $isaMultProd ? " : \n    $callConstructor($baseArgs)" : 
+	$startRule ? " : yacker::_Production(\"$productionName\")" : '';
+    my $memberAssigns = $isaMultProd ? '' : join('', map {
+	$_->[2] && $_->[2]->isa('W3C::Grammar::YaccCompileTree::GenProduction_Multi') ? 
+	"	m_$_->[2]{Nests}s = p_$_->[2]{Nests}s;\n" : 
+	"	m_$_->[1] = p_$_->[1];\n"
+						 } @$argNames);
+    my $deletes = $deleteTail ? "	delete p_$productionName;\n" : '';
+    my $memberArgv = join(', ', $parmCount, map {"m_$_->[1]"} @$argNames);
+    my $toXDecls = $isaMultProd ? '' : "    virtual size_t size () { return $parmCount; }
+    virtual _Base* operator [] (size_t i) { return *_members[i]; }
+    virtual _Base* getElement (size_t i) { return *_members[i]; }
+";
+    my $defn = "class $productionName$ruleSuffix : public $baseClass {
+${privates}public:
+    $productionName$ruleSuffix ($parmDecls)$baseConstructor {
+$memberAssigns	makeArray(_members, $parmArgv);
+	trace();
+$deletes    }
+$destructorDecl$toXDecls};
+";
+    $macros->{ProductionClasses} .= $defn;
+    return "{\n    $assign = new $callConstructor$ruleSuffix($argsStr);\n}\n";
+}
+sub _getRootObject { return 'driver.root' }
+sub generateTokens {
+    my ($self, $macros, $g, $productionList) = @_;
+    foreach my $pair (@{$self->{LexDecls}}) {
+	my ($lexName, $fold) = @$pair;
+	$macros->{TerminalTokens} .= "%token <p_$lexName> $lexName\n";
+    }
+
+    foreach my $production (@$productionList) {
+	my $p = $g->getProductionByName($production);
+	my $type = $production;
+	if ($p->isa('W3C::Grammar::YaccCompileTree::GenProduction_Multi')) {
+	    $type = "$p->{Nests}s";
+	}
+	$macros->{ProductionTypes} .= "%type <p_$type> $production\n";
+    }
+}
+sub _getProdDecl {
+    my ($self, $production, $g) = @_;
+    if ($production->isa('W3C::Grammar::YaccCompileTree::GenProduction_Multi')) {
+	return "yacker::_ProductionVector<$production->{Nests}*>* p_$production->{Nests}s;";
+    } else {
+	my $m = $production->getIdent->getTokenName;
+	return "$m* p_$m;\n"					       
+    }
+}
+
+package W3C::Grammar::GenSpec::Java;
+@W3C::Grammar::GenSpec::Java::ISA = 'W3C::Grammar::GenSpec';
+sub new {
+    my ($proto) = @_;
+    my $class = ref($proto) || $proto;
+    return $class->SUPER::new('', 'LL', 1, 'java', 0);
+}
+sub getEchoAction {
+    my ($self, $argNames, $startRule, $productionName, $callConstructor) = @_;
+}
+sub makeMakefile {
+    my ($self, $MAKE, $templateDir, $name, $g) = @_;
+    my $startProductionName = $g->getStartProductionName();
+    print $MAKE "PARSERS = $name\n\n";
+    print $MAKE "parsers: \$(PARSERS)\n\n";
+    print $MAKE "\$(PARSERS): %: %.g
+	java blah blah blah \$< $name\n\n";
+}
+sub startComment {'/*'}
+sub endComment {'*/'}
+
+
+package W3C::Grammar::YaccCompileTree::Particle;
+use W3C::Util::Exception;
+sub new {
+    my ($proto, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    $particleParms[0] || &throw();
+    my $self = {};
+    $self->{Parser} = $particleParms[0];
+    bless ($self, $class);
+    # $self->check();
+    return $self;
+}
+sub toString {
+    &throw(new W3C::Util::MethodNotImplementedException(-object => $_[0], 
+	     -function => 'W3C::Grammar::YaccCompileTree::Particle::toString'));
+}
+sub check {
+    my ($self) = @_;
+    $self->toString();
+}
+sub getFilename {
+    my ($self) = @_;
+    return $self->{Parser}->getFilename();
+}
+
+package W3C::Grammar::YaccCompileTree::Text;
+@W3C::Grammar::YaccCompileTree::Text::ISA = 'W3C::Grammar::YaccCompileTree::Particle';
+use W3C::Util::Exception;
+
+sub new {
+    my ($proto, $text, $lineNo, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@particleParms);
+    $self->{Text} = $text;
+    $self->{LineNo} = $lineNo;
+    $self->check();
+    return $self;
+}
+sub toString {
+    my ($self, %flags) = &main::_defaultPrec(@_);
+    my $ret = $self->{Text};
+    if ($flags{LineNumbers}) {
+	$ret .= " ($self->{LineNo})";
+    }
+    return $ret;
+}
+
+package W3C::Grammar::YaccCompileTree::WHITESPACE;
+@W3C::Grammar::YaccCompileTree::WHITESPACE::ISA = 'W3C::Grammar::YaccCompileTree::Text';
+sub toString {
+    my ($self, %flags) = &main::_defaultPrec(@_);
+    my $ret = '';
+    if ($flags{WhiteSpace}) {
+	$ret .= $self->SUPER::toString(%flags);
+    }
+    return $ret;
+}
+
+package W3C::Grammar::YaccCompileTree::COMMENT;
+@W3C::Grammar::YaccCompileTree::COMMENT::ISA = 'W3C::Grammar::YaccCompileTree::Text';
+sub new {
+    my ($proto, $leadWS, $text, $lineNo, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new($text, $lineNo, @particleParms);
+    $self->{LeadWS} = $leadWS;
+    $self->check();
+    return $self;
+}
+sub resolveIDENTS {
+    my ($self, $grammar) = @_;
+}
+sub toDNF {
+    my ($self, $opts, $productionList, $parserType) = @_;
+    return [];
+}
+sub toString {
+    my ($self, %flags) = &main::_defaultPrec(@_);
+    my $ret = '';
+    if ($flags{Comments}) {
+	$ret = $self->{LeadWS};
+	#$ret .= $self->prefix(%flags);
+	$ret .= $flags{GenSpec}->comment($self->SUPER::toString(%flags));
+	#$ret .= $self->postfix(%flags);
+    }
+    return $ret;
+}
+
+package W3C::Grammar::YaccCompileTree::PerlComment;
+@W3C::Grammar::YaccCompileTree::PerlComment::ISA = 'W3C::Grammar::YaccCompileTree::COMMENT';
+sub prefix {'#'}
+sub postfix {''}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    my $ch = '';
+    my $line = $self->{LineNo};
+    my $ws = $self->{LeadWS};
+    my $parser = $self->{Parser};
+    my $nLit = new W3C::Grammar::YaccCompileTree::LLITERAL("$ws$ch", $line, $parser);
+    return new W3C::Grammar::YaccCompileTree::LiteralSolution($nLit);
+}
+
+package W3C::Grammar::YaccCompileTree::CComment;
+@W3C::Grammar::YaccCompileTree::CComment::ISA = 'W3C::Grammar::YaccCompileTree::COMMENT';
+sub prefix {'/*'}
+sub postfix {'*/'}
+
+package W3C::Grammar::YaccCompileTree::TokenBase;
+@W3C::Grammar::YaccCompileTree::TokenBase::ISA = 'W3C::Grammar::YaccCompileTree::Particle';
+use W3C::Util::Exception;
+
+sub new {
+    my ($proto, $token, $lineNo, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@particleParms);
+    $self->{Token} = $token;
+    $self->{LineNo} = $lineNo;
+    $self->check();
+    return $self;
+}
+sub getToken {
+    my ($self) = @_;
+    return $self->{Token};
+}
+sub getLineNo {
+    my ($self) = @_;
+    return $self->{LineNo};
+}
+sub toString {
+    my ($self, %flags) = &main::_defaultPrec(@_);
+    return $self->{Token};
+}
+sub toString999 {
+    my ($self, %flags) = &main::_defaultPrec(@_);
+    my $ret = $self->prefix();
+    my $str = $self->{Token};
+    if (my $quoter = $flags{Quoter}) {
+	$str = &{$quoter}($str);
+    }
+    $ret .= $flags{Markup} eq 'html' ? "<span class=\"prod\"><a class=\"grammarRef\" href=\"#prod-$flags{LanguageName}$str\">$str</a></span>" : $str;
+    if ($flags{LineNumbers}) {
+	$ret .= " ($self->{LineNo})";
+    }
+    $ret .= $self->postfix();
+    return $ret;
+}
+sub prefix {''}
+sub postfix {''}
+
+@W3C::Grammar::YaccCompileTree::TAILCODE::ISA = 'W3C::Grammar::YaccCompileTree::TokenBase';
+
+package W3C::Grammar::YaccCompileTree::IDENT;
+@W3C::Grammar::YaccCompileTree::IDENT::ISA = 'W3C::Grammar::YaccCompileTree::TokenBase';
+use W3C::Util::Exception;
+sub new {
+    my ($proto, $token, $lineNo, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new($token, $lineNo, @particleParms);
+    $self->{Reference} = undef;
+    $self->check();
+    return $self;
+}
+sub setTerminal {
+    my ($self, $terminalNess) = @_;
+    $self->{Terminalness} = $terminalNess;
+}
+sub resolveIDENTS {
+    my ($self, $grammar) = @_;
+    if (defined $self->{Reference}) {
+	return;
+    }
+    my $name = $self->getToken();
+    my $production = $grammar->getProductionByName($name);
+    if (!$production) {
+	&throw(new W3C::Util::Exception(-message => "found no production called \"$name\" at $self->{LineNo}"));
+    }
+    $self->{Reference} = $production;
+    $self->{Reference}->resolveIDENTS($grammar);
+}
+sub getDistinguishedToken {
+    my ($self) = @_;
+    return $self->SUPER::getToken(); # $self->_distinguish($self->SUPER::getToken());
+}
+sub getTokenName {
+    my ($self) = @_;
+    return $self->getToken();
+}
+sub getToken2 {
+    my ($self) = @_;
+    return &W3C::Grammar::YaccCompileTree::NameMap($self->{Token});
+}
+sub flattenCharacterClass {
+    my ($self, $target) = @_;
+    return $self->{Reference}->flattenCharacterClass($target);
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    my $name = $self->getToken();
+    my $production = $grammar->getProductionByName($name);
+    if (!$production) {
+	&throw(new W3C::Util::Exception(-message => "$self found no production called \"$name\""));
+    }
+    if ($production != $self->{Reference}) {&throw(new W3C::Util::Exception(-message => "$self production confusion: $production != $self->{Reference} for ".$self->toString()));}
+    return $production->solve($policy, $grammar, $explore);
+}
+sub toString {
+    my ($self, %flags) = &main::_defaultPrec(@_);
+    my $ret = $self->prefix();
+
+    my $name = $self->_distinguish($self->{Token}); # @@@ $self->SUPER::toString(%flags));
+    if (my $quoter = $flags{Quoter}) {
+	$name = &{$quoter}($name);
+    }
+
+    if (my $lang = $flags{Stubs}) {
+	if (exists $flags{TerminalDependsOn}) {
+	    $flags{TerminalDependsOn}{$name} = $self;
+	}
+	if ($flags{GenSpec}->getExpandTerminals() && $flags{InTerminal}) { # && $self->{Terminalness}) { #$flags{TerminalRefs}) { #
+	    my $grammar = $flags{Grammar};
+	    my $name2 = $self->getToken();
+	    my $production = $grammar->getProductionByName($name2);
+	    my %newFlags = map {$_ => $flags{$_}} grep {$_ ne 'TerminalPatterns'} keys %flags;
+	    my $expandedSub = $production->toString(%newFlags);
+	    $ret .= "(?:$expandedSub)";
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::Perl')) {
+	    $ret .= $flags{TerminalRefs} ? "(?:\${$name})" : $name;
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::C_')) {
+	    $ret .= $flags{TerminalRefs} ? "({$name})" : $name;
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::N3')) {
+	    $ret .= $flags{TerminalRefs} ? "(?:{$name})" : $name;
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::Python')) {
+	    $ret .= $flags{TerminalRefs} ? "(?:{$name})" : $name;
+	} else {
+	    &throw(new W3C::Util::ProgramFlowException());
+	}
+    } elsif (exists $flags{Markup} && $flags{Markup} eq 'html') {
+	my $name = $self->_distinguish($self->{Token});
+	$ret .= $self->{InTerminal} ? # $self->{Terminalness} ? 
+	    "&lt;<span class=\"term\"><a class=\"grammarRef\" href=\"#term-$flags{LanguageName}$name\">$self->{Token}</a></span>&gt;" : 
+	    "<span class=\"prod\"><a class=\"grammarRef\" href=\"#prod-$flags{LanguageName}$name\">$name</a></span>";
+    } else {
+	$ret .= $name;
+    }
+    $ret .= $self->postfix();
+    return $ret;
+}
+sub _distinguish {
+    my ($self, $str) = @_;
+    return $str; # $self->{Terminalness} ? "T_$str" : $str;
+}
+sub toString999 {
+    my ($self, %flags) = &main::_defaultPrec(@_);
+    my $ret = $self->prefix();
+    my $str = $self->{Token};
+    if (my $quoter = $flags{Quoter}) {
+	$str = &{$quoter}($str);
+    }
+    $ret .= $flags{Markup} eq 'html' ? "<span class=\"prod\"><a class=\"grammarRef\" href=\"#prod-$flags{LanguageName}$str\">$str</a></span>" : $str;
+    if ($flags{LineNumbers}) {
+	$ret .= " ($self->{LineNo})";
+    }
+    $ret .= $self->postfix();
+	if (exists $flags{TerminalDependsOn}) {
+	    $flags{TerminalDependsOn}{$self->{Token}} = $self;
+	}
+    return $ret;
+}
+
+package W3C::Grammar::YaccCompileTree::LITERAL;
+@W3C::Grammar::YaccCompileTree::LITERAL::ISA = 'W3C::Grammar::YaccCompileTree::TokenBase';
+use W3C::Util::Exception;
+sub getToken {
+    my ($self) = @_;
+    return &W3C::Grammar::YaccCompileTree::NameMap($self->{Token});
+}
+sub getText {
+    my ($self) = @_;
+    return $self->{Token};
+}
+sub flattenCharacterClass {
+    my ($self, $target) = @_;
+    my $t = $self->getText();
+    $target->addRange($t, $t);
+    return 1;
+}
+
+package W3C::Grammar::YaccCompileTree::LLITERAL;
+@W3C::Grammar::YaccCompileTree::LLITERAL::ISA = 'W3C::Grammar::YaccCompileTree::LITERAL';
+use W3C::Util::Exception;
+sub getTokenName {
+    my ($self) = @_;
+    my $name = $self->{Token};
+    if ($name =~ m/^[a-zA-Z_][a-zA-Z_0-9]*$/) {
+	# IT_ for internal token, i.e. quoted text
+	return "IT_$name";
+    } else {
+	# IT_ for generated (internal) token, i.e. quoted non-name chars like ";"
+	if (my $mapped = &W3C::Grammar::YaccCompileTree::NameMap($name)) { # make sure every non-char pattern has a string name
+	    return "GT_$mapped";
+	} else {
+	    &throw(new W3C::Util::Exception(-message => "no map for \"$name\""));
+	}
+    }
+}
+sub resolveIDENTS {
+    my ($self, $grammar) = @_;
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    return new W3C::Grammar::YaccCompileTree::LiteralSolution($self);
+}
+sub toString {
+    my ($self, %flags) = &main::_defaultPrec(@_);
+    my $ret = $self->prefix();
+    my $str = $self->{Token};
+    if ($flags{TerminalPatterns}) {
+	my $name = $self->getTokenName();
+	my $pattern = $self->{Token};
+	if (my $quoter = $flags{Quoter}) {
+	    $pattern = &{$quoter}($pattern);
+	}
+	if (!grep {$_->[0] eq $name} @{$flags{TerminalPatterns}}) {
+	    # Create the terminal.
+	    my $assign;
+	    if (my $lang = $flags{Stubs}) {
+		if ($lang->isa('W3C::Grammar::GenSpec::Perl')) {
+		    $assign = "my \$$name = \"$pattern\";\n";
+		} elsif ($lang->isa('W3C::Grammar::GenSpec::C_')) {
+		    $pattern = $pattern =~ m/^[A-Z]+$/ ? join('', map {'['.chr($_).chr($_+32).']'} unpack('c*', $pattern)) : "\"$pattern\"";
+		    $assign = "$name		$pattern\n";
+		} elsif ($lang->isa('W3C::Grammar::GenSpec::N3')) {
+		    $pattern = "\"$pattern\"";
+		    $assign = " $name	cfg:matches	$pattern;\n	a cfg:Token . \n";
+		} elsif ($lang->isa('W3C::Grammar::GenSpec::Python')) {
+		    $pattern = "'$pattern'";
+		    # $assign = "t_$name = u$pattern\n";
+		    $assign = "    token $name: $pattern\n";
+		} else {
+		    &throw(new W3C::Util::ProgramFlowException());
+		}
+	    }
+	    push (@{$flags{TerminalPatterns}}, [$name, scalar @{$flags{TerminalPatterns}}, {}, $assign, 1, 0]);
+	}
+	if (exists $flags{TerminalDependsOn}) {
+	    $flags{TerminalDependsOn}{$name} = $self;
+	}
+	return $name;
+    } elsif ($str =~ m/^\\u([0-9a-fA-F]+)$/) {
+	if (my $lang = $flags{Stubs}) {
+	    if ($lang->isa('W3C::Grammar::GenSpec::Perl')) {
+		$ret .= "\\x{$1}";
+	    } elsif ($lang->isa('W3C::Grammar::GenSpec::C_')) {
+		$ret .= "\\x$1";
+	    } else {
+		&throw(new W3C::Util::ProgramFlowException());
+	    }
+	} else {
+	    $ret .= $str;
+	}
+    } else {
+	if (my $quoter = $flags{Quoter}) {
+	    $str = &{$quoter}($str);
+	}
+	if (my $lang = $flags{Stubs}) {
+	    if ($lang->isa('W3C::Grammar::GenSpec::Perl')) {
+		$ret .= $str;
+	    } elsif ($lang->isa('W3C::Grammar::GenSpec::C_')) {
+		# @@@ Need a flag for encoding
+		if (ord($self->{Token}) > 0x7f) {
+		    $str = $self->{Token};
+		    &utf8::encode($str);
+		    $ret .= $flags{Quoter}($str);
+		    # $str = W3C::Grammar::CharacterRange::compileUTF8range($self->{Token}, $self->{Token}, sub {$flags{Quoter}(chr($_[0]), chr($_[1]))});
+		} else {
+		    $ret .= $flags{CharacterClass} ? $str : "\"$str\"";
+		}
+	    } elsif ($lang->isa('W3C::Grammar::GenSpec::N3')) {
+		$ret .= $str;
+	    } elsif ($lang->isa('W3C::Grammar::GenSpec::Python')) {
+		$ret .= $str;
+	    } else {
+		&throw(new W3C::Util::ProgramFlowException());
+	    }
+	} elsif ($flags{SingleQuote}) {
+	    my $str = $self->{Token};
+	    if ($str =~ m/\'/) {
+		&throw(new W3C::Util::Exception(-message => "deal with single quoted single quote"));
+	    }
+	    $ret .= "\'$str\'";
+	} else {
+	    # quote-escape the string
+	    $str =~ s/\\/\\\\/g;
+	    $str =~ s/\r/\\r/g;
+	    $str =~ s/\n/\\n/g;
+	    $str =~ s/\t/\\t/g;
+	    if ($str =~ s/([^\x20-\x7f])/sprintf("#%04X",ord($1))/eg) {
+		$ret .= $str;
+	    } elsif (exists $flags{CharacterClass} && $flags{CharacterClass} && 
+		     exists $flags{LexFormat} && $flags{LexFormat} eq 'XMLSpec') {
+		$str =~ s/\"/\\\"/g;
+		$ret .= "$str";
+	    } elsif ($str =~ m/\"/ && $str !~ m/\'/) {
+		$ret .= "'$str'";
+	    } else {
+		$str =~ s/\"/\\\"/g;
+		$ret .= "\"$str\"";
+	    }
+	}
+    }
+    if ($flags{LineNumbers}) {
+	$ret .= " ($self->{LineNo})";
+    }
+    $ret .= $self->postfix();
+    return $ret;
+}
+
+@W3C::Grammar::YaccCompileTree::CODE::ISA = 'W3C::Grammar::YaccCompileTree::TokenBase';
+
+package W3C::Grammar::YaccCompileTree::ASSOC;
+@W3C::Grammar::YaccCompileTree::ASSOC::ISA = 'W3C::Grammar::YaccCompileTree::TokenBase';
+sub prefix {'%'}
+
+@W3C::Grammar::YaccCompileTree::START::ISA = 'W3C::Grammar::YaccCompileTree::TokenBase';
+@W3C::Grammar::YaccCompileTree::EXPECT::ISA = 'W3C::Grammar::YaccCompileTree::TokenBase';
+
+package W3C::Grammar::YaccCompileTree::HEADCODE;
+@W3C::Grammar::YaccCompileTree::HEADCODE::ISA = 'W3C::Grammar::YaccCompileTree::TokenBase';
+sub prefix {"%{"}
+sub postfix {"%}\n"}
+
+package W3C::Grammar::YaccCompileTree::TOKEN;
+@W3C::Grammar::YaccCompileTree::TOKEN::ISA = 'W3C::Grammar::YaccCompileTree::TokenBase';
+sub prefix {'%token'}
+
+@W3C::Grammar::YaccCompileTree::TYPE::ISA = 'W3C::Grammar::YaccCompileTree::TokenBase';
+@W3C::Grammar::YaccCompileTree::UNION::ISA = 'W3C::Grammar::YaccCompileTree::TokenBase';
+@W3C::Grammar::YaccCompileTree::NUMBER::ISA = 'W3C::Grammar::YaccCompileTree::TokenBase';
+@W3C::Grammar::YaccCompileTree::PREC::ISA = 'W3C::Grammar::YaccCompileTree::TokenBase';
+
+package W3C::Grammar::YaccCompileTree::Terminal;
+@W3C::Grammar::YaccCompileTree::Terminal::ISA = 'W3C::Grammar::YaccCompileTree::LITERAL';
+use W3C::Util::Exception;
+sub resolveIDENTS {
+    my ($self, $grammar) = @_;
+    if (defined $self->{Reference}) {
+	return;
+    }
+    my $name = $self->getToken();
+    my $production = $grammar->getProductionByName($name);
+    if (!$production) {
+	&throw(new W3C::Util::Exception(-message => "$self found no production called \"$name\""));
+    }
+    $self->{Reference} = $production;
+    $self->{Reference}->resolveIDENTS($grammar);
+}
+sub getToken {
+    my ($self) = @_;
+    return $self->_distinguish($self->SUPER::getToken());
+}
+sub getToken2 {
+    my ($self) = @_;
+    return $self->SUPER::getToken();
+}
+sub getDistinguishedToken {
+    my ($self) = @_;
+    return $self->_distinguish($self->SUPER::getToken());
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    my $name = $self->getToken();
+    my $production = $grammar->getProductionByName($name);
+    if (!$production) {
+	&throw(new W3C::Util::Exception(-message => "$self found no production called \"$name\""));
+    }
+    if ($production != $self->{Reference}) {print new W3C::Util::Exception(-message => "$self production confusion: $production != $self->{Reference} for ".$self->toString())->toString(), "\n";}
+    return $production->solve($policy, $grammar, $explore);
+}
+sub toString {
+    my ($self, %flags) = &main::_defaultPrec(@_);
+    if (my $lang = $flags{Stubs}) {
+	my $name = $self->_distinguish($self->{Token}); # @@@ $self->SUPER::toString(%flags));
+	if (my $quoter = $flags{Quoter}) {
+	    $name = &{$quoter}($name);
+	}
+	if (exists $flags{TerminalDependsOn}) {
+	    $flags{TerminalDependsOn}{$name} = $self;
+	}
+	if ($lang->isa('W3C::Grammar::GenSpec::Perl')) {
+	    return $flags{TerminalRefs} ? "(?:\${$name})" : $name;
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::C_')) {
+	    return $flags{TerminalRefs} ? "({$name})" : $name;
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::N3')) {
+	    return $flags{TerminalRefs} ? "(?:{$name})" : $name;
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::Python')) {
+	    return $flags{TerminalRefs} ? "(?:{$name})" : $name;
+	} else {
+	    &throw(new W3C::Util::ProgramFlowException());
+	}
+    } elsif (exists $flags{Markup} && $flags{Markup} eq 'html') {
+	my $name = $self->_distinguish($self->{Token});
+	return "&lt;<span class=\"term\"><a class=\"grammarRef\" href=\"#term-$flags{LanguageName}$name\">$self->{Token}</a></span>&gt;";
+    } else {
+	return $self->{Token}
+    }
+}
+sub _distinguish {
+    my ($self, $str) = @_;
+    return "T_$str";
+}
+
+package W3C::Grammar::YaccCompileTree::POS;
+@W3C::Grammar::YaccCompileTree::POS::ISA = 'W3C::Grammar::YaccCompileTree::Particle';
+use W3C::Util::Exception;
+sub new {
+    my ($proto, $value, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@particleParms);
+    $self->{Desc} = $self->pos();
+    $self->{Value} = $value;
+    $self->check();
+    if ($value->isa('W3C::Grammar::YaccCompileTree::Symb')) {
+	&throw(new W3C::Util::Exception(-message => $self->toString()));
+    }
+    return $self;
+}
+sub toDNF {
+    my ($self, $opts, $productionList, $parserType) = @_;
+    my $ret = [];
+    foreach my $seq (@$opts) {
+	push (@$ret, [@$seq, $self]);
+    }
+    return $ret;
+}
+
+package W3C::Grammar::YaccCompileTree::Symb;
+@W3C::Grammar::YaccCompileTree::Symb::ISA = 'W3C::Grammar::YaccCompileTree::POS';
+use W3C::Util::Exception;
+sub resolveIDENTS {
+    my ($self, $grammar) = @_;
+    if (defined $self->{Reference}) {
+	return;
+    }
+    my $val = $self->getValue();
+    if (!$val->isa('W3C::Grammar::YaccCompileTree::LLITERAL')) {
+    my $name = $val->getToken();
+    my $production = $grammar->getProductionByName($name);
+    if (!$production) {
+	&throw(new W3C::Util::Exception(-message => "$self found no production called \"$name\""));
+    }
+    $self->{Reference} = $production;
+    $self->{Reference}->resolveIDENTS($grammar);
+    }
+}
+sub getLineNo {
+    my ($self) = @_;
+    return $self->{Value}->getLineNo();
+};
+sub pos {'SYMB'}
+sub getProductionName {
+    my ($self) = @_;
+    my $str = $self->{Value}->getTokenName();
+    return "_Q${str}_E";
+}
+sub getBareProductionName {
+    my ($self) = @_;
+    return $self->{Value}->getTokenName();
+}
+sub getValue {
+    my ($self) = @_;
+    return $self->{Value};
+}
+sub getElts {
+    my ($self) = @_;
+    return $self;
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    my $val = $self->getValue();
+    if ($val->isa('W3C::Grammar::YaccCompileTree::LLITERAL')) {
+	my $ret = new W3C::Grammar::YaccCompileTree::Solution();
+	$ret->concat(new W3C::Grammar::YaccCompileTree::LiteralSolution($val));
+	return $ret;
+    } else {
+	my $name = $val->getToken();
+	my $production = $grammar->getProductionByName($name);
+	if (!$production) {
+	    &throw(new W3C::Util::Exception(-message => "$self found no production called \"$name\""));
+	}
+	if ($production != $self->{Reference}) {&throw(new W3C::Util::Exception(-message => "$self production confusion: $production != $self->{Reference} for ".$self->toString()));}
+	return $production->solve($policy, $grammar, $explore);
+    }
+}
+sub toString {
+    my ($self, %flags) = &main::_defaultPrec(@_);
+    my $ret = '';
+    if ($flags{Types}) {
+	$ret .= "$self->{Desc} ";
+    }
+    $ret .= $self->{Value}->toString(%flags);
+    return $ret;
+}
+
+package W3C::Grammar::YaccCompileTree::GenSymb;
+@W3C::Grammar::YaccCompileTree::GenSymb::ISA = 'W3C::Grammar::YaccCompileTree::Symb';
+use W3C::Util::Exception;
+sub new {
+    my ($proto, $value, $generator, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new($value, @particleParms);
+    $self->{Generator} = $generator;
+    return $self;
+}
+
+package W3C::Grammar::YaccCompileTree::LSymb;
+@W3C::Grammar::YaccCompileTree::LSymb::ISA = 'W3C::Grammar::YaccCompileTree::Symb';
+use W3C::Util::Exception;
+sub resolveIDENTS {
+    my ($self, $grammar) = @_;
+    $self->{Value}->resolveIDENTS($grammar);
+}
+sub flattenCharacterClass {
+    my ($self, $target) = @_;
+    return $self->{Value}->flattenCharacterClass($target);
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    return $self->{Value}->solve($policy, $grammar, $explore);
+}
+sub toString {
+    my ($self, %flags) = &main::_defaultPrec(@_);
+    # We want TerminalPatterns from productions:
+    # Line 	   ::=    	Word* "end"
+    # but not from Terminals:
+    # <WORD> 	   ::=    	[ "a"-"z","A"-"Z" ]+
+    # LSymb is only used in Terminals so hide the TerminalPatterns aggregator.
+    %flags = (%flags, TerminalPatterns => undef);
+    my $ret = '';
+    if (exists $flags{GenSpec} && $flags{GenSpec}->getExpandTerminals()) {
+	my $name = $self->getValue()->getToken();
+	my $production = $flags{Grammar}->getProductionByName($name);
+	if ($production) {
+	    my $expanded = $production->toString(%flags);
+	    $ret .= "(?:$expanded)"; # reached by W3C::Grammar::GenSpec::Python
+	} else {
+#	    &throw(new W3C::Util::Exception(-message => "$self found no production called \"$name\""));
+	    $ret .= $self->{Value}->toString(%flags);
+	}
+    } else {
+	$ret = $self->SUPER::toString(%flags);
+    }
+    return $ret;
+}
+
+package W3C::Grammar::YaccCompileTree::Group;
+@W3C::Grammar::YaccCompileTree::Group::ISA = 'W3C::Grammar::YaccCompileTree::Particle';
+use W3C::Util::Exception;
+sub new {
+    my ($proto, $open, $value, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@particleParms);
+    $self->{Unused0} = undef; # not used
+    $self->{Value} = $value;
+    $self->{Group} = $open;
+    $self->check();
+    return $self;
+}
+sub resolveIDENTS {
+    my ($self, $grammar) = @_;
+    $self->{Value}->resolveIDENTS($grammar);
+}
+sub getLineNo {
+    my ($self) = @_;
+    return $self->{Group}->getLineNo();
+};
+sub pos {'??Group??'}
+sub getProductionName {
+    my ($self) = @_;
+    return $self->{Value}->getProductionName();
+}
+sub getNestedProduction {
+    my ($self) = @_;
+    return $self->{Value}->getBareProductionName();
+}
+sub getNameMod {'_Group'}
+sub getElts {
+    my ($self) = @_;
+    return $self->{Value};
+}
+sub toDNF {
+    my ($self, $opts, $productionList, $parserType) = @_;
+    my $name = '_O'.$self->{Value}->getProductionName().'_C';
+
+    my ($list, @args) = @$productionList;
+    my $ruleOpts = new W3C::Grammar::YaccCompileTree::RuleOptions($self->{Value}->toDNF([[]], $productionList, $parserType), sub {return 0;}, $self->{Parser});
+    my $ref = $list->getNextProductionName($name, $self, @args);
+    $ref = $list->ensureProductionByName($name, $ref, $ruleOpts, $self, @args);
+
+    # Tricky bit: become the identInfo; !!! un-java-able -- will need union
+    my $old = {};
+    foreach my $key (keys %$self) {
+	$old->{$key} = $self->{$key};
+	delete $self->{$key};
+    }
+    bless ($old, ref $self);
+    foreach my $key (keys %$ref) {
+	$self->{$key} = $ref->{$key};
+    }
+    bless ($self, ref $ref);
+    $self->{Old} = $old;
+
+    my $ret = [];
+    foreach my $seq (@$opts) {
+	push (@$ret, [@$seq, $ref]);
+    }
+    # $self->{Value} = 1;
+    return $ret;
+}
+sub flattenCharacterClass {
+    my ($self, $target) = @_;
+    return 0;
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    return $self->{Value}->solve($policy, $grammar, $explore);
+}
+sub toString {
+    my ($self, %flags) = &main::_defaultPrec(@_);
+    if (my $lang = $flags{Stubs}) {
+	if ($lang->isa('W3C::Grammar::GenSpec::Perl')) {
+	    return '('.$self->{Value}->toString(%flags).')';
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::C_')) {
+	    return '('.$self->{Value}->toString(%flags).')';
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::N3')) {
+	    return '('.$self->{Value}->toString(%flags).')';
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::Python')) {
+	    return '('.$self->{Value}->toString(%flags).')'; # MARK1X
+	} else {&throw();}
+    } else {
+	my @ret;
+	if ($flags{Types}) {
+	    push (@ret, $self->{Unused0});
+	}
+	push (@ret, '(');
+	push (@ret, $self->{Value}->toString(%flags));
+	push (@ret, ')');
+	return join (' ', @ret);
+    }
+}
+
+package W3C::Grammar::YaccCompileTree::LGroup;
+@W3C::Grammar::YaccCompileTree::LGroup::ISA = 'W3C::Grammar::YaccCompileTree::Group';
+sub toString {
+    my ($self, %flags) = &main::_defaultPrec(@_);
+    if (my $lang = $flags{Stubs}) {
+	if ($lang->isa('W3C::Grammar::GenSpec::Perl')) {
+	    return '(?:'.$self->{Value}->toString(%flags).')';
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::C_')) {
+	    return '('.$self->{Value}->toString(%flags).')';
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::N3')) {
+	    return '(?:'.$self->{Value}->toString(%flags).')';
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::Python')) {
+	    return '(?:'.$self->{Value}->toString(%flags).')';
+	} else {&throw();}
+    } else {
+	my @ret;
+	if ($flags{Types}) {
+	    push (@ret, $self->{Unused0});
+	}
+	push (@ret, '(');
+	push (@ret, $self->{Value}->toString(%flags));
+	push (@ret, ')');
+	return join (' ', @ret);
+    }
+}
+
+package W3C::Grammar::YaccCompileTree::Code;
+@W3C::Grammar::YaccCompileTree::Code::ISA = 'W3C::Grammar::YaccCompileTree::POS';
+sub pos {'CODE'}
+sub resolveIDENTS {
+    my ($self, $grammar) = @_;
+}
+sub getLineNo999 {
+    my ($self) = @_;
+    return $self->{Value}->getLineNo();
+};
+sub getCode {
+    my ($self) = @_;
+    return $self->{Value};
+}
+sub toString {
+    my ($self, %flags) = &main::_defaultPrec(@_);
+    my $ret = '';
+    if ($flags{Code}) {
+	if ($flags{Types}) {
+	    $ret .= "$self->{Desc} ";
+	}
+	$ret .= $self->{Value}->toString(%flags);
+    }
+    if ($flags{AddActions}) {
+	$flags{Stubs}->addAction($flags{ActionName}, $self->{Value});
+    }
+    return $ret;
+}
+# </POS>
+
+# <Modifier>
+package W3C::Grammar::YaccCompileTree::Modifier;
+@W3C::Grammar::YaccCompileTree::Modifier::ISA = 'W3C::Grammar::YaccCompileTree::Particle';
+use W3C::Util::Exception;
+sub new {
+    my ($proto, $modified, $marker, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@particleParms);
+    $self->{Modified} = $modified;
+    $self->{DNFed} = 0; # new productions must be DNF
+    $self->{Marker} = $marker;
+    $self->check();
+    return $self;
+}
+sub resolveIDENTS {
+    my ($self, $grammar) = @_;
+    $self->{Modified}->resolveIDENTS($grammar);
+}
+sub getLineNo {
+    my ($self) = @_;
+    return $self->{Marker}->getLineNo();
+};
+sub _permute {
+    my ($self, $baseText, $appendText) = @_;
+}
+sub getProductionName {
+    my ($self) = @_;
+    return $self->{Modified}->getProductionName().$self->getNameMod();
+}
+sub getNestedProduction {
+    my ($self) = @_;
+    return $self->{Modified}->getBareProductionName();
+}
+sub getPreferredPolicy {
+    my ($self, $visited) = @_;
+    return $self->preferredVisitations() > $visited->{$self}++ ? 1 : 0;
+}
+sub toDNF {
+    my ($self, $opts, $productionList, $parserType) = @_;
+
+    my $nestedOpts = $self->{Modified}->toDNF([[]], $productionList, $parserType);
+    my ($leadRefs, $ref) = $self->getRhss($productionList, $nestedOpts, $parserType);
+
+    # Tricky bit: become the identInfo; !!! un-java-able -- will need union
+    my $old = {};
+    foreach my $key (keys %$self) {
+	$old->{$key} = $self->{$key};
+	delete $self->{$key};
+    }
+    bless ($old, ref $self);
+    foreach my $key (keys %$ref) {
+	$self->{$key} = $ref->{$key};
+    }
+    bless ($self, ref $ref);
+    $self->{Old} = $old;
+
+    my $ret = [];
+    foreach my $seq (@$opts) {
+	push (@$ret, [@$seq, @$leadRefs, $ref]);
+    }
+    $self->{DNFed} = 1;
+    return $ret;
+}
+sub flattenCharacterClass {
+    my ($self, $target) = @_;
+    return 0;
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    my $ret = new W3C::Grammar::YaccCompileTree::Solution();
+    while ($policy->getRuleNo($self)) {
+	$ret->concat($self->{Modified}->solve($policy, $grammar, $explore));
+    }
+    # @@@ think hard about how we really decide when we've seen enough of a solution
+    $policy->clearVisitations($self);
+    return $ret;
+}
+sub toString {
+    my ($self, %flags) = &main::_defaultPrec(@_);
+    my $str = $self->{Modified}->toString(%flags);
+    my $postfix .= $self->postfix();
+    if (my $lang = $flags{Stubs}) {
+	if ($lang->isa('W3C::Grammar::GenSpec::Perl')) {
+	    return "(?:$str)$postfix";
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::C_')) {
+	    return "($str)$postfix";
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::N3')) {
+	    return "(?:$str)$postfix";
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::Python')) {
+	    return "($str)$postfix";
+	} else {&throw();}
+    } else {
+	return "($str)$postfix";
+    }
+}
+
+package W3C::Grammar::YaccCompileTree::Star;
+@W3C::Grammar::YaccCompileTree::Star::ISA = 'W3C::Grammar::YaccCompileTree::Modifier';
+sub postfix {'*'}
+sub getNameMod {'_Star'}
+sub preferredVisitations {3}
+sub getRhss {
+    my ($self, $productionList, $opts, $parserType) = @_;
+    my ($list, @args) = @$productionList;
+    my $name = $self->getProductionName(); # better name after {Modifed}->toDNF
+    my $identInfo = $list->getNextProductionName($name, $self, @args);
+
+    my $ret = [];
+    foreach my $seq (@$opts) {
+	my $empty = [[]];
+	my $loop_members = $parserType->LL() ? [[@$seq, $identInfo]] : [[$identInfo, @$seq]];
+	push (@$ret, @$empty, @$loop_members);
+    }
+    my $prefVisits = $self->preferredVisitations();
+    my $rhss = new W3C::Grammar::YaccCompileTree::RuleOptions($ret, sub {return $_[0] >= $prefVisits ? 0 : 1;}, $self->{Parser});
+    return ([], $list->ensureProductionByName($name, $identInfo, $rhss, $self, @args));
+}
+
+package W3C::Grammar::YaccCompileTree::Opt;
+@W3C::Grammar::YaccCompileTree::Opt::ISA = 'W3C::Grammar::YaccCompileTree::Modifier';
+sub postfix {'?'}
+sub getNameMod {'_Opt'}
+sub preferredVisitations {1}
+sub getRhss {
+    my ($self, $productionList, $opts, $parserType) = @_;
+    my ($list, @args) = @$productionList;
+    my $name = $self->getProductionName(); # better name after {Modifed}->toDNF
+    my $identInfo = $list->getNextProductionName($name, $self, @args);
+
+    my $ret = [];
+    foreach my $seq (@$opts) {
+	my $empty = [[]];
+	my $members = [$seq];
+	push (@$ret, @$empty, @$members);
+    }
+    my $prefVisits = $self->preferredVisitations();
+    my $rhss = new W3C::Grammar::YaccCompileTree::RuleOptions($ret, sub {return $_[0] >= $prefVisits ? 0 : 1;}, $self->{Parser});
+    return ([], $list->ensureProductionByName($name, $identInfo, $rhss, $self, @args));
+}
+
+package W3C::Grammar::YaccCompileTree::Plus;
+@W3C::Grammar::YaccCompileTree::Plus::ISA = 'W3C::Grammar::YaccCompileTree::Modifier';
+sub postfix {'+'}
+sub getNameMod {'_Plus'}
+sub preferredVisitations {2}
+sub getRhss {
+    my ($self, $productionList, $opts, $parserType) = @_;
+    my ($list, @args) = @$productionList;
+    my $name = $self->getProductionName(); # better name after {Modifed}->toDNF
+    my $identInfo = $list->getNextProductionName($name, $self, @args);
+
+    my $ret = [];
+    my @prefix;
+    foreach my $seq (@$opts) {
+	if ($parserType->LL()) {
+	    my $empty = [[]];
+	    push (@prefix, @$seq); # !!! Only works for single option. !!!
+	    my $loop_members = [[@$seq, $identInfo]];
+	    push (@$ret, @$empty, @$loop_members);
+	} else {
+	    my $one = [$seq];
+	    my $loop_members = [[$identInfo, @$seq]];
+	    push (@$ret, @$one, @$loop_members);
+	}
+    }
+    my $prefVisits = $self->preferredVisitations();
+    my $rhss = new W3C::Grammar::YaccCompileTree::RuleOptions($ret, sub {return $_[0] >= $prefVisits ? 0 : 1;}, $self->{Parser});
+    return ([@prefix], $list->ensureProductionByName($name, $identInfo, $rhss, $self, @args));
+}
+# </Modifier>
+
+package W3C::Grammar::YaccCompileTree::PrecDecl;
+@W3C::Grammar::YaccCompileTree::PrecDecl::ISA = 'W3C::Grammar::YaccCompileTree::Particle';
+sub new {
+    my ($proto, $precInfo, $typedecl, $symlist, $comments, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@particleParms);
+    $self->{PrecInfo} = $precInfo;
+    $self->{TypeDecl} = $typedecl;
+    $self->{SymList} = $symlist;
+    $self->{Comments} = $comments;
+    $self->check();
+    return $self;
+}
+sub getTypedecl {
+    my ($self) = @_;
+    return $self->{PrecInfo};
+}
+sub getSymlist {
+    my ($self) = @_;
+    return $self->{TypeDecl};
+}
+
+sub toString {
+    my ($self, %flags) = @_;
+    my $ret = $self->{PrecInfo}->toString(%flags);
+    if ($self->{TypeDecl}) {
+	$ret .= ' '.$self->{TypeDecl}->toString(%flags);
+    }
+    foreach my $sym (@{$self->{SymList}}) {
+	$ret .= ' '.$sym->toString(%flags);
+    }
+    foreach my $sym (@{$self->{Comments}}) {
+	$ret .= $sym->toString(%flags);
+    }
+    return "$ret\n";
+}
+
+@W3C::Grammar::YaccCompileTree::TokenDecl::ISA = 'W3C::Grammar::YaccCompileTree::PrecDecl';
+@W3C::Grammar::YaccCompileTree::AssocDecl::ISA = 'W3C::Grammar::YaccCompileTree::PrecDecl';
+
+@W3C::Grammar::YaccCompileTree::Set::ISA = 'W3C::Grammar::YaccCompileTree::Particle';
+
+package W3C::Grammar::YaccCompileTree::Rule;
+@W3C::Grammar::YaccCompileTree::Rule::ISA = 'W3C::Grammar::YaccCompileTree::Set';
+sub new {
+    my ($proto, $rhs, $prec, $code, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@particleParms);
+    $self->{RHS} = $rhs;
+    $self->{Prec} = $prec;
+    $self->{Code} = $code; # may be epscode
+    $self->check();
+    return $self;
+}
+sub resolveIDENTS {
+    my ($self, $grammar) = @_;
+    $self->{RHS}->resolveIDENTS($grammar);
+}
+sub getRhs {
+    my ($self) = @_;
+    return $self->{RHS};
+}
+sub getPrec {
+    my ($self) = @_;
+    return $self->{Prec};
+}
+sub getCode {
+    my ($self) = @_;
+    return $self->{Code};
+}
+sub getProductionName {
+    my ($self) = @_;
+    return $self->{RHS}->getProductionName();
+}
+sub getBareProductionName {
+    my ($self) = @_;
+    return $self->getProductionName();
+}
+sub toDNF {
+    my ($self, $opts, $productionList, $parserType) = @_;
+    return $self->{RHS}->toDNF($opts, $productionList, $parserType);
+}
+sub flattenCharacterClass {
+    my ($self, $target) = @_;
+    return $self->{RHS}->flattenCharacterClass($target);
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    return $self->{RHS}->solve($policy, $grammar, $explore);
+}
+sub toString {
+    my ($self, %flags) = @_;
+    my @ret;
+    push (@ret, $self->{RHS} ? $self->{RHS}->toString(%flags) : "    # empty\n");
+    if ($self->{Prec}) {
+	push (@ret, "%prec $self->{Prec}");
+    }
+    my $ret = join(' ', @ret);
+    if ($self->{Code}) {
+	$ret .= "\n{".$self->{Code}->toString(%flags).'}';
+    }    if ($flags{AddActions}) {&throw();}
+    return $ret;
+}
+
+package W3C::Grammar::YaccCompileTree::EmptyRule;
+@W3C::Grammar::YaccCompileTree::EmptyRule::ISA = 'W3C::Grammar::YaccCompileTree::Particle'; # not a Set
+sub new {
+    my ($proto, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@particleParms);
+    $self->check();
+    return $self;
+}
+sub resolveIDENTS {
+    my ($self, $grammar) = @_;
+}
+sub getProductionName {
+    my ($self) = @_;
+    return 'empty';
+}
+sub toDNF {
+    my ($self, $opts, $productionList, $parserType) = @_;
+    return [[]];
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    my $ch = new W3C::Grammar::YaccCompileTree::LLITERAL('', 0, $self->{Parser});
+    return new W3C::Grammar::YaccCompileTree::LiteralSolution($ch);
+}
+sub toString {
+    my ($self, %flags) = @_;
+    return '';
+}
+
+package W3C::Grammar::YaccCompileTree::LRule;
+@W3C::Grammar::YaccCompileTree::LRule::ISA = 'W3C::Grammar::YaccCompileTree::Rule';
+
+sub newNUKE {
+    my ($proto, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@particleParms);
+#    my $flatRangeList = new W3C::Grammar::CharacterRange::FlatRangeList();
+#    $self->{RHS}->flattenCharacterClass($flatRangeList);
+#    $flatRangeList = $flatRangeList->getAscendingRanges();
+
+#    if ($self->{Negated}) {
+#	$self->{FlatRanges} = [[0, 0x10ffff]];
+#	&W3C::Grammar::CharacterRange::FlatRangeList::_substractRange($self->{FlatRanges}, $flatRangeList);
+#    } else {
+#	$self->{FlatRanges} = $flatRangeList;
+#    }
+#    foreach my $exclusion (@{$self->{Excluded}}) {
+#	my $excludeRangeList = new W3C::Grammar::CharacterRange::FlatRangeList();
+#	$exclusion->getLRangeList()->flattenCharacterClass($excludeRangeList);
+#	&W3C::Grammar::CharacterRange::FlatRangeList::_substractRange($self->{FlatRanges}, $excludeRangeList->getAscendingRanges());
+#    }
+    $self->check();
+    return $self;
+}
+sub toString {
+    my ($self, %flags) = @_;
+    my @ret;
+    push (@ret, $self->{RHS} ? $self->{RHS}->toString(%flags, ) : "    # empty\n");
+    my $ret = join(' ', @ret);
+    if ($self->{Code}) {
+	$ret .= "\n{".$self->{Code}->toString(%flags).'}';
+    }
+    return $ret;
+}
+
+package W3C::Grammar::YaccCompileTree::FlatRule;
+@W3C::Grammar::YaccCompileTree::FlatRule::ISA = 'W3C::Grammar::YaccCompileTree::Rule';
+use W3C::Util::Exception;
+sub getParticles {
+    my ($self) = @_;
+    return @{$self->{RHS}};
+}
+sub toString {
+    my ($self, %flags) = @_;
+    my @ret;
+    my @lines;
+    my $lastSeqIsCode = 0;
+    my @particles = $self->getParticles();
+    for (my $i = 0; $i < @particles; $i++) {
+	my $seq = $particles[$i];
+	push (@lines, $seq->toString(%flags, ActionName => join(' ', ($flags{ProductionName} || '<unknown>'), @lines)));
+	$lastSeqIsCode = $seq->isa('W3C::Grammar::YaccCompileTree::Code');
+    }
+    push (@ret, join(' ', @lines));
+    if ($flags{AddActions} && !$lastSeqIsCode) {
+	# Note that the production was declared.
+	$flags{Stubs}->addProduction(join(' ', $flags{ProductionName}, @lines), $self);
+    }
+    if ($self->{Prec}) {
+	push (@ret, $self->{Prec});
+    }
+    my $ret = join(' ', @ret);
+    if (my $lang = $flags{Stubs}) {
+	my $argNames = [];
+	my $argHash = {};
+	foreach my $el ($self->getParticles()) {
+	    if ($el->isa('W3C::Grammar::YaccCompileTree::Code')) {
+	    } else {
+		my $candidate = $el->getValue()->getTokenName();
+		my $type = $candidate;
+		# !!! horrible hack dealing with un-java-able hack below
+		my $generator = $el->isa('W3C::Grammar::YaccCompileTree::GenSymb') ? 
+		    $flags{Grammar}->getProductionByName($el->{Generator}{Old}->getProductionName()) : undef;
+		while ($argHash->{$candidate}) {
+		    $candidate .= '_';
+		}
+		$argHash->{$candidate} = $el;
+		push (@$argNames, [$type, $candidate, $generator]);
+	    }
+	}
+	if ($ret) {
+	    $ret .= '	';
+	}
+	if ($flags{AddActions}) {
+	} else {
+	    $ret .= $lang->getActionStr($flags{ProductionName}, $argNames, \@lines, $flags{IsStartRule} && ${$flags{IsStartRule}}, !$flags{SuppressLineDirectives}, $flags{CallConstructor}, $flags{RuleNo}, $flags{Nests}, $flags{DeleteRuleNo}, $flags{IsaMultProd}, $flags{Macros});
+	}
+    } elsif ($self->{Code}) {
+	$ret .= "\n{".$self->{Code}->toString(%flags).'}';    if ($flags{AddActions}) {&throw();}
+    }
+    return $ret;
+}
+
+
+package W3C::Grammar::YaccCompileTree::RuleOptions;
+@W3C::Grammar::YaccCompileTree::RuleOptions::ISA = 'W3C::Grammar::YaccCompileTree::Particle';
+sub new {
+    my ($proto, $list, $preferredPolicy, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@particleParms);
+    $self->{Rules} = [];
+    $self->{PreferredPolicy} = $preferredPolicy;
+    foreach my $opt (@$list) {
+	push (@{$self->{Rules}}, new W3C::Grammar::YaccCompileTree::FlatRule($opt, undef, undef, @particleParms));
+    }
+    $self->check();
+    return $self;
+}
+sub getRules {
+    my ($self) = @_;
+    return $self->{Rules};
+}
+sub getPreferredPolicy {
+    my ($self, $visited) = @_;
+    return &{$self->{PreferredPolicy}}($visited->{$self}++);
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    my $ruleNo = $policy->getRuleNo($self);
+    $policy->addBranch($ruleNo);
+    my $solutions = {};
+    my $ret = new W3C::Grammar::YaccCompileTree::Solution();
+    foreach my $atom ($self->{Rules}[$ruleNo]->getParticles()) {
+	my $name = $atom->getProductionName();
+	my $soln = $atom->solve($policy, $grammar, $explore);
+	if (my $t = $solutions->{$name}) {push (@$t, $soln);} else {$solutions->{$name} = [$soln];}
+	$ret->concat($soln);
+    }
+    if ($explore) {
+	if ($ruleNo > 0) {
+	    $ret->setPrevOpt($self->_explore($ruleNo - 1, $solutions, $policy->clone(), $grammar));
+	}
+	if ($ruleNo < @{$self->{Rules}}-1) {
+	    $ret->setNextOpt($self->_explore($ruleNo + 1, $solutions, $policy->clone(), $grammar));
+	}
+    }
+    return $ret;
+}
+sub _explore {
+    my ($self, $ruleNo, $solutions, $policy, $grammar) = @_;
+    my $ret = new W3C::Grammar::YaccCompileTree::Solution();
+
+    # Make a copy of the solutions so we can alter them as we calculate.
+    my $copy = {};
+    foreach my $name (keys %$solutions) {
+	$copy->{$name} = [@{$solutions->{$name}}];
+    }
+
+    foreach my $atom ($self->{Rules}[$ruleNo]->getParticles()) {
+	my $name = $atom->getProductionName();
+	my $soln;
+	if (my $t = $copy->{$name}) {
+	    $soln = shift (@$t);
+	    if (!@$t) {
+		delete $copy->{$name};
+	    }
+	} else {
+	    # Any ReferencePolicy should be exhausted by the first pass through the
+	    # rules. getRuleNo calls should be hanled by the fallback policy.
+	    $soln = $atom->solve($policy, $grammar, 0);
+	    $ret->concat($soln);
+	}
+    }
+    return $ret;
+}
+sub toString {
+    my ($self, %flags) = @_;
+    my $ret = '';
+    my $follower = '    ';
+    for (my $ruleNo = 0; $ruleNo < @{$self->{Rules}}; $ruleNo++) {
+	my $rule = $self->{Rules}[$ruleNo];
+	my %ruleNoFlags = ();
+	if (@{$self->{Rules}} > 1) {
+	    $ruleNoFlags{RuleNo} = $ruleNo;
+	}
+	my $ruleStr = $rule->toString(%flags, %ruleNoFlags);
+#	if ($ruleStr eq "") {
+#	    $ruleStr = "empty";
+#        }
+	$ret .= "$follower$ruleStr";
+	if (UNIVERSAL::isa($flags{Stubs}, 'W3C::Grammar::GenSpec::N3')) {
+	    $follower = "\n   ";
+	} else {
+	    $follower = "\n    | ";
+	}
+    }
+    return $ret;
+}
+
+package W3C::Grammar::YaccCompileTree::Sequence;
+@W3C::Grammar::YaccCompileTree::Sequence::ISA = 'W3C::Grammar::YaccCompileTree::Set';
+use W3C::Util::Exception;
+sub new {
+    my ($proto, $l, $r, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@particleParms);
+    $self->{Left} = $l;
+    $self->{Right} = $r;
+    $self->check();
+    return $self;
+}
+sub resolveIDENTS {
+    my ($self, $grammar) = @_;
+    $self->{Left}->resolveIDENTS($grammar);
+    $self->{Right}->resolveIDENTS($grammar);
+}
+sub getL {
+    my ($self) = @_;
+    return $self->{Left};
+}
+sub getR {
+    my ($self) = @_;
+    return $self->{Right};
+}
+sub getProductionName {
+    my ($self) = @_;
+    my @parts;
+    foreach my $elt ($self->{Left}, $self->{Right}) {
+	my $str = $elt->getProductionName();
+	push (@parts, $str);
+    }
+    return join('_S', @parts);
+}
+sub toDNF {
+    my ($self, $opts, $productionList, $parserType) = @_;
+    my $ret = [];
+    foreach my $seq (@$opts) {
+	my $lDNF = $self->{Left}->toDNF([$seq], $productionList, $parserType);
+	foreach my $subseq (@$lDNF) {
+	    my $rDNF = $self->{Right}->toDNF([$subseq], $productionList, $parserType);
+	    push (@$ret, @$rDNF);
+	}
+    }
+    return $ret;
+}
+sub flattenCharacterClass {
+    my ($self, $target) = @_;
+    return 0;
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    my $ret = new W3C::Grammar::YaccCompileTree::Solution();
+    $ret->concat($self->{Left}->solve($policy, $grammar, $explore));
+    $ret->concat($self->{Right}->solve($policy, $grammar, $explore));
+    return $ret;
+}
+sub toString {
+    my ($self, %flags) = @_;
+    my $lStr = $self->getL()->toString(%flags);
+    my $rStr = $self->getR()->toString(%flags);
+    return $flags{TerminalRefs} ? "$lStr$rStr" : "$lStr $rStr";
+}
+
+package W3C::Grammar::YaccCompileTree::LSequence;
+@W3C::Grammar::YaccCompileTree::LSequence::ISA = 'W3C::Grammar::YaccCompileTree::Sequence';
+use W3C::Util::Exception;
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    my $ret = new W3C::Grammar::YaccCompileTree::Solution();
+    $ret->concat($self->getL()->solve($policy, $grammar, $explore));
+    $ret->concat($self->getR()->solve($policy, $grammar, $explore));
+    return $ret;
+}
+sub toString {
+    my ($self, %flags) = @_;
+    my $lStr = $self->getL()->toString(%flags);
+    my $rStr = $self->getR()->toString(%flags);
+    if (my $lang = $flags{Stubs}) {
+	if ($lang->isa('W3C::Grammar::GenSpec::Perl')) {
+	    return "$lStr$rStr";
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::C_')) {
+	    return "$lStr$rStr";
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::N3')) {
+	    return "$lStr$rStr";
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::Python')) {
+	    return "$lStr$rStr";
+	} else {&throw();}
+    } else {
+	return "$lStr $rStr";
+    }
+}
+
+package W3C::Grammar::YaccCompileTree::Disjunction;
+@W3C::Grammar::YaccCompileTree::Disjunction::ISA = 'W3C::Grammar::YaccCompileTree::Set';
+use W3C::Util::Exception;
+sub new {
+    my ($proto, $l, $r, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@particleParms);
+    $self->{DisjLeft} = $l;
+    $self->{DisjRight} = $r;
+    $self->{DisjunctionCache} = undef; # nested disjunctions not yet cached.
+    $self->check();
+    return $self;
+}
+sub resolveIDENTS {
+    my ($self, $grammar) = @_;
+    $self->{DisjLeft}->resolveIDENTS($grammar);
+    $self->{DisjRight}->resolveIDENTS($grammar);
+}
+sub addRightBranch { # static
+    my ($l, $r, @particleParms) = @_;
+    if (UNIVERSAL::isa($l, 'W3C::Grammar::YaccCompileTree::Disjunction')) {
+	$l->{DisjRight} = &addRightBranch($l->{DisjRight}, $r, @particleParms);
+	return $l;
+    } else {
+	$l ||= new W3C::Grammar::YaccCompileTree::EmptyRule(@particleParms);
+	$r ||= new W3C::Grammar::YaccCompileTree::EmptyRule(@particleParms);
+	return new W3C::Grammar::YaccCompileTree::Disjunction($l, $r, @particleParms);
+    }
+}
+sub toDNF {
+    my ($self, $opts, $productionList, $parserType) = @_;
+    my $ret = [];
+    foreach my $seq (@$opts) {
+	my $lDNF = $self->{DisjLeft}->toDNF([$seq], $productionList, $parserType);
+	my $rDNF = $self->{DisjRight}->toDNF([$seq], $productionList, $parserType);
+	push (@$ret, @$lDNF, @$rDNF);
+    }
+    return $ret;
+}
+sub getL {
+    my ($self) = @_;
+    return $self->{DisjLeft};
+}
+sub getR {
+    my ($self) = @_;
+    return $self->{DisjRight};
+}
+sub getProductionName {
+    my ($self) = @_;
+    my @parts;
+    foreach my $elt ($self->{DisjLeft}, $self->{DisjRight}) {
+	my $str = $elt->getProductionName();
+	if ($str =~ m/^\'([^\']*)\'$/) {
+	    $str = $1;
+	    if ($str !~ m/^\w+$/) {
+		if (my $mapped = &W3C::Grammar::YaccCompileTree::NameMap($str)) {
+		    $str = $mapped;
+		} else {
+		    &throw(new W3C::Util::Exception(-message => "no map for \"$str\""));
+		}
+	    }
+	}
+	push (@parts, $str);
+    }
+    return join('_Or', @parts);
+}
+sub getBareProductionName {
+    my ($self) = @_;
+    return '_O'.$self->getProductionName().'_C';
+}
+sub getPreferredPolicy {
+    my ($self, $visited) = @_;
+    return $visited->{$self}++ % @{$self->{DisjunctionCache}};
+}
+sub getNestedDisjunctions {
+    my ($self) = @_;
+    my @ret;
+    foreach my $term ($self->{DisjLeft}, $self->{DisjRight}) {
+	push (@ret, $term->isa('W3C::Grammar::YaccCompileTree::Disjunction') ? 
+	      $term->getNestedDisjunctions() : 
+	      $term);
+    }
+    return @ret;
+}
+sub cacheNestedDisjunctions {
+    my ($self) = @_;
+    if (!$self->{DisjunctionCache}) {
+	$self->{DisjunctionCache} = [$self->getNestedDisjunctions()];
+    }
+    return @{$self->{DisjunctionCache}};
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    my @opts = $self->cacheNestedDisjunctions();
+    my $optNo = $policy->getRuleNo($self);
+    return $opts[$optNo]->solve($policy, $grammar, $explore);
+}
+sub toString {
+    my ($self, %flags) = @_;
+    my $lStr = $self->getL()->toString(%flags);
+    my $rStr = $self->getR()->toString(%flags);
+    if (my $lang = $flags{Stubs}) {
+	if ($lang->isa('W3C::Grammar::GenSpec::Perl')) {
+	    return "(?:$lStr)|(?:$rStr)";
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::C_')) {
+	    return "($lStr)|($rStr)";
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::N3')) {
+	    return "(?:$lStr)|(?:$rStr)";
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::Python')) {
+	    return "($lStr)|($rStr)";
+	} else {&throw();}
+    } else {
+	return "$lStr | $rStr";
+    }
+}
+
+package W3C::Grammar::YaccCompileTree::LDisjunction;
+@W3C::Grammar::YaccCompileTree::LDisjunction::ISA = 'W3C::Grammar::YaccCompileTree::Disjunction';
+use W3C::Util::Exception;
+sub flattenCharacterClass {
+    my ($self, $target) = @_;
+    my $testRangeList = new W3C::Grammar::CharacterRange::FlatRangeList();
+    my @opts = $self->cacheNestedDisjunctions();
+    my $i = 0;
+    foreach my $l ($testRangeList, $target) {		# try with a test range, the use real target
+	for (my $i = 0; $i < @opts; $i++) {		#   for each opt
+	    my $opt = $opts[$i];
+	    if (!$opt->flattenCharacterClass($l)) {	#     if not flatten-able, the whole thing is not flatten-able
+		return 0;
+	    }
+	}
+    }
+    return 1;						# it was flatten-able
+}
+sub getPreferredPolicy {
+    my ($self, $visited) = @_;
+    return $visited->{$self}++ % (exists $self->{FlattenedDisjunctionCache} ? @{$self->{FlattenedDisjunctionCache}} : @{$self->{DisjunctionCache}});
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    my $opts;
+    if (exists $self->{FlattenedDisjunctionCache}) {
+	$opts = $self->{FlattenedDisjunctionCache};
+    } else {
+	$opts = [$self->cacheNestedDisjunctions()];
+	my $flatRangeList = new W3C::Grammar::CharacterRange::FlatRangeList();
+	my $iMergeOpt = -1;
+	for (my $i = 0; $i < @$opts; $i++) {
+	    my $opt = $opts->[$i];
+	    if ($opt->flattenCharacterClass($flatRangeList)) {
+		if ($iMergeOpt > -1) {
+		    splice(@$opts, $i, 1);
+		    $i--;
+		} else {
+		    $iMergeOpt = $i;
+		}
+	    }
+	}
+	if ($iMergeOpt > -1) {
+	    $opts->[$iMergeOpt] = &W3C::Grammar::YaccCompileTree::CharacterClass::subsume($flatRangeList->getAscendingRanges(), $self, $self->{Parser});
+	}
+	$self->{FlattenedDisjunctionCache} = $opts;
+    }
+    my $optNo = $policy->getRuleNo($self);
+    return $opts->[$optNo]->solve($policy, $grammar, $explore);
+}
+sub newNUKE {
+    my ($proto, $l, $r, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new($l, $r, @particleParms);
+    $self->check();
+    return $self;
+}
+sub addRightBranch { # static
+    my ($l, $r, @particleParms) = @_;
+    if (UNIVERSAL::isa($l, 'W3C::Grammar::YaccCompileTree::Disjunction')) {
+	$l->{DisjRight} = &addRightBranch($l->{DisjRight}, $r, @particleParms);
+	return $l;
+    } else {
+	$l ||= new W3C::Grammar::YaccCompileTree::EmptyRule(@particleParms);
+	$r ||= new W3C::Grammar::YaccCompileTree::EmptyRule(@particleParms);
+	return new W3C::Grammar::YaccCompileTree::LDisjunction($l, $r, @particleParms);
+    }
+}
+sub toString {
+    my ($self, %flags) = @_;
+    my $lStr = $self->getL()->toString(%flags);
+    my $rStr = $self->getR()->toString(%flags);
+    if (my $lang = $flags{Stubs}) {
+	if ($lang->isa('W3C::Grammar::GenSpec::Perl')) {
+	    return "(?:$lStr)|(?:$rStr)";
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::C_')) {
+	    return "($lStr)|($rStr)";
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::N3')) {
+	    return "($lStr)|($rStr)";
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::Python')) {
+	    return "(?:$lStr)|(?:$rStr)";
+	} else {&throw();}
+    } else {
+	return "$lStr | $rStr";
+    }
+}
+
+package W3C::Grammar::YaccCompileTree::Production;
+@W3C::Grammar::YaccCompileTree::Production::ISA = 'W3C::Grammar::YaccCompileTree::Particle';
+use W3C::Util::Exception;
+sub new {
+    my ($proto, $ident, $rules, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@particleParms);
+    $self->{Ident} = $ident;
+    $self->{Rulez} = $rules;
+    $self->{DNFedForm} = undef; # DNF'd form
+    $self->{Parser}->_AddRules($self);
+    $self->check();
+    return $self;
+}
+sub getProductionName {
+    my ($self) = @_;
+    return $self->{Rulez}->getProductionName();
+}
+sub resolveIDENTS {
+    my ($self, $grammar) = @_;
+    $self->{Rulez}->resolveIDENTS($grammar);
+}
+sub getIdent {
+    my ($self) = @_;
+    return $self->{Ident};
+}
+sub getRules {
+    my ($self) = @_;
+    if (!$self->{DNFedForm}) { $self->_DNF(); }
+    return $_{Ident}->{Rulez}->getRules();
+}
+sub _DNF {
+    my ($self, $productionList, $parserType) = @_;
+    $self->{Rulez} = new W3C::Grammar::YaccCompileTree::RuleOptions($self->{Rulez}->toDNF([[]], $productionList, $parserType), sub {return 0;}, $self->{Parser});
+    $self->{DNFedForm} = $self->{Rulez};
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    return $self->{Rulez}->solve($policy, $grammar, $explore);
+}
+sub _callConstructor {
+    my ($self) = @_;
+    return $self->getIdent()->getToken();
+}
+sub toString {
+    my ($self, %flags) = @_;
+    my $ret;
+    my $name = $self->getIdent()->getToken();
+    %flags = (%flags, ProductionName => $name); # leave orig unmodified.
+
+    if (exists $flags{Markup} && $flags{Markup} eq 'html') {
+	my $prodNo = ${$flags{ProdNo}}++;
+	$ret .= "<tbody class=\"prod\">
+<tr valign=\"baseline\">
+<td><a id=\"prod-$flags{LanguageName}$name\" name=\"prod-$flags{LanguageName}$name\"></a>[<span class=\"prodNo\">$prodNo</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class=\"production prod\">$name</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class=\"content\">";
+	my $tail = $self->{Rulez};
+	while ($tail->isa('W3C::Grammar::YaccCompileTree::Disjunction')) {
+	    $ret .= $tail->getL()->toString(%flags);
+	    $ret .= "<br/>\n| ";
+	    $tail = $tail->getR();
+	}
+	$ret .= $tail->toString(%flags);
+	$ret .= "</code></td>\n</tr>\n</tbody>\n\n";
+    } else {
+	$ret .= $self->{Ident}->toString(%flags);
+
+	if ($flags{ProductionList}) {
+	    push (@{$flags{ProductionList}}, $ret);
+	}
+	$flags{CallConstructor} = $self->_callConstructor;
+	if (my $lang = $flags{Stubs}) {
+	    if ($lang->isa('W3C::Grammar::GenSpec::Perl')) {
+		$ret .= ":\n";
+		$ret .= $self->{Rulez}->toString(%flags, SingleQuote => 1);
+		$ret .= $flags{EndProductionString};
+	    } elsif ($lang->isa('W3C::Grammar::GenSpec::C_')) {
+		$ret .= ":\n";
+		$ret .= $self->{Rulez}->toString(%flags, Nests => $self->{Nests}, 
+						 DeleteRuleNo => $self->isa('W3C::Grammar::YaccCompileTree::GenProduction_Multi') ? 1 : -1, 
+						 IsaMultProd => $self->isa('W3C::Grammar::YaccCompileTree::GenProduction_Multi') ? 1 : 0);
+		$ret .= $flags{EndProductionString};
+	    } elsif ($lang->isa('W3C::Grammar::GenSpec::N3')) {
+		$ret .= " cfg:mustBeOneSequence (";
+		$ret .= $self->{Rulez}->toString(%flags);
+		$ret .= " ) .\n\n";
+	    } elsif ($lang->isa('W3C::Grammar::GenSpec::Python')) {
+		$ret = "    rule $ret:";
+		$ret .= $self->{Rulez}->toString(%flags);
+		$ret .= $flags{EndProductionString};
+	    } else {&throw();}
+	} else {
+	    $ret .= ":\n";
+	    $ret .= $self->{Rulez}->toString(%flags);
+	    $ret .= $flags{EndProductionString} if ($flags{EndProductionString});
+	}
+    }
+    if ($flags{IsStartRule} && ${$flags{IsStartRule}}) {
+	${$flags{IsStartRule}} = 0;
+	$flags{Grammar}->setStartProduction($self);
+    }
+    return $ret;
+}
+
+
+package W3C::Grammar::YaccCompileTree::GenProduction;
+@W3C::Grammar::YaccCompileTree::GenProduction::ISA = 'W3C::Grammar::YaccCompileTree::Production';
+sub new {
+    my ($proto, $ident, $rules, $nests, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new($ident, $rules, @particleParms);
+    $self->{Nests} = $nests;
+    return $self;
+}
+sub _callConstructor999 {
+    return undef;
+}
+
+@W3C::Grammar::YaccCompileTree::GenProduction_Group::ISA = 'W3C::Grammar::YaccCompileTree::GenProduction';
+@W3C::Grammar::YaccCompileTree::GenProduction_Multi::ISA = 'W3C::Grammar::YaccCompileTree::GenProduction';
+@W3C::Grammar::YaccCompileTree::GenProduction_Star::ISA = 'W3C::Grammar::YaccCompileTree::GenProduction_Multi';
+@W3C::Grammar::YaccCompileTree::GenProduction_Opt::ISA = 'W3C::Grammar::YaccCompileTree::GenProduction';
+@W3C::Grammar::YaccCompileTree::GenProduction_Plus::ISA = 'W3C::Grammar::YaccCompileTree::GenProduction_Multi';
+
+
+package W3C::Grammar::YaccCompileTree::Grammar;
+@W3C::Grammar::YaccCompileTree::Grammar::ISA = 'W3C::Grammar::YaccCompileTree::Particle';
+use W3C::Util::Exception;
+sub new {
+    my ($proto, $head, $body, $tail, $noIntegrityCheck, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@particleParms);
+    $self->{Head} = $head;
+    $self->{Body} = $body;
+    $self->{Tail} = $tail;
+    $self->{ProductionList} = {}; # list of productions
+    $self->{NameFunction} = sub {
+	    my ($grammar, $derivedName) = @_;
+	    return $derivedName;
+	};
+    foreach my $production (@{$self->{Body}}) {
+	if (!UNIVERSAL::isa($production, 'W3C::Grammar::YaccCompileTree::COMMENT')) {
+	    my $token = $production->getIdent()->getToken();
+	    # print "{$self}->{ProductionList}{$token} = [$production, undef]\n";
+	    $self->{ProductionList}{$token} = [$production, undef];
+	}
+    }
+    # If there's no @pass directive...
+    if (!$self->{ProductionList}->{$PassedTokensName}) {
+	# ...assume that we skip leading whitespace.
+# @@@	push (@{$self->{Body}}, new SomeCoolParseTree()); #Well, throw and error for now.
+    }
+    if (!$noIntegrityCheck) {
+	$self->{Body}[0]->resolveIDENTS($self);
+    }
+    $self->check();
+    return $self;
+}
+sub getHead {
+    my ($self) = @_;
+    return $self->{Head};
+}
+sub getBody {
+    my ($self) = @_;
+    return $self->{Body};
+}
+sub getTail {
+    my ($self) = @_;
+    return $self->{Tail};
+}
+sub getNextProductionName {
+    my ($self, $name, $excuse, $pIndex) = @_;
+    my $productionName = &{$self->{NameFunction}}($self, $name);
+    my $ident = new W3C::Grammar::YaccCompileTree::IDENT($productionName, $excuse->getLineNo(), $excuse->{Parser});
+    return new W3C::Grammar::YaccCompileTree::GenSymb($ident, $excuse, $excuse->{Parser});
+}
+sub getProductionByName {
+    my ($self, $name) = @_;
+    # print "getProductionByName($name) => $self->{ProductionList}{$name}[0]\n";
+    return $self->{ProductionList}{$name}[0];
+}
+sub ensureProductionByName {
+    my ($self, $name, $ref, $rhss, $excuse, $pIndex) = @_;
+    if (my $ret = $self->{ProductionList}{$name}) {
+	return $ret->[1];
+    }
+
+    my $class = 'W3C::Grammar::YaccCompileTree::GenProduction'.$excuse->getNameMod();
+    my $production = $class->new($ref->getValue(), $rhss, $excuse->getNestedProduction(), $excuse->{Parser});
+
+    $self->{ProductionList}{$name} = [$production, $ref];
+    splice (@{$self->{Body}}, $$pIndex+1, 0, $production);
+    ++$$pIndex;
+    return $ref;
+}
+sub yaccify {
+    my ($self, $nameFunc, $parserType) = @_;
+    if ($nameFunc) {
+	$self->{NameFunction} = $nameFunc;
+    }
+    my @errors;
+    for (my $i = 0; $i < @{$self->{Body}}; $i++) {
+	my $rule = $self->{Body}[$i];
+	if (!$rule->isa('W3C::Grammar::YaccCompileTree::COMMENT') && 
+	    !$rule->isa('W3C::Grammar::YaccCompileTree::LexGoal')) {
+	    eval {
+		$rule->_DNF([$self, \$i], $parserType);
+	    }; if ($@) {
+		my $errorStr;
+		if (my $ex = &catch('W3C::Util::Exception')) {
+		    $errorStr = $ex->toString()
+		} else {
+		    $errorStr = $@;
+		}
+		my $ruleStr = $rule;
+		eval {$ruleStr = $rule->toString()};
+		push (@errors, "Error in rule $ruleStr:\n$errorStr");
+	    }
+	}
+    }
+    if (@errors) {
+	&throw(new W3C::Util::Exception(-message => join ("\n===============\n", @errors)));
+    }
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    # make pseudo-random selections repeatable
+    srand($policy->getSeed());
+    return $self->{Body}[0]->solve($policy, $grammar, $explore);
+}
+sub addTerminalExpansion {
+    my ($self, $name, $value) = @_;
+    $self->{TerminalExpansions}{$name} = $value;
+}
+sub setStartProduction {
+    my ($self, $production) = @_;
+    $self->{StartProduction} = $production;
+}
+sub getStartProductionName {
+    my ($self) = @_;
+    return $self->{StartProduction}->getIdent()->getToken();
+}
+sub toString {
+    my ($self, %flags) = @_;
+    my $ret = '';
+    if (my $lang = $flags{Stubs}) {
+
+	my $terminalPatterns = [];
+
+	# We have to run the through the productions to collect terminals implied by literals ala
+	#   age: 'age' <NUM>
+	my $productions = '';
+	my $productionList = [];
+	my $dependencyList = {};
+	my $quoter = $lang->isa('W3C::Grammar::GenSpec::Perl') ? \&DQuoteRegexp : 
+	    $lang->isa('W3C::Grammar::GenSpec::Python') ? \&PyQuote : 
+	    $lang->isa('W3C::Grammar::GenSpec::N3') ? \&N3Quote : 
+	    $lang->isa('W3C::Grammar::GenSpec::C_') ? \&LexQuote : 
+	    &throw(new W3C::Util::Exception(-message => "unknown language: \"$lang\""));
+	my $isStartRule = 1;
+	foreach my $production (@{$self->{Body}}) {
+	    $productions .= $production->toString(%flags, 
+						  TerminalPatterns => $terminalPatterns, 
+						  TerminalDependsOn => $dependencyList, 
+						  Quoter => $quoter, 
+						  ProductionList => $productionList, 
+						  IsStartRule => \ $isStartRule,
+						  Grammar => $self);
+	    $productions .= "\n\n";
+	    if ($production->isa('W3C::Grammar::YaccCompileTree::Production')
+		#&& !$production->isa('W3C::Grammar::YaccCompileTree::GenProduction')
+		) {
+		$lang->addProductionDecl($production);
+	    }
+	}
+	my $junk = '';
+
+	# Collect all the terminal patterns in the terminal definitions.
+	foreach my $decl (@{$self->{Head}}) {
+	    # should not get actual rules if $flags{TerminalPatterns} is set.
+	    $junk .= $decl->toString(%flags, 
+				    TerminalPatterns => $terminalPatterns, # build list of terminals.
+				    TerminalRefs => 1 # in the lex rules, make terminals be variables.
+				    );
+	}
+
+	my $namePointers = {};
+	for (my $i = 0; $i < @$terminalPatterns; $i++) {
+	    my ($name, $index, $dependsOn, $str, $fold) = @{$terminalPatterns->[$i]};
+	    $namePointers->{$name} = $terminalPatterns->[$i];
+	    $terminalPatterns->[$i][1] = $i;
+	    if ($dependencyList->{$name}) {
+		$lang->addLexDecl($name, $fold, $flags{Macros});
+	    } # else only used to build other terminals
+	}
+
+	# Dump out the regexps as variables.
+	#   <NUM> ::= ("\\0x" <HEX>) | <DEC>
+	#   <HEX> ::= (["0"-"9","a"-"f","A"-"F"])+
+	#   <DEC> ::= (["0"-"9"])+
+	# becomes
+	#   my $T_HEX = "[0-9a-fA-F]+";
+	#   my $T_DEC = "[0-9]+";
+	#   my $T_NUM = "(?:\\\\0x${T_HEX})|${T_DEC}";
+	# Note ordering and escaping. Ordering happens below. Escaping happens in the atoms.
+
+	# First sort to not have any forward references.
+	for (my $i = 0; $i < @$terminalPatterns; $i++) {
+	    my $termDef = $terminalPatterns->[$i];
+	    my ($name, $index, $dependsOn, $str, $done) = @$termDef;
+	    my $latestDepends = $i;
+	    foreach my $depends (keys %$dependsOn) {
+		if (!$namePointers->{$depends}) {
+		    next; &throw(new W3C::Util::Exception(-message => "who uses \"$depends\"?"));
+		}
+		my ($Dname, $Dindex, $DdependsOn, $Dstr) = @{$namePointers->{$depends}};
+		if ($Dindex > $latestDepends) {
+		    $latestDepends = $Dindex;
+		    if (0 && $done) {
+			&throw(new W3C::Util::Exception(-message => "circular dependency between $name and $depends"));
+		    }
+		}
+	    }
+	    $termDef->[4] = 1; # mark done so we can find circular dependencies.
+	    if ($latestDepends > $i) {
+		# Have to move down past latest dependency.
+		splice (@$terminalPatterns, $i, 1);
+		splice (@$terminalPatterns, $latestDepends, 0, $termDef);
+		# Fix the indexes for the just move and subsequent displaced elements.
+		for (my $j = $i; $j < @$terminalPatterns; $j++) {
+		    $terminalPatterns->[$j][1] = $j;
+		}
+		$i--; # start at the new element at this postion
+	    }
+	}
+
+	$ret .= $lang->getHeadCode($productions, $productionList, $terminalPatterns, $self->{StartProduction}, (%flags, Grammar => $self));
+
+    } else {
+	if (exists $flags{Markup} && $flags{Markup} eq 'html') {
+	    $ret .= "<table border=\"0\">\n<tbody><tr><td colspan=\"4\" class=\"grammarSection\"><h3><a id=\"productions\" name=\"productions\">Productions</a>:</h3></td></tr></tbody>\n\n";
+	    foreach my $production (@{$self->{Body}}) {
+		$ret .= $production->toString(%flags, Quoter => \&W3C::Grammar::YaccCompileTree::Grammar::HtmlQuote);
+	    }
+	    $ret .= "</table>\n";
+	} else {
+	    foreach my $decl (@{$self->{Head}}) {
+		$ret .= $decl->toString(%flags);
+		$ret .= "\n\n";
+	    }
+	    $ret .= "%%\n\n";
+	    foreach my $production (@{$self->{Body}}) {
+		$ret .= $production->toString(%flags);
+		$ret .= "\n\n";
+	    }
+	    $ret .= "%%\n\n";
+	}
+    }
+    return $ret;
+}
+# Encode first as a regexp, then as a ""'d string.
+sub DQuoteRegexp { # static
+    my ($val) = @_;
+
+    # Regexps
+    $val =~ s/\\/\\\\/g;
+    $val =~ s/\//\\\//g;
+    $val =~ s/\"/\\\"/g;
+    $val =~ s/\'/\\\'/g;
+    $val =~ s/\^/\\\^/g;
+    $val =~ s/\$/\\\$/g;
+    $val =~ s/\./\\\./g;
+    $val =~ s/\+/\\\+/g;
+    $val =~ s/\*/\\\*/g;
+    $val =~ s/\|/\\\|/g;
+    $val =~ s/\?/\\\?/g;
+    $val =~ s/\[/\\\[/g;
+    $val =~ s/\]/\\\]/g;
+    $val =~ s/\{/\\\{/g;
+    $val =~ s/\}/\\\}/g;
+    $val =~ s/\(/\\\(/g;
+    $val =~ s/\)/\\\)/g;
+    $val =~ s/\r/\\r/g;
+    $val =~ s/\n/\\n/g;
+    $val =~ s/\t/\\t/g;
+
+    # DQuotes
+    $val =~ s/\\/\\\\/g;
+    $val =~ s/\"/\\\"/g;
+    $val =~ s/\$/\\\$/g;
+    $val =~ s/\@/\\\@/g;
+    $val =~ s/\%/\\\%/g;
+    $val =~ s/\r/\\r/g;
+    $val =~ s/\n/\\n/g;
+    $val =~ s/\t/\\t/g;
+    $val =~ s/([^\x20-\x7f])/sprintf("\\x{%04X}",ord($1))/eg;
+    return $val;
+}
+
+sub LexQuote { # static
+    my ($val) = @_;
+
+    $val =~ s/\\/\\\\/g;
+    $val =~ s/\[/\\\[/g;
+    $val =~ s/\]/\\\]/g;
+    $val =~ s/\"/\\\"/g;
+    $val =~ s/\r/\\r/g;
+    $val =~ s/\n/\\n/g;
+    $val =~ s/\t/\\t/g;
+    $val =~ s/([^\x20-\x7e])/sprintf("\\x%02X",ord($1))/eg;
+    return $val;
+}
+
+sub PyQuote { # static
+    my ($val) = @_;
+    # Regexps
+    $val =~ s/\\/\\\\/g;
+    #$val =~ s/\"/\\\"/g;
+    #$val =~ s/\'/\\\'/g;
+    $val =~ s/\^/\\\^/g;
+    $val =~ s/\$/\\\$/g;
+    $val =~ s/\./\\\./g;
+    $val =~ s/\+/\\\+/g;
+    $val =~ s/\*/\\\*/g;
+    $val =~ s/\|/\\\|/g;
+    $val =~ s/\?/\\\?/g;
+    $val =~ s/\[/\\\[/g;
+    $val =~ s/\]/\\\]/g;
+    $val =~ s/\{/\\\{/g;
+    $val =~ s/\}/\\\}/g;
+    $val =~ s/\(/\\\(/g;
+    $val =~ s/\)/\\\)/g;
+    $val =~ s/\r/\\r/g;
+    $val =~ s/\n/\\n/g;
+    $val =~ s/\t/\\t/g;
+
+    $val =~ s/\\/\\\\/g;
+    $val =~ s/\'/\\\'/g;
+    $val =~ s/\r/\\r/g;
+    $val =~ s/\n/\\n/g;
+    $val =~ s/\t/\\t/g;
+    $val =~ s/([^\x20-\x7f])/sprintf("\\u%04X",ord($1))/eg;
+    return $val;
+    #return "hello "
+}
+
+
+sub N3Quote { # static
+    my ($val) = @_;
+    #if ($val eq 'r') {die "How did I get an r?"; }
+    # Regexps
+    $val =~ s/\\/\\\\/g;
+    #$val =~ s/\"/\\\"/g;
+    #$val =~ s/\'/\\\'/g;
+    $val =~ s/\^/\\\^/g;
+    $val =~ s/\$/\\\$/g;
+    $val =~ s/\./\\\./g;
+    $val =~ s/\+/\\\+/g;
+    $val =~ s/\*/\\\*/g;
+    $val =~ s/\|/\\\|/g;
+    $val =~ s/\?/\\\?/g;
+    $val =~ s/\[/\\\[/g;
+    $val =~ s/\]/\\\]/g;
+    $val =~ s/\{/\\\{/g;
+    $val =~ s/\}/\\\}/g;
+    $val =~ s/\(/\\\(/g;
+    $val =~ s/\)/\\\)/g;
+    $val =~ s/\r/\\r/g;
+    $val =~ s/\n/\\n/g;
+    $val =~ s/\t/\\t/g;
+
+    $val =~ s/\\/\\\\/g;
+    $val =~ s/\"/\\\"/g;
+    $val =~ s/\r/\\r/g;
+    $val =~ s/\n/\\n/g;
+    $val =~ s/\t/\\t/g;
+    $val =~ s/([^\x20-\x7f])/sprintf("\\u%04X",ord($1))/eg;
+    return $val;
+}
+
+sub HtmlQuote { # static
+    my ($val) = @_;
+
+    $val =~ s/&/&amp;/g;
+    $val =~ s/\</&lt;/g;
+    $val =~ s/\>/&gt;/g;
+    # $val =~ s/\"/&quot;/g;
+    return $val;
+}
+
+package W3C::Grammar::YaccCompileTree::LexGoal;
+@W3C::Grammar::YaccCompileTree::LexGoal::ISA = 'W3C::Grammar::YaccCompileTree::Particle';
+use W3C::Util::Exception;
+sub new {
+    my ($proto, $ident, $rules, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@particleParms);
+    $self->{LGIdent} = $ident;
+    $self->{LGRules} = $rules;
+    $self->check();
+    return $self;
+}
+sub resolveIDENTS {
+    my ($self, $grammar) = @_;
+    $self->{LGRules}->resolveIDENTS($grammar);
+}
+sub getIdent {
+    my ($self) = @_;
+    return $self->{LGIdent};
+}
+sub getRules {
+    my ($self) = @_;
+    return $self->{LGRules};
+}
+sub flattenCharacterClass {
+    my ($self, $target) = @_;
+    return $self->{LGRules}->flattenCharacterClass($target);
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    my $ret = $self->{LGRules}->solve($policy, $grammar, $explore);
+    $ret->setSeparator('');
+    return $ret;
+}
+sub __getDisplayTitle {
+    my ($self) = @_;
+    my $displayName = $self->{LGIdent}->getToken2();
+    return "&lt;<code class=\"production term\">$displayName</code>&gt;";
+}
+sub _pythonDeclaration {
+    my ($self, $name) = @_;
+    return "token $name";
+}
+
+sub toString { # from Production;
+    my ($self, %flags) = @_;
+    my $ret = '';
+    if (exists $flags{Markup} && $flags{Markup} eq 'html') {
+	my $displayTitle = $self->__getDisplayTitle();
+	my $distinguishedName = $self->{LGIdent}->getDistinguishedToken();
+	my $prodNo = ${$flags{ProdNo}}++;
+	$ret .= "<tbody class=\"term\">
+<tr valign=\"baseline\">
+<td><a id=\"term-$flags{LanguageName}$distinguishedName\" name=\"term-$flags{LanguageName}$distinguishedName\"></a>[<span class=\"prodNo\">$prodNo</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>$displayTitle</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class=\"content\">";
+	my $tail = $self->{LGRules};
+	while ($tail->isa('W3C::Grammar::YaccCompileTree::Disjunction')) {
+	    $ret .= $tail->getL()->toString(%flags);
+	    $ret .= "<br/>\n| ";
+	    $tail = $tail->getR();
+	}
+	$ret .= $tail->toString(%flags);
+	$ret .= "</code></td>\n</tr>\n</tbody>\n\n";
+    } elsif (my $lang = $flags{Stubs}) {
+	my $name = $self->{LGIdent}->getToken();
+	my $dependencyList = {};
+	my $hasLookAhead = 0;
+	my %callFlags = (%flags, TerminalDependsOn => $dependencyList, 
+			 TerminalRefs => 1, 
+			 InTerminal => 1, HasLookAhead => \$hasLookAhead);
+	my $value = $self->{LGRules}->toString(%callFlags);
+
+	if ($flags{TerminalPatterns}) {
+	    my $str;
+	    if ($lang->isa('W3C::Grammar::GenSpec::Perl')) {
+		$str = "my \$$name = \"$value\";\n";
+	    } elsif ($lang->isa('W3C::Grammar::GenSpec::C_')) {
+		if ($hasLookAhead) {
+		    $flags{Grammar}->addTerminalExpansion($name, $value);
+		    $str = '';
+		} else {
+		    $str = "$name		$value\n";
+		}
+	    } elsif ($lang->isa('W3C::Grammar::GenSpec::N3')) {
+		$str = "$name	cfg:matches	\"$value\";\n	a cfg:Token . \n";
+	    } elsif ($lang->isa('W3C::Grammar::GenSpec::Python')) {
+		my $declaration = $self->_pythonDeclaration($name);
+		$str = "    $declaration: '$value'\n";
+	    } else {
+		&throw(new W3C::Util::ProgramFlowException());
+	    }
+	    push (@{$flags{TerminalPatterns}}, [$name, scalar @{$flags{TerminalPatterns}}, $dependencyList, $str, 0, 0]);
+	} else {
+	    $ret = $value;
+	}
+    } else { # if ($self->[2]) {
+	$ret .= $self->{LGIdent}->toString(%flags);
+	$ret .= ":\n    ";
+	$ret .= $self->{LGRules}->toString(%flags);
+	$ret .= ';';
+    }
+    return $ret;
+}
+
+package W3C::Grammar::YaccCompileTree::Pass;
+@W3C::Grammar::YaccCompileTree::Pass::ISA = 'W3C::Grammar::YaccCompileTree::LexGoal';
+
+sub __getDisplayTitle {
+    my ($self) = @_;
+    return "<code class=\"production directive\">PASSED TOKENS</code>";
+}
+sub _pythonDeclaration {
+    my ($self, $name) = @_;
+    return "ignore";
+}
+
+# Lex classes
+package W3C::Grammar::YaccCompileTree::CharacterClass;
+@W3C::Grammar::YaccCompileTree::CharacterClass::ISA = 'W3C::Grammar::YaccCompileTree::Particle';
+use W3C::Grammar::CharacterRange;
+use W3C::Util::Exception;
+sub new {
+    my ($proto, $lrangeList, $negated, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@particleParms);
+    $self->{LRangeList} = $lrangeList;
+    $self->{Negated} = $negated;
+    $self->{Excluded} = [];
+#    $self->{WideRange} = 
+#	    new W3C::Grammar::YaccCompileTree::List(
+#		new W3C::Grammar::YaccCompileTree::Symb(
+#		    new W3C::Grammar::YaccCompileTree::LLITERAL(0, $self->{Parser}->getLineNo(), $self->{Parser}), $self->{Parser}), 
+#		new W3C::Grammar::YaccCompileTree::Symb(
+#		    new W3C::Grammar::YaccCompileTree::LLITERAL(0x10FFFF, $self->{Parser}->getLineNo(), $self->{Parser}), $self->{Parser}), 
+#						    $self->{Parser});
+    my $flatRangeList = new W3C::Grammar::CharacterRange::FlatRangeList();
+    $self->getLRangeList()->flattenCharacterClass($flatRangeList);
+    $flatRangeList = $flatRangeList->getAscendingRanges();
+    if ($self->{Negated}) {
+	$self->{FlatRanges} = [[0, 0x10fffd]];
+	&W3C::Grammar::CharacterRange::FlatRangeList::_substractRange($self->{FlatRanges}, $flatRangeList);
+    } else {
+	$self->{FlatRanges} = $flatRangeList;
+    }
+    $self->check();
+    return $self;
+}
+sub resolveIDENTS {
+    my ($self, $grammar) = @_;
+}
+
+# replace (in the sense that the parser location is the same) an existing
+# CharacterRange with one that includes all the extra chars in the
+# flatRangeList.
+sub subsume { # static
+    my ($flatRangeList, $from, $parser) = @_;
+    my $ret = {Parser => $parser, From => $from};
+    $ret->{FlatRanges} = $flatRangeList;
+    bless ($ret, 'W3C::Grammar::YaccCompileTree::CharacterClass');
+    return $ret;
+}
+sub getLRangeList {
+    my ($self) = @_;
+    return $self->{LRangeList};
+}
+sub _getNegated {
+    my ($self) = @_;
+    return $self->{Negated};
+}
+sub excludeRange {
+    my ($self, $exclusion) = @_;
+    push (@{$self->{Excluded}}, $exclusion);
+    my $excludeRangeList = new W3C::Grammar::CharacterRange::FlatRangeList();
+    $exclusion->getLRangeList()->flattenCharacterClass($excludeRangeList);
+    &W3C::Grammar::CharacterRange::FlatRangeList::_substractRange($self->{FlatRanges}, $excludeRangeList->getAscendingRanges());
+}
+sub getPreferredPolicy {
+    my ($self, $visited) = @_;
+    return ++$visited->{$self};
+}
+sub flattenCharacterClass {
+    my ($self, $target) = @_;
+    foreach my $range (@{$self->{FlatRanges}}) {
+	my ($b, $t) = @$range;
+	$target->addRange(chr($b), chr($t));
+    }
+    return 1;
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+
+    # know how big each range is
+    my $all_widths = [];
+    my $all_total = 0;
+    my $all_ranges = $self->{FlatRanges}; # just used as a consistent name
+
+    # know how big the ascii subset of each range is
+    my $ascii_widths = [];
+    my $ascii_total = 0;
+    my $ascii_ranges = [];
+
+    foreach my $range (@{$self->{FlatRanges}}) {
+	my ($b, $t) = @$range;
+	my $all_width = $t - $b + 1;
+	push (@$all_widths, $all_width);
+	$all_total += $all_width;
+	if ($t > 127) {
+	    $t = 127;
+	}
+	my $ascii_width = $b <= 127 ? $t - $b + 1 : 0;
+	push (@$ascii_widths, $ascii_width);
+	$ascii_total += $ascii_width;
+	if ($ascii_width) {
+	    push (@$ascii_ranges, [$b, $t]);
+	}
+    }
+
+    my $ret = new W3C::Grammar::YaccCompileTree::Solution();
+    my $optNo = $policy->getRuleNo($self);
+
+    # make pseudo-random selections repeatable
+    # srand($optNo);
+
+    sub _randomPoint {
+	my ($ranges, $total, $widths) = @_;
+	# find a random spot in the total character space
+	my $point = int(rand($total)); my $orig = $point;
+	# find the corresponding range
+	my $rangeNo = 0;
+	while ($point >= $widths->[$rangeNo]) {
+	    $point -= $widths->[$rangeNo];
+	    $rangeNo++;
+	}
+	my ($b, $t) = @{$ranges->[$rangeNo]};
+	return $b+$point;
+    }
+    my $ch = int(rand(100)) > $policy->getAsciiWeigt() || !$ascii_total ? 
+	&_randomPoint($all_ranges, $all_total, $all_widths) : 
+	&_randomPoint($ascii_ranges, $ascii_total, $ascii_widths);
+    $ch = new W3C::Grammar::YaccCompileTree::LLITERAL(chr($ch), 0, $self->{Parser});
+    my $soln = new W3C::Grammar::YaccCompileTree::LiteralSolution($ch);
+    $ret->concat($soln);
+
+    return $ret;
+}
+sub toString {
+    my ($self, %flags) = @_;
+    if ($self->{From}) {
+	return join("\n", map {"[$_->[0] - $_->[1]]"} @{$self->{FlatRanges}})."\nFrom ".$self->{From}->toString(%flags);
+    } else {
+	return $self->toString1(%flags);
+    }
+}
+sub toString1 {
+    my ($self, %flags) = @_;
+    my $excludedStr = @{$self->{Excluded}} ? (join (' - ', undef, map {$_->toString(%flags, CharacterClass => 1)} @{$self->{Excluded}})) : '';
+
+    if (my $lang = $flags{Stubs}) {
+	if ($lang->isa('W3C::Grammar::GenSpec::Python') || 
+	    $lang->isa('W3C::Grammar::GenSpec::Perl')) {
+	    my @ret;
+	    foreach my $range (@{$self->{FlatRanges}}) {
+		my ($l, $r) = @$range;
+		my $lc = $flags{Quoter}(chr($l));
+		my $rc = $flags{Quoter}(chr($r));
+		push (@ret, $r > $l ? "$lc-$rc" : $lc);
+	    }
+	    return join('', '[', @ret, ']');
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::N3') || 
+		 $lang->isa('W3C::Grammar::GenSpec::C_')) {
+	    my @ret;
+	    my $inBracket = 0;
+	    foreach my $range (@{$self->{FlatRanges}}) {
+		my ($l, $r) = @$range;
+		my ($lc, $rc) = (chr($l), chr($r));
+		if (($l > 0x7f) ||
+		    ($r > 0x7f)) {
+		    my $t = $lang->isa('W3C::Grammar::GenSpec::C_') ? 
+			W3C::Grammar::CharacterRange::compileUTF8range($lc, $rc, sub {$flags{Quoter}(chr($_[0]))}) : 
+			W3C::Grammar::CharacterRange::compileUTF16range($lc, $rc, sub {$flags{Quoter}(chr($_[0]))});
+		    if ($inBracket) {
+			if (substr($t, 0, 1) eq '[') {
+			    # merge with the next range
+			    $t = substr($t, 1);
+			} else {
+			    push (@ret, ']|');
+			    $inBracket = 0;
+			}
+		    }
+		    push (@ret, $t);
+		} else {
+		    $lc = $flags{Quoter}(chr($l));
+		    $rc = $flags{Quoter}(chr($r));
+		    if (!$inBracket) {
+			push (@ret, '[');
+			$inBracket = 1;
+		    }
+		    push (@ret, $r > $l ? "$lc-$rc" : $lc);
+		}
+	    }
+	    if ($inBracket) {
+		push (@ret, ']');
+	    }
+	    return join('', @ret);
+	} else {&throw();}
+    } elsif (exists $flags{LexFormat} && $flags{LexFormat} eq 'XMLSpec') {
+	my $str = $self->getLRangeList()->toString(%flags, CharacterClass => 1);
+	my $negStr = $self->_getNegated() ? '^' : '';
+	return "[$negStr$str]$excludedStr";
+    } else {
+	my $str = $self->getLRangeList()->toString(%flags, CharacterClass => 1);
+	my $negStr = $self->_getNegated() ? '~' : '';
+	return "${negStr}[ $str ]$excludedStr";
+    }
+}
+
+package W3C::Grammar::YaccCompileTree::List;
+@W3C::Grammar::YaccCompileTree::List::ISA = 'W3C::Grammar::YaccCompileTree::Particle';
+use W3C::Util::Exception;
+sub new {
+    my ($proto, $l, $r, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@particleParms);
+    $self->{ListLeft} = $l;
+    $self->{ListRight} = $r;
+    $self->check();
+    return $self;
+}
+sub getL {
+    my ($self) = @_;
+    return $self->{ListLeft};
+}
+sub getR {
+    my ($self) = @_;
+    return $self->{ListRight};
+}
+sub flattenCharacterClass {
+    my ($self, $target) = @_;
+    my $testRangeList = new W3C::Grammar::CharacterRange::FlatRangeList();
+    return $self->{ListRight}->flattenCharacterClass($testRangeList) ?	# if right is flattenable
+	$self->{ListLeft}->flattenCharacterClass($target) &&		# return left and right 
+	$self->{ListRight}->flattenCharacterClass($target) : 
+	0;								# else 0
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    # return the first element in the list
+    return $self->{ListLeft}->solve($policy, $grammar, $explore);
+}
+sub toString {
+    my ($self, %flags) = @_;
+    my $lStr = $self->getL()->toString(%flags);
+    my $rStr = $self->getR()->toString(%flags);
+    if (my $lang = $flags{Stubs}) {
+	if ($lang->isa('W3C::Grammar::GenSpec::Perl') || $lang->isa('W3C::Grammar::GenSpec::C_')) {
+	    return "$lStr$rStr";
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::N3') || $lang->isa('W3C::Grammar::GenSpec::Python')) {
+	    return "$lStr$rStr";
+	} else {&throw();}
+    } elsif (exists $flags{CharacterClass} && $flags{CharacterClass} && 
+	     exists $flags{LexFormat} && $flags{LexFormat} eq 'XMLSpec') {
+	return "$lStr$rStr";
+    } else {
+	return "$lStr,$rStr";
+    }
+}
+
+package W3C::Grammar::YaccCompileTree::Range;
+@W3C::Grammar::YaccCompileTree::Range::ISA = 'W3C::Grammar::YaccCompileTree::Particle';
+use W3C::Util::Exception;
+sub new {
+    my ($proto, $l, $r, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@particleParms);
+    $self->{RangeLeft} = $l;
+    $self->{RangeRight} = $r;
+    $self->check();
+    return $self;
+}
+sub getL {
+    my ($self) = @_;
+    return $self->{RangeLeft};
+}
+sub getR {
+    my ($self) = @_;
+    return $self->{RangeRight};
+}
+sub flattenCharacterClass {
+    my ($self, $target) = @_;
+    $target->addRange($self->{RangeLeft}->getValue()->getText(), 
+		      $self->{RangeRight}->getValue()->getText());
+    return 1;
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;
+    # return the bottom end of the range
+    return new W3C::Grammar::YaccCompileTree::LiteralSolution($self->{RangeLeft}->getValue());
+}
+sub toString {
+    my ($self, %flags) = @_;
+    my $l = $self->getL()->getValue()->getText();
+    my $r = $self->getR()->getValue()->getText();
+    if (exists $flags{GenSpec} && $flags{GenSpec}->getCompileUTF8() && $flags{CollectRanges} && 
+	(($l && ord($l) > 0x7f) ||
+	 ($r && ord($r) > 0x7f))) {
+	require W3C::Grammar::CharacterRange;
+	my $expansion = W3C::Grammar::CharacterRange::compileUTF8range($l, $r, sub {$flags{Quoter}(chr($_[0]), chr($_[1]))});
+	push (@{$flags{CollectRanges}}, $expansion);
+	return '';
+    }
+    my $lStr = $self->getL()->toString(%flags);
+    my $rStr = $self->getR()->toString(%flags);
+    return "$lStr-$rStr";
+}
+
+package W3C::Grammar::YaccCompileTree::LookAhead;
+@W3C::Grammar::YaccCompileTree::LookAhead::ISA = 'W3C::Grammar::YaccCompileTree::Particle';
+use W3C::Util::Exception;
+sub new {
+    my ($proto, $lookAhead, @particleParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@particleParms);
+    $self->{LookAhead} = $lookAhead;
+    $self->check();
+    return $self;
+}
+sub resolveIDENTS {
+    my ($self, $grammar) = @_;
+    $self->{LookAhead}->resolveIDENTS($grammar);
+}
+sub solve {
+    my ($self, $policy, $grammar, $explore) = @_;				  # @@@ should return a decision tree for calling production
+    my $ch = new W3C::Grammar::YaccCompileTree::LLITERAL('', 0, $self->{Parser}); # but then, how to write that in the BNF?
+    return new W3C::Grammar::YaccCompileTree::LiteralSolution($ch);		  # can then auto-generate the lookahead.
+}										  # it will be novel grammar work.
+sub toString {
+    my ($self, %flags) = &main::_defaultPrec(@_);
+    if (my $lang = $flags{Stubs}) {
+	if ($lang->isa('W3C::Grammar::GenSpec::Perl')) {
+	    return '(?=('.$self->{LookAhead}->toString(%flags).'))'; # store look-ahead in $1
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::C_')) {
+	    ${$flags{HasLookAhead}} = 1;
+	    return '/'.$self->{LookAhead}->toString(%flags);
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::N3')) {
+	    # &throw();
+	    return '(?=('.$self->{LookAhead}->toString(%flags).'))';
+	} elsif ($lang->isa('W3C::Grammar::GenSpec::Python')) {
+	    # &throw();
+	    return '(?=('.$self->{LookAhead}->toString(%flags).'))';
+	} else {&throw();}
+    } else {
+	my @ret;
+	if ($flags{Types}) {
+	    push (@ret, $self->{Unused0});
+	}
+	push (@ret, '/ ');
+	push (@ret, $self->{LookAhead}->toString(%flags));
+	return join (' ', @ret);
+    }
+}
+
+package W3C::Grammar::YaccCompileTree::SolutionPolicy;
+use W3C::Util::Exception;
+sub new {
+    my ($proto, $seed, $limit, $asciiWeight) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = {Branches => [], Seed => $seed, 	Limit => $limit, AsciiWeight => $asciiWeight};
+    bless ($self, $class);
+    return $self;
+}
+sub addBranch {
+    my ($self, $branch) = @_;
+    push (@{$self->{Branches}}, $branch);
+}
+sub getSeed {
+    my ($self) = @_;
+    return $self->{Seed};
+}
+sub getLimit {
+    my ($self) = @_;
+    return $self->{Limit};
+}
+sub getAsciiWeigt {
+    my ($self) = @_;
+    return $self->{AsciiWeight};
+}
+sub clone {
+    my ($self) = @_;
+    my $ret = {%$self};
+    my $class = ref $self;
+    bless ($ret, $class);
+    return $ret;
+}
+
+package W3C::Grammar::YaccCompileTree::RandomPolicy;
+@W3C::Grammar::YaccCompileTree::RandomPolicy::ISA = qw(W3C::Grammar::YaccCompileTree::SolutionPolicy);
+use W3C::Util::Exception;
+sub new {
+    my ($proto, $seed, $limit, $asciiWeight) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new($seed, $limit, $asciiWeight);
+    return $self;
+}
+
+package W3C::Grammar::YaccCompileTree::RepresentativePolicy;
+@W3C::Grammar::YaccCompileTree::RepresentativePolicy::ISA = qw(W3C::Grammar::YaccCompileTree::SolutionPolicy);
+use W3C::Util::Exception;
+sub new {
+    my ($proto, $seed, $limit, $asciiWeight) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new($seed, $limit, $asciiWeight);
+    $self->{Visited} = {};
+    return $self;
+}
+sub getRuleNo {
+    my ($self, $ruleOptions) = @_;
+    return (scalar %{$self->{Visited}} > $self->{Limit}) ? 0 : $ruleOptions->getPreferredPolicy($self->{Visited});
+}
+sub clearVisitations {
+    my ($self, $visitor) = @_;
+    $self->{Visited}{$visitor} = 0;
+}
+
+package W3C::Grammar::YaccCompileTree::ReferencePolicy;
+@W3C::Grammar::YaccCompileTree::ReferencePolicy::ISA = qw(W3C::Grammar::YaccCompileTree::SolutionPolicy);
+use W3C::Util::Exception;
+sub new {
+    my ($proto, $referenceString, $fallbackPolicy) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new();
+    $self->{FallbackPolicy} = $fallbackPolicy;
+    return $self;
+}
+
+package W3C::Grammar::YaccCompileTree::Solution;
+use W3C::Util::Exception;
+sub new {
+    my ($proto) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = {Seq => [], Prev => undef, Next => undef, Separator => undef};
+    bless ($self, $class);
+    return $self;
+}
+sub setPrevOpt {
+    my ($self, $prevOpt) = @_;
+    $self->{Prev} = $prevOpt;
+}
+sub setNextOpt {
+    my ($self, $nextOpt) = @_;
+    $self->{Next} = $nextOpt;
+}
+sub setSeparator {
+    my ($self, $separator) = @_;
+    $self->{Separator} = $separator;
+}
+sub concat {
+    my ($self, $soln) = @_;
+    die if (!$soln || !$soln->can('getHtml'));
+    push (@{$self->{Seq}}, $soln);
+}
+sub getHtml {
+    my ($self, $separator) = @_;
+    if (defined $self->{Separator}) {
+	$separator = $self->{Separator};
+    }
+    my @ret = '';
+    foreach my $subSolution (@{$self->{Seq}}) {
+#	if ($subSolution->isa('W3C::Grammar::YaccCompileTree::Solution')) {
+	    push (@ret, $subSolution->getHtml($separator));
+#	} else {
+#	    push (@ret, $subSolution->getToken());
+#	}
+    }
+    if ($self->{Prev}) {
+	my $prev = $self->{Prev}->getHtmlLink($separator);
+	push (@ret, "<sub><a href=\"$prev\">-</a></sub>");
+    }
+    if ($self->{Next}) {
+	my $next = $self->{Next}->getHtmlLink($separator);
+	push (@ret, "<super><a href=\"$next\">+</a></super>");
+    }
+    return join ($separator, @ret);
+}
+
+package W3C::Grammar::YaccCompileTree::LiteralSolution;
+#@W3C::Grammar::YaccCompileTree::LiteralSolution::ISA('W3C::Grammar::YaccCompileTree::Solution');
+sub new {
+    my ($proto, $literal) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = {Literal => $literal};
+    bless ($self, $class);
+    return $self;
+}
+sub setSeparator {
+    my ($self, $separator) = @_;
+}
+sub getHtml {
+    my ($self, $separator) = @_;
+    return $self->{Literal}->getText();
+}
+
+
+1;
+
+__END__
+
+=head1 NAME
+
+W3C::Grammar::YaccCompileTree - RDF query objects
+
+=head1 SYNOPSIS
+
+  # in a parser...
+  use W3C::Grammar::YaccCompileTree;
+  my $t1 = new W3C::Grammar::YaccCompileTree::Decl([$p1, $s1, $o1], 
+				$constraints1, $self);
+  my $t2 = new W3C::Grammar::YaccCompileTree::Decl([$p2, $s2, $o2], 
+				$constraints2, $self);
+  my $conj = new W3C::Grammar::YaccCompileTree::Conjunction($t1, $t2, $self)
+
+=head1 DESCRIPTION
+
+Parsers generate YaccCompileTrees and hand them to the Yacc2 object. Yacc2
+calls the compile tree to perforn queries/assertions/rules.
+
+This module is part of the W3C::Rdf CPAN module.
+
+=head1 METHODS
+
+    $atomDictionary, $namespaceHandler, 
+	$sources, $rdfApp, $sourceAttrib, $flags
+
+=head2 immediateEvaluate($resultSet)
+
+Perform compile-time evaluations.
+
+no return value
+
+=head2 delayedEvaluate($resultSet)
+
+Perform post-compile-time (pass 2) evaluations. This is for query languages
+that require a second pass to do things like resolve namespace prefixes that
+are declared after a dependent qname is first used.
+
+no return value
+
+=head2 val($triple, $premise, $row)
+
+Perform the query evaluation. I don't remember what the hell the $premise is,
+but it sure looks important.
+
+returns an interned RDF Atom
+
+=head1 AUTHOR
+
+Eric Prud'hommeaux <eric@w3.org>
+
+=head1 SEE ALSO
+
+W3C::Rdf::Yacc2(1) W3C::Rdf::YaccParser(1) W3C::Rdf::Atom(1) perl(1).
+
+=cut
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/YaccParser.pm	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,2883 @@
+#!/usr/bin/perl
+####################################################################
+#
+#    This file was generated using Parse::Yapp version 1.05.
+#
+#        Don't edit this file, use source file instead.
+#
+#             ANY CHANGE MADE HERE WILL BE LOST !
+#
+####################################################################
+package W3C::Grammar::_YaccParser;
+use vars qw ( @ISA );
+use strict;
+
+@ISA= qw ( Parse::Yapp::Driver );
+# use Parse::Yapp::Driver; @@ replaced by W3C::Util::YappDriver
+
+#line 4 "YaccParser.yp"
+
+require 5.004;
+
+use Carp;
+
+    use W3C::Util::Exception;
+    use W3C::Util::YappDriver;
+    use W3C::Grammar::YaccCompileTree qw($PassedTokensName);
+    #use W3C::Grammar::LexLexer;
+    @ISA= qw (W3C::Util::YappDriver);
+
+my($input,$lexlevel,$nberr,@lineno,$prec,$labelno);
+my($head,$tail,$Token,$Terminals,$NonTerminals,$rules,$PrecedenceTerminals,$start,$nullable);
+my($expect);
+my $NoSemiNeeded = 0;
+my $Messages = [];
+
+my $LexMode = 0; # not lexing lex
+my $CharClass = undef; # not lexing a character class
+
+
+
+sub new {
+        my($class)=shift;
+        ref($class)
+    and $class=ref($class);
+
+    my($self)=$class->SUPER::new( yyversion => '1.05',
+                                  yystates =>
+[
+	{#State 0
+		ACTIONS => {
+			"%%" => -6,
+			"\n" => 4,
+			'EXPECT' => 3,
+			'COMMENT' => 6,
+			'TYPE' => 5,
+			'UNION' => 9,
+			'START' => 10,
+			'error' => 12,
+			'TOKEN' => 13,
+			"[" => 14,
+			'ASSOC' => 16,
+			'HEADCODE' => 15
+		},
+		GOTOS => {
+			'head' => 1,
+			'decl' => 11,
+			'yapp' => 2,
+			'headsec' => 7,
+			'decls' => 8
+		}
+	},
+	{#State 1
+		ACTIONS => {
+			'PASS' => -88,
+			"%%" => 18,
+			'TERMINAL' => -88,
+			'IDENT' => -88,
+			'COMMENT' => 19,
+			'error' => 22,
+			"[" => 24
+		},
+		GOTOS => {
+			'body' => 21,
+			'ordinalOpt' => 17,
+			'rulesec' => 23,
+			'rules' => 20
+		}
+	},
+	{#State 2
+		ACTIONS => {
+			'' => 25
+		}
+	},
+	{#State 3
+		ACTIONS => {
+			'NUMBER' => 26
+		}
+	},
+	{#State 4
+		DEFAULT => -12
+	},
+	{#State 5
+		ACTIONS => {
+			"<" => 28
+		},
+		DEFAULT => -24,
+		GOTOS => {
+			'typedecl' => 27
+		}
+	},
+	{#State 6
+		DEFAULT => -13
+	},
+	{#State 7
+		ACTIONS => {
+			"%%" => 29
+		}
+	},
+	{#State 8
+		ACTIONS => {
+			"%%" => -7,
+			"\n" => 4,
+			'EXPECT' => 3,
+			'COMMENT' => 6,
+			'TYPE' => 5,
+			'UNION' => 9,
+			'START' => 10,
+			'error' => 12,
+			'TOKEN' => 13,
+			"[" => 14,
+			'ASSOC' => 16,
+			'HEADCODE' => 15
+		},
+		GOTOS => {
+			'decl' => 30
+		}
+	},
+	{#State 9
+		ACTIONS => {
+			'CODE' => 31
+		}
+	},
+	{#State 10
+		ACTIONS => {
+			'IDENT' => 32
+		},
+		GOTOS => {
+			'ident' => 33
+		}
+	},
+	{#State 11
+		DEFAULT => -9
+	},
+	{#State 12
+		ACTIONS => {
+			"\n" => 34
+		}
+	},
+	{#State 13
+		ACTIONS => {
+			"<" => 28
+		},
+		DEFAULT => -24,
+		GOTOS => {
+			'typedecl' => 35
+		}
+	},
+	{#State 14
+		ACTIONS => {
+			'NUMBER' => 37
+		},
+		DEFAULT => -90,
+		GOTOS => {
+			'ordinal' => 36
+		}
+	},
+	{#State 15
+		ACTIONS => {
+			"\n" => 38
+		}
+	},
+	{#State 16
+		ACTIONS => {
+			"<" => 28
+		},
+		DEFAULT => -24,
+		GOTOS => {
+			'typedecl' => 39
+		}
+	},
+	{#State 17
+		ACTIONS => {
+			'PASS' => 40,
+			'IDENT' => 42,
+			'TERMINAL' => 41
+		}
+	},
+	{#State 18
+		DEFAULT => -64
+	},
+	{#State 19
+		DEFAULT => -76
+	},
+	{#State 20
+		DEFAULT => -66
+	},
+	{#State 21
+		ACTIONS => {
+			'TAILCODE' => 43
+		},
+		DEFAULT => -135,
+		GOTOS => {
+			'tail' => 44
+		}
+	},
+	{#State 22
+		ACTIONS => {
+			";" => 45
+		}
+	},
+	{#State 23
+		ACTIONS => {
+			'PASS' => -88,
+			"%%" => 46,
+			'TERMINALS' => 47,
+			'TERMINAL' => -88,
+			'IDENT' => -88,
+			'COMMENT' => 19,
+			'error' => 22,
+			"[" => 24
+		},
+		GOTOS => {
+			'ordinalOpt' => 17,
+			'rules' => 48
+		}
+	},
+	{#State 24
+		ACTIONS => {
+			'NUMBER' => 37
+		},
+		DEFAULT => -90,
+		GOTOS => {
+			'ordinal' => 49
+		}
+	},
+	{#State 25
+		DEFAULT => 0
+	},
+	{#State 26
+		ACTIONS => {
+			"\n" => 50
+		}
+	},
+	{#State 27
+		ACTIONS => {
+			'IDENT' => 32
+		},
+		GOTOS => {
+			'identlist' => 51,
+			'ident' => 52
+		}
+	},
+	{#State 28
+		ACTIONS => {
+			'IDENT' => 53
+		}
+	},
+	{#State 29
+		DEFAULT => -5
+	},
+	{#State 30
+		DEFAULT => -8
+	},
+	{#State 31
+		ACTIONS => {
+			"\n" => 54
+		}
+	},
+	{#State 32
+		DEFAULT => -4
+	},
+	{#State 33
+		ACTIONS => {
+			"\n" => 55
+		}
+	},
+	{#State 34
+		DEFAULT => -21
+	},
+	{#State 35
+		ACTIONS => {
+			'LITERAL' => 57,
+			'IDENT' => 32
+		},
+		GOTOS => {
+			'symlist' => 59,
+			'symbol' => 56,
+			'ident' => 58
+		}
+	},
+	{#State 36
+		ACTIONS => {
+			"]" => 60
+		}
+	},
+	{#State 37
+		ACTIONS => {
+			'IDENT' => 61
+		},
+		DEFAULT => -91
+	},
+	{#State 38
+		DEFAULT => -17
+	},
+	{#State 39
+		ACTIONS => {
+			'LITERAL' => 57,
+			'IDENT' => 32
+		},
+		GOTOS => {
+			'symlist' => 62,
+			'symbol' => 56,
+			'ident' => 58
+		}
+	},
+	{#State 40
+		ACTIONS => {
+			":" => 63
+		},
+		GOTOS => {
+			'ruleMarker' => 64
+		}
+	},
+	{#State 41
+		ACTIONS => {
+			":" => 63
+		},
+		GOTOS => {
+			'ruleMarker' => 65
+		}
+	},
+	{#State 42
+		ACTIONS => {
+			":" => 63
+		},
+		GOTOS => {
+			'ruleMarker' => 66
+		}
+	},
+	{#State 43
+		DEFAULT => -136
+	},
+	{#State 44
+		DEFAULT => -1
+	},
+	{#State 45
+		DEFAULT => -77
+	},
+	{#State 46
+		DEFAULT => -63
+	},
+	{#State 47
+		ACTIONS => {
+			'PASS' => -88,
+			'error' => 71,
+			'IDENT' => -88,
+			"[" => 24,
+			'COMMENT' => 69
+		},
+		GOTOS => {
+			'termsec' => 70,
+			'ordinalOpt' => 67,
+			'terms' => 68
+		}
+	},
+	{#State 48
+		DEFAULT => -65
+	},
+	{#State 49
+		ACTIONS => {
+			"]" => 72
+		}
+	},
+	{#State 50
+		DEFAULT => -20
+	},
+	{#State 51
+		ACTIONS => {
+			"\n" => 73,
+			'IDENT' => 32
+		},
+		GOTOS => {
+			'ident' => 74
+		}
+	},
+	{#State 52
+		DEFAULT => -29
+	},
+	{#State 53
+		ACTIONS => {
+			">" => 75
+		}
+	},
+	{#State 54
+		DEFAULT => -18
+	},
+	{#State 55
+		DEFAULT => -16
+	},
+	{#State 56
+		DEFAULT => -27
+	},
+	{#State 57
+		DEFAULT => -2
+	},
+	{#State 58
+		DEFAULT => -3
+	},
+	{#State 59
+		ACTIONS => {
+			'LITERAL' => 57,
+			'IDENT' => 32
+		},
+		DEFAULT => -10,
+		GOTOS => {
+			'CMNTS' => 77,
+			'symbol' => 76,
+			'ident' => 58
+		}
+	},
+	{#State 60
+		ACTIONS => {
+			'TERMINAL' => 78
+		}
+	},
+	{#State 61
+		DEFAULT => -92
+	},
+	{#State 62
+		ACTIONS => {
+			'LITERAL' => 57,
+			'IDENT' => 32
+		},
+		DEFAULT => -10,
+		GOTOS => {
+			'CMNTS' => 79,
+			'symbol' => 76,
+			'ident' => 58
+		}
+	},
+	{#State 63
+		ACTIONS => {
+			":" => 80
+		},
+		DEFAULT => -93
+	},
+	{#State 64
+		DEFAULT => -73,
+		GOTOS => {
+			'@8-3' => 81
+		}
+	},
+	{#State 65
+		DEFAULT => -70,
+		GOTOS => {
+			'@6-3' => 82
+		}
+	},
+	{#State 66
+		DEFAULT => -67,
+		GOTOS => {
+			'@4-3' => 83
+		}
+	},
+	{#State 67
+		ACTIONS => {
+			'PASS' => 84,
+			'IDENT' => 85
+		}
+	},
+	{#State 68
+		DEFAULT => -79
+	},
+	{#State 69
+		DEFAULT => -86
+	},
+	{#State 70
+		ACTIONS => {
+			'PASS' => -88,
+			"%%" => 86,
+			'error' => 71,
+			'IDENT' => -88,
+			"[" => 24,
+			'COMMENT' => 69
+		},
+		GOTOS => {
+			'ordinalOpt' => 67,
+			'terms' => 87
+		}
+	},
+	{#State 71
+		ACTIONS => {
+			";" => 88
+		}
+	},
+	{#State 72
+		DEFAULT => -89
+	},
+	{#State 73
+		DEFAULT => -19
+	},
+	{#State 74
+		DEFAULT => -28
+	},
+	{#State 75
+		DEFAULT => -25
+	},
+	{#State 76
+		DEFAULT => -26
+	},
+	{#State 77
+		ACTIONS => {
+			"\n" => 89,
+			'COMMENT' => 90
+		}
+	},
+	{#State 78
+		ACTIONS => {
+			":" => 91
+		}
+	},
+	{#State 79
+		ACTIONS => {
+			"\n" => 92,
+			'COMMENT' => 90
+		}
+	},
+	{#State 80
+		ACTIONS => {
+			"=" => 93
+		}
+	},
+	{#State 81
+		ACTIONS => {
+			"/" => 103,
+			'LITERAL' => 98,
+			'IDENT' => 97,
+			'TERMINAL' => 96,
+			'COMMENT' => 95,
+			"(" => 104,
+			"[" => 101
+		},
+		DEFAULT => -105,
+		GOTOS => {
+			'termrhs' => 102,
+			'lmodifiableelt' => 94,
+			'termrhselts' => 99,
+			'termrhselt' => 105,
+			'resolvableelt' => 106,
+			'termrhss' => 100,
+			'termmodifiedelt' => 107,
+			'termrule' => 108,
+			'resolvableelt1' => 109
+		}
+	},
+	{#State 82
+		ACTIONS => {
+			"/" => 103,
+			'LITERAL' => 98,
+			'IDENT' => 97,
+			'TERMINAL' => 96,
+			'COMMENT' => 95,
+			"(" => 104,
+			"[" => 101
+		},
+		DEFAULT => -105,
+		GOTOS => {
+			'termrhs' => 102,
+			'lmodifiableelt' => 94,
+			'termrhselts' => 99,
+			'termrhselt' => 105,
+			'resolvableelt' => 106,
+			'termrhss' => 110,
+			'termmodifiedelt' => 107,
+			'termrule' => 108,
+			'resolvableelt1' => 109
+		}
+	},
+	{#State 83
+		ACTIONS => {
+			"/" => 124,
+			'CODE' => 123,
+			'LITERAL' => 57,
+			'IDENT' => 32,
+			'COMMENT' => 113,
+			'TERMINAL' => 112,
+			"(" => 125,
+			"[" => 118
+		},
+		DEFAULT => -103,
+		GOTOS => {
+			'symbol' => 122,
+			'rhs' => 111,
+			'rule' => 115,
+			'modifiedelt' => 114,
+			'ident' => 58,
+			'rhss' => 116,
+			'rhselt' => 117,
+			'rhselts' => 119,
+			'modifiableelt' => 120,
+			'code' => 121
+		}
+	},
+	{#State 84
+		ACTIONS => {
+			":" => 63
+		},
+		GOTOS => {
+			'ruleMarker' => 126
+		}
+	},
+	{#State 85
+		ACTIONS => {
+			":" => 63
+		},
+		GOTOS => {
+			'ruleMarker' => 127
+		}
+	},
+	{#State 86
+		DEFAULT => -62
+	},
+	{#State 87
+		DEFAULT => -78
+	},
+	{#State 88
+		DEFAULT => -87
+	},
+	{#State 89
+		DEFAULT => -14
+	},
+	{#State 90
+		DEFAULT => -11
+	},
+	{#State 91
+		ACTIONS => {
+			":" => 128
+		}
+	},
+	{#State 92
+		DEFAULT => -15
+	},
+	{#State 93
+		DEFAULT => -94
+	},
+	{#State 94
+		ACTIONS => {
+			"?" => 131,
+			"+" => 129,
+			"*" => 130
+		},
+		DEFAULT => -120
+	},
+	{#State 95
+		DEFAULT => -115
+	},
+	{#State 96
+		DEFAULT => -51
+	},
+	{#State 97
+		DEFAULT => -50
+	},
+	{#State 98
+		DEFAULT => -49
+	},
+	{#State 99
+		DEFAULT => -106
+	},
+	{#State 100
+		ACTIONS => {
+			'EOProduction' => 132,
+			"|" => 133
+		}
+	},
+	{#State 101
+		DEFAULT => -52,
+		GOTOS => {
+			'@2-1' => 134
+		}
+	},
+	{#State 102
+		ACTIONS => {
+			'PREC' => 135
+		},
+		DEFAULT => -102,
+		GOTOS => {
+			'prec' => 136
+		}
+	},
+	{#State 103
+		ACTIONS => {
+			"(" => 104,
+			"/" => 103,
+			"[" => 101,
+			'LITERAL' => 98,
+			'IDENT' => 97,
+			'TERMINAL' => 96
+		},
+		GOTOS => {
+			'resolvableelt' => 106,
+			'lmodifiableelt' => 137,
+			'resolvableelt1' => 109
+		}
+	},
+	{#State 104
+		ACTIONS => {
+			"/" => 103,
+			'CODE' => 123,
+			'COMMENT' => 141,
+			'LITERAL' => 98,
+			'IDENT' => 97,
+			'TERMINAL' => 96,
+			"(" => 104,
+			"[" => 101
+		},
+		DEFAULT => -33,
+		GOTOS => {
+			'lrhs' => 143,
+			'lrhss' => 138,
+			'lrule' => 139,
+			'lmodifiableelt' => 140,
+			'lmodifiedelt' => 144,
+			'lrhselt' => 145,
+			'lrhselts' => 146,
+			'resolvableelt' => 106,
+			'resolvableelt1' => 109,
+			'code' => 142
+		}
+	},
+	{#State 105
+		ACTIONS => {
+			"/" => 103,
+			'LITERAL' => 98,
+			'IDENT' => 97,
+			'TERMINAL' => 96,
+			'COMMENT' => 95,
+			"(" => 104,
+			"[" => 101
+		},
+		DEFAULT => -110,
+		GOTOS => {
+			'termrhselts' => 147,
+			'termrhselt' => 105,
+			'resolvableelt' => 106,
+			'termmodifiedelt' => 107,
+			'lmodifiableelt' => 94,
+			'resolvableelt1' => 109
+		}
+	},
+	{#State 106
+		DEFAULT => -47
+	},
+	{#State 107
+		DEFAULT => -114
+	},
+	{#State 108
+		DEFAULT => -98
+	},
+	{#State 109
+		ACTIONS => {
+			"-" => 148
+		},
+		DEFAULT => -44
+	},
+	{#State 110
+		ACTIONS => {
+			'EOProduction' => 149,
+			"|" => 133
+		}
+	},
+	{#State 111
+		ACTIONS => {
+			'PREC' => 135
+		},
+		DEFAULT => -100,
+		GOTOS => {
+			'prec' => 150
+		}
+	},
+	{#State 112
+		DEFAULT => -125
+	},
+	{#State 113
+		DEFAULT => -113
+	},
+	{#State 114
+		DEFAULT => -111
+	},
+	{#State 115
+		DEFAULT => -96
+	},
+	{#State 116
+		ACTIONS => {
+			'EOProduction' => 151,
+			"|" => 152
+		}
+	},
+	{#State 117
+		ACTIONS => {
+			"/" => 124,
+			'CODE' => 123,
+			'LITERAL' => 57,
+			'IDENT' => 32,
+			'COMMENT' => 113,
+			'TERMINAL' => 112,
+			"(" => 125,
+			"[" => 118
+		},
+		DEFAULT => -108,
+		GOTOS => {
+			'symbol' => 122,
+			'rhselt' => 117,
+			'rhselts' => 153,
+			'modifiedelt' => 114,
+			'ident' => 58,
+			'code' => 121,
+			'modifiableelt' => 120
+		}
+	},
+	{#State 118
+		DEFAULT => -127,
+		GOTOS => {
+			'@14-1' => 154
+		}
+	},
+	{#State 119
+		DEFAULT => -104
+	},
+	{#State 120
+		ACTIONS => {
+			"+" => 155,
+			"*" => 156,
+			"?" => 157
+		},
+		DEFAULT => -116
+	},
+	{#State 121
+		DEFAULT => -112
+	},
+	{#State 122
+		DEFAULT => -124
+	},
+	{#State 123
+		DEFAULT => -134
+	},
+	{#State 124
+		ACTIONS => {
+			"(" => 104,
+			"/" => 103,
+			"[" => 101,
+			'LITERAL' => 98,
+			'IDENT' => 97,
+			'TERMINAL' => 96
+		},
+		GOTOS => {
+			'resolvableelt' => 106,
+			'lmodifiableelt' => 158,
+			'resolvableelt1' => 109
+		}
+	},
+	{#State 125
+		ACTIONS => {
+			"/" => 124,
+			'CODE' => 123,
+			'LITERAL' => 57,
+			'IDENT' => 32,
+			'COMMENT' => 113,
+			'TERMINAL' => 112,
+			"(" => 125,
+			"[" => 118
+		},
+		DEFAULT => -103,
+		GOTOS => {
+			'symbol' => 122,
+			'rhs' => 111,
+			'rule' => 115,
+			'modifiedelt' => 114,
+			'ident' => 58,
+			'rhss' => 159,
+			'rhselt' => 117,
+			'rhselts' => 119,
+			'modifiableelt' => 120,
+			'code' => 121
+		}
+	},
+	{#State 126
+		DEFAULT => -83,
+		GOTOS => {
+			'@12-3' => 160
+		}
+	},
+	{#State 127
+		DEFAULT => -80,
+		GOTOS => {
+			'@10-3' => 161
+		}
+	},
+	{#State 128
+		ACTIONS => {
+			"=" => 162
+		}
+	},
+	{#State 129
+		DEFAULT => -123
+	},
+	{#State 130
+		DEFAULT => -121
+	},
+	{#State 131
+		DEFAULT => -122
+	},
+	{#State 132
+		DEFAULT => -74,
+		GOTOS => {
+			'@9-6' => 163
+		}
+	},
+	{#State 133
+		ACTIONS => {
+			"/" => 103,
+			'LITERAL' => 98,
+			'IDENT' => 97,
+			'TERMINAL' => 96,
+			'COMMENT' => 95,
+			"(" => 104,
+			"[" => 101
+		},
+		DEFAULT => -105,
+		GOTOS => {
+			'termrhs' => 102,
+			'termrhselts' => 99,
+			'termrhselt' => 105,
+			'resolvableelt' => 106,
+			'termmodifiedelt' => 107,
+			'termrule' => 164,
+			'lmodifiableelt' => 94,
+			'resolvableelt1' => 109
+		}
+	},
+	{#State 134
+		ACTIONS => {
+			'CARROT' => 170,
+			'LITERAL' => 165
+		},
+		GOTOS => {
+			'charclass' => 166,
+			'lRangeElem' => 167,
+			'lrangeList' => 168,
+			'lRange' => 169
+		}
+	},
+	{#State 135
+		ACTIONS => {
+			'LITERAL' => 57,
+			'IDENT' => 32
+		},
+		GOTOS => {
+			'symbol' => 171,
+			'ident' => 58
+		}
+	},
+	{#State 136
+		ACTIONS => {
+			'CODE' => 123
+		},
+		DEFAULT => -132,
+		GOTOS => {
+			'epscode' => 173,
+			'code' => 172
+		}
+	},
+	{#State 137
+		DEFAULT => -46
+	},
+	{#State 138
+		ACTIONS => {
+			"|" => 175,
+			")" => 174
+		}
+	},
+	{#State 139
+		DEFAULT => -31
+	},
+	{#State 140
+		ACTIONS => {
+			"?" => 178,
+			"+" => 176,
+			"*" => 177
+		},
+		DEFAULT => -40
+	},
+	{#State 141
+		DEFAULT => -39
+	},
+	{#State 142
+		DEFAULT => -38
+	},
+	{#State 143
+		DEFAULT => -32
+	},
+	{#State 144
+		DEFAULT => -37
+	},
+	{#State 145
+		ACTIONS => {
+			"/" => 103,
+			'CODE' => 123,
+			'COMMENT' => 141,
+			'LITERAL' => 98,
+			'IDENT' => 97,
+			'TERMINAL' => 96,
+			"(" => 104,
+			"[" => 101
+		},
+		DEFAULT => -35,
+		GOTOS => {
+			'lrhselt' => 145,
+			'lmodifiedelt' => 144,
+			'lrhselts' => 179,
+			'resolvableelt' => 106,
+			'lmodifiableelt' => 140,
+			'resolvableelt1' => 109,
+			'code' => 142
+		}
+	},
+	{#State 146
+		DEFAULT => -34
+	},
+	{#State 147
+		DEFAULT => -109
+	},
+	{#State 148
+		ACTIONS => {
+			"[" => 101,
+			'LITERAL' => 98,
+			'IDENT' => 97,
+			'TERMINAL' => 96
+		},
+		GOTOS => {
+			'resolvableelt' => 180
+		}
+	},
+	{#State 149
+		DEFAULT => -71,
+		GOTOS => {
+			'@7-6' => 181
+		}
+	},
+	{#State 150
+		ACTIONS => {
+			'CODE' => 123
+		},
+		DEFAULT => -132,
+		GOTOS => {
+			'epscode' => 182,
+			'code' => 172
+		}
+	},
+	{#State 151
+		DEFAULT => -68,
+		GOTOS => {
+			'@5-6' => 183
+		}
+	},
+	{#State 152
+		ACTIONS => {
+			"/" => 124,
+			'CODE' => 123,
+			'LITERAL' => 57,
+			'IDENT' => 32,
+			'COMMENT' => 113,
+			'TERMINAL' => 112,
+			"(" => 125,
+			"[" => 118
+		},
+		DEFAULT => -103,
+		GOTOS => {
+			'symbol' => 122,
+			'rhs' => 111,
+			'rule' => 184,
+			'modifiedelt' => 114,
+			'ident' => 58,
+			'rhselt' => 117,
+			'rhselts' => 119,
+			'modifiableelt' => 120,
+			'code' => 121
+		}
+	},
+	{#State 153
+		DEFAULT => -107
+	},
+	{#State 154
+		ACTIONS => {
+			'CARROT' => 170,
+			'LITERAL' => 165
+		},
+		GOTOS => {
+			'charclass' => 185,
+			'lRangeElem' => 167,
+			'lrangeList' => 168,
+			'lRange' => 169
+		}
+	},
+	{#State 155
+		DEFAULT => -119
+	},
+	{#State 156
+		DEFAULT => -117
+	},
+	{#State 157
+		DEFAULT => -118
+	},
+	{#State 158
+		DEFAULT => -130
+	},
+	{#State 159
+		ACTIONS => {
+			"|" => 152,
+			")" => 186
+		}
+	},
+	{#State 160
+		ACTIONS => {
+			"/" => 103,
+			'LITERAL' => 98,
+			'IDENT' => 97,
+			'TERMINAL' => 96,
+			'COMMENT' => 95,
+			"(" => 104,
+			"[" => 101
+		},
+		DEFAULT => -105,
+		GOTOS => {
+			'termrhs' => 102,
+			'lmodifiableelt' => 94,
+			'termrhselts' => 99,
+			'termrhselt' => 105,
+			'resolvableelt' => 106,
+			'termrhss' => 187,
+			'termmodifiedelt' => 107,
+			'termrule' => 108,
+			'resolvableelt1' => 109
+		}
+	},
+	{#State 161
+		ACTIONS => {
+			"/" => 103,
+			'LITERAL' => 98,
+			'IDENT' => 97,
+			'TERMINAL' => 96,
+			'COMMENT' => 95,
+			"(" => 104,
+			"[" => 101
+		},
+		DEFAULT => -105,
+		GOTOS => {
+			'termrhs' => 102,
+			'lmodifiableelt' => 94,
+			'termrhselts' => 99,
+			'termrhselt' => 105,
+			'resolvableelt' => 106,
+			'termrhss' => 188,
+			'termmodifiedelt' => 107,
+			'termrule' => 108,
+			'resolvableelt1' => 109
+		}
+	},
+	{#State 162
+		ACTIONS => {
+			"/" => 103,
+			'CODE' => 123,
+			'COMMENT' => 141,
+			'LITERAL' => 98,
+			'IDENT' => 97,
+			'TERMINAL' => 96,
+			"(" => 104,
+			"[" => 101
+		},
+		DEFAULT => -33,
+		GOTOS => {
+			'lrhs' => 143,
+			'lrhss' => 189,
+			'lrule' => 139,
+			'lmodifiableelt' => 140,
+			'lmodifiedelt' => 144,
+			'lrhselt' => 145,
+			'lrhselts' => 146,
+			'resolvableelt' => 106,
+			'resolvableelt1' => 109,
+			'code' => 142
+		}
+	},
+	{#State 163
+		DEFAULT => -75
+	},
+	{#State 164
+		DEFAULT => -97
+	},
+	{#State 165
+		DEFAULT => -61
+	},
+	{#State 166
+		ACTIONS => {
+			"]" => 190
+		}
+	},
+	{#State 167
+		ACTIONS => {
+			'RANGEOP' => 191
+		},
+		DEFAULT => -59
+	},
+	{#State 168
+		ACTIONS => {
+			'LITERAL' => 165
+		},
+		DEFAULT => -55,
+		GOTOS => {
+			'lRangeElem' => 167,
+			'lRange' => 192
+		}
+	},
+	{#State 169
+		DEFAULT => -57
+	},
+	{#State 170
+		ACTIONS => {
+			'LITERAL' => 165
+		},
+		GOTOS => {
+			'lRangeElem' => 167,
+			'lrangeList' => 193,
+			'lRange' => 169
+		}
+	},
+	{#State 171
+		DEFAULT => -131
+	},
+	{#State 172
+		DEFAULT => -133
+	},
+	{#State 173
+		DEFAULT => -101
+	},
+	{#State 174
+		DEFAULT => -45
+	},
+	{#State 175
+		ACTIONS => {
+			"/" => 103,
+			'CODE' => 123,
+			'COMMENT' => 141,
+			'LITERAL' => 98,
+			'IDENT' => 97,
+			'TERMINAL' => 96,
+			"(" => 104,
+			"[" => 101
+		},
+		DEFAULT => -33,
+		GOTOS => {
+			'lrhs' => 143,
+			'lrule' => 194,
+			'lmodifiableelt' => 140,
+			'lmodifiedelt' => 144,
+			'lrhselt' => 145,
+			'resolvableelt' => 106,
+			'lrhselts' => 146,
+			'resolvableelt1' => 109,
+			'code' => 142
+		}
+	},
+	{#State 176
+		DEFAULT => -43
+	},
+	{#State 177
+		DEFAULT => -41
+	},
+	{#State 178
+		DEFAULT => -42
+	},
+	{#State 179
+		DEFAULT => -36
+	},
+	{#State 180
+		DEFAULT => -48
+	},
+	{#State 181
+		DEFAULT => -72
+	},
+	{#State 182
+		DEFAULT => -99
+	},
+	{#State 183
+		DEFAULT => -69
+	},
+	{#State 184
+		DEFAULT => -95
+	},
+	{#State 185
+		ACTIONS => {
+			"]" => 195
+		}
+	},
+	{#State 186
+		DEFAULT => -126
+	},
+	{#State 187
+		ACTIONS => {
+			'EOProduction' => 196,
+			"|" => 133
+		}
+	},
+	{#State 188
+		ACTIONS => {
+			'EOProduction' => 197,
+			"|" => 133
+		}
+	},
+	{#State 189
+		ACTIONS => {
+			'EOProduction' => 198,
+			"|" => 175
+		}
+	},
+	{#State 190
+		DEFAULT => -53,
+		GOTOS => {
+			'@3-4' => 199
+		}
+	},
+	{#State 191
+		ACTIONS => {
+			'LITERAL' => 165
+		},
+		GOTOS => {
+			'lRangeElem' => 200
+		}
+	},
+	{#State 192
+		DEFAULT => -58
+	},
+	{#State 193
+		ACTIONS => {
+			'LITERAL' => 165
+		},
+		DEFAULT => -56,
+		GOTOS => {
+			'lRangeElem' => 167,
+			'lRange' => 192
+		}
+	},
+	{#State 194
+		DEFAULT => -30
+	},
+	{#State 195
+		DEFAULT => -128,
+		GOTOS => {
+			'@15-4' => 201
+		}
+	},
+	{#State 196
+		DEFAULT => -84,
+		GOTOS => {
+			'@13-6' => 202
+		}
+	},
+	{#State 197
+		DEFAULT => -81,
+		GOTOS => {
+			'@11-6' => 203
+		}
+	},
+	{#State 198
+		DEFAULT => -22,
+		GOTOS => {
+			'@1-9' => 204
+		}
+	},
+	{#State 199
+		DEFAULT => -54
+	},
+	{#State 200
+		DEFAULT => -60
+	},
+	{#State 201
+		DEFAULT => -129
+	},
+	{#State 202
+		DEFAULT => -85
+	},
+	{#State 203
+		DEFAULT => -82
+	},
+	{#State 204
+		DEFAULT => -23
+	}
+],
+                                  yyrules  =>
+[
+	[#Rule 0
+		 '$start', 2, undef
+	],
+	[#Rule 1
+		 'yapp', 3,
+sub
+#line 31 "YaccParser.yp"
+{   my ($self, $head, $body, $tail) = @_;
+    return new W3C::Grammar::YaccCompileTree::Grammar($head, $body, $tail, $self->YYData->{NoIntegrityCheck}, $self);
+}
+	],
+	[#Rule 2
+		 'symbol', 1,
+sub
+#line 40 "YaccParser.yp"
+{   my ($self, $literalInfo) = @_;
+    my ($literal, $lineNo) = ($literalInfo->getToken(), $literalInfo->getLineNo());
+    if (!exists($self->YYData->{Symbols}{$literal})) {
+	$self->YYData->{Symbols}{$literal} = $lineNo;
+	$Terminals->{$literal} = undef;
+    }
+    return $literalInfo;
+}
+	],
+	[#Rule 3
+		 'symbol', 1, undef
+	],
+	[#Rule 4
+		 'ident', 1,
+sub
+#line 53 "YaccParser.yp"
+{   my ($self, $idenifierInfo) = @_;
+    my ($identifier, $lineNo) = ($idenifierInfo->getToken(), $idenifierInfo->getLineNo());
+    if (!exists($self->YYData->{Symbols}{$identifier})) {
+	$self->YYData->{Symbols}{$identifier} = $lineNo;
+	$Terminals->{$identifier} = undef;
+    }
+    return $idenifierInfo;
+}
+	],
+	[#Rule 5
+		 'head', 2,
+sub
+#line 67 "YaccParser.yp"
+{   my ($self, $headsec) = @_;
+    return $headsec;
+}
+	],
+	[#Rule 6
+		 'headsec', 0,
+sub
+#line 74 "YaccParser.yp"
+{   []}
+	],
+	[#Rule 7
+		 'headsec', 1, undef
+	],
+	[#Rule 8
+		 'decls', 2,
+sub
+#line 80 "YaccParser.yp"
+{   my ($self, $decls, $decl) = @_;
+    return [@$decls, $decl];
+}
+	],
+	[#Rule 9
+		 'decls', 1,
+sub
+#line 84 "YaccParser.yp"
+{   my ($self, $decl) = @_;
+    return [$decl];
+}
+	],
+	[#Rule 10
+		 'CMNTS', 0,
+sub
+#line 91 "YaccParser.yp"
+{   []}
+	],
+	[#Rule 11
+		 'CMNTS', 2,
+sub
+#line 93 "YaccParser.yp"
+{   my ($self, $cmnts, $comment) = @_;
+    return [ @$cmnts, $comment ];
+}
+	],
+	[#Rule 12
+		 'decl', 1, undef
+	],
+	[#Rule 13
+		 'decl', 1, undef
+	],
+	[#Rule 14
+		 'decl', 5,
+sub
+#line 103 "YaccParser.yp"
+{   my ($self, $tokenInfo, $typedecl, $symlist, $comments) = @_;
+    for (@$symlist) {
+	my($symbol, $lineno)=@$_;
+	if (exists $Token->{$symbol}) {
+	    _SyntaxError(0,
+			 "Token $symbol redefined: ".
+			 "Previously defined line $self->YYData->{Symbols}{$symbol}",
+			 $lineno);
+	    next;
+	}
+	$Token->{$symbol}=$lineno;
+	$Terminals->{$symbol} = [ ];
+    }
+    return new W3C::Grammar::YaccCompileTree::TokenDecl($tokenInfo, $typedecl, $symlist, $comments, $self);
+}
+	],
+	[#Rule 15
+		 'decl', 5,
+sub
+#line 119 "YaccParser.yp"
+{   my ($self, $assocInfo, $typedecl, $symlist, $comments) = @_;
+    for (@$symlist) {
+	my($symbol, $lineno)=@$_;
+	if (defined $Terminals->{$symbol}[0]) {
+	    _SyntaxError(1,
+			 "Precedence for symbol $symbol redefined: ".
+			 "Previously defined line $self->YYData->{Symbols}{$symbol}",
+			 $lineno);
+	    next;
+	}
+	my ($assoc, $lineNoXXX) = @$assocInfo;
+	$Token->{$symbol} = $lineno;
+	$Terminals->{$symbol} = [ $assoc, $prec ];
+    }
+    ++$prec;
+    return new W3C::Grammar::YaccCompileTree::AssocDecl($assocInfo, $typedecl, $symlist, $comments, $self);
+}
+	],
+	[#Rule 16
+		 'decl', 3,
+sub
+#line 137 "YaccParser.yp"
+{   my ($self, $startInfo, $identInfo, undef) = @_;
+    my ($foo, $bar) = @$identInfo;
+    $start=$foo;
+    return $identInfo;
+}
+	],
+	[#Rule 17
+		 'decl', 2,
+sub
+#line 143 "YaccParser.yp"
+{   my ($self, $headcode, undef) = @_;
+    push(@$head, $start);
+    return $headcode;
+}
+	],
+	[#Rule 18
+		 'decl', 3,
+sub
+#line 148 "YaccParser.yp"
+{   return undef; #ignore
+}
+	],
+	[#Rule 19
+		 'decl', 4,
+sub
+#line 154 "YaccParser.yp"
+{   my ($self, $type, $typedecl, $identlist, undef) = @_;
+    for ( @$identlist ) {
+	my($symbol,$lineno)=@$_;
+	if (exists $NonTerminals->{$symbol}) {
+	    _SyntaxError(0,
+			 "Non-terminal $symbol redefined: ".
+			 "Previously defined line $self->YYData->{Symbols}{$symbol}",
+			 $lineno);
+	    next;
+	}
+	delete $Terminals->{$symbol};   #not a terminal
+	$NonTerminals->{$symbol} = undef;    #is a non-terminal
+    }
+}
+	],
+	[#Rule 20
+		 'decl', 3,
+sub
+#line 169 "YaccParser.yp"
+{   my ($self, $expect, $numberInfo) = @_;
+    my ($number, $lineNo) = @$numberInfo;
+    $expect=$number;
+    return undef;
+}
+	],
+	[#Rule 21
+		 'decl', 2,
+sub
+#line 175 "YaccParser.yp"
+{   my ($self, $error, undef) = @_;
+    $self->YYErrok;
+}
+	],
+	[#Rule 22
+		 '@1-9', 0,
+sub
+#line 178 "YaccParser.yp"
+{$NoSemiNeeded = 0;}
+	],
+	[#Rule 23
+		 'decl', 10,
+sub
+#line 179 "YaccParser.yp"
+{   my ($self, undef, $ordinal, undef, $identInfo, undef, undef, undef, $rhss, undef, undef) = @_;
+    return new W3C::Grammar::YaccCompileTree::LexGoal($identInfo, $rhss, $self);
+}
+	],
+	[#Rule 24
+		 'typedecl', 0, undef
+	],
+	[#Rule 25
+		 'typedecl', 3, undef
+	],
+	[#Rule 26
+		 'symlist', 2,
+sub
+#line 191 "YaccParser.yp"
+{   my ($self, $symlist, $symbol) = @_;
+    push(@$symlist,$symbol);
+    return $symlist;
+}
+	],
+	[#Rule 27
+		 'symlist', 1,
+sub
+#line 196 "YaccParser.yp"
+{   my ($self, $symbol) = @_;
+    return [ $symbol ];
+}
+	],
+	[#Rule 28
+		 'identlist', 2,
+sub
+#line 204 "YaccParser.yp"
+{   my ($self, $identlist, $ident) = @_;
+    push(@$identlist, $ident);
+    return $identlist;
+}
+	],
+	[#Rule 29
+		 'identlist', 1,
+sub
+#line 210 "YaccParser.yp"
+{   my ($self, $ident) = @_;
+    return [ $ident ];
+}
+	],
+	[#Rule 30
+		 'lrhss', 3,
+sub
+#line 218 "YaccParser.yp"
+{   my ($self, $rhss, undef, $rule) = @_;
+    return W3C::Grammar::YaccCompileTree::LDisjunction::addRightBranch($rhss, $rule, $self);
+}
+	],
+	[#Rule 31
+		 'lrhss', 1, undef
+	],
+	[#Rule 32
+		 'lrule', 1,
+sub
+#line 226 "YaccParser.yp"
+{   my ($self, $rhs) = @_;
+    my $code = undef;
+
+    if (defined $rhs && 0 &&	# !!! Disabled code
+	$rhs->[-1]->isa('W3C::Grammar::YaccCompileTree::Code')) {
+	$code = (pop (@$rhs))->getCode();
+    }
+
+    return new W3C::Grammar::YaccCompileTree::LRule($rhs, undef, $code, $self);
+}
+	],
+	[#Rule 33
+		 'lrhs', 0, undef
+	],
+	[#Rule 34
+		 'lrhs', 1, undef
+	],
+	[#Rule 35
+		 'lrhselts', 1, undef
+	],
+	[#Rule 36
+		 'lrhselts', 2,
+sub
+#line 246 "YaccParser.yp"
+{   my ($self, $rhselt, $rhselts) = @_;
+    return new W3C::Grammar::YaccCompileTree::LSequence($rhselt, $rhselts, $self);
+}
+	],
+	[#Rule 37
+		 'lrhselt', 1, undef
+	],
+	[#Rule 38
+		 'lrhselt', 1,
+sub
+#line 254 "YaccParser.yp"
+{   my ($self, $code) = @_;
+    return new W3C::Grammar::YaccCompileTree::Code($code, $self);
+}
+	],
+	[#Rule 39
+		 'lrhselt', 1, undef
+	],
+	[#Rule 40
+		 'lmodifiedelt', 1, undef
+	],
+	[#Rule 41
+		 'lmodifiedelt', 2,
+sub
+#line 264 "YaccParser.yp"
+{   my ($self, $elt, $marker) = @_;
+    return new W3C::Grammar::YaccCompileTree::Star($elt, $marker, $self);
+}
+	],
+	[#Rule 42
+		 'lmodifiedelt', 2,
+sub
+#line 268 "YaccParser.yp"
+{   my ($self, $elt, $marker) = @_;
+    return new W3C::Grammar::YaccCompileTree::Opt($elt, $marker, $self);
+}
+	],
+	[#Rule 43
+		 'lmodifiedelt', 2,
+sub
+#line 272 "YaccParser.yp"
+{   my ($self, $elt, $marker) = @_;
+    return new W3C::Grammar::YaccCompileTree::Plus($elt, $marker, $self);
+}
+	],
+	[#Rule 44
+		 'lmodifiableelt', 1, undef
+	],
+	[#Rule 45
+		 'lmodifiableelt', 3,
+sub
+#line 281 "YaccParser.yp"
+{   my ($self, $open, $rhselts, undef) = @_;
+    return UNIVERSAL::isa($rhselts, 'W3C::Grammar::YaccCompileTree::Set') ? 
+    new W3C::Grammar::YaccCompileTree::LGroup($open, $rhselts, $self) : 
+    $rhselts;
+}
+	],
+	[#Rule 46
+		 'lmodifiableelt', 2,
+sub
+#line 287 "YaccParser.yp"
+{   my ($self, undef, $lookAhead) = @_;
+    return new W3C::Grammar::YaccCompileTree::LookAhead($lookAhead, $self);
+}
+	],
+	[#Rule 47
+		 'resolvableelt1', 1, undef
+	],
+	[#Rule 48
+		 'resolvableelt1', 3,
+sub
+#line 295 "YaccParser.yp"
+{   my ($self, $resolvableelt, undef, $lrhselts) = @_;
+    $resolvableelt->excludeRange($lrhselts);
+    return $resolvableelt;
+}
+	],
+	[#Rule 49
+		 'resolvableelt', 1,
+sub
+#line 303 "YaccParser.yp"
+{   my ($self, $symbol) = @_;
+    return new W3C::Grammar::YaccCompileTree::LSymb($symbol, $self);
+}
+	],
+	[#Rule 50
+		 'resolvableelt', 1,
+sub
+#line 307 "YaccParser.yp"
+{   my ($self, $terminal) = @_;
+    return new W3C::Grammar::YaccCompileTree::LSymb($terminal, $self);
+}
+	],
+	[#Rule 51
+		 'resolvableelt', 1,
+sub
+#line 311 "YaccParser.yp"
+{   my ($self, $terminal) = @_;
+    return new W3C::Grammar::YaccCompileTree::LSymb($terminal, $self);
+}
+	],
+	[#Rule 52
+		 '@2-1', 0,
+sub
+#line 314 "YaccParser.yp"
+{ $CharClass = 0; }
+	],
+	[#Rule 53
+		 '@3-4', 0,
+sub
+#line 314 "YaccParser.yp"
+{ $CharClass = undef; }
+	],
+	[#Rule 54
+		 'resolvableelt', 5,
+sub
+#line 315 "YaccParser.yp"
+{   my ($self, undef, undef, $charclass, undef, undef) = @_;
+    return $charclass;
+}
+	],
+	[#Rule 55
+		 'charclass', 1,
+sub
+#line 322 "YaccParser.yp"
+{   my ($self, $lrangeList) = @_;
+    return new W3C::Grammar::YaccCompileTree::CharacterClass($lrangeList, 0, $self);
+}
+	],
+	[#Rule 56
+		 'charclass', 2,
+sub
+#line 326 "YaccParser.yp"
+{   my ($self, undef, $lrangeList) = @_;
+    return new W3C::Grammar::YaccCompileTree::CharacterClass($lrangeList, 1, $self);
+}
+	],
+	[#Rule 57
+		 'lrangeList', 1, undef
+	],
+	[#Rule 58
+		 'lrangeList', 2,
+sub
+#line 342 "YaccParser.yp"
+{   my ($self, $list, $lRange) = @_;
+    return new W3C::Grammar::YaccCompileTree::List($list, $lRange, $self);
+}
+	],
+	[#Rule 59
+		 'lRange', 1, undef
+	],
+	[#Rule 60
+		 'lRange', 3,
+sub
+#line 350 "YaccParser.yp"
+{   my ($self, $list, undef, $lRange) = @_;
+    return new W3C::Grammar::YaccCompileTree::Range($list, $lRange, $self);
+}
+	],
+	[#Rule 61
+		 'lRangeElem', 1,
+sub
+#line 357 "YaccParser.yp"
+{   my ($self, $symbol) = @_;
+    return new W3C::Grammar::YaccCompileTree::LSymb($symbol, $self);
+}
+	],
+	[#Rule 62
+		 'body', 4,
+sub
+#line 365 "YaccParser.yp"
+{   my ($self, $rulesec, undef, $termsec, undef) = @_;
+    if (!$start) {
+	$start = $rules->[1][0];
+    }
+
+    if (ref $NonTerminals->{$start}) {
+    } else {
+	_SyntaxError(2,"Start symbol $start not found ".
+		     "in rules section",$_[2][1]);
+	$rules->[0]=[ '$start', [ $start, chr(0) ], undef, undef ];
+    }
+    return [@$rulesec, @$termsec];
+}
+	],
+	[#Rule 63
+		 'body', 2,
+sub
+#line 379 "YaccParser.yp"
+{   my ($self, $rulesec, undef) = @_;
+    if (!$start) {
+	$start = $rules->[1][0];
+    }
+
+    if (ref $NonTerminals->{$start}) {
+    } else {
+	_SyntaxError(2,"Start symbol $start not found ".
+		     "in rules section",$_[2][1]);
+	$rules->[0]=[ '$start', [ $start, chr(0) ], undef, undef ];
+    }
+    return $rulesec;
+}
+	],
+	[#Rule 64
+		 'body', 1,
+sub
+#line 393 "YaccParser.yp"
+{
+    _SyntaxError(2,"No rules in input grammar",$_[1][1]);
+}
+	],
+	[#Rule 65
+		 'rulesec', 2,
+sub
+#line 400 "YaccParser.yp"
+{   my ($self, $rulesec, $rules) = @_;
+    return [ @$rulesec, $rules ];
+}
+	],
+	[#Rule 66
+		 'rulesec', 1,
+sub
+#line 404 "YaccParser.yp"
+{   my ($self, $rules) = @_;
+    return [ $rules ];
+}
+	],
+	[#Rule 67
+		 '@4-3', 0,
+sub
+#line 410 "YaccParser.yp"
+{$NoSemiNeeded = 1;}
+	],
+	[#Rule 68
+		 '@5-6', 0,
+sub
+#line 410 "YaccParser.yp"
+{$NoSemiNeeded = 0;}
+	],
+	[#Rule 69
+		 'rules', 7,
+sub
+#line 411 "YaccParser.yp"
+{   my ($self, undef, $identInfo, undef, undef, $rhss, undef) = @_;
+    return new W3C::Grammar::YaccCompileTree::Production($identInfo, $rhss, $self);
+}
+	],
+	[#Rule 70
+		 '@6-3', 0,
+sub
+#line 414 "YaccParser.yp"
+{$NoSemiNeeded = 1;}
+	],
+	[#Rule 71
+		 '@7-6', 0,
+sub
+#line 414 "YaccParser.yp"
+{$NoSemiNeeded = 0;}
+	],
+	[#Rule 72
+		 'rules', 7,
+sub
+#line 415 "YaccParser.yp"
+{   my ($self, undef, $identInfo, undef, undef, $rhss, undef, undef) = @_; # lrhss
+    return new W3C::Grammar::YaccCompileTree::LexGoal($identInfo, $rhss, $self);
+}
+	],
+	[#Rule 73
+		 '@8-3', 0,
+sub
+#line 418 "YaccParser.yp"
+{$NoSemiNeeded = 1;}
+	],
+	[#Rule 74
+		 '@9-6', 0,
+sub
+#line 418 "YaccParser.yp"
+{$NoSemiNeeded = 0;}
+	],
+	[#Rule 75
+		 'rules', 7,
+sub
+#line 419 "YaccParser.yp"
+{   my ($self, undef, $identInfo, undef, undef, $rhss, undef) = @_;
+    $identInfo->setTerminal(1);
+    return new W3C::Grammar::YaccCompileTree::Pass($identInfo, $rhss, $self);
+}
+	],
+	[#Rule 76
+		 'rules', 1, undef
+	],
+	[#Rule 77
+		 'rules', 2,
+sub
+#line 425 "YaccParser.yp"
+{   my ($self) = @_;
+    $_[0]->YYErrok;
+}
+	],
+	[#Rule 78
+		 'termsec', 2,
+sub
+#line 432 "YaccParser.yp"
+{   my ($self, $termsec, $terms) = @_;
+    return [ @$termsec, $terms ];
+}
+	],
+	[#Rule 79
+		 'termsec', 1,
+sub
+#line 436 "YaccParser.yp"
+{   my ($self, $terms) = @_;
+    return [ $terms ];
+}
+	],
+	[#Rule 80
+		 '@10-3', 0,
+sub
+#line 442 "YaccParser.yp"
+{$NoSemiNeeded = 1;}
+	],
+	[#Rule 81
+		 '@11-6', 0,
+sub
+#line 442 "YaccParser.yp"
+{$NoSemiNeeded = 0;}
+	],
+	[#Rule 82
+		 'terms', 7,
+sub
+#line 443 "YaccParser.yp"
+{   my ($self, undef, $identInfo, undef, undef, $rhss, undef) = @_;
+    $identInfo->setTerminal(1);
+    return new W3C::Grammar::YaccCompileTree::LexGoal($identInfo, $rhss, $self);
+}
+	],
+	[#Rule 83
+		 '@12-3', 0,
+sub
+#line 447 "YaccParser.yp"
+{$NoSemiNeeded = 1;}
+	],
+	[#Rule 84
+		 '@13-6', 0,
+sub
+#line 447 "YaccParser.yp"
+{$NoSemiNeeded = 0;}
+	],
+	[#Rule 85
+		 'terms', 7,
+sub
+#line 448 "YaccParser.yp"
+{   my ($self, undef, $identInfo, undef, undef, $rhss, undef) = @_;
+    $identInfo->setTerminal(1);
+    return new W3C::Grammar::YaccCompileTree::Pass($identInfo, $rhss, $self);
+}
+	],
+	[#Rule 86
+		 'terms', 1, undef
+	],
+	[#Rule 87
+		 'terms', 2,
+sub
+#line 454 "YaccParser.yp"
+{   my ($self) = @_;
+    $_[0]->YYErrok;
+}
+	],
+	[#Rule 88
+		 'ordinalOpt', 0, undef
+	],
+	[#Rule 89
+		 'ordinalOpt', 3, undef
+	],
+	[#Rule 90
+		 'ordinal', 0, undef
+	],
+	[#Rule 91
+		 'ordinal', 1, undef
+	],
+	[#Rule 92
+		 'ordinal', 2, undef
+	],
+	[#Rule 93
+		 'ruleMarker', 1, undef
+	],
+	[#Rule 94
+		 'ruleMarker', 3, undef
+	],
+	[#Rule 95
+		 'rhss', 3,
+sub
+#line 477 "YaccParser.yp"
+{   my ($self, $rhss, undef, $rule) = @_;
+    return W3C::Grammar::YaccCompileTree::Disjunction::addRightBranch($rhss, $rule, $self);
+}
+	],
+	[#Rule 96
+		 'rhss', 1, undef
+	],
+	[#Rule 97
+		 'termrhss', 3,
+sub
+#line 485 "YaccParser.yp"
+{   my ($self, $rhss, undef, $rule) = @_;
+    return W3C::Grammar::YaccCompileTree::LDisjunction::addRightBranch($rhss, $rule, $self);
+}
+	],
+	[#Rule 98
+		 'termrhss', 1, undef
+	],
+	[#Rule 99
+		 'rule', 3,
+sub
+#line 493 "YaccParser.yp"
+{   my ($self, $rhs, $prec, $epscode) = @_;
+    return new W3C::Grammar::YaccCompileTree::Rule($rhs, $prec, $epscode, $self);
+}
+	],
+	[#Rule 100
+		 'rule', 1,
+sub
+#line 497 "YaccParser.yp"
+{   my ($self, $rhs) = @_;
+    my $code = undef;
+
+    if (defined $rhs && 0 &&	# !!! Disabled code
+	$rhs->[-1]->isa('W3C::Grammar::YaccCompileTree::Code')) {
+	$code = (pop (@$rhs))->getCode();
+    }
+
+    return UNIVERSAL::isa($rhs, 'W3C::Grammar::YaccCompileTree::Set') ? 
+      new W3C::Grammar::YaccCompileTree::Rule($rhs, undef, $code, $self) : 
+	$rhs;
+}
+	],
+	[#Rule 101
+		 'termrule', 3,
+sub
+#line 513 "YaccParser.yp"
+{   my ($self, $rhs, $prec, $epscode) = @_;
+    return new W3C::Grammar::YaccCompileTree::Rule($rhs, $prec, $epscode, $self);
+}
+	],
+	[#Rule 102
+		 'termrule', 1,
+sub
+#line 517 "YaccParser.yp"
+{   my ($self, $rhs) = @_;
+    my $code = undef;
+
+    if (defined $rhs && 0 &&	# !!! Disabled code
+	$rhs->[-1]->isa('W3C::Grammar::YaccCompileTree::Code')) {
+	$code = (pop (@$rhs))->getCode();
+    }
+
+    return new W3C::Grammar::YaccCompileTree::Rule($rhs, undef, $code, $self);
+}
+	],
+	[#Rule 103
+		 'rhs', 0, undef
+	],
+	[#Rule 104
+		 'rhs', 1, undef
+	],
+	[#Rule 105
+		 'termrhs', 0, undef
+	],
+	[#Rule 106
+		 'termrhs', 1, undef
+	],
+	[#Rule 107
+		 'rhselts', 2,
+sub
+#line 541 "YaccParser.yp"
+{   my ($self, $rhselt, $rhselts) = @_;
+    return new W3C::Grammar::YaccCompileTree::Sequence($rhselt, $rhselts, $self);
+}
+	],
+	[#Rule 108
+		 'rhselts', 1, undef
+	],
+	[#Rule 109
+		 'termrhselts', 2,
+sub
+#line 549 "YaccParser.yp"
+{   my ($self, $rhselt, $rhselts) = @_;
+    return new W3C::Grammar::YaccCompileTree::Sequence($rhselt, $rhselts, $self);
+}
+	],
+	[#Rule 110
+		 'termrhselts', 1, undef
+	],
+	[#Rule 111
+		 'rhselt', 1, undef
+	],
+	[#Rule 112
+		 'rhselt', 1,
+sub
+#line 558 "YaccParser.yp"
+{   my ($self, $code) = @_;
+    return new W3C::Grammar::YaccCompileTree::Code($code, $self);
+}
+	],
+	[#Rule 113
+		 'rhselt', 1, undef
+	],
+	[#Rule 114
+		 'termrhselt', 1, undef
+	],
+	[#Rule 115
+		 'termrhselt', 1, undef
+	],
+	[#Rule 116
+		 'modifiedelt', 1, undef
+	],
+	[#Rule 117
+		 'modifiedelt', 2,
+sub
+#line 572 "YaccParser.yp"
+{   my ($self, $elt, $marker) = @_;
+    return new W3C::Grammar::YaccCompileTree::Star($elt, $marker, $self);
+}
+	],
+	[#Rule 118
+		 'modifiedelt', 2,
+sub
+#line 576 "YaccParser.yp"
+{   my ($self, $elt, $marker) = @_;
+    return new W3C::Grammar::YaccCompileTree::Opt($elt, $marker, $self);
+}
+	],
+	[#Rule 119
+		 'modifiedelt', 2,
+sub
+#line 580 "YaccParser.yp"
+{   my ($self, $elt, $marker) = @_;
+    return new W3C::Grammar::YaccCompileTree::Plus($elt, $marker, $self);
+}
+	],
+	[#Rule 120
+		 'termmodifiedelt', 1, undef
+	],
+	[#Rule 121
+		 'termmodifiedelt', 2,
+sub
+#line 588 "YaccParser.yp"
+{   my ($self, $elt, $marker) = @_;
+    return new W3C::Grammar::YaccCompileTree::Star($elt, $marker, $self);
+}
+	],
+	[#Rule 122
+		 'termmodifiedelt', 2,
+sub
+#line 592 "YaccParser.yp"
+{   my ($self, $elt, $marker) = @_;
+    return new W3C::Grammar::YaccCompileTree::Opt($elt, $marker, $self);
+}
+	],
+	[#Rule 123
+		 'termmodifiedelt', 2,
+sub
+#line 596 "YaccParser.yp"
+{   my ($self, $elt, $marker) = @_;
+    return new W3C::Grammar::YaccCompileTree::Plus($elt, $marker, $self);
+}
+	],
+	[#Rule 124
+		 'modifiableelt', 1,
+sub
+#line 603 "YaccParser.yp"
+{   my ($self, $symbol) = @_;
+    return new W3C::Grammar::YaccCompileTree::Symb($symbol, $self);
+}
+	],
+	[#Rule 125
+		 'modifiableelt', 1,
+sub
+#line 607 "YaccParser.yp"
+{   my ($self, $terminal) = @_;
+    return new W3C::Grammar::YaccCompileTree::Symb($terminal, $self);
+}
+	],
+	[#Rule 126
+		 'modifiableelt', 3,
+sub
+#line 611 "YaccParser.yp"
+{   my ($self, $open, $rhselts, undef) = @_;
+    return UNIVERSAL::isa($rhselts, 'W3C::Grammar::YaccCompileTree::Set') ? 
+    new W3C::Grammar::YaccCompileTree::Group($open, $rhselts, $self) : 
+    $rhselts;
+}
+	],
+	[#Rule 127
+		 '@14-1', 0,
+sub
+#line 616 "YaccParser.yp"
+{ $CharClass = 0; }
+	],
+	[#Rule 128
+		 '@15-4', 0,
+sub
+#line 616 "YaccParser.yp"
+{ $CharClass = undef; }
+	],
+	[#Rule 129
+		 'modifiableelt', 5,
+sub
+#line 617 "YaccParser.yp"
+{   my ($self, $bracket, undef, $charclass, undef, undef) = @_;
+    my $charclassStr = $charclass->toString();
+    _SyntaxError(1, "character classes must only appear in a terminal (found $charclassStr)",
+		 $bracket->getLineNo());
+    return $charclass;
+}
+	],
+	[#Rule 130
+		 'modifiableelt', 2,
+sub
+#line 624 "YaccParser.yp"
+{   my ($self, $slash, $lookAhead) = @_;
+    my $lookAheadStr = $lookAhead->toString();
+    _SyntaxError(1, "lookahead must only appear in a terminal (found $lookAheadStr)",
+		 $slash->getLineNo());
+    return new W3C::Grammar::YaccCompileTree::LookAhead($lookAhead, $self);
+}
+	],
+	[#Rule 131
+		 'prec', 2,
+sub
+#line 634 "YaccParser.yp"
+{   my ($self, $prec, $symbol) = @_;
+    if (!defined $Terminals->{$_[2][0]}) {
+	_SyntaxError(1,"No precedence for symbol $_[2][0]",
+		     $_[2][1]);
+	return undef;
+    }
+
+    ++$$PrecedenceTerminals{$_[2][0]};
+    $Terminals->{$_[2][0]}[1];
+}
+	],
+	[#Rule 132
+		 'epscode', 0,
+sub
+#line 647 "YaccParser.yp"
+{   return undef;
+}
+	],
+	[#Rule 133
+		 'epscode', 1,
+sub
+#line 650 "YaccParser.yp"
+{   my ($self, $code) = @_;
+    return $code;
+}
+	],
+	[#Rule 134
+		 'code', 1,
+sub
+#line 657 "YaccParser.yp"
+{   my ($self, $code) = @_;
+    return $code;
+}
+	],
+	[#Rule 135
+		 'tail', 0, undef
+	],
+	[#Rule 136
+		 'tail', 1,
+sub
+#line 666 "YaccParser.yp"
+{   my ($self, $tailcode) = @_;
+    return $tail = $tailcode;
+}
+	]
+],
+                                  @_);
+    bless($self,$class);
+}
+
+#line 672 "YaccParser.yp"
+
+sub _Error {
+    my ($self, @parms) = @_;
+    my($value)=$self->YYCurval;
+
+    $self->YYData->{INPUT} = $$input;
+    $self->YYData->{my_LASTPOS} = pos $$input;
+    &throw(new W3C::Util::YappDriver::MesgYappContextException($self, @parms));
+    my($what)= $Token ? "input: '$$value[0]'" : "end of input";
+
+    _SyntaxError(1,"Unexpected $what",$$value[1]);
+}
+
+use constant SEC_head => 0;
+use constant SEC_body => 1;
+use constant SEC_tail => 2;
+
+sub _Lexer {
+    my ($self) = @_;
+
+    if ($self->YYData->{Fake} eq 'bodyTransition') {
+	$self->YYData->{Fake} = 'tailTransition';
+        ++$lexlevel;
+        return('%%', [ '%%', $lineno[0] ]);
+    }
+
+    #At EOF
+    if (pos($$input) >= length($$input)) {
+	if ($NoSemiNeeded) {
+	    $NoSemiNeeded = 0;
+	    return ('EOProduction', 'EOProduction')
+	}
+	if ($self->YYData->{Fake} eq 'tailTransition') {
+	    $self->YYData->{Fake} = '';
+	    ++$lexlevel;
+	    return('%%', [ '%%', $lineno[0] ]);
+	}
+
+	return('',[ undef, -1 ]);
+    }
+
+    #In Character Class
+    if (defined $CharClass) {
+	my $ret;
+	if ($CharClass == 0 && $$input =~ m/\G(\^)/gc) {
+	    $ret = ['CARROT' , new W3C::Grammar::YaccCompileTree::LLITERAL($1, $lineno[0], $self)];
+	} elsif ($$input =~ m/\G\#x([0-9A-Fa-f]+)/gc) {
+	    my $char = chr(hex($1));
+	    $ret = ['LITERAL' , new W3C::Grammar::YaccCompileTree::LLITERAL($char, $lineno[0], $self)];
+	} elsif ($$input =~ m/\G(\\.)/gc) {
+	    my $str = $1;
+	$str =~ s/\\\\/\\/g;
+	$str =~ s/\\\"/\"/g;
+	$str =~ s/\\r/\r/g;
+	$str =~ s/\\n/\n/g;
+	$str =~ s/\\t/\t/g;
+	    $ret = ['LITERAL' , new W3C::Grammar::YaccCompileTree::LLITERAL($str, $lineno[0], $self)];
+	} elsif ($$input =~ m/\G(\-)(?!\])/gc) {
+	    my $char = $1;
+	    $ret = ['RANGEOP' , new W3C::Grammar::YaccCompileTree::TOKEN($char, $lineno[0], $self)];
+	} elsif ($$input =~ m/\G(\])/gc) {
+	    my $char = $1;
+	    $ret = [']' , new W3C::Grammar::YaccCompileTree::TOKEN($char, $lineno[0], $self)];
+	} elsif ($$input =~ m/\G(.)/gc) {
+	    my $char = $1;
+	    $ret = ['LITERAL' , new W3C::Grammar::YaccCompileTree::LLITERAL($char, $lineno[0], $self)];
+	} else {
+	    $self->_Error(-errorMessage => "unexpected end of input in character class");
+	}
+	$CharClass++;
+	return @$ret;
+    }
+
+    #In a LEX decl
+    if ($LexMode) {
+	$$input =~ m/\G\s*/gc;
+	return _LexLexer($input, undef);
+    }
+
+    #In TAIL section
+    if ($lexlevel > SEC_body) {
+        my($pos)=pos($$input);
+
+        $lineno[0]=$lineno[1];
+        $lineno[1]=-1;
+        pos($$input)=length($$input);
+        return('TAILCODE', new W3C::Grammar::YaccCompileTree::TAILCODE(substr($$input, $pos), $lineno[0], $self));
+    }
+
+    # Handle COMMENTs and whitespace.
+    if ($NoSemiNeeded && ($lexlevel == SEC_head || $lexlevel == SEC_body) && $$input=~m{
+\G(\s+) (?= ((?:\[\d \s* [\d\w]*\]|/\*|\#(?![xX]?[0-9a-fA-F])))	# needs to include line feed in consumed \s+
+        | (?: (?: [A-Za-z_][A-Za-z0-9_]* )
+              | \< (?:[^\>]+) \>) \s*\:
+        | (?: %% )
+        | (?: \Z )
+        | (?= \@ ) )}xsgc) {
+        my ($blanks) = ($1);
+        $lineno[1]+= $blanks=~tr/\n//;
+	$lineno[0]=$lineno[1];
+	return('EOProduction', 'EOProduction');
+    } elsif ($$input=~m{\G((\s*)\#((?:[^x])[^\n]*))}xsgc) {
+	my ($blanks, $leadWS, $text) = ($1, $2, $3);
+        $lineno[1]+= $blanks=~tr/\n//;
+	$lineno[0]=$lineno[1];
+	return ('COMMENT', new W3C::Grammar::YaccCompileTree::PerlComment($leadWS, $text, $lineno[0], $self));
+    } elsif ($$input=~m{\G((\s*)/\*(.*?)\*/)}xsgc) {
+	my ($blanks, $leadWS, $text) = ($1, $2, $3);
+        $lineno[1]+= $blanks=~tr/\n//;
+	$lineno[0]=$lineno[1];
+	return ('COMMENT', new W3C::Grammar::YaccCompileTree::CComment($leadWS, $text, $lineno[0], $self));
+    } elsif ($lexlevel == SEC_head && $$input=~m{\G([\t\ ]+)}xsgc || 
+	     ($lexlevel != SEC_head || $NoSemiNeeded) && $$input=~m{\G(\s+)}xsgc) {
+        my ($blanks) = ($1);
+        $lineno[1]+= $blanks=~tr/\n//;
+
+        #Maybe now at EOF
+    if (pos($$input) >= length($$input)) {
+	if ($NoSemiNeeded) {
+	    $NoSemiNeeded = 0;
+	    return ('EOProduction', 'EOProduction')
+	}
+	if ($self->YYData->{Fake} eq 'tailTransition') {
+	    $self->YYData->{Fake} = '';
+	    ++$lexlevel;
+	    return('%%', [ '%%', $lineno[0] ]);
+	}
+
+	return('',[ undef, -1 ]);
+    }
+    }
+
+    $lineno[0]=$lineno[1];
+
+    if ($$input=~/\G\@terminals/gc) {
+	return('TERMINALS', new W3C::Grammar::YaccCompileTree::IDENT('', $lineno[0], $self));
+    }
+
+    if ($$input=~/\G\@pass/gc) {
+	return('PASS', new W3C::Grammar::YaccCompileTree::IDENT($PassedTokensName, $lineno[0], $self));
+    }
+
+    if ($$input=~/\G([A-Za-z_][A-Za-z0-9_]*)/gc) {
+	my $name = $1;
+	my $ident = $self->YYData->{KnownIdents}{$name};
+	if (!$ident) {
+	    $ident = new W3C::Grammar::YaccCompileTree::IDENT($name, $lineno[0], $self);
+	    $self->YYData->{KnownIdents}{$name} = $ident;
+	}
+	return('IDENT', $ident);
+    }
+
+    if ($$input=~/\G\'((?:[^\'\\]|\\\\|\\\'|\\)+?)\'/gc) {
+	if ($1 eq "'error'") {
+            _SyntaxError(0,"Literal 'error' ".
+			 "will be treated as error token",$lineno[0]);
+            return('IDENT', new W3C::Grammar::YaccCompileTree::IDENT('error', $lineno[0], $self));
+        }
+	my $str = $1;
+	$str =~ s/\\\\/\\/g;
+	$str =~ s/\\\"/\"/g; # @@@ forgiving mode
+	$str =~ s/\\\'/\'/g;
+	$str =~ s/\\r/\r/g; # @@@ forgiving mode
+	$str =~ s/\\n/\n/g; # @@@ forgiving mode
+	$str =~ s/\\t/\t/g; # @@@ forgiving mode
+        return('LITERAL', new W3C::Grammar::YaccCompileTree::LLITERAL($str, $lineno[0], $self));
+    }
+
+    if ($$input=~/\G\#x([0-9A-Fa-f]+)/gc) {
+	my $ch = chr(hex($1));
+        return('LITERAL', new W3C::Grammar::YaccCompileTree::LLITERAL($ch, $lineno[0], $self));
+    }
+
+    if ($$input=~/\G\"((?:[^\\\"]|(?:\\.))*)\"/gc) {
+	if ($1 eq "'error'") {
+            _SyntaxError(0,"Literal 'error' ".
+			 "will be treated as error token",$lineno[0]);
+            return('IDENT', new W3C::Grammar::YaccCompileTree::IDENT('error', $lineno[0], $self));
+        }
+	my $str = $1;
+	$str =~ s/\\\\/\\/g;
+	$str =~ s/\\\"/\"/g;
+	$str =~ s/\\\'/\'/g; # @@@ forgiving mode
+	$str =~ s/\\r/\r/g;
+	$str =~ s/\\n/\n/g;
+	$str =~ s/\\t/\t/g;
+        return('LITERAL', new W3C::Grammar::YaccCompileTree::LLITERAL($str, $lineno[0], $self));
+    }
+
+    if ($$input=~/\G\<([^\>]+)\>/gc) {
+	my $value = $1;
+	if ($value =~ m/\"/) {
+	    my $pieces = [];
+	    while ($value =~ /\G\"((?:[^\\\"]|(?:\\.))*)\"\s*/gc) {
+		my $str = $1;
+		$str =~ s/\\\\/\\/g;
+		$str =~ s/\\\"/\"/g;
+		$str =~ s/\\r/\r/g;
+		$str =~ s/\\n/\n/g;
+		$str =~ s/\\t/\t/g;
+		push (@$pieces, $str);
+	    }
+	    my $all = join(' ', @$pieces);
+	    return('LITERAL', new W3C::Grammar::YaccCompileTree::LLITERAL($all, $lineno[0], $self));
+	} elsif ($value eq "'error'") {
+            _SyntaxError(0,"Literal 'error' ".
+			 "will be treated as error token",$lineno[0]);
+            return('IDENT', new W3C::Grammar::YaccCompileTree::IDENT('error', $lineno[0], $self));
+        } else {
+	    return('TERMINAL', new W3C::Grammar::YaccCompileTree::Terminal($value, $lineno[0], $self));
+	}
+    }
+
+    if ($$input=~/\G(%%)/gc) {
+        ++$lexlevel;
+        return($1, [ $1, $lineno[0] ]);
+    }
+
+    if ($$input=~/\G{/gc) {
+        my($level,$from,$code);
+
+        $from=pos($$input);
+
+        $level=1;
+        while($$input=~/([{}])/gc) {
+	    if (substr($$input,pos($$input)-1,1) eq '\\') { #Quoted
+		next;
+	    }
+	    if ($level += ($1 eq '{' ? 1 : -1)) {
+	    } else {
+		last;
+	    }
+        }
+	if ($level) {
+	    _SyntaxError(2,"Unmatched { opened line $lineno[0]",-1);
+	}
+        $code = substr($$input,$from,pos($$input)-$from-1);
+        $lineno[1]+= $code=~tr/\n//;
+        return('CODE', new W3C::Grammar::YaccCompileTree::CODE($code, $lineno[0], $self));
+    }
+
+    if ($lexlevel == SEC_head) { # In head section
+	if ($$input=~/\G%(left|right|nonassoc)/gc) {
+	    return('ASSOC', new W3C::Grammar::YaccCompileTree::ASSOC($1, $lineno[0], $self));
+	}
+	if ($$input=~/\G%(start)/gc) {
+	    return('START', new W3C::Grammar::YaccCompileTree::START(undef, $lineno[0], $self));
+	}
+	if ($$input=~/\G%(expect)/gc) {
+	    return('EXPECT', new W3C::Grammar::YaccCompileTree::EXPECT(undef, $lineno[0], $self));
+	}
+	if ($$input=~/\G%{/gc) {
+	    my($code);
+
+	    if ($$input !~ /\G(.*?)%\}/sgc) {
+		_SyntaxError(2,"Unmatched %{ opened line $lineno[0]",-1);
+	    }
+
+	    $code=$1;
+	    $lineno[1]+= $code=~tr/\n//;
+	    return('HEADCODE', new W3C::Grammar::YaccCompileTree::HEADCODE($code, $lineno[0], $self));
+	}
+	if ($$input=~/\G%(token)/gc) {
+	    return('TOKEN', new W3C::Grammar::YaccCompileTree::TOKEN(undef, $lineno[0], $self));
+	}
+	if ($$input=~/\G%(type)/gc) {
+	    return('TYPE', new W3C::Grammar::YaccCompileTree::TYPE(undef, $lineno[0], $self));
+	}
+	if ($$input=~/\G%(union)/gc) {
+	    return('UNION', new W3C::Grammar::YaccCompileTree::UNION(undef, $lineno[0], $self));
+	}
+	if ($$input=~/\G([0-9]+)/gc) {
+	    return('NUMBER', new W3C::Grammar::YaccCompileTree::NUMBER($1, $lineno[0], $self));
+	}
+    } else {		# In rule section
+	if ($$input=~/\G%(prec)/gc) {
+	    return('PREC', new W3C::Grammar::YaccCompileTree::PREC(undef, $lineno[0], $self));
+	}
+	if ($$input=~/\G([0-9]+)/gc) { # added
+	    return('NUMBER', new W3C::Grammar::YaccCompileTree::NUMBER($1, $lineno[0], $self));
+	}
+    }
+
+    #Always return something
+    if ($$input !~ /\G(.)/sg) {
+	$self->_Error(-errorMessage => "matched no characters")
+    }
+    my $char = $1;
+
+    if ($NoSemiNeeded && $char eq ';') {
+	$NoSemiNeeded = 0;
+	return('EOProduction', 'EOProduction');
+    }
+
+    if ($char eq "\n") {
+	++$lineno[1];
+    }
+
+    return ( $char , new W3C::Grammar::YaccCompileTree::TokenBase($char, $lineno[0], $self));
+
+}
+
+sub _SyntaxError {
+    my($level,$message,$lineno)=@_;
+
+    $message= "*".
+#              [ 'Warning', 'Error', 'Fatal' ]->[$level].
+              "* $message, at ".
+              ($lineno < 0 ? "eof" : "line $lineno").
+              ".\n";
+
+    if ($level > 1) {
+	my $messagesStr = &getMessages();
+	die "$messagesStr\n*Fatal* $message";
+    }
+
+    push (@$Messages, [$level, $message]);
+
+    if ($level > 0) {
+	++$nberr;
+    }
+
+    if ($nberr == 20) {
+	my $messagesStr = &getMessages();
+	die "$messagesStr\n*Fatal* Too many errors detected.";
+    }
+}
+sub getLineNo {
+    return $lineno[0];
+}
+sub getMessages {
+    return join('', map {($_->[0] ? 'Error' : 'Warning').": $_->[1]"} @$Messages);
+}
+sub W3C::Grammar::YaccCompileTree::IDENT::_getProductionByName {
+    my ($self) = @_;
+    my $lhs = $self->getToken();
+    return $NonTerminals->{$lhs};
+}
+
+sub _AddRules {
+    my($self, $production) = @_;
+    my $lhs = $production->getIdent()->getToken();
+    my $lineno = $production->getIdent()->getLineNo();
+    my $rhss = (); # $production->getRules();
+    push(@$rules,[ $lhs, [ ], undef, undef ]);
+
+    if (ref($NonTerminals->{$lhs})) {
+	my $pref = $self->YYData->{Symbols}{$lhs};
+        _SyntaxError(1,"Non-terminal $lhs redefined: ".
+                       "Previously declared line $pref",$lineno);
+        return;
+    }
+
+    if (ref($Terminals->{$lhs})) {
+        my($where) = exists($Token->{$lhs}) ? $Token->{$lhs} : $self->YYData->{Symbols}{$lhs};
+        _SyntaxError(1,"Non-terminal $lhs previously ".
+		     "declared as token line $where",$lineno);
+        return;
+    }
+
+    if (ref($NonTerminals->{$lhs})) {      #declared through %type
+    } else {
+	$self->YYData->{Symbols}{$lhs} = $lineno;   #Say it's declared here
+	delete($Terminals->{$lhs});   #No more a terminal
+    }
+    $NonTerminals->{$lhs} = [];       #It's a non-terminal now
+
+    my($epsrules)=0;        #To issue a warning if more than one epsilon rule
+
+    for my $rhs1 (@$rhss) {
+	my $rhs = $rhs1->getRhs();
+	my $prec = $rhs1->getPrec();
+	my $code = $rhs1->getCode();
+        my($tmprule)=[ $lhs, [ ], $prec, $code ]; #Init rule
+
+	if (!@$rhs) {
+            ++$$nullable{$lhs};
+            ++$epsrules;
+        }
+
+        for (my $i = 0; $i < @$rhs; $i++) {
+	    my $ob = $rhs->[$i];
+	    if (!$ob->isa('W3C::Grammar::YaccCompileTree::Text')) {
+		if ($ob->isa('W3C::Grammar::YaccCompileTree::Code')) {
+		    my($name)='@'.++$labelno."-$i";
+		    push(@$rules,[ $name, [], undef, $ob ]);
+		    push(@{$$tmprule[1]},$name);
+		    next;
+		}
+		my $value = $ob->getValue();
+		push(@{$$tmprule[1]},$$value[0]);
+	    }
+        }
+        push(@$rules,$tmprule);
+        push(@{$NonTerminals->{$lhs}},$#$rules);
+    }
+
+    if ($epsrules > 1) {
+	_SyntaxError(0,"More than one empty rule for symbol $lhs",$lineno);
+    }
+    return $production;
+}
+
+sub Parse {
+    my ($self, $inputParm, $debug) = @_;
+
+    my($parsed)={};
+
+    $input=\$inputParm;
+
+    $lexlevel = SEC_head;
+    @lineno=(1,1);
+    $nberr=0;
+    $prec=0;
+    $labelno=0;
+
+    $head=();
+    $tail="";
+
+    $self->YYData->{Symbols} = {};
+    $self->YYData->{KnownIdents} = {};
+    $Token={};
+    $Terminals={};
+    $NonTerminals={};
+    $rules=[ undef ];   #reserve slot 0 for start rule
+    $PrecedenceTerminals={};
+
+    $start="";
+    $nullable={};
+    $expect=0;
+
+    pos($$input)=0;
+
+    $/ = undef;
+    my $ret = $self->YYParse(yylex => \&_Lexer, yyerror => \&_Error, yydebug => $debug);
+
+    if ($nberr) {
+	_SyntaxError(2,"Errors detected: No output",-1);
+    }
+
+    @$parsed{ 'HEAD', 'TAIL', 'RULES', 'NTERM', 'TERM',
+              'NULL', 'PREC', 'SYMS',  'START', 'EXPECT' }
+    =       (  $head,  $tail,  $rules,  $NonTerminals,  $Terminals,
+               $nullable, $PrecedenceTerminals, $self->YYData->{Symbols}, $start, $expect);
+    my $messages = [@$Messages];
+    $Messages = [];
+    undef($input);
+    undef($lexlevel);
+    undef(@lineno);
+    undef($nberr);
+    undef($prec);
+    undef($labelno);
+
+    undef($head);
+    undef($tail);
+
+    #undef($self->YYData->{Symbols});
+    undef($Token);
+    undef($Terminals);
+    undef($NonTerminals);
+    undef($rules);
+    undef($PrecedenceTerminals);
+
+    undef($start);
+    undef($nullable);
+    undef($expect);
+
+    return ($ret, $messages);
+    $parsed;
+}
+
+package W3C::Grammar::YaccParser;
+@W3C::Grammar::YaccParser::ISA = 'W3C::Grammar::_YaccParser';
+
+sub new {
+    my ($proto, $noIntegrityCheck, @yappParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@yappParms);
+    $self->YYData->{NoIntegrityCheck} = $noIntegrityCheck;
+    $self->YYData->{Fake} = '';
+    return $self;
+}
+
+sub fake {
+    my ($self, $fake) =@_;
+    $self->YYData->{Fake} = $fake;
+}
+
+sub setFilename {
+    my ($self, $filename) = @_;
+    $self->{Filename} = $filename;
+}
+
+sub getFilename {
+    my ($self) = @_;
+    return $self->{Filename};
+}
+
+
+1;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/YaccParser.yp	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,1177 @@
+# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
+# (c) Copyright Francois Desarmenien 1998-2001, all rights reserved.
+# (see COPYRIGHT in Parse::Yapp.pm pod section for use and distribution rights)
+#
+# Parse/Yapp/Parser.yp: Parse::Yapp::Parser.pm source file
+#
+# Use: yapp -m 'Parse::Yapp::Parse' -o Parse/Yapp/Parse.pm YappParse.yp
+#
+# to generate the Parser module.
+#
+
+%{
+require 5.004;
+
+use Carp;
+
+    use W3C::Util::Exception;
+    use W3C::Util::YappDriver;
+    use W3C::Grammar::YaccCompileTree qw($PassedTokensName);
+    #use W3C::Grammar::LexLexer;
+    @ISA= qw (W3C::Util::YappDriver);
+
+my($input,$lexlevel,$nberr,@lineno,$prec,$labelno);
+my($head,$tail,$Token,$Terminals,$NonTerminals,$rules,$PrecedenceTerminals,$start,$nullable);
+my($expect);
+my $NoSemiNeeded = 0;
+my $Messages = [];
+
+my $LexMode = 0; # not lexing lex
+my $CharClass = undef; # not lexing a character class
+
+%}
+
+%%
+
+# Main rule
+yapp:
+    head body tail
+{   my ($self, $head, $body, $tail) = @_;
+    return new W3C::Grammar::YaccCompileTree::Grammar($head, $body, $tail, $self->YYData->{NoIntegrityCheck}, $self);
+}
+;
+
+#Common rules:
+
+symbol:
+    LITERAL
+{   my ($self, $literalInfo) = @_;
+    my ($literal, $lineNo) = ($literalInfo->getToken(), $literalInfo->getLineNo());
+    if (!exists($self->YYData->{Symbols}{$literal})) {
+	$self->YYData->{Symbols}{$literal} = $lineNo;
+	$Terminals->{$literal} = undef;
+    }
+    return $literalInfo;
+}
+    |   ident   #default action
+;
+
+ident:
+    IDENT
+{   my ($self, $idenifierInfo) = @_;
+    my ($identifier, $lineNo) = ($idenifierInfo->getToken(), $idenifierInfo->getLineNo());
+    if (!exists($self->YYData->{Symbols}{$identifier})) {
+	$self->YYData->{Symbols}{$identifier} = $lineNo;
+	$Terminals->{$identifier} = undef;
+    }
+    return $idenifierInfo;
+}
+;
+
+
+# Head section:
+head:
+    headsec '%%'
+{   my ($self, $headsec) = @_;
+    return $headsec;
+}
+;
+
+headsec:
+    #empty  #default action
+{   []}
+    | decls   #default action
+;
+
+decls:
+    decls decl  #default action
+{   my ($self, $decls, $decl) = @_;
+    return [@$decls, $decl];
+}
+    | decl        #default action
+{   my ($self, $decl) = @_;
+    return [$decl];
+}
+;
+
+CMNTS:
+    # empty
+{   []}
+    | CMNTS COMMENT
+{   my ($self, $cmnts, $comment) = @_;
+    return [ @$cmnts, $comment ];
+}
+;
+
+decl:
+    '\n'                 #default action
+    | COMMENT
+#    | WHITESPACE
+    | TOKEN typedecl symlist CMNTS '\n'
+{   my ($self, $tokenInfo, $typedecl, $symlist, $comments) = @_;
+    for (@$symlist) {
+	my($symbol, $lineno)=@$_;
+	if (exists $Token->{$symbol}) {
+	    _SyntaxError(0,
+			 "Token $symbol redefined: ".
+			 "Previously defined line $self->YYData->{Symbols}{$symbol}",
+			 $lineno);
+	    next;
+	}
+	$Token->{$symbol}=$lineno;
+	$Terminals->{$symbol} = [ ];
+    }
+    return new W3C::Grammar::YaccCompileTree::TokenDecl($tokenInfo, $typedecl, $symlist, $comments, $self);
+}
+    | ASSOC typedecl symlist CMNTS '\n'  
+{   my ($self, $assocInfo, $typedecl, $symlist, $comments) = @_;
+    for (@$symlist) {
+	my($symbol, $lineno)=@$_;
+	if (defined $Terminals->{$symbol}[0]) {
+	    _SyntaxError(1,
+			 "Precedence for symbol $symbol redefined: ".
+			 "Previously defined line $self->YYData->{Symbols}{$symbol}",
+			 $lineno);
+	    next;
+	}
+	my ($assoc, $lineNoXXX) = @$assocInfo;
+	$Token->{$symbol} = $lineno;
+	$Terminals->{$symbol} = [ $assoc, $prec ];
+    }
+    ++$prec;
+    return new W3C::Grammar::YaccCompileTree::AssocDecl($assocInfo, $typedecl, $symlist, $comments, $self);
+}
+    | START ident '\n'
+{   my ($self, $startInfo, $identInfo, undef) = @_;
+    my ($foo, $bar) = @$identInfo;
+    $start=$foo;
+    return $identInfo;
+}
+    | HEADCODE '\n'
+{   my ($self, $headcode, undef) = @_;
+    push(@$head, $start);
+    return $headcode;
+}
+    | UNION CODE '\n'
+{   return undef; #ignore
+}
+#	decl -> TYPE . typedecl identlist '\n'
+#	decl -> TYPE typedecl . identlist '\n'
+#	decl -> TYPE typedecl identlist . '\n'
+    | TYPE typedecl identlist '\n'
+{   my ($self, $type, $typedecl, $identlist, undef) = @_;
+    for ( @$identlist ) {
+	my($symbol,$lineno)=@$_;
+	if (exists $NonTerminals->{$symbol}) {
+	    _SyntaxError(0,
+			 "Non-terminal $symbol redefined: ".
+			 "Previously defined line $self->YYData->{Symbols}{$symbol}",
+			 $lineno);
+	    next;
+	}
+	delete $Terminals->{$symbol};   #not a terminal
+	$NonTerminals->{$symbol} = undef;    #is a non-terminal
+    }
+}
+    | EXPECT NUMBER '\n'
+{   my ($self, $expect, $numberInfo) = @_;
+    my ($number, $lineNo) = @$numberInfo;
+    $expect=$number;
+    return undef;
+}
+    | error '\n'
+{   my ($self, $error, undef) = @_;
+    $self->YYErrok;
+}
+    | '[' ordinal ']' TERMINAL ':' ':' '=' lrhss EOProduction {$NoSemiNeeded = 0;}
+{   my ($self, undef, $ordinal, undef, $identInfo, undef, undef, undef, $rhss, undef, undef) = @_;
+    return new W3C::Grammar::YaccCompileTree::LexGoal($identInfo, $rhss, $self);
+}
+;
+
+typedecl:
+    #empty
+    | '<' IDENT '>'
+;
+
+symlist:
+    symlist symbol
+{   my ($self, $symlist, $symbol) = @_;
+    push(@$symlist,$symbol);
+    return $symlist;
+}
+    | symbol
+{   my ($self, $symbol) = @_;
+    return [ $symbol ];
+}
+;
+
+identlist:
+#	identlist -> identlist ident .
+    identlist ident
+{   my ($self, $identlist, $ident) = @_;
+    push(@$identlist, $ident);
+    return $identlist;
+}
+#	identlist -> ident .
+    | ident
+{   my ($self, $ident) = @_;
+    return [ $ident ];
+}
+;
+
+# Lex rules
+lrhss:
+    lrhss '|' lrule
+{   my ($self, $rhss, undef, $rule) = @_;
+    return W3C::Grammar::YaccCompileTree::LDisjunction::addRightBranch($rhss, $rule, $self);
+}
+    | lrule
+;
+
+lrule:
+    lrhs
+{   my ($self, $rhs) = @_;
+    my $code = undef;
+
+    if (defined $rhs && 0 &&	# !!! Disabled code
+	$rhs->[-1]->isa('W3C::Grammar::YaccCompileTree::Code')) {
+	$code = (pop (@$rhs))->getCode();
+    }
+
+    return new W3C::Grammar::YaccCompileTree::LRule($rhs, undef, $code, $self);
+}
+;
+
+lrhs:
+    #empty      #default action (will return undef)
+    | lrhselts     #default action
+;
+
+lrhselts:
+    lrhselt
+    | lrhselt lrhselts
+{   my ($self, $rhselt, $rhselts) = @_;
+    return new W3C::Grammar::YaccCompileTree::LSequence($rhselt, $rhselts, $self);
+}
+;
+
+lrhselt:
+    lmodifiedelt
+    | code
+{   my ($self, $code) = @_;
+    return new W3C::Grammar::YaccCompileTree::Code($code, $self);
+}
+    | COMMENT
+;
+
+
+lmodifiedelt:
+    lmodifiableelt
+    | lmodifiableelt '*'
+{   my ($self, $elt, $marker) = @_;
+    return new W3C::Grammar::YaccCompileTree::Star($elt, $marker, $self);
+}
+    | lmodifiableelt '?'
+{   my ($self, $elt, $marker) = @_;
+    return new W3C::Grammar::YaccCompileTree::Opt($elt, $marker, $self);
+}
+    | lmodifiableelt '+'
+{   my ($self, $elt, $marker) = @_;
+    return new W3C::Grammar::YaccCompileTree::Plus($elt, $marker, $self);
+}
+;
+
+lmodifiableelt:
+    resolvableelt1
+#    | '(' lrhsGroup ')'
+    | '(' lrhss ')'
+{   my ($self, $open, $rhselts, undef) = @_;
+    return UNIVERSAL::isa($rhselts, 'W3C::Grammar::YaccCompileTree::Set') ? 
+    new W3C::Grammar::YaccCompileTree::LGroup($open, $rhselts, $self) : 
+    $rhselts;
+}
+    | '/' lmodifiableelt
+{   my ($self, undef, $lookAhead) = @_;
+    return new W3C::Grammar::YaccCompileTree::LookAhead($lookAhead, $self);
+}
+;
+
+resolvableelt1:
+    resolvableelt
+    | resolvableelt1 '-' resolvableelt
+{   my ($self, $resolvableelt, undef, $lrhselts) = @_;
+    $resolvableelt->excludeRange($lrhselts);
+    return $resolvableelt;
+}
+;
+
+resolvableelt:
+    LITERAL
+{   my ($self, $symbol) = @_;
+    return new W3C::Grammar::YaccCompileTree::LSymb($symbol, $self);
+}
+    | IDENT
+{   my ($self, $terminal) = @_;
+    return new W3C::Grammar::YaccCompileTree::LSymb($terminal, $self);
+}
+    | TERMINAL
+{   my ($self, $terminal) = @_;
+    return new W3C::Grammar::YaccCompileTree::LSymb($terminal, $self);
+}
+    | '[' { $CharClass = 0; } charclass ']' { $CharClass = undef; }
+{   my ($self, undef, undef, $charclass, undef, undef) = @_;
+    return $charclass;
+}
+;
+
+charclass:
+    lrangeList
+{   my ($self, $lrangeList) = @_;
+    return new W3C::Grammar::YaccCompileTree::CharacterClass($lrangeList, 0, $self);
+}
+    | CARROT lrangeList
+{   my ($self, undef, $lrangeList) = @_;
+    return new W3C::Grammar::YaccCompileTree::CharacterClass($lrangeList, 1, $self);
+}
+;
+
+lrhsGroup:
+    lrhss '|' lrhs
+{   my ($self, $rhss, undef, $rule) = @_;
+    return W3C::Grammar::YaccCompileTree::LDisjunction::addRightBranch($rhss, $rule, $self);
+}
+    | lrhs
+;
+
+lrangeList:
+    lRange
+    | lrangeList  lRange
+{   my ($self, $list, $lRange) = @_;
+    return new W3C::Grammar::YaccCompileTree::List($list, $lRange, $self);
+}
+;
+
+lRange:
+    lRangeElem
+    | lRangeElem RANGEOP lRangeElem
+{   my ($self, $list, undef, $lRange) = @_;
+    return new W3C::Grammar::YaccCompileTree::Range($list, $lRange, $self);
+}
+;
+
+lRangeElem:
+    LITERAL
+{   my ($self, $symbol) = @_;
+    return new W3C::Grammar::YaccCompileTree::LSymb($symbol, $self);
+}
+;
+
+# Rule section
+body:
+    rulesec TERMINALS termsec '%%'
+{   my ($self, $rulesec, undef, $termsec, undef) = @_;
+    if (!$start) {
+	$start = $rules->[1][0];
+    }
+
+    if (ref $NonTerminals->{$start}) {
+    } else {
+	_SyntaxError(2,"Start symbol $start not found ".
+		     "in rules section",$_[2][1]);
+	$rules->[0]=[ '$start', [ $start, chr(0) ], undef, undef ];
+    }
+    return [@$rulesec, @$termsec];
+}
+    | rulesec '%%'
+{   my ($self, $rulesec, undef) = @_;
+    if (!$start) {
+	$start = $rules->[1][0];
+    }
+
+    if (ref $NonTerminals->{$start}) {
+    } else {
+	_SyntaxError(2,"Start symbol $start not found ".
+		     "in rules section",$_[2][1]);
+	$rules->[0]=[ '$start', [ $start, chr(0) ], undef, undef ];
+    }
+    return $rulesec;
+}
+    | '%%'
+{
+    _SyntaxError(2,"No rules in input grammar",$_[1][1]);
+}
+;
+
+rulesec:
+    rulesec rules
+{   my ($self, $rulesec, $rules) = @_;
+    return [ @$rulesec, $rules ];
+}
+    | rules         #default action
+{   my ($self, $rules) = @_;
+    return [ $rules ];
+}
+;
+
+rules:
+    ordinalOpt IDENT ruleMarker {$NoSemiNeeded = 1;} rhss EOProduction {$NoSemiNeeded = 0;}
+{   my ($self, undef, $identInfo, undef, undef, $rhss, undef) = @_;
+    return new W3C::Grammar::YaccCompileTree::Production($identInfo, $rhss, $self);
+}
+    | ordinalOpt TERMINAL ruleMarker {$NoSemiNeeded = 1;} termrhss EOProduction {$NoSemiNeeded = 0;}
+{   my ($self, undef, $identInfo, undef, undef, $rhss, undef, undef) = @_; # lrhss
+    return new W3C::Grammar::YaccCompileTree::LexGoal($identInfo, $rhss, $self);
+}
+    | ordinalOpt PASS ruleMarker {$NoSemiNeeded = 1;} termrhss EOProduction {$NoSemiNeeded = 0;}
+{   my ($self, undef, $identInfo, undef, undef, $rhss, undef) = @_;
+    $identInfo->setTerminal(1);
+    return new W3C::Grammar::YaccCompileTree::Pass($identInfo, $rhss, $self);
+}
+    | COMMENT
+    | error ';'
+{   my ($self) = @_;
+    $_[0]->YYErrok;
+}
+;
+
+termsec:
+    termsec terms
+{   my ($self, $termsec, $terms) = @_;
+    return [ @$termsec, $terms ];
+}
+    | terms         #default action
+{   my ($self, $terms) = @_;
+    return [ $terms ];
+}
+;
+
+terms:
+    ordinalOpt IDENT ruleMarker {$NoSemiNeeded = 1;} termrhss EOProduction {$NoSemiNeeded = 0;}
+{   my ($self, undef, $identInfo, undef, undef, $rhss, undef) = @_;
+    $identInfo->setTerminal(1);
+    return new W3C::Grammar::YaccCompileTree::LexGoal($identInfo, $rhss, $self);
+}
+    | ordinalOpt PASS ruleMarker {$NoSemiNeeded = 1;} termrhss EOProduction {$NoSemiNeeded = 0;}
+{   my ($self, undef, $identInfo, undef, undef, $rhss, undef) = @_;
+    $identInfo->setTerminal(1);
+    return new W3C::Grammar::YaccCompileTree::Pass($identInfo, $rhss, $self);
+}
+    | COMMENT
+    | error ';'
+{   my ($self) = @_;
+    $_[0]->YYErrok;
+}
+;
+
+ordinalOpt:
+    # empty
+    | '[' ordinal ']'
+;
+
+ordinal:
+    # empty
+    | NUMBER
+    | NUMBER IDENT
+;
+
+ruleMarker:
+    ':'
+    | ':' ':' '='
+;
+
+rhss:
+    rhss '|' rule
+{   my ($self, $rhss, undef, $rule) = @_;
+    return W3C::Grammar::YaccCompileTree::Disjunction::addRightBranch($rhss, $rule, $self);
+}
+    | rule
+;
+
+termrhss:
+    termrhss '|' termrule
+{   my ($self, $rhss, undef, $rule) = @_;
+    return W3C::Grammar::YaccCompileTree::LDisjunction::addRightBranch($rhss, $rule, $self);
+}
+    | termrule
+;
+
+rule:
+    rhs prec epscode
+{   my ($self, $rhs, $prec, $epscode) = @_;
+    return new W3C::Grammar::YaccCompileTree::Rule($rhs, $prec, $epscode, $self);
+}
+    | rhs
+{   my ($self, $rhs) = @_;
+    my $code = undef;
+
+    if (defined $rhs && 0 &&	# !!! Disabled code
+	$rhs->[-1]->isa('W3C::Grammar::YaccCompileTree::Code')) {
+	$code = (pop (@$rhs))->getCode();
+    }
+
+    return UNIVERSAL::isa($rhs, 'W3C::Grammar::YaccCompileTree::Set') ? 
+      new W3C::Grammar::YaccCompileTree::Rule($rhs, undef, $code, $self) : 
+	$rhs;
+}
+;
+
+termrule:
+    termrhs prec epscode
+{   my ($self, $rhs, $prec, $epscode) = @_;
+    return new W3C::Grammar::YaccCompileTree::Rule($rhs, $prec, $epscode, $self);
+}
+    | termrhs
+{   my ($self, $rhs) = @_;
+    my $code = undef;
+
+    if (defined $rhs && 0 &&	# !!! Disabled code
+	$rhs->[-1]->isa('W3C::Grammar::YaccCompileTree::Code')) {
+	$code = (pop (@$rhs))->getCode();
+    }
+
+    return new W3C::Grammar::YaccCompileTree::Rule($rhs, undef, $code, $self);
+}
+;
+
+rhs:
+    #empty      #default action (will return undef)
+    | rhselts     #default action
+;
+
+termrhs:
+    #empty      #default action (will return undef)
+    | termrhselts     #default action
+;
+
+rhselts:
+    rhselt rhselts
+{   my ($self, $rhselt, $rhselts) = @_;
+    return new W3C::Grammar::YaccCompileTree::Sequence($rhselt, $rhselts, $self);
+}
+    | rhselt
+;
+
+termrhselts:
+    termrhselt termrhselts
+{   my ($self, $rhselt, $rhselts) = @_;
+    return new W3C::Grammar::YaccCompileTree::Sequence($rhselt, $rhselts, $self);
+}
+    | termrhselt
+;
+
+rhselt:
+    modifiedelt
+    | code
+{   my ($self, $code) = @_;
+    return new W3C::Grammar::YaccCompileTree::Code($code, $self);
+}
+    | COMMENT
+;
+
+termrhselt:
+    termmodifiedelt
+    | COMMENT
+;
+
+modifiedelt:
+    modifiableelt
+    | modifiableelt '*'
+{   my ($self, $elt, $marker) = @_;
+    return new W3C::Grammar::YaccCompileTree::Star($elt, $marker, $self);
+}
+    | modifiableelt '?'
+{   my ($self, $elt, $marker) = @_;
+    return new W3C::Grammar::YaccCompileTree::Opt($elt, $marker, $self);
+}
+    | modifiableelt '+'
+{   my ($self, $elt, $marker) = @_;
+    return new W3C::Grammar::YaccCompileTree::Plus($elt, $marker, $self);
+}
+;
+
+termmodifiedelt:
+    lmodifiableelt
+    | lmodifiableelt '*'
+{   my ($self, $elt, $marker) = @_;
+    return new W3C::Grammar::YaccCompileTree::Star($elt, $marker, $self);
+}
+    | lmodifiableelt '?'
+{   my ($self, $elt, $marker) = @_;
+    return new W3C::Grammar::YaccCompileTree::Opt($elt, $marker, $self);
+}
+    | lmodifiableelt '+'
+{   my ($self, $elt, $marker) = @_;
+    return new W3C::Grammar::YaccCompileTree::Plus($elt, $marker, $self);
+}
+;
+
+modifiableelt:
+    symbol
+{   my ($self, $symbol) = @_;
+    return new W3C::Grammar::YaccCompileTree::Symb($symbol, $self);
+}
+    | TERMINAL
+{   my ($self, $terminal) = @_;
+    return new W3C::Grammar::YaccCompileTree::Symb($terminal, $self);
+}
+    | '(' rhss ')'
+{   my ($self, $open, $rhselts, undef) = @_;
+    return UNIVERSAL::isa($rhselts, 'W3C::Grammar::YaccCompileTree::Set') ? 
+    new W3C::Grammar::YaccCompileTree::Group($open, $rhselts, $self) : 
+    $rhselts;
+}
+    | '[' { $CharClass = 0; } charclass ']' { $CharClass = undef; }
+{   my ($self, $bracket, undef, $charclass, undef, undef) = @_;
+    my $charclassStr = $charclass->toString();
+    _SyntaxError(1, "character classes must only appear in a terminal (found $charclassStr)",
+		 $bracket->getLineNo());
+    return $charclass;
+}
+    | '/' lmodifiableelt
+{   my ($self, $slash, $lookAhead) = @_;
+    my $lookAheadStr = $lookAhead->toString();
+    _SyntaxError(1, "lookahead must only appear in a terminal (found $lookAheadStr)",
+		 $slash->getLineNo());
+    return new W3C::Grammar::YaccCompileTree::LookAhead($lookAhead, $self);
+}
+;
+
+prec:
+    PREC symbol
+{   my ($self, $prec, $symbol) = @_;
+    if (!defined $Terminals->{$_[2][0]}) {
+	_SyntaxError(1,"No precedence for symbol $_[2][0]",
+		     $_[2][1]);
+	return undef;
+    }
+
+    ++$$PrecedenceTerminals{$_[2][0]};
+    $Terminals->{$_[2][0]}[1];
+}
+;
+
+epscode:
+{   return undef;
+}
+    | code
+{   my ($self, $code) = @_;
+    return $code;
+}
+;
+
+code:
+    CODE
+{   my ($self, $code) = @_;
+    return $code;
+}
+;
+
+# Tail section:
+
+tail:       /*empty*/
+    | TAILCODE
+{   my ($self, $tailcode) = @_;
+    return $tail = $tailcode;
+}
+;
+
+
+%%
+sub _Error {
+    my ($self, @parms) = @_;
+    my($value)=$self->YYCurval;
+
+    $self->YYData->{INPUT} = $$input;
+    $self->YYData->{my_LASTPOS} = pos $$input;
+    &throw(new W3C::Util::YappDriver::MesgYappContextException($self, @parms));
+    my($what)= $Token ? "input: '$$value[0]'" : "end of input";
+
+    _SyntaxError(1,"Unexpected $what",$$value[1]);
+}
+
+use constant SEC_head => 0;
+use constant SEC_body => 1;
+use constant SEC_tail => 2;
+
+sub _Lexer {
+    my ($self) = @_;
+
+    if ($self->YYData->{Fake} eq 'bodyTransition') {
+	$self->YYData->{Fake} = 'tailTransition';
+        ++$lexlevel;
+        return('%%', [ '%%', $lineno[0] ]);
+    }
+
+    #At EOF
+    if (pos($$input) >= length($$input)) {
+	if ($NoSemiNeeded) {
+	    $NoSemiNeeded = 0;
+	    return ('EOProduction', 'EOProduction')
+	}
+	if ($self->YYData->{Fake} eq 'tailTransition') {
+	    $self->YYData->{Fake} = '';
+	    ++$lexlevel;
+	    return('%%', [ '%%', $lineno[0] ]);
+	}
+
+	return('',[ undef, -1 ]);
+    }
+
+    #In Character Class
+    if (defined $CharClass) {
+	my $ret;
+	if ($CharClass == 0 && $$input =~ m/\G(\^)/gc) {
+	    $ret = ['CARROT' , new W3C::Grammar::YaccCompileTree::LLITERAL($1, $lineno[0], $self)];
+	} elsif ($$input =~ m/\G\#x([0-9A-Fa-f]+)/gc) {
+	    my $char = chr(hex($1));
+	    $ret = ['LITERAL' , new W3C::Grammar::YaccCompileTree::LLITERAL($char, $lineno[0], $self)];
+	} elsif ($$input =~ m/\G(\\.)/gc) {
+	    my $str = $1;
+	$str =~ s/\\\\/\\/g;
+	$str =~ s/\\\"/\"/g;
+	$str =~ s/\\r/\r/g;
+	$str =~ s/\\n/\n/g;
+	$str =~ s/\\t/\t/g;
+	    $ret = ['LITERAL' , new W3C::Grammar::YaccCompileTree::LLITERAL($str, $lineno[0], $self)];
+	} elsif ($$input =~ m/\G(\-)(?!\])/gc) {
+	    my $char = $1;
+	    $ret = ['RANGEOP' , new W3C::Grammar::YaccCompileTree::TOKEN($char, $lineno[0], $self)];
+	} elsif ($$input =~ m/\G(\])/gc) {
+	    my $char = $1;
+	    $ret = [']' , new W3C::Grammar::YaccCompileTree::TOKEN($char, $lineno[0], $self)];
+	} elsif ($$input =~ m/\G(.)/gc) {
+	    my $char = $1;
+	    $ret = ['LITERAL' , new W3C::Grammar::YaccCompileTree::LLITERAL($char, $lineno[0], $self)];
+	} else {
+	    $self->_Error(-errorMessage => "unexpected end of input in character class");
+	}
+	$CharClass++;
+	return @$ret;
+    }
+
+    #In a LEX decl
+    if ($LexMode) {
+	$$input =~ m/\G\s*/gc;
+	return _LexLexer($input, undef);
+    }
+
+    #In TAIL section
+    if ($lexlevel > SEC_body) {
+        my($pos)=pos($$input);
+
+        $lineno[0]=$lineno[1];
+        $lineno[1]=-1;
+        pos($$input)=length($$input);
+        return('TAILCODE', new W3C::Grammar::YaccCompileTree::TAILCODE(substr($$input, $pos), $lineno[0], $self));
+    }
+
+    # Handle COMMENTs and whitespace.
+    if ($NoSemiNeeded && ($lexlevel == SEC_head || $lexlevel == SEC_body) && $$input=~m{
+\G(\s+) (?= ((?:\[\d \s* [\d\w]*\]|/\*|\#(?![xX]?[0-9a-fA-F])))	# needs to include line feed in consumed \s+
+        | (?: (?: [A-Za-z_][A-Za-z0-9_]* )
+              | \< (?:[^\>]+) \>) \s*\:
+        | (?: %% )
+        | (?: \Z )
+        | (?= \@ ) )}xsgc) {
+        my ($blanks) = ($1);
+        $lineno[1]+= $blanks=~tr/\n//;
+	$lineno[0]=$lineno[1];
+	return('EOProduction', 'EOProduction');
+    } elsif ($$input=~m{\G((\s*)\#((?:[^x])[^\n]*))}xsgc) {
+	my ($blanks, $leadWS, $text) = ($1, $2, $3);
+        $lineno[1]+= $blanks=~tr/\n//;
+	$lineno[0]=$lineno[1];
+	return ('COMMENT', new W3C::Grammar::YaccCompileTree::PerlComment($leadWS, $text, $lineno[0], $self));
+    } elsif ($$input=~m{\G((\s*)/\*(.*?)\*/)}xsgc) {
+	my ($blanks, $leadWS, $text) = ($1, $2, $3);
+        $lineno[1]+= $blanks=~tr/\n//;
+	$lineno[0]=$lineno[1];
+	return ('COMMENT', new W3C::Grammar::YaccCompileTree::CComment($leadWS, $text, $lineno[0], $self));
+    } elsif ($lexlevel == SEC_head && $$input=~m{\G([\t\ ]+)}xsgc || 
+	     ($lexlevel != SEC_head || $NoSemiNeeded) && $$input=~m{\G(\s+)}xsgc) {
+        my ($blanks) = ($1);
+        $lineno[1]+= $blanks=~tr/\n//;
+
+        #Maybe now at EOF
+    if (pos($$input) >= length($$input)) {
+	if ($NoSemiNeeded) {
+	    $NoSemiNeeded = 0;
+	    return ('EOProduction', 'EOProduction')
+	}
+	if ($self->YYData->{Fake} eq 'tailTransition') {
+	    $self->YYData->{Fake} = '';
+	    ++$lexlevel;
+	    return('%%', [ '%%', $lineno[0] ]);
+	}
+
+	return('',[ undef, -1 ]);
+    }
+    }
+
+    $lineno[0]=$lineno[1];
+
+    if ($$input=~/\G\@terminals/gc) {
+	return('TERMINALS', new W3C::Grammar::YaccCompileTree::IDENT('', $lineno[0], $self));
+    }
+
+    if ($$input=~/\G\@pass/gc) {
+	return('PASS', new W3C::Grammar::YaccCompileTree::IDENT($PassedTokensName, $lineno[0], $self));
+    }
+
+    if ($$input=~/\G([A-Za-z_][A-Za-z0-9_]*)/gc) {
+	my $name = $1;
+	my $ident = $self->YYData->{KnownIdents}{$name};
+	if (!$ident) {
+	    $ident = new W3C::Grammar::YaccCompileTree::IDENT($name, $lineno[0], $self);
+	    $self->YYData->{KnownIdents}{$name} = $ident;
+	}
+	return('IDENT', $ident);
+    }
+
+    if ($$input=~/\G\'((?:[^\'\\]|\\\\|\\\'|\\)+?)\'/gc) {
+	if ($1 eq "'error'") {
+            _SyntaxError(0,"Literal 'error' ".
+			 "will be treated as error token",$lineno[0]);
+            return('IDENT', new W3C::Grammar::YaccCompileTree::IDENT('error', $lineno[0], $self));
+        }
+	my $str = $1;
+	$str =~ s/\\\\/\\/g;
+	$str =~ s/\\\"/\"/g; # @@@ forgiving mode
+	$str =~ s/\\\'/\'/g;
+	$str =~ s/\\r/\r/g; # @@@ forgiving mode
+	$str =~ s/\\n/\n/g; # @@@ forgiving mode
+	$str =~ s/\\t/\t/g; # @@@ forgiving mode
+        return('LITERAL', new W3C::Grammar::YaccCompileTree::LLITERAL($str, $lineno[0], $self));
+    }
+
+    if ($$input=~/\G\#x([0-9A-Fa-f]+)/gc) {
+	my $ch = chr(hex($1));
+        return('LITERAL', new W3C::Grammar::YaccCompileTree::LLITERAL($ch, $lineno[0], $self));
+    }
+
+    if ($$input=~/\G\"((?:[^\\\"]|(?:\\.))*)\"/gc) {
+	if ($1 eq "'error'") {
+            _SyntaxError(0,"Literal 'error' ".
+			 "will be treated as error token",$lineno[0]);
+            return('IDENT', new W3C::Grammar::YaccCompileTree::IDENT('error', $lineno[0], $self));
+        }
+	my $str = $1;
+	$str =~ s/\\\\/\\/g;
+	$str =~ s/\\\"/\"/g;
+	$str =~ s/\\\'/\'/g; # @@@ forgiving mode
+	$str =~ s/\\r/\r/g;
+	$str =~ s/\\n/\n/g;
+	$str =~ s/\\t/\t/g;
+        return('LITERAL', new W3C::Grammar::YaccCompileTree::LLITERAL($str, $lineno[0], $self));
+    }
+
+    if ($$input=~/\G\<([^\>]+)\>/gc) {
+	my $value = $1;
+	if ($value =~ m/\"/) {
+	    my $pieces = [];
+	    while ($value =~ /\G\"((?:[^\\\"]|(?:\\.))*)\"\s*/gc) {
+		my $str = $1;
+		$str =~ s/\\\\/\\/g;
+		$str =~ s/\\\"/\"/g;
+		$str =~ s/\\r/\r/g;
+		$str =~ s/\\n/\n/g;
+		$str =~ s/\\t/\t/g;
+		push (@$pieces, $str);
+	    }
+	    my $all = join(' ', @$pieces);
+	    return('LITERAL', new W3C::Grammar::YaccCompileTree::LLITERAL($all, $lineno[0], $self));
+	} elsif ($value eq "'error'") {
+            _SyntaxError(0,"Literal 'error' ".
+			 "will be treated as error token",$lineno[0]);
+            return('IDENT', new W3C::Grammar::YaccCompileTree::IDENT('error', $lineno[0], $self));
+        } else {
+	    return('TERMINAL', new W3C::Grammar::YaccCompileTree::Terminal($value, $lineno[0], $self));
+	}
+    }
+
+    if ($$input=~/\G(%%)/gc) {
+        ++$lexlevel;
+        return($1, [ $1, $lineno[0] ]);
+    }
+
+    if ($$input=~/\G{/gc) {
+        my($level,$from,$code);
+
+        $from=pos($$input);
+
+        $level=1;
+        while($$input=~/([{}])/gc) {
+	    if (substr($$input,pos($$input)-1,1) eq '\\') { #Quoted
+		next;
+	    }
+	    if ($level += ($1 eq '{' ? 1 : -1)) {
+	    } else {
+		last;
+	    }
+        }
+	if ($level) {
+	    _SyntaxError(2,"Unmatched { opened line $lineno[0]",-1);
+	}
+        $code = substr($$input,$from,pos($$input)-$from-1);
+        $lineno[1]+= $code=~tr/\n//;
+        return('CODE', new W3C::Grammar::YaccCompileTree::CODE($code, $lineno[0], $self));
+    }
+
+    if ($lexlevel == SEC_head) { # In head section
+	if ($$input=~/\G%(left|right|nonassoc)/gc) {
+	    return('ASSOC', new W3C::Grammar::YaccCompileTree::ASSOC($1, $lineno[0], $self));
+	}
+	if ($$input=~/\G%(start)/gc) {
+	    return('START', new W3C::Grammar::YaccCompileTree::START(undef, $lineno[0], $self));
+	}
+	if ($$input=~/\G%(expect)/gc) {
+	    return('EXPECT', new W3C::Grammar::YaccCompileTree::EXPECT(undef, $lineno[0], $self));
+	}
+	if ($$input=~/\G%{/gc) {
+	    my($code);
+
+	    if ($$input !~ /\G(.*?)%\}/sgc) {
+		_SyntaxError(2,"Unmatched %{ opened line $lineno[0]",-1);
+	    }
+
+	    $code=$1;
+	    $lineno[1]+= $code=~tr/\n//;
+	    return('HEADCODE', new W3C::Grammar::YaccCompileTree::HEADCODE($code, $lineno[0], $self));
+	}
+	if ($$input=~/\G%(token)/gc) {
+	    return('TOKEN', new W3C::Grammar::YaccCompileTree::TOKEN(undef, $lineno[0], $self));
+	}
+	if ($$input=~/\G%(type)/gc) {
+	    return('TYPE', new W3C::Grammar::YaccCompileTree::TYPE(undef, $lineno[0], $self));
+	}
+	if ($$input=~/\G%(union)/gc) {
+	    return('UNION', new W3C::Grammar::YaccCompileTree::UNION(undef, $lineno[0], $self));
+	}
+	if ($$input=~/\G([0-9]+)/gc) {
+	    return('NUMBER', new W3C::Grammar::YaccCompileTree::NUMBER($1, $lineno[0], $self));
+	}
+    } else {		# In rule section
+	if ($$input=~/\G%(prec)/gc) {
+	    return('PREC', new W3C::Grammar::YaccCompileTree::PREC(undef, $lineno[0], $self));
+	}
+	if ($$input=~/\G([0-9]+)/gc) { # added
+	    return('NUMBER', new W3C::Grammar::YaccCompileTree::NUMBER($1, $lineno[0], $self));
+	}
+    }
+
+    #Always return something
+    if ($$input !~ /\G(.)/sg) {
+	$self->_Error(-errorMessage => "matched no characters")
+    }
+    my $char = $1;
+
+    if ($NoSemiNeeded && $char eq ';') {
+	$NoSemiNeeded = 0;
+	return('EOProduction', 'EOProduction');
+    }
+
+    if ($char eq "\n") {
+	++$lineno[1];
+    }
+
+    return ( $char , new W3C::Grammar::YaccCompileTree::TokenBase($char, $lineno[0], $self));
+
+}
+
+sub _SyntaxError {
+    my($level,$message,$lineno)=@_;
+
+    $message= "*".
+#              [ 'Warning', 'Error', 'Fatal' ]->[$level].
+              "* $message, at ".
+              ($lineno < 0 ? "eof" : "line $lineno").
+              ".\n";
+
+    if ($level > 1) {
+	my $messagesStr = &getMessages();
+	die "$messagesStr\n*Fatal* $message";
+    }
+
+    push (@$Messages, [$level, $message]);
+
+    if ($level > 0) {
+	++$nberr;
+    }
+
+    if ($nberr == 20) {
+	my $messagesStr = &getMessages();
+	die "$messagesStr\n*Fatal* Too many errors detected.";
+    }
+}
+sub getLineNo {
+    return $lineno[0];
+}
+sub getMessages {
+    return join('', map {($_->[0] ? 'Error' : 'Warning').": $_->[1]"} @$Messages);
+}
+sub W3C::Grammar::YaccCompileTree::IDENT::_getProductionByName {
+    my ($self) = @_;
+    my $lhs = $self->getToken();
+    return $NonTerminals->{$lhs};
+}
+
+sub _AddRules {
+    my($self, $production) = @_;
+    my $lhs = $production->getIdent()->getToken();
+    my $lineno = $production->getIdent()->getLineNo();
+    my $rhss = (); # $production->getRules();
+    push(@$rules,[ $lhs, [ ], undef, undef ]);
+
+    if (ref($NonTerminals->{$lhs})) {
+	my $pref = $self->YYData->{Symbols}{$lhs};
+        _SyntaxError(1,"Non-terminal $lhs redefined: ".
+                       "Previously declared line $pref",$lineno);
+        return;
+    }
+
+    if (ref($Terminals->{$lhs})) {
+        my($where) = exists($Token->{$lhs}) ? $Token->{$lhs} : $self->YYData->{Symbols}{$lhs};
+        _SyntaxError(1,"Non-terminal $lhs previously ".
+		     "declared as token line $where",$lineno);
+        return;
+    }
+
+    if (ref($NonTerminals->{$lhs})) {      #declared through %type
+    } else {
+	$self->YYData->{Symbols}{$lhs} = $lineno;   #Say it's declared here
+	delete($Terminals->{$lhs});   #No more a terminal
+    }
+    $NonTerminals->{$lhs} = [];       #It's a non-terminal now
+
+    my($epsrules)=0;        #To issue a warning if more than one epsilon rule
+
+    for my $rhs1 (@$rhss) {
+	my $rhs = $rhs1->getRhs();
+	my $prec = $rhs1->getPrec();
+	my $code = $rhs1->getCode();
+        my($tmprule)=[ $lhs, [ ], $prec, $code ]; #Init rule
+
+	if (!@$rhs) {
+            ++$$nullable{$lhs};
+            ++$epsrules;
+        }
+
+        for (my $i = 0; $i < @$rhs; $i++) {
+	    my $ob = $rhs->[$i];
+	    if (!$ob->isa('W3C::Grammar::YaccCompileTree::Text')) {
+		if ($ob->isa('W3C::Grammar::YaccCompileTree::Code')) {
+		    my($name)='@'.++$labelno."-$i";
+		    push(@$rules,[ $name, [], undef, $ob ]);
+		    push(@{$$tmprule[1]},$name);
+		    next;
+		}
+		my $value = $ob->getValue();
+		push(@{$$tmprule[1]},$$value[0]);
+	    }
+        }
+        push(@$rules,$tmprule);
+        push(@{$NonTerminals->{$lhs}},$#$rules);
+    }
+
+    if ($epsrules > 1) {
+	_SyntaxError(0,"More than one empty rule for symbol $lhs",$lineno);
+    }
+    return $production;
+}
+
+sub Parse {
+    my ($self, $inputParm, $debug) = @_;
+
+    my($parsed)={};
+
+    $input=\$inputParm;
+
+    $lexlevel = SEC_head;
+    @lineno=(1,1);
+    $nberr=0;
+    $prec=0;
+    $labelno=0;
+
+    $head=();
+    $tail="";
+
+    $self->YYData->{Symbols} = {};
+    $self->YYData->{KnownIdents} = {};
+    $Token={};
+    $Terminals={};
+    $NonTerminals={};
+    $rules=[ undef ];   #reserve slot 0 for start rule
+    $PrecedenceTerminals={};
+
+    $start="";
+    $nullable={};
+    $expect=0;
+
+    pos($$input)=0;
+
+    $/ = undef;
+    my $ret = $self->YYParse(yylex => \&_Lexer, yyerror => \&_Error, yydebug => $debug);
+
+    if ($nberr) {
+	_SyntaxError(2,"Errors detected: No output",-1);
+    }
+
+    @$parsed{ 'HEAD', 'TAIL', 'RULES', 'NTERM', 'TERM',
+              'NULL', 'PREC', 'SYMS',  'START', 'EXPECT' }
+    =       (  $head,  $tail,  $rules,  $NonTerminals,  $Terminals,
+               $nullable, $PrecedenceTerminals, $self->YYData->{Symbols}, $start, $expect);
+    my $messages = [@$Messages];
+    $Messages = [];
+    undef($input);
+    undef($lexlevel);
+    undef(@lineno);
+    undef($nberr);
+    undef($prec);
+    undef($labelno);
+
+    undef($head);
+    undef($tail);
+
+    #undef($self->YYData->{Symbols});
+    undef($Token);
+    undef($Terminals);
+    undef($NonTerminals);
+    undef($rules);
+    undef($PrecedenceTerminals);
+
+    undef($start);
+    undef($nullable);
+    undef($expect);
+
+    return ($ret, $messages);
+    $parsed;
+}
+
+package W3C::Grammar::YaccParser;
+@W3C::Grammar::YaccParser::ISA = 'W3C::Grammar::_YaccParser';
+
+sub new {
+    my ($proto, $noIntegrityCheck, @yappParms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@yappParms);
+    $self->YYData->{NoIntegrityCheck} = $noIntegrityCheck;
+    $self->YYData->{Fake} = '';
+    return $self;
+}
+
+sub fake {
+    my ($self, $fake) =@_;
+    $self->YYData->{Fake} = $fake;
+}
+
+sub setFilename {
+    my ($self, $filename) = @_;
+    $self->{Filename} = $filename;
+}
+
+sub getFilename {
+    my ($self) = @_;
+    return $self->{Filename};
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/YackerSymbolParser.pm	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,542 @@
+#!/usr/bin/perl
+####################################################################
+#
+#    This file was generated using Parse::Yapp version 1.05.
+#
+#        Don't edit this file, use source file instead.
+#
+#             ANY CHANGE MADE HERE WILL BE LOST !
+#
+####################################################################
+package W3C::Grammar::_YackerSymbolParser;
+use vars qw ( @ISA );
+use strict;
+
+@ISA= qw ( Parse::Yapp::Driver );
+# use Parse::Yapp::Driver; @@ replaced by W3C::Util::YappDriver
+
+#line 1 "YackerSymbolParser.yp"
+
+use W3C::Util::YappDriver;
+use W3C::Grammar::YaccCompileTree;
+use W3C::Util::Exception;
+
+# START TokenBlock
+my $IT__Opt = "_Opt";
+my $IT__Plus = "_Plus";
+my $IT__Star = "_Star";
+my $IT__Q = "_Q";
+my $IT__E = "_E";
+my $IT__O = "_O";
+my $IT__C = "_C";
+my $IT__Or = "_Or";
+my $IT__S = "_S";
+my $escapedSymbol = "(?:[GI]T_(?:[A-Za-z])+)|(?:(?:(?:(?:[\x{0000}-\\^`-\x{10FFFE}])|(?:__)))+)";
+my $PASSED_TOKENS = "(?:[\\t\\n\\r ])+";
+my $Tokens = [[0, qr/$PASSED_TOKENS/, undef],
+              [0, qr/$IT__Opt/i, 'IT__Opt'],
+              [0, qr/$IT__Plus/i, 'IT__Plus'],
+              [0, qr/$IT__Star/i, 'IT__Star'],
+              [0, qr/$IT__Q/i, 'IT__Q'],
+              [0, qr/$IT__E/i, 'IT__E'],
+              [0, qr/$IT__O/i, 'IT__O'],
+              [0, qr/$IT__C/i, 'IT__C'],
+              [0, qr/$IT__Or/i, 'IT__Or'],
+              [0, qr/$IT__S/i, 'IT__S'],
+              [0, qr/$escapedSymbol/, 'escapedSymbol']];
+# END TokenBlock
+
+
+sub new {
+        my($class)=shift;
+        ref($class)
+    and $class=ref($class);
+
+    my($self)=$class->SUPER::new( yyversion => '1.05',
+                                  yystates =>
+[
+	{#State 0
+		ACTIONS => {
+			'IT__O' => 1,
+			'escapedSymbol' => 7,
+			'IT__Q' => 4
+		},
+		GOTOS => {
+			'quotedSymbol' => 6,
+			'symbol' => 2,
+			'starSymbol' => 3,
+			'root' => 8,
+			'list' => 10,
+			'plusSymbol' => 9,
+			'optSymbol' => 5
+		}
+	},
+	{#State 1
+		ACTIONS => {
+			'IT__Q' => 4
+		},
+		GOTOS => {
+			'quotedSymbol' => 11,
+			'symbolSequence' => 12,
+			'symbolOrGroup' => 13
+		}
+	},
+	{#State 2
+		DEFAULT => -1
+	},
+	{#State 3
+		DEFAULT => -5
+	},
+	{#State 4
+		ACTIONS => {
+			'IT__O' => 1,
+			'escapedSymbol' => 7,
+			'IT__Q' => 4
+		},
+		GOTOS => {
+			'quotedSymbol' => 6,
+			'symbol' => 14,
+			'starSymbol' => 3,
+			'plusSymbol' => 9,
+			'list' => 10,
+			'optSymbol' => 5
+		}
+	},
+	{#State 5
+		DEFAULT => -3
+	},
+	{#State 6
+		ACTIONS => {
+			'IT__Star' => 16,
+			'IT__Opt' => 17,
+			'IT__Plus' => 15
+		}
+	},
+	{#State 7
+		DEFAULT => -2
+	},
+	{#State 8
+		ACTIONS => {
+			'' => 18
+		}
+	},
+	{#State 9
+		DEFAULT => -4
+	},
+	{#State 10
+		DEFAULT => -6
+	},
+	{#State 11
+		DEFAULT => -14
+	},
+	{#State 12
+		ACTIONS => {
+			'IT__S' => 19
+		},
+		DEFAULT => -12
+	},
+	{#State 13
+		ACTIONS => {
+			'IT__C' => 21,
+			'IT__Or' => 20
+		}
+	},
+	{#State 14
+		ACTIONS => {
+			'IT__E' => 22
+		}
+	},
+	{#State 15
+		DEFAULT => -8
+	},
+	{#State 16
+		DEFAULT => -9
+	},
+	{#State 17
+		DEFAULT => -7
+	},
+	{#State 18
+		DEFAULT => 0
+	},
+	{#State 19
+		ACTIONS => {
+			'IT__Q' => 4
+		},
+		GOTOS => {
+			'quotedSymbol' => 23
+		}
+	},
+	{#State 20
+		ACTIONS => {
+			'IT__Q' => 4
+		},
+		GOTOS => {
+			'quotedSymbol' => 11,
+			'symbolSequence' => 24
+		}
+	},
+	{#State 21
+		DEFAULT => -11
+	},
+	{#State 22
+		DEFAULT => -10
+	},
+	{#State 23
+		DEFAULT => -15
+	},
+	{#State 24
+		ACTIONS => {
+			'IT__S' => 19
+		},
+		DEFAULT => -13
+	}
+],
+                                  yyrules  =>
+[
+	[#Rule 0
+		 '$start', 2, undef
+	],
+	[#Rule 1
+		 'root', 1,
+sub
+#line 34 "YackerSymbolParser.yp"
+{
+    my ($self, $symbol) = @_;
+    new W3C::Grammar::YaccCompileTree::Rule($symbol, undef, undef, $self);
+}
+	],
+	[#Rule 2
+		 'symbol', 1, undef
+	],
+	[#Rule 3
+		 'symbol', 1, undef
+	],
+	[#Rule 4
+		 'symbol', 1, undef
+	],
+	[#Rule 5
+		 'symbol', 1, undef
+	],
+	[#Rule 6
+		 'symbol', 1, undef
+	],
+	[#Rule 7
+		 'optSymbol', 2,
+sub
+#line 48 "YackerSymbolParser.yp"
+{
+    my ($self, $quotedSymbol, $IT__Opt) = @_;
+    new W3C::Grammar::YaccCompileTree::Opt($quotedSymbol, undef, $self);
+}
+	],
+	[#Rule 8
+		 'plusSymbol', 2,
+sub
+#line 54 "YackerSymbolParser.yp"
+{
+    my ($self, $quotedSymbol, $IT__Plus) = @_;
+    new W3C::Grammar::YaccCompileTree::Plus($quotedSymbol, undef, $self);
+}
+	],
+	[#Rule 9
+		 'starSymbol', 2,
+sub
+#line 60 "YackerSymbolParser.yp"
+{
+    my ($self, $quotedSymbol, $IT__Star) = @_;
+    new W3C::Grammar::YaccCompileTree::Star($quotedSymbol, undef, $self);
+}
+	],
+	[#Rule 10
+		 'quotedSymbol', 3,
+sub
+#line 66 "YackerSymbolParser.yp"
+{
+    my ($self, $IT__Q, $symbol, $IT__E) = @_;
+    $symbol;
+}
+	],
+	[#Rule 11
+		 'list', 3,
+sub
+#line 72 "YackerSymbolParser.yp"
+{
+    my ($self, $IT__O, $symbolOrGroup, $IT__C) = @_;
+    $symbolOrGroup;
+}
+	],
+	[#Rule 12
+		 'symbolOrGroup', 1, undef
+	],
+	[#Rule 13
+		 'symbolOrGroup', 3,
+sub
+#line 79 "YackerSymbolParser.yp"
+{
+    my ($self, $symbolOrGroup, $IT__Or, $symbolSequence) = @_;
+    $symbolOrGroup ? 
+	W3C::Grammar::YaccCompileTree::Disjunction::addRightBranch($symbolOrGroup, $symbolSequence, $self) : 
+	$symbolSequence;
+}
+	],
+	[#Rule 14
+		 'symbolSequence', 1, undef
+	],
+	[#Rule 15
+		 'symbolSequence', 3,
+sub
+#line 88 "YackerSymbolParser.yp"
+{
+    my ($self, $symbolSequence, $IT__S, $quotedSymbol) = @_;
+    new W3C::Grammar::YaccCompileTree::Sequence($symbolSequence, $quotedSymbol, $self);
+}
+	]
+],
+                                  @_);
+    bless($self,$class);
+}
+
+#line 97 "YackerSymbolParser.yp"
+
+
+my $LanguageName = 'yackerSymbol';
+# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
+# START LexerBlock
+#
+# YappTemplate: used by yacker to create yapp input files.
+#
+# Use: yacker -l perl -s -n <name> <name>.txt
+#
+# to generate a yapp input module called Sparql.yp.
+
+#line 11 "YappTemplate"
+
+# $Id: YackerSymbolParser.pm,v 1.1 2007-01-08 09:52:15 eric Exp $
+
+package W3C::Grammar::YackerSymbolParser;
+require Exporter;
+@W3C::Grammar::YackerSymbolParser::ISA = qw(W3C::Grammar::_YackerSymbolParser Exporter);
+use vars qw(@EXPORT);
+@EXPORT = qw(&test);
+
+use W3C::Util::Exception;
+use W3C::Grammar::YaccCompileTree qw($Name2Symbol);
+
+sub _Error {
+    my ($self) = @_;
+        exists $self->YYData->{ERRMSG}
+    and do {
+        print $self->YYData->{ERRMSG};
+        delete $self->YYData->{ERRMSG};
+        return;
+    };
+    my $pos = pos $self->YYData->{INPUT};
+    my $lastPos = $self->YYData->{my_LASTPOS};
+    my $excerpt = substr($self->YYData->{INPUT}, $lastPos, $pos - $lastPos);
+    my $expect = @{$self->{STACK}} ? join (' | ', sort {(!(lc $a cmp lc $b)) ? $b cmp $a : lc $a cmp lc $b} map {&_terminalString($_)} $self->YYExpect()) : 'INVALID INITIALIZER';
+    if (ref $expect) {
+	# Flag unexpected (by the author at this point) refs with '?ref'.
+	if (ref $expect eq 'HASH') {
+	    if (exists $expect->{NEXT}) {
+		$expect = $ {$expect->{NEXT}};
+	    } else {
+		$expect = "?ref {%$expect}";
+	    }
+	} elsif (ref $expect eq 'ARRAY') {
+	    $expect = "?ref [@$expect]";
+	} elsif (ref $expect eq 'SCALAR') {
+	    $expect = "?ref $$expect";
+	} elsif (ref $expect eq 'GLOB') {
+	    $expect = "?ref \**$expect";
+	} else {
+	    $expect = "?ref ??? $expect";
+	}
+    }
+    my $token = &_terminalString($self->YYData->{my_LASTTOKEN});
+    my $value = $self->YYData->{my_LASTVALUE};
+    die "expected \"$expect\", got ($token, $value) from \"$excerpt\" at offset $lastPos.\n";
+}
+
+sub _terminalString { # static
+    my ($token) = @_;
+    if ($token =~ m{^I_T_(.+)$}) {
+	$token = "'$1'";
+    } elsif ($token =~ m{^T_(.+)$}) {
+	if (my $base = $ARGV[0]) {
+	    $token = "&lt;<a href=\"${base}$token\">$1</a>&gt;";
+	} else {
+	    $token = "<$1>";
+	}
+    }
+    return $token;
+}
+
+my $AtStart;
+
+sub _Lexer {
+    my($self)=shift;
+
+    my ($token, $value) = ('', undef);
+
+  top:
+    if (defined $self->YYData->{INPUT} && 
+	pos $self->YYData->{INPUT} < length ($self->YYData->{INPUT})) {
+	# still some chars left.
+    } else {
+	return ('', undef);
+    }
+
+    $self->YYData->{my_LASTPOS} = pos $self->YYData->{INPUT};
+    my $startPos = pos $self->YYData->{INPUT};
+    my ($mText, $mLen, $mI, $mLookAhead) = ('', 0, undef, undef);
+    for (my $i = 0; $i < @$Tokens; $i++) {
+	my $rule = $Tokens->[$i];
+	my ($start, $regexp, $action) = @$rule;
+	if ($start && !$AtStart) {
+	    next;
+	}
+	eval {
+	    if ($self->YYData->{INPUT} =~ m/\G($regexp)/gc) {
+		my $lookAhead = length $2;
+		my $len = (pos $self->YYData->{INPUT}) - $startPos + $lookAhead;
+		if ($len > $mLen) {
+		    $mText = substr($self->YYData->{INPUT}, $startPos, $len - $lookAhead);
+		    $mLen = $len;
+		    $mI = $i;
+		    $mLookAhead = $lookAhead
+		}
+		pos $self->YYData->{INPUT} = $startPos;
+	    }
+	}; if ($@) {
+	    die "error processing $action: $@";
+	}
+    }
+    if ($mLen) {
+	my ($start, $regexp, $action) = @{$Tokens->[$mI]};
+	pos $self->YYData->{INPUT} += $mLen - $mLookAhead;
+	$AtStart = $mText =~ m/\z/gc;
+	($token, $value) = ($action, $mText);
+    } else {
+	my $excerpt = substr($self->YYData->{INPUT}, pos $self->YYData->{INPUT}, 40);
+	die "lexer couldn't parse at \"$excerpt\"\n";
+    }
+    if (!defined $token) {
+	# We just parsed whitespace or comment.
+	goto top;
+    }
+#    my $pos = pos $self->YYData->{INPUT};
+#    print "\n$pos,$token,$value\n";
+    $self->YYData->{my_LASTTOKEN} = $token;
+    $self->YYData->{my_LASTVALUE} = $value;
+    &utf8::encode($value);
+    my $ret = undef;
+    if ($token eq 'escapedSymbol') {
+	if ($value =~ m/^IT_(.*)$/) {
+	    $ret = new W3C::Grammar::YaccCompileTree::LLITERAL($1, undef, $self);
+	} elsif ($value =~ m/^GT_(.*)$/) {
+	    if (my $mapped = $Name2Symbol->{$1}) {
+		$ret = new W3C::Grammar::YaccCompileTree::LLITERAL($mapped, undef, $self);
+	    } else {
+		&throw(new W3C::Util::Exception(-message => "no map for \"$1\""));
+	    }
+	} else {
+	    $value =~ s/__/_/g;
+	    $ret = new W3C::Grammar::YaccCompileTree::IDENT($value, undef, $self);
+	}
+    } elsif ($token eq 'IT__Or') {
+	$ret = '|';
+    }
+    return ($token, $ret);
+}
+
+sub parse {
+    my($self, $symbol) = @_;
+    $self->YYData->{INPUT} = $symbol;
+    return $self->YYParse( yylex => \&_Lexer, yyerror => \&_Error, yydebug => $ENV{YYDEBUG} );
+}
+
+sub test {
+    my ($symbol, $langName) = @ARGV[0..1];
+    my $parser = new W3C::Grammar::YackerSymbolParser();
+    eval {
+	&utf8::decode($symbol);
+	my $root = $parser->parse($symbol);
+	my $text = $root->toString();
+	&utf8::encode($text);
+	print "$text\n";
+    }; if ($@) {if (my $ex = &catch('W3C::Util::Exception')) {
+	die $ex->toString;
+    } else {die $@;}}
+}
+# END LexerBlock
+
+1;
+
+__END__
+
+=head1 NAME
+
+W3C::Grammar::YackerSymbolParser - parse intermediate production names generated by Yacker.
+
+=head1 SYNOPSIS
+
+    my ($symbol, $langName) = @ARGV[0..1];
+    my $parser = new W3C::Grammar::YackerSymbolParser();
+    &utf8::decode($symbol);
+    my $root = $parser->parse($symbol);
+    my $text = $root->toString(Markup => 'html', LanguageName => $langName);
+    &utf8::encode($text);
+    print "$text\n";
+
+=head1 DESCRIPTION
+
+Yacker needs to encode rule patterns in [a-zA-Z_]+ so it reserves symbols starting with '_'. This parser reverses the process.
+
+This module is part of the W3C::Grammar CPAN module.
+
+=head1 API
+
+This function supplies a single parsing function. The methods of the returned object are described in W3C::Grammar::YaccCompileTree(1).
+
+=head2 parse($inputString)
+
+Returns a W3C::Grammar::YaccCompileTree::Rule represented by $inputString. $inputString is expected to be [a-zA-Z0-0_]+, though no specific restrictions prevent any of the rest of unicode.
+
+=head1 TEST
+
+    perl -MW3C::Grammar::YackerSymbolParser -e test \
+    _Q_O_QOptionalGraphPattern_E_S_QGT_DOT_E_Opt_S_QGroupElement_E_C_E_Opt
+
+which should return
+
+    BrackettedExpression | BuiltInCall | FunctionCall
+
+
+=head2 longer test
+
+    _Q_O_QGT_EQUAL_E_S_QNumericExpression_E_Or__QGT_NEQUAL_E_S_QNumericExpression_E_Or__QGT_LT_E_S_QNumericExpression_E_Or__QGT_GT_E_S_QNumericExpression_E_Or__QGT_LE_E_S_QNumericExpression_E_Or__QGT_GE_E_S_QNumericExpression_E_C_E_Opt
+
+    ("=" NumericExpression | "!=" NumericExpression | "<" NumericExpression | ">" NumericExpression | "<=" NumericExpression | ">=" NumericExpression)?
+
+With extra args $root->toString(Markup => 'html', LanguageName => 'SPARQL-')
+you get:
+
+    ("=" <span class="prod"><a class="grammarRef" href="#prod-SPARQL-NumericExpression">NumericExpression</a></span> | "!=" <span class="prod"><a class="grammarRef" href="#prod-SPARQL-NumericExpression">NumericExpression</a></span> | "<" <span class="prod"><a class="grammarRef" href="#prod-SPARQL-NumericExpression">NumericExpression</a></span> | ">" <span class="prod"><a class="grammarRef" href="#prod-SPARQL-NumericExpression">NumericExpression</a></span> | "<=" <span class="prod"><a class="grammarRef" href="#prod-SPARQL-NumericExpression">NumericExpression</a></span> | ">=" <span class="prod"><a class="grammarRef" href="#prod-SPARQL-NumericExpression">NumericExpression</a></span>)?
+
+
+=head1 BUGS
+
+    _O_QGraphPatternNotTriples_E_S_QGT_DOT_E_Opt_S_QGraphPattern_E_C
+
+
+=head1 AUTHOR
+
+Eric Prud'hommeaux <eric@w3.org>
+
+=head1 SEE ALSO
+
+W3C::Grammar::YaccCompileTree(1)
+
+=cut
+
+1;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/YackerSymbolParser.yp	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,337 @@
+%{
+use W3C::Util::YappDriver;
+use W3C::Grammar::YaccCompileTree;
+use W3C::Util::Exception;
+
+# START TokenBlock
+my $IT__Opt = "_Opt";
+my $IT__Plus = "_Plus";
+my $IT__Star = "_Star";
+my $IT__Q = "_Q";
+my $IT__E = "_E";
+my $IT__O = "_O";
+my $IT__C = "_C";
+my $IT__Or = "_Or";
+my $IT__S = "_S";
+my $escapedSymbol = "(?:[GI]T_(?:[A-Za-z])+)|(?:(?:(?:(?:[\x{0000}-\\^`-\x{10FFFE}])|(?:__)))+)";
+my $PASSED_TOKENS = "(?:[\\t\\n\\r ])+";
+my $Tokens = [[0, qr/$PASSED_TOKENS/, undef],
+              [0, qr/$IT__Opt/i, 'IT__Opt'],
+              [0, qr/$IT__Plus/i, 'IT__Plus'],
+              [0, qr/$IT__Star/i, 'IT__Star'],
+              [0, qr/$IT__Q/i, 'IT__Q'],
+              [0, qr/$IT__E/i, 'IT__E'],
+              [0, qr/$IT__O/i, 'IT__O'],
+              [0, qr/$IT__C/i, 'IT__C'],
+              [0, qr/$IT__Or/i, 'IT__Or'],
+              [0, qr/$IT__S/i, 'IT__S'],
+              [0, qr/$escapedSymbol/, 'escapedSymbol']];
+# END TokenBlock
+%}
+%%
+
+root:
+    symbol	{
+    my ($self, $symbol) = @_;
+    new W3C::Grammar::YaccCompileTree::Rule($symbol, undef, undef, $self);
+};
+
+symbol:
+    escapedSymbol
+    | optSymbol
+    | plusSymbol
+    | starSymbol
+    | list
+;
+
+optSymbol:
+    quotedSymbol IT__Opt	{
+    my ($self, $quotedSymbol, $IT__Opt) = @_;
+    new W3C::Grammar::YaccCompileTree::Opt($quotedSymbol, undef, $self);
+};
+
+plusSymbol:
+    quotedSymbol IT__Plus	{
+    my ($self, $quotedSymbol, $IT__Plus) = @_;
+    new W3C::Grammar::YaccCompileTree::Plus($quotedSymbol, undef, $self);
+};
+
+starSymbol:
+    quotedSymbol IT__Star	{
+    my ($self, $quotedSymbol, $IT__Star) = @_;
+    new W3C::Grammar::YaccCompileTree::Star($quotedSymbol, undef, $self);
+};
+
+quotedSymbol:
+    IT__Q symbol IT__E	{
+    my ($self, $IT__Q, $symbol, $IT__E) = @_;
+    $symbol;
+};
+
+list:
+    IT__O symbolOrGroup IT__C	{
+    my ($self, $IT__O, $symbolOrGroup, $IT__C) = @_;
+    $symbolOrGroup;
+};
+
+symbolOrGroup:
+    symbolSequence
+    | symbolOrGroup IT__Or symbolSequence	{
+    my ($self, $symbolOrGroup, $IT__Or, $symbolSequence) = @_;
+    $symbolOrGroup ? 
+	W3C::Grammar::YaccCompileTree::Disjunction::addRightBranch($symbolOrGroup, $symbolSequence, $self) : 
+	$symbolSequence;
+};
+
+symbolSequence:
+    quotedSymbol
+    | symbolSequence IT__S quotedSymbol	{
+    my ($self, $symbolSequence, $IT__S, $quotedSymbol) = @_;
+    new W3C::Grammar::YaccCompileTree::Sequence($symbolSequence, $quotedSymbol, $self);
+};
+
+
+
+
+
+%%
+
+my $LanguageName = 'yackerSymbol';
+# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
+# START LexerBlock
+#
+# YappTemplate: used by yacker to create yapp input files.
+#
+# Use: yacker -l perl -s -n <name> <name>.txt
+#
+# to generate a yapp input module called Sparql.yp.
+
+#line 11 "YappTemplate"
+
+# $Id: YackerSymbolParser.yp,v 1.2 2007-01-10 02:00:05 eric Exp $
+
+package W3C::Grammar::YackerSymbolParser;
+require Exporter;
+@W3C::Grammar::YackerSymbolParser::ISA = qw(W3C::Grammar::_YackerSymbolParser Exporter);
+use vars qw(@EXPORT);
+@EXPORT = qw(&test);
+
+use W3C::Util::Exception;
+use W3C::Grammar::YaccCompileTree qw($Name2Symbol);
+
+sub _Error {
+    my ($self) = @_;
+        exists $self->YYData->{ERRMSG}
+    and do {
+        print $self->YYData->{ERRMSG};
+        delete $self->YYData->{ERRMSG};
+        return;
+    };
+    my $pos = pos $self->YYData->{INPUT};
+    my $lastPos = $self->YYData->{my_LASTPOS};
+    my $excerpt = substr($self->YYData->{INPUT}, $lastPos, $pos - $lastPos);
+    my $expect = @{$self->{STACK}} ? join (' | ', sort {(!(lc $a cmp lc $b)) ? $b cmp $a : lc $a cmp lc $b} map {&_terminalString($_)} $self->YYExpect()) : 'INVALID INITIALIZER';
+    if (ref $expect) {
+	# Flag unexpected (by the author at this point) refs with '?ref'.
+	if (ref $expect eq 'HASH') {
+	    if (exists $expect->{NEXT}) {
+		$expect = $ {$expect->{NEXT}};
+	    } else {
+		$expect = "?ref {%$expect}";
+	    }
+	} elsif (ref $expect eq 'ARRAY') {
+	    $expect = "?ref [@$expect]";
+	} elsif (ref $expect eq 'SCALAR') {
+	    $expect = "?ref $$expect";
+	} elsif (ref $expect eq 'GLOB') {
+	    $expect = "?ref \**$expect";
+	} else {
+	    $expect = "?ref ??? $expect";
+	}
+    }
+    my $token = &_terminalString($self->YYData->{my_LASTTOKEN});
+    my $value = $self->YYData->{my_LASTVALUE};
+    die "expected \"$expect\", got ($token, $value) from \"$excerpt\" at offset $lastPos.\n";
+}
+
+sub _terminalString { # static
+    my ($token) = @_;
+    if ($token =~ m{^I_T_(.+)$}) {
+	$token = "'$1'";
+    } elsif ($token =~ m{^T_(.+)$}) {
+	if (my $base = $ARGV[0]) {
+	    $token = "&lt;<a href=\"${base}$token\">$1</a>&gt;";
+	} else {
+	    $token = "<$1>";
+	}
+    }
+    return $token;
+}
+
+my $AtStart;
+
+sub _Lexer {
+    my($self)=shift;
+
+    my ($token, $value) = ('', undef);
+
+  top:
+    if (defined $self->YYData->{INPUT} && 
+	pos $self->YYData->{INPUT} < length ($self->YYData->{INPUT})) {
+	# still some chars left.
+    } else {
+	return ('', undef);
+    }
+
+    $self->YYData->{my_LASTPOS} = pos $self->YYData->{INPUT};
+    my $startPos = pos $self->YYData->{INPUT};
+    my ($mText, $mLen, $mI, $mLookAhead) = ('', 0, undef, undef);
+    for (my $i = 0; $i < @$Tokens; $i++) {
+	my $rule = $Tokens->[$i];
+	my ($start, $regexp, $action) = @$rule;
+	if ($start && !$AtStart) {
+	    next;
+	}
+	eval {
+	    if ($self->YYData->{INPUT} =~ m/\G($regexp)/gc) {
+		my $lookAhead = length $2;
+		my $len = (pos $self->YYData->{INPUT}) - $startPos + $lookAhead;
+		if ($len > $mLen) {
+		    $mText = substr($self->YYData->{INPUT}, $startPos, $len - $lookAhead);
+		    $mLen = $len;
+		    $mI = $i;
+		    $mLookAhead = $lookAhead
+		}
+		pos $self->YYData->{INPUT} = $startPos;
+	    }
+	}; if ($@) {
+	    die "error processing $action: $@";
+	}
+    }
+    if ($mLen) {
+	my ($start, $regexp, $action) = @{$Tokens->[$mI]};
+	pos $self->YYData->{INPUT} += $mLen - $mLookAhead;
+	$AtStart = $mText =~ m/\z/gc;
+	($token, $value) = ($action, $mText);
+    } else {
+	my $excerpt = substr($self->YYData->{INPUT}, pos $self->YYData->{INPUT}, 40);
+	die "lexer couldn't parse at \"$excerpt\"\n";
+    }
+    if (!defined $token) {
+	# We just parsed whitespace or comment.
+	goto top;
+    }
+#    my $pos = pos $self->YYData->{INPUT};
+#    print "\n$pos,$token,$value\n";
+    $self->YYData->{my_LASTTOKEN} = $token;
+    $self->YYData->{my_LASTVALUE} = $value;
+    &utf8::encode($value);
+    my $ret = undef;
+    if ($token eq 'escapedSymbol') {
+	if ($value =~ m/^IT_(.*)$/) {
+	    $ret = new W3C::Grammar::YaccCompileTree::LLITERAL($1, undef, $self);
+	} elsif ($value =~ m/^GT_(.*)$/) {
+	    if (my $mapped = $Name2Symbol->{$1}) {
+		$ret = new W3C::Grammar::YaccCompileTree::LLITERAL($mapped, undef, $self);
+	    } else {
+		&throw(new W3C::Util::Exception(-message => "no map for \"$1\""));
+	    }
+	} else {
+	    $value =~ s/__/_/g;
+	    $ret = new W3C::Grammar::YaccCompileTree::IDENT($value, undef, $self);
+	}
+    } elsif ($token eq 'IT__Or') {
+	$ret = '|';
+    }
+    return ($token, $ret);
+}
+
+sub parse {
+    my($self, $symbol) = @_;
+    $self->YYData->{INPUT} = $symbol;
+    return $self->YYParse( yylex => \&_Lexer, yyerror => \&_Error, yydebug => $ENV{YYDEBUG} );
+}
+
+sub test {
+    my ($symbol, $langName) = @ARGV[0..1];
+    my $parser = new W3C::Grammar::YackerSymbolParser();
+    eval {
+	&utf8::decode($symbol);
+	my $root = $parser->parse($symbol);
+	my $text = $root->toString();
+	&utf8::encode($text);
+	print "$text\n";
+    }; if ($@) {if (my $ex = &catch('W3C::Util::Exception')) {
+	die $ex->toString;
+    } else {die $@;}}
+}
+# END LexerBlock
+
+1;
+
+__END__
+
+=head1 NAME
+
+W3C::Grammar::YackerSymbolParser - parse intermediate production names generated by Yacker.
+
+=head1 SYNOPSIS
+
+    my ($symbol, $langName) = @ARGV[0..1];
+    my $parser = new W3C::Grammar::YackerSymbolParser();
+    &utf8::decode($symbol);
+    my $root = $parser->parse($symbol);
+    my $text = $root->toString(Markup => 'html', LanguageName => $langName);
+    &utf8::encode($text);
+    print "$text\n";
+
+=head1 DESCRIPTION
+
+Yacker needs to encode rule patterns in [a-zA-Z_]+ so it reserves symbols starting with '_'. This parser reverses the process.
+
+This module is part of the W3C::Grammar CPAN module.
+
+=head1 API
+
+This function supplies a single parsing function. The methods of the returned object are described in W3C::Grammar::YaccCompileTree(1).
+
+=head2 parse($inputString)
+
+Returns a W3C::Grammar::YaccCompileTree::Rule represented by $inputString. $inputString is expected to be [a-zA-Z0-0_]+, though no specific restrictions prevent any of the rest of unicode.
+
+=head1 TESTING/DEBUGGING
+
+    perl -MW3C::Grammar::YackerSymbolParser -e test \
+    _Q_O_QOptionalGraphPattern_E_S_QGT_DOT_E_Opt_S_QGroupElement_E_C_E_Opt
+
+which should return
+
+    BrackettedExpression | BuiltInCall | FunctionCall
+
+
+=head2 longer test
+
+    _Q_O_QGT_EQUAL_E_S_QNumericExpression_E_Or__QGT_NEQUAL_E_S_QNumericExpression_E_Or__QGT_LT_E_S_QNumericExpression_E_Or__QGT_GT_E_S_QNumericExpression_E_Or__QGT_LE_E_S_QNumericExpression_E_Or__QGT_GE_E_S_QNumericExpression_E_C_E_Opt
+
+    ("=" NumericExpression | "!=" NumericExpression | "<" NumericExpression | ">" NumericExpression | "<=" NumericExpression | ">=" NumericExpression)?
+
+With extra args $root->toString(Markup => 'html', LanguageName => 'SPARQL-')
+you get:
+
+    ("=" <span class="prod"><a class="grammarRef" href="#prod-SPARQL-NumericExpression">NumericExpression</a></span> | "!=" <span class="prod"><a class="grammarRef" href="#prod-SPARQL-NumericExpression">NumericExpression</a></span> | "<" <span class="prod"><a class="grammarRef" href="#prod-SPARQL-NumericExpression">NumericExpression</a></span> | ">" <span class="prod"><a class="grammarRef" href="#prod-SPARQL-NumericExpression">NumericExpression</a></span> | "<=" <span class="prod"><a class="grammarRef" href="#prod-SPARQL-NumericExpression">NumericExpression</a></span> | ">=" <span class="prod"><a class="grammarRef" href="#prod-SPARQL-NumericExpression">NumericExpression</a></span>)?
+
+
+=head1 BUGS
+
+    _O_QGraphPatternNotTriples_E_S_QGT_DOT_E_Opt_S_QGraphPattern_E_C
+
+
+=head1 AUTHOR
+
+Eric Prud'hommeaux <eric@w3.org>
+
+=head1 SEE ALSO
+
+W3C::Grammar::YaccCompileTree(1)
+
+=cut
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/YackerSymbolParser.yp.onDeck	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,337 @@
+# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
+#
+
+%{
+use W3C::Util::YappDriver;
+use W3C::Grammar::YaccCompileTree;
+use W3C::Util::Exception;
+
+# START TokenBlock
+my $IT__Opt = "_Opt";
+my $IT__Plus = "_Plus";
+my $IT__Star = "_Star";
+my $IT__Q = "_Q";
+my $IT__E = "_E";
+my $IT__O = "_O";
+my $IT__C = "_C";
+my $IT__Or = "_Or_";
+my $IT__S = "_S";
+my $escapedSymbol = "(?:[GI]T_(?:[A-Za-z])+)|(?:(?:(?:(?:[\x{0000}-\\^`-\x{10FFFE}])|(?:__)))+)";
+my $PASSED_TOKENS = "(?:[\\t\\n\\r ])+";
+my $Tokens = [[0, qr/$PASSED_TOKENS/, undef],
+              [0, qr/$IT__Opt/i, 'IT__Opt'],
+              [0, qr/$IT__Plus/i, 'IT__Plus'],
+              [0, qr/$IT__Star/i, 'IT__Star'],
+              [0, qr/$IT__Q/i, 'IT__Q'],
+              [0, qr/$IT__E/i, 'IT__E'],
+              [0, qr/$IT__O/i, 'IT__O'],
+              [0, qr/$IT__C/i, 'IT__C'],
+              [0, qr/$IT__Or/i, 'IT__Or'],
+              [0, qr/$IT__S/i, 'IT__S'],
+              [0, qr/$escapedSymbol/, 'escapedSymbol']];
+# END TokenBlock
+%}
+%%
+
+rule:
+    rhselt	{
+    my ($self, $rhselt) = @_;
+    new W3C::Grammar::YaccCompileTree::Rule($rhselt, undef, undef, $self);
+};
+
+rhselt:
+    modifiedelt
+;
+
+modifiedelt:
+    modifiableelt
+    | modifiableelt IT__Star
+{   my ($self, $modifiableelt, $IT__Star) = @_;
+    new W3C::Grammar::YaccCompileTree::Star($modifiableelt, undef, $self);
+}
+    | modifiableelt IT__Opt
+{   my ($self, $modifiableelt, $IT__Opt) = @_;
+    new W3C::Grammar::YaccCompileTree::Opt($modifiableelt, undef, $self);
+}
+    | modifiableelt IT__Plus
+{   my ($self, $modifiableelt, $IT__Plus) = @_;
+    new W3C::Grammar::YaccCompileTree::Plus($modifiableelt, undef, $self);
+}
+;
+
+modifiableelt:
+    IT__Q escapedSymbol IT__E	{
+    my ($self, $IT__Q, $escapedSymbol, $IT__E) = @_;
+    $escapedSymbol;
+}
+    | IT__O rhss IT__C	{
+    my ($self, $IT__O, $rhss, $IT__C) = @_;
+    $rhss;
+};
+
+rhss:
+    rhs
+    | rhss IT__Or rhs	{
+    my ($self, $rhss, $IT__Or, $rhs) = @_;
+    $rhss ? 
+	W3C::Grammar::YaccCompileTree::Disjunction::addRightBranch($rhss, $rhs, $self) : 
+	$rhs;
+};
+
+rhs:
+    #empty
+    | rhselts
+;
+
+rhselts:
+    rhselt
+    | rhselt IT__S rhselts	{
+    my ($self, $rhs, $IT__S, $rhselts) = @_;
+    new W3C::Grammar::YaccCompileTree::Sequence($rhs, $rhselts, $self);
+};
+
+
+
+
+
+%%
+
+my $LanguageName = 'yackerSymbol';
+# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
+# START LexerBlock
+#
+# YappTemplate: used by yacker to create yapp input files.
+#
+# Use: yacker -l perl -s -n <name> <name>.txt
+#
+# to generate a yapp input module called Sparql.yp.
+
+##line 11 "YappTemplate"
+
+# $Id: YackerSymbolParser.yp.onDeck,v 1.1 2007-10-18 21:08:35 eric Exp $
+
+package W3C::Grammar::YackerSymbolParser;
+require Exporter;
+@W3C::Grammar::YackerSymbolParser::ISA = qw(W3C::Grammar::_YackerSymbolParser Exporter);
+use vars qw(@EXPORT);
+@EXPORT = qw(&test);
+
+use W3C::Util::Exception;
+use W3C::Grammar::YaccCompileTree qw($Name2Symbol);
+
+sub _Error {
+    my ($self) = @_;
+        exists $self->YYData->{ERRMSG}
+    and do {
+        print $self->YYData->{ERRMSG};
+        delete $self->YYData->{ERRMSG};
+        return;
+    };
+    my $pos = pos $self->YYData->{INPUT};
+    my $lastPos = $self->YYData->{my_LASTPOS};
+    my $excerpt = substr($self->YYData->{INPUT}, $lastPos, $pos - $lastPos);
+    my $expect = @{$self->{STACK}} ? join (' | ', sort {(!(lc $a cmp lc $b)) ? $b cmp $a : lc $a cmp lc $b} map {&_terminalString($_)} $self->YYExpect()) : 'INVALID INITIALIZER';
+    if (ref $expect) {
+	# Flag unexpected (by the author at this point) refs with '?ref'.
+	if (ref $expect eq 'HASH') {
+	    if (exists $expect->{NEXT}) {
+		$expect = $ {$expect->{NEXT}};
+	    } else {
+		$expect = "?ref {%$expect}";
+	    }
+	} elsif (ref $expect eq 'ARRAY') {
+	    $expect = "?ref [@$expect]";
+	} elsif (ref $expect eq 'SCALAR') {
+	    $expect = "?ref $$expect";
+	} elsif (ref $expect eq 'GLOB') {
+	    $expect = "?ref \**$expect";
+	} else {
+	    $expect = "?ref ??? $expect";
+	}
+    }
+    my $token = &_terminalString($self->YYData->{my_LASTTOKEN});
+    my $value = $self->YYData->{my_LASTVALUE};
+    die "expected \"$expect\", got ($token, $value) from \"$excerpt\" at offset $lastPos.\n";
+}
+
+sub _terminalString { # static
+    my ($token) = @_;
+    if ($token =~ m{^I_T_(.+)$}) {
+	$token = "'$1'";
+    } elsif ($token =~ m{^T_(.+)$}) {
+	if (my $base = $ARGV[0]) {
+	    $token = "&lt;<a href=\"${base}$token\">$1</a>&gt;";
+	} else {
+	    $token = "<$1>";
+	}
+    }
+    return $token;
+}
+
+my $AtStart;
+
+sub _Lexer {
+    my($self)=shift;
+
+    my ($token, $value) = ('', undef);
+
+  top:
+    if (defined $self->YYData->{INPUT} && 
+	pos $self->YYData->{INPUT} < length ($self->YYData->{INPUT})) {
+	# still some chars left.
+    } else {
+	return ('', undef);
+    }
+
+    $self->YYData->{my_LASTPOS} = pos $self->YYData->{INPUT};
+    my $startPos = pos $self->YYData->{INPUT};
+    my ($mText, $mLen, $mI, $mLookAhead) = ('', 0, undef, undef);
+    for (my $i = 0; $i < @$Tokens; $i++) {
+	my $rule = $Tokens->[$i];
+	my ($start, $regexp, $action) = @$rule;
+	if ($start && !$AtStart) {
+	    next;
+	}
+	eval {
+	    if ($self->YYData->{INPUT} =~ m/\G($regexp)/gc) {
+		my $lookAhead = length $2;
+		my $len = (pos $self->YYData->{INPUT}) - $startPos + $lookAhead;
+		if ($len > $mLen) {
+		    $mText = substr($self->YYData->{INPUT}, $startPos, $len - $lookAhead);
+		    $mLen = $len;
+		    $mI = $i;
+		    $mLookAhead = $lookAhead
+		}
+		pos $self->YYData->{INPUT} = $startPos;
+	    }
+	}; if ($@) {
+	    die "error processing $action: $@";
+	}
+    }
+    if ($mLen) {
+	my ($start, $regexp, $action) = @{$Tokens->[$mI]};
+	pos $self->YYData->{INPUT} += $mLen - $mLookAhead;
+	$AtStart = $mText =~ m/\z/gc;
+	($token, $value) = ($action, $mText);
+    } else {
+	my $excerpt = substr($self->YYData->{INPUT}, pos $self->YYData->{INPUT}, 40);
+	die "lexer couldn't parse at \"$excerpt\"\n";
+    }
+    if (!defined $token) {
+	# We just parsed whitespace or comment.
+	goto top;
+    }
+#    my $pos = pos $self->YYData->{INPUT};
+#    print "\n$pos,$token,$value\n";
+    $self->YYData->{my_LASTTOKEN} = $token;
+    $self->YYData->{my_LASTVALUE} = $value;
+    &utf8::encode($value);
+    my $ret = undef;
+    if ($token eq 'escapedSymbol') {
+	if ($value =~ m/^IT_(.*)$/) {
+	    $ret = new W3C::Grammar::YaccCompileTree::LLITERAL($1, undef, $self);
+	} elsif ($value =~ m/^GT_(.*)$/) {
+	    if (my $mapped = $Name2Symbol->{$1}) {
+		$ret = new W3C::Grammar::YaccCompileTree::LLITERAL($mapped, undef, $self);
+	    } else {
+		&throw(new W3C::Util::Exception(-message => "no map for \"$1\""));
+	    }
+	} else {
+	    $value =~ s/__/_/g;
+	    $ret = new W3C::Grammar::YaccCompileTree::IDENT($value, undef, $self);
+	}
+    } elsif ($token eq 'IT__Or') {
+	$ret = '|';
+    }
+    return ($token, $ret);
+}
+
+sub parse {
+    my($self, $symbol) = @_;
+    $self->YYData->{INPUT} = $symbol;
+    return $self->YYParse( yylex => \&_Lexer, yyerror => \&_Error, yydebug => $ENV{YYDEBUG} );
+}
+
+sub test {
+    my ($symbol, $langName) = @ARGV[0..1];
+    my $parser = new W3C::Grammar::YackerSymbolParser();
+    eval {
+	&utf8::decode($symbol);
+	my $root = $parser->parse($symbol);
+	my $text = $root->toString();
+	&utf8::encode($text);
+	print "$text\n";
+    }; if ($@) {if (my $ex = &catch('W3C::Util::Exception')) {
+	die $ex->toString;
+    } else {die $@;}}
+}
+# END LexerBlock
+
+1;
+
+__END__
+
+=head1 NAME
+
+W3C::Grammar::YackerSymbolParser - parse intermediate production names generated by Yacker.
+
+=head1 SYNOPSIS
+
+    my ($symbol, $langName) = @ARGV[0..1];
+    my $parser = new W3C::Grammar::YackerSymbolParser();
+    &utf8::decode($symbol);
+    my $root = $parser->parse($symbol);
+    my $text = $root->toString(Markup => 'html', LanguageName => $langName);
+    &utf8::encode($text);
+    print "$text\n";
+
+=head1 DESCRIPTION
+
+Yacker needs to encode rule patterns in [a-zA-Z_]+ so it reserves symbols starting with '_'. This parser reverses the process.
+
+This module is part of the W3C::Grammar CPAN module.
+
+=head1 API
+
+This function supplies a single parsing function. The methods of the returned object are described in W3C::Grammar::YaccCompileTree(1).
+
+=head2 parse($inputString)
+
+Returns a W3C::Grammar::YaccCompileTree::Rule represented by $inputString. $inputString is expected to be [a-zA-Z0-0_]+, though no specific restrictions prevent any of the rest of unicode.
+
+=head1 TESTING/DEBUGGING
+
+    perl -MW3C::Grammar::YackerSymbolParser -e test \
+    _Q_O_QOptionalGraphPattern_E_S_QGT_DOT_E_Opt_S_QGroupElement_E_C_E_Opt
+
+which should return
+
+    BrackettedExpression | BuiltInCall | FunctionCall
+
+
+=head2 longer test
+
+    _Q_O_QGT_EQUAL_E_S_QNumericExpression_E_Or__QGT_NEQUAL_E_S_QNumericExpression_E_Or__QGT_LT_E_S_QNumericExpression_E_Or__QGT_GT_E_S_QNumericExpression_E_Or__QGT_LE_E_S_QNumericExpression_E_Or__QGT_GE_E_S_QNumericExpression_E_C_E_Opt
+
+    ("=" NumericExpression | "!=" NumericExpression | "<" NumericExpression | ">" NumericExpression | "<=" NumericExpression | ">=" NumericExpression)?
+
+With extra args $root->toString(Markup => 'html', LanguageName => 'SPARQL-')
+you get:
+
+    ("=" <span class="prod"><a class="grammarRef" href="#prod-SPARQL-NumericExpression">NumericExpression</a></span> | "!=" <span class="prod"><a class="grammarRef" href="#prod-SPARQL-NumericExpression">NumericExpression</a></span> | "<" <span class="prod"><a class="grammarRef" href="#prod-SPARQL-NumericExpression">NumericExpression</a></span> | ">" <span class="prod"><a class="grammarRef" href="#prod-SPARQL-NumericExpression">NumericExpression</a></span> | "<=" <span class="prod"><a class="grammarRef" href="#prod-SPARQL-NumericExpression">NumericExpression</a></span> | ">=" <span class="prod"><a class="grammarRef" href="#prod-SPARQL-NumericExpression">NumericExpression</a></span>)?
+
+
+=head1 BUGS
+
+    _O_QGraphPatternNotTriples_E_S_QGT_DOT_E_Opt_S_QGraphPattern_E_C
+
+
+=head1 AUTHOR
+
+Eric Prud'hommeaux <eric@w3.org>
+
+=head1 SEE ALSO
+
+W3C::Grammar::YaccCompileTree(1)
+
+=cut
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/YackerTraceParser.pm	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,227 @@
+#Copyright Massachusetts Institute of technology, 2007.
+#Written by Eric Prud'hommeaux for the World Wide Web Consortium
+
+# $Id: YackerTraceParser.pm,v 1.3 2007-12-01 10:05:04 eric Exp $
+
+use strict;
+
+package W3C::Grammar::YackerTraceEvent;
+
+sub new {
+    my ($proto, $parser) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = {Parser => $parser};
+    bless ($self, $class);
+    return $self;
+}
+
+
+package W3C::Grammar::YackerTraceParseError;
+@W3C::Grammar::YackerTraceParseError::ISA = qw(W3C::Grammar::YackerTraceEvent);
+sub new {
+    my ($proto, $error, $parser) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new($parser);
+    $self->{Error} = $error;
+    bless ($self, $class);
+    return $self;
+}
+sub getError {
+    my ($self) = @_;
+    return $self->{Error};
+}
+
+
+package W3C::Grammar::YackerTraceConsume;
+@W3C::Grammar::YackerTraceConsume::ISA = qw(W3C::Grammar::YackerTraceEvent);
+sub new {
+    my ($proto, $token, $value, $parser) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new($parser);
+    $self->{Token} = $token;
+    $self->{Value} = $value;
+    bless ($self, $class);
+    return $self;
+}
+sub getToken {
+    my ($self) = @_;
+    return $self->{Token};
+}
+sub getValue {
+    my ($self) = @_;
+    return $self->{Value};
+}
+sub toString {
+    my ($self, %flags) = @_;
+    return 'shift ('.$self->getToken().', '.$self->getValue().')';
+}
+
+
+package W3C::Grammar::YackerTraceMatch;
+@W3C::Grammar::YackerTraceMatch::ISA = qw(W3C::Grammar::YackerTraceEvent);
+sub new {
+    my ($proto, $match, $parser) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new($parser);
+    $self->{Match} = $match;
+    bless ($self, $class);
+    return $self;
+}
+sub getMatch {
+    my ($self) = @_;
+    return $self->{Match};
+}
+sub toString {
+    my ($self, %flags) = @_;
+    return $self->getMatch();
+}
+
+
+package W3C::Grammar::YackerTraceRule;
+@W3C::Grammar::YackerTraceRule::ISA = qw(W3C::Grammar::YackerTraceEvent);
+sub new {
+    my ($proto, $rule, $matched, $parser) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new($parser);
+    $self->{Rule} = $rule;
+    $self->{Matched} = $matched;
+    bless ($self, $class);
+    return $self;
+}
+sub getRule {
+    my ($self) = @_;
+    return $self->{Rule};
+}
+sub getMatched {
+    my ($self) = @_;
+    return $self->{Matched};
+}
+sub toString {
+    my ($self, %flags) = @_;
+    my $matched = $self->getMatched();
+    my @ret = (' '.$self->getRule().'('.(scalar @$matched).')');
+    for (my $iMatch = 0; $iMatch < @$matched; $iMatch++) {
+	my $match = $matched->[$iMatch];
+	push (@ret, '    '.$self->getRule."($iMatch): ".$match->toString(%flags));
+    }
+    return wantarray ? @ret : join("\n", @ret);
+}
+
+
+package W3C::Grammar::YackerTraceStateChange;
+@W3C::Grammar::YackerTraceStateChange::ISA = qw(W3C::Grammar::YackerTraceEvent);
+sub new {
+    my ($proto, $production, $rules, $parser) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new($parser);
+    $self->{Production} = $production;
+    $self->{Rules} = $rules;
+    bless ($self, $class);
+    return $self;
+}
+sub getProduction {
+    my ($self) = @_;
+    return $self->{Production};
+}
+sub getRules {
+    my ($self) = @_;
+    return $self->{Rules};
+}
+sub toString {
+    my ($self, %flags) = @_;
+    my @ret = '  '.$self->getProduction().':';
+    foreach my $rule (@{$self->{Rules}}) {
+	my $matched = $rule->getMatched();
+	$ret[0] .= ' '.$rule->getRule().'('.(scalar @$matched).')';
+	for (my $iMatch = 0; $iMatch < @$matched; $iMatch++) {
+	    my $match = $matched->[$iMatch];
+	    push (@ret, '    '.$rule->getRule."($iMatch): ".$match->toString(%flags));
+	}
+    }
+    return wantarray ? @ret : join("\n", @ret);
+}
+
+
+package W3C::Grammar::YackerTraceParser;
+
+sub new {
+    my ($proto, %parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = {Consumes => [], Productions => [], Events => [], %parms};
+    bless ($self, $class);
+    return $self;
+}
+sub getConsumes {
+    my ($self) = @_;
+    return $self->{Consumes};
+}
+sub getProductions {
+    my ($self) = @_;
+    return $self->{Productions};
+}
+sub parse {
+    my ($self, $text) = @_;
+    my @inputLines = split("\n", $text);
+    for (my $lineNo = 0; $lineNo < @inputLines; $lineNo++) {
+	my $line = $inputLines[$lineNo];
+	if ($line =~ m/^shift \((.*?), (.*?)\)$/) {
+	    my ($token, $value) = ($1, $2);
+	    my $consume = new W3C::Grammar::YackerTraceConsume($token, $value, $self);
+	    push (@{$self->{Consumes}}, $consume);
+	    push (@{$self->{Events}}, $consume);
+	} elsif ($line =~ m/^  ([^:]+): ?(.*)$/) {
+	    my ($production, @ruleStrs) = ($1, split (' ', $2));
+	    my $rules = [];
+	  RULE:
+	    foreach my $rule (@ruleStrs) {
+		$rule =~ s/\((\d+)\)$//;
+		my $matched = [];
+		my $matchCount = $1;
+		for (my $col = 0; $col < $matchCount; $col++) {
+		    if ($inputLines[++$lineNo] =~ m/^    \Q$rule($col)\E: (.*)$/) {
+			push (@$matched, new W3C::Grammar::YackerTraceMatch($1, $self));
+		    } else {
+			my $errorStr = "\"$inputLines[$lineNo]\" did not match \"^    \\Q$rule\\E: (.*)\$\"";
+			if ($self->{-noErrors}) {
+			    push (@$matched, new W3C::Grammar::YackerTraceParseError($errorStr, $self));
+			    --$lineNo;
+			    last RULE;
+			} else {
+			    &throw(new W3C::Util::Exception(-message => $errorStr));
+			}
+		    }
+		}
+		push (@$rules, new W3C::Grammar::YackerTraceRule($rule, $matched, $self));
+	    }
+	    my $stateChange = new W3C::Grammar::YackerTraceStateChange($production, $rules, $self);
+	    push (@{$self->{Productions}}, $stateChange);
+	    push (@{$self->{Events}}, $stateChange);
+	} else {
+	    chomp $line;
+	    my $errorStr = "line $lineNo not expected: \"$line\"";
+	    if ($self->{-noErrors}) {
+		push (@{$self->{Events}}, new W3C::Grammar::YackerTraceParseError($errorStr, $self));
+	    } else {
+		&throw(new W3C::Util::Exception(-message => $errorStr));
+	    }
+	}
+    }
+    return $self->{Events};
+}
+sub toString {
+    my ($self, %flags) = @_;
+    my @ret = map {$_->toString(%flags)} @{$self->{Events}};
+    return wantarray ? @ret : join("\n", @ret);
+}
+
+1;
+
+# $Log: YackerTraceParser.pm,v $
+# Revision 1.3  2007-12-01 10:05:04  eric
+# don't require a trailing space on empty productions
+#
+# Revision 1.2  2007/01/10 03:21:46  eric
+# + toString functions
+# ~ make work
+#
+# 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/bin/.cvsignore	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,2 @@
+uploads
+yacker.cgi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/bin/BNFTemplate	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,7 @@
+Line ::= Word* 'end'
+Word ::= 'word' WORD
+       | 'num' NUM
+@terminals
+WORD ::= [a-zA-Z]+ | [#x00C9-#x00D6]+
+HEX ::= [0-9a-fA-F]
+NUM ::= "0" [xX] HEX+ | ([0-9])+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/bin/YaccFooterTemplate	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,37 @@
+// -------------------------------------- START
+#include <stdio.h>
+#include "ClassnameParser.h"
+extern "C++" {
+
+struct yy_buffer_state;
+typedef int yy_state_type;
+
+// -------------------------------------- END
+
+#include <stdio.h>
+
+struct Classname
+{
+private:
+  yyFlexLexer theScanner;
+};
+
+int yylex()
+{
+ return theScanner.yylex(&yylval);
+}
+
+void yyerror(char *m)
+{
+  fprintf(stderr,"%d: %s at token '%s'\n",yylloc.first_line, m,yylloc.text);
+}
+
+int main(int argc,char **argv)
+{
+ Classname aCompiler;
+
+ int result=yyparse();
+ printf("Parsing result: %s.\n", result?"Error":"OK");
+ return result;
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/bin/YaccHeaderTemplate	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,78 @@
+%{
+#define YY_ClassnameParser_STYPE yy_ClassnameParser_stype
+%}
+%name ClassnameParser
+%define LSP_NEEDED
+%define ERROR_BODY =0
+%define LEX_BODY =0
+%header{
+#include <iostream>
+#include <string>
+  using namespace std;
+#define YY_DECL int yyFlexLexer::yylex(YY_ClassnameParser_STYPE *val)
+#ifndef FLEXFIX
+#define FLEXFIX YY_ClassnameParser_STYPE *val
+#define FLEXFIX2 val
+#endif
+
+#include <iostream>
+#include <sstream>
+#include <cstdarg>
+
+struct Buf {
+  char* data;
+  int len;
+}
+Buf makeBuf0 () {
+    len = 0;
+    data = 0;
+  }
+Buf makeBuf1 (char *str) {
+    len = strlen(str);
+    data = (char*) malloc(len+1);
+    strncpy(data, str, len);
+    data[len] = 0;
+  }
+  // Build a space-separated concatonation of bufs.
+Buf makeBuf (int count, ...) {
+    va_list bufs;
+    const Buf *src;
+
+    // This is inefficient for a single buf as the created buf could
+    // just steal the other buf's data pointer and delete it.
+
+    // Walk args to find the total len.
+    len = -1;
+    va_start(bufs, count);
+    for (int i = 0; i < count; i++) {
+      src = va_arg(bufs, Buf*);
+      len += src->len+1;
+    }
+    va_end(bufs);
+
+    data = (char*) malloc(len+1);
+
+    // Walk args to fill the data buffer.
+    len = -1;
+    va_start(bufs, count);
+    for (int i = 0; i < count; i++) {
+      src = va_arg(bufs, Buf*);
+      strncpy(data + len+1, src->data, src->len);
+      len += src->len+1;
+      data[len] = ' ';
+      destroyBuf(src);
+      src = 0;
+    }
+    va_end(bufs);
+    data[len] = 0;
+  }
+void destroyBuf () {
+    if (data) free(data);
+  }
+char *str() {return data;}
+%}
+
+%union {
+  Buf *buf;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/bin/YappTemplate	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,371 @@
+# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
+# START LexerBlock
+#
+# YappTemplate: used by yacker to create yapp input files.
+#
+# Use: yacker -l perl -s -n <name> <name>.txt
+#
+# to generate a yapp input module called Sparql.yp.
+
+#line 11 "YappTemplate"
+
+# $Id: YappTemplate,v 1.30 2007-12-01 19:11:19 eric Exp $
+
+sub _Base::new {
+    my ($proto, @args) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = [];
+    foreach my $arg (@args) {
+	if (UNIVERSAL::isa($arg, $class)) {
+
+	    # Collapse nested left-recursive *, +, ? and () productions.
+	    push (@$self, @$arg);
+	} else {
+
+	    # Construct simple parse tree of production parameters.
+	    push (@$self, $arg);
+	}
+    }
+    bless ($self, $class);
+    return $self;
+}
+sub _Base::toString {
+    my ($self) = @_;
+    my @ret = map {$_->toString} @$self;
+    return wantarray ? @ret : join(' ', @ret);
+}
+sub _Base::toXML {
+    my ($self, $prefix, $decls) = @_;
+    my $class = ref $self;
+    my $declsStr = join('', map {my $p = $_ ? ":$_" : ''; "\n xmlns$p=\"$decls->{$_}\""} keys %$decls);
+    my @ret = ("$prefix<$class$declsStr>", map {ref $_ ? $_->toXML("$prefix  ", {}) : $_} @$self, "$prefix</$class>");
+    return wantarray ? @ret : join("\n", @ret);
+}
+
+@_Production::ISA = qw(_Base);
+@_GenProduction::ISA = qw(_Production);
+sub _GenProduction::toXML {
+    my ($self, $prefix) = @_;
+    return join("\n", map {$_->toXML($prefix)} @$self);
+}
+
+@_Terminal::ISA = qw(_Base);
+sub _Terminal::toString {
+    my ($self) = @_;
+    my $encodedValue = $self->[0];
+    $encodedValue =~ s/\r/\\r/g;
+    $encodedValue =~ s/\n/\\n/g;
+    $encodedValue =~ s/\t/\\t/g;
+    return $encodedValue;
+}
+sub _Terminal::toXML {
+    my ($self, $prefix) = @_;
+    my $class = ref $self;
+    my $encodedValue = $self->[0];
+    $encodedValue =~ s/&/&amp;/g;
+    $encodedValue =~ s/</&lt;/g;
+    $encodedValue =~ s/>/&gt;/g;
+    return "$prefix<$class>$encodedValue</$class>";
+}
+@_Constant::ISA = qw(_Base);
+sub _Constant::toString {
+    my ($self) = @_;
+    return ($self->[0]);
+}
+sub _Constant::toXML {
+    my ($self, $prefix) = @_;
+    my $class = ref $self;
+    $class =~ s/^[IG]T_//;
+    return "$prefix<yacker:implicit-terminal>$class</yacker:implicit-terminal>";
+}
+
+sub _Error {
+    my ($self) = @_;
+        exists $self->YYData->{ERRMSG}
+    and do {
+        print $self->YYData->{ERRMSG};
+        delete $self->YYData->{ERRMSG};
+        return;
+    };
+    my $pos = pos $self->YYData->{INPUT};
+    my $lastPos = $self->YYData->{my_LASTPOS};
+    my $excerpt = substr($self->YYData->{INPUT}, $lastPos, $pos - $lastPos);
+    my $expect = @{$self->{STACK}} ? join (' | ', sort {(!(lc $a cmp lc $b)) ? $b cmp $a : lc $a cmp lc $b} map {&_terminalString($_)} $self->YYExpect()) : 'INVALID INITIALIZER';
+    if (ref $expect) {
+	# Flag unexpected (by the author at this point) refs with '?ref'.
+	if (ref $expect eq 'HASH') {
+	    if (exists $expect->{NEXT}) {
+		$expect = $ {$expect->{NEXT}};
+	    } else {
+		$expect = "?ref {%$expect}";
+	    }
+	} elsif (ref $expect eq 'ARRAY') {
+	    $expect = "?ref [@$expect]";
+	} elsif (ref $expect eq 'SCALAR') {
+	    $expect = "?ref $$expect";
+	} elsif (ref $expect eq 'GLOB') {
+	    $expect = "?ref \**$expect";
+	} else {
+	    $expect = "?ref ??? $expect";
+	}
+    }
+    my $token = &_terminalString($self->YYData->{my_LASTTOKEN});
+    my $value = $self->YYData->{my_LASTVALUE};
+    die "expected \"$expect\", got ($token, $value) from \"$excerpt\" at offset $lastPos.\n";
+}
+
+sub _terminalString { # static
+    my ($token) = @_;
+    if ($token =~ m{^I_T_(.+)$}) {
+	$token = "'$1'";
+    } elsif ($token =~ m{^T_(.+)$}) {
+	if (my $base = $ARGV[0]) {
+	    $token = "&lt;<a href=\"${base}$token\">$1</a>&gt;";
+	} else {
+	    $token = "<$1>";
+	}
+    }
+    return $token;
+}
+
+my $AtStart;
+
+sub _Lexer {
+    my($self)=shift;
+
+    my ($token, $value) = ('', undef);
+
+  top:
+    if (defined $self->YYData->{INPUT} && 
+	pos $self->YYData->{INPUT} < length ($self->YYData->{INPUT})) {
+	# still some chars left.
+    } else {
+	return ('', undef);
+    }
+
+    $self->YYData->{my_LASTPOS} = pos $self->YYData->{INPUT};
+    my $startPos = pos $self->YYData->{INPUT};
+    my ($mText, $mLen, $mI, $mLookAhead) = ('', 0, undef, undef);
+    for (my $i = 0; $i < @$Tokens; $i++) {
+	my $rule = $Tokens->[$i];
+	my ($start, $regexp, $action) = @$rule;
+	if ($start && !$AtStart) {
+	    next;
+	}
+	eval {
+	    if ($self->YYData->{INPUT} =~ m/\G($regexp)/gc) {
+		my $lookAhead = defined $2 ? length $2 : 0;
+		my $len = (pos $self->YYData->{INPUT}) - $startPos + $lookAhead;
+		if ($len > $mLen) {
+		    $mText = substr($self->YYData->{INPUT}, $startPos, $len - $lookAhead);
+		    $mLen = $len;
+		    $mI = $i;
+		    $mLookAhead = $lookAhead
+		}
+		pos $self->YYData->{INPUT} = $startPos;
+	    }
+	}; if ($@) {
+	    die "error processing $action: $@";
+	}
+    }
+    if ($mLen) {
+	my ($start, $regexp, $action) = @{$Tokens->[$mI]};
+	pos $self->YYData->{INPUT} += $mLen - $mLookAhead;
+	$AtStart = $mText =~ m/\z/gc;
+	($token, $value) = ($action, $mText);
+    } else {
+	my $excerpt = substr($self->YYData->{INPUT}, pos $self->YYData->{INPUT}, 40);
+	die "lexer couldn't parse at \"$excerpt\"\n";
+    }
+    if (!defined $token) {
+	# We just parsed whitespace or comment.
+	goto top;
+    }
+#    my $pos = pos $self->YYData->{INPUT};
+#    print "\n$pos,$token,$value\n";
+    $self->YYData->{my_LASTTOKEN} = $token;
+    $self->YYData->{my_LASTVALUE} = $value;
+    my $ret = $token->new($value);
+    my $str = $ret->toString;
+    $self->trace("shift ($token, $str)");
+    return ($token, $ret);
+}
+
+# END LexerBlock
+
+sub parse {
+    my ($self, $sample) = @_;
+    $self->YYData->{INPUT} = $sample;
+    pos $self->YYData->{INPUT} = 0;
+    return $self->YYParse( yylex => \&_Lexer, yyerror => \&_Error, yydebug => $ENV{YYDEBUG} );
+}
+
+sub openTraceFd {
+    my ($self, $fd) = @_;
+    open $self->YYData->{Trace}, '>&', $fd;
+}
+sub closeTrace {
+    my ($self, $fd) = @_;
+    close $self->YYData->{Trace};
+}
+sub trace {
+    my($self, $str) = @_;
+    if ($self->YYData->{Trace}) {
+	&utf8::encode($str);
+	print {$self->YYData->{Trace}} "$str\n";
+    }
+}
+sub traceProduction {
+    my($self, $prod, @parms) = @_;
+    if ($self->YYData->{Trace}) {
+	my $str = "  $prod:";
+	my @lines;
+	while (@parms) {
+	    my ($parmName, $parmVal) = (shift @parms, shift @parms);
+
+	    if (UNIVERSAL::isa($parmVal, '_GenProduction')) {
+
+		# Enumerate elements of *, +, ? and () productions.
+		$str .= sprintf(" %s(%d)", $parmName, scalar @$parmVal);
+		for (my $i = 0; $i < @$parmVal; $i++) {
+		    push (@lines, sprintf("    %s(%d): %s", $parmName, $i, join(' ', $parmVal->[$i]->toString)));
+		}
+	    } else {
+
+		# Display singleton properties via their toString form.
+		$str .= sprintf(" %s(%d)", $parmName, 1);
+		push (@lines, sprintf("    %s(%d): %s", $parmName, 0, join(' ', $parmVal->toString)));
+	    }
+	}
+	$str = join("\n", $str, @lines);  
+	&utf8::encode($str);
+	print {$self->YYData->{Trace}} "$str\n";
+    }
+}
+
+require Exporter;
+use vars qw ( @EXPORT );
+push (@ISA, qw ( Exporter ));
+@EXPORT = qw(&test);
+
+sub test {
+    if (@ARGV < 1) {
+	local $/ = undef;
+	&testFile(<STDIN>, $ENV{TRACE_FD});
+    } else {
+	foreach my $file (@ARGV) {
+	    open(F, $file) || die "unable to open input $file: $!\n";
+	    local $/ = undef;
+	    &testFile(<F>, $ENV{TRACE_FD});
+	    close (F);
+	}
+    }
+}
+sub testFile {
+    my ($sample, $traceFd) = @_;
+    my $parser = $LanguageName->new();
+    &utf8::decode($sample);
+    if ($ENV{TRACE_FD}) {
+	$parser->openTraceFd($ENV{TRACE_FD});
+    }
+    eval {
+	my $root = $parser->parse($sample);
+	my $text = $root->toXML('', {
+	 '' => 'http://www.w3.org/2005/01/yacker/uploads/$LanguageName/', 
+	 'yacker' => 'http://www.w3.org/2005/01/yacker/'});
+
+	# @@@ you may need to comment this for command line processing.
+	&utf8::encode($text);
+
+	print "$text\n";
+    };
+    my $lastError = $@;
+    if ($ENV{TRACE_FD}) {
+	$parser->closeTrace();
+    }
+    if ($lastError) {
+	die $lastError;
+    }
+}
+
+1;
+
+__END__
+
+=head1 $LanguageName
+
+$LanguageName - parse some language.
+
+=head1 SYNOPSIS
+
+    my ($sample) = $ARGV[0];
+    &utf8::decode($sample);
+    my $parser = new $LanguageName();
+    my $root = $parser->parser($sample);
+    my $text = $root->toXML('', {
+	 '' => 'http://www.w3.org/2005/01/yacker/uploads/$LanguageName/', 
+	 'yacker' => 'http://www.w3.org/2005/01/yacker/'});
+    &utf8::encode($text);
+    print "$text\n";
+
+=head1 DESCRIPTION
+
+Yacker needs to encode rule patterns in [a-zA-Z_]+ so it reserves symbols starting with '_'. This parser reverses the process.
+
+This module was generated by W3C::Grammar::bin::yacker.
+
+
+=head1 API
+
+This function supplies a single parsing function. The methods of the returned object are described below.
+
+=head2 parse($sample)
+
+Returns an array of objects parsed into the language given to yacker.
+
+=head2 returned object
+
+The returned objects are blessed subclasses of _Production. They have the following functions:
+
+=head3 toString
+
+Return a ' '-separated "normalization" of the parsed $sample.
+
+=head3 toXML
+
+Return an XML parse tree of the parsed $sample.
+
+
+=head1 TESTING/DEBUGGING
+
+    TRACE_FD=3 perl -M$LanguageName -e test < sample.in 3> sample.trace
+or
+    TRACE_FD=3 perl -M$LanguageName -e test sample 3> sample.trace
+
+which should return a parse tree for the given language.
+
+Setting the trace file descriptor to 1 will send the trace output to stdout.
+    TRACE_FD=1
+Leaving it unset will suppress the trace output.
+
+
+=head1 BUGS
+
+The web interface to yacker requires the results to be encoded:
+  &utf8::encode($text)
+
+Many shells do not expect this so you may need to comment it out. You
+may search for the "@@@" above to find the line in sub test.
+
+
+=head1 AUTHOR
+
+$LanguageName author: unknown
+yacker author: Eric Prud'hommeaux <eric@w3.org>
+
+=head1 SEE ALSO
+
+W3C::Grammar::bin::yacker(1)
+
+=cut
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/bin/regTest	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,26 @@
+#!/usr/bin/perl
+
+use strict;
+
+sub ToFold {
+  print join (', ', @_),"\n";
+  return 1;
+}
+
+sub test {
+  my ($test, $regexp, $fold) = @_;
+  if ($fold) {
+    print $test =~ m/\G($regexp)/gci;
+  } else {
+    print $test =~ m/\G($regexp)/gc;
+  }
+  print "\n";
+}
+
+my $IT_prefix = "prefix";
+my $T_NCCHAR1 = "(?:(?:(?:(?:(?:(?:(?:(?:(?:(?:(?:[A-Z])|(?:[a-z]))|(?:[\x{00C0}-\x{00D6}]))|(?:[\x{00D8}-\x{00F6}]))|(?:[\x{00F8}-\x{02FF}]))|(?:[\x{0370}-\x{037D}]))|(?:[\x{037F}-\x{1FFF}]))|(?:[\x{200C}-\x{200D}]))|(?:[\x{2070}-\x{218F}]))|(?:[\x{2C00}-\x{2FEF}]))|(?:[\x{3001}-\x{D7FF}]))|(?:[\x{F900}-\x{FFFE}])";
+my $T_Q_URIref = "<(?:[^> ])*>"; # /* A URI relative reference : RFC 3896 :/*
+
+&test('prefix foo bar', $IT_prefix, 1);
+&test('asfd hibby hop', $T_NCCHAR1, 0);
+&test('<as#fd> hibby hop', $T_Q_URIref, 0);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/bin/scanTests	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,259 @@
+#!/usr/bin/perl
+
+# scanTests -- scan DAWG tests for what grammar productions they hit
+# $Id: scanTests,v 1.6 2007-01-16 18:58:33 eric Exp $
+
+#my $PARSER_INVOCATION = 'perl -M/Users/eric/perl/modules/W3C/Grammar/bin/uploads/SPARQL/SPARQL.pm -e test';
+my $PARSER_INVOCATION; # = "perl -I$path -MSPARQL -e test";
+my $REPORT_MISSING = 1;
+my $SHOW_MAPPINGS = 0;
+my $WATCH_PRODUCTION = '999_O_QVar_E_Plus_Or_QGT_TIMES_E_C';
+
+use strict;
+use utf8;
+use constant facet => 0;
+use constant type => 1;
+use constant example => 2;
+use constant prodName => 3;
+use constant prodURI => 4;
+use constant yaccProd => 5;
+use constant rule => 6;
+use constant regexp => 7;
+use constant yaccProdStr => 8;
+use constant ruleStr => 9;
+
+use W3C::Util::Exception;
+use W3C::Util::Filter;
+use W3C::Grammar::YackerTraceParser;
+use W3C::Grammar::YaccParser;
+use SPARQL;
+
+
+my $facets = {};
+my $SEP = '│'; # chr(9474);
+my $FacetsNS = 'http://www.w3.org/2001/sw/DataAccess/tests/facets#';
+my $TypesNS = 'http://www.w3.org/2001/sw/DataAccess/tests/#';
+my $UseType = 'types:DAWGfacet';
+my $IgnoreType = 'types:xDAWGfacet';
+
+sub main {
+    my ($argv) = @_;
+    local($SIG{"__DIE__"}) = \&DieHandler;
+    eval {
+	&readFacets(shift @$argv, $facets);
+	foreach my $file (@$argv) {
+	    print "$file\n";
+	    &testQuery($file, $facets, "$file.dump");
+	    print "--------------------\n";
+	}
+	if ($REPORT_MISSING) {
+	    foreach my $productionName (sort keys %$facets) {
+		next if ($productionName =~ m/^_Q(.*?)_E$/ && $facets->{$1});
+		next if ($productionName =~ m/^_O(.*?)_C$/ && $facets->{$1});
+		if (!$facets->{$productionName}[0]) {
+		    foreach my $facet (@{$facets->{$productionName}[1]}) {
+			print "!$facet->[facet] $facet->[example]\n";
+		    }
+		}
+	    }
+	}
+    }; if ($@) {
+	if (my $ex = &catch('W3C::Util::Exception')) {
+	    die $ex->toString();
+	} else {
+	    die $@;
+	}
+    }
+}
+
+sub readFacets {
+    my ($facetsFile, $facets) = @_;
+    my $facetsText = &readFile($facetsFile, 'query file');
+    open(F, "<:utf8", $facetsFile) || die "could not open facets \"$facetsFile\": $!";
+    foreach my $facet (<F>) {
+	if ($facet =~ m/^$SEP *<(.*?)> *$SEP *<(.*?)> *$SEP *"(.*?)" *$SEP *"(.*?)" *$SEP *<(.*?)> *$SEP *(?:"(.*?)"|NULL) *$SEP *(?:"(.*?)"|NULL) *$SEP *(?:"(.*?)"|NULL) *$SEP$/) {
+	    my ($facetName, $type, $example, $prodName, $prodURI, $yaccProd, $rule, $regexp) = ($1, $2, $3, $4, $5, $6, $7, $8);
+	    $facetName =~ s{$FacetsNS}{test:};
+	    $type =~ s{$TypesNS}{types:};
+	    next if ($type ne $UseType);
+	    my ($ruleStr, $yaccProdStr) = ($rule, $yaccProd);
+	    my $lookFors;
+	    if (defined $rule) {
+		$ruleStr = $rule;
+		$rule = &getProductionName($rule, $facetsFile);
+		if ($SHOW_MAPPINGS && $rule ne $ruleStr) {print "rule: $facetName $ruleStr -> $rule\n";}
+	    }
+	    if (defined $yaccProd) {
+		$yaccProdStr = $yaccProd;
+		$yaccProd = &getProductionName($yaccProd, $facetsFile);
+		if ($SHOW_MAPPINGS && $yaccProd ne $yaccProdStr) {print "yaccProd: $facetName $yaccProdStr -> $yaccProd\n";}
+		push (@$lookFors, $yaccProd);
+		push (@$lookFors, "_Q${yaccProd}_E");
+		push (@$lookFors, "_O${yaccProd}_C");
+	    } else {
+		push (@$lookFors, $prodName);
+	    }
+	    foreach my $lookFor (@$lookFors) {
+		if (exists $facets->{$lookFor}) {
+		    push (@{$facets->{$lookFor}[1]}, [$facetName, $type, $example, $prodName, $prodURI, $yaccProd, $rule, $regexp, $yaccProdStr, $ruleStr]);
+		} else {
+		    $facets->{$lookFor} = [0, [[$facetName, $type, $example, $prodName, $prodURI, $yaccProd, $rule, $regexp, $yaccProdStr, $ruleStr]]];
+		}
+	    }
+	}
+    }
+    close(F);
+}
+
+sub getProductionName {
+    my ($rule, $filename) = @_;
+    my $p = new W3C::Grammar::YaccParser(1); # no integrity check
+    $p->setFilename($filename);
+    $p->fake('bodyTransition');
+    my ($g, $errs) = $p->Parse("__foo: $rule", 0x00);
+    my $gen = new W3C::Grammar::GenSpec::Perl();
+    $g->toString(Stubs => $gen, GenSpec => $gen, EndProductionString => '');
+    return $g->getProductionByName($g->getStartProductionName())->getProductionName();
+}
+
+sub testQuery {
+    my ($queryFile, $facets, $dumpTrace) = @_;
+
+    my $queryText = &readFile($queryFile, 'query file');
+
+    # Run parser and get production trace.
+    my $path = 'uploads/SPARQL';
+    my ($results, $error, $trace);
+    if (defined $PARSER_INVOCATION) {
+	my $env = {TRACE_FD => 3};
+	W3C::Util::FilterN->new([$queryText, \$results, \$error, \$trace], 
+				[\*STDIN, \*STDOUT, \*STDERR], 2)->
+				    execute($PARSER_INVOCATION, $env, 65536);
+    } else {
+	eval {
+	    &utf8::decode($queryText);
+	    my $parser = new SPARQL();
+	    my $root = $parser->parse($queryText)->[0];
+	    $trace = $parser->getTrace();
+	    my $text = $root->toXML('');
+	    &utf8::encode($text);
+	};
+	$error = $@;
+    }
+    if ($error) {
+	print "error parsing $queryFile: $error\n";
+	return;
+    }
+    if ($dumpTrace) {
+	if (open(T, ">:utf8", $dumpTrace)) {
+	    print T $trace;
+	    close T;
+	    print sprintf("created $dumpTrace: \n", length $trace);
+	} else {
+	    warn "unable to open trace file \"$dumpTrace\": $!\n";
+	}
+    }
+    my $parser = new W3C::Grammar::YackerTraceParser(-noErrors => 1);
+    $parser->parse($trace);
+
+    # Check each production to see if it matches a facet.
+    my $c = @{$parser->getProductions()};
+    foreach my $production (@{$parser->getProductions()}) {
+	my $productionName = $production->getProduction();
+	if ($productionName eq $WATCH_PRODUCTION) {
+	    print "$productionName refd $facets->{$productionName}[0] times\n";
+	    my $count = @{$production->getRules()};
+	    print "$count rules\n";
+	}
+	foreach my $rule (@{$production->getRules()}) {
+	    my $match = join(' ', map {$_->getMatch()} @{$rule->getMatched()});
+	    if ($facets->{$productionName}) {
+		if ($productionName eq $WATCH_PRODUCTION) {
+		    print "RULE:".$rule->getRule()." $match\n";
+		}
+		my $possibleFacets = $facets->{$productionName}[1];
+		my $remainingFacets = [];
+		foreach my $possibleFacet (@$possibleFacets) {
+		    if ($productionName eq $WATCH_PRODUCTION) {
+			print $possibleFacet->[rule].' vs '.$rule->getRule()."\n";
+			my $match999 = (!defined $possibleFacet->[rule] || $possibleFacet->[rule] eq $rule->getRule()) ? 'true' : 'false';
+			print "rule: $match999\n";
+		    }
+		    my $ruleStr = $rule->getRule();
+		    if ((!defined $possibleFacet->[rule] || ($possibleFacet->[rule] eq $ruleStr || 
+							     $possibleFacet->[rule] eq "_Q${ruleStr}_E" || 
+							     $possibleFacet->[rule] eq "_O${ruleStr}_C")) &&
+			(!defined $possibleFacet->[regexp] || $match =~ m/$possibleFacet->[regexp]/)) {
+			my $prodStr = defined $possibleFacet->[yaccProd] ? "$possibleFacet->[yaccProdStr]" : "$possibleFacet->[prodName]";
+			my $ruleStr = defined $possibleFacet->[rule] ? " rule: $possibleFacet->[ruleStr]" : '';
+			my $regexpStr = defined $possibleFacet->[regexp] ? " regexp: $possibleFacet->[regexp]" : '';
+			my $whyStr = "$prodStr$ruleStr$regexpStr";
+			push (@$remainingFacets, [$possibleFacet, $ruleStr, $match, $whyStr]);
+		    }
+		}
+		if (!@$remainingFacets) {
+		} elsif (@$remainingFacets == 1) {
+		    print "$remainingFacets->[0][0][facet] matched $remainingFacets->[0][3] \"$remainingFacets->[0][2]\"\n";
+		    if ($productionName =~ m/^_Q(.*?)_E$/) {
+			$facets->{$1}[0]++;
+		    } elsif ($productionName =~ m/^_O(.*?)_C$/) {
+			$facets->{$1}[0]++;
+		    } else {
+			$facets->{$productionName}[0]++;
+		    }
+		} else { # @$remainingFacets > 1
+		    print "find \"$match\" in\n";
+		    foreach my $remainingFacet (@$remainingFacets) {
+			print "  $remainingFacet->[0][facet]:$remainingFacet->[3]: $remainingFacet->[example]\n";
+		    }
+		}
+	    }
+	}
+    }
+}
+
+
+sub readFile {
+    my ($file, $type) = @_;
+    open(F, "<:utf8", $file) || die "could not open $type \"$file\": $!";
+    local $/ = undef;
+    my $text = <F>;
+    close F;
+    return $text;
+}
+
+&main(\@ARGV);
+
+# $Log: scanTests,v $
+# Revision 1.6  2007-01-16 18:58:33  eric
+# - give up on warnings (two parsers and regexp range exclusion)
+# + conrol behavoir with constants at the top
+# ~ facets uses grammar strings instead of generated names
+# + exception support
+# + stupid _Q.*?_E hacks
+# + invoke SPARQL module directly
+# + $WATCH_PRODUCTION
+# ~ improve feedback
+#
+# Revision 1.5  2007/01/10 03:28:04  eric
+# + scan multiple files
+# + comments
+# + improve ambiguous feature selection feedback
+# + handle errors
+#
+# Revision 1.4  2007/01/09 12:43:38  eric
+# + split out YackerTraceParser
+# + store and show match info
+#
+# Revision 1.3  2007/01/03 21:16:12  eric
+# + changed field names
+# + type
+# ~ new ambiguity presenter
+#
+# Revision 1.2  2007/01/02 11:19:02  eric
+# snapshot
+#
+# Revision 1.1  2007/01/01 13:55:26  eric
+# created
+#
+# 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/CPPYacc/Langname_Parser.yy	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,543 @@
+/* $Id: Langname_Parser.yy,v 1.8 2008-04-21 01:46:20 eric Exp ${Langname}Parser.yy 19 2007-08-19 20:36:24Z tb $ -*- mode: c++ -*- */
+/** \file ${Langname}Parser.yy Contains the Bison parser source */
+
+/*** yacc/bison Declarations ***/
+
+/* Require bison 2.3 or later */
+%require "2.3"
+
+/* add debug output code to generated parser. disable this for release
+ * versions. */
+%debug
+
+/* start symbol is named "start" */
+%start ${Startname}
+
+/* write out a header file containing the token defines */
+%defines
+
+/* use newer C++ skeleton file */
+%skeleton "lalr1.cc"
+
+/* namespace to enclose parser in */
+%name-prefix="${Langname}NS"
+
+/* set the parser's class identifier */
+%define "parser_class_name" "${Langname}Parser"
+
+/* keep track of the current position within the input */
+%locations
+%initial-action
+{
+    // initialize the initial location object
+    @$.begin.filename = @$.end.filename = &driver.streamname;
+};
+
+/* The driver is passed by reference to the parser and to the scanner. This
+ * provides a simple but effective pure interface, not relying on global
+ * variables. */
+%parse-param { class Driver& driver }
+
+/* verbose error messages */
+%error-verbose
+
+%{ /*** C/C++ Declarations ***/
+
+extern std::ostream* _Trace;
+
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <vector>
+#include <exception>
+#include <cassert>
+
+/* START ClassBlock */
+namespace yacker {
+class _Base {
+private:
+    const char* productionName;
+public:
+    _Base (const char* productionName) : productionName(productionName) { }
+    const char* getProductionName() { return productionName; };
+    virtual std::string toStr(std::ofstream* out = NULL) = 0;
+    virtual std::string toXml(size_t depth, std::ofstream* out = NULL) = 0;
+    virtual size_t size () { return 1; }
+    virtual _Base* getElement (size_t) { return this; }
+    virtual ~_Base() { }
+};
+class _Production : public _Base {
+protected:
+    _Production (const char* productionName) : _Base(productionName) { }
+    void makeArray(_Base** target[], ...);
+    void trace(unsigned creditToSelf = 0);
+public:
+    virtual bool transparent() { return false; } // in general, productions are not transparent.
+    virtual _Base* operator [] (size_t i) = 0;
+    virtual _Base* getElement (size_t i) = 0;
+    virtual std::string toStr(std::ofstream* out = NULL);
+    virtual std::string toXml(size_t depth, std::ofstream* out = NULL);
+};
+
+class _GenProduction : public _Production {
+protected:
+    _GenProduction (const char* productionName) : _Production(productionName) { }
+    ~_GenProduction () {}
+};
+
+extern bool TransparentGroupProductions;
+extern bool TransparentMultiplicityProductions;
+template <typename T> class _ProductionVector : public _GenProduction {
+    std::vector<T> data;
+public:
+    _ProductionVector (const char* productionName) : _GenProduction(productionName) {
+	trace();
+    }
+    _ProductionVector (const char* productionName, T v) : _GenProduction(productionName) {
+	data.push_back(v);
+	trace(size()-1);
+    }
+    ~_ProductionVector () {
+	for (size_t i = 0; i < size(); i++)
+	    delete data[i];
+    }
+    virtual bool transparent() { return TransparentMultiplicityProductions; }
+
+    void push_back(T v) {
+	data.push_back(v);
+	trace(size()-1);
+    }
+    size_t size() { return data.size(); }
+    virtual T operator [] (size_t i) { return data[i]; }
+    _Base* getElement (size_t i) { return data[i]; }
+};
+class _GroupProduction : public _GenProduction {
+protected:
+    _GroupProduction (const char* productionName) : _GenProduction (productionName) { }
+    virtual bool transparent() { return TransparentGroupProductions; }
+};
+class _Token : public _Base {
+private:
+    const char* matched;
+
+protected:
+    _Token (const char* productionName, const char* matched) : _Base(productionName), matched(copyOf(matched)) { }
+public:
+    ~_Token () { delete[] matched; }
+
+protected:
+    void trace();
+
+private:
+    static char* copyOf (const char* copyMe) {
+	char* ret = new char[strlen(copyMe)+1];
+	strcpy(ret, copyMe);
+	return ret;
+    }
+public:
+    virtual std::string toStr(std::ofstream* out = NULL);
+    virtual std::string toXml(size_t depth, std::ofstream* out = NULL);
+};
+class _Terminal : public _Base {
+protected:
+    const char* terminal;
+    _Terminal (const char* productionName, const char* p) : _Base(productionName) {
+	terminal = new char[strlen(p) + 1];
+	strcpy((char*)terminal, p); // @@ should initialize as member
+    }
+    ~_Terminal () {
+	delete[] terminal;
+    }
+    void trace();
+public:
+    virtual std::string toStr(std::ofstream* out = NULL);
+    virtual std::string toXml(size_t depth, std::ofstream* out = NULL);
+};
+
+} // namespace yacker
+
+namespace ${Langname}NS {
+${ProductionClassDecls}
+${TerminalClassDecls}
+
+${ProductionClasses}
+${TerminalClasses}
+}
+class ProgramFlowException : public std::exception  {
+private:
+    const char* msg;
+public:
+    ProgramFlowException(const char* msg) : msg(msg) { }
+
+    // This declaration is not useless:
+    // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
+    virtual ~ProgramFlowException() throw() { }
+
+    // See comment in eh_exception.cc.
+    virtual const char* what () { return msg; }
+};
+/* END ClassBlock */
+
+namespace ${Langname}NS {
+
+/** The Driver class brings together all components. It creates an instance of
+ * the ${Langname}Parser and ${Langname}Scanner classes and connects them. Then the input stream is
+ * fed into the scanner object and the parser gets it's token
+ * sequence. Furthermore the driver object is available in the grammar rules as
+ * a parameter. Therefore the driver class contains a reference to the
+ * structure into which the parsed data is saved. */
+class ${Langname}Context {
+public:
+    ~${Langname}Context()
+    {
+    }
+};
+
+class Driver
+{
+public:
+    /// construct a new parser driver context
+    Driver(${Langname}Context& context);
+
+    /// enable debug output in the flex scanner
+    bool trace_scanning;
+
+    /// enable debug output in the bison parser
+    bool trace_parsing;
+
+    /// stream name (file or input stream) used for error messages.
+    std::string streamname;
+
+    /** Invoke the scanner and parser for a stream.
+     * @param in	input stream
+     * @param sname	stream name for error messages
+     * @return		true if successfully parsed
+     */
+    bool parse_stream(std::istream& in,
+		      const std::string& sname = "stream input");
+
+    /** Invoke the scanner and parser on an input string.
+     * @param input	input string
+     * @param sname	stream name for error messages
+     * @return		true if successfully parsed
+     */
+    bool parse_string(const std::string& input,
+		      const std::string& sname = "string stream");
+
+    /** Invoke the scanner and parser on a file. Use parse_stream with a
+     * std::ifstream if detection of file reading errors is required.
+     * @param filename	input file name
+     * @return		true if successfully parsed
+     */
+    bool parse_file(const std::string& filename);
+
+    // To demonstrate pure handling of parse errors, instead of
+    // simply dumping them on the standard error output, we will pass
+    // them to the driver using the following two member functions.
+
+    /** Error handling with associated line number. This can be modified to
+     * output the error e.g. to a dialog box. */
+    void error(const class location& l, const std::string& m);
+
+    /** General error handling. This can be modified to output the error
+     * e.g. to a dialog box. */
+    void error(const std::string& m);
+
+    /** Pointer to the current lexer instance, this is used to connect the
+     * parser to the scanner. It is used in the yylex macro. */
+    class ${Langname}Scanner* lexer;
+
+    /** Reference to the context filled during parsing of the expressions. */
+    ${Langname}Context& context;
+    ${Goalname}* root;
+};
+
+} // namespace ${Langname}NS
+
+%}
+
+ /*** BEGIN ${Langname} - Change the grammar's tokens below ***/
+
+%union {
+    /* Terminals */
+${TerminalDeclarations}
+    /* Productions */
+${ProductionDeclarations}
+}
+
+%{
+#include "${Langname}Scanner.hh"
+%}
+%token			__EOF__	     0	"end of file"
+/* START TokenBlock */
+/* Terminals */
+${TerminalTokens}
+/* Productions */
+${ProductionTypes}
+/* END TokenBlock */
+
+//%destructor { delete $$; } BlankNode
+
+ /*** END ${Langname} - Change the grammar's tokens above ***/
+
+%{
+#include <stdarg.h>
+#include "${Langname}Scanner.hh"
+
+/* this "connects" the bison parser in the driver to the flex scanner class
+ * object. it defines the yylex() function call to pull the next token from the
+ * current lexer object of the driver context. */
+#undef yylex
+#define yylex driver.lexer->lex
+%}
+
+%% /*** Grammar Rules ***/
+
+ /*** BEGIN ${Langname} - Change the grammar rules below ***/
+${ProductionActions}
+
+ /*** END ${Langname} - Change the grammar rules above ***/
+
+%% /*** Additional Code ***/
+
+void ${Langname}NS::${Langname}Parser::error(const ${Langname}Parser::location_type& l,
+			    const std::string& m)
+{
+    driver.error(l, m);
+}
+
+/* START yacker-specific test harness */
+
+namespace yacker {
+std::ostream* _Trace = NULL;
+
+std::string _Production::toStr(std::ofstream* out) {
+    std::stringstream ret;
+    for (size_t i = 0; i < size(); i++) {
+	if (i > 0)
+	    ret << " ";
+	ret << getElement(i)->toStr(out);
+    }
+    return ret.str();
+}
+
+#define TAB "  "
+char const * yit = "yacker:implicit-terminal";
+#define ns "\n xmlns=\"http://www.w3.org/2005/01/yacker/uploads/${Langname}/\"\n xmlns:yacker=\"http://www.w3.org/2005/01/yacker/\""
+
+std::string _Production::toXml (size_t depth, std::ofstream* out) {
+    std::stringstream ret;
+    if (!transparent()) {
+	for (size_t i = 0; i < depth; i++)
+	    ret << TAB;
+	ret << "<" << getProductionName() << ">" << std::endl;
+    }
+    for (size_t i = 0; i < size(); i++) {
+	_Base* base = getElement(i);
+	if (base != NULL)
+	    ret << base->toXml(transparent() ? depth : depth+1, out);
+    }
+    if (!transparent()) {
+	for (size_t i = 0; i < depth; i++)
+	    ret << TAB;
+	ret << "</" << getProductionName() << ">" << std::endl;
+    }
+    return ret.str();
+}
+
+void _Production::makeArray (_Base** target[], ...) {
+    va_list bases;
+    va_start(bases, target);
+    for (size_t argNo = 0; argNo < size(); argNo++)
+	target[argNo] = va_arg(bases, _Base**);
+    va_end(bases);    
+}
+void _Production::trace (unsigned creditToSelf) {
+    if (!_Trace)
+	return;
+    *_Trace << "  " << getProductionName() << ":";
+    if (creditToSelf > 0)
+	*_Trace << " " << getProductionName() << "(" << creditToSelf << ")";
+
+    for (size_t argNo = creditToSelf; argNo < size(); argNo++) {
+	_Base* parm = getElement(argNo);
+	*_Trace << " " << parm->getProductionName() << "(" << parm->size() << ")";
+    }
+    *_Trace << std::endl;
+
+    for (size_t argNo = 0; argNo < size(); argNo++) {
+	_Base* parm = getElement(argNo);
+	size_t parmSize = parm->size();
+	for (size_t j = 0; j < parmSize; j++)
+	    *_Trace << "    " << (creditToSelf && argNo < size()-1 ? getProductionName() : parm->getProductionName()) << "(" << (creditToSelf && argNo < size()-1 ? argNo : j) << "): " << parm->getElement(j)->toStr() << std::endl;
+    }
+}
+
+void _Token::trace() {
+    if (!_Trace)
+	return;
+    *_Trace << "shift (" << getProductionName() << ", " << matched << ")" << std::endl;
+}
+
+void _Terminal::trace() {
+    if (!_Trace)
+	return;
+    *_Trace << "shift (" << getProductionName() << ", " << terminal << ")" << std::endl;
+}
+
+std::string _Token::toStr(std::ofstream*) {
+    std::string ret(matched);
+    return ret;
+}
+std::string _Token::toXml(size_t depth, std::ofstream*) {
+    std::stringstream ret;
+    for (size_t i = 0; i < depth; i++)
+	ret << TAB;
+    ret << "<" << yit << ">" << matched << "</" << yit << ">" << std::endl;
+    return ret.str();
+}
+
+std::string _Terminal::toStr(std::ofstream*) {
+    std::string ret(terminal);
+    return ret;
+}
+std::string _Terminal::toXml(size_t depth, std::ofstream*) {
+    std::stringstream ret;
+    for (size_t i = 0; i < depth; i++)
+	ret << TAB;
+    ret << "<" << getProductionName() << ">" << terminal << "</" << getProductionName() << ">" << std::endl;
+    return ret.str();
+}
+
+} // namespace yacker
+
+/* END yacker-specific test harness */
+
+/* START Driver (@@ stand-alone would allow it to be shared with other parsers */
+
+namespace ${Langname}NS {
+
+Driver::Driver(class ${Langname}Context& _context)
+    : trace_scanning(false),
+      trace_parsing(false),
+      context(_context)
+{
+}
+
+bool Driver::parse_stream(std::istream& in, const std::string& sname)
+{
+    streamname = sname;
+
+    ${Langname}Scanner scanner(&in);
+    scanner.set_debug(trace_scanning);
+    this->lexer = &scanner;
+
+    ${Langname}Parser parser(*this);
+    parser.set_debug_level(trace_parsing);
+    return (parser.parse());
+}
+
+bool Driver::parse_file(const std::string &filename)
+{
+    std::ifstream in(filename.c_str());
+    return parse_stream(in, filename);
+}
+
+bool Driver::parse_string(const std::string &input, const std::string& sname)
+{
+    std::istringstream iss(input);
+    return parse_stream(iss, sname);
+}
+
+void Driver::error(const class location& l,
+		   const std::string& m)
+{
+    std::cerr << l << ": " << m << std::endl;
+}
+
+void Driver::error(const std::string& m)
+{
+    std::cerr << m << std::endl;
+}
+
+${ProductionDestructors}
+} // namespace ${Langname}NS
+
+/* END Driver */
+
+/* START main */
+
+#include <stdio.h>
+// #include "${Langname}Frob.h"
+
+#include <stdlib.h>
+#include <ostream>
+#include <fstream>
+
+#ifdef HAVE_BOOST
+#include <boost/iostreams/stream.hpp>
+#include <boost/iostreams/device/file_descriptor.hpp>
+#endif /* HAVE_BOOST */
+
+bool yacker::TransparentGroupProductions = false;
+bool yacker::TransparentMultiplicityProductions = false;
+
+int main(int argc,char** argv) {
+
+    ${Langname}NS::${Langname}Context context;
+    ${Langname}NS::Driver driver(context);
+
+#ifdef HAVE_BOOST
+    boost::iostreams::stream_buffer<boost::iostreams::file_descriptor_sink>* buf = NULL;
+    if (char* tmp = getenv("TRACE_FD")) {
+	std::istringstream is(tmp);
+	int fd;
+	is >> fd;
+	buf = new boost::iostreams::stream_buffer<boost::iostreams::file_descriptor_sink>(fd);
+	if (!(yacker::_Trace = new std::ostream(buf)))
+	    std::cerr << "couldn't open trace fd " << fd << std::endl;
+    }
+#endif /* HAVE_BOOST */
+
+    std::istream* yyin;
+    const char* inputId;
+    if (argc > 1) {
+	inputId = argv[1];
+	yyin = new std::ifstream(argv[1], std::ifstream::in);
+    } else {
+	inputId = "<stdin>";
+	yyin = &std::cin;
+    }
+
+    std::string str(inputId);
+    int result = driver.parse_stream(*yyin, str);
+
+    if (argc > 1)
+	delete yyin;
+
+    if (result)
+	std::cerr << "Error: " << inputId << " did not contain a valid SPARQLfed string." << std::endl;
+    else {
+	try {
+	    std::string xml = driver.root->toXml(0);
+	    std::cout << xml;
+	    delete driver.root;
+	} catch (ProgramFlowException& e) {
+	    std::cout << "Standard exception: " << e.what() << std::endl;
+	} catch (std::exception& e) {
+	    std::cout << "Standard exception: " << e.what() << std::endl;
+	}
+    }
+
+#ifdef HAVE_BOOST
+    delete buf; // this delete breaks cout!
+#endif /* HAVE_BOOST */
+
+    if (yacker::_Trace)
+	delete yacker::_Trace;
+
+    return result;
+};
+
+/* END main */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/CPPYacc/Langname_Scanner.hh	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,60 @@
+// $Id: Langname_Scanner.hh,v 1.1 2008-04-06 17:10:46 eric Exp $
+
+#ifndef ${Langname}Scanner_H
+#define ${Langname}Scanner_H
+
+// Flex expects the signature of yylex to be defined in the macro YY_DECL, and
+// the C++ parser expects it to be declared. We can factor both as follows.
+
+#ifndef YY_DECL
+
+#define	YY_DECL						\
+    ${Langname}NS::${Langname}Parser::token_type				\
+    ${Langname}NS::${Langname}Scanner::lex(				\
+	${Langname}NS::${Langname}Parser::semantic_type* yylval,		\
+	${Langname}NS::${Langname}Parser::location_type* yylloc		\
+    )
+#endif
+
+#ifndef __FLEX_LEXER_H
+#define yyFlexLexer ${Langname}FlexLexer
+#include "FlexLexer.h"
+#undef yyFlexLexer
+#endif
+
+#include "${Langname}Parser.hh"
+
+namespace ${Langname}NS {
+
+/** ${Langname}Scanner is a derived class to add some extra function to the scanner
+ * class. Flex itself creates a class named yyFlexLexer, which is renamed using
+ * macros to ${Langname}FlexLexer. However we change the context of the generated
+ * yylex() function to be contained within the ${Langname}Scanner class. This is required
+ * because the yylex() defined in ${Langname}FlexLexer has no parameters. */
+class ${Langname}Scanner : public ${Langname}FlexLexer
+{
+public:
+    /** Create a new scanner object. The streams arg_yyin and arg_yyout default
+     * to cin and cout, but that assignment is only made when initializing in
+     * yylex(). */
+    ${Langname}Scanner(std::istream* arg_yyin = 0,
+	    std::ostream* arg_yyout = 0);
+
+    /** Required for virtual functions */
+    virtual ~${Langname}Scanner();
+
+    /** This is the main lexing function. It is generated by flex according to
+     * the macro declaration YY_DECL above. The generated bison parser then
+     * calls this virtual function to fetch new tokens. */
+    virtual ${Langname}Parser::token_type lex(
+	${Langname}Parser::semantic_type* yylval,
+	${Langname}Parser::location_type* yylloc
+	);
+
+    /** Enable debug output (via arg_yyout) if compiled into the scanner. */
+    void set_debug(bool b);
+};
+
+} // namespace ${Langname}NS
+
+#endif // ${Langname}Scanner_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/CPPYacc/Langname_Scanner.ll	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,102 @@
+/* $Id: Langname_Scanner.ll,v 1.1 2008-04-06 17:10:46 eric Exp ${Langname}Scanner.ll 28 2007-08-20 10:27:39Z tb $ -*- mode: c++ -*- */
+/** \file ${Langname}Scanner.ll Define the Flex lexical scanner */
+
+%{ /*** C/C++ Declarations ***/
+
+#include "${Langname}Parser.hh"
+#include "${Langname}Scanner.hh"
+
+/* import the parser's token type into a local typedef */
+typedef ${Langname}NS::${Langname}Parser::token token;
+typedef ${Langname}NS::${Langname}Parser::token_type token_type;
+
+/* Work around an incompatibility in flex (at least versions 2.5.31 through
+ * 2.5.33): it generates code that does not conform to C89.  See Debian bug
+ * 333231 <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.  */
+#undef yywrap
+#define yywrap()	1
+
+/* By default yylex returns int, we use token_type. Unfortunately yyterminate
+ * by default returns 0, which is not of token_type. */
+#define yyterminate() return token::__EOF__
+
+/* This disables inclusion of unistd.h, which is not available under Visual C++
+ * on Win32. The C++ scanner uses STL streams instead. */
+#define YY_NO_UNISTD_H
+
+%}
+
+/*** Flex Declarations and Options ***/
+
+/* enable c++ scanner class generation */
+%option c++
+
+/* change the name of the scanner class. results in "${Langname}FlexLexer" */
+%option prefix="${Langname}"
+
+/* the manual says "somewhat more optimized" */
+%option batch
+
+/* enable scanner to generate debug output. disable this for release
+ * versions. */
+%option debug
+
+/* no support for include files is planned */
+%option noyywrap nounput 
+
+/* enables the use of start condition stacks */
+%option stack
+
+/* The following paragraph suffices to track locations accurately. Each time
+ * yylex is invoked, the begin position is moved onto the end position. */
+%{
+#define YY_USER_ACTION  yylloc->columns(yyleng);
+%}
+
+/* START patterns for ${Langname} terminals */
+${TerminalPatterns}
+/* END patterns for ${Langname} terminals */
+
+/* START semantic actions for ${Langname} terminals */
+%%
+{PASSED_TOKENS}		{ /* yylloc->step(); @@ needed? useful? */ }
+${TerminalActions}
+<<EOF>>			{ yyterminate();}
+%%
+/* END semantic actions for ${Langname} terminals */
+
+/* START ${Langname}Scanner */
+namespace ${Langname}NS {
+
+${Langname}Scanner::${Langname}Scanner(std::istream* in,
+		 std::ostream* out)
+    : ${Langname}FlexLexer(in, out)
+{
+}
+
+${Langname}Scanner::~${Langname}Scanner()
+{
+}
+
+void ${Langname}Scanner::set_debug(bool b)
+{
+    yy_flex_debug = b;
+}
+
+}
+/* END ${Langname}Scanner */
+
+/* This implementation of ${Langname}FlexLexer::yylex() is required to fill the
+ * vtable of the class ${Langname}FlexLexer. We define the scanner's main yylex
+ * function via YY_DECL to reside in the ${Langname}Scanner class instead. */
+
+#ifdef yylex
+#undef yylex
+#endif
+
+int ${Langname}FlexLexer::yylex()
+{
+    std::cerr << "in ${Langname}FlexLexer::yylex() !" << std::endl;
+    return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/CPPYacc/Makefile	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,63 @@
+# $Id: Makefile,v 1.4 2008-04-12 04:10:11 eric Exp $
+
+# recipies:
+#   normal build:
+#     make ${Langname}
+#   force the use of the tracing facilities (and redirect to stdout):
+#     HAVE_BOOST=1 TRACE_FD=1 make -W ${Langname}Parser.yy test
+#   have valgrind start a debugger (works as M-x gdb invocation command):
+#     valgrind --db-attach=yes --leak-check=yes ${Langname} ${Langname}.txt
+#   same, if you aren't working in gdb:
+#     HAVE_BOOST=1 TRACE_FD=1 make valgrind
+#   debugging in emacs:
+#     gdb --annotate=3 ${Langname}    (set args ${Langname}.txt)
+
+ifdef HAVE_BOOST
+LIBS=-lboost_iostreams
+DEFS=-DHAVE_BOOST
+else
+LIBS=
+DEFS=
+endif
+
+GPP=g++ -DYYTEXT_POINTER=1 $(DEFS) -W -Wall -Wextra -ansi -g -c
+LINK=g++ -W -Wall -Wextra -ansi -g $(LIBS) -o
+
+${Langname}Parser.cc ${Langname}Parser.hh location.hh position.hh stack.hh: ${Langname}Parser.yy
+	bison -o ${Langname}Parser.cc ${Langname}Parser.yy
+
+#/bin/sh ../scripts/ylwrap parser.yy y.tab.c parser.cc y.tab.h parser.h y.output parser.output -- bison -y  
+
+${Langname}Scanner.cc: ${Langname}Scanner.ll ${Langname}Parser.hh
+	flex -o ${Langname}Scanner.cc ${Langname}Scanner.ll
+
+#/bin/sh ../scripts/ylwrap scanner.ll lex.yy.c scanner.cc -- flex  -olex.yy.c
+
+${Langname}Parser.o: ${Langname}Parser.cc ${Langname}Parser.hh ${Langname}Scanner.hh
+	$(GPP)  -o ${Langname}Parser.o ${Langname}Parser.cc
+
+${Langname}Scanner.o: ${Langname}Scanner.cc ${Langname}Scanner.hh
+	$(GPP)  -o ${Langname}Scanner.o ${Langname}Scanner.cc
+
+#lib${Langname}.a: ${Langname}Parser.o ${Langname}Scanner.o
+#	ar cru lib${Langname}.a ${Langname}Parser.o ${Langname}Scanner.o
+#	ranlib lib${Langname}.a
+
+#${Langname}Test.o: ${Langname}Test.cc
+#	$(GPP)  -o ${Langname}Test.o ${Langname}Test.cc
+
+#${Langname}Test: ${Langname}Test.o lib${Langname}.a
+#	$(LINK) ${Langname}Test ${Langname}Test.o lib${Langname}.a
+
+${Langname}: ${Langname}Parser.o ${Langname}Scanner.o
+	$(LINK) ${Langname} ${Langname}Parser.o ${Langname}Scanner.o
+
+test: ${Langname}
+	./${Langname} ${Langname}.txt 
+
+valgrind: ${Langname}
+	valgrind --leak-check=yes ./${Langname} ${Langname}.txt 
+
+clean:
+	rm -f ${Langname} lib${Langname}.a ${Langname}Parser.o ${Langname}Scanner.o ${Langname}Parser.cc ${Langname}Parser.hh ${Langname}Scanner.cc location.hh position.hh stack.hh
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/CYacc/Langname_Enums.h	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,35 @@
+typedef enum {
+    _Production = 0, 
+    _GenProduction, 
+    _Constant, 
+    _Terminal
+} Class_e;
+
+typedef struct {
+    const char const * name;
+    size_t size;
+    const Class_e type;
+} Class_t;
+
+/* START ClassBlock */
+typedef enum {
+  _INVISIBLE_, 
+  _TERMINAL_, 
+  /* Productions */
+${ProductionClassDecls}
+  /* Terminals */
+${TerminalClassDecls}
+  } Classes_e;
+extern Class_t Classes[];
+/* END ClassBlock */
+typedef struct semval_s Semval;
+struct semval_s {
+    Classes_e type;
+    size_t size;
+    union {
+	Semval** vals;
+	const char const * str;
+    };
+};
+Semval* constructProduction(const Classes_e type, size_t size, ...);
+Semval* constructTerminal(const Classes_e type, const char const * str);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/CYacc/Langname_Parser.y	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,326 @@
+/* $Id: Langname_Parser.y,v 1.2 2008-04-06 18:15:14 eric Exp ${Langname}Parser.yy 19 2007-08-19 20:36:24Z tb $ -*- mode: c++ -*- */
+/** \file ${Langname}Parser.yy Contains the Bison parser source */
+
+/*** yacc/bison Declarations ***/
+
+/* Require bison 2.3 or later */
+%require "2.3"
+
+/* add debug output code to generated parser. disable this for release
+ * versions. */
+%debug
+
+/* start symbol is named "start" */
+%start ${Startname}
+
+/* write out a header file containing the token defines */
+%defines
+
+/* set the parser's class identifier */
+%define "parser_class_name" "${Langname}Parser"
+
+%{ /*** C/C++ Declarations ***/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <malloc.h>
+#include "${Langname}Enums.h"
+#include "${Langname}Parser.h"
+
+void yyerror(char *m);
+
+int ${Langname}_lex(void);
+void ${Langname}_error(char *);
+typedef struct _Buf {
+    char* data;
+    int len;
+} Buf;
+Buf* makeBuf0 ();
+Buf* makeBuf1 (char *str);
+Buf* makeBuf (int count, ...);
+void destroyBuf (Buf*);
+char *str(Buf*);
+
+Semval* StupidGlobal;
+%}
+%union {
+    Semval* semval;
+};
+
+/* START TokenBlock */
+/* Terminals */
+${TerminalTokens}
+
+/* Productions */
+${ProductionTypes}
+/* END TokenBlock */
+%{
+//#include "${Langname}Driver.hh"
+//#include "${Langname}Scanner.hh"
+//#undef yylex
+#define yylex ${Langname}lex
+%}
+%% /*** Grammar Rules ***/
+
+ /*** BEGIN ${Langname} - Change the grammar rules below ***/
+${ProductionActions}
+
+ /*** END ${Langname} - Change the grammar rules above ***/
+
+%% /*** Additional Code ***/
+
+Class_t Classes[] = {
+    {"_INVISIBLE_", 0, 0}, 
+    {"_TERMINAL_", 0, 0}, 
+    /* Productions */
+${ProductionClasses}
+    /* Terminals */
+${TerminalClasses}
+};
+
+const char const * toString (Semval* semval) {
+    char* ret;
+    const char const ** rets;
+    size_t size = 0;
+    size_t i;
+
+    switch (Classes[semval->type].type) {
+    case _GenProduction:
+    case _Production:
+	if (semval->size == 0)
+	    size = 0;
+	else
+	    rets = malloc(sizeof(const char const *) * semval->size);
+	for (i = 0; i < semval->size; i++) {
+	    rets[i] = toString(semval->vals[i]);
+	    size += 1+strlen(rets[i]);
+	}
+	ret = malloc(size + 1);
+	ret[0] = 0;
+	for (i = 0; i < semval->size; i++) {
+	    strcat(ret, " ");
+	    strcat(ret, rets[i]);
+	}
+	if (semval->size != 0)
+	    free(rets);
+	return ret;
+    case _Constant:
+    case _Terminal:
+	ret = malloc(sizeof(char*)*semval->size + 1);
+	strncpy(ret, semval->str, semval->size + 1);
+	return ret;
+    default:
+	fprintf(stderr, "how do i toString a %d?\n", semval->type);
+    }
+}
+
+#define tab 2
+const char const * yit = "yacker:implicit-terminal";
+#define lyit strlen(yit)
+#define ns "\n xmlns=\"http://www.w3.org/2005/01/yacker/uploads/katherine/\"\n xmlns:yacker=\"http://www.w3.org/2005/01/yacker/\""
+#define lns sizeof(ns)-1	/* strlen(ns) */
+
+const char const * toXml (Semval* semval, unsigned depth) {
+    char* ret;
+    const char const ** rets;
+    size_t size = 0;
+    size_t i;
+
+    unsigned leaderLen = depth*tab;
+    char* leader = malloc(leaderLen+1);
+    for (i = 0; i < leaderLen; i++) leader[i] = ' ';
+    leader[leaderLen] = 0;
+
+    switch (Classes[semval->type].type) {
+    case _GenProduction:
+    case _Production:
+	/* Calculate size of namespaces and embedded elements. */
+	if (semval->size == 0)
+	    size = 0;
+	else
+	    rets = malloc(sizeof(const char const *) * semval->size);
+	for (i = 0; i < semval->size; i++) {
+	    rets[i] = toXml(semval->vals[i], Classes[semval->type].type == _Production ? depth+1 : depth);
+	    size += strlen(rets[i]);
+	}
+	if (depth == 0)
+	    size += lns;
+
+	ret = malloc(leaderLen*2 + Classes[semval->type].size*2+8 + size);
+	if (Classes[semval->type].type == _Production)
+	    sprintf(ret, "%s<%s%s>\n", leader, Classes[semval->type].name, depth == 0 ? ns : "");
+	else
+	    ret[0] = 0;
+
+	for (i = 0; i < semval->size; i++)
+	    strcat(ret, rets[i]);
+
+	if (semval->size != 0)
+	    free(rets);
+	if (Classes[semval->type].type == _Production)
+	    sprintf(ret+leaderLen+1+Classes[semval->type].size+2+size, "%s</%s>\n", leader, Classes[semval->type].name);
+	break;
+    case _Constant:
+	ret = malloc(leaderLen+lyit*2+6 + semval->size);
+	sprintf(ret, "%s<%s>%s</%s>\n", leader, yit, semval->str, yit);
+	break;
+    case _Terminal:
+	ret = malloc(leaderLen+Classes[semval->type].size*2+6 + semval->size);
+	sprintf(ret, "%s<%s>%s</%s>\n", leader, Classes[semval->type].name, semval->str, Classes[semval->type].name);
+	break;
+    default:
+	fprintf(stderr, "how do i toXml a %d?\n", semval->type);
+    }
+    return ret;
+}
+
+FILE* _Trace = NULL;
+
+Semval* constructProduction (const Classes_e type, size_t argc, ...) {
+    Semval* ret = malloc(sizeof(Semval));
+    va_list semvals;
+    size_t argNo, valsNo;
+    Semval* semval;
+    const char const * str;
+
+    ret->type = type;
+    ret->size = argc;
+
+    /* Appropriate type? */
+    if (Classes[type].type != _Production && 
+	Classes[type].type != _GenProduction) {
+	fprintf(stderr, "constructProduction(%d, %d, ...). Classes[type] (%d) != _Production (%d)", type, argc, Classes[type], _Production);
+    }
+
+    /* Trace */
+    if (_Trace)
+	fprintf(_Trace, "  %s:", Classes[type].name);
+    va_start(semvals, argc);
+    for (argNo = 0; argNo < argc; argNo++) {
+	semval = va_arg(semvals, Semval*);
+
+	/* By default, each argument represents a series of parameter. */
+	int semvalSize = 1;
+
+	/* Productions created for *, +, ? or ()s are represented
+	 * as a series of n parameters. */
+	if (Classes[semval->type].type == _GenProduction) {
+	    semvalSize = semval->size; /* copying elements from an array */
+
+	    /* Absorb the nested created production when the production
+	     * is an expansion for a *, + or ?, e.g.
+	     foo_Star: foo_Star foo */
+	    if (semval->type == type) {
+		ret->size -= 1;
+		ret->size += semvalSize;
+	    }
+	}
+	if (_Trace)
+	    fprintf(_Trace, " %s(%d)", Classes[semval->type].name, semvalSize);
+    }
+    va_end(semvals);
+    if (_Trace)
+	fprintf(_Trace, "\n");
+
+    if (argc) {
+	ret->vals = malloc(sizeof(Semval*) * ret->size);
+	va_start(semvals, argc);
+	for (argNo = valsNo = 0; argNo < argc; argNo++) {
+	    semval = va_arg(semvals, Semval*);
+	    if (Classes[semval->type].type == _GenProduction) {
+		short absorbSemval = semval->type == type;
+		size_t j;
+		for (j = 0; j < semval->size; j++) {
+		    Semval* nestedSemval = semval->vals[j];
+		    if (absorbSemval)
+			/* If absorbing the argument, take each of its
+			 * constructor args. */
+			ret->vals[valsNo++] = nestedSemval;
+
+		    if (_Trace && semval->size > 0) {
+			/* Regardless of absorption, display each
+			 * generated argument separately. */
+			str = toString(nestedSemval);
+			fprintf(_Trace, "    %s(%d): %s\n", 
+				Classes[semval->type].name, j, str);
+			free ((char*)str);
+		    }
+		}
+		if (absorbSemval) {
+		    /* If we absorbed the nested production, free it. */
+		    if (semval->size)
+			free (semval->vals);
+		    free (semval);
+		} else {
+		    /* If not absorbing the argument, add it to the
+		     * constructor args. */
+		    ret->vals[valsNo++] = semval;
+		}
+	    } else {
+		ret->vals[valsNo++] = semval;
+		if (_Trace && semval->size > 0) {
+		    str = toString(semval);
+		    fprintf(_Trace, "    %s(%d): %s\n", Classes[semval->type].name, 0, str);
+		    free ((char*)str);
+		}
+	    }
+	}
+	va_end(semvals);
+    }
+    free ((char*)toString(ret));
+    free ((char*)toXml(ret, 0));
+    return ret;
+}
+
+Semval* constructTerminal (const Classes_e type, const char const * str) {
+    Semval* ret = malloc(sizeof(Semval));
+    if (_Trace)
+	fprintf(_Trace, "shift (%s, %s)\n", Classes[type].name, str);
+    ret->type = type;
+    ret->size = strlen(str);
+    ret->str = malloc(ret->size+1);
+    strncpy((char*)ret->str, str, ret->size+1);
+    free ((char*)toString(ret));
+    free ((char*)toXml(ret, 0));
+    return ret;
+}
+
+void yyerror (char *m) /* ${Langname}_ */
+{
+  fprintf(stderr,"error %s at \"%s\"\n", m, getContextString(m));
+}
+
+#include <stdlib.h>
+extern FILE *${Langname}in, *${Langname}out;
+int main(int argc, char* argv[]) {
+    char* tmp;
+    if (tmp = getenv("TRACE_FD")) {
+	int fd;
+	sscanf(tmp, "%d", &fd);
+	if (!(_Trace = fdopen(fd, "a")))
+	    fprintf(stderr, "couldn't open trace fd %d\n", fd);
+    }
+
+    const char* inputId;
+    if (argc > 1) {
+	inputId = argv[1];
+	${Langname}in = fopen(argv[1], "r");
+    } else {
+	inputId = "<stdin>";
+	${Langname}in = stdin;
+    }
+
+    ${Langname}set_debug(0); /* prevent lex from printing tokens */
+    int result = yyparse(); /* @@ ${Langname}_ */
+
+    if (result)
+	fprintf(stderr, "Error: %s did not contain a valid ${Langname} string.\n", inputId);
+    else
+	fprintf(stdout, "%s", toXml(StupidGlobal, 0));
+
+    if (_Trace)
+	close(_Trace);
+
+    return result;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/CYacc/Langname_Scanner.l	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,44 @@
+/* $Id: Langname_Scanner.l,v 1.1 2008-04-06 17:10:48 eric Exp ${Langname}Scanner.ll 28 2007-08-20 10:27:39Z tb $ -*- mode: c++ -*- */
+/** \file ${Langname}Scanner.ll Define the Flex lexical scanner */
+
+%{ /*** C/C++ Declarations ***/
+
+#include "${Langname}Enums.h"
+#include "${Langname}Parser.h"
+
+%}
+
+/*** Flex Declarations and Options ***/
+
+/* change the name of the scanner class. results in "${Langname}FlexLexer" */
+%option prefix="${Langname}"
+
+/* the manual says "somewhat more optimized" */
+%option batch
+
+/* enable scanner to generate debug output. disable this for release
+ * versions. */
+%option debug
+
+/* no support for include files is planned */
+%option noyywrap nounput 
+
+/* START patterns for ${Langname} terminals */
+${TerminalPatterns}
+/* END patterns for ${Langname} terminals */
+
+/* START semantic actions for ${Langname} terminals */
+%%
+{PASSED_TOKENS}
+${TerminalActions}
+<<EOF>>			{ yyterminate();}
+%%
+char* getContextString(char* m)
+{
+  #define _SIZE 80
+  char* ptr = (yy_buffer_stack)[(yy_buffer_stack_top)]->yy_ch_buf + strlen((yy_buffer_stack)[(yy_buffer_stack_top)]->yy_ch_buf);
+  int len;
+  for (len = 0; ptr > (yy_buffer_stack)[(yy_buffer_stack_top)]->yy_ch_buf && *(ptr-1) != '\n' && len < _SIZE-1; --ptr, ++len);
+  return ptr;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/CYacc/Makefile	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,28 @@
+
+.SUFFIXES : .cc .y .l $(SUFFIXES)
+
+.c.o :
+	gcc -g  -I . -I$(CENTERCCLIBDIR)/incl -c  $*.c
+
+.y.c :
+	bison -d -o $*.c $*.y
+.l.c :
+	flex  -o$*.c -P${Langname}_ $*.l
+.y.h :
+	bison -d -o $*.c $*.y
+.l.h :
+	flex  -o$*.c -P${Langname}_ $*.l
+
+${Langname}Parser.o : ${Langname}Parser.c ${Langname}Parser.h
+
+${Langname}Scanner.o : ${Langname}Scanner.c ${Langname}Parser.h
+
+${Langname}Parser.c : ${Langname}Parser.y
+
+${Langname}Scanner.c : ${Langname}Scanner.l
+
+${Langname}Parser.h : ${Langname}Parser.y
+
+${Langname} : ${Langname}Parser.o ${Langname}Scanner.o
+	gcc -Wno-deprecated -g -o $@ ${Langname}Parser.o ${Langname}Scanner.o
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/PerlYapp/Langname_.yp	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,394 @@
+%{
+# START TokenBlock
+${TerminalTokens}
+my $Tokens = [[0, qr/$PASSED_TOKENS/, undef],
+${TerminalDeclarations}];
+# END TokenBlock
+
+# START ClassBlock
+${ProductionClasses}
+${TerminalClasses}
+# END ClassBlock
+%}
+
+%% #*** Grammar Rules ***
+
+ #*** BEGIN ${Langname} - Change the grammar rules below ***
+${ProductionActions}
+
+ #*** END ${Langname} - Change the grammar rules above ***
+
+%% #*** Additional Code ***
+
+my $LanguageName = '${Langname}';
+# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
+# START LexerBlock
+#
+# YappTemplate: used by yacker to create yapp input files.
+#
+# Use: yacker -l perl -s -n <name> <name>.txt
+#
+# to generate a yapp input module called ${Langname}.yp.
+
+#line 11 "YappTemplate"
+
+# $Id: Langname_.yp,v 1.1 2008-04-08 09:34:09 eric Exp $
+
+sub _Base::new {
+    my ($proto, @args) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = [];
+    foreach my $arg (@args) {
+	if (UNIVERSAL::isa($arg, $class)) {
+
+	    # Collapse nested left-recursive *, +, ? and () productions.
+	    push (@$self, @$arg);
+	} else {
+
+	    # Construct simple parse tree of production parameters.
+	    push (@$self, $arg);
+	}
+    }
+    bless ($self, $class);
+    return $self;
+}
+sub _Base::toString {
+    my ($self) = @_;
+    my @ret = map {$_->toString} @$self;
+    return wantarray ? @ret : join(' ', @ret);
+}
+sub _Base::toXML {
+    my ($self, $prefix, $decls) = @_;
+    my $class = ref $self;
+    my $declsStr = join('', map {my $p = $_ ? ":$_" : ''; "\n xmlns$p=\"$decls->{$_}\""} keys %$decls);
+    my @ret = ("$prefix<$class$declsStr>", map {ref $_ ? $_->toXML("$prefix  ", {}) : $_} @$self, "$prefix</$class>");
+    return wantarray ? @ret : join("\n", @ret);
+}
+
+@_Production::ISA = qw(_Base);
+@_GenProduction::ISA = qw(_Production);
+sub _GenProduction::toXML {
+    my ($self, $prefix) = @_;
+    return join("\n", map {$_->toXML($prefix)} @$self);
+}
+
+@_Terminal::ISA = qw(_Base);
+sub _Terminal::toString {
+    my ($self) = @_;
+    my $encodedValue = $self->[0];
+    $encodedValue =~ s/\r/\\r/g;
+    $encodedValue =~ s/\n/\\n/g;
+    $encodedValue =~ s/\t/\\t/g;
+    return $encodedValue;
+}
+sub _Terminal::toXML {
+    my ($self, $prefix) = @_;
+    my $class = ref $self;
+    my $encodedValue = $self->[0];
+    $encodedValue =~ s/&/&amp;/g;
+    $encodedValue =~ s/</&lt;/g;
+    $encodedValue =~ s/>/&gt;/g;
+    return "$prefix<$class>$encodedValue</$class>";
+}
+@_Constant::ISA = qw(_Base);
+sub _Constant::toString {
+    my ($self) = @_;
+    return ($self->[0]);
+}
+sub _Constant::toXML {
+    my ($self, $prefix) = @_;
+    my $class = ref $self;
+    $class =~ s/^[IG]T_//;
+    return "$prefix<yacker:implicit-terminal>$class</yacker:implicit-terminal>";
+}
+
+sub _Error {
+    my ($self) = @_;
+        exists $self->YYData->{ERRMSG}
+    and do {
+        print $self->YYData->{ERRMSG};
+        delete $self->YYData->{ERRMSG};
+        return;
+    };
+    my $pos = pos $self->YYData->{INPUT};
+    my $lastPos = $self->YYData->{my_LASTPOS};
+    my $excerpt = substr($self->YYData->{INPUT}, $lastPos, $pos - $lastPos);
+    my $expect = @{$self->{STACK}} ? join (' | ', sort {(!(lc $a cmp lc $b)) ? $b cmp $a : lc $a cmp lc $b} map {&_terminalString($_)} $self->YYExpect()) : 'INVALID INITIALIZER';
+    if (ref $expect) {
+	# Flag unexpected (by the author at this point) refs with '?ref'.
+	if (ref $expect eq 'HASH') {
+	    if (exists $expect->{NEXT}) {
+		$expect = $ {$expect->{NEXT}};
+	    } else {
+		$expect = "?ref {%$expect}";
+	    }
+	} elsif (ref $expect eq 'ARRAY') {
+	    $expect = "?ref [@$expect]";
+	} elsif (ref $expect eq 'SCALAR') {
+	    $expect = "?ref $$expect";
+	} elsif (ref $expect eq 'GLOB') {
+	    $expect = "?ref \**$expect";
+	} else {
+	    $expect = "?ref ??? $expect";
+	}
+    }
+    my $token = &_terminalString($self->YYData->{my_LASTTOKEN});
+    my $value = $self->YYData->{my_LASTVALUE};
+    die "expected \"$expect\", got ($token, $value) from \"$excerpt\" at offset $lastPos.\n";
+}
+
+sub _terminalString { # static
+    my ($token) = @_;
+    if ($token =~ m{^I_T_(.+)$}) {
+	$token = "'$1'";
+    } elsif ($token =~ m{^T_(.+)$}) {
+	if (my $base = $ARGV[0]) {
+	    $token = "&lt;<a href=\"$base$token\">$1</a>&gt;";
+	} else {
+	    $token = "<$1>";
+	}
+    }
+    return $token;
+}
+
+my $AtStart;
+
+sub _Lexer {
+    my($self)=shift;
+
+    my ($token, $value) = ('', undef);
+
+  top:
+    if (defined $self->YYData->{INPUT} && 
+	pos $self->YYData->{INPUT} < length ($self->YYData->{INPUT})) {
+	# still some chars left.
+    } else {
+	return ('', undef);
+    }
+
+    $self->YYData->{my_LASTPOS} = pos $self->YYData->{INPUT};
+    my $startPos = pos $self->YYData->{INPUT};
+    my ($mText, $mLen, $mI, $mLookAhead) = ('', 0, undef, undef);
+    for (my $i = 0; $i < @$Tokens; $i++) {
+	my $rule = $Tokens->[$i];
+	my ($start, $regexp, $action) = @$rule;
+	if ($start && !$AtStart) {
+	    next;
+	}
+	eval {
+	    if ($self->YYData->{INPUT} =~ m/\G($regexp)/gc) {
+		my $lookAhead = defined $2 ? length $2 : 0;
+		my $len = (pos $self->YYData->{INPUT}) - $startPos + $lookAhead;
+		if ($len > $mLen) {
+		    $mText = substr($self->YYData->{INPUT}, $startPos, $len - $lookAhead);
+		    $mLen = $len;
+		    $mI = $i;
+		    $mLookAhead = $lookAhead
+		}
+		pos $self->YYData->{INPUT} = $startPos;
+	    }
+	}; if ($@) {
+	    die "error processing $action: $@";
+	}
+    }
+    if ($mLen) {
+	my ($start, $regexp, $action) = @{$Tokens->[$mI]};
+	pos $self->YYData->{INPUT} += $mLen - $mLookAhead;
+	$AtStart = $mText =~ m/\z/gc;
+	($token, $value) = ($action, $mText);
+    } else {
+	my $excerpt = substr($self->YYData->{INPUT}, pos $self->YYData->{INPUT}, 40);
+	die "lexer couldn't parse at \"$excerpt\"\n";
+    }
+    if (!defined $token) {
+	# We just parsed whitespace or comment.
+	goto top;
+    }
+#    my $pos = pos $self->YYData->{INPUT};
+#    print "\n$pos,$token,$value\n";
+    $self->YYData->{my_LASTTOKEN} = $token;
+    $self->YYData->{my_LASTVALUE} = $value;
+    my $ret = $token->new($value);
+    my $str = $ret->toString;
+    $self->trace("shift ($token, $str)");
+    return ($token, $ret);
+}
+
+# END LexerBlock
+
+sub parse {
+    my ($self, $sample) = @_;
+    $self->YYData->{INPUT} = $sample;
+    pos $self->YYData->{INPUT} = 0;
+    return $self->YYParse( yylex => \&_Lexer, yyerror => \&_Error, yydebug => $ENV{YYDEBUG} );
+}
+
+sub openTraceFd {
+    my ($self, $fd) = @_;
+    open $self->YYData->{Trace}, '>&', $fd;
+}
+sub closeTrace {
+    my ($self, $fd) = @_;
+    close $self->YYData->{Trace};
+}
+sub trace {
+    my($self, $str) = @_;
+    if ($self->YYData->{Trace}) {
+	&utf8::encode($str);
+	print {$self->YYData->{Trace}} "$str\n";
+    }
+}
+sub traceProduction {
+    my($self, $prod, @parms) = @_;
+    if ($self->YYData->{Trace}) {
+	my $str = "  $prod:";
+	my @lines;
+	while (@parms) {
+	    my ($parmName, $parmVal) = (shift @parms, shift @parms);
+
+	    if (UNIVERSAL::isa($parmVal, '_GenProduction')) {
+
+		# Enumerate elements of *, +, ? and () productions.
+		$str .= sprintf(" %s(%d)", $parmName, scalar @$parmVal);
+		for (my $i = 0; $i < @$parmVal; $i++) {
+		    push (@lines, sprintf("    %s(%d): %s", $parmName, $i, join(' ', $parmVal->[$i]->toString)));
+		}
+	    } else {
+
+		# Display singleton properties via their toString form.
+		$str .= sprintf(" %s(%d)", $parmName, 1);
+		push (@lines, sprintf("    %s(%d): %s", $parmName, 0, join(' ', $parmVal->toString)));
+	    }
+	}
+	$str = join("\n", $str, @lines);  
+	&utf8::encode($str);
+	print {$self->YYData->{Trace}} "$str\n";
+    }
+}
+
+require Exporter;
+use vars qw ( @EXPORT );
+push (@ISA, qw ( Exporter ));
+@EXPORT = qw(&test);
+
+sub test {
+    if (@ARGV < 1) {
+	local $/ = undef;
+	&testFile(<STDIN>, $ENV{TRACE_FD});
+    } else {
+	foreach my $file (@ARGV) {
+	    open(F, $file) || die "unable to open input $file: $!\n";
+	    local $/ = undef;
+	    &testFile(<F>, $ENV{TRACE_FD});
+	    close (F);
+	}
+    }
+}
+sub testFile {
+    my ($sample, $traceFd) = @_;
+    my $parser = ${Langname}->new();
+    &utf8::decode($sample);
+    if ($ENV{TRACE_FD}) {
+	$parser->openTraceFd($ENV{TRACE_FD});
+    }
+    eval {
+	my $root = $parser->parse($sample);
+	my $text = $root->toXML('', {
+	 '' => 'http://www.w3.org/2005/01/yacker/uploads/${Langname}/', 
+	 'yacker' => 'http://www.w3.org/2005/01/yacker/'});
+
+	# @@@ you may need to comment this for command line processing.
+	&utf8::encode($text);
+
+	print "$text\n";
+    };
+    my $lastError = $@;
+    if ($ENV{TRACE_FD}) {
+	$parser->closeTrace();
+    }
+    if ($lastError) {
+	die $lastError;
+    }
+}
+
+1;
+
+__END__
+
+=head1 ${Langname}
+
+${Langname} - parse some language.
+
+=head1 SYNOPSIS
+
+    my ($sample) = $ARGV[0];
+    &utf8::decode($sample);
+    my $parser = new ${Langname}();
+    my $root = $parser->parser($sample);
+    my $text = $root->toXML('', {
+	 '' => 'http://www.w3.org/2005/01/yacker/uploads/${Langname}/', 
+	 'yacker' => 'http://www.w3.org/2005/01/yacker/'});
+    &utf8::encode($text);
+    print "$text\n";
+
+=head1 DESCRIPTION
+
+Yacker needs to encode rule patterns in [a-zA-Z_]+ so it reserves symbols starting with '_'. This parser reverses the process.
+
+This module was generated by W3C::Grammar::bin::yacker.
+
+
+=head1 API
+
+This function supplies a single parsing function. The methods of the returned object are described below.
+
+=head2 parse($sample)
+
+Returns an array of objects parsed into the language given to yacker.
+
+=head2 returned object
+
+The returned objects are blessed subclasses of _Production. They have the following functions:
+
+=head3 toString
+
+Return a ' '-separated "normalization" of the parsed $sample.
+
+=head3 toXML
+
+Return an XML parse tree of the parsed $sample.
+
+
+=head1 TESTING/DEBUGGING
+
+    TRACE_FD=3 perl -M${Langname} -e test < sample.in 3> sample.trace
+or
+    TRACE_FD=3 perl -M${Langname} -e test sample 3> sample.trace
+
+which should return a parse tree for the given language.
+
+Setting the trace file descriptor to 1 will send the trace output to stdout.
+    TRACE_FD=1
+Leaving it unset will suppress the trace output.
+
+
+=head1 BUGS
+
+The web interface to yacker requires the results to be encoded:
+  &utf8::encode($text)
+
+Many shells do not expect this so you may need to comment it out. You
+may search for the "@@@" above to find the line in sub test.
+
+
+=head1 AUTHOR
+
+${Langname} author: unknown
+yacker author: Eric Prud'hommeaux <eric@w3.org>
+
+=head1 SEE ALSO
+
+W3C::Grammar::bin::yacker(1)
+
+=cut
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/bin/templates/PerlYapp/Makefile	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,7 @@
+PARSERS = ${Langname}.pm
+
+parsers: $(PARSERS)
+
+$(PARSERS): %.pm: %.yp
+	yapp -v -s -o $@ $<
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/bin/yacker	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,993 @@
+#!/usr/bin/perl
+# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
+
+# See copyright info at the bottom.
+# CVS Version: $Id: yacker,v 1.82 2008-04-12 04:10:11 eric Exp $
+
+# Quickee install example:
+#    unagi:/home/eric$ mkdir /tmp/yack
+#    unagi:/home/eric$ cd /tmp/yack
+#    unagi:/tmp/yack$ cvs -Q -d eric@homer.w3.org:/sources/public co perl/modules/W3C/{Grammar,Util/{Exception,YappDriver}.pm}
+#    unagi:/tmp/yack$ wget -O sparqlTest.bnf 'http://www.w3.org/2005/01/yacker/uploads/sparqlTest/bnf?lang=c'
+#    unagi:/tmp/yack$ PERL5LIB=perl/modules perl/modules/W3C/Grammar/bin/yacker --lang=perl sparqlTest.bnf > sparqlTest.yp
+
+use strict;
+
+my $REVISION = '$Id: yacker,v 1.82 2008-04-12 04:10:11 eric Exp $';
+
+use W3C::Util::Exception qw(&throw &catch &DieHandler);
+use W3C::Grammar::YaccParser;
+use W3C::Grammar::Presenter;
+use Parse::Yapp::Driver;
+use W3C::Grammar::YaccCompileTree qw($Name2Symbol);
+
+my $LANGS = {'c' => new W3C::Grammar::GenSpec::C_(), 
+	     'cpp' => new W3C::Grammar::GenSpec::CPP(), 
+	     'perl' => new W3C::Grammar::GenSpec::Perl(), 
+	     'n3' => new W3C::Grammar::GenSpec::N3(), 
+	     'python' => new W3C::Grammar::GenSpec::Python(), 
+	     'java' => new W3C::Grammar::GenSpec::Java()};
+
+my ($GenSpec, $name, $code, $stubs, $mimick, $suppressLineDirectives, $generateNames, $processed) = ($LANGS->{'perl'}, 'a', undef, 0, 0, 0, 0, 0);
+my $LegalFileName = '[a-zA-Z_][a-zA-Z_0-9\.-]*';
+my $LanguageParmNames = [['perl', 'Perl'], ['c', 'C'], ['cpp', 'C++'], ['python', 'Python']];
+
+my $man = 0;
+my $help = 0;
+
+if (exists $ENV{QUERY_STRING}) {
+    &cgiMode($ARGV[0] eq 'DEBUG' ? defined $ARGV[1] ? $ARGV[1] : -1 : undef);
+} else {
+    &cliMode();
+}
+
+sub cgiMode {
+    my ($debugSession) = @_;
+    # Run in CGI mode.
+
+    require W3C::Util::W3CDebugCGI;
+    require W3C::Util::Filter;
+    require Digest::MD5;
+
+    my $query;
+    eval {
+	local($SIG{"__DIE__"}) = \&DieHandler;
+	$W3C::Util::W3CDebugCGI::DEBUG_SESSION = $ARGV[1]; # use a session id like 957296047.909868 or -2;
+	$query = new W3C::Util::W3CDebugCGI($0, defined $debugSession, 
+					    {-dieNoOpen => 1, 
+					     -logExt => '.log', 
+					     -storeIn => '/tmp', 
+					     -rerun => 'rerun'});
+	my $presenter = new W3C::Grammar::XHTMLPresenter($REVISION, $LegalFileName);
+	my $action = $query->param('action');
+
+	# Some constantsKinda like globals in use:
+	my $CreateParser = 'create parser';
+	my $GenerateText = 'generate text';
+	my $UGenerateText = CGI::escape($GenerateText);
+	$UGenerateText =~ s/\%20/\+/g;
+	my $ValidateText = 'validate text';
+	my $AddTest = 'add test';
+	my $ValidateTextOptions = [$ValidateText]; # , $AddTest];
+	my $ListGrammars = 'list grammars';
+	my $path = $ENV{PATH_INFO};
+	if ($path eq '/') {
+	    $path = undef;
+	}
+
+	# name
+	my $nameWarning = undef;
+	$name = $query->param('name');
+	if (!$name) {
+	    $nameWarning = "No name supplied";
+	} elsif ($name !~ m/^$LegalFileName$/) {
+	    $presenter->error("invalid name \"$name\". must match ^$LegalFileName\$");
+	}
+
+	my $uploads = 'uploads';
+
+	# path parameter required for some actions, optional for others.
+	my $pathWarning = undef;
+	my $showFile;
+	if ($path =~ m/^\/$uploads\/($LegalFileName)\/?$/) {
+	    $name = $1;
+	} elsif ($path =~ m/^\/$uploads\/($LegalFileName)\/($LegalFileName)$/) {
+	    $name = $1;
+	    $showFile = $2;
+	} else {
+	    $pathWarning = "invalid name \"$name\"";
+	}
+
+	# lang parameter required for some actions, optional for others.
+	my $langWarning = undef;
+	my $langStr = $query->param('lang');
+	if ($langStr) {
+	} elsif (open (COMPILE, "$uploads/$name/compilationResults")) {
+	    $langStr = <COMPILE>; # ignore lang string
+	    chomp $langStr;
+	    close (COMPILE);
+	} else {
+	    if (!$query->param('markup')) {
+		$presenter->warning("no grammar language supplied - defaulting to perl");
+	    }
+	    $langStr = 'perl';
+	}
+	if ($GenSpec = $LANGS->{$langStr}) {
+	} else {
+	    my $opts = join(', ', keys %$LANGS);
+	    $langWarning = "unknown language \"$langStr\". must be one of $opts";
+	}
+
+	# Switch on form action parameter.
+	if (!$path && !$action) {
+
+	    # Step 0: create
+	    my $defaultBNF;
+	    my $defaultFile = $name ? "$uploads/$name/bnf" : 'BNFTemplate';
+	    if (open(DEF, $defaultFile)) {
+		local $/ = undef;
+		$defaultBNF = <DEF>;
+		close(DEF);
+	    } else {
+		$presenter->error($!);
+	    }
+	    $presenter->promptCreateGrammar('.', $CreateParser, $LanguageParmNames, $name, scalar $query->param('replace'), $GenSpec->getName(), $defaultBNF);
+	} else {
+
+	    # Subsequent actions need a language.
+	    if ($langWarning && !$query->param('markup') && 
+		$action ne $ListGrammars) {
+		$presenter->warning($langWarning);
+	    }
+
+	    if ($action eq $ListGrammars) {
+		$presenter->listGrammars($uploads);
+	    } elsif ($action eq $CreateParser) {
+
+		# Step 1: create grammar and show results
+
+		# The Create action needs the name to come from a cgi parameter.
+		if ($nameWarning) {
+		    $presenter->error($nameWarning);
+		}
+
+		# Also needs a bnf parameter.
+		my $bnf = $query->param('bnf');
+		if (!$bnf) {
+		    $presenter->error("no grammar supplied");
+		}
+
+		if (-d "$uploads/$name" && !$query->param('replace')) {
+		    $presenter->warning("name <a href=\"yacker/$uploads/$name/bnf?markup=html\">$name</a> already exists");
+		    $presenter->promptCreateGrammar('.', $CreateParser, $LanguageParmNames, $name, 0, $GenSpec, $bnf);
+		} else {
+		    # Parse and transform the grammar to yacc syntax.
+		    &utf8::decode($bnf);
+		    my ($g, $errs) = &_parseGrammar($bnf);
+		    if (@$errs) {
+			my $errsStr = &W3C::Grammar::YaccParser::getMessages($errs);
+			&throw(new W3C::Util::Exception(-message => "rejected because of the following errors:\n$errsStr"));
+		    }
+		    my $html = &_getHtmlGrammar($g, 'html', $name);
+
+		    $stubs = 1;
+		    $generateNames = $query->param('generate') eq 'short';
+
+		    # Create a Makefile to yacc the created yacc syntax.
+		    my $new = 0;
+		    if (! -d "$uploads/$name") {
+			mkdir("$uploads/$name") || &throw(new W3C::Util::FileCreationException(-filename => $name));
+			$new = 1;
+		    }
+		    eval {
+			open(my $MAKE, '>', "$uploads/$name/Makefile") || die "unable to create Makefile";
+			$GenSpec->makeMakefile($MAKE, '.', $name, $g);
+			close($MAKE);
+			&createGrammar($g, $presenter, "$uploads/$name", 
+				       $suppressLineDirectives);
+		    }; if ($@) { # would be nicer to detect generation errors before needing the dir.
+			rmdir("$uploads/$name");
+			die $@;
+		    }
+
+		    # Keep the BNF around for reference.
+		    my $bnfFile = "$uploads/$name/bnf";
+		    &utf8::encode($bnf);
+
+		    # Compare the saved BNF to the one we're considering writing.
+		    my $savedBnfSum = undef;
+		    if (-e $bnfFile && open(BNF, '<', $bnfFile)) {
+			local $/ = undef;
+			$savedBnfSum = &Digest::MD5::md5(<BNF>);
+			close(BNF);
+		    }
+		    # Write only if they are different. (Handy for local editing mode.)
+		    if ($savedBnfSum ne &Digest::MD5::md5($bnf)) {
+			open(BNF, '>', $bnfFile) || die "unable to create BNF file";
+			print BNF $bnf;
+			close(BNF);
+		    }
+
+		    # Build the grammar.
+		    my $target = $GenSpec->getTarget($name);
+		    $ENV{HAVE_BOOST} = 1; # tell the build env that we have libboost
+		    my ($results) = 
+		      W3C::Util::SyncFilter->new("make -C $uploads/$name $target", undef)->execute(4096, 1);
+		    my $errors = $results->getByFlavor('stderr');
+		    if ($errors && $name =~ m/\-/) {
+			$presenter->warning("some versions of bison yack ungracefully on names with '-'s in them.\n");
+		    }
+		    my $resultsMarkup;
+		    $presenter->creationResults($name, $new, $uploads, $name, $GenSpec->getName(), $results, \$resultsMarkup, $html);
+
+		    # Keep the HTML markup for the results for redisplay.
+		    my $compilationResults = "$uploads/$name/compilationResults";
+		    open(COMPILE, '>', $compilationResults) || die "unable to create COMPILE file \"$compilationResults\"";
+		    print COMPILE "$langStr\n";
+		    print COMPILE $resultsMarkup;
+		    close(COMPILE);
+
+		}
+	    } else {
+		# Subsequent actions need a name derived from the path.
+		if ($pathWarning && !$query->param('markup') && 
+		    $action ne $ListGrammars) {
+		    $presenter->warning($pathWarning);
+		}
+
+		my $html = $query->param('markup') ? 
+		  &_getHtmlGrammar(&_loadGrammar("$uploads/$name/bnf"), 'html', $name) : 
+		    '';
+
+		open (COMPILE, "$uploads/$name/compilationResults");
+		<COMPILE>; # ignore lang string
+		local $/ = undef;
+		my $resultsMarkup = <COMPILE>;
+		close (COMPILE);
+
+		if (!$action) {
+
+		    my $path = "$uploads/$name/$showFile";
+
+		    # Step 2: show creation results
+		    if ($showFile) {
+
+			if ($showFile eq "$name.output") {
+			    open (OUTPUT, $path) || die;;
+			    my @markup;
+			    local $/ = "\n";
+			    my %ruleNames;
+			    my $lineNo = 1;
+			    while (my $line = <OUTPUT>) {
+				if (($line eq "Warnings:\n") && (my $line2 = <OUTPUT>) =~ m/^\-+$/) {
+				    push (@markup, $line);
+				    push (@markup, $line2);
+				    my $errorLine = <OUTPUT>;
+				    if ($errorLine eq "Useless terminals:\n") {
+					push (@markup, $errorLine);
+					push (@markup, scalar <OUTPUT>); # blank line
+					while ((my $terminalLine = <OUTPUT>) ne "\n") {
+					    push (@markup, $terminalLine);
+					}
+					push (@markup, "\n");
+					$errorLine = <OUTPUT>;
+				    }
+				    if ($errorLine eq "Useless non-terminals:\n") {
+					push (@markup, $errorLine);
+					push (@markup, scalar <OUTPUT>); # blank line
+					while ((my $terminalLine = <OUTPUT>) ne "\n") {
+					    push (@markup, $terminalLine);
+					}
+					push (@markup, "\n");
+					$errorLine = <OUTPUT>;
+				    }
+				    if ($errorLine eq "Useless rules:\n") {
+					push (@markup, $errorLine);
+					push (@markup, scalar <OUTPUT>); # blank line
+					while ((my $ruleLine = <OUTPUT>) ne "\n") {
+					    push (@markup, $ruleLine);
+					}
+					push (@markup, "\n");
+					$errorLine = <OUTPUT>;
+				    }
+				    push (@markup, $errorLine); # 2 shift/reduce conflicts and 24 reduce/reduce conflicts
+				    push (@markup, scalar <OUTPUT>); #
+				} elsif (($line eq "Conflicts:\n") && (my $line2 = <OUTPUT>) =~ m/^\-+$/) {
+				    push (@markup, $line);
+				    push (@markup, $line2);
+				    while ((my $conflictLine = <OUTPUT>) ne "\n") {
+					$conflictLine =~ m/^State (\d+) (contains .*?)$/ || die;
+					my ($state, $contains) = ($1, $2);
+					push (@markup, "<a href=\"#s_$state\">State $state</a> $contains\n");
+				    }
+				    push (@markup, "\n");
+				} elsif (($line eq "Rules:\n") && (my $line2 = <OUTPUT>) =~ m/^\-+$/) {
+				    push (@markup, $line);
+				    push (@markup, $line2);
+				    my @rulez;
+				    while ((my $ruleLine = <OUTPUT>) ne "\n") {
+					$ruleLine =~ m/^(\d+):(\s+)([^ ]+) -> (?:(\/\* .*? \*\/)|(.*))$/ || (chomp $ruleLine, die "can't parse \"$ruleLine\"");
+					my ($ruleNo, $space, $name, $comment, $ruleText) = ($1, $2, $3, $4, $5);
+					if (!$ruleNames{$name} && $name !~ m/\$/) {
+					    $ruleNames{$name} = scalar @rulez;
+					    $name = "<a name=\"r_$name\">$name</a>";
+					}
+					push (@rulez, [$ruleNo, $space, $name, $comment, $ruleText]);
+				    }
+				    foreach my $rule (@rulez) {
+					my ($ruleNo, $space, $name, $comment, $ruleText) = @$rule;
+					if ($comment) {
+					    $comment = "<span class=\"comment\">$comment</span>";
+					}
+					$ruleText =~ s/(\S+)/$ruleNames{$1} ? "<a href=\"#r_$1\">$1<\/a>" : $1/gex;
+					push (@markup, "<a name=\"r_$ruleNo\">$ruleNo</a>$space$name -> $ruleText$comment\n");
+				    }
+				    push (@markup, "\n");
+				} elsif (($line eq "States:\n") && (my $line2 = <OUTPUT>) =~ m/^\-+$/) {
+				    push (@markup, $line);
+				    push (@markup, $line2);
+				    my $stateLine = <OUTPUT>;
+				  StateLine:
+				    while ($stateLine =~ m/^State (\d+):$/) {
+					my $stateNo = $1;
+					push (@markup, "State <a name=\"s_$stateNo\">$stateNo</a>:\n");
+					while ($stateLine = <OUTPUT>) {
+					    if ($stateLine =~ m/^State (\d+):$/) {
+						next StateLine;
+					    }
+					    if ($stateLine eq "Summary:/n") {
+						last StateLine;
+					    }
+					    $stateLine =~ s/(\S+)/$ruleNames{$1} ? "<a href=\"#r_$1\">$1<\/a>" : $1/gex;
+					    $stateLine =~ s/(Rule|rule) (\d+)/<a href="#r_$2">$1 $2<\/a>/g;
+					    $stateLine =~ s/state (\d+)/<a href="#s_$1">state $1<\/a>/g;
+					    $stateLine =~ s/reduce/<a onclick="history.back()">reduce<\/a>/g;
+					    $stateLine =~ s/\[([^\]]*)\]/<span class="error">\[$1\]<\/span>/g;
+					    push (@markup, "$stateLine");
+					}
+				    }
+				    push (@markup, "\n");
+				    if (($stateLine eq "Summary:\n") && (my $line2 = <OUTPUT>) =~ m/^\-+$/) {
+					push (@markup, $stateLine);
+					push (@markup, $line2);
+					push (@markup, scalar <OUTPUT>);
+					push (@markup, scalar <OUTPUT>);
+					push (@markup, scalar <OUTPUT>);
+					push (@markup, scalar <OUTPUT>);
+				    }
+				} else {
+				    die "could not parse line $lineNo in output: $line";
+				}
+				$lineNo++;
+			    }
+			    $presenter->renderMarkup($name, $GenSpec, 'output', join('', '<pre>', @markup, '</pre>'));
+			} else {
+
+			    # Show a generated file.
+			    $presenter->showFile($path);
+			}
+		    } else {
+
+			# Show the list and prompt for validation.
+			$presenter->promptValidateText('.', $ValidateTextOptions, 
+						       $UGenerateText, $uploads, 
+						       $name, $GenSpec->getName(), undef, 
+						       undef, undef, undef, $html, 
+						       $resultsMarkup, 0, 50, 90);
+		    }
+		} elsif ($action eq $GenerateText) {
+
+		    my $g = &_loadGrammar("$uploads/$name/bnf");
+		    # $g->yaccify(undef);
+
+		    my $random = $query->param('random');
+		    my $seed = defined $query->param('seed') ? $query->param('seed') : 0;
+		    my $limit = defined $query->param('limit') ? $query->param('limit') : 0;
+		    my $asciiWeight = defined $query->param('asciiWeight') ? $query->param('asciiWeight') : 90;
+		    my $reference = $query->param('reference');
+		    my $solution = &generateText($g, $random, $seed, $limit, $asciiWeight, $reference);
+		    my $text = $solution->getHtml(' ');
+		    # Show the list and prompt again for validation.
+		    $presenter->promptValidateText('.', $ValidateTextOptions, 
+						   $UGenerateText, $uploads, 
+						   $name, $GenSpec->getName(), $text, 
+						   undef, undef, undef, $html, 
+						   $resultsMarkup, $seed, $limit, $asciiWeight);
+		} elsif ($action eq $ValidateText) {
+		    require W3C::Grammar::YackerSymbolParser;
+		    require W3C::Grammar::YackerTraceParser;
+
+		    # Step 3: validate text.
+		    my $text = $query->param('text');
+		    &utf8::decode($text);
+		    if (!$text) {
+			$presenter->error("no text supplied");
+		    }
+
+		    # Use directory timestamp to keep track of last use.
+		    my $time = time;
+		    utime($time, $time, "$uploads/$name");
+
+		    # Run the parser.
+		    my $argv0 = $GenSpec->getExecString("$uploads/$name", $name);
+		    #my $argv1 = $html ? 
+		    #  "#term-$name-" : 
+		    #	"$name/bnf?markup=html#term-$name-";
+		    my $processStdin = $text;
+		    &utf8::encode($processStdin);
+		    my ($results, $error, $traceHtml);
+
+		    # If the markup param is set, ask the executable for a trace.
+		    my $env = {TRACE_FD => 3}; # $query->param('markup') ? {TRACE_FD => 3} : {};
+		    W3C::Util::FilterN->new([$processStdin, \$results, \$error, \$traceHtml], 
+					    [\*STDIN, \*STDOUT, \*STDERR], 2)->
+			execute($argv0, $env, 1048576);
+		    &utf8::decode($results);
+		    &utf8::decode($error);
+		    my $html = '';
+		    if ($query->param('markup')) {
+			my $grammar = &_loadGrammar("$uploads/$name/bnf");
+			$html = &_getHtmlGrammar($grammar, 'html', $name);
+		    }
+		    if ($traceHtml) {
+			my @dl = ();
+			my $events = new W3C::Grammar::YackerTraceParser(-noErrors => 1)->parse($traceHtml);
+			foreach my $event (@$events) {
+			    # Unescape the production names to correspond to the EBNF.
+			    if ($event->isa('W3C::Grammar::YackerTraceConsume')) {
+				my ($token, $value) = ($event->getToken(), $event->getValue());
+				$token =~ s/GT_([a-z]+)/&lt;$Name2Symbol->{$1}&gt;/ig;
+				$token =~ s/IT_([a-z]+)/"$1"/ig;
+				$token =~ s/</&lt;/g;
+				$token =~ s/>/&gt;/g;
+				$value =~ s/</&lt;/g;
+				$value =~ s/>/&gt;/g;
+				push (@dl, "<dt><span class=\"token\">$token</span> <code class=\"result\">$value</code></dt>");
+			    } elsif ($event->isa('W3C::Grammar::YackerTraceStateChange')) {
+				my ($production, $rules) = ($event->getProduction(), $event->getRules());
+				my $productionMarkup = &prettyProduction($production, $query->param('markup') ? $name : undef);
+				my $ruleStr = '';
+				my $line2 = '';
+				my $rowSpan = '';
+				if (@$rules) {
+				    $line2 = "\n<tr>";
+				    $rowSpan = ' rowspan="2"';
+				    my @ruleStrs;
+				    foreach my $rule (@$rules) {
+					my $matched = $rule->getMatched();
+					foreach my $match (@$matched) {
+					    if ($match->isa('W3C::Grammar::YackerTraceMatch')) {
+						my $text = $match->getMatch();
+						$text =~ s/ +/ /g;
+						$text =~ s/</&lt;/g;
+						$text =~ s/>/&gt;/g;
+						$line2 .= "<td class=\"result\">$text</td>";
+					    } else {
+						my $error = $match->getError();
+						$line2 .= "<td class=\"error\">$error</td>";
+					    }
+					}
+					my $prettyRule = &prettyProduction($rule->getRule(), $query->param('markup') ? $name : undef);
+					my $matchCount = scalar @$matched;
+					if ($matchCount == 0) {
+					    $line2 .= "<td></td>";
+					    $matchCount = 1;
+					} elsif ($matchCount > 1) {
+					    $prettyRule .= "($matchCount)";
+					}
+					push (@ruleStrs, "<th colspan=\"$matchCount\"><span class=\"term\">$prettyRule</span></th>");
+				    }
+				    $ruleStr = join('', @ruleStrs);
+				    $line2 .= "</tr>";
+				}
+				push (@dl, "<dd><table border=\"1\" style=\"border-style: none; border-collapse: collapse; \"><tr><th$rowSpan style=\"vertical-align: top\"><span class=\"production\">$productionMarkup</span>:</th>$ruleStr</tr>$line2</table></dd>\n");
+			    } else {
+				my $error = $event->getError();
+				push (@dl, "<dd class=\"error\">$error</dd>");
+			    }
+			}
+			$traceHtml = join("\n", @dl);
+		    }
+		    $presenter->promptValidateText('.', $ValidateTextOptions, 
+						   $UGenerateText, $uploads, 
+						   $name, $GenSpec->getName(), $text, 
+						   $results, $error, $traceHtml, $html, 
+						   $resultsMarkup, 0, 50, 90);
+
+		} elsif ($action eq $AddTest) {
+		} else {
+		    $presenter->error("unknown action \"$action\"");
+		}
+	    }
+	}
+	print $presenter->flush(200);
+    }; if ($@) {
+	# Some exception handling pasted here -- @@@ needs work.
+	my $sessionId = $query ? $query->getSessionId : undef;
+	if (my $ex = &catch('W3C::Http::HttpMessageException')) {
+	    my $message = $ex->getHttpMessage();
+	    $message->addHeader('Session-Id', $sessionId) if (defined $sessionId);
+	    print $message->toString;
+	} elsif (my $ex = &catch('W3C::Rdf::CGIApp::AppException')) {
+	    print $ex->toString($sessionId);
+	} elsif (my $ex = &catch('W3C::Util::Exception')) {
+	    print "Status: 500\n";
+	    print "Content-Type: text/html\n\n";
+	    my $title = $ex->getMessage;
+	    print "<html><head><title>Yacker Error</title></head><body>\n";
+	    print "<pre>".$ex->toString."</pre>\n";
+	    if ($sessionId) {
+		print "<p>Session-id: $sessionId</p>\n";
+	    }
+	    print "</body></html>\n";
+	} else {
+	    print "Status: 500\n\n";
+	    print "died with $@";
+	    if ($sessionId) {
+		print "<p>Session-id: $sessionId</p>\n";
+	    }
+	}
+    }
+}
+
+sub prettyProduction {
+    my ($production, $language) = @_;
+    my $count = undef;
+    if ($production =~ s/\((\d+)\)$//) {
+      $count = $1;
+    }
+    my $parser = new W3C::Grammar::YackerSymbolParser();
+    my ($ret, $error) = (undef, undef);
+    eval {
+	my $root = $parser->parse($production);
+	$ret = $root->toString(Markup => 'html', LanguageName => $language);
+	if (defined $count) {
+	    $ret = "$ret($count)";
+	}
+    }; if ($@) {
+	my $ex = &catch('W3C::Util::Exception');
+	$error = $ex->getMessage;
+    }
+    if (defined $ret) {
+	return $ret;
+    }
+    $production =~ s/GT_([A-Z]+)/<$Name2Symbol->{$1}>/ig;
+    $production =~ s/IT_([A-Z]+)/"$1"/ig;
+    $production =~ s/_Opt/?/g;
+    $production =~ s/_Plus/+/g;
+    $production =~ s/_Star/*/g;
+    $production =~ s/_Or_/ | /g;
+    $production =~ s/_O/( /g;
+    $production =~ s/_C/ )/g;
+    $production =~ s/_Q//g;
+    $production =~ s/_E//g;
+    $production =~ s/_S/ /g;
+    $production =~ s/__/_/g;
+
+    # Escape HTML.
+    $production =~ s/</&<<;/g;
+    $production =~ s/>/&>>;/g;
+
+    # Add markup.
+    if ($language) {
+	$production =~ s/([\w\d]+)/<a href="#prod-$language-$1">$1<\/a>/gm;
+    }
+    $production =~ s/&<<;/&lt;/g;
+    $production =~ s/&>>;/&gt;/g;
+    if (defined $count) {
+	$production = "$production($count)";
+    }
+    return $production; # "$production <span class=\"error\">$error</span>";
+}
+
+sub cliMode {
+
+
+    # Run as a command line tool.
+
+    require Getopt::Long;
+    require Pod::Usage;
+
+
+
+    my $presenter = new W3C::Grammar::TextPresenter($REVISION, $LegalFileName);
+    my $solve = 0;
+    my $seed = 0;
+    my $limit = 50;
+    my $asciiWeight = 90;
+    &Getopt::Long::GetOptions(
+      '<>' => sub {
+	  eval {
+	      my ($file) = @_;
+	      my $bnf;
+
+	      open (G, $file) || die "can't open file \"$file\"; $!\n";
+	      {
+		  local $/=undef;
+		  $bnf=<G>;
+	      }
+	      local($SIG{"__DIE__"}) = \&DieHandler;
+	      my ($g, $errs) = &_parseGrammar($bnf);
+		    if (@$errs) {
+			my $errsStr = &W3C::Grammar::YaccParser::getMessages($errs);
+			&throw(new W3C::Util::Exception(-message => "rejected because of the following errors:\n$errsStr"));
+		    }
+	      if ($solve) {
+		  my ($random, $reference) = (0, 0);
+		  my $solution = &generateText($g, $random, $seed, $limit, $asciiWeight, $reference);
+		  my $t = $solution->getHtml(' ');
+
+		  &utf8::encode($t);
+		  print "$t\n";
+	      } else {
+		  &createGrammar($g, $presenter, '.', $suppressLineDirectives);
+		  if (my @missingActions = $GenSpec->getMissingActions()) {
+		      my $count = @missingActions;
+		      my $list = join("\n    ", "$count missing actions:", map {
+			  $_ =~ s/([^ ]+)([ ]?)/$1:$2/; $_;
+		      } @missingActions);
+		      print STDOUT "$list\n";
+		  }
+		  if (my @unusedActions = $GenSpec->getUnusedActions()) {
+		      my $count = @unusedActions;
+		      my $list = join("\n    ", "$count unused actions:", map {
+			  my $lineNo = $GenSpec->getAction($_)->getLineNo();
+			  $_ =~ s/([^ ]+)([ ]?)/$1:$2/; "$_ at $lineNo"
+		      } @unusedActions);
+		      print STDOUT "$list\n";
+		  }
+
+		      print STDOUT "LUC LUC\n";
+		    my $html = &_getHtmlGrammar($g, 'html', $name);
+		    open(HTML, '>', "prov_n.html") || die "unable to create HTML file \"prov_n.html\"";
+
+		      print HTML "$html\n";
+
+
+
+		  my $prodNo = 1;
+	      }
+	      #print $g->toString(Stubs => $GenSpec, ProdNo => \ $prodNo, LanguageName => "${name}-", ExpandTerminals => $expandTerminals);
+	      #print $presenter->print($g->toString(Markup => $GenSpec, ProdNo => \ $prodNo, LanguageName => "${name}-"));
+	      #print $presenter->print($g->toString(Markup => undef, ProdNo => \ $prodNo, LanguageName => "${name}-"));
+	      $processed++;
+	  }; if ($@) {if (my $ex = &catch('W3C::Util::Exception')) {
+	      die $ex->toString();
+	  } else {
+	      die $@;
+	  }
+		  }
+      }, 
+      'lang|l=s' => sub {
+	  if (defined $code) {
+	      die "-lang must be used before -code\n";
+	  }
+	  if (!($GenSpec = $LANGS->{$_[1]})) {
+	      my $opts = join(', ', keys %$LANGS);
+	      if ($_[1] eq 'help') {
+		  print "$opts\n";
+		  exit (0);
+	      } else {
+		  die "unknown language \"$_[1]\". must be one of $opts\n";
+	      }
+	  }
+      }, 
+      'output|o=s' => \$name, 
+      'nolines|n!' => \$suppressLineDirectives, 
+      'stubs|s!' => \$stubs, 
+      'debug=s' => sub {
+	  my (undef, $debugSession) = @_;
+	  &cgiMode($debugSession);
+	  exit(0);
+      }, 
+      'code|c=s' => sub {
+	  my (undef, $filename) = @_;
+	  $code = $filename;
+	  eval {
+	      if (!open (C, $filename)) {
+		  &throw(new W3C::Util::FileOperationException(-filename => $filename, 
+							       -operation => 'open for reading'));
+	      }
+	      local $/=undef;
+	      my $code = <C>;
+	      close (C);
+	      my $p = new W3C::Grammar::YaccParser(1); # no integrity check
+	      $p->setFilename($filename);
+	      my ($g, $errs) = $p->Parse($code, 0x00);
+		    if (@$errs) {
+			my $errsStr = &W3C::Grammar::YaccParser::getMessages($errs);
+			&throw(new W3C::Util::Exception(-message => "code file rejected because of the following errors:\n$errsStr"));
+		    }
+	      $g->yaccify(sub {&throw();}, $GenSpec);
+	      $GenSpec->read($g, $filename);
+	      $stubs = 1;	# No reason to read code unless you are generating stubs.
+	  }; if ($@) {if (my $ex = &catch('W3C::Util::Exception')) {
+	      die $ex->toString();
+	  } else {
+	      die $@;
+	  }}
+      }, 
+      'short!' => \$generateNames, 
+      'expandTerminals!' => sub {$GenSpec->toggleExpandTerminals()}, 
+      'solve!' => \$solve, 
+      'seed=i' => \$seed, 
+      'limit=i' => \$limit, 
+      'ascii=i' => \$asciiWeight, 
+      'help|?' => \$help, 
+      'man' => \$man) || &Pod::Usage::pod2usage(2);
+
+    &Pod::Usage::pod2usage(1) if $help;
+    &Pod::Usage::pod2usage(-exitstatus => 0, -verbose => 2) if $man;
+    if (!$processed) {
+	&Pod::Usage::pod2usage(2);
+    }
+}
+
+sub generateText { # static
+    my ($g, $random, $seed, $limit, $asciiWeight, $reference) = @_;
+    my $creativePolicy = $random ? 
+      new W3C::Grammar::YaccCompileTree::RandomPolicy($seed, $limit, $asciiWeight) : 
+	new W3C::Grammar::YaccCompileTree::RepresentativePolicy($seed, $limit, $asciiWeight);
+    my $relativePolicy = $reference ? 
+      new W3C::Grammar::YaccCompileTree::ReferencePolicy($reference, $creativePolicy) : 
+	$creativePolicy;
+
+    return $g->solve($relativePolicy, $g, 1);
+}
+
+sub W3C::Grammar::_YaccParser::IsSpacePerl {
+    return &utf8::IsSpacePerl;
+#    my $argsStr = join(' | ', @_, $a);
+#    my $wa = wantarray;
+#    return qr(\s\r\n);
+#    die "$wa W3C::Grammar::_YaccParser::IsSpacePerl($argsStr)\n";
+}
+
+sub _parseGrammar {
+    my ($bnf) = @_;
+    my $p = new W3C::Grammar::YaccParser();
+    # @@ Hack -- to add the default @pass directive.
+    my $text = $bnf =~ m/^\s*(?:\[[0-9][0-9a-zA-Z]*\]\s*)?\@pass\s*:/m ? 
+      $bnf : 
+	"$bnf\n\@pass: [ \\t\\r\\n]+\n";
+    if ($text !~ m{^\%\%}) {
+	$p->fake('bodyTransition');
+    }
+    return $p->Parse($text, 0x00);
+}
+
+sub _loadGrammar {
+    my ($path) = @_;
+    # Grab the BNF.
+    my $bnf;
+    {
+	local $/ = undef;
+	open(BNF, $path) || die "unable to open BNF file \"$path\"";
+	$bnf = <BNF>;
+	close(BNF);
+	&utf8::decode($bnf);
+    }
+    my ($g, $errs) = &_parseGrammar($bnf);
+		    if (@$errs) {
+			my $errsStr = &W3C::Grammar::YaccParser::getMessages($errs);
+    # Assume no errors on re-load
+			&throw(new W3C::Util::Exception(-message => "inexplicable errors:\n$errsStr"));
+		    }
+    return $g;
+}
+
+sub _getHtmlGrammar {
+    my ($g, $lang, $name) = @_;
+    my $prodNo = 1;
+    return $g->toString(Markup => $lang, ProdNo => \ $prodNo, LanguageName => "${name}-", LexFormat => 'XMLSpec');
+}
+
+sub createGrammar {
+    my ($g, $presenter, $uploads, $suppressLineDirectives) = @_;
+    eval {
+	my $symNumber = 0;
+	my $genNamesFunc = $generateNames ? sub {
+	    my ($grammar, $derivedName) = @_;
+	    return 'gen'.$symNumber++;
+	} : undef;
+	my %flags = (LineNumbers => 0, 
+		     Types => 0, 
+		     OrigCode => 0, 
+		     Comments => 1, 
+		     Yacc => 1, 
+		     GenSpec => $GenSpec, 
+		     Stubs => $stubs ? $GenSpec : undef, 
+		     SuppressLineDirectives => $suppressLineDirectives, 
+		     Class => $name);
+
+	if ($stubs) {
+	    my $templateDir = ($0 =~ m/^(.*?)yacker/)[0];
+
+	    # We're called upon to create a yacc grammar with
+	    # semantic actions that parse the specified language.
+	    $GenSpec->createGrammar($g, $genNamesFunc, $uploads, $name, $templateDir, %flags);
+	} else {
+
+	    # Simply reformat the BNF and present it.
+
+	    $presenter->print($g->toString(%flags));
+	}
+
+    }; if ($@) {
+	if (my $ex = &catch('W3C::Util::Exception')) {
+	    die $ex->toString();
+	} else {
+	    die $@;
+	}
+    }
+}
+
+__END__
+
+=head1 NAME
+
+yacker - grammar manipulation tool
+
+=head1 SYNOPSIS
+
+yacker [options] grammar
+
+    -man for more details
+
+=head1 OPTIONS
+
+=over 8
+
+=item B<-lang|s> name
+
+Language for output. -lang help will give a list of supported languages.
+
+B<-lang> must be used before B<-code>.
+
+default: perl
+
+=item B<-output|o> name
+
+Name of the language to generate a parser for.
+
+default: a
+
+=item B<-short>
+
+Flag to generate short names for generated productions.
+
+=item B<-expandTerminals>
+
+Flag to embed the text of one terminal in another, rather than including it by reference. This generally defaults to off, but python and n3 require it so it is forced on regardless of expandTerminals directives.
+
+=item B<-nolines|n>
+
+Suppress line directives (in languages where they are possible).
+
+=item B<-stubs|s>
+
+Generate code stubs for each production. This is useful when starting a parser. See the B<-code> option.
+
+B<-lang> must be used before B<-stubs>.
+
+=item B<-code|c> file
+
+Read code for each production from file. The file can be the output of an earlier B<-stubs> call, potentially updated by your skilled hand. This is useful when updating a parser.
+
+B<-code> file implies B<-stubs>.
+
+B<-lang> must be used before B<-code>.
+
+=item B<-solve>
+
+Flag to generate a piece of text that parses in the new language.
+
+=over 4
+
+=item B<-seed> int
+
+Random seed for parts of the solution that are randomly generated. Using the same seed will yield the same solution.
+
+=item B<-limit> int
+
+How many productions to expand before always taking the shortest solution, i.e.
+  - expand * to 0 entries
+  - expand ? to 0 entries
+  - expand + to 1 entry
+
+=item B<-ascii> int
+
+The weight to give ASCII ranges within larger ranges. This is useful when testing on primative terminals.
+
+=back
+
+=item B<-debug> sessionId
+
+Runs the CGI interface, reading the input for the given session from /tmp/yacker.log .
+This is exploited by running $(QUERY_STRING=1 ./yacker DEBUG).
+
+=item B<-help>
+
+Print a brief help message and exits.
+
+=item B<-man>
+
+Prints the manual page and exits.
+
+=back
+
+=head1 DESCRIPTION
+
+B<yacker> parses BNF or yack grammars and generates.
+
+The typical maintaince cycle of language will start with the generation of stubs:
+
+    yacker -stubs -lang perl -o foo foo.bnf
+
+This will produce some code, for example foo.yp for the perl B<-lang>. The maintainer will use the output of the above command as a starting point for generating the parser, modifying foo.yp as necessary. If the lanuage (foo.bnf) changes, the maintainer can update the parser, using the previous code to generate the new code:
+
+    cp foo.yp foo.yp.last
+    yacker -lang perl -code foo.yp.last -o foo foo.bnf
+
+This will generate a list of changes from one version of the grammar to the next.
+
+=over 4
+
+1 missing actions:
+    BaseDecl: IT_BASE Q_IRI_REF
+
+1 unused actions:
+    BaseDecl: IT_BASE QuotedIRIref at 212
+
+=back
+
+I (ericP) usually start with the most repeated unused action and look for it something analogous to it in the missing actions. Frequently, a few renamed productions can reduce the mismatch between the old and new grammar.
+
+=head2 missing actions
+
+Each entry is a production name that is present in (or implied by) the new grammar, but for which there is no code in the grammar linked by the B<-code> argument. e.g.
+
+=over 4
+
+    BaseDecl: IT_BASE Q_IRI_REF
+
+=back
+
+
+=head2 unused actions
+
+Each entry is a production name that was present in the grammar linked by the B<-code> argument, but is not needed (or implied) by the new grammar. The line number is where the code was declared in the code source. e.g.
+
+=over 4
+
+    BaseDecl: IT_BASE QuotedIRIref at 212
+
+=back
+
+=head1 ENVIRONMENT
+
+B<QUERY_STRING> controls whether yacker runs as a CGI script or a command like tool.
+E.g. to re-run the last web query: QUERY_STRING=1 ./yacker DEBUG
+
+=head1 AUTHOR
+
+Eric Prud'hommeaux <eric@w3.org>
+
+=head1 COPYRIGHT
+
+Copyright Massachusetts Institute of technology, 2004.
+
+THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS
+OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR
+FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE
+ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. 
+
+COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION. 
+
+The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining 
+to the software without specific, written prior permission. Title to copyright in this software and 
+any associated documentation will at all times remain with copyright holders. 
+
+=cut
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/t/01basic.t	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,16 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+use Test::More qw(no_plan);
+use_ok('W3C::Grammar::YaccParser') or exit;
+
+# specifying a bogus grammar should fail
+
+eval {
+    my $p = new W3C::Grammar::YaccParser(1); # no integrity check
+    $p->setFilename('nonexistent.ebnf');
+    my ($g, $errs) = $p->Parse('asdf', 0x00);
+};
+like($@, qr/START/);
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/t/02yaml.t	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,22 @@
+#!/usr/bin/perl -w
+use strict;
+use warnings;
+use lib 't/lib';
+
+use Test::More qw(no_plan);
+use TestRunner qw(test_yml foreach_parser);
+
+my $buildTestDir = 't/buildTestDir';
+mkdir($buildTestDir);
+foreach_parser {
+    my ($genspec) = @_;
+    if ($ENV{TEST_YML}) {
+        test_yml($genspec, $buildTestDir, $ENV{TEST_YML});
+    } else {
+        for (sort glob('t/*.yml')) {
+            print "\n######## $_ #######\n";
+            test_yml($genspec, $buildTestDir, $_);
+        }
+    }    
+};
+rmdir($buildTestDir);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Grammar/t/lib/TestRunner.pm	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,144 @@
+# YAML test runner for XML::Grammar.  Takes .yml files
+# containing a schema and applies it to one or more files evaluating
+# the results as specified.  Just look at t/*.yml and you'll get the
+# idea.
+
+package TestRunner;
+use strict;
+use warnings;
+
+use Test::Builder;
+my $Test = Test::Builder->new;
+
+require Exporter;
+our @ISA = qw(Exporter);
+our @EXPORT = ('test_yml', 'foreach_parser');
+
+use YAML qw(LoadFile);
+use W3C::Grammar::YaccParser;
+use W3C::Util::Filter;
+use W3C::Util::Exception;
+use Cwd qw(cwd);
+
+use Data::Dumper;
+
+sub foreach_parser (&) {
+    my $tests = shift;
+
+    my @path = split(':', $ENV{PATH});
+    my @genspecs = ();
+    push (@genspecs, new W3C::Grammar::GenSpec::Perl()) if (grep { -e "$_/perl" } @path);
+    if (grep { -e "$_/yacc" } @path) {
+	push (@genspecs, new W3C::Grammar::GenSpec::C_()) if (grep { -e "$_/bison" } @path);
+	push (@genspecs, new W3C::Grammar::GenSpec::CPP()) if (grep { -e "$_/bison++" } @path);
+    }
+    push (@genspecs, new W3C::Grammar::GenSpec::Python()) if (grep { -e "$_/python" } @path);
+
+    # run tests with all available parser languages
+    foreach my $genspec (@genspecs) {
+        my $name = ref $genspec;
+        print STDERR "\n\n                ======> Testing against $name ".
+          "<======\n\n";
+        $tests->($genspec);
+    }
+}
+
+sub test_yml {
+    my ($genspec, $uploads, $file) = @_;
+    my ($name) = $file =~ /(\w+)\.yml$/;
+    my @data = LoadFile($file);
+
+    # write out the schema file
+    my $ebnf = shift @data;
+    my $ebnfFile = "$uploads/$name.ebnf";
+    open(my $fh, '>', $ebnfFile) or die $!;
+    print $fh $ebnf;
+    close($fh) or die $!;
+
+    my $templateDir = 'bin';
+    my %flags = (LineNumbers => 0, 
+		 Types => 0, 
+		 OrigCode => 0, 
+		 Comments => 1, 
+		 Yacc => 1, 
+		 GenSpec => $genspec, 
+		 Stubs => $genspec, 
+		 SuppressLineDirectives => 0, 
+		 Class => $name);
+
+    my ($results, $error);
+    # generate a parser from the EBNF.
+    eval { 
+	my $p = new W3C::Grammar::YaccParser(1); # no integrity check
+	$p->setFilename($ebnfFile);
+	my ($g, $errs) = $p->Parse($ebnf, 0x00);
+	$genspec->createGrammar($g, undef, $uploads, $name, $templateDir, %flags);
+	open(my $MAKE, '>', "$uploads/Makefile") || die "unable to create Makefile";
+	$genspec->makeMakefile($MAKE, $templateDir, $name, $g);
+	close($MAKE);
+	$genspec->makeAuxilliaryFiles($uploads, $templateDir, $name);
+	$genspec->clearLexDecls(); # so they don't accumulate over each pass.
+
+	# perform the system calls to build the parser.
+	my $target = $genspec->getTarget($name);
+	($results) = 
+	    W3C::Util::SyncFilter->new("make -C $uploads $target", undef)->execute(4096, 1);
+	if (my @errors = $results->getByFlavor('stderr')) {
+	    $error = join('', map {$_->getData()} @errors);
+	    die "\$(make -C $uploads $target) failed: $error";
+	}
+    };
+    if ($@) {
+	my $errStr = $@;
+	if (my $ex = &catch('W3C::Util::Exception')) {
+	    $@ = $errStr; # restore the exception from before the call to catch.
+	    $errStr = $ex->toString();
+	}
+	print STDERR "$name.yml: grammar construction ====> $errStr\n";
+    } else {
+	my $num = 0;
+	while(@data) {
+	    my $text = shift @data;
+	    my $result = shift @data;
+	    chomp($result);
+	    $num++;
+
+	    eval {
+		# perform the system calls to parse $text.
+		my $argv0 = $genspec->getExecString($uploads, $name);
+		($results, $error) = 
+		    W3C::Util::Filter->new($argv0, $text)->execute(4096, 1);
+		die "\$($argv0) failed: $error" if $error;
+	    };
+	    my $err = $@;
+	    my $errStr = $@;
+	    if ($@) {
+		if (my $ex = &catch('W3C::Util::Exception')) {
+		    $errStr = $ex->toString();
+		    $@ = $err; # restore the exception from before the call to catch.
+		}
+	    }
+
+	    if ($result =~ m!^FAIL\s*(?:/(.*?)/)?$!) {
+		my $re = $1;
+		$Test->ok($err, "$name.yml: block $num should fail validation");
+		if ($re) {
+		    if ($err) {
+			$Test->like($err, qr/$re/, 
+				    "$name.yml: block $num should fail matching /$re/");
+		    } else {
+			$Test->ok(0, "$name.yml: block $num should fail matching /$re/");
+		    }
+		}
+	    } else {
+		$Test->ok(not($err), "$name.yml: block $num should pass validation");
+		print STDERR "$name.yml: block $num ====> $errStr\n" if $err;
+	    }
+	}
+    }
+    # cleanup
+    `rm $uploads/*`;
+}
+
+
+1;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Util/Exception.pm	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,881 @@
+#Copyright Massachusetts Institute of technology, 1998.
+#Written by Eric Prud'hommeaux for the World Wide Web Consortium
+
+use strict;
+
+require Exporter;
+require AutoLoader;
+
+package W3C::Util::Exception;
+
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
+@ISA = qw(Exporter AutoLoader);
+@EXPORT = qw(&throw &catch);
+@EXPORT_OK = qw(&watch &DieHandler);
+$VERSION = 1.0;
+
+$W3C::Util::Exception::revision = '$Id: Exception.pm,v 1.79 2007-05-25 21:16:15 eric Exp $ ';
+
+@W3C::Util::ExceptionConstructionException::ISA = qw(W3C::Util::Exception);
+@W3C::Util::IOException::ISA = qw(W3C::Util::Exception);
+@W3C::Util::OutOfBoundsException::ISA = qw(W3C::Util::Exception);
+@W3C::Util::FunctionException::ISA = qw(W3C::Util::Exception);
+@W3C::Util::DeprecatedException::ISA = qw(W3C::Util::FunctionException);
+@W3C::Util::NotImplementedException::ISA = qw(W3C::Util::FunctionException);
+@W3C::Util::ParameterException::ISA = qw(W3C::Util::Exception);
+@W3C::Util::SafeEvaluationException::ISA = qw(W3C::Util::Exception);
+@W3C::Util::UnsafeEvaluationException::ISA = qw(W3C::Util::Exception);
+
+
+#####
+# per-class data
+# hash table of current exceptions - needed in multi-threaded environment.
+%W3C::Util::Exception::currentException = ();
+$W3C::Util::Exception::IgnoreNext = 0;
+
+#####
+# constants
+my ($PACKAGENAME, $FILENAME, $LINE, $SUBROUTINE, $HASARGS, $WANTARRAY, $EVALTEXT, $IS_REQUIRE) = (0..7);
+
+#####
+# throw
+
+sub throw {
+    my ($exception) = @_;
+    if (!$exception || !UNIVERSAL::isa($exception, 'W3C::Util::Exception')) {
+	if ($exception = &catch('W3C::Util::Exception')) {
+	} else {
+	    $exception = new W3C::Util::UnspecifiedException();
+	}
+    }
+    $@ = '<'.$exception.'> '.$exception->getMessage." at $exception->{STACK_FRAMES}[0][1] line $exception->{STACK_FRAMES}[0][2].\n";
+    $W3C::Util::Exception::currentExceptions{$exception} = [$exception, $@];
+    $W3C::Util::Exception::currentException = $exception;
+    if ($W3C::Util::Exception::IgnoreNext) {
+	$W3C::Util::Exception::IgnoreNext--;
+	return $exception;
+    }
+    die $@;
+}
+
+#####
+# catch
+
+sub catch {
+    my ($type) = @_;
+    return undef if (!$@ || $@ !~ m/^\<([^\>]+)\>/);
+    my $lookFor = $1;
+    my $pair = $W3C::Util::Exception::currentExceptions{$lookFor};
+    return undef if (!defined $pair);
+    my ($current, $msg) = @$pair;
+    if (UNIVERSAL::isa($current, $type)) {
+	delete $W3C::Util::Exception::currentExceptions{$lookFor};
+	if ($@ ne $msg) {
+	    print STDERR "\$@ changed to $@";
+	}
+	undef $@;
+	return $current;
+    } else {
+	return undef;
+    }
+}
+
+sub watch {
+    my (@codes) = @_;
+    my @ret;
+    foreach my $code (@codes) {
+	eval {
+	    @ret = &$code;
+	}; if ($@) {
+	    # watch is not intended to be used with other die handlers.
+	    local($SIG{"__DIE__"}) = '__DEFAULT__';
+	    if (my $ex = &catch('W3C::Util::Exception')) {
+		die $ex->toString;
+	    } else {
+		die $@;
+	    }
+	}
+    }
+    return @ret;
+}
+
+sub DieHandler {
+    my ($msg) = @_;
+
+    # Keep nested calls to die (like in &throw) from calling this handler.
+    local($SIG{"__DIE__"}) = '__DEFAULT__';
+
+    if (my $ex = &catch('W3C::Util::Exception')) {
+	# Already in an exception state.
+	&throw($ex);
+    } else {
+	# Handling a perl exception.
+	&throw(new W3C::Util::DieException(-dieHandlerArg => $msg));
+    };
+}
+
+sub new {
+    my ($proto, $parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self;
+    if (ref $parms eq 'HASH') {
+	$self = $parms;
+    } elsif (ref $parms eq 'ARRAY') {
+	$self = {@$parms};
+    } elsif (ref $parms eq 'SCALAR') {
+	$self = {-message => $$parms};
+    } elsif ($parms) {
+	$self = {$parms, @_};
+    } else {
+	$self = {};
+    }
+    bless ($self, $class);
+    $self->fillInStackTrace;
+    return $self;
+}
+
+sub fillInStackTrace {
+    my ($self, $stackIncrement) = @_;
+    if (!defined $stackIncrement) {
+	$stackIncrement = 0;
+    }
+    $self->{STACK_FRAMES} = [];
+    for (my $i = 1 + $stackIncrement; $i < 100; $i++) {
+	my (@frame) = caller($i);
+	if (defined $frame[$SUBROUTINE]) {
+	    push (@{$self->{STACK_FRAMES}}, \@frame);
+	} else {
+	    last;
+	}
+    }
+}
+
+sub assumeStackTrace {
+    my ($self, $ex) = @_;
+    $self->{STACK_FRAMES} = $ex->{STACK_FRAMES};
+}
+
+sub getMessage {
+    my ($self) = @_;
+    if ($_[0]->{-exceptionConstructionException}) {
+	return $self->{-exceptionConstructionException}->getMessage;
+    }
+    my $chainedMessage = $self->{-chainedException} ? 
+	join ("\n", $self->{-chainedException}->getMessage)."\n" : '';
+    my $message = $self->getSpecificMessage ? 
+	join ("\n", $self->getSpecificMessage) : 
+	$self->{-message};
+    return "$message$chainedMessage";
+}
+sub toString {
+    my ($self) = @_;
+    if ($self->{-exceptionConstructionException}) {
+	return $self->{-exceptionConstructionException}->toString();
+    }
+    my $ret;
+    foreach my $message ($self->getMessage) {
+	&printMessage($message, \ $ret);
+    }
+    $self->printStackTrace(\ $ret);
+    return $ret;
+}
+# overload this baby for exception-specific messages
+sub getSpecificMessage {return undef;}
+sub printStackTrace {
+    my ($self, $outputHandle) = @_;
+    if ($self->{-chainedException}) {
+	return $self->{-chainedException}->printStackTrace($outputHandle);
+    }
+    for (my $i = 0; $i < @{$self->{STACK_FRAMES}}; $i++) {
+	my $frame = $self->{STACK_FRAMES}[$i];
+	my @messageLine;
+	if ($i > 0) {
+	    if ($frame->[$SUBROUTINE] eq '(eval)' && $frame->[$EVALTEXT]) {
+		push (@messageLine, 'eval ('.$frame->[$EVALTEXT].')');
+	    } else {
+		push (@messageLine, $frame->[$SUBROUTINE]);
+	    }
+	    push (@messageLine, '(...)') if ($frame->[$HASARGS]);
+	} else {
+	    push (@messageLine, (ref $self).' thrown');
+	}
+	push (@messageLine, ' at '.$frame->[$FILENAME].':'.$frame->[$LINE]);
+	&printMessage(join ('', @messageLine), $outputHandle);
+    }
+}
+
+sub printMessage {
+    my ($message, $outputHandle) = @_;
+    if (ref $outputHandle eq 'SCALAR') {
+	$$outputHandle .= $message."\n";
+    } elsif (ref $outputHandle eq 'ARRAY') {
+	push (@$outputHandle, $message);
+    } elsif (ref $outputHandle eq 'GLOB') {
+	print $outputHandle $message."\n";
+    } elsif (ref $outputHandle && $outputHandle->can('println')) {
+	$outputHandle->println($message);
+    } elsif (defined $outputHandle) {
+	print $outputHandle $message."\n";
+    } else {
+	print STDERR $message."\n";
+    }
+}
+
+# missingParm -- called by an Exception constructor to flag missing missing
+# 		 constructor parameters.
+# May make this cooler, but exceptions within exceptions are a pain.
+sub missingParm {
+    my ($self, $name) = @_;
+    $self->{-exceptionConstructionException} = 
+	new W3C::Util::ExceptionConstructionException((caller(1))[0,1,2], 
+						      -missingParm => $name, 
+						      -parentException => $self);
+}
+
+package W3C::Util::UnspecifiedException;
+@W3C::Util::UnspecifiedException::ISA = qw(W3C::Util::Exception);
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    $self->{-error} = "$@:($!)" if (!$self->{-error});
+    $self->fillInStackTrace;
+    shift (@{$self->{STACK_FRAMES}});
+    return $self;
+}
+sub getSpecificMessage {
+    my ($self) = @_;
+    my $curError = $self->getError ? ' (current perl error: '.$_[0]->getError().')' : '';
+    return "Unspecified Exception$curError";}
+sub getError {return $_[0]->{-error}}
+
+package W3C::Util::ExceptionConstructionException;
+sub new {
+    my ($proto, $ex, $file, $line, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    die 'W3C::Util::ExceptionConstructionException (via '.$ex.') exception needs a "-missingParm" parameter' 
+	if (!$self->{-missingParm});
+    die 'W3C::Util::ExceptionConstructionException (via '.$ex.') exception needs a "-exceptionConstructionException" parameter' 
+	if (!$self->{-parentException});
+    return $self;
+}
+sub getSpecificMessage {return (ref $_[0]->{-parentException}).' exception needs a "'.$_[0]->{-missingParm}.'" parameter';}
+
+package W3C::Util::FileException;
+@W3C::Util::FileException::ISA = qw(W3C::Util::IOException);
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    $self->missingParm('-filename') if (!exists $self->{-filename});
+    $self->{-error} = $! if (!$self->{-error});
+    $self->fillInStackTrace;
+    return $self;
+}
+sub getSpecificMessage {&W3C::Util::Exception::throw(new W3C::Util::NotImplementedException());}
+sub getFilename {return $_[0]->{-filename}}
+sub getError {return $_[0]->{-error}}
+
+package W3C::Util::FileOperationException;
+@W3C::Util::FileOperationException::ISA = qw(W3C::Util::FileException);
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    $self->missingParm('-operation') if (!exists $self->{-operation});
+    $self->fillInStackTrace;
+    return $self;
+}
+sub getSpecificMessage {return $_[0]->getOperation." exception on file \"".$_[0]->getFilename.'": '.$_[0]->getError;}
+sub getOperation {return $_[0]->{-operation}}
+
+package W3C::Util::FileNotFoundException;
+@W3C::Util::FileNotFoundException::ISA = qw(W3C::Util::FileException);
+sub getSpecificMessage {return "Can't open file \"".$_[0]->getFilename.'": '.$_[0]->getError;}
+
+package W3C::Util::LibraryNotFoundException;
+@W3C::Util::LibraryNotFoundException::ISA = qw(W3C::Util::FileException);
+sub getSpecificMessage {return "Can't open library \"".$_[0]->getFilename.'": '.$_[0]->getError;}
+
+package W3C::Util::FileCreationException;
+@W3C::Util::FileCreationException::ISA = qw(W3C::Util::FileException);
+sub getSpecificMessage {return "Can't create file \"".$_[0]->getFilename.'": '.$_[0]->getError;}
+
+package W3C::Util::EOFException;
+@W3C::Util::EOFException::ISA = qw(W3C::Util::IOException);
+sub getSpecificMessage {return 'EOF'.($_[0]->getFilename ? ' on "'.$_[0]->getFilename.'"' : '')}
+sub getFilename {return $_[0]->{-filename}}
+
+package W3C::Util::FunctionException;
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    if (!$self->{-class} || !$self->{-method}) {
+	if ($self->{-function}) {
+	    my @segments = split ('::', $self->{-function});
+	    $self->{-class} = join ('::', @segments[0..@segments-2]);
+	    $self->{-method} = $segments[-1];
+	} else {
+	    no strict;
+	    my $depth = defined $ {$class.'::_ClassDepth'} ? $ {$class.'::_ClassDepth'} : 1;
+	    use strict;
+	    my ($packageName, $filename, $line, $subroutine, $hasargs, $wantarray, $evaltext, $is_require) = caller($depth);
+#	    print join (' | ', ($packageName, $filename, $line, $subroutine, $hasargs, $wantarray, $evaltext, $is_require)),"\n";
+	    $subroutine = '- - main - -' if (!defined $subroutine);
+	    $subroutine =~ m/(?:(.*?)::)?([^\:]+)$/;
+	    my ($derivedPackage, $derivedMethod) = ($1, $2);
+	    $self->{-class} = $derivedPackage if (!$self->{-class});
+	    $self->{-method} = $derivedMethod if (!$self->{-method});
+	    if (!$self->{-location}) {
+		my ($packageName, $filename, $line, $subroutine, $hasargs, $wantarray, $evaltext, $is_require) = caller($depth-1);
+		$self->{-location} = $line;
+	    }
+	}
+    }
+    $self->fillInStackTrace;
+    return $self;
+}
+sub getSpecificMessage {
+    my ($self) = @_;
+    my $post = $self->{-callingClass} ? ' for class '.ref $self->{-callingClass} : '';
+    return 'function "'.$self->getFunction.'" is not implemented'.$self->_getObjectString.$post;
+}
+sub getClass {return $_[0]->{-class}}
+sub getMethod {return $_[0]->{-method}}
+sub getFunction {return $_[0]->getClass ? $_[0]->getClass.'::'.$_[0]->getMethod : $_[0]->getMethod}
+sub getObject {return $_[0]->{-object}}
+sub _getObjectString {return $_[0]->{-object} ? " for object $_[0]->{-object}" : ''}
+
+package W3C::Util::ProgramFlowException;
+@W3C::Util::ProgramFlowException::ISA = qw(W3C::Util::FunctionException);
+sub getSpecificMessage {my $ret = 'should not arrive at "'.$_[0]->getFunction; 
+			$ret .= ':'.$_[0]->getLocation if ($_[0]->getLocation); 
+			$ret .= ' state:{'.$_[0]->getState.'}' if ($_[0]->getState); 
+			return $ret.'"';}
+sub getLocation {return $_[0]->{-location}}
+sub getState {return $_[0]->{-state}}
+
+@W3C::Util::DebugCheckException::ISA = qw(W3C::Util::ProgramFlowException);
+
+package W3C::Util::PerlException;
+@W3C::Util::PerlException::ISA = qw(W3C::Util::FunctionException);
+$W3C::Util::PerlException::_ClassDepth = 2;
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    if (!$self->{-error}) {
+	chomp ($@), $self->{-error} = $@.' - '.$! ;
+    }
+    $self->fillInStackTrace;
+    return $self;
+}
+
+sub getSpecificMessage {return 'native perl exception "'.$_[0]->getError.'" in '.$_[0]->getFunction}
+sub getError {return $_[0]->{-error}}
+
+package W3C::Util::DieException;
+@W3C::Util::DieException::ISA = qw(W3C::Util::Exception);
+#$W3C::Util::DieException::_ClassDepth = 4; when this is a FunctionException
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    $self->missingParm('-dieHandlerArg') if (!exists $self->{-dieHandlerArg});
+    $self->fillInStackTrace;
+
+    my $text = $self->{-dieHandlerArg};
+
+    # Parse the die message. Could look like:
+    # 'could not read "/asdf": No such file or directory at Makefile.PL line 82.'
+    # 'could not read "/asdf": No such file or directory at Makefile.PL line 82, <STDIN> line 2.'
+    # how about this format?
+    # 'could not read "/asdf": No such file or directory at Makefile.PL line 82, <STDIN> line 2, <STDOUT> line 5.'
+    if (my ($msg, $where) = $text =~ 
+	m/^(.*?) at ((?:[^ ]+ line \d+\, )*[^ ]+ line \d+\.?)$/) {
+	my ($file, $line, $coords) = $where =~ m/^([^ ]+) line (\d+)(.*)$/g;
+	$msg .= $coords;
+
+	$@ = $text;
+	$self->{-message} = $msg;
+
+	# Get rid of extra stack frames from calling Die handlers and
+	# constructing Exceptions.
+	for (my $sp = 1; $sp < 10; $sp++) {
+	    if ($self->{STACK_FRAMES}[$sp][$FILENAME] eq $file && $self->{STACK_FRAMES}[$sp][$LINE] == $line) {
+		splice (@{$self->{STACK_FRAMES}}, 0, $sp);
+		last;
+	    }
+	}
+
+    # Failed to parse line info. Just use the message.
+    } else {
+	chomp $text;
+	$self->{-message} = $text;
+    }
+
+    return $self;
+}
+
+package W3C::Util::MethodNotImplementedException; # !!! do we need this and ProgramFlowException ?
+@W3C::Util::MethodNotImplementedException::ISA = qw(W3C::Util::FunctionException);
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    $self->missingParm('-object') if (!exists $self->{-object});
+    $self->fillInStackTrace;
+    return $self;
+}
+
+sub getSpecificMessage {return 'unimplemlemented method '.$_[0]->getClass.'::'.$_[0]->getMethod().' called on '.$_[0]->getObject();}
+sub getObject {return $_[0]->{-object}}
+
+package W3C::Util::UnexpectedObjectException;
+@W3C::Util::UnexpectedObjectException::ISA = qw(W3C::Util::FunctionException);
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    $self->missingParm('-object') if (!exists $self->{-object});
+    $self->fillInStackTrace;
+    return $self;
+}
+
+sub getSpecificMessage {return 'unexpected object '.$_[0]->getObject();}
+sub getObject {return ref $_[0]->{-object}}
+
+package W3C::Util::OutOfBoundsException;
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    $self->missingParm('-name') if (!exists $self->{-name});
+    $self->missingParm('-index') if (!exists $self->{-index});
+    $self->fillInStackTrace;
+    return $self;
+}
+sub getSpecificMessage {return 'variable "'.$_[0]->getName.'['.$_[0]->getIndex.']" is out of bounds';}
+sub getName {return $_[0]->{-name}}
+sub getIndex {return $_[0]->{-index}}
+
+package W3C::Util::ParameterException;
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    $self->missingParm('-parameter') if (!exists $self->{-parameter});
+    $self->fillInStackTrace;
+    return $self;
+}
+sub getSpecificMessage {
+    my ($self) = @_;
+    my $ret = 'parameter "'.$self->getParameter;
+    if (exists $self->{-value}) {
+	my $value = $self->getValue;
+	$ret .= ": $value";
+    }
+    $ret .= '" not legal in this context';
+    if ($self->getHint) {
+	$ret .= ' ('.$self->getHint.')';
+    }
+    return $ret;
+}
+sub getParameter {return $_[0]->{-parameter}}
+sub getValue {return $_[0]->{-value}};
+sub getHint {return $_[0]->{-hint}};
+
+package W3C::Util::ParameterFormatException;
+@W3C::Util::ParameterFormatException::ISA = qw(W3C::Util::ParameterException);
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    $self->missingParm('-format') if (!exists $self->{-format});
+    $self->fillInStackTrace;
+    return $self;
+}
+sub getSpecificMessage {
+    my ($self) = @_;
+    my $ret = $self->getParameter.' malformed. '.$self->getFormat;
+    return $ret;
+}
+sub getFormat {return $_[0]->{-format}};
+
+package W3C::Util::MissingParameterException;
+@W3C::Util::MissingParameterException::ISA = qw(W3C::Util::ParameterException);
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    $self->fillInStackTrace;
+    return $self;
+}
+sub getSpecificMessage {
+    my ($self) = @_;
+    my $ret = 'missing parameter "'.$self->getParameter;
+    if ($self->getHint) {
+	$ret .= '" ('.$self->getHint.')';
+    } else {
+	$ret .= '" required in this context';
+    }
+    return $ret;
+}
+
+package W3C::Util::ResourceException;
+@W3C::Util::ResourceException::ISA = qw(W3C::Util::Exception);
+use W3C::Util::Exception;
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    $self->missingParm('-uri') if (!exists $self->{-uri});
+    $self->fillInStackTrace;
+    return $self;
+}
+sub getSpecificMessage {&W3C::Util::Exception::throw(new W3C::Util::FunctionException)} # pure virtual
+sub getUri {return $_[0]->{-uri};}
+
+package W3C::Util::NoSuchFileException;
+@W3C::Util::NoSuchFileException::ISA = qw(W3C::Util::ResourceException);
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    $self->missingParm('-file') if (!exists $self->{-file});
+    $self->fillInStackTrace;
+    return $self;
+}
+sub getSpecificMessage {return 'No such file: "'.$_[0]->{-file}.'"';}
+sub getFile {return $_[0]->{-file};}
+
+package W3C::Util::NoSuchResourceException;
+@W3C::Util::NoSuchResourceException::ISA = qw(W3C::Util::ResourceException);
+sub getSpecificMessage {return 'No such Resource: "'.$_[0]->{-uri}.'"';}
+
+package W3C::Util::MalformedUriException;
+@W3C::Util::MalformedUriException::ISA = qw(W3C::Util::ResourceException);
+sub getSpecificMessage {return 'Malformed URI: "'.$_[0]->{-uri}.'"';}
+
+package W3C::Util::StringEncodingException;
+@W3C::Util::StringEncodingException::ISA = qw(W3C::Util::Exception);
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    $self->missingParm('-str') if (!exists $self->{-str});
+    $self->missingParm('-encoding') if (!exists $self->{-encoding});
+    $self->fillInStackTrace;
+    return $self;
+}
+sub getSpecificMessage {return "expected $_[0]->{-encoding} of \"$_[0]->{-str}\"";}
+
+package W3C::Util::BaseContextException;
+@W3C::Util::BaseContextException::ISA = qw(W3C::Util::Exception);
+
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    $self->missingParm('-contextID') if (!exists $self->{-contextID});
+    $self->fillInStackTrace;
+    return $self;
+}
+sub ensure {
+    my ($proto, $parms) = @_;
+    my $class = ref($proto) || $proto;
+    if ($parms->{-chainedException} && 
+	(my $chainedCtx = $parms->{-chainedException}->{-contextID} && 
+	 (my $ctx = $parms->{-contextID}))) {
+	if ($chainedCtx != $ctx) {
+	    return $class->new($parms);
+	}
+    } else {
+	return $class->new($parms);
+    }
+}
+sub getSpecificMessage {
+    my ($self) = @_;
+    my $errorMessage = $self->{-errorMessage} ? $self->{-errorMessage} : $self->exceptionClass.' string context:';
+    if (wantarray) {
+	my $location = $self->{-location} || '';
+	return ($errorMessage, 
+		"$location:$self->{-line}:$self->{-column}($self->{-pos})", 
+		$self->{-ctxString}, $self->{-indicator});
+    } else {
+	return $errorMessage.$self->{-ctxString};
+    }
+}
+sub exceptionClass {
+    my ($self) = @_;
+    return ref ($self->{-chainedException} ? $self->{-chainedException} : $self);
+}
+package W3C::Util::CachedContextException;
+@W3C::Util::CachedContextException::ISA = qw(W3C::Util::BaseContextException);
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    $self->missingParm('-str') if (!exists $self->{-str});
+    $self->missingParm('-pos') if (!exists $self->{-pos});
+    ($self->{-head}, $self->{-lineHead}, $self->{-ctxString}, 
+     $self->{-indicator}, $self->{-lineTail}, $self->{-tail}, 
+     $self->{-line}, $self->{-column}) = 
+	&W3C::Util::CachedContextException::getContextString($self->{-str}, $self->{-pos});
+    $self->fillInStackTrace;
+    return $self;
+}
+sub getContextString {
+    my ($str, $pos, $max) = @_;
+    if (!defined $max) {$max = 40;}
+
+    my $iBeforeError = $max;
+    my $startAt = $pos - $iBeforeError;
+    if ($startAt < 0) {
+	$iBeforeError += $startAt;
+	$startAt = 0;
+    }
+    my $t = substr($str, 0, $pos);
+    my ($beforeError, $head, $lineHead);
+    if (reverse ($t) =~ m/^([^\n]*)\n(.*)/s) {
+	($beforeError, $head) = (substr($str, 1+length $2, length $1), substr($str, 0, length $2));
+    } else {
+	$beforeError = substr ($str, $startAt, $iBeforeError);
+    }
+    if (length $beforeError > $iBeforeError) {
+	$lineHead = substr($beforeError, 0, length ($beforeError) - $iBeforeError);
+	$beforeError = substr($beforeError, length ($beforeError) - $iBeforeError, $iBeforeError);
+    }
+
+    my $iAfterError = $max;
+    my $endAt = $pos + $iAfterError;
+    if ($endAt > (length $str)) {
+	$iAfterError -= ($endAt - (length $str));
+	$endAt = (length $str);
+    }
+    $t = substr($str, $pos);
+    my ($afterError, $tail) = $t =~ m/^([^\n]*)\n(.*)/s ? ($1, $2) : ($t, undef);
+    my $lineTail = '';
+    if (length $afterError > $iAfterError) {
+	$lineTail = substr($afterError, $iAfterError);
+	$afterError = substr($afterError, 0, $iAfterError);
+    }
+
+    $t = substr($str, 0, $pos);
+    my $count = $t =~ m/\Z/m;
+    my ($line, $column);
+    for ($line = 0; $t =~ m/\n/gcs; $line++) {}
+    for ($column = 0; $t =~ m/./gcs; $column++) {}
+
+    return ($head, 
+	    $lineHead, 
+	    $beforeError.$afterError,
+	    ('=' x ((length $beforeError)-1)).'^', 
+	    $lineTail, 
+	    $tail, 
+	    $line, 
+	    $column);
+}
+
+package W3C::Util::HttpMessage;
+use vars qw(@ISA);
+@ISA = qw(W3C::Util::Exception);
+
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    $self->missingParm('-statusCode') if (!exists $self->{-statusCode});
+    $self->missingParm('-headers') if (!exists $self->{-headers});
+    $self->missingParm('-body') if (!exists $self->{-body});
+    $self->fillInStackTrace;
+    return $self;
+}
+
+sub getSpecificMessage {return 'HTTP early return message';}
+
+sub addHeader {
+    my ($self, $header, $value) = @_;
+    push (@{$self->{-headers}}, [$header, $value]);
+}
+
+sub toString {
+    my ($self) = @_;
+    my (@ret, $contentLength, $contentType);
+    push (@ret, "Status: $self->{-statusCode}");
+    foreach my $header (@{$self->{-headers}}) {
+	if ($header->[0] =~ m/^Content-length$/i) {
+	    $contentLength = $header->[1];
+	} elsif ($header->[0] =~ m/^Content-type$/i) {
+	    $contentType = $header->[1];
+	}
+	push (@ret, "$header->[0]: $header->[1]");
+    }
+    push (@ret, 'Content-length: '. length $self->{-body}) if (!defined $contentLength);
+    push (@ret, 'Content-type: text/html') if (!defined $contentType);
+    push (@ret, '');
+    push (@ret, $self->{-body});
+    return join ("\n", @ret);
+}
+
+package W3C::Util::SignalException;
+@W3C::Util::SignalException::ISA = qw(W3C::Util::Exception);
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    $self->missingParm('-pid') if (!exists $self->{-pid});
+    $self->missingParm('-signal') if (!exists $self->{-signal});
+    $self->fillInStackTrace;
+    return $self;
+}
+sub getSpecificMessage {return $_[0]->getPid.' got signal '.$_[0]->getSignal.' signal';}
+sub getPid {return $_[0]->{-pid};}
+sub getSignal {return $_[0]->{-signal};}
+
+package W3C::Util::Exception;
+
+1;
+
+__END__
+
+=head1 NAME
+
+W3C::Util::Exception - throw and catch and useful exceptions.
+
+=head1 SYNOPSIS
+
+    use W3C::Util::Exception;
+    @NegotiationException::ISA = qw(W3C::Util::Exception);
+    eval {
+	&iNeed('it yesterday');
+    }; if ($@) {if (my $ex = &catch('NegotiationException')) {
+	print "Try again with larger stick or carrot.\n";
+    } elsif (my $ex = &catch('W3C::Util::Exception')) {
+	warn 'got some random exception: '.$ex->getMessage."\n";
+	$ex->toString;
+	die "\n";
+    } else {die $@;}}
+
+    sub iNeed {
+	throw(new NegotiationException(-message => 'What about my needs?'));
+    }
+
+=head1 DESCRIPTION
+
+This module is part of the W3C::Utils CPAN module.
+
+This probably won't be needed when die passes a first class object.
+
+Create an exception class and derive it from W3C::Util::Exception.
+Write a function that throws it.
+Call the function from inside an eval.
+At the end of the eval, add
+    "if ($@) {"
+Try each exception that could be thrown with
+    "if (my $ex = &catch('NegotiationException')) {"
+At the end, have an "
+    "} elsif (my $ex = &catch('W3C::Util::Exception')) {"
+to make sure you get all possible exceptions. (Note - this is one area
+where language support could make sure you've covered all the bases.)
+At the end, you may want to add
+    "} else {die $@;}}"
+to make sure that you catch any non-exception calls to die.
+
+Uncaught exceptions may be found by putting an eval around your
+program's main. Exceptions that are thrown and are caught by a an eval
+will display with a leading block containing the exception's address
+and toString value. For instance:
+    "<W3C::Util::FileNotFoundException=HASH(0x8313e1c)> Can't
+     open file "asdf": No such file or directory at 
+     ../../../W3C/Util/Exception.pm line 34."
+This should be save as long there are no '>'s allowed in object::print.
+
+=head1 DIE Handling
+
+By default W3C::Util::Exception does not set any DIE handlers. It is likely that you will want to include
+
+      local($SIG{"__DIE__"}) = sub {&DieHandler(@_)};
+
+in your main. This will cause perl to throw exceptions for situations like calls to non-existent methods or invalid reference use.
+
+=head1 watch
+
+Simple programs will probably just want to call &watch to get
+rudimentary exception handling. The exceptions's toString method is
+called and the results passed to the normal (__DEFAULT__) perl die
+handler. This simply prints the message to standard error and exits
+with a code of 1.
+
+=head1 NOTES
+
+I considered using a syntax like
+    try (sub {
+	&iNeed('it yesterday');
+    }, 'NegotiationException', sub {
+	print "Try again with larger stick or carrot.\n";
+    }, 'W3C::Util::Exception', sub {
+	warn 'got some random exception: '.$ex->getMessage."\n";
+	$ex->toString;
+	die "\n";
+    });
+but figured it would just complicate the control without improving the
+interface significantly. Anyone have any good ideas here?
+
+=head1 ContextExceptions
+
+Suppose an exception occurs part way through parsing an x-included XML document
+and the directive to parse that document was part way through a parsing query
+string. Ideally, the exception message will appear something like:
+
+  unknown namespace: "preson"
+  file:/data/Bob.xml::8:35(74)
+    <person:Record name="Bob Dobbs"><preson:homeAddr><addr:Address>
+  ===================================^
+  file:/data/People.xml::103:34(5184)
+    <xincl:include href="joe.xml"/><xincl:include href="bob.xml"/>
+  ==================================^
+  file:/data/hr-report.alg::3:28(70)
+    slurp (schema.xml) slurp (People.xml) slurp (post)
+  ============================^
+  W3C::Util::UnknownNamespaceException thrown at W3C/Util/NamespaceHandler.pm:235
+  W3C::Util::NamespaceHandler::_getNs(...) at W3C/Util/NamespaceHandler.pm:217
+  W3C::Util::NamespaceHandler::mapNamespace(...) at W3C/Util/NamespaceHandler.pm:213
+  ...
+
+We see three contexts which refine our search for the error: hr-report.alg read
+People.xml which xincluded Bob.xml. Each parser is expected to catch Exceptions
+and add a context to them. A ContextException is constructed with a reference
+to the chainedException and the Locator. If the chainedException is also a
+ContextException, the context from the chainedException is added to the
+getMessage (and thereby toString) method unless the chainedException is for the
+same context. This last case would occur if a parser trapped an exception it
+has already thrown as it wound in this case:
+
+  sub parse {
+    eval {
+	$p->interp("bad data");
+    }; if ($@) {
+	my $ex = &catch('W3C::Util::Exception') || new W3C::Util::PerlException();
+	my $newEx = new MyContextException($self, {-chainedException => $ex, -locator => $self});
+	$newEx->assumeStackTrace($ex);
+	&throw($newEx);
+    }
+  }
+  sub eval {
+    if ($_[1] eq "bad data") {
+	&throw(new new MyContextException($self, {-chainedException => $ex, -locator => $self});
+    }
+  }
+
+=head1 AUTHOR
+
+Eric Prud'hommeaux <eric@w3.org>
+
+=head1 SEE ALSO
+
+perl(1).
+
+=cut
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/perl/modules/W3C/Util/YappDriver.pm	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,800 @@
+#Copyright Massachusetts Institute of technology, 2003.
+#Written by Eric Prud'hommeaux for the World Wide Web Consortium
+
+# $Id: YappDriver.pm,v 1.15 2005-11-05 11:11:17 eric Exp $
+
+use strict;
+
+package W3C::Util::YappDriver::GrammarException;
+use W3C::Util::Exception;
+@W3C::Util::YappDriver::GrammarException::ISA = qw(W3C::Util::Exception);
+
+package W3C::Util::YappDriver::YappContextException;
+@W3C::Util::YappDriver::YappContextException::ISA = qw(W3C::Util::CachedContextException);
+sub new {
+    my ($proto, $parser, @parms) = @_;
+    my $class = ref($proto) || $proto;
+
+    my ($token, $value, $data) = ($parser->YYCurtok(), $parser->YYCurval(), $parser->YYData);
+    my $expect = @{$parser->{STACK}} ? $parser->YYExpect() : 'INVALID INITIALIZER';
+    my $tokenStr = defined $token && $token ne $value ? "$token " : '';
+    my $trimmed = $parser->YYData->{INPUT};
+    $trimmed =~ s/[\r\n]*\Z//m;
+
+    my $before = substr($trimmed, 0, $parser->YYData->{my_LASTPOS}+1);
+    $before =~ m/([^\r\n]*)\Z/m;
+    my $column = length ($1) - 1;
+    my $after = substr($trimmed, $parser->YYData->{my_LASTPOS}+1);
+
+    $after =~ m/([^\r\n]*)[\r\n]?(.*)/s;
+    my ($line, $last) = ($1, $2);
+
+    my $self = $class->SUPER::new(-contextID => $parser, 
+				  -str => $parser->YYData->{INPUT}, 
+				  -pos => $parser->YYData->{my_LASTPOS}+1, 
+				  -token => $tokenStr, 
+				  -parser => $parser, 
+#				  -before => "$before$line", 
+#				  -marker => ('=' x $column).'^'
+#				  -last_ => $last, 
+				  -parserStack => [@{$parser->{STACK}}], 
+				  -location => $parser->YYData->{LOCATION}, 
+				  @parms);
+    $self->fillInStackTrace;
+    return $self;
+}
+
+sub getFullContext {$_[0]->{-before}, $_[0]->{-marker}, $_[0]->{-last_}}
+
+package W3C::Util::YappDriver::MesgYappContextException;
+@W3C::Util::YappDriver::MesgYappContextException::ISA = qw(W3C::Util::CachedContextException);
+sub new {
+    my ($proto, $parser, @parms) = @_;
+    my $class = ref($proto) || $proto;
+
+    my ($token, $value, $data) = ($parser->YYCurtok(), $parser->YYCurval(), $parser->YYData);
+    if (UNIVERSAL::can($value, "toString")) {
+	$value = $value->toString();
+    }
+    my $expect = @{$parser->{STACK}} ? join (' | ', sort {(!(lc $a cmp lc $b)) ? $b cmp $a : lc $a cmp lc $b} $parser->YYExpect()) : 'INVALID INITIALIZER';
+    my $tokenStr = defined $token && $token ne $value ? "$token " : '';
+    my $trimmed = $parser->YYData->{INPUT};
+    $trimmed =~ s/[\r\n]*\Z//m;
+
+    if (ref $expect) {
+	# Flag unexpected (by the author at this point) refs with '?ref'.
+	if (ref $expect eq 'HASH') {
+	    if (exists $expect->{NEXT}) {
+		$expect = $ {$expect->{NEXT}};
+	    } else {
+		$expect = "?ref {%$expect}";
+	    }
+	} elsif (ref $expect eq 'ARRAY') {
+	    $expect = "?ref [@$expect]";
+	} elsif (ref $expect eq 'SCALAR') {
+	    $expect = "?ref $$expect";
+	} elsif (ref $expect eq 'GLOB') {
+	    $expect = "?ref \**$expect";
+	} else {
+	    $expect = "?ref ??? $expect";
+	}
+    }
+    my $valueStr = defined $value ? "'$value'" : 'EOF';
+    my $dataStr = ref $data eq 'HASH' ? join ("\n", map {"$_: $data->{$_}"} keys %$data) : $data;
+    $dataStr = substr($trimmed, $parser->YYData->{my_LASTPOS}, 20);
+    my @stackStrs;
+    foreach my $entry (@{$parser->{STACK}}) {
+	my ($state, $semval) = @$entry;
+	my $semvalStr = $semval ? 
+	    UNIVERSAL::can($semval, 'toString') ? $semval->toString() : 
+	    ref $semval eq 'ARRAY' ? '['.join('|', @$semval).']' : 
+	    $semval : 
+	    '';
+	push (@stackStrs, "$state   $semvalStr");
+    }
+    my $stackStr = join("\n", '', 'LALR STACK:', @stackStrs, '___________');
+
+    return $class->SUPER::new(-str => $parser->YYData->{INPUT}, 
+			      -pos => $parser->YYData->{my_LASTPOS}, 
+			      -contextID => $parser, 
+			      -errorMessage => "expected '$expect', got $tokenStr$valueStr at \"$dataStr\"$stackStr", 
+			      @parms);
+}
+
+#Included Parse/Yapp/Driver.pm file----------------------------------------
+{
+#
+# Module Parse::Yapp::Driver
+#
+# This module is part of the Parse::Yapp package available on your
+# nearest CPAN
+#
+# Any use of this module in a standalone parser make the included
+# text under the same copyright as the Parse::Yapp module itself.
+#
+# This notice should remain unchanged.
+#
+# (c) Copyright 1998-2001 Francois Desarmenien, all rights reserved.
+# (see the pod text in Parse::Yapp module for use and distribution rights)
+#
+
+package Parse::Yapp::Driver;
+
+require 5.004;
+
+use strict;
+
+use vars qw ( $VERSION $COMPATIBLE $FILENAME );
+
+$VERSION = '1.05';
+$COMPATIBLE = '0.07';
+$FILENAME=__FILE__;
+
+use Carp;
+
+#Known parameters, all starting with YY (leading YY will be discarded)
+my(%params)=(YYLEX => 'CODE', 'YYERROR' => 'CODE', YYVERSION => '',
+			 YYRULES => 'ARRAY', YYSTATES => 'ARRAY', YYDEBUG => '');
+#Mandatory parameters
+my(@params)=('LEX','RULES','STATES');
+
+sub new {
+    my($class)=shift;
+	my($errst,$nberr,$token,$value,$check,$dotpos);
+    my($self)={ ERROR => \&_Error,
+				ERRST => \$errst,
+                NBERR => \$nberr,
+				TOKEN => \$token,
+				VALUE => \$value,
+				DOTPOS => \$dotpos,
+				STACK => [],
+				DEBUG => 0,
+				CHECK => \$check };
+
+	_CheckParams( [], \%params, \@_, $self );
+
+		exists($$self{VERSION})
+	and	$$self{VERSION} < $COMPATIBLE
+	and	croak "Yapp driver version $VERSION ".
+			  "incompatible with version $$self{VERSION}:\n".
+			  "Please recompile parser module.";
+
+        ref($class)
+    and $class=ref($class);
+
+    bless($self,$class);
+}
+
+sub YYParse {
+    my($self)=shift;
+    my($retval);
+
+	_CheckParams( \@params, \%params, \@_, $self );
+
+	if($$self{DEBUG}) {
+		_DBLoad();
+		$retval = eval '$self->_DBParse()';#Do not create stab entry on compile
+        $@ and die $@;
+	}
+	else {
+		$retval = $self->_Parse();
+	}
+    $retval
+}
+
+sub YYData {
+	my($self)=shift;
+
+		exists($$self{USER})
+	or	$$self{USER}={};
+
+	$$self{USER};
+	
+}
+
+sub YYErrok {
+	my($self)=shift;
+
+	${$$self{ERRST}}=0;
+    undef;
+}
+
+sub YYNberr {
+	my($self)=shift;
+
+	${$$self{NBERR}};
+}
+
+sub YYRecovering {
+	my($self)=shift;
+
+	${$$self{ERRST}} != 0;
+}
+
+sub YYAbort {
+	my($self)=shift;
+
+	${$$self{CHECK}}='ABORT';
+    undef;
+}
+
+sub YYAccept {
+	my($self)=shift;
+
+	${$$self{CHECK}}='ACCEPT';
+    undef;
+}
+
+sub YYError {
+	my($self)=shift;
+
+	${$$self{CHECK}}='ERROR';
+    undef;
+}
+
+sub YYSemval {
+	my($self)=shift;
+	my($index)= $_[0] - ${$$self{DOTPOS}} - 1;
+
+		$index < 0
+	and	-$index <= @{$$self{STACK}}
+	and	return $$self{STACK}[$index][1];
+
+	undef;	#Invalid index
+}
+
+sub YYCurtok {
+	my($self)=shift;
+
+        @_
+    and ${$$self{TOKEN}}=$_[0];
+    ${$$self{TOKEN}};
+}
+
+sub YYCurval {
+	my($self)=shift;
+
+        @_
+    and ${$$self{VALUE}}=$_[0];
+    ${$$self{VALUE}};
+}
+
+sub YYExpect {
+    my($self)=shift;
+
+    keys %{$self->{STATES}[$self->{STACK}[-1][0]]{ACTIONS}}
+}
+
+sub YYLexer {
+    my($self)=shift;
+
+	$$self{LEX};
+}
+
+
+#################
+# Private stuff #
+#################
+
+
+sub _CheckParams {
+	my($mandatory,$checklist,$inarray,$outhash)=@_;
+	my($prm,$value);
+	my($prmlst)={};
+
+	while(($prm,$value)=splice(@$inarray,0,2)) {
+        $prm=uc($prm);
+			exists($$checklist{$prm})
+		or	croak("Unknow parameter '$prm'");
+			ref($value) eq $$checklist{$prm}
+		or	croak("Invalid value for parameter '$prm'");
+        $prm=unpack('@2A*',$prm);
+		$$outhash{$prm}=$value;
+	}
+	for (@$mandatory) {
+			exists($$outhash{$_})
+		or	croak("Missing mandatory parameter '".lc($_)."'");
+	}
+}
+
+sub _Error {
+	print "Parse error.\n";
+}
+
+sub _DBLoad {
+	{
+		no strict 'refs';
+
+			exists(${__PACKAGE__.'::'}{_DBParse})#Already loaded ?
+		and	return;
+	}
+	my($fname)=__FILE__;
+	my(@drv);
+	open(DRV,"<$fname") or die "Report this as a BUG: Cannot open $fname";
+	while(<DRV>) {
+                	/^\s*sub\s+_Parse\s*{\s*$/ .. /^\s*}\s*#\s*_Parse\s*$/
+        	and     do {
+                	s/^#DBG>//;
+                	push(@drv,$_);
+        	}
+	}
+	close(DRV);
+
+	$drv[0]=~s/_P/_DBP/;
+	eval join('',@drv);
+}
+
+#Note that for loading debugging version of the driver,
+#this file will be parsed from 'sub _Parse' up to '}#_Parse' inclusive.
+#So, DO NOT remove comment at end of sub !!!
+sub _Parse {
+    my($self)=shift;
+
+	my($rules,$states,$lex,$error)
+     = @$self{ 'RULES', 'STATES', 'LEX', 'ERROR' };
+	my($errstatus,$nberror,$token,$value,$stack,$check,$dotpos)
+     = @$self{ 'ERRST', 'NBERR', 'TOKEN', 'VALUE', 'STACK', 'CHECK', 'DOTPOS' };
+
+#DBG>	my($debug)=$$self{DEBUG};
+#DBG>	my($dbgerror)=0;
+
+#DBG>	my($ShowCurToken) = sub {
+#DBG>		my($tok)='>';
+#DBG>		for (split('',$$token)) {
+#DBG>			$tok.=		(ord($_) < 32 or ord($_) > 126)
+#DBG>					?	sprintf('<%02X>',ord($_))
+#DBG>					:	$_;
+#DBG>		}
+#DBG>		$tok.='<';
+#DBG>	};
+
+	$$errstatus=0;
+	$$nberror=0;
+	($$token,$$value)=(undef,undef);
+	@$stack=( [ 0, undef ] );
+	$$check='';
+
+    while(1) {
+        my($actions,$act,$stateno);
+
+        $stateno=$$stack[-1][0];
+        $actions=$$states[$stateno];
+
+#DBG>	print STDERR ('-' x 40),"\n";
+#DBG>		$debug & 0x2
+#DBG>	and	print STDERR "In state $stateno:\n";
+#DBG>		$debug & 0x08
+#DBG>	and	print STDERR "Stack:[".
+#DBG>					 join(',',map { $$_[0] } @$stack).
+#DBG>					 "]\n";
+
+
+        if  (exists($$actions{ACTIONS})) {
+
+				defined($$token)
+            or	do {
+				($$token,$$value)=&$lex($self);
+#DBG>				$debug & 0x01
+#DBG>			and	print STDERR "Need token. Got ".&$ShowCurToken."\n";
+			};
+
+            $act=   exists($$actions{ACTIONS}{$$token})
+                    ?   $$actions{ACTIONS}{$$token}
+                    :   exists($$actions{DEFAULT})
+                        ?   $$actions{DEFAULT}
+                        :   undef;
+        }
+        else {
+            $act=$$actions{DEFAULT};
+#DBG>			$debug & 0x01
+#DBG>		and	print STDERR "Don't need token.\n";
+        }
+
+            defined($act)
+        and do {
+
+                $act > 0
+            and do {        #shift
+
+#DBG>				$debug & 0x04
+#DBG>			and	print STDERR "Shift and go to state $act.\n";
+
+					$$errstatus
+				and	do {
+					--$$errstatus;
+
+#DBG>					$debug & 0x10
+#DBG>				and	$dbgerror
+#DBG>				and	$$errstatus == 0
+#DBG>				and	do {
+#DBG>					print STDERR "**End of Error recovery.\n";
+#DBG>					$dbgerror=0;
+#DBG>				};
+				};
+
+
+                push(@$stack,[ $act, $$value ]);
+
+					$$token ne ''	#Don't eat the eof
+				and	$$token=$$value=undef;
+                next;
+            };
+
+            #reduce
+            my($lhs,$len,$code,@sempar,$semval);
+            ($lhs,$len,$code)=@{$$rules[-$act]};
+
+#DBG>			$debug & 0x04
+#DBG>		and	$act
+#DBG>		and	print STDERR "Reduce using rule ".-$act." ($lhs,$len): ";
+
+                $act
+            or  $self->YYAccept();
+
+            $$dotpos=$len;
+
+                unpack('A1',$lhs) eq '@'    #In line rule
+            and do {
+                    $lhs =~ /^\@[0-9]+\-([0-9]+)$/
+                or  die "In line rule name '$lhs' ill formed: ".
+                        "report it as a BUG.\n";
+                $$dotpos = $1;
+            };
+
+            @sempar =       $$dotpos
+                        ?   map { $$_[1] } @$stack[ -$$dotpos .. -1 ]
+                        :   ();
+
+            $semval = $code ? &$code( $self, @sempar )
+                            : @sempar ? $sempar[0] : undef;
+
+            splice(@$stack,-$len,$len);
+
+                $$check eq 'ACCEPT'
+            and do {
+
+#DBG>			$debug & 0x04
+#DBG>		and	print STDERR "Accept.\n";
+
+				return($semval);
+			};
+
+                $$check eq 'ABORT'
+            and	do {
+
+#DBG>			$debug & 0x04
+#DBG>		and	print STDERR "Abort.\n";
+
+				return(undef);
+
+			};
+
+#DBG>			$debug & 0x04
+#DBG>		and	print STDERR "Back to state $$stack[-1][0], then ";
+
+                $$check eq 'ERROR'
+            or  do {
+#DBG>				$debug & 0x04
+#DBG>			and	print STDERR 
+#DBG>				    "go to state $$states[$$stack[-1][0]]{GOTOS}{$lhs}.\n";
+
+#DBG>				$debug & 0x10
+#DBG>			and	$dbgerror
+#DBG>			and	$$errstatus == 0
+#DBG>			and	do {
+#DBG>				print STDERR "**End of Error recovery.\n";
+#DBG>				$dbgerror=0;
+#DBG>			};
+
+			    push(@$stack,
+                     [ $$states[$$stack[-1][0]]{GOTOS}{$lhs}, $semval ]);
+                $$check='';
+                next;
+            };
+
+#DBG>			$debug & 0x04
+#DBG>		and	print STDERR "Forced Error recovery.\n";
+
+            $$check='';
+
+        };
+
+        #Error
+            $$errstatus
+        or   do {
+
+            $$errstatus = 1;
+            &$error($self);
+                $$errstatus # if 0, then YYErrok has been called
+            or  next;       # so continue parsing
+
+#DBG>			$debug & 0x10
+#DBG>		and	do {
+#DBG>			print STDERR "**Entering Error recovery.\n";
+#DBG>			++$dbgerror;
+#DBG>		};
+
+            ++$$nberror;
+
+        };
+
+			$$errstatus == 3	#The next token is not valid: discard it
+		and	do {
+				$$token eq ''	# End of input: no hope
+			and	do {
+#DBG>				$debug & 0x10
+#DBG>			and	print STDERR "**At eof: aborting.\n";
+				return(undef);
+			};
+
+#DBG>			$debug & 0x10
+#DBG>		and	print STDERR "**Dicard invalid token ".&$ShowCurToken.".\n";
+
+			$$token=$$value=undef;
+		};
+
+        $$errstatus=3;
+
+		while(	  @$stack
+			  and (		not exists($$states[$$stack[-1][0]]{ACTIONS})
+			        or  not exists($$states[$$stack[-1][0]]{ACTIONS}{error})
+					or	$$states[$$stack[-1][0]]{ACTIONS}{error} <= 0)) {
+
+#DBG>			$debug & 0x10
+#DBG>		and	print STDERR "**Pop state $$stack[-1][0].\n";
+
+			pop(@$stack);
+		}
+
+			@$stack
+		or	do {
+
+#DBG>			$debug & 0x10
+#DBG>		and	print STDERR "**No state left on stack: aborting.\n";
+
+			return(undef);
+		};
+
+		#shift the error token
+
+#DBG>			$debug & 0x10
+#DBG>		and	print STDERR "**Shift \$error token and go to state ".
+#DBG>						 $$states[$$stack[-1][0]]{ACTIONS}{error}.
+#DBG>						 ".\n";
+
+		push(@$stack, [ $$states[$$stack[-1][0]]{ACTIONS}{error}, undef ]);
+
+    }
+
+    #never reached
+	croak("Error in driver logic. Please, report it as a BUG");
+
+}#_Parse
+#DO NOT remove comment
+
+1;
+
+}
+#End of include--------------------------------------------------
+
+package W3C::Util::YappDriver;
+use W3C::Util::Exception;
+use vars qw(@ISA);
+@ISA= qw (Parse::Yapp::Driver);
+
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    $self->{yd_CHOICES} = [];
+    return $self;
+}
+
+sub parse {
+    my ($self, $yydebug, $errorSub) = @_;
+    my $ret = undef;
+    eval {
+	$errorSub ||= sub {$self->_Error()};
+	$ret = $self->YYParse( yylex => sub {$self->_Lexer()}, yyerror => $errorSub, yydebug => $yydebug );
+    }; if ($@) {if (my $ex = &catch('W3C::Util::CachedContextException')) {
+	if ($ex->{-contextID} == $self) {
+	    # Something thrown by this parse, pass it on.
+	    &throw($ex);;
+	} else {
+	    # Something thrown by a child parser, show context for it.
+	    my $newEx = new W3C::Util::YappDriver::YappContextException($self, -chainedException => $ex);
+	    $newEx->assumeStackTrace($ex);
+	    &throw($newEx);
+	}
+    } elsif ($ex = &catch('W3C::Util::Exception')) {
+	my $newEx = new W3C::Util::YappDriver::YappContextException($self, -chainedException => $ex);
+	$newEx->assumeStackTrace($ex);
+	&throw($newEx);
+    } else {
+	my $newEx = new W3C::Util::YappDriver::MesgYappContextException($self, -errorMessage => $@);
+	&throw($newEx);
+    }}
+    return $ret;
+}
+
+package W3C::Util::rlDriver;
+use vars qw(@ISA);
+@ISA= qw (W3C::Util::YappDriver);
+
+use Term::ReadLine;
+use W3C::Util::Exception;
+
+sub new {
+    my ($proto, @parms) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = $class->SUPER::new(@parms);
+    $self->YYData->{my_CHUNKS} = []; # "(\n", ")\n"]; # '( ask \' ( ( '];
+    $self->{rl_LINES} = [];
+    $self->prepareReadline;
+    return $self;
+}
+
+sub prepareReadline {
+    my ($self) = @_;
+    $self->{rl_TERM} = new Term::ReadLine 'Calc';
+    my $attribs = $self->{rl_TERM}->Attribs;
+    my $counter = undef;
+    $attribs->{attempted_completion_function} = sub {$self->_hairyCompletionFunction($self->{rl_TERM}, \$counter, @_)};
+    $self->{rl_TERM}->ornaments('md,me,,');	# bold face prompt
+    $self->{rl_PROMPT} = "command: ";
+    my $OUT = $self->{rl_TERM}->OUT || *STDOUT;
+}
+
+sub readline {
+    my ($self, $defaultInput) = @_;
+    my $line = $self->{rl_TERM}->readline($self->{rl_PROMPT}, $defaultInput);
+    push (@{$self->{rl_LINES}}, $line);
+    return $line;
+}
+
+sub _hairyCompletionFunction {
+    my ($self, $term, $pCounter, $text, $line, $start, $end) = @_;
+    my $soFar = join ("\n", @{$self->{rl_LINES}}).substr($line, 0, $start).$text;
+    #print $main::DBG "$self->_hairyCompletionFunction($term, $pCounter, $text, $line, $start, $end [$soFar])\n";
+    my $attribs = $term->Attribs;
+    my $class = ref $self;
+
+    $self->{yd_CHOICES} = [];
+    if ($soFar =~ m/^\w*$/) {
+        $self->_BuildOpts;
+    } else {
+	$self->{rl_COMPLETE_MODE} = 1;
+	$self->{rl_SO_FAR} = $soFar;
+	my $copy = new Parse::Yapp::Driver(yyversion => $self->{VERSION}, yystates => $self->{STATES}, yyrules => $self->{RULES});
+	$copy->{USER} = {%{$self->{USER}}};
+	$self->initState($copy);
+	my $save = {};
+	foreach my $key (%$copy) {
+	    $save->{$key} = $self->{$key};
+	    $self->{$key} = $copy->{$key};
+	}
+	#print "\n$self calling $self->YYparser($soFar)\n";
+	my $lexer = $self->{LEX}; # $soFar =~ m/^\w*$/ ? \&_Empty : $self->{LEX};
+	$self->parse(0x00, \&_BuildOpts);
+	foreach my $key (%$copy) {
+	    $self->{$key} = $save->{$key};
+	}
+	$self->{rl_COMPLETE_MODE} = 0;
+    }
+    #$self->{STACK} = [];
+    #print join (' | ', @{$self->{yd_CHOICES}}), "\n";
+    if (@{$self->{yd_CHOICES}}) {
+	$attribs->{completion_word} = $self->{yd_CHOICES};
+	undef $attribs->{completion_display_matches_hook};
+	my ($l, $r) = $text =~ m/^(.*?)([^\s]*)$/;
+	my $completeFunction = $attribs->{'list_completion_function'};
+	my $wordStr = join (' ', @{$attribs->{completion_word}});
+
+	print $main::DBG "_BuildOpts(\$text:$text, \$l:$l, \$r:$r) match $text in ($wordStr)\n";
+	return $term->completion_matches("$r $l", sub {
+	    my ($t, $i) = @_;
+	    my ($r, $l) = $t =~ m/^([^ ]*) (.*)$/;
+	    my $ret = &$completeFunction($r, $i);
+	    print $main::DBG "complete($r, $i) => $ret\n";
+	    return $ret ? "$l$ret" : undef;
+	});
+    } else {
+	print "\nstop hitting tab\n";
+	return undef;
+    }
+}
+
+sub _BuildOpts {
+    my ($self) = @_;
+
+    #print $main::DBG "$self->_BuildOpts()\n";
+
+    # Start at latest stack entry.
+    my $stateNo = @{$self->{STACK}} > 0 ? $self->{STACK}[-1][0] : 0;
+
+    # Some debugging stuff...
+    #print "\nstateNo: $stateNo\n";
+    foreach my $entry (@{$self->{STACK}}) {
+	#print join (' | ', @$entry),"\n";
+    }
+
+    # Follow default actions untill we find one expecting tokens.
+    while (defined $stateNo) {
+	if (exists $self->{STATES}[$stateNo]{ACTIONS}) {
+	    #print "actions: stateNo: $stateNo  action: ", join (' | ', keys %{$self->{STATES}[$stateNo]{ACTIONS}}), "\n";
+	    push (@{$self->{yd_CHOICES}}, keys %{$self->{STATES}[$stateNo]{ACTIONS}});
+	}
+	$stateNo = $self->defaultStateNo($stateNo);
+    }
+
+    # Follow stack up to find all default actions that led us here.
+    # look up stack
+    # if has a negative default
+    #   my $production = RULES[-DEFAULT]
+    #   my $reduce = GOTOS{$production}
+    #   if $reduce = $stateNo
+    #      add words from ACTIONS
+    for (my $sp = @{$self->{STACK}} - 2; $sp >= 0; $sp--) {
+	$stateNo = $self->{STACK}[$sp][0];
+	if ($self->{STATES}[$stateNo]{DEFAULT} &&
+	    $self->{STACK}[$sp+1][0] == $self->defaultStateNo($stateNo)) {
+	    #print "parent actions: stateNo: $stateNo  action: ", join (' | ', keys %{$self->{STATES}[$stateNo]{ACTIONS}}), "\n";
+	    push (@{$self->{yd_CHOICES}}, keys %{$self->{STATES}[$stateNo]{ACTIONS}});	    
+	} else {
+	    last;
+	}
+    }
+
+    if (!@{$self->{yd_CHOICES}}) {
+	push (@{$self->{yd_CHOICES}}, $self->YYExpect());
+    }
+}
+
+sub defaultStateNo {
+    my ($self, $stateNo) = @_;
+    my $next = $self->{STATES}[$stateNo]{DEFAULT};
+    if ($next < 0) {
+	my ($production, $depth, $code) = @{$self->{RULES}[-$next]};
+	$next = $self->{STATES}[$stateNo]{GOTOS}{$production};
+    }
+    return $next;
+}
+
+sub initState {}
+
+sub _Empty {print "Empty!\n"; return ('', undef)}
+
+1;
+
+__END__
+
+=head1 NAME
+
+W3C::Util::rlDriver - Parse::Yapp::Driver derivative to allow readline interaction.
+
+=head1 SYNOPSIS
+
+  %{
+    use W3C::Util::rlDriver;
+    @ISA= qw ( W3C::Util::rlDriver );
+
+    use W3C::Rdf::AlgaeStructure;
+  %}
+
+  $parser->YYData->{INPUT} = $self->readline('test')
+
+=head1 DESCRIPTION
+
+This is a parser program generated by Parse::Yapp to use Term::ReadLine to feed input to the lexer. This leverages off the grammer definition passed to yapp to provide lists of syntacticly legal alternatives to the readline completion function.
+
+This module is currently part of the W3C::Util CPAN module.
+
+=head1 AUTHOR
+
+Eric Prud\'hommeaux <eric@w3.org>
+
+=head1 SEE ALSO
+
+Parse::Yapp(3) Term::ReadLine(3) perl(1).
+
+=cut
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/prov-n.bnf	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,139 @@
+ 
+[2] bundle ::= "bundle" namespaceDeclarations? expression* (namedBundle namedBundle*)? "endBundle"
+
+[3] namedBundle ::= "bundle" identifier (namespaceDeclarations)? (expression)* "endBundle"
+
+[4] namespaceDeclarations ::=  (defaultNamespaceDeclaration | namespaceDeclaration) namespaceDeclaration*
+
+[5] namespaceDeclaration ::= "prefix" QNAME namespace
+
+[6] namespace ::= IRI_REF
+
+[7] defaultNamespaceDeclaration ::=     "default" IRI_REF
+
+[10] expression::=
+        (   
+
+           entityExpression | activityExpression | generationExpression
+        )
+
+
+[11] entityExpression::=	"entity" "(" identifier optionalAttributeValuePairs ")"
+
+[12] activityExpression::=	"activity" "(" identifier ("," (timeZZ | "-" ) "," (timeZZ | "-"))? optionalAttributeValuePairs ")"
+
+generationExpression::=	"wasGeneratedBy" "(" ((identifier | "-") ";")? identifier ("," ((identifier) | "-") "," ( timeZZ | "-" ))? optionalAttributeValuePairs ")"
+
+
+optionalAttributeValuePairs::= ("," "[" attributeValuePairs "]")?
+
+identifier ::=QNAME
+attribute ::=QNAME
+attributeValuePairs::=      (  | attributeValuePair ( "," attributeValuePair )* )
+
+attributeValuePair::= attribute '='  literal
+
+
+timeZZ::= ISODATETIME
+
+
+
+
+
+
+
+
+
+
+
+
+
+[13] literal ::= RDFLiteral 
+ | BooleanLiteral 
+
+ 
+ 
+[60s] RDFLiteral ::= String (  ( "^^" IRIref ) )? 
+ 
+[65s] BooleanLiteral ::= "true" 
+ | "false" 
+[66s] String ::= STRING_LITERAL
+[67s] IRIref ::= IRI_REF 
+ | PrefixedName 
+[68s] PrefixedName ::= PNAME_LN 
+ | PNAME_NS 
+
+
+@terminals
+QNAME::= (PN_PREFIX ":")? PN_LOCAL | PN_PREFIX ":"
+
+PREFX::=  PN_PREFIX
+DIGIT::=[0-9]
+ISODATETIME::=  DIGIT DIGIT DIGIT DIGIT "-" DIGIT DIGIT "-" DIGIT DIGIT "T" DIGIT DIGIT ":" DIGIT DIGIT ":" DIGIT DIGIT ("." DIGIT (DIGIT DIGIT?)?)? ("Z" | TIMEZONEOFFSET)?
+
+TIMEZONEOFFSET::= ("+" | "-") DIGIT DIGIT ":" DIGIT DIGIT;
+
+
+
+ 
+[18] PREFIX ::= "@prefix" 
+
+[70s] IRI_REF ::= "<" ( [^<>\"{}|^`\\] - [#x00-#x20] | UCHAR )* ">" 
+ 
+[71s] PNAME_NS ::= (PN_PREFIX)? ":" 
+ 
+[72s] PNAME_LN ::= PNAME_NS PN_LOCAL 
+ 
+ 
+ 
+[149s] STRING_LITERAL ::= '"' ( ( [^#x22#x5C#xA#xD]) | ECHAR | UCHAR )* '"' 
+ 
+[19] UCHAR ::= ( "\\u" HEX HEX HEX HEX ) 
+ | ( "\\U" HEX HEX HEX HEX HEX HEX HEX HEX ) 
+
+[91s] ECHAR ::= "\\" [tbnrf\\\"'] 
+ 
+[92s] NIL ::= "(" (WS)* ")" 
+ 
+[93s] WS ::= " " 
+ | "\t" 
+ | "\r" 
+ | "\n" 
+[94s] ANON ::= "[" (WS)* "]" 
+ 
+[95s] PN_CHARS_BASE ::= [A-Z] 
+ | [a-z] 
+ | [#00C0-#00D6] 
+ | [#00D8-#00F6] 
+ | [#00F8-#02FF] 
+ | [#0370-#037D] 
+ | [#037F-#1FFF] 
+ | [#200C-#200D] 
+ | [#2070-#218F] 
+ | [#2C00-#2FEF] 
+ | [#3001-#D7FF] 
+ | [#F900-#FDCF] 
+ | [#FDF0-#FFFD] 
+ | [#10000-#EFFFF] 
+[96s] PN_CHARS_U ::= PN_CHARS_BASE 
+ | "_" 
+[98s] PN_CHARS ::= PN_CHARS_U 
+ | "-" 
+ | [0-9] 
+ | #00B7 
+ | [#0300-#036F] 
+ | [#203F-#2040] 
+[99s] PN_PREFIX ::= PN_CHARS_BASE ( ( PN_CHARS | "." )* PN_CHARS )? 
+ 
+[100s] PN_LOCAL ::= ( PN_CHARS_U | [0-9] | PLX ) ( ( PN_CHARS | '.' | PLX )*  ( PN_CHARS | PLX ) ) ?
+
+[160s] PLX ::= PERCENT | PN_LOCAL_ESC
+
+[161s] PERCENT ::= '%' HEX HEX
+
+[162s] HEX ::= [0-9] | [A-F] | [a-f]
+
+[163s] PN_LOCAL_ESC ::= '\\' ( '_' | '~' | '.' | '-' | '!' | '$' | '&' | "'" | '(' | ')' | '*' | '+' | ',' | ';' | '=' | ':' | '/' | '?' | '#' | '@' | '%' )
+ 
+@pass ::= [ \t\r\n]+ 
+ | "#" [^\r\n]* 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/prov_n.html	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,684 @@
+<table border="0">
+<tbody><tr><td colspan="4" class="grammarSection"><h3><a id="productions" name="productions">Productions</a>:</h3></td></tr></tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-bundle" name="prod-prov_n-bundle"></a>[<span class="prodNo">1</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">bundle</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    "bundle" <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen0">gen0</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen1">gen1</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen4">gen4</a></span> "endBundle"</code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen0" name="prod-prov_n-gen0"></a>[<span class="prodNo">2</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen0</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    
+    | <span class="prod"><a class="grammarRef" href="#prod-prov_n-namespaceDeclarations">namespaceDeclarations</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen1" name="prod-prov_n-gen1"></a>[<span class="prodNo">3</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen1</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    
+    | <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen1">gen1</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-expression">expression</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen2" name="prod-prov_n-gen2"></a>[<span class="prodNo">4</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen2</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    
+    | <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen2">gen2</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-namedBundle">namedBundle</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen3" name="prod-prov_n-gen3"></a>[<span class="prodNo">5</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen3</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-namedBundle">namedBundle</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen2">gen2</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen4" name="prod-prov_n-gen4"></a>[<span class="prodNo">6</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen4</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    
+    | <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen3">gen3</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-namedBundle" name="prod-prov_n-namedBundle"></a>[<span class="prodNo">7</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">namedBundle</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    "bundle" <span class="prod"><a class="grammarRef" href="#prod-prov_n-identifier">identifier</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen0">gen0</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen1">gen1</a></span> "endBundle"</code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-namespaceDeclarations" name="prod-prov_n-namespaceDeclarations"></a>[<span class="prodNo">8</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">namespaceDeclarations</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen7">gen7</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen8">gen8</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen7" name="prod-prov_n-gen7"></a>[<span class="prodNo">9</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen7</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-defaultNamespaceDeclaration">defaultNamespaceDeclaration</a></span>
+    | <span class="prod"><a class="grammarRef" href="#prod-prov_n-namespaceDeclaration">namespaceDeclaration</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen8" name="prod-prov_n-gen8"></a>[<span class="prodNo">10</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen8</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    
+    | <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen8">gen8</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-namespaceDeclaration">namespaceDeclaration</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-namespaceDeclaration" name="prod-prov_n-namespaceDeclaration"></a>[<span class="prodNo">11</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">namespaceDeclaration</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    "prefix" <span class="prod"><a class="grammarRef" href="#prod-prov_n-QNAME">QNAME</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-namespace">namespace</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-namespace" name="prod-prov_n-namespace"></a>[<span class="prodNo">12</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">namespace</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-IRI_REF">IRI_REF</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-defaultNamespaceDeclaration" name="prod-prov_n-defaultNamespaceDeclaration"></a>[<span class="prodNo">13</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">defaultNamespaceDeclaration</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    "default" <span class="prod"><a class="grammarRef" href="#prod-prov_n-IRI_REF">IRI_REF</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-expression" name="prod-prov_n-expression"></a>[<span class="prodNo">14</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">expression</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen9">gen9</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen9" name="prod-prov_n-gen9"></a>[<span class="prodNo">15</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen9</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-entityExpression">entityExpression</a></span>
+    | <span class="prod"><a class="grammarRef" href="#prod-prov_n-activityExpression">activityExpression</a></span>
+    | <span class="prod"><a class="grammarRef" href="#prod-prov_n-generationExpression">generationExpression</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-entityExpression" name="prod-prov_n-entityExpression"></a>[<span class="prodNo">16</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">entityExpression</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    "entity" "(" <span class="prod"><a class="grammarRef" href="#prod-prov_n-identifier">identifier</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-optionalAttributeValuePairs">optionalAttributeValuePairs</a></span> ")"</code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-activityExpression" name="prod-prov_n-activityExpression"></a>[<span class="prodNo">17</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">activityExpression</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    "activity" "(" <span class="prod"><a class="grammarRef" href="#prod-prov_n-identifier">identifier</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen13">gen13</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-optionalAttributeValuePairs">optionalAttributeValuePairs</a></span> ")"</code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen10" name="prod-prov_n-gen10"></a>[<span class="prodNo">18</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen10</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-timeZZ">timeZZ</a></span>
+    | "-"</code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen12" name="prod-prov_n-gen12"></a>[<span class="prodNo">19</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen12</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    "," <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen10">gen10</a></span> "," <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen10">gen10</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen13" name="prod-prov_n-gen13"></a>[<span class="prodNo">20</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen13</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    
+    | <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen12">gen12</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-generationExpression" name="prod-prov_n-generationExpression"></a>[<span class="prodNo">21</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">generationExpression</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    "wasGeneratedBy" "(" <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen16">gen16</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-identifier">identifier</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen20">gen20</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-optionalAttributeValuePairs">optionalAttributeValuePairs</a></span> ")"</code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen14" name="prod-prov_n-gen14"></a>[<span class="prodNo">22</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen14</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-identifier">identifier</a></span>
+    | "-"</code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen15" name="prod-prov_n-gen15"></a>[<span class="prodNo">23</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen15</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen14">gen14</a></span> ";"</code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen16" name="prod-prov_n-gen16"></a>[<span class="prodNo">24</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen16</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    
+    | <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen15">gen15</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen19" name="prod-prov_n-gen19"></a>[<span class="prodNo">25</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen19</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    "," <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen14">gen14</a></span> "," <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen10">gen10</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen20" name="prod-prov_n-gen20"></a>[<span class="prodNo">26</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen20</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    
+    | <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen19">gen19</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-optionalAttributeValuePairs" name="prod-prov_n-optionalAttributeValuePairs"></a>[<span class="prodNo">27</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">optionalAttributeValuePairs</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen22">gen22</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen21" name="prod-prov_n-gen21"></a>[<span class="prodNo">28</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen21</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    "," "[" <span class="prod"><a class="grammarRef" href="#prod-prov_n-attributeValuePairs">attributeValuePairs</a></span> "]"</code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen22" name="prod-prov_n-gen22"></a>[<span class="prodNo">29</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen22</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    
+    | <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen21">gen21</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-identifier" name="prod-prov_n-identifier"></a>[<span class="prodNo">30</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">identifier</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-QNAME">QNAME</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-attribute" name="prod-prov_n-attribute"></a>[<span class="prodNo">31</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">attribute</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-QNAME">QNAME</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-attributeValuePairs" name="prod-prov_n-attributeValuePairs"></a>[<span class="prodNo">32</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">attributeValuePairs</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen25">gen25</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen23" name="prod-prov_n-gen23"></a>[<span class="prodNo">33</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen23</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    "," <span class="prod"><a class="grammarRef" href="#prod-prov_n-attributeValuePair">attributeValuePair</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen24" name="prod-prov_n-gen24"></a>[<span class="prodNo">34</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen24</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    
+    | <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen24">gen24</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen23">gen23</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen25" name="prod-prov_n-gen25"></a>[<span class="prodNo">35</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen25</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    
+    | <span class="prod"><a class="grammarRef" href="#prod-prov_n-attributeValuePair">attributeValuePair</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen24">gen24</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-attributeValuePair" name="prod-prov_n-attributeValuePair"></a>[<span class="prodNo">36</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">attributeValuePair</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-attribute">attribute</a></span> "=" <span class="prod"><a class="grammarRef" href="#prod-prov_n-literal">literal</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-timeZZ" name="prod-prov_n-timeZZ"></a>[<span class="prodNo">37</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">timeZZ</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-ISODATETIME">ISODATETIME</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-literal" name="prod-prov_n-literal"></a>[<span class="prodNo">38</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">literal</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-RDFLiteral">RDFLiteral</a></span>
+    | <span class="prod"><a class="grammarRef" href="#prod-prov_n-BooleanLiteral">BooleanLiteral</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-RDFLiteral" name="prod-prov_n-RDFLiteral"></a>[<span class="prodNo">39</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">RDFLiteral</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-String">String</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen27">gen27</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen26" name="prod-prov_n-gen26"></a>[<span class="prodNo">40</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen26</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    "^^" <span class="prod"><a class="grammarRef" href="#prod-prov_n-IRIref">IRIref</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-gen27" name="prod-prov_n-gen27"></a>[<span class="prodNo">41</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">gen27</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    
+    | <span class="prod"><a class="grammarRef" href="#prod-prov_n-gen26">gen26</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-BooleanLiteral" name="prod-prov_n-BooleanLiteral"></a>[<span class="prodNo">42</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">BooleanLiteral</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    "true"
+    | "false"</code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-String" name="prod-prov_n-String"></a>[<span class="prodNo">43</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">String</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-STRING_LITERAL">STRING_LITERAL</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-IRIref" name="prod-prov_n-IRIref"></a>[<span class="prodNo">44</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">IRIref</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-IRI_REF">IRI_REF</a></span>
+    | <span class="prod"><a class="grammarRef" href="#prod-prov_n-PrefixedName">PrefixedName</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="prod">
+<tr valign="baseline">
+<td><a id="prod-prov_n-PrefixedName" name="prod-prov_n-PrefixedName"></a>[<span class="prodNo">45</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production prod">PrefixedName</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">    <span class="prod"><a class="grammarRef" href="#prod-prov_n-PNAME_LN">PNAME_LN</a></span>
+    | <span class="prod"><a class="grammarRef" href="#prod-prov_n-PNAME_NS">PNAME_NS</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-QNAME" name="term-prov_n-QNAME"></a>[<span class="prodNo">46</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">QNAME</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">(( <span class="prod"><a class="grammarRef" href="#prod-prov_n-PN_PREFIX">PN_PREFIX</a></span> ":" ))? <span class="prod"><a class="grammarRef" href="#prod-prov_n-PN_LOCAL">PN_LOCAL</a></span><br/>
+| <span class="prod"><a class="grammarRef" href="#prod-prov_n-PN_PREFIX">PN_PREFIX</a></span> ":"</code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-PREFX" name="term-prov_n-PREFX"></a>[<span class="prodNo">47</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">PREFX</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content"><span class="prod"><a class="grammarRef" href="#prod-prov_n-PN_PREFIX">PN_PREFIX</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-DIGIT" name="term-prov_n-DIGIT"></a>[<span class="prodNo">48</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">DIGIT</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">[0-9]</code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-ISODATETIME" name="term-prov_n-ISODATETIME"></a>[<span class="prodNo">49</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">ISODATETIME</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content"><span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span> "-" <span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span> "-" <span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span> "T" <span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span> ":" <span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span> ":" <span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span> (( "." <span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span> (( <span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span> (<span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span>)? ))? ))? (( "Z" | <span class="prod"><a class="grammarRef" href="#prod-prov_n-TIMEZONEOFFSET">TIMEZONEOFFSET</a></span> ))?</code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-TIMEZONEOFFSET" name="term-prov_n-TIMEZONEOFFSET"></a>[<span class="prodNo">50</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">TIMEZONEOFFSET</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">( "+" | "-" ) <span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span> ":" <span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-DIGIT">DIGIT</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-PREFIX" name="term-prov_n-PREFIX"></a>[<span class="prodNo">51</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">PREFIX</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">"@prefix"</code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-IRI_REF" name="term-prov_n-IRI_REF"></a>[<span class="prodNo">52</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">IRI_REF</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">"&lt;" (( [^&lt;&gt;\"{}|^`\\] - [#0000- ] | <span class="prod"><a class="grammarRef" href="#prod-prov_n-UCHAR">UCHAR</a></span> ))* "&gt;"</code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-PNAME_NS" name="term-prov_n-PNAME_NS"></a>[<span class="prodNo">53</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">PNAME_NS</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">(( <span class="prod"><a class="grammarRef" href="#prod-prov_n-PN_PREFIX">PN_PREFIX</a></span> ))? ":"</code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-PNAME_LN" name="term-prov_n-PNAME_LN"></a>[<span class="prodNo">54</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">PNAME_LN</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content"><span class="prod"><a class="grammarRef" href="#prod-prov_n-PNAME_NS">PNAME_NS</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-PN_LOCAL">PN_LOCAL</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-STRING_LITERAL" name="term-prov_n-STRING_LITERAL"></a>[<span class="prodNo">55</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">STRING_LITERAL</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">'"' (( ( [^\"\\\n\r] ) | <span class="prod"><a class="grammarRef" href="#prod-prov_n-ECHAR">ECHAR</a></span> | <span class="prod"><a class="grammarRef" href="#prod-prov_n-UCHAR">UCHAR</a></span> ))* '"'</code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-UCHAR" name="term-prov_n-UCHAR"></a>[<span class="prodNo">56</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">UCHAR</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">( "\\u" <span class="prod"><a class="grammarRef" href="#prod-prov_n-HEX">HEX</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-HEX">HEX</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-HEX">HEX</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-HEX">HEX</a></span> )<br/>
+| ( "\\U" <span class="prod"><a class="grammarRef" href="#prod-prov_n-HEX">HEX</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-HEX">HEX</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-HEX">HEX</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-HEX">HEX</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-HEX">HEX</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-HEX">HEX</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-HEX">HEX</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-HEX">HEX</a></span> )</code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-ECHAR" name="term-prov_n-ECHAR"></a>[<span class="prodNo">57</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">ECHAR</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">"\\" [tbnrf\\\"']</code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-NIL" name="term-prov_n-NIL"></a>[<span class="prodNo">58</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">NIL</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">"(" (( <span class="prod"><a class="grammarRef" href="#prod-prov_n-WS">WS</a></span> ))* ")"</code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-WS" name="term-prov_n-WS"></a>[<span class="prodNo">59</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">WS</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">" "<br/>
+| "\t"<br/>
+| "\r"<br/>
+| "\n"</code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-ANON" name="term-prov_n-ANON"></a>[<span class="prodNo">60</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">ANON</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">"[" (( <span class="prod"><a class="grammarRef" href="#prod-prov_n-WS">WS</a></span> ))* "]"</code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-PN_CHARS_BASE" name="term-prov_n-PN_CHARS_BASE"></a>[<span class="prodNo">61</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">PN_CHARS_BASE</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">[A-Z]<br/>
+| [a-z]<br/>
+| [#00C0-#00D6]<br/>
+| [#00D8-#00F6]<br/>
+| [#00F8-#02FF]<br/>
+| [#0370-#037D]<br/>
+| [#037F-#1FFF]<br/>
+| [#200C-#200D]<br/>
+| [#2070-#218F]<br/>
+| [#2C00-#2FEF]<br/>
+| [#3001-#D7FF]<br/>
+| [#F900-#FDCF]<br/>
+| [#FDF0-#FFFD]<br/>
+| [#10000-#EFFFF]</code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-PN_CHARS_U" name="term-prov_n-PN_CHARS_U"></a>[<span class="prodNo">62</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">PN_CHARS_U</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content"><span class="prod"><a class="grammarRef" href="#prod-prov_n-PN_CHARS_BASE">PN_CHARS_BASE</a></span><br/>
+| "_"</code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-PN_CHARS" name="term-prov_n-PN_CHARS"></a>[<span class="prodNo">63</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">PN_CHARS</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content"><span class="prod"><a class="grammarRef" href="#prod-prov_n-PN_CHARS_U">PN_CHARS_U</a></span><br/>
+| "-"<br/>
+| [0-9]<br/>
+| <br/>
+| [#0300-#036F]<br/>
+| [#203F-#2040]</code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-PN_PREFIX" name="term-prov_n-PN_PREFIX"></a>[<span class="prodNo">64</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">PN_PREFIX</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content"><span class="prod"><a class="grammarRef" href="#prod-prov_n-PN_CHARS_BASE">PN_CHARS_BASE</a></span> (( (( <span class="prod"><a class="grammarRef" href="#prod-prov_n-PN_CHARS">PN_CHARS</a></span> | "." ))* <span class="prod"><a class="grammarRef" href="#prod-prov_n-PN_CHARS">PN_CHARS</a></span> ))?</code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-PN_LOCAL" name="term-prov_n-PN_LOCAL"></a>[<span class="prodNo">65</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">PN_LOCAL</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">( <span class="prod"><a class="grammarRef" href="#prod-prov_n-PN_CHARS_U">PN_CHARS_U</a></span> | [0-9] | <span class="prod"><a class="grammarRef" href="#prod-prov_n-PLX">PLX</a></span> ) (( (( <span class="prod"><a class="grammarRef" href="#prod-prov_n-PN_CHARS">PN_CHARS</a></span> | "." | <span class="prod"><a class="grammarRef" href="#prod-prov_n-PLX">PLX</a></span> ))* ( <span class="prod"><a class="grammarRef" href="#prod-prov_n-PN_CHARS">PN_CHARS</a></span> | <span class="prod"><a class="grammarRef" href="#prod-prov_n-PLX">PLX</a></span> ) ))?</code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-PLX" name="term-prov_n-PLX"></a>[<span class="prodNo">66</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">PLX</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content"><span class="prod"><a class="grammarRef" href="#prod-prov_n-PERCENT">PERCENT</a></span><br/>
+| <span class="prod"><a class="grammarRef" href="#prod-prov_n-PN_LOCAL_ESC">PN_LOCAL_ESC</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-PERCENT" name="term-prov_n-PERCENT"></a>[<span class="prodNo">67</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">PERCENT</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">"%" <span class="prod"><a class="grammarRef" href="#prod-prov_n-HEX">HEX</a></span> <span class="prod"><a class="grammarRef" href="#prod-prov_n-HEX">HEX</a></span></code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-HEX" name="term-prov_n-HEX"></a>[<span class="prodNo">68</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">HEX</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">[0-9]<br/>
+| [A-F]<br/>
+| [a-f]</code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-PN_LOCAL_ESC" name="term-prov_n-PN_LOCAL_ESC"></a>[<span class="prodNo">69</span>]&nbsp;&nbsp;&nbsp;</td>
+<td>&lt;<code class="production term">PN_LOCAL_ESC</code>&gt;</td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">"\\" ( "_" | "~" | "." | "-" | "!" | "$" | "&amp;" | "'" | "(" | ")" | "*" | "+" | "," | ";" | "=" | ":" | "/" | "?" | "#" | "@" | "%" )</code></td>
+</tr>
+</tbody>
+
+<tbody class="term">
+<tr valign="baseline">
+<td><a id="term-prov_n-PASSED_TOKENS" name="term-prov_n-PASSED_TOKENS"></a>[<span class="prodNo">70</span>]&nbsp;&nbsp;&nbsp;</td>
+<td><code class="production directive">PASSED TOKENS</code></td>
+<td>&nbsp;&nbsp;&nbsp;::=&nbsp;&nbsp;&nbsp;</td>
+<td><code class="content">([ \t\r\n])+<br/>
+| "#" ([^\r\n])*</code></td>
+</tr>
+</tbody>
+
+</table>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/sample.in	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,13 @@
+
+
+bundle
+prefix ex <http://example>
+
+          entity(ex:e1, [ex:param="a"])
+          activity(ex:a10, 2011-11-16T16:00:00, 2011-11-16T16:00:01, [prov:type="createFile"])
+
+          wasGeneratedBy(g1; ex:e1, ex:a1, 2001-10-26T21:32:52, [ex:param1="a", ex:param2="b"])
+
+
+endBundle
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/templates	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,1 @@
+perl/modules/W3C/Grammar/bin/templates
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/model/grammar/yack/turtle.bnf	Wed May 09 23:20:21 2012 +0100
@@ -0,0 +1,157 @@
+[1] turtleDoc ::= (statement)* 
+ 
+[2] statement ::= directive "." 
+ | triples "." 
+[3] directive ::= prefixID 
+ | base 
+[4] prefixID ::= PREFIX PNAME_NS IRI_REF 
+ 
+[5] base ::= BASE IRI_REF 
+ 
+[6] triples ::= subject predicateObjectList 
+ 
+[7] predicateObjectList ::= verb objectList ( ";" verb objectList )* (";")? 
+ 
+[8] objectList ::= object ( "," object )* 
+ 
+[9] verb ::= predicate 
+ | "a" 
+[10] subject ::= IRIref 
+ | blank 
+[11] predicate ::= IRIref 
+ 
+[12] object ::= IRIref 
+ | blank 
+ | literal 
+[13] literal ::= RDFLiteral 
+ | NumericLiteral 
+ | BooleanLiteral 
+[14] blank ::= BlankNode 
+ | blankNodePropertyList 
+ | collection 
+[15] blankNodePropertyList ::= "[" predicateObjectList "]" 
+ 
+[16] collection ::= "(" object* ")" 
+ 
+[60s] RDFLiteral ::= String ( LANGTAG | ( "^^" IRIref ) )? 
+ 
+[61s] NumericLiteral ::= NumericLiteralUnsigned 
+ | NumericLiteralPositive 
+ | NumericLiteralNegative 
+[62s] NumericLiteralUnsigned ::= INTEGER 
+ | DECIMAL 
+ | DOUBLE 
+[63s] NumericLiteralPositive ::= INTEGER_POSITIVE 
+ | DECIMAL_POSITIVE 
+ | DOUBLE_POSITIVE 
+[64s] NumericLiteralNegative ::= INTEGER_NEGATIVE 
+ | DECIMAL_NEGATIVE 
+ | DOUBLE_NEGATIVE 
+[65s] BooleanLiteral ::= "true" 
+ | "false" 
+[66s] String ::= STRING_LITERAL1 
+ | STRING_LITERAL2 
+ | STRING_LITERAL_LONG1 
+ | STRING_LITERAL_LONG2 
+[67s] IRIref ::= IRI_REF 
+ | PrefixedName 
+[68s] PrefixedName ::= PNAME_LN 
+ | PNAME_NS 
+[69s] BlankNode ::= BLANK_NODE_LABEL 
+ | ANON 
+
+@terminals
+
+[17] BASE ::= "@base" 
+ 
+[18] PREFIX ::= "@prefix" 
+
+[70s] IRI_REF ::= "<" ( [^<>\"{}|^`\\] - [#x00-#x20] | UCHAR )* ">" 
+ 
+[71s] PNAME_NS ::= (PN_PREFIX)? ":" 
+ 
+[72s] PNAME_LN ::= PNAME_NS PN_LOCAL 
+ 
+[73s] BLANK_NODE_LABEL ::= "_:" ( PN_CHARS_U | [0-9] ) ( ( PN_CHARS | '.' )*  PN_CHARS )?
+ 
+[76s] LANGTAG ::= BASE 
+ | PREFIX 
+ | "@" [a-zA-Z]+ ( "-" [a-zA-Z0-9]+ )* 
+[77s] INTEGER ::= [0-9]+ 
+ 
+[78s] DECIMAL ::= [0-9]+ "." [0-9]+ 
+ | "." [0-9]+ 
+[79s] DOUBLE ::= [0-9]+ "." [0-9]+ EXPONENT 
+ | "." ( [0-9] )+ EXPONENT 
+ | ( [0-9] )+ EXPONENT 
+[80s] INTEGER_POSITIVE ::= "+" INTEGER 
+ 
+[81s] DECIMAL_POSITIVE ::= "+" DECIMAL 
+ 
+[82s] DOUBLE_POSITIVE ::= "+" DOUBLE 
+ 
+[83s] INTEGER_NEGATIVE ::= "-" INTEGER 
+ 
+[84s] DECIMAL_NEGATIVE ::= "-" DECIMAL 
+ 
+[85s] DOUBLE_NEGATIVE ::= "-" DOUBLE 
+ 
+[86s] EXPONENT ::= [eE] [+-]? [0-9]+ 
+ 
+[148s] STRING_LITERAL1 ::= "'" ( ( [^#x27#x5C#xA#xD]) | ECHAR | UCHAR )* "'" 
+ 
+[149s] STRING_LITERAL2 ::= '"' ( ( [^#x22#x5C#xA#xD]) | ECHAR | UCHAR )* '"' 
+ 
+[89s] STRING_LITERAL_LONG1 ::= "'''" ( ( "'" | "''" )? ( [^'\\] | ECHAR | UCHAR ) )* "'''" 
+ 
+[90s] STRING_LITERAL_LONG2 ::= '"""' ( ( '"' | '""' )? ( [^\"\\] | ECHAR | UCHAR ) )* '"""' 
+ 
+[19] UCHAR ::= ( "\\u" HEX HEX HEX HEX ) 
+ | ( "\\U" HEX HEX HEX HEX HEX HEX HEX HEX ) 
+
+[91s] ECHAR ::= "\\" [tbnrf\\\"'] 
+ 
+[92s] NIL ::= "(" (WS)* ")" 
+ 
+[93s] WS ::= " " 
+ | "\t" 
+ | "\r" 
+ | "\n" 
+[94s] ANON ::= "[" (WS)* "]" 
+ 
+[95s] PN_CHARS_BASE ::= [A-Z] 
+ | [a-z] 
+ | [#00C0-#00D6] 
+ | [#00D8-#00F6] 
+ | [#00F8-#02FF] 
+ | [#0370-#037D] 
+ | [#037F-#1FFF] 
+ | [#200C-#200D] 
+ | [#2070-#218F] 
+ | [#2C00-#2FEF] 
+ | [#3001-#D7FF] 
+ | [#F900-#FDCF] 
+ | [#FDF0-#FFFD] 
+ | [#10000-#EFFFF] 
+[96s] PN_CHARS_U ::= PN_CHARS_BASE 
+ | "_" 
+[98s] PN_CHARS ::= PN_CHARS_U 
+ | "-" 
+ | [0-9] 
+ | #00B7 
+ | [#0300-#036F] 
+ | [#203F-#2040] 
+[99s] PN_PREFIX ::= PN_CHARS_BASE ( ( PN_CHARS | "." )* PN_CHARS )? 
+ 
+[100s] PN_LOCAL ::= ( PN_CHARS_U | [0-9] | PLX ) ( ( PN_CHARS | '.' | PLX )*  ( PN_CHARS | PLX ) ) ?
+
+[160s] PLX ::= PERCENT | PN_LOCAL_ESC
+
+[161s] PERCENT ::= '%' HEX HEX
+
+[162s] HEX ::= [0-9] | [A-F] | [a-f]
+
+[163s] PN_LOCAL_ESC ::= '\\' ( '_' | '~' | '.' | '-' | '!' | '$' | '&' | "'" | '(' | ')' | '*' | '+' | ',' | ';' | '=' | ':' | '/' | '?' | '#' | '@' | '%' )
+ 
+@pass ::= [ \t\r\n]+ 
+ | "#" [^\r\n]* 
\ No newline at end of file