home: hub: minipeg

Download patch

ref: bf7a16e59b193714cece221765b046845acb1696
parent: 5e0acc3b77861587b89d7fd2c5da6f160d012209
author: Gregory Pakosz <gregory.pakosz@gmail.com>
date: Mon Jul 1 08:09:48 CDT 2013

imported peg-0.1.11

--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-CFLAGS = -g -Wall $(OFLAGS) $(XFLAGS)
+CFLAGS = -g -Wall $(OFLAGS) $(XFLAGS) -Isrc
 OFLAGS = -O3 -DNDEBUG
 #OFLAGS = -pg
 
@@ -17,47 +17,69 @@
 ROOT	=
 PREFIX	= /usr/local
 BINDIR	= $(ROOT)$(PREFIX)/bin
+MANDIR	= $(ROOT)$(PREFIX)/man/man1
 
-install : $(BINDIR)/peg $(BINDIR)/leg
+install : $(BINDIR) $(BINDIR)/peg $(BINDIR)/leg $(MANDIR) $(MANDIR)/peg.1
 
+$(BINDIR) :
+	mkdir -p $(BINDIR)
+
 $(BINDIR)/% : %
 	cp -p $< $@
 	strip $@
 
+$(MANDIR) :
+	mkdir -p $(MANDIR)
+
+$(MANDIR)/% : src/%
+	cp -p $< $@
+
 uninstall : .FORCE
 	rm -f $(BINDIR)/peg
 	rm -f $(BINDIR)/leg
+	rm -f $(MANDIR)/peg.1
 
-peg.o : peg.c peg.peg-c
+%.o : src/%.c
+	$(CC) $(CFLAGS) -c -o $@ $<
 
-%.peg-c : %.peg compile.c
-	./peg -o $@ $<
+peg.o : src/peg.c src/peg.peg-c
 
-leg.o : leg.c
+leg.o : src/leg.c
 
-leg.c : leg.leg compile.c
+check : check-peg check-leg
+
+check-peg : peg.peg-c .FORCE
+	diff src/peg.peg-c peg.peg-c
+
+check-leg : leg.c .FORCE
+	diff src/leg.c leg.c
+
+peg.peg-c : src/peg.peg peg
+	./peg -o $@ $<
+
+leg.c : src/leg.leg leg
 	./leg -o $@ $<
 
-check : check-peg check-leg
+new : newpeg newleg
 
-check-peg : peg .FORCE
-	./peg < peg.peg > peg.out
-	diff peg.peg-c peg.out
-	rm peg.out
+newpeg : peg.peg-c
+	mv src/peg.peg-c src/peg.peg-c-
+	mv peg.peg-c src/.
 
-check-leg : leg .FORCE
-	./leg < leg.leg > leg.out
-	diff leg.c leg.out
-	rm leg.out
+newleg : leg.c
+	mv src/leg.c src/leg.c-
+	mv leg.c src/.
 
-test examples : .FORCE
+test examples : peg leg .FORCE
 	$(SHELL) -ec '(cd examples;  $(MAKE))'
 
 clean : .FORCE
-	rm -f *~ *.o *.peg.[cd] *.leg.[cd]
+	rm -f src/*~ *~ *.o *.peg.[cd] *.leg.[cd] peg.peg-c leg.c
 	$(SHELL) -ec '(cd examples;  $(MAKE) $@)'
 
 spotless : clean .FORCE
+	rm -f src/*-
+	rm -rf build
 	rm -f peg
 	rm -f leg
 	$(SHELL) -ec '(cd examples;  $(MAKE) $@)'
--- a/README.md
+++ b/README.md
@@ -26,28 +26,36 @@
 
 ## Version history
 
-* **0.1.9** ([zip](peg/zipball/0.1.9), [tar.gz](peg/tarball/0.1.9)) &mdash; 2012-04-29  
+* **0.1.11** ([zip](../../archive/0.1.11.zip), [tar.gz](../../archive/0.1.11.tar.gz)) &mdash; 2013-06-03  
+Add error actions via `"~"` operator.  
+Support declaration of local variables at the top level of semantic actions.  
+Dynamically grow data structures to remove artificial limits on rule recursion (thanks to Alex Klinkhamer).  
+Many small changes to better support C++.  
+Add build files for Win32 and MacOS (thanks to Fyodor Sheremetyev).  
+Update manual page to describe new features.  
+* **0.1.10** &mdash; missing in upstream
+* **0.1.9** ([zip](../../archive/0.1.9.zip), [tar.gz](../../archive/0.1.9.tar.gz)) &mdash; 2012-04-29  
 Move global state into a structure to facilitate reentrant and thread-safe parsers (thanks to Dmitry Lipovoi).
-* **0.1.8** ([zip](peg/zipball/0.1.8), [tar.gz](peg/tarball/0.1.8)) &mdash; 2012-03-29  
+* **0.1.8** ([zip](../../archive/0.1.8.zip), [tar.gz](../../archive/0.1.8.tar.gz)) &mdash; 2012-03-29  
 Allow nested, matched braces within actions.
-* **0.1.7** ([zip](peg/zipball/0.1.7), [tar.gz](peg/tarball/0.1.7)) &mdash; 2011-11-25  
+* **0.1.7** ([zip](../../archive/0.1.7.zip), [tar.gz](../../archive/0.1.7.tar.gz)) &mdash; 2011-11-25  
 Fix matching of 8-bit chars to allow utf-8 sequences in matching expressions (thanks to Grégory Pakosz).
-* **0.1.6** ([zip](peg/zipball/0.1.6), [tar.gz](peg/tarball/0.1.6)) &mdash; 2011-11-24  
+* **0.1.6** ([zip](../../archive/0.1.6.zip), [tar.gz](../../archive/0.1.6.tar.gz)) &mdash; 2011-11-24  
 Allow octal escapes in character classes.
-* **0.1.5** ([zip](peg/zipball/0.1.5), [tar.gz](peg/tarball/0.1.5)) &mdash; 2011-11-24  
+* **0.1.5** ([zip](../../archive/0.1.5.zip), [tar.gz](../../archive/0.1.5.tar.gz)) &mdash; 2011-11-24  
 Remove dwarf sym dirs when cleaning.  
 Fix size calculation when resizing text buffers.  
 Backslash can be escaped.  
-* **0.1.4** ([zip](peg/zipball/0.1.4), [tar.gz](peg/tarball/0.1.4)) &mdash; 2009-08-26  
+* **0.1.4** ([zip](../../archive/0.1.4.zip), [tar.gz](../../archive/0.1.4.tar.gz)) &mdash; 2009-08-26  
 Fix match of a single single quote character.  
 Rename `getline` -> `nextline` to avoid C namespace conflict.  
-* **0.1.3** ([zip](peg/zipball/0.1.3), [tar.gz](peg/tarball/0.1.3)) &mdash; 2007-09-13  
+* **0.1.3** ([zip](../../archive/0.1.3.zip), [tar.gz](../../archive/0.1.3.tar.gz)) &mdash; 2007-09-13  
 Allow matched braces inside `leg` actions.  
 Handle empty rules.  
 Handle empty grammars.  
-* **0.1.2** ([zip](peg/zipball/0.1.2), [tar.gz](peg/tarball/0.1.2)) &mdash; 2007-08-31  
+* **0.1.2** ([zip](../../archive/0.1.2.zip), [tar.gz](../../archive/0.1.2.tar.gz)) &mdash; 2007-08-31  
 Grow buffers while (not if) they are too small.  
 Remove dependencies on grammar files.  
 Add more basic examples.  
-* **0.1.1** ([zip](peg/zipball/0.1.1), [tar.gz](peg/tarball/0.1.1)) &mdash; 2007-05-15  
+* **0.1.1** ([zip](../../archive/0.1.1.zip), [tar.gz](../../archive/0.1.1.tar.gz)) &mdash; 2007-05-15  
 First public release.
--- /dev/null
+++ b/README.txt
@@ -1,0 +1,42 @@
+Building on a Unix-like system
+------------------------------
+
+Type 'make' or 'make test'.
+
+The latter builds all the examples and runs them, comparing their
+output with the expected output.
+
+Type 'make install' to install the binaries and manual page under
+/usr/local.  (Type 'make uninstall' to remove them.)  You may have to
+do this using 'sudo' or while logged in as root.
+
+Edit 'Makefile' to change the way things are built and/or the places
+where things are installed.
+
+
+Building on MacOS X
+-------------------
+
+Run the 'build-mac.sh' script from a terminal or by double-clicking on
+it in the Finder.
+
+You will need Xcode.  The provided project is known to work with Xcode
+versions 3.2.6 and 4.3.2.
+
+Modify build-mac.sh and/or peg.xcodeproj to change the way things are
+built.
+
+
+Building on Windows
+-------------------
+
+Run the 'build-win.cmd' script.
+
+You will need Visual Studio 2010 Express.
+
+Modify build-win.cmd, leg.vcxproj, leg.vcxproj.filters, peg.gyp,
+peg.sln, peg.vcxproj and/or peg.vcxproj.filters to change the way
+things are built.
+
+Local implementations of getopt() and basename() are provided in the
+'win' directory.
--- /dev/null
+++ b/build-mac.sh
@@ -1,0 +1,6 @@
+#!/bin/bash
+
+xcodebuild -project peg.xcodeproj -configuration Release
+
+cp build/Release/peg ./
+cp build/Release/leg ./
--- /dev/null
+++ b/build-win.cmd
@@ -1,0 +1,5 @@
+@echo off
+call "%VS100COMNTOOLS%vsvars32.bat"
+msbuild peg.sln /p:Configuration=Release
+
+xcopy /Y /D Release\*.exe .\
--- a/compile.c
+++ /dev/null
@@ -1,717 +1,0 @@
-/* Copyright (c) 2007, 2012 by Ian Piumarta
- * All rights reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the 'Software'),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, provided that the above copyright notice(s) and this
- * permission notice appear in all copies of the Software.  Acknowledgement
- * of the use of this Software in supporting documentation would be
- * appreciated but is not required.
- * 
- * THE SOFTWARE IS PROVIDED 'AS IS'.  USE ENTIRELY AT YOUR OWN RISK.
- * 
- * Last edited: 2012-04-29 16:09:36 by piumarta on emilia
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "version.h"
-#include "tree.h"
-
-static int yyl(void)
-{
-  static int prev= 0;
-  return ++prev;
-}
-
-static void charClassSet  (unsigned char bits[], int c)	{ bits[c >> 3] |=  (1 << (c & 7)); }
-static void charClassClear(unsigned char bits[], int c)	{ bits[c >> 3] &= ~(1 << (c & 7)); }
-
-typedef void (*setter)(unsigned char bits[], int c);
-
-static inline int oigit(int c)	{ return '0' <= c && c <= '7'; }
-
-static int cnext(unsigned char **ccp)
-{
-    unsigned char *cclass= *ccp;
-    int c= *cclass++;
-    if (c)
-    {
-	if ('\\' == c && *cclass)
-	{
-	    switch (c= *cclass++)
-	    {
-		case 'a':  c= '\a'; break;	/* bel */
-		case 'b':  c= '\b'; break;	/* bs */
-		case 'e':  c= '\e'; break;	/* esc */
-		case 'f':  c= '\f'; break;	/* ff */
-		case 'n':  c= '\n'; break;	/* nl */
-		case 'r':  c= '\r'; break;	/* cr */
-		case 't':  c= '\t'; break;	/* ht */
-		case 'v':  c= '\v'; break;	/* vt */
-		default:
-		    if (oigit(c))
-		    {
-			c -= '0';
-			if (oigit(*cclass)) c= (c << 3) + *cclass++ - '0';
-			if (oigit(*cclass)) c= (c << 3) + *cclass++ - '0';
-		    }
-		    break;
-	    }
-	}
-	*ccp= cclass;
-    }
-    return c;
-}
-
-static char *makeCharClass(unsigned char *cclass)
-{
-  unsigned char	 bits[32];
-  setter	 set;
-  int		 c, prev= -1;
-  static char	 string[256];
-  char		*ptr;
-
-  if ('^' == *cclass)
-    {
-      memset(bits, 255, 32);
-      set= charClassClear;
-      ++cclass;
-    }
-  else
-    {
-      memset(bits, 0, 32);
-      set= charClassSet;
-    }
-
-  while (*cclass)
-    {
-      if ('-' == *cclass && cclass[1] && prev >= 0)
-	{
-	  ++cclass;
-	  for (c= cnext(&cclass);  prev <= c;  ++prev)
-	    set(bits, prev);
-	  prev= -1;
-	}
-      else
-	{
-	  c= cnext(&cclass);
-	  set(bits, prev= c);
-	}
-    }
-
-  ptr= string;
-  for (c= 0;  c < 32;  ++c)
-    ptr += sprintf(ptr, "\\%03o", bits[c]);
-
-  return string;
-}
-
-static void begin(void)		{ fprintf(output, "\n  {"); }
-static void end(void)		{ fprintf(output, "\n  }"); }
-static void label(int n)	{ fprintf(output, "\n  l%d:;\t", n); }
-static void jump(int n)		{ fprintf(output, "  goto l%d;", n); }
-static void save(int n)		{ fprintf(output, "  int yypos%d= ctx->pos, yythunkpos%d= ctx->thunkpos;", n, n); }
-static void restore(int n)	{ fprintf(output,     "  ctx->pos= yypos%d; ctx->thunkpos= yythunkpos%d;", n, n); }
-
-static void Node_compile_c_ko(Node *node, int ko)
-{
-  assert(node);
-  switch (node->type)
-    {
-    case Rule:
-      fprintf(stderr, "\ninternal error #1 (%s)\n", node->rule.name);
-      exit(1);
-      break;
-
-    case Dot:
-      fprintf(output, "  if (!yymatchDot(ctx)) goto l%d;", ko);
-      break;
-
-    case Name:
-      fprintf(output, "  if (!yy_%s(ctx)) goto l%d;", node->name.rule->rule.name, ko);
-      if (node->name.variable)
-	fprintf(output, "  yyDo(ctx, yySet, %d, 0);", node->name.variable->variable.offset);
-      break;
-
-    case Character:
-    case String:
-      {
-	int len= strlen(node->string.value);
-	if (1 == len)
-	  {
-	    if ('\'' == node->string.value[0])
-	      fprintf(output, "  if (!yymatchChar(ctx, '\\'')) goto l%d;", ko);
-	    else
-	      fprintf(output, "  if (!yymatchChar(ctx, '%s')) goto l%d;", node->string.value, ko);
-	  }
-	else
-	  if (2 == len && '\\' == node->string.value[0])
-	    fprintf(output, "  if (!yymatchChar(ctx, '%s')) goto l%d;", node->string.value, ko);
-	  else 
-	    fprintf(output, "  if (!yymatchString(ctx, \"%s\")) goto l%d;", node->string.value, ko);
-      }
-      break;
-
-    case Class:
-      fprintf(output, "  if (!yymatchClass(ctx, (unsigned char *)\"%s\")) goto l%d;", makeCharClass(node->cclass.value), ko);
-      break;
-
-    case Action:
-      fprintf(output, "  yyDo(ctx, yy%s, ctx->begin, ctx->end);", node->action.name);
-      break;
-
-    case Predicate:
-      fprintf(output, "  yyText(ctx, ctx->begin, ctx->end);  if (!(%s)) goto l%d;", node->action.text, ko);
-      break;
-
-    case Alternate:
-      {
-	int ok= yyl();
-	begin();
-	save(ok);
-	for (node= node->alternate.first;  node;  node= node->alternate.next)
-	  if (node->alternate.next)
-	    {
-	      int next= yyl();
-	      Node_compile_c_ko(node, next);
-	      jump(ok);
-	      label(next);
-	      restore(ok);
-	    }
-	  else
-	    Node_compile_c_ko(node, ko);
-	end();
-	label(ok);
-      }
-      break;
-
-    case Sequence:
-      for (node= node->sequence.first;  node;  node= node->sequence.next)
-	Node_compile_c_ko(node, ko);
-      break;
-
-    case PeekFor:
-      {
-	int ok= yyl();
-	begin();
-	save(ok);
-	Node_compile_c_ko(node->peekFor.element, ko);
-	restore(ok);
-	end();
-      }
-      break;
-
-    case PeekNot:
-      {
-	int ok= yyl();
-	begin();
-	save(ok);
-	Node_compile_c_ko(node->peekFor.element, ok);
-	jump(ko);
-	label(ok);
-	restore(ok);
-	end();
-      }
-      break;
-
-    case Query:
-      {
-	int qko= yyl(), qok= yyl();
-	begin();
-	save(qko);
-	Node_compile_c_ko(node->query.element, qko);
-	jump(qok);
-	label(qko);
-	restore(qko);
-	end();
-	label(qok);
-      }
-      break;
-
-    case Star:
-      {
-	int again= yyl(), out= yyl();
-	label(again);
-	begin();
-	save(out);
-	Node_compile_c_ko(node->star.element, out);
-	jump(again);
-	label(out);
-	restore(out);
-	end();
-      }
-      break;
-
-    case Plus:
-      {
-	int again= yyl(), out= yyl();
-	Node_compile_c_ko(node->plus.element, ko);
-	label(again);
-	begin();
-	save(out);
-	Node_compile_c_ko(node->plus.element, out);
-	jump(again);
-	label(out);
-	restore(out);
-	end();
-      }
-      break;
-
-    default:
-      fprintf(stderr, "\nNode_compile_c_ko: illegal node type %d\n", node->type);
-      exit(1);
-    }
-}
-
-
-static int countVariables(Node *node)
-{
-  int count= 0;
-  while (node)
-    {
-      ++count;
-      node= node->variable.next;
-    }
-  return count;
-}
-
-static void defineVariables(Node *node)
-{
-  int count= 0;
-  while (node)
-    {
-      fprintf(output, "#define %s ctx->val[%d]\n", node->variable.name, --count);
-      node->variable.offset= count;
-      node= node->variable.next;
-    }
-  fprintf(output, "#define yy ctx->yy\n");
-  fprintf(output, "#define yypos ctx->pos\n");
-  fprintf(output, "#define yythunkpos ctx->thunkpos\n");
-}
-
-static void undefineVariables(Node *node)
-{
-  fprintf(output, "#undef yythunkpos\n");
-  fprintf(output, "#undef yypos\n");
-  fprintf(output, "#undef yy\n");
-  while (node)
-    {
-      fprintf(output, "#undef %s\n", node->variable.name);
-      node= node->variable.next;
-    }
-}
-
-
-static void Rule_compile_c2(Node *node)
-{
-  assert(node);
-  assert(Rule == node->type);
-
-  if (!node->rule.expression)
-    fprintf(stderr, "rule '%s' used but not defined\n", node->rule.name);
-  else
-    {
-      int ko= yyl(), safe;
-
-      if ((!(RuleUsed & node->rule.flags)) && (node != start))
-	fprintf(stderr, "rule '%s' defined but not used\n", node->rule.name);
-
-      safe= ((Query == node->rule.expression->type) || (Star == node->rule.expression->type));
-
-      fprintf(output, "\nYY_RULE(int) yy_%s(yycontext *ctx)\n{", node->rule.name);
-      if (!safe) save(0);
-      if (node->rule.variables)
-	fprintf(output, "  yyDo(ctx, yyPush, %d, 0);", countVariables(node->rule.variables));
-      fprintf(output, "\n  yyprintf((stderr, \"%%s\\n\", \"%s\"));", node->rule.name);
-      Node_compile_c_ko(node->rule.expression, ko);
-      fprintf(output, "\n  yyprintf((stderr, \"  ok   %%s @ %%s\\n\", \"%s\", ctx->buf+ctx->pos));", node->rule.name);
-      if (node->rule.variables)
-	fprintf(output, "  yyDo(ctx, yyPop, %d, 0);", countVariables(node->rule.variables));
-      fprintf(output, "\n  return 1;");
-      if (!safe)
-	{
-	  label(ko);
-	  restore(0);
-	  fprintf(output, "\n  yyprintf((stderr, \"  fail %%s @ %%s\\n\", \"%s\", ctx->buf+ctx->pos));", node->rule.name);
-	  fprintf(output, "\n  return 0;");
-	}
-      fprintf(output, "\n}");
-    }
-
-  if (node->rule.next)
-    Rule_compile_c2(node->rule.next);
-}
-
-static char *header= "\
-#include <stdio.h>\n\
-#include <stdlib.h>\n\
-#include <string.h>\n\
-";
-
-static char *preamble= "\
-#ifndef YY_LOCAL\n\
-#define YY_LOCAL(T)	static T\n\
-#endif\n\
-#ifndef YY_ACTION\n\
-#define YY_ACTION(T)	static T\n\
-#endif\n\
-#ifndef YY_RULE\n\
-#define YY_RULE(T)	static T\n\
-#endif\n\
-#ifndef YY_PARSE\n\
-#define YY_PARSE(T)	T\n\
-#endif\n\
-#ifndef YYPARSE\n\
-#define YYPARSE		yyparse\n\
-#endif\n\
-#ifndef YYPARSEFROM\n\
-#define YYPARSEFROM	yyparsefrom\n\
-#endif\n\
-#ifndef YY_INPUT\n\
-#define YY_INPUT(buf, result, max_size)			\\\n\
-  {							\\\n\
-    int yyc= getchar();					\\\n\
-    result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1);	\\\n\
-    yyprintf((stderr, \"<%c>\", yyc));			\\\n\
-  }\n\
-#endif\n\
-#ifndef YY_BEGIN\n\
-#define YY_BEGIN	( ctx->begin= ctx->pos, 1)\n\
-#endif\n\
-#ifndef YY_END\n\
-#define YY_END		( ctx->end= ctx->pos, 1)\n\
-#endif\n\
-#ifdef YY_DEBUG\n\
-# define yyprintf(args)	fprintf args\n\
-#else\n\
-# define yyprintf(args)\n\
-#endif\n\
-#ifndef YYSTYPE\n\
-#define YYSTYPE	int\n\
-#endif\n\
-\n\
-#ifndef YY_PART\n\
-\n\
-typedef struct _yycontext yycontext;\n\
-typedef void (*yyaction)(yycontext *ctx, char *yytext, int yyleng);\n\
-typedef struct _yythunk { int begin, end;  yyaction  action;  struct _yythunk *next; } yythunk;\n\
-\n\
-struct _yycontext {\n\
-  char     *buf;\n\
-  int       buflen;\n\
-  int       pos;\n\
-  int       limit;\n\
-  char     *text;\n\
-  int       textlen;\n\
-  int       begin;\n\
-  int       end;\n\
-  int       textmax;\n\
-  yythunk  *thunks;\n\
-  int       thunkslen;\n\
-  int       thunkpos;\n\
-  YYSTYPE   yy;\n\
-  YYSTYPE  *val;\n\
-  YYSTYPE  *vals;\n\
-  int       valslen;\n\
-#ifdef YY_CTX_MEMBERS\n\
-  YY_CTX_MEMBERS\n\
-#endif\n\
-};\n\
-\n\
-#ifdef YY_CTX_LOCAL\n\
-#define YY_CTX_PARAM_	yycontext *yyctx,\n\
-#define YY_CTX_PARAM	yycontext *yyctx\n\
-#define YY_CTX_ARG_	yyctx,\n\
-#define YY_CTX_ARG	yyctx\n\
-#else\n\
-#define YY_CTX_PARAM_\n\
-#define YY_CTX_PARAM\n\
-#define YY_CTX_ARG_\n\
-#define YY_CTX_ARG\n\
-yycontext yyctx0;\n\
-yycontext *yyctx= &yyctx0;\n\
-#endif\n\
-\n\
-YY_LOCAL(int) yyrefill(yycontext *ctx)\n\
-{\n\
-  int yyn;\n\
-  while (ctx->buflen - ctx->pos < 512)\n\
-    {\n\
-      ctx->buflen *= 2;\n\
-      ctx->buf= (char *)realloc(ctx->buf, ctx->buflen);\n\
-    }\n\
-  YY_INPUT((ctx->buf + ctx->pos), yyn, (ctx->buflen - ctx->pos));\n\
-  if (!yyn) return 0;\n\
-  ctx->limit += yyn;\n\
-  return 1;\n\
-}\n\
-\n\
-YY_LOCAL(int) yymatchDot(yycontext *ctx)\n\
-{\n\
-  if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;\n\
-  ++ctx->pos;\n\
-  return 1;\n\
-}\n\
-\n\
-YY_LOCAL(int) yymatchChar(yycontext *ctx, int c)\n\
-{\n\
-  if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;\n\
-  if ((unsigned char)ctx->buf[ctx->pos] == c)\n\
-    {\n\
-      ++ctx->pos;\n\
-      yyprintf((stderr, \"  ok   yymatchChar(ctx, %c) @ %s\\n\", c, ctx->buf+ctx->pos));\n\
-      return 1;\n\
-    }\n\
-  yyprintf((stderr, \"  fail yymatchChar(ctx, %c) @ %s\\n\", c, ctx->buf+ctx->pos));\n\
-  return 0;\n\
-}\n\
-\n\
-YY_LOCAL(int) yymatchString(yycontext *ctx, char *s)\n\
-{\n\
-  int yysav= ctx->pos;\n\
-  while (*s)\n\
-    {\n\
-      if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;\n\
-      if (ctx->buf[ctx->pos] != *s)\n\
-        {\n\
-          ctx->pos= yysav;\n\
-          return 0;\n\
-        }\n\
-      ++s;\n\
-      ++ctx->pos;\n\
-    }\n\
-  return 1;\n\
-}\n\
-\n\
-YY_LOCAL(int) yymatchClass(yycontext *ctx, unsigned char *bits)\n\
-{\n\
-  int c;\n\
-  if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;\n\
-  c= (unsigned char)ctx->buf[ctx->pos];\n\
-  if (bits[c >> 3] & (1 << (c & 7)))\n\
-    {\n\
-      ++ctx->pos;\n\
-      yyprintf((stderr, \"  ok   yymatchClass @ %s\\n\", ctx->buf+ctx->pos));\n\
-      return 1;\n\
-    }\n\
-  yyprintf((stderr, \"  fail yymatchClass @ %s\\n\", ctx->buf+ctx->pos));\n\
-  return 0;\n\
-}\n\
-\n\
-YY_LOCAL(void) yyDo(yycontext *ctx, yyaction action, int begin, int end)\n\
-{\n\
-  while (ctx->thunkpos >= ctx->thunkslen)\n\
-    {\n\
-      ctx->thunkslen *= 2;\n\
-      ctx->thunks= (yythunk *)realloc(ctx->thunks, sizeof(yythunk) * ctx->thunkslen);\n\
-    }\n\
-  ctx->thunks[ctx->thunkpos].begin=  begin;\n\
-  ctx->thunks[ctx->thunkpos].end=    end;\n\
-  ctx->thunks[ctx->thunkpos].action= action;\n\
-  ++ctx->thunkpos;\n\
-}\n\
-\n\
-YY_LOCAL(int) yyText(yycontext *ctx, int begin, int end)\n\
-{\n\
-  int yyleng= end - begin;\n\
-  if (yyleng <= 0)\n\
-    yyleng= 0;\n\
-  else\n\
-    {\n\
-      while (ctx->textlen < (yyleng + 1))\n\
-	{\n\
-	  ctx->textlen *= 2;\n\
-	  ctx->text= (char *)realloc(ctx->text, ctx->textlen);\n\
-	}\n\
-      memcpy(ctx->text, ctx->buf + begin, yyleng);\n\
-    }\n\
-  ctx->text[yyleng]= '\\0';\n\
-  return yyleng;\n\
-}\n\
-\n\
-YY_LOCAL(void) yyDone(yycontext *ctx)\n\
-{\n\
-  int pos;\n\
-  for (pos= 0;  pos < ctx->thunkpos;  ++pos)\n\
-    {\n\
-      yythunk *thunk= &ctx->thunks[pos];\n\
-      int yyleng= thunk->end ? yyText(ctx, thunk->begin, thunk->end) : thunk->begin;\n\
-      yyprintf((stderr, \"DO [%d] %p %s\\n\", pos, thunk->action, ctx->text));\n\
-      thunk->action(ctx, ctx->text, yyleng);\n\
-    }\n\
-  ctx->thunkpos= 0;\n\
-}\n\
-\n\
-YY_LOCAL(void) yyCommit(yycontext *ctx)\n\
-{\n\
-  if ((ctx->limit -= ctx->pos))\n\
-    {\n\
-      memmove(ctx->buf, ctx->buf + ctx->pos, ctx->limit);\n\
-    }\n\
-  ctx->begin -= ctx->pos;\n\
-  ctx->end -= ctx->pos;\n\
-  ctx->pos= ctx->thunkpos= 0;\n\
-}\n\
-\n\
-YY_LOCAL(int) yyAccept(yycontext *ctx, int tp0)\n\
-{\n\
-  if (tp0)\n\
-    {\n\
-      fprintf(stderr, \"accept denied at %d\\n\", tp0);\n\
-      return 0;\n\
-    }\n\
-  else\n\
-    {\n\
-      yyDone(ctx);\n\
-      yyCommit(ctx);\n\
-    }\n\
-  return 1;\n\
-}\n\
-\n\
-YY_LOCAL(void) yyPush(yycontext *ctx, char *text, int count)  { ctx->val += count; }\n\
-YY_LOCAL(void) yyPop(yycontext *ctx, char *text, int count)   { ctx->val -= count; }\n\
-YY_LOCAL(void) yySet(yycontext *ctx, char *text, int count)   { ctx->val[count]= ctx->yy; }\n\
-\n\
-#endif /* YY_PART */\n\
-\n\
-#define	YYACCEPT	yyAccept(ctx, yythunkpos0)\n\
-\n\
-";
-
-static char *footer= "\n\
-\n\
-#ifndef YY_PART\n\
-\n\
-typedef int (*yyrule)(yycontext *ctx);\n\
-\n\
-YY_PARSE(int) YYPARSEFROM(YY_CTX_PARAM_ yyrule yystart)\n\
-{\n\
-  int yyok;\n\
-  if (!yyctx->buflen)\n\
-    {\n\
-      yyctx->buflen= 1024;\n\
-      yyctx->buf= (char *)malloc(yyctx->buflen);\n\
-      yyctx->textlen= 1024;\n\
-      yyctx->text= (char *)malloc(yyctx->textlen);\n\
-      yyctx->thunkslen= 32;\n\
-      yyctx->thunks= (yythunk *)malloc(sizeof(yythunk) * yyctx->thunkslen);\n\
-      yyctx->valslen= 32;\n\
-      yyctx->vals= (YYSTYPE *)malloc(sizeof(YYSTYPE) * yyctx->valslen);\n\
-      yyctx->begin= yyctx->end= yyctx->pos= yyctx->limit= yyctx->thunkpos= 0;\n\
-    }\n\
-  yyctx->begin= yyctx->end= yyctx->pos;\n\
-  yyctx->thunkpos= 0;\n\
-  yyctx->val= yyctx->vals;\n\
-  yyok= yystart(yyctx);\n\
-  if (yyok) yyDone(yyctx);\n\
-  yyCommit(yyctx);\n\
-  return yyok;\n\
-}\n\
-\n\
-YY_PARSE(int) YYPARSE(YY_CTX_PARAM)\n\
-{\n\
-  return YYPARSEFROM(YY_CTX_ARG_ yy_%s);\n\
-}\n\
-\n\
-#endif\n\
-";
-
-void Rule_compile_c_header(void)
-{
-  fprintf(output, "/* A recursive-descent parser generated by peg %d.%d.%d */\n", PEG_MAJOR, PEG_MINOR, PEG_LEVEL);
-  fprintf(output, "\n");
-  fprintf(output, "%s", header);
-  fprintf(output, "#define YYRULECOUNT %d\n", ruleCount);
-}
-
-int consumesInput(Node *node)
-{
-  if (!node) return 0;
-
-  switch (node->type)
-    {
-    case Rule:
-      {
-	int result= 0;
-	if (RuleReached & node->rule.flags)
-	  fprintf(stderr, "possible infinite left recursion in rule '%s'\n", node->rule.name);
-	else
-	  {
-	    node->rule.flags |= RuleReached;
-	    result= consumesInput(node->rule.expression);
-	    node->rule.flags &= ~RuleReached;
-	  }
-	return result;
-      }
-      break;
-
-    case Dot:		return 1;
-    case Name:		return consumesInput(node->name.rule);
-    case Character:
-    case String:	return strlen(node->string.value) > 0;
-    case Class:		return 1;
-    case Action:	return 0;
-    case Predicate:	return 0;
-
-    case Alternate:
-      {
-	Node *n;
-	for (n= node->alternate.first;  n;  n= n->alternate.next)
-	  if (!consumesInput(n))
-	    return 0;
-      }
-      return 1;
-
-    case Sequence:
-      {
-	Node *n;
-	for (n= node->alternate.first;  n;  n= n->alternate.next)
-	  if (consumesInput(n))
-	    return 1;
-      }
-      return 0;
-
-    case PeekFor:	return 0;
-    case PeekNot:	return 0;
-    case Query:		return 0;
-    case Star:		return 0;
-    case Plus:		return consumesInput(node->plus.element);
-
-    default:
-      fprintf(stderr, "\nconsumesInput: illegal node type %d\n", node->type);
-      exit(1);
-    }
-  return 0;
-}
-
-
-void Rule_compile_c(Node *node)
-{
-  Node *n;
-
-  for (n= rules;  n;  n= n->rule.next)
-    consumesInput(n);
-
-  fprintf(output, "%s", preamble);
-  for (n= node;  n;  n= n->rule.next)
-    fprintf(output, "YY_RULE(int) yy_%s(yycontext *ctx); /* %d */\n", n->rule.name, n->rule.id);
-  fprintf(output, "\n");
-  for (n= actions;  n;  n= n->action.list)
-    {
-      fprintf(output, "YY_ACTION(void) yy%s(yycontext *ctx, char *yytext, int yyleng)\n{\n", n->action.name);
-      defineVariables(n->action.rule->rule.variables);
-      fprintf(output, "  yyprintf((stderr, \"do yy%s\\n\"));\n", n->action.name);
-      fprintf(output, "  %s;\n", n->action.text);
-      undefineVariables(n->action.rule->rule.variables);
-      fprintf(output, "}\n");
-    }
-  Rule_compile_c2(node);
-  fprintf(output, footer, start->rule.name);
-}
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -1,4 +1,4 @@
-EXAMPLES = test rule accept wc dc dcv calc basic localctx
+EXAMPLES = test rule accept wc dc dcv calc basic localpeg localleg erract
 
 CFLAGS = -g -O3
 
@@ -71,10 +71,26 @@
 	rm -f $@.out
 	@echo
 
-localctx : .FORCE
+localpeg : .FORCE
 	../peg -o test.peg.c test.peg
-	$(CC) $(CFLAGS) -o localctx localctx.c
+	$(CC) $(CFLAGS) -o localpeg localpeg.c
 	echo 'ab.ac.ad.ae.afg.afh.afg.afh.afi.afj.' | ./$@ | $(TEE) $@.out
+	$(DIFF) $@.ref $@.out
+	rm -f $@.out
+	@echo
+
+localleg : .FORCE
+	../leg -o localleg.leg.c localleg.leg
+	$(CC) $(CFLAGS) -o localleg localleg.leg.c
+	./$@ < localleg.leg | $(TEE) $@.out
+	$(DIFF) $@.ref $@.out
+	rm -f $@.out
+	@echo
+
+erract : .FORCE
+	../leg -o erract.leg.c erract.leg
+	$(CC) $(CFLAGS) -o erract erract.leg.c
+	echo '6*9' | ./$@ | $(TEE) $@.out
 	$(DIFF) $@.ref $@.out
 	rm -f $@.out
 	@echo
--- /dev/null
+++ b/examples/erract.leg
@@ -1,0 +1,27 @@
+%{
+#include <stdio.h>
+%}
+
+Expr	=   a:NUMBER PLUS   ~{ printf("fail at PLUS\n") } b:NUMBER { printf("got addition\n"); }
+	| ( a:NUMBER MINUS  				  b:NUMBER { printf("got subtraction\n"); } ) ~{ printf("fail at subtraction\n") }
+	|   a:NUMBER TIMES  				  b:NUMBER { printf("got multiplication\n"); }
+	|   a:NUMBER DIVIDE 				  b:NUMBER { printf("got division\n"); }
+
+NUMBER	= < [0-9]+ >	-					   { $$= atoi(yytext); }
+PLUS	= '+'		-
+MINUS	= '-'		-
+TIMES	= '*'		-
+DIVIDE	= '/'		-
+
+-	= (SPACE | EOL)*
+SPACE	= [ \t]
+EOL	= '\n' | '\r\n' | '\r' | ';'
+
+%%
+
+int main()
+{
+  while (yyparse());
+
+  return 0;
+}
--- /dev/null
+++ b/examples/erract.ref
@@ -1,0 +1,4 @@
+fail at PLUS
+fail at subtraction
+got multiplication
+fail at subtraction
--- a/examples/localctx.c
+++ /dev/null
@@ -1,13 +1,0 @@
-#include <stdio.h>
-
-#define YY_CTX_LOCAL
-
-#include "test.peg.c"
-
-int main()
-{
-  yycontext ctx;
-  memset(&ctx, 0, sizeof(yycontext));
-  while (yyparse(&ctx));
-  return 0;
-}
--- a/examples/localctx.ref
+++ /dev/null
@@ -1,10 +1,0 @@
-a1 ab1 .
-a2 ac2 .
-a3 ad3 .
-a3 ae3 .
-a4 af4 afg4 .
-a4 af5 afh5 .
-a4 af4 afg4 .
-a4 af5 afh5 .
-af6 afi6 a6 .
-af6 af7 afj7 a6 .
--- /dev/null
+++ b/examples/localleg.leg
@@ -1,0 +1,24 @@
+%{
+#define YY_CTX_LOCAL 1
+#define YY_CTX_MEMBERS \
+  int count;
+%}
+
+Char	= ('\n' | '\r\n' | '\r')	{ yy->count++ }
+	| .
+
+%%
+
+#include <stdio.h>
+#include <string.h>
+
+int main()
+{
+    yycontext yy;
+    memset(&yy, 0, sizeof(yy));
+    while (yyparse(&yy))
+	;
+    printf("%d newlines\n", yy.count);
+    yyrelease(&yy);
+    return 0;
+}
--- /dev/null
+++ b/examples/localleg.ref
@@ -1,0 +1,1 @@
+24 newlines
--- /dev/null
+++ b/examples/localpeg.c
@@ -1,0 +1,13 @@
+#include <stdio.h>
+
+#define YY_CTX_LOCAL
+
+#include "test.peg.c"
+
+int main()
+{
+  yycontext ctx;
+  memset(&ctx, 0, sizeof(yycontext));
+  while (yyparse(&ctx));
+  return 0;
+}
--- /dev/null
+++ b/examples/localpeg.ref
@@ -1,0 +1,10 @@
+a1 ab1 .
+a2 ac2 .
+a3 ad3 .
+a3 ae3 .
+a4 af4 afg4 .
+a4 af5 afh5 .
+a4 af4 afg4 .
+a4 af5 afh5 .
+af6 afi6 a6 .
+af6 af7 afj7 a6 .
--- a/leg.c
+++ /dev/null
@@ -1,1209 +1,0 @@
-/* A recursive-descent parser generated by peg 0.1.9 */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#define YYRULECOUNT 36
-
-# include "tree.h"
-# include "version.h"
-
-# include <stdio.h>
-# include <stdlib.h>
-# include <unistd.h>
-# include <string.h>
-# include <libgen.h>
-# include <assert.h>
-
-  typedef struct Header Header;
-
-  struct Header {
-    char   *text;
-    Header *next;
-  };
-
-  FILE *input= 0;
-
-  int   verboseFlag= 0;
-
-  static int	 lineNumber= 0;
-  static char	*fileName= 0;
-  static char	*trailer= 0;
-  static Header	*headers= 0;
-
-  void makeHeader(char *text);
-  void makeTrailer(char *text);
-
-  void yyerror(char *message);
-
-# define YY_INPUT(buf, result, max)		\
-  {						\
-    int c= getc(input);				\
-    if ('\n' == c || '\r' == c) ++lineNumber;	\
-    result= (EOF == c) ? 0 : (*(buf)= c, 1);	\
-  }
-
-# define YY_LOCAL(T)	static T
-# define YY_RULE(T)	static T
-
-#ifndef YY_LOCAL
-#define YY_LOCAL(T)	static T
-#endif
-#ifndef YY_ACTION
-#define YY_ACTION(T)	static T
-#endif
-#ifndef YY_RULE
-#define YY_RULE(T)	static T
-#endif
-#ifndef YY_PARSE
-#define YY_PARSE(T)	T
-#endif
-#ifndef YYPARSE
-#define YYPARSE		yyparse
-#endif
-#ifndef YYPARSEFROM
-#define YYPARSEFROM	yyparsefrom
-#endif
-#ifndef YY_INPUT
-#define YY_INPUT(buf, result, max_size)			\
-  {							\
-    int yyc= getchar();					\
-    result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1);	\
-    yyprintf((stderr, "<%c>", yyc));			\
-  }
-#endif
-#ifndef YY_BEGIN
-#define YY_BEGIN	( ctx->begin= ctx->pos, 1)
-#endif
-#ifndef YY_END
-#define YY_END		( ctx->end= ctx->pos, 1)
-#endif
-#ifdef YY_DEBUG
-# define yyprintf(args)	fprintf args
-#else
-# define yyprintf(args)
-#endif
-#ifndef YYSTYPE
-#define YYSTYPE	int
-#endif
-
-#ifndef YY_PART
-
-typedef struct _yycontext yycontext;
-typedef void (*yyaction)(yycontext *ctx, char *yytext, int yyleng);
-typedef struct _yythunk { int begin, end;  yyaction  action;  struct _yythunk *next; } yythunk;
-
-struct _yycontext {
-  char     *buf;
-  int       buflen;
-  int       pos;
-  int       limit;
-  char     *text;
-  int       textlen;
-  int       begin;
-  int       end;
-  int       textmax;
-  yythunk  *thunks;
-  int       thunkslen;
-  int       thunkpos;
-  YYSTYPE   yy;
-  YYSTYPE  *val;
-  YYSTYPE  *vals;
-  int       valslen;
-#ifdef YY_CTX_MEMBERS
-  YY_CTX_MEMBERS
-#endif
-};
-
-#ifdef YY_CTX_LOCAL
-#define YY_CTX_PARAM_	yycontext *yyctx,
-#define YY_CTX_PARAM	yycontext *yyctx
-#define YY_CTX_ARG_	yyctx,
-#define YY_CTX_ARG	yyctx
-#else
-#define YY_CTX_PARAM_
-#define YY_CTX_PARAM
-#define YY_CTX_ARG_
-#define YY_CTX_ARG
-yycontext yyctx0;
-yycontext *yyctx= &yyctx0;
-#endif
-
-YY_LOCAL(int) yyrefill(yycontext *ctx)
-{
-  int yyn;
-  while (ctx->buflen - ctx->pos < 512)
-    {
-      ctx->buflen *= 2;
-      ctx->buf= (char *)realloc(ctx->buf, ctx->buflen);
-    }
-  YY_INPUT((ctx->buf + ctx->pos), yyn, (ctx->buflen - ctx->pos));
-  if (!yyn) return 0;
-  ctx->limit += yyn;
-  return 1;
-}
-
-YY_LOCAL(int) yymatchDot(yycontext *ctx)
-{
-  if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;
-  ++ctx->pos;
-  return 1;
-}
-
-YY_LOCAL(int) yymatchChar(yycontext *ctx, int c)
-{
-  if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;
-  if ((unsigned char)ctx->buf[ctx->pos] == c)
-    {
-      ++ctx->pos;
-      yyprintf((stderr, "  ok   yymatchChar(ctx, %c) @ %s\n", c, ctx->buf+ctx->pos));
-      return 1;
-    }
-  yyprintf((stderr, "  fail yymatchChar(ctx, %c) @ %s\n", c, ctx->buf+ctx->pos));
-  return 0;
-}
-
-YY_LOCAL(int) yymatchString(yycontext *ctx, char *s)
-{
-  int yysav= ctx->pos;
-  while (*s)
-    {
-      if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;
-      if (ctx->buf[ctx->pos] != *s)
-        {
-          ctx->pos= yysav;
-          return 0;
-        }
-      ++s;
-      ++ctx->pos;
-    }
-  return 1;
-}
-
-YY_LOCAL(int) yymatchClass(yycontext *ctx, unsigned char *bits)
-{
-  int c;
-  if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;
-  c= (unsigned char)ctx->buf[ctx->pos];
-  if (bits[c >> 3] & (1 << (c & 7)))
-    {
-      ++ctx->pos;
-      yyprintf((stderr, "  ok   yymatchClass @ %s\n", ctx->buf+ctx->pos));
-      return 1;
-    }
-  yyprintf((stderr, "  fail yymatchClass @ %s\n", ctx->buf+ctx->pos));
-  return 0;
-}
-
-YY_LOCAL(void) yyDo(yycontext *ctx, yyaction action, int begin, int end)
-{
-  while (ctx->thunkpos >= ctx->thunkslen)
-    {
-      ctx->thunkslen *= 2;
-      ctx->thunks= (yythunk *)realloc(ctx->thunks, sizeof(yythunk) * ctx->thunkslen);
-    }
-  ctx->thunks[ctx->thunkpos].begin=  begin;
-  ctx->thunks[ctx->thunkpos].end=    end;
-  ctx->thunks[ctx->thunkpos].action= action;
-  ++ctx->thunkpos;
-}
-
-YY_LOCAL(int) yyText(yycontext *ctx, int begin, int end)
-{
-  int yyleng= end - begin;
-  if (yyleng <= 0)
-    yyleng= 0;
-  else
-    {
-      while (ctx->textlen < (yyleng + 1))
-	{
-	  ctx->textlen *= 2;
-	  ctx->text= (char *)realloc(ctx->text, ctx->textlen);
-	}
-      memcpy(ctx->text, ctx->buf + begin, yyleng);
-    }
-  ctx->text[yyleng]= '\0';
-  return yyleng;
-}
-
-YY_LOCAL(void) yyDone(yycontext *ctx)
-{
-  int pos;
-  for (pos= 0;  pos < ctx->thunkpos;  ++pos)
-    {
-      yythunk *thunk= &ctx->thunks[pos];
-      int yyleng= thunk->end ? yyText(ctx, thunk->begin, thunk->end) : thunk->begin;
-      yyprintf((stderr, "DO [%d] %p %s\n", pos, thunk->action, ctx->text));
-      thunk->action(ctx, ctx->text, yyleng);
-    }
-  ctx->thunkpos= 0;
-}
-
-YY_LOCAL(void) yyCommit(yycontext *ctx)
-{
-  if ((ctx->limit -= ctx->pos))
-    {
-      memmove(ctx->buf, ctx->buf + ctx->pos, ctx->limit);
-    }
-  ctx->begin -= ctx->pos;
-  ctx->end -= ctx->pos;
-  ctx->pos= ctx->thunkpos= 0;
-}
-
-YY_LOCAL(int) yyAccept(yycontext *ctx, int tp0)
-{
-  if (tp0)
-    {
-      fprintf(stderr, "accept denied at %d\n", tp0);
-      return 0;
-    }
-  else
-    {
-      yyDone(ctx);
-      yyCommit(ctx);
-    }
-  return 1;
-}
-
-YY_LOCAL(void) yyPush(yycontext *ctx, char *text, int count)  { ctx->val += count; }
-YY_LOCAL(void) yyPop(yycontext *ctx, char *text, int count)   { ctx->val -= count; }
-YY_LOCAL(void) yySet(yycontext *ctx, char *text, int count)   { ctx->val[count]= ctx->yy; }
-
-#endif /* YY_PART */
-
-#define	YYACCEPT	yyAccept(ctx, yythunkpos0)
-
-YY_RULE(int) yy_end_of_line(yycontext *ctx); /* 36 */
-YY_RULE(int) yy_comment(yycontext *ctx); /* 35 */
-YY_RULE(int) yy_space(yycontext *ctx); /* 34 */
-YY_RULE(int) yy_braces(yycontext *ctx); /* 33 */
-YY_RULE(int) yy_range(yycontext *ctx); /* 32 */
-YY_RULE(int) yy_char(yycontext *ctx); /* 31 */
-YY_RULE(int) yy_END(yycontext *ctx); /* 30 */
-YY_RULE(int) yy_BEGIN(yycontext *ctx); /* 29 */
-YY_RULE(int) yy_DOT(yycontext *ctx); /* 28 */
-YY_RULE(int) yy_class(yycontext *ctx); /* 27 */
-YY_RULE(int) yy_literal(yycontext *ctx); /* 26 */
-YY_RULE(int) yy_CLOSE(yycontext *ctx); /* 25 */
-YY_RULE(int) yy_OPEN(yycontext *ctx); /* 24 */
-YY_RULE(int) yy_COLON(yycontext *ctx); /* 23 */
-YY_RULE(int) yy_PLUS(yycontext *ctx); /* 22 */
-YY_RULE(int) yy_STAR(yycontext *ctx); /* 21 */
-YY_RULE(int) yy_QUESTION(yycontext *ctx); /* 20 */
-YY_RULE(int) yy_primary(yycontext *ctx); /* 19 */
-YY_RULE(int) yy_NOT(yycontext *ctx); /* 18 */
-YY_RULE(int) yy_suffix(yycontext *ctx); /* 17 */
-YY_RULE(int) yy_action(yycontext *ctx); /* 16 */
-YY_RULE(int) yy_AND(yycontext *ctx); /* 15 */
-YY_RULE(int) yy_prefix(yycontext *ctx); /* 14 */
-YY_RULE(int) yy_BAR(yycontext *ctx); /* 13 */
-YY_RULE(int) yy_sequence(yycontext *ctx); /* 12 */
-YY_RULE(int) yy_SEMICOLON(yycontext *ctx); /* 11 */
-YY_RULE(int) yy_expression(yycontext *ctx); /* 10 */
-YY_RULE(int) yy_EQUAL(yycontext *ctx); /* 9 */
-YY_RULE(int) yy_identifier(yycontext *ctx); /* 8 */
-YY_RULE(int) yy_RPERCENT(yycontext *ctx); /* 7 */
-YY_RULE(int) yy_end_of_file(yycontext *ctx); /* 6 */
-YY_RULE(int) yy_trailer(yycontext *ctx); /* 5 */
-YY_RULE(int) yy_definition(yycontext *ctx); /* 4 */
-YY_RULE(int) yy_declaration(yycontext *ctx); /* 3 */
-YY_RULE(int) yy__(yycontext *ctx); /* 2 */
-YY_RULE(int) yy_grammar(yycontext *ctx); /* 1 */
-
-YY_ACTION(void) yy_9_primary(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_9_primary\n"));
-   push(makePredicate("YY_END")); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_8_primary(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_8_primary\n"));
-   push(makePredicate("YY_BEGIN")); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_7_primary(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_7_primary\n"));
-   push(makeAction(yytext)); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_6_primary(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_6_primary\n"));
-   push(makeDot()); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_5_primary(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_5_primary\n"));
-   push(makeClass(yytext)); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_4_primary(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_4_primary\n"));
-   push(makeString(yytext)); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_3_primary(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_3_primary\n"));
-   push(makeName(findRule(yytext))); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_2_primary(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_2_primary\n"));
-   Node *name= makeName(findRule(yytext));  name->name.variable= pop();  push(name); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_1_primary(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_1_primary\n"));
-   push(makeVariable(yytext)); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_3_suffix(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_3_suffix\n"));
-   push(makePlus (pop())); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_2_suffix(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_2_suffix\n"));
-   push(makeStar (pop())); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_1_suffix(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_1_suffix\n"));
-   push(makeQuery(pop())); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_3_prefix(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_3_prefix\n"));
-   push(makePeekNot(pop())); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_2_prefix(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_2_prefix\n"));
-   push(makePeekFor(pop())); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_1_prefix(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_1_prefix\n"));
-   push(makePredicate(yytext)); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_1_sequence(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_1_sequence\n"));
-   Node *f= pop();  push(Sequence_append(pop(), f)); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_1_expression(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_1_expression\n"));
-   Node *f= pop();  push(Alternate_append(pop(), f)); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_2_definition(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_2_definition\n"));
-   Node *e= pop();  Rule_setExpression(pop(), e); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_1_definition(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_1_definition\n"));
-   if (push(beginRule(findRule(yytext)))->rule.expression)
-							    fprintf(stderr, "rule '%s' redefined\n", yytext); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_1_trailer(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_1_trailer\n"));
-   makeTrailer(yytext); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_1_declaration(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_1_declaration\n"));
-   makeHeader(yytext); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-
-YY_RULE(int) yy_end_of_line(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "end_of_line"));
-  {  int yypos2= ctx->pos, yythunkpos2= ctx->thunkpos;  if (!yymatchString(ctx, "\r\n")) goto l3;  goto l2;
-  l3:;	  ctx->pos= yypos2; ctx->thunkpos= yythunkpos2;  if (!yymatchChar(ctx, '\n')) goto l4;  goto l2;
-  l4:;	  ctx->pos= yypos2; ctx->thunkpos= yythunkpos2;  if (!yymatchChar(ctx, '\r')) goto l1;
-  }
-  l2:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "end_of_line", ctx->buf+ctx->pos));
-  return 1;
-  l1:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "end_of_line", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_comment(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "comment"));  if (!yymatchChar(ctx, '#')) goto l5;
-  l6:;	
-  {  int yypos7= ctx->pos, yythunkpos7= ctx->thunkpos;
-  {  int yypos8= ctx->pos, yythunkpos8= ctx->thunkpos;  if (!yy_end_of_line(ctx)) goto l8;  goto l7;
-  l8:;	  ctx->pos= yypos8; ctx->thunkpos= yythunkpos8;
-  }  if (!yymatchDot(ctx)) goto l7;  goto l6;
-  l7:;	  ctx->pos= yypos7; ctx->thunkpos= yythunkpos7;
-  }  if (!yy_end_of_line(ctx)) goto l5;
-  yyprintf((stderr, "  ok   %s @ %s\n", "comment", ctx->buf+ctx->pos));
-  return 1;
-  l5:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "comment", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_space(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "space"));
-  {  int yypos10= ctx->pos, yythunkpos10= ctx->thunkpos;  if (!yymatchChar(ctx, ' ')) goto l11;  goto l10;
-  l11:;	  ctx->pos= yypos10; ctx->thunkpos= yythunkpos10;  if (!yymatchChar(ctx, '\t')) goto l12;  goto l10;
-  l12:;	  ctx->pos= yypos10; ctx->thunkpos= yythunkpos10;  if (!yy_end_of_line(ctx)) goto l9;
-  }
-  l10:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "space", ctx->buf+ctx->pos));
-  return 1;
-  l9:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "space", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_braces(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "braces"));
-  {  int yypos14= ctx->pos, yythunkpos14= ctx->thunkpos;  if (!yymatchChar(ctx, '{')) goto l15;
-  l16:;	
-  {  int yypos17= ctx->pos, yythunkpos17= ctx->thunkpos;  if (!yy_braces(ctx)) goto l17;  goto l16;
-  l17:;	  ctx->pos= yypos17; ctx->thunkpos= yythunkpos17;
-  }  if (!yymatchChar(ctx, '}')) goto l15;  goto l14;
-  l15:;	  ctx->pos= yypos14; ctx->thunkpos= yythunkpos14;
-  {  int yypos18= ctx->pos, yythunkpos18= ctx->thunkpos;  if (!yymatchChar(ctx, '}')) goto l18;  goto l13;
-  l18:;	  ctx->pos= yypos18; ctx->thunkpos= yythunkpos18;
-  }  if (!yymatchDot(ctx)) goto l13;
-  }
-  l14:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "braces", ctx->buf+ctx->pos));
-  return 1;
-  l13:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "braces", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_range(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "range"));
-  {  int yypos20= ctx->pos, yythunkpos20= ctx->thunkpos;  if (!yy_char(ctx)) goto l21;  if (!yymatchChar(ctx, '-')) goto l21;  if (!yy_char(ctx)) goto l21;  goto l20;
-  l21:;	  ctx->pos= yypos20; ctx->thunkpos= yythunkpos20;  if (!yy_char(ctx)) goto l19;
-  }
-  l20:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "range", ctx->buf+ctx->pos));
-  return 1;
-  l19:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "range", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_char(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "char"));
-  {  int yypos23= ctx->pos, yythunkpos23= ctx->thunkpos;  if (!yymatchChar(ctx, '\\')) goto l24;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\204\040\000\000\000\000\000\070\146\100\124\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l24;  goto l23;
-  l24:;	  ctx->pos= yypos23; ctx->thunkpos= yythunkpos23;  if (!yymatchChar(ctx, '\\')) goto l25;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l25;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l25;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l25;  goto l23;
-  l25:;	  ctx->pos= yypos23; ctx->thunkpos= yythunkpos23;  if (!yymatchChar(ctx, '\\')) goto l26;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l26;
-  {  int yypos27= ctx->pos, yythunkpos27= ctx->thunkpos;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l27;  goto l28;
-  l27:;	  ctx->pos= yypos27; ctx->thunkpos= yythunkpos27;
-  }
-  l28:;	  goto l23;
-  l26:;	  ctx->pos= yypos23; ctx->thunkpos= yythunkpos23;
-  {  int yypos29= ctx->pos, yythunkpos29= ctx->thunkpos;  if (!yymatchChar(ctx, '\\')) goto l29;  goto l22;
-  l29:;	  ctx->pos= yypos29; ctx->thunkpos= yythunkpos29;
-  }  if (!yymatchDot(ctx)) goto l22;
-  }
-  l23:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "char", ctx->buf+ctx->pos));
-  return 1;
-  l22:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "char", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_END(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "END"));  if (!yymatchChar(ctx, '>')) goto l30;  if (!yy__(ctx)) goto l30;
-  yyprintf((stderr, "  ok   %s @ %s\n", "END", ctx->buf+ctx->pos));
-  return 1;
-  l30:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "END", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_BEGIN(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "BEGIN"));  if (!yymatchChar(ctx, '<')) goto l31;  if (!yy__(ctx)) goto l31;
-  yyprintf((stderr, "  ok   %s @ %s\n", "BEGIN", ctx->buf+ctx->pos));
-  return 1;
-  l31:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "BEGIN", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_DOT(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "DOT"));  if (!yymatchChar(ctx, '.')) goto l32;  if (!yy__(ctx)) goto l32;
-  yyprintf((stderr, "  ok   %s @ %s\n", "DOT", ctx->buf+ctx->pos));
-  return 1;
-  l32:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "DOT", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_class(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "class"));  if (!yymatchChar(ctx, '[')) goto l33;  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_BEGIN)) goto l33;
-  l34:;	
-  {  int yypos35= ctx->pos, yythunkpos35= ctx->thunkpos;
-  {  int yypos36= ctx->pos, yythunkpos36= ctx->thunkpos;  if (!yymatchChar(ctx, ']')) goto l36;  goto l35;
-  l36:;	  ctx->pos= yypos36; ctx->thunkpos= yythunkpos36;
-  }  if (!yy_range(ctx)) goto l35;  goto l34;
-  l35:;	  ctx->pos= yypos35; ctx->thunkpos= yythunkpos35;
-  }  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_END)) goto l33;  if (!yymatchChar(ctx, ']')) goto l33;  if (!yy__(ctx)) goto l33;
-  yyprintf((stderr, "  ok   %s @ %s\n", "class", ctx->buf+ctx->pos));
-  return 1;
-  l33:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "class", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_literal(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "literal"));
-  {  int yypos38= ctx->pos, yythunkpos38= ctx->thunkpos;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l39;  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_BEGIN)) goto l39;
-  l40:;	
-  {  int yypos41= ctx->pos, yythunkpos41= ctx->thunkpos;
-  {  int yypos42= ctx->pos, yythunkpos42= ctx->thunkpos;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l42;  goto l41;
-  l42:;	  ctx->pos= yypos42; ctx->thunkpos= yythunkpos42;
-  }  if (!yy_char(ctx)) goto l41;  goto l40;
-  l41:;	  ctx->pos= yypos41; ctx->thunkpos= yythunkpos41;
-  }  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_END)) goto l39;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l39;  if (!yy__(ctx)) goto l39;  goto l38;
-  l39:;	  ctx->pos= yypos38; ctx->thunkpos= yythunkpos38;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l37;  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_BEGIN)) goto l37;
-  l43:;	
-  {  int yypos44= ctx->pos, yythunkpos44= ctx->thunkpos;
-  {  int yypos45= ctx->pos, yythunkpos45= ctx->thunkpos;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l45;  goto l44;
-  l45:;	  ctx->pos= yypos45; ctx->thunkpos= yythunkpos45;
-  }  if (!yy_char(ctx)) goto l44;  goto l43;
-  l44:;	  ctx->pos= yypos44; ctx->thunkpos= yythunkpos44;
-  }  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_END)) goto l37;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l37;  if (!yy__(ctx)) goto l37;
-  }
-  l38:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "literal", ctx->buf+ctx->pos));
-  return 1;
-  l37:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "literal", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_CLOSE(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "CLOSE"));  if (!yymatchChar(ctx, ')')) goto l46;  if (!yy__(ctx)) goto l46;
-  yyprintf((stderr, "  ok   %s @ %s\n", "CLOSE", ctx->buf+ctx->pos));
-  return 1;
-  l46:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "CLOSE", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_OPEN(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "OPEN"));  if (!yymatchChar(ctx, '(')) goto l47;  if (!yy__(ctx)) goto l47;
-  yyprintf((stderr, "  ok   %s @ %s\n", "OPEN", ctx->buf+ctx->pos));
-  return 1;
-  l47:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "OPEN", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_COLON(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "COLON"));  if (!yymatchChar(ctx, ':')) goto l48;  if (!yy__(ctx)) goto l48;
-  yyprintf((stderr, "  ok   %s @ %s\n", "COLON", ctx->buf+ctx->pos));
-  return 1;
-  l48:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "COLON", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_PLUS(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "PLUS"));  if (!yymatchChar(ctx, '+')) goto l49;  if (!yy__(ctx)) goto l49;
-  yyprintf((stderr, "  ok   %s @ %s\n", "PLUS", ctx->buf+ctx->pos));
-  return 1;
-  l49:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "PLUS", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_STAR(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "STAR"));  if (!yymatchChar(ctx, '*')) goto l50;  if (!yy__(ctx)) goto l50;
-  yyprintf((stderr, "  ok   %s @ %s\n", "STAR", ctx->buf+ctx->pos));
-  return 1;
-  l50:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "STAR", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_QUESTION(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "QUESTION"));  if (!yymatchChar(ctx, '?')) goto l51;  if (!yy__(ctx)) goto l51;
-  yyprintf((stderr, "  ok   %s @ %s\n", "QUESTION", ctx->buf+ctx->pos));
-  return 1;
-  l51:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "QUESTION", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_primary(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "primary"));
-  {  int yypos53= ctx->pos, yythunkpos53= ctx->thunkpos;  if (!yy_identifier(ctx)) goto l54;  yyDo(ctx, yy_1_primary, ctx->begin, ctx->end);  if (!yy_COLON(ctx)) goto l54;  if (!yy_identifier(ctx)) goto l54;
-  {  int yypos55= ctx->pos, yythunkpos55= ctx->thunkpos;  if (!yy_EQUAL(ctx)) goto l55;  goto l54;
-  l55:;	  ctx->pos= yypos55; ctx->thunkpos= yythunkpos55;
-  }  yyDo(ctx, yy_2_primary, ctx->begin, ctx->end);  goto l53;
-  l54:;	  ctx->pos= yypos53; ctx->thunkpos= yythunkpos53;  if (!yy_identifier(ctx)) goto l56;
-  {  int yypos57= ctx->pos, yythunkpos57= ctx->thunkpos;  if (!yy_EQUAL(ctx)) goto l57;  goto l56;
-  l57:;	  ctx->pos= yypos57; ctx->thunkpos= yythunkpos57;
-  }  yyDo(ctx, yy_3_primary, ctx->begin, ctx->end);  goto l53;
-  l56:;	  ctx->pos= yypos53; ctx->thunkpos= yythunkpos53;  if (!yy_OPEN(ctx)) goto l58;  if (!yy_expression(ctx)) goto l58;  if (!yy_CLOSE(ctx)) goto l58;  goto l53;
-  l58:;	  ctx->pos= yypos53; ctx->thunkpos= yythunkpos53;  if (!yy_literal(ctx)) goto l59;  yyDo(ctx, yy_4_primary, ctx->begin, ctx->end);  goto l53;
-  l59:;	  ctx->pos= yypos53; ctx->thunkpos= yythunkpos53;  if (!yy_class(ctx)) goto l60;  yyDo(ctx, yy_5_primary, ctx->begin, ctx->end);  goto l53;
-  l60:;	  ctx->pos= yypos53; ctx->thunkpos= yythunkpos53;  if (!yy_DOT(ctx)) goto l61;  yyDo(ctx, yy_6_primary, ctx->begin, ctx->end);  goto l53;
-  l61:;	  ctx->pos= yypos53; ctx->thunkpos= yythunkpos53;  if (!yy_action(ctx)) goto l62;  yyDo(ctx, yy_7_primary, ctx->begin, ctx->end);  goto l53;
-  l62:;	  ctx->pos= yypos53; ctx->thunkpos= yythunkpos53;  if (!yy_BEGIN(ctx)) goto l63;  yyDo(ctx, yy_8_primary, ctx->begin, ctx->end);  goto l53;
-  l63:;	  ctx->pos= yypos53; ctx->thunkpos= yythunkpos53;  if (!yy_END(ctx)) goto l52;  yyDo(ctx, yy_9_primary, ctx->begin, ctx->end);
-  }
-  l53:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "primary", ctx->buf+ctx->pos));
-  return 1;
-  l52:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "primary", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_NOT(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "NOT"));  if (!yymatchChar(ctx, '!')) goto l64;  if (!yy__(ctx)) goto l64;
-  yyprintf((stderr, "  ok   %s @ %s\n", "NOT", ctx->buf+ctx->pos));
-  return 1;
-  l64:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "NOT", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_suffix(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "suffix"));  if (!yy_primary(ctx)) goto l65;
-  {  int yypos66= ctx->pos, yythunkpos66= ctx->thunkpos;
-  {  int yypos68= ctx->pos, yythunkpos68= ctx->thunkpos;  if (!yy_QUESTION(ctx)) goto l69;  yyDo(ctx, yy_1_suffix, ctx->begin, ctx->end);  goto l68;
-  l69:;	  ctx->pos= yypos68; ctx->thunkpos= yythunkpos68;  if (!yy_STAR(ctx)) goto l70;  yyDo(ctx, yy_2_suffix, ctx->begin, ctx->end);  goto l68;
-  l70:;	  ctx->pos= yypos68; ctx->thunkpos= yythunkpos68;  if (!yy_PLUS(ctx)) goto l66;  yyDo(ctx, yy_3_suffix, ctx->begin, ctx->end);
-  }
-  l68:;	  goto l67;
-  l66:;	  ctx->pos= yypos66; ctx->thunkpos= yythunkpos66;
-  }
-  l67:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "suffix", ctx->buf+ctx->pos));
-  return 1;
-  l65:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "suffix", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_action(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "action"));  if (!yymatchChar(ctx, '{')) goto l71;  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_BEGIN)) goto l71;
-  l72:;	
-  {  int yypos73= ctx->pos, yythunkpos73= ctx->thunkpos;  if (!yy_braces(ctx)) goto l73;  goto l72;
-  l73:;	  ctx->pos= yypos73; ctx->thunkpos= yythunkpos73;
-  }  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_END)) goto l71;  if (!yymatchChar(ctx, '}')) goto l71;  if (!yy__(ctx)) goto l71;
-  yyprintf((stderr, "  ok   %s @ %s\n", "action", ctx->buf+ctx->pos));
-  return 1;
-  l71:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "action", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_AND(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "AND"));  if (!yymatchChar(ctx, '&')) goto l74;  if (!yy__(ctx)) goto l74;
-  yyprintf((stderr, "  ok   %s @ %s\n", "AND", ctx->buf+ctx->pos));
-  return 1;
-  l74:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "AND", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_prefix(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "prefix"));
-  {  int yypos76= ctx->pos, yythunkpos76= ctx->thunkpos;  if (!yy_AND(ctx)) goto l77;  if (!yy_action(ctx)) goto l77;  yyDo(ctx, yy_1_prefix, ctx->begin, ctx->end);  goto l76;
-  l77:;	  ctx->pos= yypos76; ctx->thunkpos= yythunkpos76;  if (!yy_AND(ctx)) goto l78;  if (!yy_suffix(ctx)) goto l78;  yyDo(ctx, yy_2_prefix, ctx->begin, ctx->end);  goto l76;
-  l78:;	  ctx->pos= yypos76; ctx->thunkpos= yythunkpos76;  if (!yy_NOT(ctx)) goto l79;  if (!yy_suffix(ctx)) goto l79;  yyDo(ctx, yy_3_prefix, ctx->begin, ctx->end);  goto l76;
-  l79:;	  ctx->pos= yypos76; ctx->thunkpos= yythunkpos76;  if (!yy_suffix(ctx)) goto l75;
-  }
-  l76:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "prefix", ctx->buf+ctx->pos));
-  return 1;
-  l75:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "prefix", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_BAR(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "BAR"));  if (!yymatchChar(ctx, '|')) goto l80;  if (!yy__(ctx)) goto l80;
-  yyprintf((stderr, "  ok   %s @ %s\n", "BAR", ctx->buf+ctx->pos));
-  return 1;
-  l80:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "BAR", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_sequence(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "sequence"));  if (!yy_prefix(ctx)) goto l81;
-  l82:;	
-  {  int yypos83= ctx->pos, yythunkpos83= ctx->thunkpos;  if (!yy_prefix(ctx)) goto l83;  yyDo(ctx, yy_1_sequence, ctx->begin, ctx->end);  goto l82;
-  l83:;	  ctx->pos= yypos83; ctx->thunkpos= yythunkpos83;
-  }
-  yyprintf((stderr, "  ok   %s @ %s\n", "sequence", ctx->buf+ctx->pos));
-  return 1;
-  l81:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "sequence", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_SEMICOLON(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "SEMICOLON"));  if (!yymatchChar(ctx, ';')) goto l84;  if (!yy__(ctx)) goto l84;
-  yyprintf((stderr, "  ok   %s @ %s\n", "SEMICOLON", ctx->buf+ctx->pos));
-  return 1;
-  l84:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "SEMICOLON", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_expression(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "expression"));  if (!yy_sequence(ctx)) goto l85;
-  l86:;	
-  {  int yypos87= ctx->pos, yythunkpos87= ctx->thunkpos;  if (!yy_BAR(ctx)) goto l87;  if (!yy_sequence(ctx)) goto l87;  yyDo(ctx, yy_1_expression, ctx->begin, ctx->end);  goto l86;
-  l87:;	  ctx->pos= yypos87; ctx->thunkpos= yythunkpos87;
-  }
-  yyprintf((stderr, "  ok   %s @ %s\n", "expression", ctx->buf+ctx->pos));
-  return 1;
-  l85:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "expression", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_EQUAL(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "EQUAL"));  if (!yymatchChar(ctx, '=')) goto l88;  if (!yy__(ctx)) goto l88;
-  yyprintf((stderr, "  ok   %s @ %s\n", "EQUAL", ctx->buf+ctx->pos));
-  return 1;
-  l88:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "EQUAL", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_identifier(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "identifier"));  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_BEGIN)) goto l89;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\040\000\000\376\377\377\207\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l89;
-  l90:;	
-  {  int yypos91= ctx->pos, yythunkpos91= ctx->thunkpos;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\040\377\003\376\377\377\207\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l91;  goto l90;
-  l91:;	  ctx->pos= yypos91; ctx->thunkpos= yythunkpos91;
-  }  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_END)) goto l89;  if (!yy__(ctx)) goto l89;
-  yyprintf((stderr, "  ok   %s @ %s\n", "identifier", ctx->buf+ctx->pos));
-  return 1;
-  l89:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "identifier", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_RPERCENT(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "RPERCENT"));  if (!yymatchString(ctx, "%}")) goto l92;  if (!yy__(ctx)) goto l92;
-  yyprintf((stderr, "  ok   %s @ %s\n", "RPERCENT", ctx->buf+ctx->pos));
-  return 1;
-  l92:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "RPERCENT", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_end_of_file(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "end_of_file"));
-  {  int yypos94= ctx->pos, yythunkpos94= ctx->thunkpos;  if (!yymatchDot(ctx)) goto l94;  goto l93;
-  l94:;	  ctx->pos= yypos94; ctx->thunkpos= yythunkpos94;
-  }
-  yyprintf((stderr, "  ok   %s @ %s\n", "end_of_file", ctx->buf+ctx->pos));
-  return 1;
-  l93:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "end_of_file", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_trailer(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "trailer"));  if (!yymatchString(ctx, "%%")) goto l95;  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_BEGIN)) goto l95;
-  l96:;	
-  {  int yypos97= ctx->pos, yythunkpos97= ctx->thunkpos;  if (!yymatchDot(ctx)) goto l97;  goto l96;
-  l97:;	  ctx->pos= yypos97; ctx->thunkpos= yythunkpos97;
-  }  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_END)) goto l95;  yyDo(ctx, yy_1_trailer, ctx->begin, ctx->end);
-  yyprintf((stderr, "  ok   %s @ %s\n", "trailer", ctx->buf+ctx->pos));
-  return 1;
-  l95:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "trailer", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_definition(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "definition"));  if (!yy_identifier(ctx)) goto l98;  yyDo(ctx, yy_1_definition, ctx->begin, ctx->end);  if (!yy_EQUAL(ctx)) goto l98;  if (!yy_expression(ctx)) goto l98;  yyDo(ctx, yy_2_definition, ctx->begin, ctx->end);
-  {  int yypos99= ctx->pos, yythunkpos99= ctx->thunkpos;  if (!yy_SEMICOLON(ctx)) goto l99;  goto l100;
-  l99:;	  ctx->pos= yypos99; ctx->thunkpos= yythunkpos99;
-  }
-  l100:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "definition", ctx->buf+ctx->pos));
-  return 1;
-  l98:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "definition", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_declaration(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "declaration"));  if (!yymatchString(ctx, "%{")) goto l101;  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_BEGIN)) goto l101;
-  l102:;	
-  {  int yypos103= ctx->pos, yythunkpos103= ctx->thunkpos;
-  {  int yypos104= ctx->pos, yythunkpos104= ctx->thunkpos;  if (!yymatchString(ctx, "%}")) goto l104;  goto l103;
-  l104:;	  ctx->pos= yypos104; ctx->thunkpos= yythunkpos104;
-  }  if (!yymatchDot(ctx)) goto l103;  goto l102;
-  l103:;	  ctx->pos= yypos103; ctx->thunkpos= yythunkpos103;
-  }  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_END)) goto l101;  if (!yy_RPERCENT(ctx)) goto l101;  yyDo(ctx, yy_1_declaration, ctx->begin, ctx->end);
-  yyprintf((stderr, "  ok   %s @ %s\n", "declaration", ctx->buf+ctx->pos));
-  return 1;
-  l101:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "declaration", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy__(yycontext *ctx)
-{
-  yyprintf((stderr, "%s\n", "_"));
-  l106:;	
-  {  int yypos107= ctx->pos, yythunkpos107= ctx->thunkpos;
-  {  int yypos108= ctx->pos, yythunkpos108= ctx->thunkpos;  if (!yy_space(ctx)) goto l109;  goto l108;
-  l109:;	  ctx->pos= yypos108; ctx->thunkpos= yythunkpos108;  if (!yy_comment(ctx)) goto l107;
-  }
-  l108:;	  goto l106;
-  l107:;	  ctx->pos= yypos107; ctx->thunkpos= yythunkpos107;
-  }
-  yyprintf((stderr, "  ok   %s @ %s\n", "_", ctx->buf+ctx->pos));
-  return 1;
-}
-YY_RULE(int) yy_grammar(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "grammar"));  if (!yy__(ctx)) goto l110;
-  {  int yypos113= ctx->pos, yythunkpos113= ctx->thunkpos;  if (!yy_declaration(ctx)) goto l114;  goto l113;
-  l114:;	  ctx->pos= yypos113; ctx->thunkpos= yythunkpos113;  if (!yy_definition(ctx)) goto l110;
-  }
-  l113:;	
-  l111:;	
-  {  int yypos112= ctx->pos, yythunkpos112= ctx->thunkpos;
-  {  int yypos115= ctx->pos, yythunkpos115= ctx->thunkpos;  if (!yy_declaration(ctx)) goto l116;  goto l115;
-  l116:;	  ctx->pos= yypos115; ctx->thunkpos= yythunkpos115;  if (!yy_definition(ctx)) goto l112;
-  }
-  l115:;	  goto l111;
-  l112:;	  ctx->pos= yypos112; ctx->thunkpos= yythunkpos112;
-  }
-  {  int yypos117= ctx->pos, yythunkpos117= ctx->thunkpos;  if (!yy_trailer(ctx)) goto l117;  goto l118;
-  l117:;	  ctx->pos= yypos117; ctx->thunkpos= yythunkpos117;
-  }
-  l118:;	  if (!yy_end_of_file(ctx)) goto l110;
-  yyprintf((stderr, "  ok   %s @ %s\n", "grammar", ctx->buf+ctx->pos));
-  return 1;
-  l110:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "grammar", ctx->buf+ctx->pos));
-  return 0;
-}
-
-#ifndef YY_PART
-
-typedef int (*yyrule)(yycontext *ctx);
-
-YY_PARSE(int) YYPARSEFROM(YY_CTX_PARAM_ yyrule yystart)
-{
-  int yyok;
-  if (!yyctx->buflen)
-    {
-      yyctx->buflen= 1024;
-      yyctx->buf= (char *)malloc(yyctx->buflen);
-      yyctx->textlen= 1024;
-      yyctx->text= (char *)malloc(yyctx->textlen);
-      yyctx->thunkslen= 32;
-      yyctx->thunks= (yythunk *)malloc(sizeof(yythunk) * yyctx->thunkslen);
-      yyctx->valslen= 32;
-      yyctx->vals= (YYSTYPE *)malloc(sizeof(YYSTYPE) * yyctx->valslen);
-      yyctx->begin= yyctx->end= yyctx->pos= yyctx->limit= yyctx->thunkpos= 0;
-    }
-  yyctx->begin= yyctx->end= yyctx->pos;
-  yyctx->thunkpos= 0;
-  yyctx->val= yyctx->vals;
-  yyok= yystart(yyctx);
-  if (yyok) yyDone(yyctx);
-  yyCommit(yyctx);
-  return yyok;
-}
-
-YY_PARSE(int) YYPARSE(YY_CTX_PARAM)
-{
-  return YYPARSEFROM(YY_CTX_ARG_ yy_grammar);
-}
-
-#endif
-
-
-void yyerror(char *message)
-{
-  fprintf(stderr, "%s:%d: %s", fileName, lineNumber, message);
-  if (yyctx->text[0]) fprintf(stderr, " near token '%s'", yyctx->text);
-  if (yyctx->pos < yyctx->limit || !feof(input))
-    {
-      yyctx->buf[yyctx->limit]= '\0';
-      fprintf(stderr, " before text \"");
-      while (yyctx->pos < yyctx->limit)
-	{
-	  if ('\n' == yyctx->buf[yyctx->pos] || '\r' == yyctx->buf[yyctx->pos]) break;
-	  fputc(yyctx->buf[yyctx->pos++], stderr);
-	}
-      if (yyctx->pos == yyctx->limit)
-	{
-	  int c;
-	  while (EOF != (c= fgetc(input)) && '\n' != c && '\r' != c)
-	    fputc(c, stderr);
-	}
-      fputc('\"', stderr);
-    }
-  fprintf(stderr, "\n");
-  exit(1);
-}
-
-void makeHeader(char *text)
-{
-  Header *header= (Header *)malloc(sizeof(Header));
-  header->text= strdup(text);
-  header->next= headers;
-  headers= header;
-}
-
-void makeTrailer(char *text)
-{
-  trailer= strdup(text);
-}
-
-static void version(char *name)
-{
-  printf("%s version %d.%d.%d\n", name, PEG_MAJOR, PEG_MINOR, PEG_LEVEL);
-}
-
-static void usage(char *name)
-{
-  version(name);
-  fprintf(stderr, "usage: %s [<option>...] [<file>...]\n", name);
-  fprintf(stderr, "where <option> can be\n");
-  fprintf(stderr, "  -h          print this help information\n");
-  fprintf(stderr, "  -o <ofile>  write output to <ofile>\n");
-  fprintf(stderr, "  -v          be verbose\n");
-  fprintf(stderr, "  -V          print version number and exit\n");
-  fprintf(stderr, "if no <file> is given, input is read from stdin\n");
-  fprintf(stderr, "if no <ofile> is given, output is written to stdout\n");
-  exit(1);
-}
-
-int main(int argc, char **argv)
-{
-  Node *n;
-  int   c;
-
-  output= stdout;
-  input= stdin;
-  lineNumber= 1;
-  fileName= "<stdin>";
-
-  while (-1 != (c= getopt(argc, argv, "Vho:v")))
-    {
-      switch (c)
-	{
-	case 'V':
-	  version(basename(argv[0]));
-	  exit(0);
-
-	case 'h':
-	  usage(basename(argv[0]));
-	  break;
-
-	case 'o':
-	  if (!(output= fopen(optarg, "w")))
-	    {
-	      perror(optarg);
-	      exit(1);
-	    }
-	  break;
-
-	case 'v':
-	  verboseFlag= 1;
-	  break;
-
-	default:
-	  fprintf(stderr, "for usage try: %s -h\n", argv[0]);
-	  exit(1);
-	}
-    }
-  argc -= optind;
-  argv += optind;
-
-  if (argc)
-    {
-      for (;  argc;  --argc, ++argv)
-	{
-	  if (!strcmp(*argv, "-"))
-	    {
-	      input= stdin;
-	      fileName= "<stdin>";
-	    }
-	  else
-	    {
-	      if (!(input= fopen(*argv, "r")))
-		{
-		  perror(*argv);
-		  exit(1);
-		}
-	      fileName= *argv;
-	    }
-	  lineNumber= 1;
-	  if (!yyparse())
-	    yyerror("syntax error");
-	  if (input != stdin)
-	    fclose(input);
-	}
-    }
-  else
-    if (!yyparse())
-      yyerror("syntax error");
-
-  if (verboseFlag)
-    for (n= rules;  n;  n= n->any.next)
-      Rule_print(n);
-
-  Rule_compile_c_header();
-
-  for (; headers;  headers= headers->next)
-    fprintf(output, "%s\n", headers->text);
-
-  if (rules)
-    Rule_compile_c(rules);
-
-  if (trailer)
-    fprintf(output, "%s\n", trailer);
-
-  return 0;
-}
-
--- a/leg.leg
+++ /dev/null
@@ -1,292 +1,0 @@
-# LE Grammar for LE Grammars
-# 
-# Copyright (c) 2007 by Ian Piumarta
-# All rights reserved.
-# 
-# Permission is hereby granted, free of charge, to any person obtaining a
-# copy of this software and associated documentation files (the 'Software'),
-# to deal in the Software without restriction, including without limitation
-# the rights to use, copy, modify, merge, publish, distribute, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, provided that the above copyright notice(s) and this
-# permission notice appear in all copies of the Software.  Acknowledgement
-# of the use of this Software in supporting documentation would be
-# appreciated but is not required.
-# 
-# THE SOFTWARE IS PROVIDED 'AS IS'.  USE ENTIRELY AT YOUR OWN RISK.
-# 
-# Last edited: 2012-04-29 15:51:15 by piumarta on emilia
-
-%{
-# include "tree.h"
-# include "version.h"
-
-# include <stdio.h>
-# include <stdlib.h>
-# include <unistd.h>
-# include <string.h>
-# include <libgen.h>
-# include <assert.h>
-
-  typedef struct Header Header;
-
-  struct Header {
-    char   *text;
-    Header *next;
-  };
-
-  FILE *input= 0;
-
-  int   verboseFlag= 0;
-
-  static int	 lineNumber= 0;
-  static char	*fileName= 0;
-  static char	*trailer= 0;
-  static Header	*headers= 0;
-
-  void makeHeader(char *text);
-  void makeTrailer(char *text);
-
-  void yyerror(char *message);
-
-# define YY_INPUT(buf, result, max)		\
-  {						\
-    int c= getc(input);				\
-    if ('\n' == c || '\r' == c) ++lineNumber;	\
-    result= (EOF == c) ? 0 : (*(buf)= c, 1);	\
-  }
-
-# define YY_LOCAL(T)	static T
-# define YY_RULE(T)	static T
-%}
-
-# Hierarchical syntax
-
-grammar=	- ( declaration | definition )+ trailer? end-of-file
-
-declaration=	'%{' < ( !'%}' . )* > RPERCENT		{ makeHeader(yytext); }						#{YYACCEPT}
-
-trailer=	'%%' < .* >				{ makeTrailer(yytext); }					#{YYACCEPT}
-
-definition=	identifier 				{ if (push(beginRule(findRule(yytext)))->rule.expression)
-							    fprintf(stderr, "rule '%s' redefined\n", yytext); }
-			EQUAL expression		{ Node *e= pop();  Rule_setExpression(pop(), e); }
-			SEMICOLON?											#{YYACCEPT}
-
-expression=	sequence (BAR sequence			{ Node *f= pop();  push(Alternate_append(pop(), f)); }
-			    )*
-
-sequence=	prefix (prefix				{ Node *f= pop();  push(Sequence_append(pop(), f)); }
-			  )*
-
-prefix=		AND action				{ push(makePredicate(yytext)); }
-|		AND suffix				{ push(makePeekFor(pop())); }
-|		NOT suffix				{ push(makePeekNot(pop())); }
-|		    suffix
-
-suffix=		primary (QUESTION			{ push(makeQuery(pop())); }
-			     | STAR			{ push(makeStar (pop())); }
-			     | PLUS			{ push(makePlus (pop())); }
-			   )?
-
-primary=	identifier				{ push(makeVariable(yytext)); }
-			COLON identifier !EQUAL		{ Node *name= makeName(findRule(yytext));  name->name.variable= pop();  push(name); }
-|		identifier !EQUAL			{ push(makeName(findRule(yytext))); }
-|		OPEN expression CLOSE
-|		literal					{ push(makeString(yytext)); }
-|		class					{ push(makeClass(yytext)); }
-|		DOT					{ push(makeDot()); }
-|		action					{ push(makeAction(yytext)); }
-|		BEGIN					{ push(makePredicate("YY_BEGIN")); }
-|		END					{ push(makePredicate("YY_END")); }
-
-# Lexical syntax
-
-identifier=	< [-a-zA-Z_][-a-zA-Z_0-9]* > -
-
-literal=	['] < ( !['] char )* > ['] -
-|		["] < ( !["] char )* > ["] -
-
-class=		'[' < ( !']' range )* > ']' -
-
-range=		char '-' char | char
-
-char=		'\\' [-abefnrtv'"\[\]\\]
-|		'\\' [0-3][0-7][0-7]
-|		'\\' [0-7][0-7]?
-|		!'\\' .
-
-action=		'{' < braces* > '}' -
-
-braces=		'{' braces* '}'
-|		!'}' .
-
-EQUAL=		'=' -
-COLON=		':' -
-SEMICOLON=	';' -
-BAR=		'|' -
-AND=		'&' -
-NOT=		'!' -
-QUESTION=	'?' -
-STAR=		'*' -
-PLUS=		'+' -
-OPEN=		'(' -
-CLOSE=		')' -
-DOT=		'.' -
-BEGIN=		'<' -
-END=		'>' -
-RPERCENT=	'%}' -
-
--=		(space | comment)*
-space=		' ' | '\t' | end-of-line
-comment=	'#' (!end-of-line .)* end-of-line
-end-of-line=	'\r\n' | '\n' | '\r'
-end-of-file=	!.
-
-%%
-
-void yyerror(char *message)
-{
-  fprintf(stderr, "%s:%d: %s", fileName, lineNumber, message);
-  if (yyctx->text[0]) fprintf(stderr, " near token '%s'", yyctx->text);
-  if (yyctx->pos < yyctx->limit || !feof(input))
-    {
-      yyctx->buf[yyctx->limit]= '\0';
-      fprintf(stderr, " before text \"");
-      while (yyctx->pos < yyctx->limit)
-	{
-	  if ('\n' == yyctx->buf[yyctx->pos] || '\r' == yyctx->buf[yyctx->pos]) break;
-	  fputc(yyctx->buf[yyctx->pos++], stderr);
-	}
-      if (yyctx->pos == yyctx->limit)
-	{
-	  int c;
-	  while (EOF != (c= fgetc(input)) && '\n' != c && '\r' != c)
-	    fputc(c, stderr);
-	}
-      fputc('\"', stderr);
-    }
-  fprintf(stderr, "\n");
-  exit(1);
-}
-
-void makeHeader(char *text)
-{
-  Header *header= (Header *)malloc(sizeof(Header));
-  header->text= strdup(text);
-  header->next= headers;
-  headers= header;
-}
-
-void makeTrailer(char *text)
-{
-  trailer= strdup(text);
-}
-
-static void version(char *name)
-{
-  printf("%s version %d.%d.%d\n", name, PEG_MAJOR, PEG_MINOR, PEG_LEVEL);
-}
-
-static void usage(char *name)
-{
-  version(name);
-  fprintf(stderr, "usage: %s [<option>...] [<file>...]\n", name);
-  fprintf(stderr, "where <option> can be\n");
-  fprintf(stderr, "  -h          print this help information\n");
-  fprintf(stderr, "  -o <ofile>  write output to <ofile>\n");
-  fprintf(stderr, "  -v          be verbose\n");
-  fprintf(stderr, "  -V          print version number and exit\n");
-  fprintf(stderr, "if no <file> is given, input is read from stdin\n");
-  fprintf(stderr, "if no <ofile> is given, output is written to stdout\n");
-  exit(1);
-}
-
-int main(int argc, char **argv)
-{
-  Node *n;
-  int   c;
-
-  output= stdout;
-  input= stdin;
-  lineNumber= 1;
-  fileName= "<stdin>";
-
-  while (-1 != (c= getopt(argc, argv, "Vho:v")))
-    {
-      switch (c)
-	{
-	case 'V':
-	  version(basename(argv[0]));
-	  exit(0);
-
-	case 'h':
-	  usage(basename(argv[0]));
-	  break;
-
-	case 'o':
-	  if (!(output= fopen(optarg, "w")))
-	    {
-	      perror(optarg);
-	      exit(1);
-	    }
-	  break;
-
-	case 'v':
-	  verboseFlag= 1;
-	  break;
-
-	default:
-	  fprintf(stderr, "for usage try: %s -h\n", argv[0]);
-	  exit(1);
-	}
-    }
-  argc -= optind;
-  argv += optind;
-
-  if (argc)
-    {
-      for (;  argc;  --argc, ++argv)
-	{
-	  if (!strcmp(*argv, "-"))
-	    {
-	      input= stdin;
-	      fileName= "<stdin>";
-	    }
-	  else
-	    {
-	      if (!(input= fopen(*argv, "r")))
-		{
-		  perror(*argv);
-		  exit(1);
-		}
-	      fileName= *argv;
-	    }
-	  lineNumber= 1;
-	  if (!yyparse())
-	    yyerror("syntax error");
-	  if (input != stdin)
-	    fclose(input);
-	}
-    }
-  else
-    if (!yyparse())
-      yyerror("syntax error");
-
-  if (verboseFlag)
-    for (n= rules;  n;  n= n->any.next)
-      Rule_print(n);
-
-  Rule_compile_c_header();
-
-  for (; headers;  headers= headers->next)
-    fprintf(output, "%s\n", headers->text);
-
-  if (rules)
-    Rule_compile_c(rules);
-
-  if (trailer)
-    fprintf(output, "%s\n", trailer);
-
-  return 0;
-}
--- /dev/null
+++ b/leg.vcxproj
@@ -1,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{5ECEC9E5-8F23-47B6-93E0-C3B328B3BE66}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>leg</RootNamespace>
+    <TargetName>$(ProjectName)</TargetName>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings" />
+  <ImportGroup Label="PropertySheets">
+    <Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <ExecutablePath>$(ExecutablePath);$(MSBuildProjectDirectory)\.\bin\;$(MSBuildProjectDirectory)\.\bin\</ExecutablePath>
+    <IntDir>$(Configuration)\obj\$(ProjectName)\</IntDir>
+    <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>win;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <OutputFile>$(OutDir)$(ProjectName).exe</OutputFile>
+      <SubSystem>Console</SubSystem>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>win;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>win;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <OutputFile>$(OutDir)$(ProjectName).exe</OutputFile>
+      <SubSystem>Console</SubSystem>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>win;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <None Include="peg.gyp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="src\compile.c" />
+    <ClCompile Include="src\leg.c" />
+    <ClCompile Include="src\tree.c" />
+    <ClCompile Include="win\getopt.c" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets" />
+</Project>
\ No newline at end of file
--- /dev/null
+++ b/leg.vcxproj.filters
@@ -1,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="win">
+      <UniqueIdentifier>{47FC5EC4-15EB-E92F-89D7-AFE51CF838A9}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="peg.gyp" />
+    <ClCompile Include="win\getopt.c">
+      <Filter>win</Filter>
+    </ClCompile>
+    <ClCompile Include="src\compile.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="src\leg.c" />
+    <ClCompile Include="src\tree.c" />
+  </ItemGroup>
+</Project>
\ No newline at end of file
--- a/peg.1
+++ /dev/null
@@ -1,933 +1,0 @@
-.\" Copyright (c) 2007 by Ian Piumarta
-.\" All rights reserved.
-.\" 
-.\" Permission is hereby granted, free of charge, to any person obtaining a
-.\" copy of this software and associated documentation files (the 'Software'),
-.\" to deal in the Software without restriction, including without limitation
-.\" the rights to use, copy, modify, merge, publish, distribute, and/or sell
-.\" copies of the Software, and to permit persons to whom the Software is
-.\" furnished to do so, provided that the above copyright notice(s) and this
-.\" permission notice appear in all copies of the Software.  Acknowledgement
-.\" of the use of this Software in supporting documentation would be
-.\" appreciated but is not required.
-.\" 
-.\" THE SOFTWARE IS PROVIDED 'AS IS'.  USE ENTIRELY AT YOUR OWN RISK.
-.\" 
-.\" Last edited: 2012-04-29 16:58:44 by piumarta on emilia
-.\"
-.TH PEG 1 "April 2012" "Version 0.1"
-.SH NAME
-peg, leg \- parser generators
-.SH SYNOPSIS
-.B peg
-.B [\-hvV \-ooutput]
-.I [filename ...]
-.sp 0
-.B leg
-.B [\-hvV \-ooutput]
-.I [filename ...]
-.SH DESCRIPTION
-.I peg
-and
-.I leg
-are tools for generating recursive-descent parsers: programs that
-perform pattern matching on text.  They process a Parsing Expression
-Grammar (PEG) [Ford 2004] to produce a program that recognises legal
-sentences of that grammar.
-.I peg
-processes PEGs written using the original syntax described by Ford;
-.I leg
-processes PEGs written using slightly different syntax and conventions
-that are intended to make it an attractive replacement for parsers
-built with
-.IR lex (1)
-and
-.IR yacc (1).
-Unlike
-.I lex
-and
-.IR yacc ,
-.I peg
-and
-.I leg
-support unlimited backtracking, provide ordered choice as a means for
-disambiguation, and can combine scanning (lexical analysis) and
-parsing (syntactic analysis) into a single activity.
-.PP
-.I peg
-reads the specified
-.IR filename s,
-or standard input if no
-.IR filename s
-are given, for a grammar describing the parser to generate.
-.I peg
-then generates a C source file that defines a function
-.IR yyparse().
-This C source file can be included in, or compiled and then linked
-with, a client program.  Each time the client program calls
-.IR yyparse ()
-the parser consumes input text according to the parsing rules,
-starting from the first rule in the grammar.
-.IR yyparse ()
-returns non-zero if the input could be parsed according to the
-grammar; it returns zero if the input could not be parsed.
-.PP
-The prefix 'yy' or 'YY' is prepended to all externally-visible symbols
-in the generated parser.  This is intended to reduce the risk of
-namespace pollution in client programs.  (The choice of 'yy' is
-historical; see
-.IR lex (1)
-and
-.IR yacc (1),
-for example.)
-.SH OPTIONS
-.I peg
-and 
-.I leg
-provide the following options:
-.TP
-.B \-h
-prints a summary of available options and then exits.
-.TP
-.B \-ooutput
-writes the generated parser to the file
-.B output
-instead of the standard output.
-.TP
-.B \-v
-writes verbose information to standard error while working.
-.TP
-.B \-V
-writes version information to standard error then exits.
-.SH A SIMPLE EXAMPLE
-The following
-.I peg
-input specifies a grammar with a single rule (called 'start') that is
-satisfied when the input contains the string "username".
-.nf
-
-    start <- "username"
-
-.fi
-(The quotation marks are
-.I not
-part of the matched text; they serve to indicate a literal string to
-be matched.)  In other words,
-.IR  yyparse ()
-in the generated C source will return non-zero only if the next eight
-characters read from the input spell the word "username".  If the
-input contains anything else,
-.IR yyparse ()
-returns zero and no input will have been consumed.  (Subsequent calls
-to
-.IR yyparse ()
-will also return zero, since the parser is effectively blocked looking
-for the string "username".)  To ensure progress we can add an
-alternative clause to the 'start' rule that will match any single
-character if "username" is not found.
-.nf
-
-    start <- "username"
-           / .
-
-.fi
-.IR yyparse ()
-now always returns non-zero (except at the very end of the input).  To
-do something useful we can add actions to the rules.  These actions
-are performed after a complete match is found (starting from the first
-rule) and are chosen according to the 'path' taken through the grammar
-to match the input.  (Linguists would call this path a 'phrase
-marker'.)
-.nf
-
-    start <- "username"    { printf("%s\\n", getlogin()); }
-           / < . >         { putchar(yytext[0]); }
-
-.fi
-The first line instructs the parser to print the user's login name
-whenever it sees "username" in the input.  If that match fails, the
-second line tells the parser to echo the next character on the input
-the standard output.  Our parser is now performing useful work: it
-will copy the input to the output, replacing all occurrences of
-"username" with the user's account name.
-.PP
-Note the angle brackets ('<' and '>') that were added to the second
-alternative.  These have no effect on the meaning of the rule, but
-serve to delimit the text made available to the following action in
-the variable
-.IR yytext .
-.PP
-If the above grammar is placed in the file
-.BR username.peg ,
-running the command
-.nf
-
-    peg -o username.c username.peg
-
-.fi
-will save the corresponding parser in the file
-.BR username.c .
-To create a complete program this parser could be included by a C
-program as follows.
-.nf
-
-    #include <stdio.h>      /* printf(), putchar() */
-    #include <unistd.h>     /* getlogin() */
-
-    #include "username.c"   /* yyparse() */
-
-    int main()
-    {
-      while (yyparse())     /* repeat until EOF */
-        ;
-      return 0;
-    }
-.fi
-.SH PEG GRAMMARS
-A grammar consists of a set of named rules.
-.nf
-
-    name <- pattern
-
-.fi
-The
-.B pattern
-contains one or more of the following elements.
-.TP
-.B name
-The element stands for the entire pattern in the rule with the given
-.BR name .
-.TP
-.BR \(dq characters \(dq
-A character or string enclosed in double quotes is matched literally.
-The ANSI C esacpe sequences are recognised within the
-.IR characters .
-.TP
-.BR ' characters '
-A character or string enclosed in single quotes is matched literally, as above.
-.TP
-.BR [ characters ]
-A set of characters enclosed in square brackets matches any single
-character from the set, with escape characters recognised as above.
-If the set begins with an uparrow (^) then the set is negated (the
-element matches any character
-.I not
-in the set).  Any pair of characters separated with a dash (-)
-represents the range of characters from the first to the second,
-inclusive.  A single alphabetic character or underscore is matched by
-the following set.
-.nf
-
-    [a-zA-Z_]
-
-.fi
-Similarly, the following matches  any single non-digit character.
-.nf
-
-    [^0-9]
-
-.fi
-.TP
-.B .
-A dot matches any character.  Note that the only time this fails is at
-the end of file, where there is no character to match.
-.TP
-.BR ( \ pattern\  )
-Parentheses are used for grouping (modifying the precendence of the
-operators described below).
-.TP
-.BR { \ action\  }
-Curly braces surround actions.  The action is arbitray C source code
-to be executed at the end of matching.  Any braces within the action
-must be properly nested.  Any input text that was matched before the
-action and delimited by angle brackets (see below) is made available
-within the action as the contents of the character array
-.IR yytext .
-The length of (number of characters in)
-.I yytext
-is available in the variable
-.IR yyleng .
-(These variable names are historical; see
-.IR lex (1).)
-.TP
-.B <
-An opening angle bracket always matches (consuming no input) and
-causes the parser to begin accumulating matched text.  This text will
-be made available to actions in the variable
-.IR yytext .
-.TP
-.B >
-A closing angle bracket always matches (consuming no input) and causes
-the parser to stop accumulating text for
-.IR yytext .
-.PP
-The above
-.IR element s
-can be made optional and/or repeatable with the following suffixes:
-.TP
-.RB element\  ?
-The element is optional.  If present on the input, it is consumed and
-the match succeeds.  If not present on the input, no text is consumed
-and the match succeeds anyway.
-.TP
-.RB element\  +
-The element is repeatable.  If present on the input, one or more
-occurrences of
-.I element
-are consumed and the match succeeds.  If no occurrences of
-.I element
-are present on the input, the match fails.
-.TP
-.RB element\  *
-The element is optional and repeatable.  If present on the input, one or more
-occurrences of
-.I element
-are consumed and the match succeeds.  If no occurrences of
-.I element
-are present on the input, the match succeeds anyway.
-.PP
-The above elements and suffixes can be converted into predicates (that
-match arbitray input text and subsequently succeed or fail
-.I without
-consuming that input) with the following prefixes:
-.TP
-.BR & \ element
-The predicate succeeds only if
-.I element
-can be matched.  Input text scanned while matching
-.I element
-is not consumed from the input and remains available for subsequent
-matching.
-.TP
-.BR ! \ element
-The predicate succeeds only if
-.I element
-cannot be matched.  Input text scanned while matching
-.I element
-is not consumed from the input and remains available for subsequent
-matching.  A popular idiom is
-.nf
-
-    !.
-
-.fi
-which matches the end of file, after the last character of the input
-has already been consumed.
-.PP
-A special form of the '&' predicate is provided:
-.TP
-.BR & {\ expression\ }
-In this predicate the simple C
-.I expression
-.RB ( not
-statement) is evaluated immediately when the parser reaches the
-predicate.  If the
-.I expression
-yields non-zero (true) the 'match' succeeds and the parser continues
-with the next element in the pattern.  If the
-.I expression
-yields zero (false) the 'match' fails and the parser backs up to look
-for an alternative parse of the input.
-.PP
-Several elements (with or without prefixes and suffixes) can be
-combined into a
-.I sequence
-by writing them one after the other.  The entire sequence matches only
-if each individual element within it matches, from left to right.
-.PP
-Sequences can be separated into disjoint alternatives by the
-alternation operator '/'.
-.TP
-.RB sequence-1\  / \ sequence-2\  / \ ...\  / \ sequence-N
-Each sequence is tried in turn until one of them matches, at which
-time matching for the overall pattern succeeds.  If none of the
-sequences matches then the match of the overall pattern fails.
-.PP
-Finally, the pound sign (#) introduces a comment (discarded) that
-continues until the end of the line.
-.PP
-To summarise the above, the parser tries to match the input text
-against a pattern containing literals, names (representing other
-rules), and various operators (written as prefixes, suffixes,
-juxtaposition for sequencing and and infix alternation operator) that
-modify how the elements within the pattern are matched.  Matches are
-made from left to right, 'descending' into named sub-rules as they are
-encountered.  If the matching process fails, the parser 'back tracks'
-('rewinding' the input appropriately in the process) to find the
-nearest alternative 'path' through the grammar.  In other words the
-parser performs a depth-first, left-to-right search for the first
-successfully-matching path through the rules.  If found, the actions
-along the successful path are executed (in the order they were
-encountered).
-.PP
-Note that predicates are evaluated
-.I immediately
-during the search for a successful match, since they contribute to the
-success or failure of the search.  Actions, however, are evaluated
-only after a successful match has been found.
-.SH PEG GRAMMAR FOR PEG GRAMMARS
-The grammar for
-.I peg
-grammars is shown below.  This will both illustrate and formalise
-the above description.
-.nf
-
-    Grammar         <- Spacing Definition+ EndOfFile
-    
-    Definition      <- Identifier LEFTARROW Expression
-    Expression      <- Sequence ( SLASH Sequence )*
-    Sequence        <- Prefix*
-    Prefix          <- AND Action
-                     / ( AND | NOT )? Suffix
-    Suffix          <- Primary ( QUERY / STAR / PLUS )?
-    Primary         <- Identifier !LEFTARROW
-                     / OPEN Expression CLOSE
-                     / Literal
-                     / Class
-                     / DOT
-                     / Action
-                     / BEGIN
-                     / END
-    
-    Identifier      <- < IdentStart IdentCont* > Spacing
-    IdentStart      <- [a-zA-Z_]
-    IdentCont       <- IdentStart / [0-9]
-    Literal         <- ['] < ( !['] Char  )* > ['] Spacing
-                     / ["] < ( !["] Char  )* > ["] Spacing
-    Class           <- '[' < ( !']' Range )* > ']' Spacing
-    Range           <- Char '-' Char / Char
-    Char            <- '\\\\' [abefnrtv'"\\[\\]\\\\]
-                     / '\\\\' [0-3][0-7][0-7]
-                     / '\\\\' [0-7][0-7]?
-                     / '\\\\' '-'
-                     / !'\\\\' .
-    LEFTARROW       <- '<-' Spacing
-    SLASH           <- '/' Spacing
-    AND             <- '&' Spacing
-    NOT             <- '!' Spacing
-    QUERY           <- '?' Spacing
-    STAR            <- '*' Spacing
-    PLUS            <- '+' Spacing
-    OPEN            <- '(' Spacing
-    CLOSE           <- ')' Spacing
-    DOT             <- '.' Spacing
-    Spacing         <- ( Space / Comment )*
-    Comment         <- '#' ( !EndOfLine . )* EndOfLine
-    Space           <- ' ' / '\\t' / EndOfLine
-    EndOfLine       <- '\\r\\n' / '\\n' / '\\r'
-    EndOfFile       <- !.
-    Action          <- '{' < [^}]* > '}' Spacing
-    BEGIN           <- '<' Spacing
-    END             <- '>' Spacing
-
-.fi
-.SH LEG GRAMMARS
-.I leg
-is a variant of
-.I peg
-that adds some features of
-.IR lex (1)
-and
-.IR yacc (1).
-It differs from
-.I peg
-in the following ways.
-.TP
-.BI %{\  text... \ %}
-A declaration section can appear anywhere that a rule definition is
-expected.  The
-.I text
-between the delimiters '%{' and '%}' is copied verbatim to the
-generated C parser code
-.I before
-the code that implements the parser itself.
-.TP
-.IB name\  = \ pattern
-The 'assignment' operator replaces the left arrow operator '<-'.
-.TP
-.B rule-name
-Hyphens can appear as letters in the names of rules.  Each hyphen is
-converted into an underscore in the generated C source code.  A single
-single hyphen '-' is a legal rule name.
-.nf
-
-    -       = [ \\t\\n\\r]*
-    number  = [0-9]+                 -
-    name    = [a-zA-Z_][a-zA_Z_0-9]* -
-    l-paren = '('                    -
-    r-paren = ')'                    -
-    
-.fi
-This example shows how ignored whitespace can be obvious when reading
-the grammar and yet unobtrusive when placed liberally at the end of
-every rule associated with a lexical element.
-.TP
-.IB seq-1\  | \ seq-2
-The alternation operator is vertical bar '|' rather than forward
-slash '/'.  The
-.I peg
-rule
-.nf
-
-    name <- sequence-1
-          / sequence-2
-          / sequence-3
-
-.fi
-is therefore written
-.nf
-
-    name = sequence-1
-         | sequence-2
-         | sequence-3
-         ;
-
-.fi
-in
-.I leg
-(with the final semicolon being optional, as described next).
-.TP
-.IB pattern\  ;
-A semicolon punctuator can optionally terminate a
-.IR pattern .
-.TP
-.BI %% \ text...
-A double percent '%%' terminates the rules (and declarations) section of
-the grammar.  All
-.I text
-following '%%' is copied verbatim to the generated C parser code
-.I after
-the parser implementation code.
-.TP
-.BI $$\ = \ value
-A sub-rule can return a semantic
-.I value
-from an action by assigning it to the pseudo-variable '$$'.  All
-semantic values must have the same type (which defaults to 'int').
-This type can be changed by defining YYSTYPE in a declaration section.
-.TP
-.IB identifier : name
-The semantic value returned (by assigning to '$$') from the sub-rule
-.I name
-is associated with the
-.I identifier
-and can be referred to in subsequent actions.
-.PP
-The desk calclator example below illustrates the use of '$$' and ':'.
-.SH LEG EXAMPLE: A DESK CALCULATOR
-The extensions in
-.I leg
-described above allow useful parsers and evaluators (including
-declarations, grammar rules, and supporting C functions such
-as 'main') to be kept within a single source file.  To illustrate this
-we show a simple desk calculator supporting the four common arithmetic
-operators and named variables.  The intermediate results of arithmetic
-evaluation will be accumulated on an implicit stack by returning them
-as semantic values from sub-rules.
-.nf
-
-    %{
-    #include <stdio.h>     /* printf() */
-    #include <stdlib.h>    /* atoi() */
-    int vars[26];
-    %}
-    
-    Stmt    = - e:Expr EOL                  { printf("%d\\n", e); }
-            | ( !EOL . )* EOL               { printf("error\\n"); }
-    
-    Expr    = i:ID ASSIGN s:Sum             { $$ = vars[i] = s; }
-            | s:Sum                         { $$ = s; }
-    
-    Sum     = l:Product
-                    ( PLUS  r:Product       { l += r; }
-                    | MINUS r:Product       { l -= r; }
-                    )*                      { $$ = l; }
-    
-    Product = l:Value
-                    ( TIMES  r:Value        { l *= r; }
-                    | DIVIDE r:Value        { l /= r; }
-                    )*                      { $$ = l; }
-    
-    Value   = i:NUMBER                      { $$ = atoi(yytext); }
-            | i:ID !ASSIGN                  { $$ = vars[i]; }
-            | OPEN i:Expr CLOSE             { $$ = i; }
-    
-    NUMBER  = < [0-9]+ >    -               { $$ = atoi(yytext); }
-    ID      = < [a-z]  >    -               { $$ = yytext[0] - 'a'; }
-    ASSIGN  = '='           -
-    PLUS    = '+'           -
-    MINUS   = '-'           -
-    TIMES   = '*'           -
-    DIVIDE  = '/'           -
-    OPEN    = '('           -
-    CLOSE   = ')'           -
-    
-    -       = [ \\t]*
-    EOL     = '\\n' | '\\r\\n' | '\\r' | ';'
-    
-    %%
-    
-    int main()
-    {
-      while (yyparse())
-        ;
-      return 0;
-    }
-
-.fi
-.SH LEG GRAMMAR FOR LEG GRAMMARS
-The grammar for
-.I leg
-grammars is shown below.  This will both illustrate and formalise the
-above description.
-.nf
-
-    grammar =       -
-                    ( declaration | definition )+
-                    trailer? end-of-file
-    
-    declaration =   '%{' < ( !'%}' . )* > RPERCENT
-    
-    trailer =       '%%' < .* >
-    
-    definition =    identifier EQUAL expression SEMICOLON?
-    
-    expression =    sequence ( BAR sequence )*
-    
-    sequence =      prefix+
-    
-    prefix =        AND action
-    |               ( AND | NOT )? suffix
-    
-    suffix =        primary ( QUERY | STAR | PLUS )?
-    
-    primary =       identifier COLON identifier !EQUAL
-    |               identifier !EQUAL
-    |               OPEN expression CLOSE
-    |               literal
-    |               class
-    |               DOT
-    |               action
-    |               BEGIN
-    |               END
-    
-    identifier =    < [-a-zA-Z_][-a-zA-Z_0-9]* > -
-    
-    literal =       ['] < ( !['] char )* > ['] -
-    |               ["] < ( !["] char )* > ["] -
-    
-    class =         '[' < ( !']' range )* > ']' -
-    
-    range =         char '-' char | char
-    
-    char =          '\\\\' [abefnrtv'"\\[\\]\\\\]
-    |               '\\\\' [0-3][0-7][0-7]
-    |               '\\\\' [0-7][0-7]?
-    |               !'\\\\' .
-    
-    action =        '{' < [^}]* > '}' -
-    
-    EQUAL =         '=' -
-    COLON =         ':' -
-    SEMICOLON =     ';' -
-    BAR =           '|' -
-    AND =           '&' -
-    NOT =           '!' -
-    QUERY =         '?' -
-    STAR =          '*' -
-    PLUS =          '+' -
-    OPEN =          '(' -
-    CLOSE =         ')' -
-    DOT =           '.' -
-    BEGIN =         '<' -
-    END =           '>' -
-    RPERCENT =      '%}' -
-    
-    - =             ( space | comment )*
-    space =         ' ' | '\\t' | end-of-line
-    comment =       '#' ( !end-of-line . )* end-of-line
-    end-of-line =   '\\r\\n' | '\\n' | '\\r'
-    end-of-file =   !.
-
-.fi
-.SH CUSTOMISING THE PARSER
-The following symbols can be redefined in declaration sections to
-modify the generated parser code.
-.TP
-.B YYSTYPE
-The semantic value type.  The pseudo-variable '$$' and the
-identifiers 'bound' to rule results with the colon operator ':' should
-all be considered as being declared to have this type.  The default
-value is 'int'.
-.TP
-.B YYPARSE
-The name of the main entry point to the parser.  The default value
-is 'yyparse'.
-.TP
-.B YYPARSEFROM
-The name of an alternative entry point to the parser.  This function
-expects one argument: the function corresponding to the rule from
-which the search for a match should begin.  The default
-is 'yyparsefrom'.  Note that yyparse() is defined as
-.nf
-
-    int yyparse() { return yyparsefrom(yy_foo); }
-
-.fi
-where 'foo' is the name of the first rule in the grammar.
-.TP
-.BI YY_INPUT( buf , \ result , \ max_size )
-This macro is invoked by the parser to obtain more input text.
-.I buf
-points to an area of memory that can hold at most
-.I max_size
-characters.  The macro should copy input text to
-.I buf
-and then assign the integer variable
-.I result
-to indicate the number of characters copied.  If no more input is available,
-the macro should assign 0 to
-.IR result .
-By default, the YY_INPUT macro is defined as follows.
-.nf
-
-    #define YY_INPUT(buf, result, max_size)        \\
-    {                                              \\
-      int yyc= getchar();                          \\
-      result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \\
-    }
-
-.fi
-.TP
-.B YY_DEBUG
-If this symbols is defined then additional code will be included in
-the parser that prints vast quantities of arcane information to the
-standard error while the parser is running.
-.TP
-.B YY_BEGIN
-This macro is invoked to mark the start of input text that will be
-made available in actions as 'yytext'.  This corresponds to
-occurrences of '<' in the grammar.  These are converted into
-predicates that are expected to succeed.  The default definition
-.nf
-
-    #define YY_BEGIN (yybegin= yypos, 1)
-
-.fi
-therefore saves the current input position and returns 1 ('true') as
-the result of the predicate.
-.TP
-.B YY_END
-This macros corresponds to '>' in the grammar.  Again, it is a
-predicate so the default definition saves the input position
-before 'succeeding'.
-.nf
-
-    #define YY_END (yyend= yypos, 1)
-
-.fi
-.TP
-.BI YY_PARSE( T )
-This macro declares the parser entry points (yyparse and yyparsefrom)
-to be of type
-.IR T .
-The default definition
-.nf
-
-    #define YY_PARSE(T) T
-
-.fi
-leaves yyparse() and yyparsefrom() with global visibility.  If they
-should not be externally visible in other source files, this macro can
-be redefined to declare them 'static'.
-.nf
-
-    #define YY_PARSE(T) static T
-
-.fi
-.TP
-.BI YY_CTX_LOCAL
-If this symbol is defined during compilation of a generated parser
-then global parser state will be kept in a structure of
-type 'yycontext' which can be declared as a local variable.  This
-allows multiple instances of parsers to coexist and to be thread-safe.
-The parsing function
-.IR yyparse ()
-will be declared to expect a first argument of type 'yycontext *', an
-instance of the structure holding the global state for the parser.
-This instance must be allocated and initialised to zero by the client.
-A trivial but complete example is as follows.
-.nf
-
-    #include <stdio.h>
-
-    #define YY_CTX_LOCAL
-
-    #include "the-generated-parser.peg.c"
-
-    int main()
-    {
-      yycontext ctx;
-      memset(&ctx, 0, sizeof(yycontext));
-      while (yyparse(&ctx));
-      return 0;
-    }
-
-.fi
-Note that if this symbol is undefined then the compiled parser will
-statically allocate its global state and will be neither reentrant nor
-thread-safe.
-.TP
-.BI YY_CTX_MEMBERS
-If YY_CTX_LOCAL is defined (see above) then the macro YY_CTX_MEMBERS
-can be defined to expand to any additional member field declarations
-that the client would like included in the declaration of
-the 'yycontext' structure type.  These additional members are
-otherwise ignored by the generated parser.  The instance
-of 'yycontext' associated with the currently-active parser is
-available in actions through the pointer variable
-.IR yyctx .
-.PP
-The following variables can be reffered to within actions.
-.TP
-.B char *yybuf
-This variable points to the parser's input buffer used to store input
-text that has not yet been matched.
-.TP
-.B int yypos
-This is the offset (in yybuf) of the next character to be matched and
-consumed.
-.TP
-.B char *yytext
-The most recent matched text delimited by '<' and '>' is stored in this variable.
-.TP
-.B int yyleng
-This variable indicates the number of characters in 'yytext'.
-.TP
-.B yycontext *yyctx
-This variable points to the instance of 'yycontext' associated with
-the currently-active parser.
-.SH DIAGNOSTICS
-.I peg
-and
-.I leg
-warn about the following conditions while converting a grammar into a parser.
-.TP
-.B syntax error
-The input grammar was malformed in some way.  The error message will
-include the text about to be matched (often backed up a huge amount
-from the actual location of the error) and the line number of the most
-recently considered character (which is often the real location of the
-problem).
-.TP
-.B rule 'foo' used but not defined
-The grammar referred to a rule named 'foo' but no definition for it
-was given.  Attempting to use the generated parser will likely result
-in errors from the linker due to undefined symbols associated with the
-missing rule.
-.TP
-.B rule 'foo' defined but not used
-The grammar defined a rule named 'foo' and then ignored it.  The code
-associated with the rule is included in the generated parser which
-will in all other respects be healthy.
-.TP
-.B possible infinite left recursion in rule 'foo'
-There exists at least one path through the grammar that leads from the
-rule 'foo' back to (a recursive invocation of) the same rule without
-consuming any input.
-.PP
-Left recursion, especially that found in standards documents, is
-often 'direct' and implies trivial repetition.
-.nf
-
-    # (6.7.6)
-    direct-abstract-declarator =
-        LPAREN abstract-declarator RPAREN
-    |   direct-abstract-declarator? LBRACKET assign-expr? RBRACKET
-    |   direct-abstract-declarator? LBRACKET STAR RBRACKET
-    |   direct-abstract-declarator? LPAREN param-type-list? RPAREN
-
-.fi
-The recursion can easily be eliminated by converting the parts of the
-pattern following the recursion into a repeatable suffix.
-.nf
-    
-    # (6.7.6)
-    direct-abstract-declarator =
-        direct-abstract-declarator-head?
-        direct-abstract-declarator-tail*
-    
-    direct-abstract-declarator-head =
-        LPAREN abstract-declarator RPAREN
-    
-    direct-abstract-declarator-tail =
-        LBRACKET assign-expr? RBRACKET
-    |   LBRACKET STAR RBRACKET
-    |   LPAREN param-type-list? RPAREN
-
-.fi
-.SH BUGS
-The 'yy' and 'YY' prefixes cannot be changed.
-.PP
-Left recursion is detected in the input grammar but is not handled
-correctly in the generated parser.
-.PP
-Diagnostics for errors in the input grammar are obscure and not
-particularly helpful.
-.PP
-Several commonly-used
-.IR lex (1)
-features (yywrap(), yyin, etc.) are completely absent.
-.PP
-The generated parser foes not contain '#line' directives to direct C
-compiler errors back to the grammar description when appropriate.
-.IR lex (1)
-features (yywrap(), yyin, etc.) are completely absent.
-.SH SEE ALSO
-D. Val Schorre,
-.I META II, a syntax-oriented compiler writing language,
-19th ACM National Conference, 1964, pp.\ 41.301--41.311.  Describes a
-self-implementing parser generator for analytic grammars with no
-backtracking.
-.PP
-Alexander Birman,
-.I The TMG Recognition Schema,
-Ph.D. dissertation, Princeton, 1970.  A mathematical treatment of the
-power and complexity of recursive-descent parsing with backtracking.
-.PP
-Bryan Ford,
-.I Parsing Expression Grammars: A Recognition-Based Syntactic Foundation,
-ACM SIGPLAN Symposium on Principles of Programming Languages, 2004.
-Defines PEGs and analyses them in relation to context-free and regular
-grammars.  Introduces the syntax adopted in
-.IR peg .
-.PP
-The standard Unix utilies
-.IR lex (1)
-and
-.IR yacc (1)
-which influenced the syntax and features of
-.IR leg .
-.PP
-The source code for
-.I peg
-and
-.I leg
-whose grammar parsers are written using themselves.
-.PP
-The latest version of this software and documentation:
-.nf
-
-    http://piumarta.com/software/peg
-
-.fi
-.SH AUTHOR
-.IR peg ,
-.I leg
-and this manual page were written by Ian Piumarta (first-name at
-last-name dot com) while investigating the viablility of regular- and
-parsing-expression grammars for efficiently extracting type and
-signature information from C header files.
-.PP
-Please send bug reports and suggestions for improvements to the author
-at the above address.
--- a/peg.c
+++ /dev/null
@@ -1,173 +1,0 @@
-/* Copyright (c) 2007 by Ian Piumarta
- * All rights reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the 'Software'),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, provided that the above copyright notice(s) and this
- * permission notice appear in all copies of the Software.  Acknowledgement
- * of the use of this Software in supporting documentation would be
- * appreciated but is not required.
- * 
- * THE SOFTWARE IS PROVIDED 'AS IS'.  USE ENTIRELY AT YOUR OWN RISK.
- * 
- * Last edited: 2012-04-29 15:49:09 by piumarta on emilia
- */
-
-#include "tree.h"
-#include "version.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <libgen.h>
-#include <assert.h>
-
-FILE *input= 0;
-
-int   verboseFlag= 0;
-
-static int   lineNumber= 0;
-static char *fileName= 0;
-
-void yyerror(char *message);
-
-#define YY_INPUT(buf, result, max)			\
-{							\
-  int c= getc(input);					\
-  if ('\n' == c || '\r' == c) ++lineNumber;		\
-  result= (EOF == c) ? 0 : (*(buf)= c, 1);		\
-}
-
-#define YY_LOCAL(T)	static T
-#define YY_RULE(T)	static T
-
-#include "peg.peg-c"
-
-void yyerror(char *message)
-{
-  fprintf(stderr, "%s:%d: %s", fileName, lineNumber, message);
-  if (yyctx->text[0]) fprintf(stderr, " near token '%s'", yyctx->text);
-  if (yyctx->pos < yyctx->limit || !feof(input))
-    {
-      yyctx->buf[yyctx->limit]= '\0';
-      fprintf(stderr, " before text \"");
-      while (yyctx->pos < yyctx->limit)
-	{
-	  if ('\n' == yyctx->buf[yyctx->pos] || '\r' == yyctx->buf[yyctx->pos]) break;
-	  fputc(yyctx->buf[yyctx->pos++], stderr);
-	}
-      if (yyctx->pos == yyctx->limit)
-	{
-	  int c;
-	  while (EOF != (c= fgetc(input)) && '\n' != c && '\r' != c)
-	    fputc(c, stderr);
-	}
-      fputc('\"', stderr);
-    }
-  fprintf(stderr, "\n");
-  exit(1);
-}
-
-static void version(char *name)
-{
-  printf("%s version %d.%d.%d\n", name, PEG_MAJOR, PEG_MINOR, PEG_LEVEL);
-}
-
-static void usage(char *name)
-{
-  version(name);
-  fprintf(stderr, "usage: %s [<option>...] [<file>...]\n", name);
-  fprintf(stderr, "where <option> can be\n");
-  fprintf(stderr, "  -h          print this help information\n");
-  fprintf(stderr, "  -o <ofile>  write output to <ofile>\n");
-  fprintf(stderr, "  -v          be verbose\n");
-  fprintf(stderr, "  -V          print version number and exit\n");
-  fprintf(stderr, "if no <file> is given, input is read from stdin\n");
-  fprintf(stderr, "if no <ofile> is given, output is written to stdout\n");
-  exit(1);
-}
-
-int main(int argc, char **argv)
-{
-  Node *n;
-  int   c;
-
-  output= stdout;
-  input= stdin;
-  lineNumber= 1;
-  fileName= "<stdin>";
-
-  while (-1 != (c= getopt(argc, argv, "Vho:v")))
-    {
-      switch (c)
-	{
-	case 'V':
-	  version(basename(argv[0]));
-	  exit(0);
-
-	case 'h':
-	  usage(basename(argv[0]));
-	  break;
-
-	case 'o':
-	  if (!(output= fopen(optarg, "w")))
-	    {
-	      perror(optarg);
-	      exit(1);
-	    }
-	  break;
-
-	case 'v':
-	  verboseFlag= 1;
-	  break;
-
-	default:
-	  fprintf(stderr, "for usage try: %s -h\n", argv[0]);
-	  exit(1);
-	}
-    }
-  argc -= optind;
-  argv += optind;
-
-  if (argc)
-    {
-      for (;  argc;  --argc, ++argv)
-	{
-	  if (!strcmp(*argv, "-"))
-	    {
-	      input= stdin;
-	      fileName= "<stdin>";
-	    }
-	  else
-	    {
-	      if (!(input= fopen(*argv, "r")))
-		{
-		  perror(*argv);
-		  exit(1);
-		}
-	      fileName= *argv;
-	    }
-	  lineNumber= 1;
-	  if (!yyparse())
-	    yyerror("syntax error");
-	  if (input != stdin)
-	    fclose(input);
-	}
-    }
-  else
-    if (!yyparse())
-      yyerror("syntax error");
-
-  if (verboseFlag)
-    for (n= rules;  n;  n= n->any.next)
-      Rule_print(n);
-
-  Rule_compile_c_header();
-  if (rules) Rule_compile_c(rules);
-
-  return 0;
-}
--- /dev/null
+++ b/peg.gyp
@@ -1,0 +1,81 @@
+{
+  'targets': [
+    {
+      'target_name': 'peg',
+      'type': 'executable',
+      'msvs_guid': '5ECEC9E5-8F23-47B6-93E0-C3B328B3BE65',
+      'sources': [
+        'peg.c',
+        'tree.c',
+        'compile.c',
+      ],
+      'conditions': [
+        ['OS=="win"', {
+          'include_dirs': [
+            'win',
+          ],
+          'sources': [
+            'win/getopt.c',
+          ],
+        }],
+      ],
+    },
+    {
+      'target_name': 'leg',
+      'type': 'executable',
+      'msvs_guid': '5ECEC9E5-8F23-47B6-93E0-C3B328B3BE66',
+      'sources': [
+        'leg.c',
+        'tree.c',
+        'compile.c',
+      ],
+      'conditions': [
+        ['OS=="win"', {
+          'include_dirs': [
+            'win',
+          ],
+          'sources': [
+            'win/getopt.c',
+          ],
+        }],
+      ],
+    },
+  ],
+
+  'target_defaults': {
+    'configurations': {
+      'Debug': {
+        'defines': [
+          'DEBUG',
+        ],
+      },
+      'Release': {
+        'defines': [
+          'NDEBUG',
+        ],
+      },
+    },
+  },
+
+  # define default project settings
+  'conditions': [
+    ['OS=="win"', {
+      'target_defaults': {
+        'defines': [
+          'WIN32',
+          '_WINDOWS',
+        ],
+        'msvs_settings': {
+          'VCLinkerTool': {
+            'GenerateDebugInformation': 'true',
+            # SubSystem values:
+            #   0 == not set
+            #   1 == /SUBSYSTEM:CONSOLE
+            #   2 == /SUBSYSTEM:WINDOWS
+            'SubSystem': '1',
+          },
+        },
+      },
+    }],
+  ],
+}
--- a/peg.peg
+++ /dev/null
@@ -1,77 +1,0 @@
-# PE Grammar for PE Grammars
-# 
-# Adapted from [1] by Ian Piumarta <first-name at last-name point com>.
-# 
-# Local modifications (marked '#ikp') to support:
-#     C text in '{ ... }' copied verbatim to output as 'semantic action'
-#     input consumed between '<' and '>' is 'char yytext[]' in semantic actions
-# 
-# Best viewed using 140 columns monospaced with tabs every 8.
-# 
-# [1] Bryan Ford.  "Parsing Expression Grammars: A Recognition-Based Syntactic
-#     Foundation."  Symposium on Principles of Programming Languages,
-#     January 14--16, 2004, Venice, Italy.
-# 
-# Last edited: 2007-05-15 10:32:44 by piumarta on emilia
-
-# Hierarchical syntax
-
-Grammar		<- Spacing Definition+ EndOfFile
-
-Definition	<- Identifier 			{ if (push(beginRule(findRule(yytext)))->rule.expression) fprintf(stderr, "rule '%s' redefined\n", yytext); }
-		     LEFTARROW Expression	{ Node *e= pop();  Rule_setExpression(pop(), e); } &{ YYACCEPT }
-Expression	<- Sequence (SLASH Sequence	{ Node *f= pop();  push(Alternate_append(pop(), f)); }
-			    )*
-Sequence	<- Prefix (Prefix		{ Node *f= pop();  push(Sequence_append(pop(), f)); }	#ikp expanded from 'Seq <- Prefix*'
-			  )*
-		 / 				{ push(makePredicate("1")); }				#ikp added
-Prefix		<- AND Action			{ push(makePredicate(yytext)); }	#ikp added
-		 / AND Suffix			{ push(makePeekFor(pop())); }		#ikp expanded from 'Prefix <- (AND/NOT)? Suffix'
-		 / NOT Suffix			{ push(makePeekNot(pop())); }
-		 /     Suffix
-Suffix		<- Primary (QUESTION		{ push(makeQuery(pop())); }
-			     / STAR		{ push(makeStar (pop())); }
-			     / PLUS		{ push(makePlus (pop())); }
-			   )?
-Primary		<- Identifier !LEFTARROW	{ push(makeName(findRule(yytext))); }
-		 / OPEN Expression CLOSE
-		 / Literal			{ push(makeString(yytext)); }
-		 / Class			{ push(makeClass(yytext)); }
-		 / DOT				{ push(makeDot()); }
-		 / Action			{ push(makeAction(yytext)); }		#ikp added
-		 / BEGIN			{ push(makePredicate("YY_BEGIN")); }	#ikp added
-		 / END				{ push(makePredicate("YY_END")); }	#ikp added
-
-# Lexical syntax
-
-Identifier	<- < IdentStart IdentCont* > Spacing		#ikp inserted < ... >
-IdentStart	<- [a-zA-Z_]
-IdentCont	<- IdentStart / [0-9]
-Literal		<- ['] < (!['] Char )* > ['] Spacing		#ikp inserted < ... >
-		 / ["] < (!["] Char )* > ["] Spacing		#ikp inserted < ... >
-Class		<- '[' < (!']' Range)* > ']' Spacing		#ikp inserted < ... >
-Range		<- Char '-' Char / Char
-Char		<- '\\' [abefnrtv'"\[\]\\]			#ikp added missing ANSI escapes: abefv
-		 / '\\' [0-3][0-7][0-7]
-		 / '\\' [0-7][0-7]?
-		 / '\\' '-'					#ikp added
-		 / !'\\' .
-LEFTARROW	<- '<-' Spacing
-SLASH		<- '/' Spacing
-AND		<- '&' Spacing
-NOT		<- '!' Spacing
-QUESTION	<- '?' Spacing
-STAR		<- '*' Spacing
-PLUS		<- '+' Spacing
-OPEN		<- '(' Spacing
-CLOSE		<- ')' Spacing
-DOT		<- '.' Spacing
-Spacing		<- (Space / Comment)*
-Comment		<- '#' (!EndOfLine .)* EndOfLine
-Space		<- ' ' / '\t' / EndOfLine
-EndOfLine	<- '\r\n' / '\n' / '\r'
-EndOfFile	<- !.
-
-Action		<- '{' < [^}]* > '}' Spacing		#ikp added
-BEGIN		<- '<' Spacing				#ikp added
-END		<- '>' Spacing				#ikp added
--- a/peg.peg-c
+++ /dev/null
@@ -1,912 +1,0 @@
-/* A recursive-descent parser generated by peg 0.1.9 */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#define YYRULECOUNT 32
-#ifndef YY_LOCAL
-#define YY_LOCAL(T)	static T
-#endif
-#ifndef YY_ACTION
-#define YY_ACTION(T)	static T
-#endif
-#ifndef YY_RULE
-#define YY_RULE(T)	static T
-#endif
-#ifndef YY_PARSE
-#define YY_PARSE(T)	T
-#endif
-#ifndef YYPARSE
-#define YYPARSE		yyparse
-#endif
-#ifndef YYPARSEFROM
-#define YYPARSEFROM	yyparsefrom
-#endif
-#ifndef YY_INPUT
-#define YY_INPUT(buf, result, max_size)			\
-  {							\
-    int yyc= getchar();					\
-    result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1);	\
-    yyprintf((stderr, "<%c>", yyc));			\
-  }
-#endif
-#ifndef YY_BEGIN
-#define YY_BEGIN	( ctx->begin= ctx->pos, 1)
-#endif
-#ifndef YY_END
-#define YY_END		( ctx->end= ctx->pos, 1)
-#endif
-#ifdef YY_DEBUG
-# define yyprintf(args)	fprintf args
-#else
-# define yyprintf(args)
-#endif
-#ifndef YYSTYPE
-#define YYSTYPE	int
-#endif
-
-#ifndef YY_PART
-
-typedef struct _yycontext yycontext;
-typedef void (*yyaction)(yycontext *ctx, char *yytext, int yyleng);
-typedef struct _yythunk { int begin, end;  yyaction  action;  struct _yythunk *next; } yythunk;
-
-struct _yycontext {
-  char     *buf;
-  int       buflen;
-  int       pos;
-  int       limit;
-  char     *text;
-  int       textlen;
-  int       begin;
-  int       end;
-  int       textmax;
-  yythunk  *thunks;
-  int       thunkslen;
-  int       thunkpos;
-  YYSTYPE   yy;
-  YYSTYPE  *val;
-  YYSTYPE  *vals;
-  int       valslen;
-#ifdef YY_CTX_MEMBERS
-  YY_CTX_MEMBERS
-#endif
-};
-
-#ifdef YY_CTX_LOCAL
-#define YY_CTX_PARAM_	yycontext *yyctx,
-#define YY_CTX_PARAM	yycontext *yyctx
-#define YY_CTX_ARG_	yyctx,
-#define YY_CTX_ARG	yyctx
-#else
-#define YY_CTX_PARAM_
-#define YY_CTX_PARAM
-#define YY_CTX_ARG_
-#define YY_CTX_ARG
-yycontext yyctx0;
-yycontext *yyctx= &yyctx0;
-#endif
-
-YY_LOCAL(int) yyrefill(yycontext *ctx)
-{
-  int yyn;
-  while (ctx->buflen - ctx->pos < 512)
-    {
-      ctx->buflen *= 2;
-      ctx->buf= (char *)realloc(ctx->buf, ctx->buflen);
-    }
-  YY_INPUT((ctx->buf + ctx->pos), yyn, (ctx->buflen - ctx->pos));
-  if (!yyn) return 0;
-  ctx->limit += yyn;
-  return 1;
-}
-
-YY_LOCAL(int) yymatchDot(yycontext *ctx)
-{
-  if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;
-  ++ctx->pos;
-  return 1;
-}
-
-YY_LOCAL(int) yymatchChar(yycontext *ctx, int c)
-{
-  if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;
-  if ((unsigned char)ctx->buf[ctx->pos] == c)
-    {
-      ++ctx->pos;
-      yyprintf((stderr, "  ok   yymatchChar(ctx, %c) @ %s\n", c, ctx->buf+ctx->pos));
-      return 1;
-    }
-  yyprintf((stderr, "  fail yymatchChar(ctx, %c) @ %s\n", c, ctx->buf+ctx->pos));
-  return 0;
-}
-
-YY_LOCAL(int) yymatchString(yycontext *ctx, char *s)
-{
-  int yysav= ctx->pos;
-  while (*s)
-    {
-      if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;
-      if (ctx->buf[ctx->pos] != *s)
-        {
-          ctx->pos= yysav;
-          return 0;
-        }
-      ++s;
-      ++ctx->pos;
-    }
-  return 1;
-}
-
-YY_LOCAL(int) yymatchClass(yycontext *ctx, unsigned char *bits)
-{
-  int c;
-  if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;
-  c= (unsigned char)ctx->buf[ctx->pos];
-  if (bits[c >> 3] & (1 << (c & 7)))
-    {
-      ++ctx->pos;
-      yyprintf((stderr, "  ok   yymatchClass @ %s\n", ctx->buf+ctx->pos));
-      return 1;
-    }
-  yyprintf((stderr, "  fail yymatchClass @ %s\n", ctx->buf+ctx->pos));
-  return 0;
-}
-
-YY_LOCAL(void) yyDo(yycontext *ctx, yyaction action, int begin, int end)
-{
-  while (ctx->thunkpos >= ctx->thunkslen)
-    {
-      ctx->thunkslen *= 2;
-      ctx->thunks= (yythunk *)realloc(ctx->thunks, sizeof(yythunk) * ctx->thunkslen);
-    }
-  ctx->thunks[ctx->thunkpos].begin=  begin;
-  ctx->thunks[ctx->thunkpos].end=    end;
-  ctx->thunks[ctx->thunkpos].action= action;
-  ++ctx->thunkpos;
-}
-
-YY_LOCAL(int) yyText(yycontext *ctx, int begin, int end)
-{
-  int yyleng= end - begin;
-  if (yyleng <= 0)
-    yyleng= 0;
-  else
-    {
-      while (ctx->textlen < (yyleng + 1))
-	{
-	  ctx->textlen *= 2;
-	  ctx->text= (char *)realloc(ctx->text, ctx->textlen);
-	}
-      memcpy(ctx->text, ctx->buf + begin, yyleng);
-    }
-  ctx->text[yyleng]= '\0';
-  return yyleng;
-}
-
-YY_LOCAL(void) yyDone(yycontext *ctx)
-{
-  int pos;
-  for (pos= 0;  pos < ctx->thunkpos;  ++pos)
-    {
-      yythunk *thunk= &ctx->thunks[pos];
-      int yyleng= thunk->end ? yyText(ctx, thunk->begin, thunk->end) : thunk->begin;
-      yyprintf((stderr, "DO [%d] %p %s\n", pos, thunk->action, ctx->text));
-      thunk->action(ctx, ctx->text, yyleng);
-    }
-  ctx->thunkpos= 0;
-}
-
-YY_LOCAL(void) yyCommit(yycontext *ctx)
-{
-  if ((ctx->limit -= ctx->pos))
-    {
-      memmove(ctx->buf, ctx->buf + ctx->pos, ctx->limit);
-    }
-  ctx->begin -= ctx->pos;
-  ctx->end -= ctx->pos;
-  ctx->pos= ctx->thunkpos= 0;
-}
-
-YY_LOCAL(int) yyAccept(yycontext *ctx, int tp0)
-{
-  if (tp0)
-    {
-      fprintf(stderr, "accept denied at %d\n", tp0);
-      return 0;
-    }
-  else
-    {
-      yyDone(ctx);
-      yyCommit(ctx);
-    }
-  return 1;
-}
-
-YY_LOCAL(void) yyPush(yycontext *ctx, char *text, int count)  { ctx->val += count; }
-YY_LOCAL(void) yyPop(yycontext *ctx, char *text, int count)   { ctx->val -= count; }
-YY_LOCAL(void) yySet(yycontext *ctx, char *text, int count)   { ctx->val[count]= ctx->yy; }
-
-#endif /* YY_PART */
-
-#define	YYACCEPT	yyAccept(ctx, yythunkpos0)
-
-YY_RULE(int) yy_EndOfLine(yycontext *ctx); /* 32 */
-YY_RULE(int) yy_Comment(yycontext *ctx); /* 31 */
-YY_RULE(int) yy_Space(yycontext *ctx); /* 30 */
-YY_RULE(int) yy_Range(yycontext *ctx); /* 29 */
-YY_RULE(int) yy_Char(yycontext *ctx); /* 28 */
-YY_RULE(int) yy_IdentCont(yycontext *ctx); /* 27 */
-YY_RULE(int) yy_IdentStart(yycontext *ctx); /* 26 */
-YY_RULE(int) yy_END(yycontext *ctx); /* 25 */
-YY_RULE(int) yy_BEGIN(yycontext *ctx); /* 24 */
-YY_RULE(int) yy_DOT(yycontext *ctx); /* 23 */
-YY_RULE(int) yy_Class(yycontext *ctx); /* 22 */
-YY_RULE(int) yy_Literal(yycontext *ctx); /* 21 */
-YY_RULE(int) yy_CLOSE(yycontext *ctx); /* 20 */
-YY_RULE(int) yy_OPEN(yycontext *ctx); /* 19 */
-YY_RULE(int) yy_PLUS(yycontext *ctx); /* 18 */
-YY_RULE(int) yy_STAR(yycontext *ctx); /* 17 */
-YY_RULE(int) yy_QUESTION(yycontext *ctx); /* 16 */
-YY_RULE(int) yy_Primary(yycontext *ctx); /* 15 */
-YY_RULE(int) yy_NOT(yycontext *ctx); /* 14 */
-YY_RULE(int) yy_Suffix(yycontext *ctx); /* 13 */
-YY_RULE(int) yy_Action(yycontext *ctx); /* 12 */
-YY_RULE(int) yy_AND(yycontext *ctx); /* 11 */
-YY_RULE(int) yy_Prefix(yycontext *ctx); /* 10 */
-YY_RULE(int) yy_SLASH(yycontext *ctx); /* 9 */
-YY_RULE(int) yy_Sequence(yycontext *ctx); /* 8 */
-YY_RULE(int) yy_Expression(yycontext *ctx); /* 7 */
-YY_RULE(int) yy_LEFTARROW(yycontext *ctx); /* 6 */
-YY_RULE(int) yy_Identifier(yycontext *ctx); /* 5 */
-YY_RULE(int) yy_EndOfFile(yycontext *ctx); /* 4 */
-YY_RULE(int) yy_Definition(yycontext *ctx); /* 3 */
-YY_RULE(int) yy_Spacing(yycontext *ctx); /* 2 */
-YY_RULE(int) yy_Grammar(yycontext *ctx); /* 1 */
-
-YY_ACTION(void) yy_7_Primary(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_7_Primary\n"));
-   push(makePredicate("YY_END")); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_6_Primary(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_6_Primary\n"));
-   push(makePredicate("YY_BEGIN")); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_5_Primary(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_5_Primary\n"));
-   push(makeAction(yytext)); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_4_Primary(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_4_Primary\n"));
-   push(makeDot()); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_3_Primary(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_3_Primary\n"));
-   push(makeClass(yytext)); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_2_Primary(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_2_Primary\n"));
-   push(makeString(yytext)); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_1_Primary(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_1_Primary\n"));
-   push(makeName(findRule(yytext))); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_3_Suffix(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_3_Suffix\n"));
-   push(makePlus (pop())); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_2_Suffix(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_2_Suffix\n"));
-   push(makeStar (pop())); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_1_Suffix(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_1_Suffix\n"));
-   push(makeQuery(pop())); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_3_Prefix(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_3_Prefix\n"));
-   push(makePeekNot(pop())); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_2_Prefix(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_2_Prefix\n"));
-   push(makePeekFor(pop())); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_1_Prefix(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_1_Prefix\n"));
-   push(makePredicate(yytext)); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_2_Sequence(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_2_Sequence\n"));
-   push(makePredicate("1")); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_1_Sequence(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_1_Sequence\n"));
-   Node *f= pop();  push(Sequence_append(pop(), f)); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_1_Expression(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_1_Expression\n"));
-   Node *f= pop();  push(Alternate_append(pop(), f)); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_2_Definition(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_2_Definition\n"));
-   Node *e= pop();  Rule_setExpression(pop(), e); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-YY_ACTION(void) yy_1_Definition(yycontext *ctx, char *yytext, int yyleng)
-{
-#define yy ctx->yy
-#define yypos ctx->pos
-#define yythunkpos ctx->thunkpos
-  yyprintf((stderr, "do yy_1_Definition\n"));
-   if (push(beginRule(findRule(yytext)))->rule.expression) fprintf(stderr, "rule '%s' redefined\n", yytext); ;
-#undef yythunkpos
-#undef yypos
-#undef yy
-}
-
-YY_RULE(int) yy_EndOfLine(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "EndOfLine"));
-  {  int yypos2= ctx->pos, yythunkpos2= ctx->thunkpos;  if (!yymatchString(ctx, "\r\n")) goto l3;  goto l2;
-  l3:;	  ctx->pos= yypos2; ctx->thunkpos= yythunkpos2;  if (!yymatchChar(ctx, '\n')) goto l4;  goto l2;
-  l4:;	  ctx->pos= yypos2; ctx->thunkpos= yythunkpos2;  if (!yymatchChar(ctx, '\r')) goto l1;
-  }
-  l2:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "EndOfLine", ctx->buf+ctx->pos));
-  return 1;
-  l1:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "EndOfLine", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_Comment(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "Comment"));  if (!yymatchChar(ctx, '#')) goto l5;
-  l6:;	
-  {  int yypos7= ctx->pos, yythunkpos7= ctx->thunkpos;
-  {  int yypos8= ctx->pos, yythunkpos8= ctx->thunkpos;  if (!yy_EndOfLine(ctx)) goto l8;  goto l7;
-  l8:;	  ctx->pos= yypos8; ctx->thunkpos= yythunkpos8;
-  }  if (!yymatchDot(ctx)) goto l7;  goto l6;
-  l7:;	  ctx->pos= yypos7; ctx->thunkpos= yythunkpos7;
-  }  if (!yy_EndOfLine(ctx)) goto l5;
-  yyprintf((stderr, "  ok   %s @ %s\n", "Comment", ctx->buf+ctx->pos));
-  return 1;
-  l5:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "Comment", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_Space(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "Space"));
-  {  int yypos10= ctx->pos, yythunkpos10= ctx->thunkpos;  if (!yymatchChar(ctx, ' ')) goto l11;  goto l10;
-  l11:;	  ctx->pos= yypos10; ctx->thunkpos= yythunkpos10;  if (!yymatchChar(ctx, '\t')) goto l12;  goto l10;
-  l12:;	  ctx->pos= yypos10; ctx->thunkpos= yythunkpos10;  if (!yy_EndOfLine(ctx)) goto l9;
-  }
-  l10:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "Space", ctx->buf+ctx->pos));
-  return 1;
-  l9:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "Space", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_Range(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "Range"));
-  {  int yypos14= ctx->pos, yythunkpos14= ctx->thunkpos;  if (!yy_Char(ctx)) goto l15;  if (!yymatchChar(ctx, '-')) goto l15;  if (!yy_Char(ctx)) goto l15;  goto l14;
-  l15:;	  ctx->pos= yypos14; ctx->thunkpos= yythunkpos14;  if (!yy_Char(ctx)) goto l13;
-  }
-  l14:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "Range", ctx->buf+ctx->pos));
-  return 1;
-  l13:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "Range", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_Char(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "Char"));
-  {  int yypos17= ctx->pos, yythunkpos17= ctx->thunkpos;  if (!yymatchChar(ctx, '\\')) goto l18;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\204\000\000\000\000\000\000\070\146\100\124\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l18;  goto l17;
-  l18:;	  ctx->pos= yypos17; ctx->thunkpos= yythunkpos17;  if (!yymatchChar(ctx, '\\')) goto l19;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l19;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l19;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l19;  goto l17;
-  l19:;	  ctx->pos= yypos17; ctx->thunkpos= yythunkpos17;  if (!yymatchChar(ctx, '\\')) goto l20;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l20;
-  {  int yypos21= ctx->pos, yythunkpos21= ctx->thunkpos;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l21;  goto l22;
-  l21:;	  ctx->pos= yypos21; ctx->thunkpos= yythunkpos21;
-  }
-  l22:;	  goto l17;
-  l20:;	  ctx->pos= yypos17; ctx->thunkpos= yythunkpos17;  if (!yymatchChar(ctx, '\\')) goto l23;  if (!yymatchChar(ctx, '-')) goto l23;  goto l17;
-  l23:;	  ctx->pos= yypos17; ctx->thunkpos= yythunkpos17;
-  {  int yypos24= ctx->pos, yythunkpos24= ctx->thunkpos;  if (!yymatchChar(ctx, '\\')) goto l24;  goto l16;
-  l24:;	  ctx->pos= yypos24; ctx->thunkpos= yythunkpos24;
-  }  if (!yymatchDot(ctx)) goto l16;
-  }
-  l17:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "Char", ctx->buf+ctx->pos));
-  return 1;
-  l16:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "Char", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_IdentCont(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "IdentCont"));
-  {  int yypos26= ctx->pos, yythunkpos26= ctx->thunkpos;  if (!yy_IdentStart(ctx)) goto l27;  goto l26;
-  l27:;	  ctx->pos= yypos26; ctx->thunkpos= yythunkpos26;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l25;
-  }
-  l26:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "IdentCont", ctx->buf+ctx->pos));
-  return 1;
-  l25:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "IdentCont", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_IdentStart(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "IdentStart"));  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\000\000\000\000\376\377\377\207\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l28;
-  yyprintf((stderr, "  ok   %s @ %s\n", "IdentStart", ctx->buf+ctx->pos));
-  return 1;
-  l28:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "IdentStart", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_END(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "END"));  if (!yymatchChar(ctx, '>')) goto l29;  if (!yy_Spacing(ctx)) goto l29;
-  yyprintf((stderr, "  ok   %s @ %s\n", "END", ctx->buf+ctx->pos));
-  return 1;
-  l29:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "END", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_BEGIN(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "BEGIN"));  if (!yymatchChar(ctx, '<')) goto l30;  if (!yy_Spacing(ctx)) goto l30;
-  yyprintf((stderr, "  ok   %s @ %s\n", "BEGIN", ctx->buf+ctx->pos));
-  return 1;
-  l30:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "BEGIN", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_DOT(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "DOT"));  if (!yymatchChar(ctx, '.')) goto l31;  if (!yy_Spacing(ctx)) goto l31;
-  yyprintf((stderr, "  ok   %s @ %s\n", "DOT", ctx->buf+ctx->pos));
-  return 1;
-  l31:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "DOT", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_Class(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "Class"));  if (!yymatchChar(ctx, '[')) goto l32;  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_BEGIN)) goto l32;
-  l33:;	
-  {  int yypos34= ctx->pos, yythunkpos34= ctx->thunkpos;
-  {  int yypos35= ctx->pos, yythunkpos35= ctx->thunkpos;  if (!yymatchChar(ctx, ']')) goto l35;  goto l34;
-  l35:;	  ctx->pos= yypos35; ctx->thunkpos= yythunkpos35;
-  }  if (!yy_Range(ctx)) goto l34;  goto l33;
-  l34:;	  ctx->pos= yypos34; ctx->thunkpos= yythunkpos34;
-  }  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_END)) goto l32;  if (!yymatchChar(ctx, ']')) goto l32;  if (!yy_Spacing(ctx)) goto l32;
-  yyprintf((stderr, "  ok   %s @ %s\n", "Class", ctx->buf+ctx->pos));
-  return 1;
-  l32:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "Class", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_Literal(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "Literal"));
-  {  int yypos37= ctx->pos, yythunkpos37= ctx->thunkpos;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l38;  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_BEGIN)) goto l38;
-  l39:;	
-  {  int yypos40= ctx->pos, yythunkpos40= ctx->thunkpos;
-  {  int yypos41= ctx->pos, yythunkpos41= ctx->thunkpos;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l41;  goto l40;
-  l41:;	  ctx->pos= yypos41; ctx->thunkpos= yythunkpos41;
-  }  if (!yy_Char(ctx)) goto l40;  goto l39;
-  l40:;	  ctx->pos= yypos40; ctx->thunkpos= yythunkpos40;
-  }  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_END)) goto l38;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l38;  if (!yy_Spacing(ctx)) goto l38;  goto l37;
-  l38:;	  ctx->pos= yypos37; ctx->thunkpos= yythunkpos37;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l36;  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_BEGIN)) goto l36;
-  l42:;	
-  {  int yypos43= ctx->pos, yythunkpos43= ctx->thunkpos;
-  {  int yypos44= ctx->pos, yythunkpos44= ctx->thunkpos;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l44;  goto l43;
-  l44:;	  ctx->pos= yypos44; ctx->thunkpos= yythunkpos44;
-  }  if (!yy_Char(ctx)) goto l43;  goto l42;
-  l43:;	  ctx->pos= yypos43; ctx->thunkpos= yythunkpos43;
-  }  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_END)) goto l36;  if (!yymatchClass(ctx, (unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l36;  if (!yy_Spacing(ctx)) goto l36;
-  }
-  l37:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "Literal", ctx->buf+ctx->pos));
-  return 1;
-  l36:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "Literal", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_CLOSE(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "CLOSE"));  if (!yymatchChar(ctx, ')')) goto l45;  if (!yy_Spacing(ctx)) goto l45;
-  yyprintf((stderr, "  ok   %s @ %s\n", "CLOSE", ctx->buf+ctx->pos));
-  return 1;
-  l45:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "CLOSE", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_OPEN(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "OPEN"));  if (!yymatchChar(ctx, '(')) goto l46;  if (!yy_Spacing(ctx)) goto l46;
-  yyprintf((stderr, "  ok   %s @ %s\n", "OPEN", ctx->buf+ctx->pos));
-  return 1;
-  l46:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "OPEN", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_PLUS(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "PLUS"));  if (!yymatchChar(ctx, '+')) goto l47;  if (!yy_Spacing(ctx)) goto l47;
-  yyprintf((stderr, "  ok   %s @ %s\n", "PLUS", ctx->buf+ctx->pos));
-  return 1;
-  l47:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "PLUS", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_STAR(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "STAR"));  if (!yymatchChar(ctx, '*')) goto l48;  if (!yy_Spacing(ctx)) goto l48;
-  yyprintf((stderr, "  ok   %s @ %s\n", "STAR", ctx->buf+ctx->pos));
-  return 1;
-  l48:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "STAR", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_QUESTION(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "QUESTION"));  if (!yymatchChar(ctx, '?')) goto l49;  if (!yy_Spacing(ctx)) goto l49;
-  yyprintf((stderr, "  ok   %s @ %s\n", "QUESTION", ctx->buf+ctx->pos));
-  return 1;
-  l49:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "QUESTION", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_Primary(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "Primary"));
-  {  int yypos51= ctx->pos, yythunkpos51= ctx->thunkpos;  if (!yy_Identifier(ctx)) goto l52;
-  {  int yypos53= ctx->pos, yythunkpos53= ctx->thunkpos;  if (!yy_LEFTARROW(ctx)) goto l53;  goto l52;
-  l53:;	  ctx->pos= yypos53; ctx->thunkpos= yythunkpos53;
-  }  yyDo(ctx, yy_1_Primary, ctx->begin, ctx->end);  goto l51;
-  l52:;	  ctx->pos= yypos51; ctx->thunkpos= yythunkpos51;  if (!yy_OPEN(ctx)) goto l54;  if (!yy_Expression(ctx)) goto l54;  if (!yy_CLOSE(ctx)) goto l54;  goto l51;
-  l54:;	  ctx->pos= yypos51; ctx->thunkpos= yythunkpos51;  if (!yy_Literal(ctx)) goto l55;  yyDo(ctx, yy_2_Primary, ctx->begin, ctx->end);  goto l51;
-  l55:;	  ctx->pos= yypos51; ctx->thunkpos= yythunkpos51;  if (!yy_Class(ctx)) goto l56;  yyDo(ctx, yy_3_Primary, ctx->begin, ctx->end);  goto l51;
-  l56:;	  ctx->pos= yypos51; ctx->thunkpos= yythunkpos51;  if (!yy_DOT(ctx)) goto l57;  yyDo(ctx, yy_4_Primary, ctx->begin, ctx->end);  goto l51;
-  l57:;	  ctx->pos= yypos51; ctx->thunkpos= yythunkpos51;  if (!yy_Action(ctx)) goto l58;  yyDo(ctx, yy_5_Primary, ctx->begin, ctx->end);  goto l51;
-  l58:;	  ctx->pos= yypos51; ctx->thunkpos= yythunkpos51;  if (!yy_BEGIN(ctx)) goto l59;  yyDo(ctx, yy_6_Primary, ctx->begin, ctx->end);  goto l51;
-  l59:;	  ctx->pos= yypos51; ctx->thunkpos= yythunkpos51;  if (!yy_END(ctx)) goto l50;  yyDo(ctx, yy_7_Primary, ctx->begin, ctx->end);
-  }
-  l51:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "Primary", ctx->buf+ctx->pos));
-  return 1;
-  l50:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "Primary", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_NOT(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "NOT"));  if (!yymatchChar(ctx, '!')) goto l60;  if (!yy_Spacing(ctx)) goto l60;
-  yyprintf((stderr, "  ok   %s @ %s\n", "NOT", ctx->buf+ctx->pos));
-  return 1;
-  l60:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "NOT", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_Suffix(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "Suffix"));  if (!yy_Primary(ctx)) goto l61;
-  {  int yypos62= ctx->pos, yythunkpos62= ctx->thunkpos;
-  {  int yypos64= ctx->pos, yythunkpos64= ctx->thunkpos;  if (!yy_QUESTION(ctx)) goto l65;  yyDo(ctx, yy_1_Suffix, ctx->begin, ctx->end);  goto l64;
-  l65:;	  ctx->pos= yypos64; ctx->thunkpos= yythunkpos64;  if (!yy_STAR(ctx)) goto l66;  yyDo(ctx, yy_2_Suffix, ctx->begin, ctx->end);  goto l64;
-  l66:;	  ctx->pos= yypos64; ctx->thunkpos= yythunkpos64;  if (!yy_PLUS(ctx)) goto l62;  yyDo(ctx, yy_3_Suffix, ctx->begin, ctx->end);
-  }
-  l64:;	  goto l63;
-  l62:;	  ctx->pos= yypos62; ctx->thunkpos= yythunkpos62;
-  }
-  l63:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "Suffix", ctx->buf+ctx->pos));
-  return 1;
-  l61:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "Suffix", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_Action(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "Action"));  if (!yymatchChar(ctx, '{')) goto l67;  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_BEGIN)) goto l67;
-  l68:;	
-  {  int yypos69= ctx->pos, yythunkpos69= ctx->thunkpos;  if (!yymatchClass(ctx, (unsigned char *)"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\337\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377")) goto l69;  goto l68;
-  l69:;	  ctx->pos= yypos69; ctx->thunkpos= yythunkpos69;
-  }  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_END)) goto l67;  if (!yymatchChar(ctx, '}')) goto l67;  if (!yy_Spacing(ctx)) goto l67;
-  yyprintf((stderr, "  ok   %s @ %s\n", "Action", ctx->buf+ctx->pos));
-  return 1;
-  l67:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "Action", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_AND(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "AND"));  if (!yymatchChar(ctx, '&')) goto l70;  if (!yy_Spacing(ctx)) goto l70;
-  yyprintf((stderr, "  ok   %s @ %s\n", "AND", ctx->buf+ctx->pos));
-  return 1;
-  l70:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "AND", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_Prefix(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "Prefix"));
-  {  int yypos72= ctx->pos, yythunkpos72= ctx->thunkpos;  if (!yy_AND(ctx)) goto l73;  if (!yy_Action(ctx)) goto l73;  yyDo(ctx, yy_1_Prefix, ctx->begin, ctx->end);  goto l72;
-  l73:;	  ctx->pos= yypos72; ctx->thunkpos= yythunkpos72;  if (!yy_AND(ctx)) goto l74;  if (!yy_Suffix(ctx)) goto l74;  yyDo(ctx, yy_2_Prefix, ctx->begin, ctx->end);  goto l72;
-  l74:;	  ctx->pos= yypos72; ctx->thunkpos= yythunkpos72;  if (!yy_NOT(ctx)) goto l75;  if (!yy_Suffix(ctx)) goto l75;  yyDo(ctx, yy_3_Prefix, ctx->begin, ctx->end);  goto l72;
-  l75:;	  ctx->pos= yypos72; ctx->thunkpos= yythunkpos72;  if (!yy_Suffix(ctx)) goto l71;
-  }
-  l72:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "Prefix", ctx->buf+ctx->pos));
-  return 1;
-  l71:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "Prefix", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_SLASH(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "SLASH"));  if (!yymatchChar(ctx, '/')) goto l76;  if (!yy_Spacing(ctx)) goto l76;
-  yyprintf((stderr, "  ok   %s @ %s\n", "SLASH", ctx->buf+ctx->pos));
-  return 1;
-  l76:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "SLASH", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_Sequence(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "Sequence"));
-  {  int yypos78= ctx->pos, yythunkpos78= ctx->thunkpos;  if (!yy_Prefix(ctx)) goto l79;
-  l80:;	
-  {  int yypos81= ctx->pos, yythunkpos81= ctx->thunkpos;  if (!yy_Prefix(ctx)) goto l81;  yyDo(ctx, yy_1_Sequence, ctx->begin, ctx->end);  goto l80;
-  l81:;	  ctx->pos= yypos81; ctx->thunkpos= yythunkpos81;
-  }  goto l78;
-  l79:;	  ctx->pos= yypos78; ctx->thunkpos= yythunkpos78;  yyDo(ctx, yy_2_Sequence, ctx->begin, ctx->end);
-  }
-  l78:;	
-  yyprintf((stderr, "  ok   %s @ %s\n", "Sequence", ctx->buf+ctx->pos));
-  return 1;
-  l77:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "Sequence", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_Expression(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "Expression"));  if (!yy_Sequence(ctx)) goto l82;
-  l83:;	
-  {  int yypos84= ctx->pos, yythunkpos84= ctx->thunkpos;  if (!yy_SLASH(ctx)) goto l84;  if (!yy_Sequence(ctx)) goto l84;  yyDo(ctx, yy_1_Expression, ctx->begin, ctx->end);  goto l83;
-  l84:;	  ctx->pos= yypos84; ctx->thunkpos= yythunkpos84;
-  }
-  yyprintf((stderr, "  ok   %s @ %s\n", "Expression", ctx->buf+ctx->pos));
-  return 1;
-  l82:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "Expression", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_LEFTARROW(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "LEFTARROW"));  if (!yymatchString(ctx, "<-")) goto l85;  if (!yy_Spacing(ctx)) goto l85;
-  yyprintf((stderr, "  ok   %s @ %s\n", "LEFTARROW", ctx->buf+ctx->pos));
-  return 1;
-  l85:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "LEFTARROW", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_Identifier(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "Identifier"));  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_BEGIN)) goto l86;  if (!yy_IdentStart(ctx)) goto l86;
-  l87:;	
-  {  int yypos88= ctx->pos, yythunkpos88= ctx->thunkpos;  if (!yy_IdentCont(ctx)) goto l88;  goto l87;
-  l88:;	  ctx->pos= yypos88; ctx->thunkpos= yythunkpos88;
-  }  yyText(ctx, ctx->begin, ctx->end);  if (!(YY_END)) goto l86;  if (!yy_Spacing(ctx)) goto l86;
-  yyprintf((stderr, "  ok   %s @ %s\n", "Identifier", ctx->buf+ctx->pos));
-  return 1;
-  l86:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "Identifier", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_EndOfFile(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "EndOfFile"));
-  {  int yypos90= ctx->pos, yythunkpos90= ctx->thunkpos;  if (!yymatchDot(ctx)) goto l90;  goto l89;
-  l90:;	  ctx->pos= yypos90; ctx->thunkpos= yythunkpos90;
-  }
-  yyprintf((stderr, "  ok   %s @ %s\n", "EndOfFile", ctx->buf+ctx->pos));
-  return 1;
-  l89:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "EndOfFile", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_Definition(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "Definition"));  if (!yy_Identifier(ctx)) goto l91;  yyDo(ctx, yy_1_Definition, ctx->begin, ctx->end);  if (!yy_LEFTARROW(ctx)) goto l91;  if (!yy_Expression(ctx)) goto l91;  yyDo(ctx, yy_2_Definition, ctx->begin, ctx->end);  yyText(ctx, ctx->begin, ctx->end);  if (!( YYACCEPT )) goto l91;
-  yyprintf((stderr, "  ok   %s @ %s\n", "Definition", ctx->buf+ctx->pos));
-  return 1;
-  l91:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "Definition", ctx->buf+ctx->pos));
-  return 0;
-}
-YY_RULE(int) yy_Spacing(yycontext *ctx)
-{
-  yyprintf((stderr, "%s\n", "Spacing"));
-  l93:;	
-  {  int yypos94= ctx->pos, yythunkpos94= ctx->thunkpos;
-  {  int yypos95= ctx->pos, yythunkpos95= ctx->thunkpos;  if (!yy_Space(ctx)) goto l96;  goto l95;
-  l96:;	  ctx->pos= yypos95; ctx->thunkpos= yythunkpos95;  if (!yy_Comment(ctx)) goto l94;
-  }
-  l95:;	  goto l93;
-  l94:;	  ctx->pos= yypos94; ctx->thunkpos= yythunkpos94;
-  }
-  yyprintf((stderr, "  ok   %s @ %s\n", "Spacing", ctx->buf+ctx->pos));
-  return 1;
-}
-YY_RULE(int) yy_Grammar(yycontext *ctx)
-{  int yypos0= ctx->pos, yythunkpos0= ctx->thunkpos;
-  yyprintf((stderr, "%s\n", "Grammar"));  if (!yy_Spacing(ctx)) goto l97;  if (!yy_Definition(ctx)) goto l97;
-  l98:;	
-  {  int yypos99= ctx->pos, yythunkpos99= ctx->thunkpos;  if (!yy_Definition(ctx)) goto l99;  goto l98;
-  l99:;	  ctx->pos= yypos99; ctx->thunkpos= yythunkpos99;
-  }  if (!yy_EndOfFile(ctx)) goto l97;
-  yyprintf((stderr, "  ok   %s @ %s\n", "Grammar", ctx->buf+ctx->pos));
-  return 1;
-  l97:;	  ctx->pos= yypos0; ctx->thunkpos= yythunkpos0;
-  yyprintf((stderr, "  fail %s @ %s\n", "Grammar", ctx->buf+ctx->pos));
-  return 0;
-}
-
-#ifndef YY_PART
-
-typedef int (*yyrule)(yycontext *ctx);
-
-YY_PARSE(int) YYPARSEFROM(YY_CTX_PARAM_ yyrule yystart)
-{
-  int yyok;
-  if (!yyctx->buflen)
-    {
-      yyctx->buflen= 1024;
-      yyctx->buf= (char *)malloc(yyctx->buflen);
-      yyctx->textlen= 1024;
-      yyctx->text= (char *)malloc(yyctx->textlen);
-      yyctx->thunkslen= 32;
-      yyctx->thunks= (yythunk *)malloc(sizeof(yythunk) * yyctx->thunkslen);
-      yyctx->valslen= 32;
-      yyctx->vals= (YYSTYPE *)malloc(sizeof(YYSTYPE) * yyctx->valslen);
-      yyctx->begin= yyctx->end= yyctx->pos= yyctx->limit= yyctx->thunkpos= 0;
-    }
-  yyctx->begin= yyctx->end= yyctx->pos;
-  yyctx->thunkpos= 0;
-  yyctx->val= yyctx->vals;
-  yyok= yystart(yyctx);
-  if (yyok) yyDone(yyctx);
-  yyCommit(yyctx);
-  return yyok;
-}
-
-YY_PARSE(int) YYPARSE(YY_CTX_PARAM)
-{
-  return YYPARSEFROM(YY_CTX_ARG_ yy_Grammar);
-}
-
-#endif
--- /dev/null
+++ b/peg.sln
@@ -1,0 +1,27 @@
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "leg", "leg.vcxproj", "{5ECEC9E5-8F23-47B6-93E0-C3B328B3BE66}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "peg", "peg.vcxproj", "{5ECEC9E5-8F23-47B6-93E0-C3B328B3BE65}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{5ECEC9E5-8F23-47B6-93E0-C3B328B3BE65}.Debug|Win32.ActiveCfg = Debug|Win32
+		{5ECEC9E5-8F23-47B6-93E0-C3B328B3BE65}.Debug|Win32.Build.0 = Debug|Win32
+		{5ECEC9E5-8F23-47B6-93E0-C3B328B3BE65}.Release|Win32.ActiveCfg = Release|Win32
+		{5ECEC9E5-8F23-47B6-93E0-C3B328B3BE65}.Release|Win32.Build.0 = Release|Win32
+		{5ECEC9E5-8F23-47B6-93E0-C3B328B3BE66}.Debug|Win32.ActiveCfg = Debug|Win32
+		{5ECEC9E5-8F23-47B6-93E0-C3B328B3BE66}.Debug|Win32.Build.0 = Debug|Win32
+		{5ECEC9E5-8F23-47B6-93E0-C3B328B3BE66}.Release|Win32.ActiveCfg = Release|Win32
+		{5ECEC9E5-8F23-47B6-93E0-C3B328B3BE66}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(NestedProjects) = preSolution
+	EndGlobalSection
+EndGlobal
--- /dev/null
+++ b/peg.vcxproj
@@ -1,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{5ECEC9E5-8F23-47B6-93E0-C3B328B3BE65}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>peg</RootNamespace>
+    <TargetName>$(ProjectName)</TargetName>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings" />
+  <ImportGroup Label="PropertySheets">
+    <Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <ExecutablePath>$(ExecutablePath);$(MSBuildProjectDirectory)\.\bin\;$(MSBuildProjectDirectory)\.\bin\</ExecutablePath>
+    <IntDir>$(Configuration)\obj\$(ProjectName)\</IntDir>
+    <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>win;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <OutputFile>$(OutDir)$(ProjectName).exe</OutputFile>
+      <SubSystem>Console</SubSystem>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>win;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;DEBUG;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>win;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <OutputFile>$(OutDir)$(ProjectName).exe</OutputFile>
+      <SubSystem>Console</SubSystem>
+    </Link>
+    <ResourceCompile>
+      <AdditionalIncludeDirectories>win;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions);%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <None Include="peg.gyp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="src\compile.c" />
+    <ClCompile Include="src\peg.c" />
+    <ClCompile Include="src\tree.c" />
+    <ClCompile Include="win\getopt.c" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets" />
+</Project>
\ No newline at end of file
--- /dev/null
+++ b/peg.vcxproj.filters
@@ -1,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="win">
+      <UniqueIdentifier>{47FC5EC4-15EB-E92F-89D7-AFE51CF838A9}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="peg.gyp" />
+    <ClCompile Include="win\getopt.c">
+      <Filter>win</Filter>
+    </ClCompile>
+    <ClCompile Include="src\compile.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="src\peg.c" />
+    <ClCompile Include="src\tree.c" />
+  </ItemGroup>
+</Project>
\ No newline at end of file
--- /dev/null
+++ b/peg.xcodeproj/project.pbxproj
@@ -1,0 +1,317 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 45;
+	objects = {
+
+/* Begin PBXAggregateTarget section */
+		EFBC7368F96EACB75989C21D /* All */ = {
+			isa = PBXAggregateTarget;
+			buildConfigurationList = 007E1122105A105C63F8A59F /* Build configuration list for PBXAggregateTarget "All" */;
+			buildPhases = (
+			);
+			dependencies = (
+				B85F90055126E00C1334834C /* PBXTargetDependency */,
+				3DF530CEA77A591E4DFBFF2F /* PBXTargetDependency */,
+			);
+			name = All;
+			productName = All;
+		};
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+		2D4E663DE432A398FC78635B /* compile.c in Sources */ = {isa = PBXBuildFile; fileRef = D4BAF07C3AF28E51DD58E853 /* compile.c */; };
+		3FE25C706AB45972C102CBB4 /* tree.c in Sources */ = {isa = PBXBuildFile; fileRef = E503317C684EFEB3E7E03861 /* tree.c */; };
+		4D30CEABCD51397A50F65058 /* compile.c in Sources */ = {isa = PBXBuildFile; fileRef = D4BAF07C3AF28E51DD58E853 /* compile.c */; };
+		7921C7C2AD25A4A4C02470F5 /* peg.c in Sources */ = {isa = PBXBuildFile; fileRef = 27FA3C119507A9A914A66936 /* peg.c */; };
+		8B61C6AE75A1750C17350E64 /* tree.c in Sources */ = {isa = PBXBuildFile; fileRef = E503317C684EFEB3E7E03861 /* tree.c */; };
+		D8C3FFD80B6642D8BB341B90 /* leg.c in Sources */ = {isa = PBXBuildFile; fileRef = 454F9F599E7B65F90C62CF9C /* leg.c */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+		12CD2CA862C5C1693300D7EF /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = D23EA86C97C1C940E2591A06 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 84A1E5C1231D1E337ED0FC84;
+			remoteInfo = leg;
+		};
+		22C9A5E8EF76D4B801BB24E5 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = D23EA86C97C1C940E2591A06 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 050EA9DBA8F5C296C3E39B8A;
+			remoteInfo = peg;
+		};
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+		27FA3C119507A9A914A66936 /* peg.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = src/peg.c; sourceTree = "<group>"; };
+		4165F882B6F541E12DBD6A0D /* peg */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = peg; sourceTree = BUILT_PRODUCTS_DIR; };
+		454F9F599E7B65F90C62CF9C /* leg.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = src/leg.c; sourceTree = "<group>"; };
+		5C991B5472A7498A982B7350 /* peg.gyp */ = {isa = PBXFileReference; lastKnownFileType = text; path = peg.gyp; sourceTree = "<group>"; };
+		C9B3F1D07DD720C50DE87DC5 /* leg */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = leg; sourceTree = BUILT_PRODUCTS_DIR; };
+		D4BAF07C3AF28E51DD58E853 /* compile.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = src/compile.c; sourceTree = "<group>"; };
+		E503317C684EFEB3E7E03861 /* tree.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = src/tree.c; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		3DF86BD64E76AD4F8D892CF6 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		97D5812F2529A3E39CE17CDE /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		3854A05A8AE7E9B329F09174 /* Build */ = {
+			isa = PBXGroup;
+			children = (
+				5C991B5472A7498A982B7350 /* peg.gyp */,
+			);
+			name = Build;
+			sourceTree = "<group>";
+		};
+		AB7FD4EAF4FFE1A1CE63E31B = {
+			isa = PBXGroup;
+			children = (
+				E2D71C5771542F758C302162 /* Source */,
+				AF64E60ED33C9E5DC5DB4C21 /* Products */,
+				3854A05A8AE7E9B329F09174 /* Build */,
+			);
+			sourceTree = "<group>";
+		};
+		AF64E60ED33C9E5DC5DB4C21 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				4165F882B6F541E12DBD6A0D /* peg */,
+				C9B3F1D07DD720C50DE87DC5 /* leg */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		E2D71C5771542F758C302162 /* Source */ = {
+			isa = PBXGroup;
+			children = (
+				D4BAF07C3AF28E51DD58E853 /* compile.c */,
+				454F9F599E7B65F90C62CF9C /* leg.c */,
+				27FA3C119507A9A914A66936 /* peg.c */,
+				E503317C684EFEB3E7E03861 /* tree.c */,
+			);
+			name = Source;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		050EA9DBA8F5C296C3E39B8A /* peg */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = EF4B00311D83FC2C01B276A4 /* Build configuration list for PBXNativeTarget "peg" */;
+			buildPhases = (
+				74AA795D8990365CCE282118 /* Sources */,
+				97D5812F2529A3E39CE17CDE /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = peg;
+			productName = peg;
+			productReference = 4165F882B6F541E12DBD6A0D /* peg */;
+			productType = "com.apple.product-type.tool";
+		};
+		84A1E5C1231D1E337ED0FC84 /* leg */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = F7568C4D321FF46C2F4B43FB /* Build configuration list for PBXNativeTarget "leg" */;
+			buildPhases = (
+				915DAD0C515729956FE2BC69 /* Sources */,
+				3DF86BD64E76AD4F8D892CF6 /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = leg;
+			productName = leg;
+			productReference = C9B3F1D07DD720C50DE87DC5 /* leg */;
+			productType = "com.apple.product-type.tool";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		D23EA86C97C1C940E2591A06 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				BuildIndependentTargetsInParallel = YES;
+			};
+			buildConfigurationList = 283B121430353A60CB56914F /* Build configuration list for PBXProject "peg" */;
+			compatibilityVersion = "Xcode 3.2";
+			hasScannedForEncodings = 1;
+			mainGroup = AB7FD4EAF4FFE1A1CE63E31B;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				EFBC7368F96EACB75989C21D /* All */,
+				050EA9DBA8F5C296C3E39B8A /* peg */,
+				84A1E5C1231D1E337ED0FC84 /* leg */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+		74AA795D8990365CCE282118 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				7921C7C2AD25A4A4C02470F5 /* peg.c in Sources */,
+				8B61C6AE75A1750C17350E64 /* tree.c in Sources */,
+				4D30CEABCD51397A50F65058 /* compile.c in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		915DAD0C515729956FE2BC69 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				D8C3FFD80B6642D8BB341B90 /* leg.c in Sources */,
+				3FE25C706AB45972C102CBB4 /* tree.c in Sources */,
+				2D4E663DE432A398FC78635B /* compile.c in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+		3DF530CEA77A591E4DFBFF2F /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 84A1E5C1231D1E337ED0FC84 /* leg */;
+			targetProxy = 12CD2CA862C5C1693300D7EF /* PBXContainerItemProxy */;
+		};
+		B85F90055126E00C1334834C /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 050EA9DBA8F5C296C3E39B8A /* peg */;
+			targetProxy = 22C9A5E8EF76D4B801BB24E5 /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+		05AA053A004215362908ED84 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				EXECUTABLE_PREFIX = "";
+				GCC_PREPROCESSOR_DEFINITIONS = "\"NDEBUG\"";
+				PRODUCT_NAME = peg;
+			};
+			name = Release;
+		};
+		2CB45BB7949774F10834EB3B /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				INTERMEDIATE_DIR = "$(PROJECT_DERIVED_FILE_DIR)/$(CONFIGURATION)";
+				SHARED_INTERMEDIATE_DIR = "$(SYMROOT)/DerivedSources/$(CONFIGURATION)";
+			};
+			name = Release;
+		};
+		7C93F597151F1782DBAF2E6E /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				INTERMEDIATE_DIR = "$(PROJECT_DERIVED_FILE_DIR)/$(CONFIGURATION)";
+				SHARED_INTERMEDIATE_DIR = "$(SYMROOT)/DerivedSources/$(CONFIGURATION)";
+			};
+			name = Debug;
+		};
+		879858F43394AA4CEFDC7263 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				EXECUTABLE_PREFIX = "";
+				GCC_PREPROCESSOR_DEFINITIONS = "\"NDEBUG\"";
+				PRODUCT_NAME = leg;
+			};
+			name = Release;
+		};
+		8CF09EF6E825DDB8D49A6EA9 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = All;
+			};
+			name = Release;
+		};
+		DEFEA64AA5600BECDDA9A939 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = All;
+			};
+			name = Debug;
+		};
+		E2B1202070FAC019FA0BF2ED /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				EXECUTABLE_PREFIX = "";
+				GCC_PREPROCESSOR_DEFINITIONS = "\"DEBUG\"";
+				PRODUCT_NAME = leg;
+			};
+			name = Debug;
+		};
+		F41144D27A6369001B96C713 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				EXECUTABLE_PREFIX = "";
+				GCC_PREPROCESSOR_DEFINITIONS = "\"DEBUG\"";
+				PRODUCT_NAME = peg;
+			};
+			name = Debug;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		007E1122105A105C63F8A59F /* Build configuration list for PBXAggregateTarget "All" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				DEFEA64AA5600BECDDA9A939 /* Debug */,
+				8CF09EF6E825DDB8D49A6EA9 /* Release */,
+			);
+			defaultConfigurationIsVisible = 1;
+			defaultConfigurationName = Debug;
+		};
+		283B121430353A60CB56914F /* Build configuration list for PBXProject "peg" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				7C93F597151F1782DBAF2E6E /* Debug */,
+				2CB45BB7949774F10834EB3B /* Release */,
+			);
+			defaultConfigurationIsVisible = 1;
+			defaultConfigurationName = Debug;
+		};
+		EF4B00311D83FC2C01B276A4 /* Build configuration list for PBXNativeTarget "peg" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				F41144D27A6369001B96C713 /* Debug */,
+				05AA053A004215362908ED84 /* Release */,
+			);
+			defaultConfigurationIsVisible = 1;
+			defaultConfigurationName = Debug;
+		};
+		F7568C4D321FF46C2F4B43FB /* Build configuration list for PBXNativeTarget "leg" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				E2B1202070FAC019FA0BF2ED /* Debug */,
+				879858F43394AA4CEFDC7263 /* Release */,
+			);
+			defaultConfigurationIsVisible = 1;
+			defaultConfigurationName = Debug;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = D23EA86C97C1C940E2591A06 /* Project object */;
+}
--- /dev/null
+++ b/src/compile.c
@@ -1,0 +1,797 @@
+/* Copyright (c) 2007, 2012 by Ian Piumarta
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the 'Software'),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, provided that the above copyright notice(s) and this
+ * permission notice appear in all copies of the Software.  Acknowledgement
+ * of the use of this Software in supporting documentation would be
+ * appreciated but is not required.
+ * 
+ * THE SOFTWARE IS PROVIDED 'AS IS'.  USE ENTIRELY AT YOUR OWN RISK.
+ * 
+ * Last edited: 2013-06-06 12:24:20 by piumarta on ubuntu
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#ifdef WIN32
+# undef inline
+# define inline __inline
+#endif
+
+#include "version.h"
+#include "tree.h"
+
+static int yyl(void)
+{
+  static int prev= 0;
+  return ++prev;
+}
+
+static void charClassSet  (unsigned char bits[], int c)	{ bits[c >> 3] |=  (1 << (c & 7)); }
+static void charClassClear(unsigned char bits[], int c)	{ bits[c >> 3] &= ~(1 << (c & 7)); }
+
+typedef void (*setter)(unsigned char bits[], int c);
+
+static inline int oigit(int c)	{ return '0' <= c && c <= '7'; }
+
+static int cnext(unsigned char **ccp)
+{
+    unsigned char *cclass= *ccp;
+    int c= *cclass++;
+    if (c)
+    {
+	if ('\\' == c && *cclass)
+	{
+	    switch (c= *cclass++)
+	    {
+		case 'a':  c= '\a';   break;	/* bel */
+		case 'b':  c= '\b';   break;	/* bs */
+		case 'e':  c= '\033'; break;	/* esc */
+		case 'f':  c= '\f';   break;	/* ff */
+		case 'n':  c= '\n';   break;	/* nl */
+		case 'r':  c= '\r';   break;	/* cr */
+		case 't':  c= '\t';   break;	/* ht */
+		case 'v':  c= '\v';   break;	/* vt */
+		default:
+		    if (oigit(c))
+		    {
+			c -= '0';
+			if (oigit(*cclass)) c= (c << 3) + *cclass++ - '0';
+			if (oigit(*cclass)) c= (c << 3) + *cclass++ - '0';
+		    }
+		    break;
+	    }
+	}
+	*ccp= cclass;
+    }
+    return c;
+}
+
+static char *makeCharClass(unsigned char *cclass)
+{
+  unsigned char	 bits[32];
+  setter	 set;
+  int		 c, prev= -1;
+  static char	 string[256];
+  char		*ptr;
+
+  if ('^' == *cclass)
+    {
+      memset(bits, 255, 32);
+      set= charClassClear;
+      ++cclass;
+    }
+  else
+    {
+      memset(bits, 0, 32);
+      set= charClassSet;
+    }
+
+  while (*cclass)
+    {
+      if ('-' == *cclass && cclass[1] && prev >= 0)
+	{
+	  ++cclass;
+	  for (c= cnext(&cclass);  prev <= c;  ++prev)
+	    set(bits, prev);
+	  prev= -1;
+	}
+      else
+	{
+	  c= cnext(&cclass);
+	  set(bits, prev= c);
+	}
+    }
+
+  ptr= string;
+  for (c= 0;  c < 32;  ++c)
+    ptr += sprintf(ptr, "\\%03o", bits[c]);
+
+  return string;
+}
+
+static void begin(void)		{ fprintf(output, "\n  {"); }
+static void end(void)		{ fprintf(output, "\n  }"); }
+static void label(int n)	{ fprintf(output, "\n  l%d:;\t", n); }
+static void jump(int n)		{ fprintf(output, "  goto l%d;", n); }
+static void save(int n)		{ fprintf(output, "  int yypos%d= yy->__pos, yythunkpos%d= yy->__thunkpos;", n, n); }
+static void restore(int n)	{ fprintf(output,     "  yy->__pos= yypos%d; yy->__thunkpos= yythunkpos%d;", n, n); }
+
+static void Node_compile_c_ko(Node *node, int ko)
+{
+  assert(node);
+  switch (node->type)
+    {
+    case Rule:
+      fprintf(stderr, "\ninternal error #1 (%s)\n", node->rule.name);
+      exit(1);
+      break;
+
+    case Dot:
+      fprintf(output, "  if (!yymatchDot(yy)) goto l%d;", ko);
+      break;
+
+    case Name:
+      fprintf(output, "  if (!yy_%s(yy)) goto l%d;", node->name.rule->rule.name, ko);
+      if (node->name.variable)
+	fprintf(output, "  yyDo(yy, yySet, %d, 0);", node->name.variable->variable.offset);
+      break;
+
+    case Character:
+    case String:
+      {
+	int len= strlen(node->string.value);
+	if (1 == len)
+	  {
+	    if ('\'' == node->string.value[0])
+	      fprintf(output, "  if (!yymatchChar(yy, '\\'')) goto l%d;", ko);
+	    else
+	      fprintf(output, "  if (!yymatchChar(yy, '%s')) goto l%d;", node->string.value, ko);
+	  }
+	else
+	  if (2 == len && '\\' == node->string.value[0])
+	    fprintf(output, "  if (!yymatchChar(yy, '%s')) goto l%d;", node->string.value, ko);
+	  else 
+	    fprintf(output, "  if (!yymatchString(yy, \"%s\")) goto l%d;", node->string.value, ko);
+      }
+      break;
+
+    case Class:
+      fprintf(output, "  if (!yymatchClass(yy, (unsigned char *)\"%s\")) goto l%d;", makeCharClass(node->cclass.value), ko);
+      break;
+
+    case Action:
+      fprintf(output, "  yyDo(yy, yy%s, yy->__begin, yy->__end);", node->action.name);
+      break;
+
+    case Predicate:
+      fprintf(output, "  yyText(yy, yy->__begin, yy->__end);  if (!(%s)) goto l%d;", node->action.text, ko);
+      break;
+
+    case Error:
+      {
+	int eok= yyl(), eko= yyl();
+	Node_compile_c_ko(node->error.element, eko);
+	jump(eok);
+	label(eko);
+	fprintf(output, "  yyText(yy, yy->__begin, yy->__end);  {\n");
+	fprintf(output, "#define yytext yy->__text\n");
+	fprintf(output, "#define yyleng yy->__textlen\n");
+	fprintf(output, "  %s;\n", node->error.text);
+	fprintf(output, "#undef yytext\n");
+	fprintf(output, "#undef yyleng\n");
+	fprintf(output, "  }");
+	jump(ko);
+	label(eok);
+      }
+      break;
+
+    case Alternate:
+      {
+	int ok= yyl();
+	begin();
+	save(ok);
+	for (node= node->alternate.first;  node;  node= node->alternate.next)
+	  if (node->alternate.next)
+	    {
+	      int next= yyl();
+	      Node_compile_c_ko(node, next);
+	      jump(ok);
+	      label(next);
+	      restore(ok);
+	    }
+	  else
+	    Node_compile_c_ko(node, ko);
+	end();
+	label(ok);
+      }
+      break;
+
+    case Sequence:
+      for (node= node->sequence.first;  node;  node= node->sequence.next)
+	Node_compile_c_ko(node, ko);
+      break;
+
+    case PeekFor:
+      {
+	int ok= yyl();
+	begin();
+	save(ok);
+	Node_compile_c_ko(node->peekFor.element, ko);
+	restore(ok);
+	end();
+      }
+      break;
+
+    case PeekNot:
+      {
+	int ok= yyl();
+	begin();
+	save(ok);
+	Node_compile_c_ko(node->peekFor.element, ok);
+	jump(ko);
+	label(ok);
+	restore(ok);
+	end();
+      }
+      break;
+
+    case Query:
+      {
+	int qko= yyl(), qok= yyl();
+	begin();
+	save(qko);
+	Node_compile_c_ko(node->query.element, qko);
+	jump(qok);
+	label(qko);
+	restore(qko);
+	end();
+	label(qok);
+      }
+      break;
+
+    case Star:
+      {
+	int again= yyl(), out= yyl();
+	label(again);
+	begin();
+	save(out);
+	Node_compile_c_ko(node->star.element, out);
+	jump(again);
+	label(out);
+	restore(out);
+	end();
+      }
+      break;
+
+    case Plus:
+      {
+	int again= yyl(), out= yyl();
+	Node_compile_c_ko(node->plus.element, ko);
+	label(again);
+	begin();
+	save(out);
+	Node_compile_c_ko(node->plus.element, out);
+	jump(again);
+	label(out);
+	restore(out);
+	end();
+      }
+      break;
+
+    default:
+      fprintf(stderr, "\nNode_compile_c_ko: illegal node type %d\n", node->type);
+      exit(1);
+    }
+}
+
+
+static int countVariables(Node *node)
+{
+  int count= 0;
+  while (node)
+    {
+      ++count;
+      node= node->variable.next;
+    }
+  return count;
+}
+
+static void defineVariables(Node *node)
+{
+  int count= 0;
+  while (node)
+    {
+      fprintf(output, "#define %s yy->__val[%d]\n", node->variable.name, --count);
+      node->variable.offset= count;
+      node= node->variable.next;
+    }
+  fprintf(output, "#define __ yy->__\n");
+  fprintf(output, "#define yypos yy->__pos\n");
+  fprintf(output, "#define yythunkpos yy->__thunkpos\n");
+}
+
+static void undefineVariables(Node *node)
+{
+  fprintf(output, "#undef yythunkpos\n");
+  fprintf(output, "#undef yypos\n");
+  fprintf(output, "#undef yy\n");
+  while (node)
+    {
+      fprintf(output, "#undef %s\n", node->variable.name);
+      node= node->variable.next;
+    }
+}
+
+
+static void Rule_compile_c2(Node *node)
+{
+  assert(node);
+  assert(Rule == node->type);
+
+  if (!node->rule.expression)
+    fprintf(stderr, "rule '%s' used but not defined\n", node->rule.name);
+  else
+    {
+      int ko= yyl(), safe;
+
+      if ((!(RuleUsed & node->rule.flags)) && (node != start))
+	fprintf(stderr, "rule '%s' defined but not used\n", node->rule.name);
+
+      safe= ((Query == node->rule.expression->type) || (Star == node->rule.expression->type));
+
+      fprintf(output, "\nYY_RULE(int) yy_%s(yycontext *yy)\n{", node->rule.name);
+      if (!safe) save(0);
+      if (node->rule.variables)
+	fprintf(output, "  yyDo(yy, yyPush, %d, 0);", countVariables(node->rule.variables));
+      fprintf(output, "\n  yyprintf((stderr, \"%%s\\n\", \"%s\"));", node->rule.name);
+      Node_compile_c_ko(node->rule.expression, ko);
+      fprintf(output, "\n  yyprintf((stderr, \"  ok   %%s @ %%s\\n\", \"%s\", yy->__buf+yy->__pos));", node->rule.name);
+      if (node->rule.variables)
+	fprintf(output, "  yyDo(yy, yyPop, %d, 0);", countVariables(node->rule.variables));
+      fprintf(output, "\n  return 1;");
+      if (!safe)
+	{
+	  label(ko);
+	  restore(0);
+	  fprintf(output, "\n  yyprintf((stderr, \"  fail %%s @ %%s\\n\", \"%s\", yy->__buf+yy->__pos));", node->rule.name);
+	  fprintf(output, "\n  return 0;");
+	}
+      fprintf(output, "\n}");
+    }
+
+  if (node->rule.next)
+    Rule_compile_c2(node->rule.next);
+}
+
+static char *header= "\
+#include <stdio.h>\n\
+#include <stdlib.h>\n\
+#include <string.h>\n\
+";
+
+static char *preamble= "\
+#ifndef YY_MALLOC\n\
+#define YY_MALLOC(C, N)		malloc(N)\n\
+#endif\n\
+#ifndef YY_REALLOC\n\
+#define YY_REALLOC(C, P, N)	realloc(P, N)\n\
+#endif\n\
+#ifndef YY_FREE\n\
+#define YY_FREE free\n\
+#endif\n\
+#ifndef YY_LOCAL\n\
+#define YY_LOCAL(T)	static T\n\
+#endif\n\
+#ifndef YY_ACTION\n\
+#define YY_ACTION(T)	static T\n\
+#endif\n\
+#ifndef YY_RULE\n\
+#define YY_RULE(T)	static T\n\
+#endif\n\
+#ifndef YY_PARSE\n\
+#define YY_PARSE(T)	T\n\
+#endif\n\
+#ifndef YYPARSE\n\
+#define YYPARSE		yyparse\n\
+#endif\n\
+#ifndef YYPARSEFROM\n\
+#define YYPARSEFROM	yyparsefrom\n\
+#endif\n\
+#ifndef YYRELEASE\n\
+#define YYRELEASE	yyrelease\n\
+#endif\n\
+#ifndef YY_BEGIN\n\
+#define YY_BEGIN	( yy->__begin= yy->__pos, 1)\n\
+#endif\n\
+#ifndef YY_END\n\
+#define YY_END		( yy->__end= yy->__pos, 1)\n\
+#endif\n\
+#ifdef YY_DEBUG\n\
+# define yyprintf(args)	fprintf args\n\
+#else\n\
+# define yyprintf(args)\n\
+#endif\n\
+#ifndef YYSTYPE\n\
+#define YYSTYPE	int\n\
+#endif\n\
+#ifndef YY_STACK_SIZE\n\
+#define YY_STACK_SIZE 128\n\
+#endif\n\
+\n\
+#ifndef YY_BUFFER_SIZE\n\
+#define YY_BUFFER_SIZE 1024\n\
+#endif\n\
+\n\
+#ifndef YY_PART\n\
+\n\
+typedef struct _yycontext yycontext;\n\
+typedef void (*yyaction)(yycontext *yy, char *yytext, int yyleng);\n\
+typedef struct _yythunk { int begin, end;  yyaction  action;  struct _yythunk *next; } yythunk;\n\
+\n\
+struct _yycontext {\n\
+  char     *__buf;\n\
+  int       __buflen;\n\
+  int       __pos;\n\
+  int       __limit;\n\
+  char     *__text;\n\
+  int       __textlen;\n\
+  int       __begin;\n\
+  int       __end;\n\
+  int       __textmax;\n\
+  yythunk  *__thunks;\n\
+  int       __thunkslen;\n\
+  int       __thunkpos;\n\
+  YYSTYPE   __;\n\
+  YYSTYPE  *__val;\n\
+  YYSTYPE  *__vals;\n\
+  int       __valslen;\n\
+#ifdef YY_CTX_MEMBERS\n\
+  YY_CTX_MEMBERS\n\
+#endif\n\
+};\n\
+\n\
+#ifdef YY_CTX_LOCAL\n\
+#define YY_CTX_PARAM_	yycontext *yyctx,\n\
+#define YY_CTX_PARAM	yycontext *yyctx\n\
+#define YY_CTX_ARG_	yyctx,\n\
+#define YY_CTX_ARG	yyctx\n\
+#ifndef YY_INPUT\n\
+#define YY_INPUT(yy, buf, result, max_size)		\\\n\
+  {							\\\n\
+    int yyc= getchar();					\\\n\
+    result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1);	\\\n\
+    yyprintf((stderr, \"<%c>\", yyc));			\\\n\
+  }\n\
+#endif\n\
+#else\n\
+#define YY_CTX_PARAM_\n\
+#define YY_CTX_PARAM\n\
+#define YY_CTX_ARG_\n\
+#define YY_CTX_ARG\n\
+yycontext _yyctx= { 0, 0 };\n\
+yycontext *yyctx= &_yyctx;\n\
+#ifndef YY_INPUT\n\
+#define YY_INPUT(buf, result, max_size)			\\\n\
+  {							\\\n\
+    int yyc= getchar();					\\\n\
+    result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1);	\\\n\
+    yyprintf((stderr, \"<%c>\", yyc));			\\\n\
+  }\n\
+#endif\n\
+#endif\n\
+\n\
+YY_LOCAL(int) yyrefill(yycontext *yy)\n\
+{\n\
+  int yyn;\n\
+  while (yy->__buflen - yy->__pos < 512)\n\
+    {\n\
+      yy->__buflen *= 2;\n\
+      yy->__buf= (char *)YY_REALLOC(yy, yy->__buf, yy->__buflen);\n\
+    }\n\
+#ifdef YY_CTX_LOCAL\n\
+  YY_INPUT(yy, (yy->__buf + yy->__pos), yyn, (yy->__buflen - yy->__pos));\n\
+#else\n\
+  YY_INPUT((yy->__buf + yy->__pos), yyn, (yy->__buflen - yy->__pos));\n\
+#endif\n\
+  if (!yyn) return 0;\n\
+  yy->__limit += yyn;\n\
+  return 1;\n\
+}\n\
+\n\
+YY_LOCAL(int) yymatchDot(yycontext *yy)\n\
+{\n\
+  if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0;\n\
+  ++yy->__pos;\n\
+  return 1;\n\
+}\n\
+\n\
+YY_LOCAL(int) yymatchChar(yycontext *yy, int c)\n\
+{\n\
+  if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0;\n\
+  if ((unsigned char)yy->__buf[yy->__pos] == c)\n\
+    {\n\
+      ++yy->__pos;\n\
+      yyprintf((stderr, \"  ok   yymatchChar(yy, %c) @ %s\\n\", c, yy->__buf+yy->__pos));\n\
+      return 1;\n\
+    }\n\
+  yyprintf((stderr, \"  fail yymatchChar(yy, %c) @ %s\\n\", c, yy->__buf+yy->__pos));\n\
+  return 0;\n\
+}\n\
+\n\
+YY_LOCAL(int) yymatchString(yycontext *yy, const char *s)\n\
+{\n\
+  int yysav= yy->__pos;\n\
+  while (*s)\n\
+    {\n\
+      if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0;\n\
+      if (yy->__buf[yy->__pos] != *s)\n\
+        {\n\
+          yy->__pos= yysav;\n\
+          return 0;\n\
+        }\n\
+      ++s;\n\
+      ++yy->__pos;\n\
+    }\n\
+  return 1;\n\
+}\n\
+\n\
+YY_LOCAL(int) yymatchClass(yycontext *yy, unsigned char *bits)\n\
+{\n\
+  int c;\n\
+  if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0;\n\
+  c= (unsigned char)yy->__buf[yy->__pos];\n\
+  if (bits[c >> 3] & (1 << (c & 7)))\n\
+    {\n\
+      ++yy->__pos;\n\
+      yyprintf((stderr, \"  ok   yymatchClass @ %s\\n\", yy->__buf+yy->__pos));\n\
+      return 1;\n\
+    }\n\
+  yyprintf((stderr, \"  fail yymatchClass @ %s\\n\", yy->__buf+yy->__pos));\n\
+  return 0;\n\
+}\n\
+\n\
+YY_LOCAL(void) yyDo(yycontext *yy, yyaction action, int begin, int end)\n\
+{\n\
+  while (yy->__thunkpos >= yy->__thunkslen)\n\
+    {\n\
+      yy->__thunkslen *= 2;\n\
+      yy->__thunks= (yythunk *)YY_REALLOC(yy, yy->__thunks, sizeof(yythunk) * yy->__thunkslen);\n\
+    }\n\
+  yy->__thunks[yy->__thunkpos].begin=  begin;\n\
+  yy->__thunks[yy->__thunkpos].end=    end;\n\
+  yy->__thunks[yy->__thunkpos].action= action;\n\
+  ++yy->__thunkpos;\n\
+}\n\
+\n\
+YY_LOCAL(int) yyText(yycontext *yy, int begin, int end)\n\
+{\n\
+  int yyleng= end - begin;\n\
+  if (yyleng <= 0)\n\
+    yyleng= 0;\n\
+  else\n\
+    {\n\
+      while (yy->__textlen < (yyleng + 1))\n\
+	{\n\
+	  yy->__textlen *= 2;\n\
+	  yy->__text= (char *)YY_REALLOC(yy, yy->__text, yy->__textlen);\n\
+	}\n\
+      memcpy(yy->__text, yy->__buf + begin, yyleng);\n\
+    }\n\
+  yy->__text[yyleng]= '\\0';\n\
+  return yyleng;\n\
+}\n\
+\n\
+YY_LOCAL(void) yyDone(yycontext *yy)\n\
+{\n\
+  int pos;\n\
+  for (pos= 0;  pos < yy->__thunkpos;  ++pos)\n\
+    {\n\
+      yythunk *thunk= &yy->__thunks[pos];\n\
+      int yyleng= thunk->end ? yyText(yy, thunk->begin, thunk->end) : thunk->begin;\n\
+      yyprintf((stderr, \"DO [%d] %p %s\\n\", pos, thunk->action, yy->__text));\n\
+      thunk->action(yy, yy->__text, yyleng);\n\
+    }\n\
+  yy->__thunkpos= 0;\n\
+}\n\
+\n\
+YY_LOCAL(void) yyCommit(yycontext *yy)\n\
+{\n\
+  if ((yy->__limit -= yy->__pos))\n\
+    {\n\
+      memmove(yy->__buf, yy->__buf + yy->__pos, yy->__limit);\n\
+    }\n\
+  yy->__begin -= yy->__pos;\n\
+  yy->__end -= yy->__pos;\n\
+  yy->__pos= yy->__thunkpos= 0;\n\
+}\n\
+\n\
+YY_LOCAL(int) yyAccept(yycontext *yy, int tp0)\n\
+{\n\
+  if (tp0)\n\
+    {\n\
+      fprintf(stderr, \"accept denied at %d\\n\", tp0);\n\
+      return 0;\n\
+    }\n\
+  else\n\
+    {\n\
+      yyDone(yy);\n\
+      yyCommit(yy);\n\
+    }\n\
+  return 1;\n\
+}\n\
+\n\
+YY_LOCAL(void) yyPush(yycontext *yy, char *text, int count)\n\
+{\n\
+  yy->__val += count;\n\
+  while (yy->__valslen <= yy->__val - yy->__vals)\n\
+    {\n\
+      long offset= yy->__val - yy->__vals;\n\
+      yy->__valslen *= 2;\n\
+      yy->__vals= (YYSTYPE *)YY_REALLOC(yy, yy->__vals, sizeof(YYSTYPE) * yy->__valslen);\n\
+      yy->__val= yy->__vals + offset;\n\
+    }\n\
+}\n\
+YY_LOCAL(void) yyPop(yycontext *yy, char *text, int count)   { yy->__val -= count; }\n\
+YY_LOCAL(void) yySet(yycontext *yy, char *text, int count)   { yy->__val[count]= yy->__; }\n\
+\n\
+#endif /* YY_PART */\n\
+\n\
+#define	YYACCEPT	yyAccept(yy, yythunkpos0)\n\
+\n\
+";
+
+static char *footer= "\n\
+\n\
+#ifndef YY_PART\n\
+\n\
+typedef int (*yyrule)(yycontext *yy);\n\
+\n\
+YY_PARSE(int) YYPARSEFROM(YY_CTX_PARAM_ yyrule yystart)\n\
+{\n\
+  int yyok;\n\
+  if (!yyctx->__buflen)\n\
+    {\n\
+      yyctx->__buflen= YY_BUFFER_SIZE;\n\
+      yyctx->__buf= (char *)YY_MALLOC(yyctx, yyctx->__buflen);\n\
+      yyctx->__textlen= YY_BUFFER_SIZE;\n\
+      yyctx->__text= (char *)YY_MALLOC(yyctx, yyctx->__textlen);\n\
+      yyctx->__thunkslen= YY_STACK_SIZE;\n\
+      yyctx->__thunks= (yythunk *)YY_MALLOC(yyctx, sizeof(yythunk) * yyctx->__thunkslen);\n\
+      yyctx->__valslen= YY_STACK_SIZE;\n\
+      yyctx->__vals= (YYSTYPE *)YY_MALLOC(yyctx, sizeof(YYSTYPE) * yyctx->__valslen);\n\
+      yyctx->__begin= yyctx->__end= yyctx->__pos= yyctx->__limit= yyctx->__thunkpos= 0;\n\
+    }\n\
+  yyctx->__begin= yyctx->__end= yyctx->__pos;\n\
+  yyctx->__thunkpos= 0;\n\
+  yyctx->__val= yyctx->__vals;\n\
+  yyok= yystart(yyctx);\n\
+  if (yyok) yyDone(yyctx);\n\
+  yyCommit(yyctx);\n\
+  return yyok;\n\
+}\n\
+\n\
+YY_PARSE(int) YYPARSE(YY_CTX_PARAM)\n\
+{\n\
+  return YYPARSEFROM(YY_CTX_ARG_ yy_%s);\n\
+}\n\
+\n\
+YY_PARSE(yycontext *) YYRELEASE(yycontext *yyctx)\n\
+{\n\
+  if (yyctx->__buflen)\n\
+    {\n\
+      yyctx->__buflen= 0;\n\
+      YY_FREE(yyctx->__buf);\n\
+      YY_FREE(yyctx->__text);\n\
+      YY_FREE(yyctx->__thunks);\n\
+      YY_FREE(yyctx->__vals);\n\
+    }\n\
+  return yyctx;\n\
+}\n\
+\n\
+#endif\n\
+";
+
+void Rule_compile_c_header(void)
+{
+  fprintf(output, "/* A recursive-descent parser generated by peg %d.%d.%d */\n", PEG_MAJOR, PEG_MINOR, PEG_LEVEL);
+  fprintf(output, "\n");
+  fprintf(output, "%s", header);
+  fprintf(output, "#define YYRULECOUNT %d\n", ruleCount);
+}
+
+int consumesInput(Node *node)
+{
+  if (!node) return 0;
+
+  switch (node->type)
+    {
+    case Rule:
+      {
+	int result= 0;
+	if (RuleReached & node->rule.flags)
+	  fprintf(stderr, "possible infinite left recursion in rule '%s'\n", node->rule.name);
+	else
+	  {
+	    node->rule.flags |= RuleReached;
+	    result= consumesInput(node->rule.expression);
+	    node->rule.flags &= ~RuleReached;
+	  }
+	return result;
+      }
+      break;
+
+    case Dot:		return 1;
+    case Name:		return consumesInput(node->name.rule);
+    case Character:
+    case String:	return strlen(node->string.value) > 0;
+    case Class:		return 1;
+    case Action:	return 0;
+    case Predicate:	return 0;
+    case Error:		return consumesInput(node->error.element);
+
+    case Alternate:
+      {
+	Node *n;
+	for (n= node->alternate.first;  n;  n= n->alternate.next)
+	  if (!consumesInput(n))
+	    return 0;
+      }
+      return 1;
+
+    case Sequence:
+      {
+	Node *n;
+	for (n= node->alternate.first;  n;  n= n->alternate.next)
+	  if (consumesInput(n))
+	    return 1;
+      }
+      return 0;
+
+    case PeekFor:	return 0;
+    case PeekNot:	return 0;
+    case Query:		return 0;
+    case Star:		return 0;
+    case Plus:		return consumesInput(node->plus.element);
+
+    default:
+      fprintf(stderr, "\nconsumesInput: illegal node type %d\n", node->type);
+      exit(1);
+    }
+  return 0;
+}
+
+
+void Rule_compile_c(Node *node)
+{
+  Node *n;
+
+  for (n= rules;  n;  n= n->rule.next)
+    consumesInput(n);
+
+  fprintf(output, "%s", preamble);
+  for (n= node;  n;  n= n->rule.next)
+    fprintf(output, "YY_RULE(int) yy_%s(yycontext *yy); /* %d */\n", n->rule.name, n->rule.id);
+  fprintf(output, "\n");
+  for (n= actions;  n;  n= n->action.list)
+    {
+      fprintf(output, "YY_ACTION(void) yy%s(yycontext *yy, char *yytext, int yyleng)\n{\n", n->action.name);
+      defineVariables(n->action.rule->rule.variables);
+      fprintf(output, "  yyprintf((stderr, \"do yy%s\\n\"));\n", n->action.name);
+      fprintf(output, "  {\n");
+      fprintf(output, "  %s;\n", n->action.text);
+      fprintf(output, "  }\n");
+      undefineVariables(n->action.rule->rule.variables);
+      fprintf(output, "}\n");
+    }
+  Rule_compile_c2(node);
+  fprintf(output, footer, start->rule.name);
+}
--- /dev/null
+++ b/src/leg.c
@@ -1,0 +1,1342 @@
+/* A recursive-descent parser generated by peg 0.1.11 */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define YYRULECOUNT 38
+
+# include "tree.h"
+# include "version.h"
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <unistd.h>
+# include <string.h>
+# include <libgen.h>
+# include <assert.h>
+
+  typedef struct Header Header;
+
+  struct Header {
+    char   *text;
+    Header *next;
+  };
+
+  FILE *input= 0;
+
+  int   verboseFlag= 0;
+
+  static int	 lineNumber= 0;
+  static char	*fileName= 0;
+  static char	*trailer= 0;
+  static Header	*headers= 0;
+
+  void makeHeader(char *text);
+  void makeTrailer(char *text);
+
+  void yyerror(char *message);
+
+# define YY_INPUT(buf, result, max)		\
+  {						\
+    int c= getc(input);				\
+    if ('\n' == c || '\r' == c) ++lineNumber;	\
+    result= (EOF == c) ? 0 : (*(buf)= c, 1);	\
+  }
+
+# define YY_LOCAL(T)	static T
+# define YY_RULE(T)	static T
+
+#ifndef YY_MALLOC
+#define YY_MALLOC(C, N)		malloc(N)
+#endif
+#ifndef YY_REALLOC
+#define YY_REALLOC(C, P, N)	realloc(P, N)
+#endif
+#ifndef YY_FREE
+#define YY_FREE free
+#endif
+#ifndef YY_LOCAL
+#define YY_LOCAL(T)	static T
+#endif
+#ifndef YY_ACTION
+#define YY_ACTION(T)	static T
+#endif
+#ifndef YY_RULE
+#define YY_RULE(T)	static T
+#endif
+#ifndef YY_PARSE
+#define YY_PARSE(T)	T
+#endif
+#ifndef YYPARSE
+#define YYPARSE		yyparse
+#endif
+#ifndef YYPARSEFROM
+#define YYPARSEFROM	yyparsefrom
+#endif
+#ifndef YYRELEASE
+#define YYRELEASE	yyrelease
+#endif
+#ifndef YY_BEGIN
+#define YY_BEGIN	( yy->__begin= yy->__pos, 1)
+#endif
+#ifndef YY_END
+#define YY_END		( yy->__end= yy->__pos, 1)
+#endif
+#ifdef YY_DEBUG
+# define yyprintf(args)	fprintf args
+#else
+# define yyprintf(args)
+#endif
+#ifndef YYSTYPE
+#define YYSTYPE	int
+#endif
+#ifndef YY_STACK_SIZE
+#define YY_STACK_SIZE 128
+#endif
+
+#ifndef YY_BUFFER_SIZE
+#define YY_BUFFER_SIZE 1024
+#endif
+
+#ifndef YY_PART
+
+typedef struct _yycontext yycontext;
+typedef void (*yyaction)(yycontext *yy, char *yytext, int yyleng);
+typedef struct _yythunk { int begin, end;  yyaction  action;  struct _yythunk *next; } yythunk;
+
+struct _yycontext {
+  char     *__buf;
+  int       __buflen;
+  int       __pos;
+  int       __limit;
+  char     *__text;
+  int       __textlen;
+  int       __begin;
+  int       __end;
+  int       __textmax;
+  yythunk  *__thunks;
+  int       __thunkslen;
+  int       __thunkpos;
+  YYSTYPE   __;
+  YYSTYPE  *__val;
+  YYSTYPE  *__vals;
+  int       __valslen;
+#ifdef YY_CTX_MEMBERS
+  YY_CTX_MEMBERS
+#endif
+};
+
+#ifdef YY_CTX_LOCAL
+#define YY_CTX_PARAM_	yycontext *yyctx,
+#define YY_CTX_PARAM	yycontext *yyctx
+#define YY_CTX_ARG_	yyctx,
+#define YY_CTX_ARG	yyctx
+#ifndef YY_INPUT
+#define YY_INPUT(yy, buf, result, max_size)		\
+  {							\
+    int yyc= getchar();					\
+    result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1);	\
+    yyprintf((stderr, "<%c>", yyc));			\
+  }
+#endif
+#else
+#define YY_CTX_PARAM_
+#define YY_CTX_PARAM
+#define YY_CTX_ARG_
+#define YY_CTX_ARG
+yycontext _yyctx= { 0, 0 };
+yycontext *yyctx= &_yyctx;
+#ifndef YY_INPUT
+#define YY_INPUT(buf, result, max_size)			\
+  {							\
+    int yyc= getchar();					\
+    result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1);	\
+    yyprintf((stderr, "<%c>", yyc));			\
+  }
+#endif
+#endif
+
+YY_LOCAL(int) yyrefill(yycontext *yy)
+{
+  int yyn;
+  while (yy->__buflen - yy->__pos < 512)
+    {
+      yy->__buflen *= 2;
+      yy->__buf= (char *)YY_REALLOC(yy, yy->__buf, yy->__buflen);
+    }
+#ifdef YY_CTX_LOCAL
+  YY_INPUT(yy, (yy->__buf + yy->__pos), yyn, (yy->__buflen - yy->__pos));
+#else
+  YY_INPUT((yy->__buf + yy->__pos), yyn, (yy->__buflen - yy->__pos));
+#endif
+  if (!yyn) return 0;
+  yy->__limit += yyn;
+  return 1;
+}
+
+YY_LOCAL(int) yymatchDot(yycontext *yy)
+{
+  if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0;
+  ++yy->__pos;
+  return 1;
+}
+
+YY_LOCAL(int) yymatchChar(yycontext *yy, int c)
+{
+  if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0;
+  if ((unsigned char)yy->__buf[yy->__pos] == c)
+    {
+      ++yy->__pos;
+      yyprintf((stderr, "  ok   yymatchChar(yy, %c) @ %s\n", c, yy->__buf+yy->__pos));
+      return 1;
+    }
+  yyprintf((stderr, "  fail yymatchChar(yy, %c) @ %s\n", c, yy->__buf+yy->__pos));
+  return 0;
+}
+
+YY_LOCAL(int) yymatchString(yycontext *yy, const char *s)
+{
+  int yysav= yy->__pos;
+  while (*s)
+    {
+      if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0;
+      if (yy->__buf[yy->__pos] != *s)
+        {
+          yy->__pos= yysav;
+          return 0;
+        }
+      ++s;
+      ++yy->__pos;
+    }
+  return 1;
+}
+
+YY_LOCAL(int) yymatchClass(yycontext *yy, unsigned char *bits)
+{
+  int c;
+  if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0;
+  c= (unsigned char)yy->__buf[yy->__pos];
+  if (bits[c >> 3] & (1 << (c & 7)))
+    {
+      ++yy->__pos;
+      yyprintf((stderr, "  ok   yymatchClass @ %s\n", yy->__buf+yy->__pos));
+      return 1;
+    }
+  yyprintf((stderr, "  fail yymatchClass @ %s\n", yy->__buf+yy->__pos));
+  return 0;
+}
+
+YY_LOCAL(void) yyDo(yycontext *yy, yyaction action, int begin, int end)
+{
+  while (yy->__thunkpos >= yy->__thunkslen)
+    {
+      yy->__thunkslen *= 2;
+      yy->__thunks= (yythunk *)YY_REALLOC(yy, yy->__thunks, sizeof(yythunk) * yy->__thunkslen);
+    }
+  yy->__thunks[yy->__thunkpos].begin=  begin;
+  yy->__thunks[yy->__thunkpos].end=    end;
+  yy->__thunks[yy->__thunkpos].action= action;
+  ++yy->__thunkpos;
+}
+
+YY_LOCAL(int) yyText(yycontext *yy, int begin, int end)
+{
+  int yyleng= end - begin;
+  if (yyleng <= 0)
+    yyleng= 0;
+  else
+    {
+      while (yy->__textlen < (yyleng + 1))
+	{
+	  yy->__textlen *= 2;
+	  yy->__text= (char *)YY_REALLOC(yy, yy->__text, yy->__textlen);
+	}
+      memcpy(yy->__text, yy->__buf + begin, yyleng);
+    }
+  yy->__text[yyleng]= '\0';
+  return yyleng;
+}
+
+YY_LOCAL(void) yyDone(yycontext *yy)
+{
+  int pos;
+  for (pos= 0;  pos < yy->__thunkpos;  ++pos)
+    {
+      yythunk *thunk= &yy->__thunks[pos];
+      int yyleng= thunk->end ? yyText(yy, thunk->begin, thunk->end) : thunk->begin;
+      yyprintf((stderr, "DO [%d] %p %s\n", pos, thunk->action, yy->__text));
+      thunk->action(yy, yy->__text, yyleng);
+    }
+  yy->__thunkpos= 0;
+}
+
+YY_LOCAL(void) yyCommit(yycontext *yy)
+{
+  if ((yy->__limit -= yy->__pos))
+    {
+      memmove(yy->__buf, yy->__buf + yy->__pos, yy->__limit);
+    }
+  yy->__begin -= yy->__pos;
+  yy->__end -= yy->__pos;
+  yy->__pos= yy->__thunkpos= 0;
+}
+
+YY_LOCAL(int) yyAccept(yycontext *yy, int tp0)
+{
+  if (tp0)
+    {
+      fprintf(stderr, "accept denied at %d\n", tp0);
+      return 0;
+    }
+  else
+    {
+      yyDone(yy);
+      yyCommit(yy);
+    }
+  return 1;
+}
+
+YY_LOCAL(void) yyPush(yycontext *yy, char *text, int count)
+{
+  yy->__val += count;
+  while (yy->__valslen <= yy->__val - yy->__vals)
+    {
+      long offset= yy->__val - yy->__vals;
+      yy->__valslen *= 2;
+      yy->__vals= (YYSTYPE *)YY_REALLOC(yy, yy->__vals, sizeof(YYSTYPE) * yy->__valslen);
+      yy->__val= yy->__vals + offset;
+    }
+}
+YY_LOCAL(void) yyPop(yycontext *yy, char *text, int count)   { yy->__val -= count; }
+YY_LOCAL(void) yySet(yycontext *yy, char *text, int count)   { yy->__val[count]= yy->__; }
+
+#endif /* YY_PART */
+
+#define	YYACCEPT	yyAccept(yy, yythunkpos0)
+
+YY_RULE(int) yy_end_of_line(yycontext *yy); /* 38 */
+YY_RULE(int) yy_comment(yycontext *yy); /* 37 */
+YY_RULE(int) yy_space(yycontext *yy); /* 36 */
+YY_RULE(int) yy_braces(yycontext *yy); /* 35 */
+YY_RULE(int) yy_range(yycontext *yy); /* 34 */
+YY_RULE(int) yy_char(yycontext *yy); /* 33 */
+YY_RULE(int) yy_END(yycontext *yy); /* 32 */
+YY_RULE(int) yy_BEGIN(yycontext *yy); /* 31 */
+YY_RULE(int) yy_DOT(yycontext *yy); /* 30 */
+YY_RULE(int) yy_class(yycontext *yy); /* 29 */
+YY_RULE(int) yy_literal(yycontext *yy); /* 28 */
+YY_RULE(int) yy_CLOSE(yycontext *yy); /* 27 */
+YY_RULE(int) yy_OPEN(yycontext *yy); /* 26 */
+YY_RULE(int) yy_COLON(yycontext *yy); /* 25 */
+YY_RULE(int) yy_PLUS(yycontext *yy); /* 24 */
+YY_RULE(int) yy_STAR(yycontext *yy); /* 23 */
+YY_RULE(int) yy_QUESTION(yycontext *yy); /* 22 */
+YY_RULE(int) yy_primary(yycontext *yy); /* 21 */
+YY_RULE(int) yy_NOT(yycontext *yy); /* 20 */
+YY_RULE(int) yy_suffix(yycontext *yy); /* 19 */
+YY_RULE(int) yy_AND(yycontext *yy); /* 18 */
+YY_RULE(int) yy_action(yycontext *yy); /* 17 */
+YY_RULE(int) yy_TILDE(yycontext *yy); /* 16 */
+YY_RULE(int) yy_prefix(yycontext *yy); /* 15 */
+YY_RULE(int) yy_error(yycontext *yy); /* 14 */
+YY_RULE(int) yy_BAR(yycontext *yy); /* 13 */
+YY_RULE(int) yy_sequence(yycontext *yy); /* 12 */
+YY_RULE(int) yy_SEMICOLON(yycontext *yy); /* 11 */
+YY_RULE(int) yy_expression(yycontext *yy); /* 10 */
+YY_RULE(int) yy_EQUAL(yycontext *yy); /* 9 */
+YY_RULE(int) yy_identifier(yycontext *yy); /* 8 */
+YY_RULE(int) yy_RPERCENT(yycontext *yy); /* 7 */
+YY_RULE(int) yy_end_of_file(yycontext *yy); /* 6 */
+YY_RULE(int) yy_trailer(yycontext *yy); /* 5 */
+YY_RULE(int) yy_definition(yycontext *yy); /* 4 */
+YY_RULE(int) yy_declaration(yycontext *yy); /* 3 */
+YY_RULE(int) yy__(yycontext *yy); /* 2 */
+YY_RULE(int) yy_grammar(yycontext *yy); /* 1 */
+
+YY_ACTION(void) yy_9_primary(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_9_primary\n"));
+  {
+   push(makePredicate("YY_END")); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_8_primary(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_8_primary\n"));
+  {
+   push(makePredicate("YY_BEGIN")); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_7_primary(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_7_primary\n"));
+  {
+   push(makeAction(yytext)); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_6_primary(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_6_primary\n"));
+  {
+   push(makeDot()); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_5_primary(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_5_primary\n"));
+  {
+   push(makeClass(yytext)); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_4_primary(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_4_primary\n"));
+  {
+   push(makeString(yytext)); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_3_primary(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_3_primary\n"));
+  {
+   push(makeName(findRule(yytext))); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_2_primary(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_2_primary\n"));
+  {
+   Node *name= makeName(findRule(yytext));  name->name.variable= pop();  push(name); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_1_primary(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_1_primary\n"));
+  {
+   push(makeVariable(yytext)); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_3_suffix(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_3_suffix\n"));
+  {
+   push(makePlus (pop())); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_2_suffix(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_2_suffix\n"));
+  {
+   push(makeStar (pop())); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_1_suffix(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_1_suffix\n"));
+  {
+   push(makeQuery(pop())); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_3_prefix(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_3_prefix\n"));
+  {
+   push(makePeekNot(pop())); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_2_prefix(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_2_prefix\n"));
+  {
+   push(makePeekFor(pop())); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_1_prefix(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_1_prefix\n"));
+  {
+   push(makePredicate(yytext)); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_1_error(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_1_error\n"));
+  {
+   push(makeError(pop(), yytext)); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_1_sequence(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_1_sequence\n"));
+  {
+   Node *f= pop();  push(Sequence_append(pop(), f)); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_1_expression(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_1_expression\n"));
+  {
+   Node *f= pop();  push(Alternate_append(pop(), f)); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_2_definition(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_2_definition\n"));
+  {
+   Node *e= pop();  Rule_setExpression(pop(), e); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_1_definition(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_1_definition\n"));
+  {
+   if (push(beginRule(findRule(yytext)))->rule.expression)
+							    fprintf(stderr, "rule '%s' redefined\n", yytext); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_1_trailer(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_1_trailer\n"));
+  {
+   makeTrailer(yytext); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_1_declaration(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_1_declaration\n"));
+  {
+   makeHeader(yytext); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+
+YY_RULE(int) yy_end_of_line(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "end_of_line"));
+  {  int yypos2= yy->__pos, yythunkpos2= yy->__thunkpos;  if (!yymatchString(yy, "\r\n")) goto l3;  goto l2;
+  l3:;	  yy->__pos= yypos2; yy->__thunkpos= yythunkpos2;  if (!yymatchChar(yy, '\n')) goto l4;  goto l2;
+  l4:;	  yy->__pos= yypos2; yy->__thunkpos= yythunkpos2;  if (!yymatchChar(yy, '\r')) goto l1;
+  }
+  l2:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "end_of_line", yy->__buf+yy->__pos));
+  return 1;
+  l1:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "end_of_line", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_comment(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "comment"));  if (!yymatchChar(yy, '#')) goto l5;
+  l6:;	
+  {  int yypos7= yy->__pos, yythunkpos7= yy->__thunkpos;
+  {  int yypos8= yy->__pos, yythunkpos8= yy->__thunkpos;  if (!yy_end_of_line(yy)) goto l8;  goto l7;
+  l8:;	  yy->__pos= yypos8; yy->__thunkpos= yythunkpos8;
+  }  if (!yymatchDot(yy)) goto l7;  goto l6;
+  l7:;	  yy->__pos= yypos7; yy->__thunkpos= yythunkpos7;
+  }  if (!yy_end_of_line(yy)) goto l5;
+  yyprintf((stderr, "  ok   %s @ %s\n", "comment", yy->__buf+yy->__pos));
+  return 1;
+  l5:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "comment", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_space(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "space"));
+  {  int yypos10= yy->__pos, yythunkpos10= yy->__thunkpos;  if (!yymatchChar(yy, ' ')) goto l11;  goto l10;
+  l11:;	  yy->__pos= yypos10; yy->__thunkpos= yythunkpos10;  if (!yymatchChar(yy, '\t')) goto l12;  goto l10;
+  l12:;	  yy->__pos= yypos10; yy->__thunkpos= yythunkpos10;  if (!yy_end_of_line(yy)) goto l9;
+  }
+  l10:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "space", yy->__buf+yy->__pos));
+  return 1;
+  l9:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "space", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_braces(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "braces"));
+  {  int yypos14= yy->__pos, yythunkpos14= yy->__thunkpos;  if (!yymatchChar(yy, '{')) goto l15;
+  l16:;	
+  {  int yypos17= yy->__pos, yythunkpos17= yy->__thunkpos;  if (!yy_braces(yy)) goto l17;  goto l16;
+  l17:;	  yy->__pos= yypos17; yy->__thunkpos= yythunkpos17;
+  }  if (!yymatchChar(yy, '}')) goto l15;  goto l14;
+  l15:;	  yy->__pos= yypos14; yy->__thunkpos= yythunkpos14;
+  {  int yypos18= yy->__pos, yythunkpos18= yy->__thunkpos;  if (!yymatchChar(yy, '}')) goto l18;  goto l13;
+  l18:;	  yy->__pos= yypos18; yy->__thunkpos= yythunkpos18;
+  }  if (!yymatchDot(yy)) goto l13;
+  }
+  l14:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "braces", yy->__buf+yy->__pos));
+  return 1;
+  l13:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "braces", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_range(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "range"));
+  {  int yypos20= yy->__pos, yythunkpos20= yy->__thunkpos;  if (!yy_char(yy)) goto l21;  if (!yymatchChar(yy, '-')) goto l21;  if (!yy_char(yy)) goto l21;  goto l20;
+  l21:;	  yy->__pos= yypos20; yy->__thunkpos= yythunkpos20;  if (!yy_char(yy)) goto l19;
+  }
+  l20:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "range", yy->__buf+yy->__pos));
+  return 1;
+  l19:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "range", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_char(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "char"));
+  {  int yypos23= yy->__pos, yythunkpos23= yy->__thunkpos;  if (!yymatchChar(yy, '\\')) goto l24;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\204\040\000\000\000\000\000\070\146\100\124\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l24;  goto l23;
+  l24:;	  yy->__pos= yypos23; yy->__thunkpos= yythunkpos23;  if (!yymatchChar(yy, '\\')) goto l25;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l25;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l25;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l25;  goto l23;
+  l25:;	  yy->__pos= yypos23; yy->__thunkpos= yythunkpos23;  if (!yymatchChar(yy, '\\')) goto l26;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l26;
+  {  int yypos27= yy->__pos, yythunkpos27= yy->__thunkpos;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l27;  goto l28;
+  l27:;	  yy->__pos= yypos27; yy->__thunkpos= yythunkpos27;
+  }
+  l28:;	  goto l23;
+  l26:;	  yy->__pos= yypos23; yy->__thunkpos= yythunkpos23;
+  {  int yypos29= yy->__pos, yythunkpos29= yy->__thunkpos;  if (!yymatchChar(yy, '\\')) goto l29;  goto l22;
+  l29:;	  yy->__pos= yypos29; yy->__thunkpos= yythunkpos29;
+  }  if (!yymatchDot(yy)) goto l22;
+  }
+  l23:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "char", yy->__buf+yy->__pos));
+  return 1;
+  l22:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "char", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_END(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "END"));  if (!yymatchChar(yy, '>')) goto l30;  if (!yy__(yy)) goto l30;
+  yyprintf((stderr, "  ok   %s @ %s\n", "END", yy->__buf+yy->__pos));
+  return 1;
+  l30:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "END", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_BEGIN(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "BEGIN"));  if (!yymatchChar(yy, '<')) goto l31;  if (!yy__(yy)) goto l31;
+  yyprintf((stderr, "  ok   %s @ %s\n", "BEGIN", yy->__buf+yy->__pos));
+  return 1;
+  l31:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "BEGIN", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_DOT(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "DOT"));  if (!yymatchChar(yy, '.')) goto l32;  if (!yy__(yy)) goto l32;
+  yyprintf((stderr, "  ok   %s @ %s\n", "DOT", yy->__buf+yy->__pos));
+  return 1;
+  l32:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "DOT", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_class(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "class"));  if (!yymatchChar(yy, '[')) goto l33;  yyText(yy, yy->__begin, yy->__end);  if (!(YY_BEGIN)) goto l33;
+  l34:;	
+  {  int yypos35= yy->__pos, yythunkpos35= yy->__thunkpos;
+  {  int yypos36= yy->__pos, yythunkpos36= yy->__thunkpos;  if (!yymatchChar(yy, ']')) goto l36;  goto l35;
+  l36:;	  yy->__pos= yypos36; yy->__thunkpos= yythunkpos36;
+  }  if (!yy_range(yy)) goto l35;  goto l34;
+  l35:;	  yy->__pos= yypos35; yy->__thunkpos= yythunkpos35;
+  }  yyText(yy, yy->__begin, yy->__end);  if (!(YY_END)) goto l33;  if (!yymatchChar(yy, ']')) goto l33;  if (!yy__(yy)) goto l33;
+  yyprintf((stderr, "  ok   %s @ %s\n", "class", yy->__buf+yy->__pos));
+  return 1;
+  l33:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "class", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_literal(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "literal"));
+  {  int yypos38= yy->__pos, yythunkpos38= yy->__thunkpos;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l39;  yyText(yy, yy->__begin, yy->__end);  if (!(YY_BEGIN)) goto l39;
+  l40:;	
+  {  int yypos41= yy->__pos, yythunkpos41= yy->__thunkpos;
+  {  int yypos42= yy->__pos, yythunkpos42= yy->__thunkpos;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l42;  goto l41;
+  l42:;	  yy->__pos= yypos42; yy->__thunkpos= yythunkpos42;
+  }  if (!yy_char(yy)) goto l41;  goto l40;
+  l41:;	  yy->__pos= yypos41; yy->__thunkpos= yythunkpos41;
+  }  yyText(yy, yy->__begin, yy->__end);  if (!(YY_END)) goto l39;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l39;  if (!yy__(yy)) goto l39;  goto l38;
+  l39:;	  yy->__pos= yypos38; yy->__thunkpos= yythunkpos38;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l37;  yyText(yy, yy->__begin, yy->__end);  if (!(YY_BEGIN)) goto l37;
+  l43:;	
+  {  int yypos44= yy->__pos, yythunkpos44= yy->__thunkpos;
+  {  int yypos45= yy->__pos, yythunkpos45= yy->__thunkpos;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l45;  goto l44;
+  l45:;	  yy->__pos= yypos45; yy->__thunkpos= yythunkpos45;
+  }  if (!yy_char(yy)) goto l44;  goto l43;
+  l44:;	  yy->__pos= yypos44; yy->__thunkpos= yythunkpos44;
+  }  yyText(yy, yy->__begin, yy->__end);  if (!(YY_END)) goto l37;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l37;  if (!yy__(yy)) goto l37;
+  }
+  l38:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "literal", yy->__buf+yy->__pos));
+  return 1;
+  l37:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "literal", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_CLOSE(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "CLOSE"));  if (!yymatchChar(yy, ')')) goto l46;  if (!yy__(yy)) goto l46;
+  yyprintf((stderr, "  ok   %s @ %s\n", "CLOSE", yy->__buf+yy->__pos));
+  return 1;
+  l46:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "CLOSE", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_OPEN(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "OPEN"));  if (!yymatchChar(yy, '(')) goto l47;  if (!yy__(yy)) goto l47;
+  yyprintf((stderr, "  ok   %s @ %s\n", "OPEN", yy->__buf+yy->__pos));
+  return 1;
+  l47:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "OPEN", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_COLON(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "COLON"));  if (!yymatchChar(yy, ':')) goto l48;  if (!yy__(yy)) goto l48;
+  yyprintf((stderr, "  ok   %s @ %s\n", "COLON", yy->__buf+yy->__pos));
+  return 1;
+  l48:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "COLON", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_PLUS(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "PLUS"));  if (!yymatchChar(yy, '+')) goto l49;  if (!yy__(yy)) goto l49;
+  yyprintf((stderr, "  ok   %s @ %s\n", "PLUS", yy->__buf+yy->__pos));
+  return 1;
+  l49:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "PLUS", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_STAR(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "STAR"));  if (!yymatchChar(yy, '*')) goto l50;  if (!yy__(yy)) goto l50;
+  yyprintf((stderr, "  ok   %s @ %s\n", "STAR", yy->__buf+yy->__pos));
+  return 1;
+  l50:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "STAR", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_QUESTION(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "QUESTION"));  if (!yymatchChar(yy, '?')) goto l51;  if (!yy__(yy)) goto l51;
+  yyprintf((stderr, "  ok   %s @ %s\n", "QUESTION", yy->__buf+yy->__pos));
+  return 1;
+  l51:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "QUESTION", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_primary(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "primary"));
+  {  int yypos53= yy->__pos, yythunkpos53= yy->__thunkpos;  if (!yy_identifier(yy)) goto l54;  yyDo(yy, yy_1_primary, yy->__begin, yy->__end);  if (!yy_COLON(yy)) goto l54;  if (!yy_identifier(yy)) goto l54;
+  {  int yypos55= yy->__pos, yythunkpos55= yy->__thunkpos;  if (!yy_EQUAL(yy)) goto l55;  goto l54;
+  l55:;	  yy->__pos= yypos55; yy->__thunkpos= yythunkpos55;
+  }  yyDo(yy, yy_2_primary, yy->__begin, yy->__end);  goto l53;
+  l54:;	  yy->__pos= yypos53; yy->__thunkpos= yythunkpos53;  if (!yy_identifier(yy)) goto l56;
+  {  int yypos57= yy->__pos, yythunkpos57= yy->__thunkpos;  if (!yy_EQUAL(yy)) goto l57;  goto l56;
+  l57:;	  yy->__pos= yypos57; yy->__thunkpos= yythunkpos57;
+  }  yyDo(yy, yy_3_primary, yy->__begin, yy->__end);  goto l53;
+  l56:;	  yy->__pos= yypos53; yy->__thunkpos= yythunkpos53;  if (!yy_OPEN(yy)) goto l58;  if (!yy_expression(yy)) goto l58;  if (!yy_CLOSE(yy)) goto l58;  goto l53;
+  l58:;	  yy->__pos= yypos53; yy->__thunkpos= yythunkpos53;  if (!yy_literal(yy)) goto l59;  yyDo(yy, yy_4_primary, yy->__begin, yy->__end);  goto l53;
+  l59:;	  yy->__pos= yypos53; yy->__thunkpos= yythunkpos53;  if (!yy_class(yy)) goto l60;  yyDo(yy, yy_5_primary, yy->__begin, yy->__end);  goto l53;
+  l60:;	  yy->__pos= yypos53; yy->__thunkpos= yythunkpos53;  if (!yy_DOT(yy)) goto l61;  yyDo(yy, yy_6_primary, yy->__begin, yy->__end);  goto l53;
+  l61:;	  yy->__pos= yypos53; yy->__thunkpos= yythunkpos53;  if (!yy_action(yy)) goto l62;  yyDo(yy, yy_7_primary, yy->__begin, yy->__end);  goto l53;
+  l62:;	  yy->__pos= yypos53; yy->__thunkpos= yythunkpos53;  if (!yy_BEGIN(yy)) goto l63;  yyDo(yy, yy_8_primary, yy->__begin, yy->__end);  goto l53;
+  l63:;	  yy->__pos= yypos53; yy->__thunkpos= yythunkpos53;  if (!yy_END(yy)) goto l52;  yyDo(yy, yy_9_primary, yy->__begin, yy->__end);
+  }
+  l53:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "primary", yy->__buf+yy->__pos));
+  return 1;
+  l52:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "primary", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_NOT(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "NOT"));  if (!yymatchChar(yy, '!')) goto l64;  if (!yy__(yy)) goto l64;
+  yyprintf((stderr, "  ok   %s @ %s\n", "NOT", yy->__buf+yy->__pos));
+  return 1;
+  l64:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "NOT", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_suffix(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "suffix"));  if (!yy_primary(yy)) goto l65;
+  {  int yypos66= yy->__pos, yythunkpos66= yy->__thunkpos;
+  {  int yypos68= yy->__pos, yythunkpos68= yy->__thunkpos;  if (!yy_QUESTION(yy)) goto l69;  yyDo(yy, yy_1_suffix, yy->__begin, yy->__end);  goto l68;
+  l69:;	  yy->__pos= yypos68; yy->__thunkpos= yythunkpos68;  if (!yy_STAR(yy)) goto l70;  yyDo(yy, yy_2_suffix, yy->__begin, yy->__end);  goto l68;
+  l70:;	  yy->__pos= yypos68; yy->__thunkpos= yythunkpos68;  if (!yy_PLUS(yy)) goto l66;  yyDo(yy, yy_3_suffix, yy->__begin, yy->__end);
+  }
+  l68:;	  goto l67;
+  l66:;	  yy->__pos= yypos66; yy->__thunkpos= yythunkpos66;
+  }
+  l67:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "suffix", yy->__buf+yy->__pos));
+  return 1;
+  l65:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "suffix", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_AND(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "AND"));  if (!yymatchChar(yy, '&')) goto l71;  if (!yy__(yy)) goto l71;
+  yyprintf((stderr, "  ok   %s @ %s\n", "AND", yy->__buf+yy->__pos));
+  return 1;
+  l71:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "AND", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_action(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "action"));  if (!yymatchChar(yy, '{')) goto l72;  yyText(yy, yy->__begin, yy->__end);  if (!(YY_BEGIN)) goto l72;
+  l73:;	
+  {  int yypos74= yy->__pos, yythunkpos74= yy->__thunkpos;  if (!yy_braces(yy)) goto l74;  goto l73;
+  l74:;	  yy->__pos= yypos74; yy->__thunkpos= yythunkpos74;
+  }  yyText(yy, yy->__begin, yy->__end);  if (!(YY_END)) goto l72;  if (!yymatchChar(yy, '}')) goto l72;  if (!yy__(yy)) goto l72;
+  yyprintf((stderr, "  ok   %s @ %s\n", "action", yy->__buf+yy->__pos));
+  return 1;
+  l72:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "action", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_TILDE(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "TILDE"));  if (!yymatchChar(yy, '~')) goto l75;  if (!yy__(yy)) goto l75;
+  yyprintf((stderr, "  ok   %s @ %s\n", "TILDE", yy->__buf+yy->__pos));
+  return 1;
+  l75:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "TILDE", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_prefix(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "prefix"));
+  {  int yypos77= yy->__pos, yythunkpos77= yy->__thunkpos;  if (!yy_AND(yy)) goto l78;  if (!yy_action(yy)) goto l78;  yyDo(yy, yy_1_prefix, yy->__begin, yy->__end);  goto l77;
+  l78:;	  yy->__pos= yypos77; yy->__thunkpos= yythunkpos77;  if (!yy_AND(yy)) goto l79;  if (!yy_suffix(yy)) goto l79;  yyDo(yy, yy_2_prefix, yy->__begin, yy->__end);  goto l77;
+  l79:;	  yy->__pos= yypos77; yy->__thunkpos= yythunkpos77;  if (!yy_NOT(yy)) goto l80;  if (!yy_suffix(yy)) goto l80;  yyDo(yy, yy_3_prefix, yy->__begin, yy->__end);  goto l77;
+  l80:;	  yy->__pos= yypos77; yy->__thunkpos= yythunkpos77;  if (!yy_suffix(yy)) goto l76;
+  }
+  l77:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "prefix", yy->__buf+yy->__pos));
+  return 1;
+  l76:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "prefix", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_error(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "error"));  if (!yy_prefix(yy)) goto l81;
+  {  int yypos82= yy->__pos, yythunkpos82= yy->__thunkpos;  if (!yy_TILDE(yy)) goto l82;  if (!yy_action(yy)) goto l82;  yyDo(yy, yy_1_error, yy->__begin, yy->__end);  goto l83;
+  l82:;	  yy->__pos= yypos82; yy->__thunkpos= yythunkpos82;
+  }
+  l83:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "error", yy->__buf+yy->__pos));
+  return 1;
+  l81:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "error", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_BAR(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "BAR"));  if (!yymatchChar(yy, '|')) goto l84;  if (!yy__(yy)) goto l84;
+  yyprintf((stderr, "  ok   %s @ %s\n", "BAR", yy->__buf+yy->__pos));
+  return 1;
+  l84:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "BAR", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_sequence(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "sequence"));  if (!yy_error(yy)) goto l85;
+  l86:;	
+  {  int yypos87= yy->__pos, yythunkpos87= yy->__thunkpos;  if (!yy_error(yy)) goto l87;  yyDo(yy, yy_1_sequence, yy->__begin, yy->__end);  goto l86;
+  l87:;	  yy->__pos= yypos87; yy->__thunkpos= yythunkpos87;
+  }
+  yyprintf((stderr, "  ok   %s @ %s\n", "sequence", yy->__buf+yy->__pos));
+  return 1;
+  l85:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "sequence", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_SEMICOLON(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "SEMICOLON"));  if (!yymatchChar(yy, ';')) goto l88;  if (!yy__(yy)) goto l88;
+  yyprintf((stderr, "  ok   %s @ %s\n", "SEMICOLON", yy->__buf+yy->__pos));
+  return 1;
+  l88:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "SEMICOLON", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_expression(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "expression"));  if (!yy_sequence(yy)) goto l89;
+  l90:;	
+  {  int yypos91= yy->__pos, yythunkpos91= yy->__thunkpos;  if (!yy_BAR(yy)) goto l91;  if (!yy_sequence(yy)) goto l91;  yyDo(yy, yy_1_expression, yy->__begin, yy->__end);  goto l90;
+  l91:;	  yy->__pos= yypos91; yy->__thunkpos= yythunkpos91;
+  }
+  yyprintf((stderr, "  ok   %s @ %s\n", "expression", yy->__buf+yy->__pos));
+  return 1;
+  l89:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "expression", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_EQUAL(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "EQUAL"));  if (!yymatchChar(yy, '=')) goto l92;  if (!yy__(yy)) goto l92;
+  yyprintf((stderr, "  ok   %s @ %s\n", "EQUAL", yy->__buf+yy->__pos));
+  return 1;
+  l92:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "EQUAL", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_identifier(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "identifier"));  yyText(yy, yy->__begin, yy->__end);  if (!(YY_BEGIN)) goto l93;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\040\000\000\376\377\377\207\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l93;
+  l94:;	
+  {  int yypos95= yy->__pos, yythunkpos95= yy->__thunkpos;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\040\377\003\376\377\377\207\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l95;  goto l94;
+  l95:;	  yy->__pos= yypos95; yy->__thunkpos= yythunkpos95;
+  }  yyText(yy, yy->__begin, yy->__end);  if (!(YY_END)) goto l93;  if (!yy__(yy)) goto l93;
+  yyprintf((stderr, "  ok   %s @ %s\n", "identifier", yy->__buf+yy->__pos));
+  return 1;
+  l93:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "identifier", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_RPERCENT(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "RPERCENT"));  if (!yymatchString(yy, "%}")) goto l96;  if (!yy__(yy)) goto l96;
+  yyprintf((stderr, "  ok   %s @ %s\n", "RPERCENT", yy->__buf+yy->__pos));
+  return 1;
+  l96:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "RPERCENT", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_end_of_file(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "end_of_file"));
+  {  int yypos98= yy->__pos, yythunkpos98= yy->__thunkpos;  if (!yymatchDot(yy)) goto l98;  goto l97;
+  l98:;	  yy->__pos= yypos98; yy->__thunkpos= yythunkpos98;
+  }
+  yyprintf((stderr, "  ok   %s @ %s\n", "end_of_file", yy->__buf+yy->__pos));
+  return 1;
+  l97:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "end_of_file", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_trailer(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "trailer"));  if (!yymatchString(yy, "%%")) goto l99;  yyText(yy, yy->__begin, yy->__end);  if (!(YY_BEGIN)) goto l99;
+  l100:;	
+  {  int yypos101= yy->__pos, yythunkpos101= yy->__thunkpos;  if (!yymatchDot(yy)) goto l101;  goto l100;
+  l101:;	  yy->__pos= yypos101; yy->__thunkpos= yythunkpos101;
+  }  yyText(yy, yy->__begin, yy->__end);  if (!(YY_END)) goto l99;  yyDo(yy, yy_1_trailer, yy->__begin, yy->__end);
+  yyprintf((stderr, "  ok   %s @ %s\n", "trailer", yy->__buf+yy->__pos));
+  return 1;
+  l99:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "trailer", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_definition(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "definition"));  if (!yy_identifier(yy)) goto l102;  yyDo(yy, yy_1_definition, yy->__begin, yy->__end);  if (!yy_EQUAL(yy)) goto l102;  if (!yy_expression(yy)) goto l102;  yyDo(yy, yy_2_definition, yy->__begin, yy->__end);
+  {  int yypos103= yy->__pos, yythunkpos103= yy->__thunkpos;  if (!yy_SEMICOLON(yy)) goto l103;  goto l104;
+  l103:;	  yy->__pos= yypos103; yy->__thunkpos= yythunkpos103;
+  }
+  l104:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "definition", yy->__buf+yy->__pos));
+  return 1;
+  l102:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "definition", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_declaration(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "declaration"));  if (!yymatchString(yy, "%{")) goto l105;  yyText(yy, yy->__begin, yy->__end);  if (!(YY_BEGIN)) goto l105;
+  l106:;	
+  {  int yypos107= yy->__pos, yythunkpos107= yy->__thunkpos;
+  {  int yypos108= yy->__pos, yythunkpos108= yy->__thunkpos;  if (!yymatchString(yy, "%}")) goto l108;  goto l107;
+  l108:;	  yy->__pos= yypos108; yy->__thunkpos= yythunkpos108;
+  }  if (!yymatchDot(yy)) goto l107;  goto l106;
+  l107:;	  yy->__pos= yypos107; yy->__thunkpos= yythunkpos107;
+  }  yyText(yy, yy->__begin, yy->__end);  if (!(YY_END)) goto l105;  if (!yy_RPERCENT(yy)) goto l105;  yyDo(yy, yy_1_declaration, yy->__begin, yy->__end);
+  yyprintf((stderr, "  ok   %s @ %s\n", "declaration", yy->__buf+yy->__pos));
+  return 1;
+  l105:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "declaration", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy__(yycontext *yy)
+{
+  yyprintf((stderr, "%s\n", "_"));
+  l110:;	
+  {  int yypos111= yy->__pos, yythunkpos111= yy->__thunkpos;
+  {  int yypos112= yy->__pos, yythunkpos112= yy->__thunkpos;  if (!yy_space(yy)) goto l113;  goto l112;
+  l113:;	  yy->__pos= yypos112; yy->__thunkpos= yythunkpos112;  if (!yy_comment(yy)) goto l111;
+  }
+  l112:;	  goto l110;
+  l111:;	  yy->__pos= yypos111; yy->__thunkpos= yythunkpos111;
+  }
+  yyprintf((stderr, "  ok   %s @ %s\n", "_", yy->__buf+yy->__pos));
+  return 1;
+}
+YY_RULE(int) yy_grammar(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "grammar"));  if (!yy__(yy)) goto l114;
+  {  int yypos117= yy->__pos, yythunkpos117= yy->__thunkpos;  if (!yy_declaration(yy)) goto l118;  goto l117;
+  l118:;	  yy->__pos= yypos117; yy->__thunkpos= yythunkpos117;  if (!yy_definition(yy)) goto l114;
+  }
+  l117:;	
+  l115:;	
+  {  int yypos116= yy->__pos, yythunkpos116= yy->__thunkpos;
+  {  int yypos119= yy->__pos, yythunkpos119= yy->__thunkpos;  if (!yy_declaration(yy)) goto l120;  goto l119;
+  l120:;	  yy->__pos= yypos119; yy->__thunkpos= yythunkpos119;  if (!yy_definition(yy)) goto l116;
+  }
+  l119:;	  goto l115;
+  l116:;	  yy->__pos= yypos116; yy->__thunkpos= yythunkpos116;
+  }
+  {  int yypos121= yy->__pos, yythunkpos121= yy->__thunkpos;  if (!yy_trailer(yy)) goto l121;  goto l122;
+  l121:;	  yy->__pos= yypos121; yy->__thunkpos= yythunkpos121;
+  }
+  l122:;	  if (!yy_end_of_file(yy)) goto l114;
+  yyprintf((stderr, "  ok   %s @ %s\n", "grammar", yy->__buf+yy->__pos));
+  return 1;
+  l114:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "grammar", yy->__buf+yy->__pos));
+  return 0;
+}
+
+#ifndef YY_PART
+
+typedef int (*yyrule)(yycontext *yy);
+
+YY_PARSE(int) YYPARSEFROM(YY_CTX_PARAM_ yyrule yystart)
+{
+  int yyok;
+  if (!yyctx->__buflen)
+    {
+      yyctx->__buflen= YY_BUFFER_SIZE;
+      yyctx->__buf= (char *)YY_MALLOC(yyctx, yyctx->__buflen);
+      yyctx->__textlen= YY_BUFFER_SIZE;
+      yyctx->__text= (char *)YY_MALLOC(yyctx, yyctx->__textlen);
+      yyctx->__thunkslen= YY_STACK_SIZE;
+      yyctx->__thunks= (yythunk *)YY_MALLOC(yyctx, sizeof(yythunk) * yyctx->__thunkslen);
+      yyctx->__valslen= YY_STACK_SIZE;
+      yyctx->__vals= (YYSTYPE *)YY_MALLOC(yyctx, sizeof(YYSTYPE) * yyctx->__valslen);
+      yyctx->__begin= yyctx->__end= yyctx->__pos= yyctx->__limit= yyctx->__thunkpos= 0;
+    }
+  yyctx->__begin= yyctx->__end= yyctx->__pos;
+  yyctx->__thunkpos= 0;
+  yyctx->__val= yyctx->__vals;
+  yyok= yystart(yyctx);
+  if (yyok) yyDone(yyctx);
+  yyCommit(yyctx);
+  return yyok;
+}
+
+YY_PARSE(int) YYPARSE(YY_CTX_PARAM)
+{
+  return YYPARSEFROM(YY_CTX_ARG_ yy_grammar);
+}
+
+YY_PARSE(yycontext *) YYRELEASE(yycontext *yyctx)
+{
+  if (yyctx->__buflen)
+    {
+      yyctx->__buflen= 0;
+      YY_FREE(yyctx->__buf);
+      YY_FREE(yyctx->__text);
+      YY_FREE(yyctx->__thunks);
+      YY_FREE(yyctx->__vals);
+    }
+  return yyctx;
+}
+
+#endif
+
+
+void yyerror(char *message)
+{
+  fprintf(stderr, "%s:%d: %s", fileName, lineNumber, message);
+  if (yyctx->__text[0]) fprintf(stderr, " near token '%s'", yyctx->__text);
+  if (yyctx->__pos < yyctx->__limit || !feof(input))
+    {
+      yyctx->__buf[yyctx->__limit]= '\0';
+      fprintf(stderr, " before text \"");
+      while (yyctx->__pos < yyctx->__limit)
+	{
+	  if ('\n' == yyctx->__buf[yyctx->__pos] || '\r' == yyctx->__buf[yyctx->__pos]) break;
+	  fputc(yyctx->__buf[yyctx->__pos++], stderr);
+	}
+      if (yyctx->__pos == yyctx->__limit)
+	{
+	  int c;
+	  while (EOF != (c= fgetc(input)) && '\n' != c && '\r' != c)
+	    fputc(c, stderr);
+	}
+      fputc('\"', stderr);
+    }
+  fprintf(stderr, "\n");
+  exit(1);
+}
+
+void makeHeader(char *text)
+{
+  Header *header= (Header *)malloc(sizeof(Header));
+  header->text= strdup(text);
+  header->next= headers;
+  headers= header;
+}
+
+void makeTrailer(char *text)
+{
+  trailer= strdup(text);
+}
+
+static void version(char *name)
+{
+  printf("%s version %d.%d.%d\n", name, PEG_MAJOR, PEG_MINOR, PEG_LEVEL);
+}
+
+static void usage(char *name)
+{
+  version(name);
+  fprintf(stderr, "usage: %s [<option>...] [<file>...]\n", name);
+  fprintf(stderr, "where <option> can be\n");
+  fprintf(stderr, "  -h          print this help information\n");
+  fprintf(stderr, "  -o <ofile>  write output to <ofile>\n");
+  fprintf(stderr, "  -v          be verbose\n");
+  fprintf(stderr, "  -V          print version number and exit\n");
+  fprintf(stderr, "if no <file> is given, input is read from stdin\n");
+  fprintf(stderr, "if no <ofile> is given, output is written to stdout\n");
+  exit(1);
+}
+
+int main(int argc, char **argv)
+{
+  Node *n;
+  int   c;
+
+  output= stdout;
+  input= stdin;
+  lineNumber= 1;
+  fileName= "<stdin>";
+
+  while (-1 != (c= getopt(argc, argv, "Vho:v")))
+    {
+      switch (c)
+	{
+	case 'V':
+	  version(basename(argv[0]));
+	  exit(0);
+
+	case 'h':
+	  usage(basename(argv[0]));
+	  break;
+
+	case 'o':
+	  if (!(output= fopen(optarg, "w")))
+	    {
+	      perror(optarg);
+	      exit(1);
+	    }
+	  break;
+
+	case 'v':
+	  verboseFlag= 1;
+	  break;
+
+	default:
+	  fprintf(stderr, "for usage try: %s -h\n", argv[0]);
+	  exit(1);
+	}
+    }
+  argc -= optind;
+  argv += optind;
+
+  if (argc)
+    {
+      for (;  argc;  --argc, ++argv)
+	{
+	  if (!strcmp(*argv, "-"))
+	    {
+	      input= stdin;
+	      fileName= "<stdin>";
+	    }
+	  else
+	    {
+	      if (!(input= fopen(*argv, "r")))
+		{
+		  perror(*argv);
+		  exit(1);
+		}
+	      fileName= *argv;
+	    }
+	  lineNumber= 1;
+	  if (!yyparse())
+	    yyerror("syntax error");
+	  if (input != stdin)
+	    fclose(input);
+	}
+    }
+  else
+    if (!yyparse())
+      yyerror("syntax error");
+
+  if (verboseFlag)
+    for (n= rules;  n;  n= n->any.next)
+      Rule_print(n);
+
+  Rule_compile_c_header();
+
+  for (; headers;  headers= headers->next)
+    fprintf(output, "%s\n", headers->text);
+
+  if (rules)
+    Rule_compile_c(rules);
+
+  if (trailer)
+    fprintf(output, "%s\n", trailer);
+
+  return 0;
+}
+
--- /dev/null
+++ b/src/leg.leg
@@ -1,0 +1,296 @@
+# LE Grammar for LE Grammars
+# 
+# Copyright (c) 2007 by Ian Piumarta
+# All rights reserved.
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the 'Software'),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, provided that the above copyright notice(s) and this
+# permission notice appear in all copies of the Software.  Acknowledgement
+# of the use of this Software in supporting documentation would be
+# appreciated but is not required.
+# 
+# THE SOFTWARE IS PROVIDED 'AS IS'.  USE ENTIRELY AT YOUR OWN RISK.
+# 
+# Last edited: 2012-05-16 08:56:08 by piumarta on emilia
+
+%{
+# include "tree.h"
+# include "version.h"
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <unistd.h>
+# include <string.h>
+# include <libgen.h>
+# include <assert.h>
+
+  typedef struct Header Header;
+
+  struct Header {
+    char   *text;
+    Header *next;
+  };
+
+  FILE *input= 0;
+
+  int   verboseFlag= 0;
+
+  static int	 lineNumber= 0;
+  static char	*fileName= 0;
+  static char	*trailer= 0;
+  static Header	*headers= 0;
+
+  void makeHeader(char *text);
+  void makeTrailer(char *text);
+
+  void yyerror(char *message);
+
+# define YY_INPUT(buf, result, max)		\
+  {						\
+    int c= getc(input);				\
+    if ('\n' == c || '\r' == c) ++lineNumber;	\
+    result= (EOF == c) ? 0 : (*(buf)= c, 1);	\
+  }
+
+# define YY_LOCAL(T)	static T
+# define YY_RULE(T)	static T
+%}
+
+# Hierarchical syntax
+
+grammar=	- ( declaration | definition )+ trailer? end-of-file
+
+declaration=	'%{' < ( !'%}' . )* > RPERCENT		{ makeHeader(yytext); }						#{YYACCEPT}
+
+trailer=	'%%' < .* >				{ makeTrailer(yytext); }					#{YYACCEPT}
+
+definition=	identifier 				{ if (push(beginRule(findRule(yytext)))->rule.expression)
+							    fprintf(stderr, "rule '%s' redefined\n", yytext); }
+			EQUAL expression		{ Node *e= pop();  Rule_setExpression(pop(), e); }
+			SEMICOLON?											#{YYACCEPT}
+
+expression=	sequence (BAR sequence			{ Node *f= pop();  push(Alternate_append(pop(), f)); }
+			    )*
+
+sequence=	error   (error				{ Node *f= pop();  push(Sequence_append(pop(), f)); }
+			)*
+
+error=		prefix  (TILDE action			{ push(makeError(pop(), yytext)); }
+			)?
+
+prefix=		AND action				{ push(makePredicate(yytext)); }
+|		AND suffix				{ push(makePeekFor(pop())); }
+|		NOT suffix				{ push(makePeekNot(pop())); }
+|		    suffix
+
+suffix=		primary (QUESTION			{ push(makeQuery(pop())); }
+			     | STAR			{ push(makeStar (pop())); }
+			     | PLUS			{ push(makePlus (pop())); }
+			   )?
+
+primary=	identifier				{ push(makeVariable(yytext)); }
+			COLON identifier !EQUAL		{ Node *name= makeName(findRule(yytext));  name->name.variable= pop();  push(name); }
+|		identifier !EQUAL			{ push(makeName(findRule(yytext))); }
+|		OPEN expression CLOSE
+|		literal					{ push(makeString(yytext)); }
+|		class					{ push(makeClass(yytext)); }
+|		DOT					{ push(makeDot()); }
+|		action					{ push(makeAction(yytext)); }
+|		BEGIN					{ push(makePredicate("YY_BEGIN")); }
+|		END					{ push(makePredicate("YY_END")); }
+
+# Lexical syntax
+
+identifier=	< [-a-zA-Z_][-a-zA-Z_0-9]* > -
+
+literal=	['] < ( !['] char )* > ['] -
+|		["] < ( !["] char )* > ["] -
+
+class=		'[' < ( !']' range )* > ']' -
+
+range=		char '-' char | char
+
+char=		'\\' [-abefnrtv'"\[\]\\]
+|		'\\' [0-3][0-7][0-7]
+|		'\\' [0-7][0-7]?
+|		!'\\' .
+
+action=		'{' < braces* > '}' -
+
+braces=		'{' braces* '}'
+|		!'}' .
+
+EQUAL=		'=' -
+COLON=		':' -
+SEMICOLON=	';' -
+BAR=		'|' -
+AND=		'&' -
+NOT=		'!' -
+QUESTION=	'?' -
+STAR=		'*' -
+PLUS=		'+' -
+OPEN=		'(' -
+CLOSE=		')' -
+DOT=		'.' -
+BEGIN=		'<' -
+END=		'>' -
+TILDE=		'~' -
+RPERCENT=	'%}' -
+
+-=		(space | comment)*
+space=		' ' | '\t' | end-of-line
+comment=	'#' (!end-of-line .)* end-of-line
+end-of-line=	'\r\n' | '\n' | '\r'
+end-of-file=	!.
+
+%%
+
+void yyerror(char *message)
+{
+  fprintf(stderr, "%s:%d: %s", fileName, lineNumber, message);
+  if (yyctx->__text[0]) fprintf(stderr, " near token '%s'", yyctx->__text);
+  if (yyctx->__pos < yyctx->__limit || !feof(input))
+    {
+      yyctx->__buf[yyctx->__limit]= '\0';
+      fprintf(stderr, " before text \"");
+      while (yyctx->__pos < yyctx->__limit)
+	{
+	  if ('\n' == yyctx->__buf[yyctx->__pos] || '\r' == yyctx->__buf[yyctx->__pos]) break;
+	  fputc(yyctx->__buf[yyctx->__pos++], stderr);
+	}
+      if (yyctx->__pos == yyctx->__limit)
+	{
+	  int c;
+	  while (EOF != (c= fgetc(input)) && '\n' != c && '\r' != c)
+	    fputc(c, stderr);
+	}
+      fputc('\"', stderr);
+    }
+  fprintf(stderr, "\n");
+  exit(1);
+}
+
+void makeHeader(char *text)
+{
+  Header *header= (Header *)malloc(sizeof(Header));
+  header->text= strdup(text);
+  header->next= headers;
+  headers= header;
+}
+
+void makeTrailer(char *text)
+{
+  trailer= strdup(text);
+}
+
+static void version(char *name)
+{
+  printf("%s version %d.%d.%d\n", name, PEG_MAJOR, PEG_MINOR, PEG_LEVEL);
+}
+
+static void usage(char *name)
+{
+  version(name);
+  fprintf(stderr, "usage: %s [<option>...] [<file>...]\n", name);
+  fprintf(stderr, "where <option> can be\n");
+  fprintf(stderr, "  -h          print this help information\n");
+  fprintf(stderr, "  -o <ofile>  write output to <ofile>\n");
+  fprintf(stderr, "  -v          be verbose\n");
+  fprintf(stderr, "  -V          print version number and exit\n");
+  fprintf(stderr, "if no <file> is given, input is read from stdin\n");
+  fprintf(stderr, "if no <ofile> is given, output is written to stdout\n");
+  exit(1);
+}
+
+int main(int argc, char **argv)
+{
+  Node *n;
+  int   c;
+
+  output= stdout;
+  input= stdin;
+  lineNumber= 1;
+  fileName= "<stdin>";
+
+  while (-1 != (c= getopt(argc, argv, "Vho:v")))
+    {
+      switch (c)
+	{
+	case 'V':
+	  version(basename(argv[0]));
+	  exit(0);
+
+	case 'h':
+	  usage(basename(argv[0]));
+	  break;
+
+	case 'o':
+	  if (!(output= fopen(optarg, "w")))
+	    {
+	      perror(optarg);
+	      exit(1);
+	    }
+	  break;
+
+	case 'v':
+	  verboseFlag= 1;
+	  break;
+
+	default:
+	  fprintf(stderr, "for usage try: %s -h\n", argv[0]);
+	  exit(1);
+	}
+    }
+  argc -= optind;
+  argv += optind;
+
+  if (argc)
+    {
+      for (;  argc;  --argc, ++argv)
+	{
+	  if (!strcmp(*argv, "-"))
+	    {
+	      input= stdin;
+	      fileName= "<stdin>";
+	    }
+	  else
+	    {
+	      if (!(input= fopen(*argv, "r")))
+		{
+		  perror(*argv);
+		  exit(1);
+		}
+	      fileName= *argv;
+	    }
+	  lineNumber= 1;
+	  if (!yyparse())
+	    yyerror("syntax error");
+	  if (input != stdin)
+	    fclose(input);
+	}
+    }
+  else
+    if (!yyparse())
+      yyerror("syntax error");
+
+  if (verboseFlag)
+    for (n= rules;  n;  n= n->any.next)
+      Rule_print(n);
+
+  Rule_compile_c_header();
+
+  for (; headers;  headers= headers->next)
+    fprintf(output, "%s\n", headers->text);
+
+  if (rules)
+    Rule_compile_c(rules);
+
+  if (trailer)
+    fprintf(output, "%s\n", trailer);
+
+  return 0;
+}
--- /dev/null
+++ b/src/peg.1
@@ -1,0 +1,1093 @@
+.\" Copyright (c) 2007 by Ian Piumarta
+.\" All rights reserved.
+.\" 
+.\" Permission is hereby granted, free of charge, to any person obtaining a
+.\" copy of this software and associated documentation files (the 'Software'),
+.\" to deal in the Software without restriction, including without limitation
+.\" the rights to use, copy, modify, merge, publish, distribute, and/or sell
+.\" copies of the Software, and to permit persons to whom the Software is
+.\" furnished to do so, provided that the above copyright notice(s) and this
+.\" permission notice appear in all copies of the Software.  Acknowledgement
+.\" of the use of this Software in supporting documentation would be
+.\" appreciated but is not required.
+.\" 
+.\" THE SOFTWARE IS PROVIDED 'AS IS'.  USE ENTIRELY AT YOUR OWN RISK.
+.\" 
+.\" Last edited: 2012-05-17 15:38:34 by piumarta on emilia
+.\"
+.TH PEG 1 "April 2012" "Version 0.1"
+.SH NAME
+peg, leg \- parser generators
+.SH SYNOPSIS
+.B peg
+.B [\-hvV \-ooutput]
+.I [filename ...]
+.sp 0
+.B leg
+.B [\-hvV \-ooutput]
+.I [filename ...]
+.SH DESCRIPTION
+.I peg
+and
+.I leg
+are tools for generating recursive-descent parsers: programs that
+perform pattern matching on text.  They process a Parsing Expression
+Grammar (PEG) [Ford 2004] to produce a program that recognises legal
+sentences of that grammar.
+.I peg
+processes PEGs written using the original syntax described by Ford;
+.I leg
+processes PEGs written using slightly different syntax and conventions
+that are intended to make it an attractive replacement for parsers
+built with
+.IR lex (1)
+and
+.IR yacc (1).
+Unlike
+.I lex
+and
+.IR yacc ,
+.I peg
+and
+.I leg
+support unlimited backtracking, provide ordered choice as a means for
+disambiguation, and can combine scanning (lexical analysis) and
+parsing (syntactic analysis) into a single activity.
+.PP
+.I peg
+reads the specified
+.IR filename s,
+or standard input if no
+.IR filename s
+are given, for a grammar describing the parser to generate.
+.I peg
+then generates a C source file that defines a function
+.IR yyparse().
+This C source file can be included in, or compiled and then linked
+with, a client program.  Each time the client program calls
+.IR yyparse ()
+the parser consumes input text according to the parsing rules,
+starting from the first rule in the grammar.
+.IR yyparse ()
+returns non-zero if the input could be parsed according to the
+grammar; it returns zero if the input could not be parsed.
+.PP
+The prefix 'yy' or 'YY' is prepended to all externally-visible symbols
+in the generated parser.  This is intended to reduce the risk of
+namespace pollution in client programs.  (The choice of 'yy' is
+historical; see
+.IR lex (1)
+and
+.IR yacc (1),
+for example.)
+.SH OPTIONS
+.I peg
+and 
+.I leg
+provide the following options:
+.TP
+.B \-h
+prints a summary of available options and then exits.
+.TP
+.B \-ooutput
+writes the generated parser to the file
+.B output
+instead of the standard output.
+.TP
+.B \-v
+writes verbose information to standard error while working.
+.TP
+.B \-V
+writes version information to standard error then exits.
+.SH A SIMPLE EXAMPLE
+The following
+.I peg
+input specifies a grammar with a single rule (called 'start') that is
+satisfied when the input contains the string "username".
+.nf
+
+    start <- "username"
+
+.fi
+(The quotation marks are
+.I not
+part of the matched text; they serve to indicate a literal string to
+be matched.)  In other words,
+.IR  yyparse ()
+in the generated C source will return non-zero only if the next eight
+characters read from the input spell the word "username".  If the
+input contains anything else,
+.IR yyparse ()
+returns zero and no input will have been consumed.  (Subsequent calls
+to
+.IR yyparse ()
+will also return zero, since the parser is effectively blocked looking
+for the string "username".)  To ensure progress we can add an
+alternative clause to the 'start' rule that will match any single
+character if "username" is not found.
+.nf
+
+    start <- "username"
+           / .
+
+.fi
+.IR yyparse ()
+now always returns non-zero (except at the very end of the input).  To
+do something useful we can add actions to the rules.  These actions
+are performed after a complete match is found (starting from the first
+rule) and are chosen according to the 'path' taken through the grammar
+to match the input.  (Linguists would call this path a 'phrase
+marker'.)
+.nf
+
+    start <- "username"    { printf("%s\\n", getlogin()); }
+           / < . >         { putchar(yytext[0]); }
+
+.fi
+The first line instructs the parser to print the user's login name
+whenever it sees "username" in the input.  If that match fails, the
+second line tells the parser to echo the next character on the input
+the standard output.  Our parser is now performing useful work: it
+will copy the input to the output, replacing all occurrences of
+"username" with the user's account name.
+.PP
+Note the angle brackets ('<' and '>') that were added to the second
+alternative.  These have no effect on the meaning of the rule, but
+serve to delimit the text made available to the following action in
+the variable
+.IR yytext .
+.PP
+If the above grammar is placed in the file
+.BR username.peg ,
+running the command
+.nf
+
+    peg -o username.c username.peg
+
+.fi
+will save the corresponding parser in the file
+.BR username.c .
+To create a complete program this parser could be included by a C
+program as follows.
+.nf
+
+    #include <stdio.h>      /* printf(), putchar() */
+    #include <unistd.h>     /* getlogin() */
+
+    #include "username.c"   /* yyparse() */
+
+    int main()
+    {
+      while (yyparse())     /* repeat until EOF */
+        ;
+      return 0;
+    }
+.fi
+.SH PEG GRAMMARS
+A grammar consists of a set of named rules.
+.nf
+
+    name <- pattern
+
+.fi
+The
+.B pattern
+contains one or more of the following elements.
+.TP
+.B name
+The element stands for the entire pattern in the rule with the given
+.BR name .
+.TP
+.BR \(dq characters \(dq
+A character or string enclosed in double quotes is matched literally.
+The ANSI C esacpe sequences are recognised within the
+.IR characters .
+.TP
+.BR ' characters '
+A character or string enclosed in single quotes is matched literally, as above.
+.TP
+.BR [ characters ]
+A set of characters enclosed in square brackets matches any single
+character from the set, with escape characters recognised as above.
+If the set begins with an uparrow (^) then the set is negated (the
+element matches any character
+.I not
+in the set).  Any pair of characters separated with a dash (-)
+represents the range of characters from the first to the second,
+inclusive.  A single alphabetic character or underscore is matched by
+the following set.
+.nf
+
+    [a-zA-Z_]
+
+.fi
+Similarly, the following matches  any single non-digit character.
+.nf
+
+    [^0-9]
+
+.fi
+.TP
+.B .
+A dot matches any character.  Note that the only time this fails is at
+the end of file, where there is no character to match.
+.TP
+.BR ( \ pattern\  )
+Parentheses are used for grouping (modifying the precendence of the
+operators described below).
+.TP
+.BR { \ action\  }
+Curly braces surround actions.  The action is arbitray C source code
+to be executed at the end of matching.  Any braces within the action
+must be properly nested.  Any input text that was matched before the
+action and delimited by angle brackets (see below) is made available
+within the action as the contents of the character array
+.IR yytext .
+The length of (number of characters in)
+.I yytext
+is available in the variable
+.IR yyleng .
+(These variable names are historical; see
+.IR lex (1).)
+.TP
+.B <
+An opening angle bracket always matches (consuming no input) and
+causes the parser to begin accumulating matched text.  This text will
+be made available to actions in the variable
+.IR yytext .
+.TP
+.B >
+A closing angle bracket always matches (consuming no input) and causes
+the parser to stop accumulating text for
+.IR yytext .
+.PP
+The above
+.IR element s
+can be made optional and/or repeatable with the following suffixes:
+.TP
+.RB element\  ?
+The element is optional.  If present on the input, it is consumed and
+the match succeeds.  If not present on the input, no text is consumed
+and the match succeeds anyway.
+.TP
+.RB element\  +
+The element is repeatable.  If present on the input, one or more
+occurrences of
+.I element
+are consumed and the match succeeds.  If no occurrences of
+.I element
+are present on the input, the match fails.
+.TP
+.RB element\  *
+The element is optional and repeatable.  If present on the input, one or more
+occurrences of
+.I element
+are consumed and the match succeeds.  If no occurrences of
+.I element
+are present on the input, the match succeeds anyway.
+.PP
+The above elements and suffixes can be converted into predicates (that
+match arbitray input text and subsequently succeed or fail
+.I without
+consuming that input) with the following prefixes:
+.TP
+.BR & \ element
+The predicate succeeds only if
+.I element
+can be matched.  Input text scanned while matching
+.I element
+is not consumed from the input and remains available for subsequent
+matching.
+.TP
+.BR ! \ element
+The predicate succeeds only if
+.I element
+cannot be matched.  Input text scanned while matching
+.I element
+is not consumed from the input and remains available for subsequent
+matching.  A popular idiom is
+.nf
+
+    !.
+
+.fi
+which matches the end of file, after the last character of the input
+has already been consumed.
+.PP
+A special form of the '&' predicate is provided:
+.TP
+.BR & {\ expression\ }
+In this predicate the simple C
+.I expression
+.RB ( not
+statement) is evaluated immediately when the parser reaches the
+predicate.  If the
+.I expression
+yields non-zero (true) the 'match' succeeds and the parser continues
+with the next element in the pattern.  If the
+.I expression
+yields zero (false) the 'match' fails and the parser backs up to look
+for an alternative parse of the input.
+.PP
+Several elements (with or without prefixes and suffixes) can be
+combined into a
+.I sequence
+by writing them one after the other.  The entire sequence matches only
+if each individual element within it matches, from left to right.
+.PP
+Sequences can be separated into disjoint alternatives by the
+alternation operator '/'.
+.TP
+.RB sequence-1\  / \ sequence-2\  / \ ...\  / \ sequence-N
+Each sequence is tried in turn until one of them matches, at which
+time matching for the overall pattern succeeds.  If none of the
+sequences matches then the match of the overall pattern fails.
+.PP
+Finally, the pound sign (#) introduces a comment (discarded) that
+continues until the end of the line.
+.PP
+To summarise the above, the parser tries to match the input text
+against a pattern containing literals, names (representing other
+rules), and various operators (written as prefixes, suffixes,
+juxtaposition for sequencing and and infix alternation operator) that
+modify how the elements within the pattern are matched.  Matches are
+made from left to right, 'descending' into named sub-rules as they are
+encountered.  If the matching process fails, the parser 'back tracks'
+('rewinding' the input appropriately in the process) to find the
+nearest alternative 'path' through the grammar.  In other words the
+parser performs a depth-first, left-to-right search for the first
+successfully-matching path through the rules.  If found, the actions
+along the successful path are executed (in the order they were
+encountered).
+.PP
+Note that predicates are evaluated
+.I immediately
+during the search for a successful match, since they contribute to the
+success or failure of the search.  Actions, however, are evaluated
+only after a successful match has been found.
+.SH PEG GRAMMAR FOR PEG GRAMMARS
+The grammar for
+.I peg
+grammars is shown below.  This will both illustrate and formalise
+the above description.
+.nf
+
+    Grammar         <- Spacing Definition+ EndOfFile
+    
+    Definition      <- Identifier LEFTARROW Expression
+    Expression      <- Sequence ( SLASH Sequence )*
+    Sequence        <- Prefix*
+    Prefix          <- AND Action
+                     / ( AND | NOT )? Suffix
+    Suffix          <- Primary ( QUERY / STAR / PLUS )?
+    Primary         <- Identifier !LEFTARROW
+                     / OPEN Expression CLOSE
+                     / Literal
+                     / Class
+                     / DOT
+                     / Action
+                     / BEGIN
+                     / END
+    
+    Identifier      <- < IdentStart IdentCont* > Spacing
+    IdentStart      <- [a-zA-Z_]
+    IdentCont       <- IdentStart / [0-9]
+    Literal         <- ['] < ( !['] Char  )* > ['] Spacing
+                     / ["] < ( !["] Char  )* > ["] Spacing
+    Class           <- '[' < ( !']' Range )* > ']' Spacing
+    Range           <- Char '-' Char / Char
+    Char            <- '\\\\' [abefnrtv'"\\[\\]\\\\]
+                     / '\\\\' [0-3][0-7][0-7]
+                     / '\\\\' [0-7][0-7]?
+                     / '\\\\' '-'
+                     / !'\\\\' .
+    LEFTARROW       <- '<-' Spacing
+    SLASH           <- '/' Spacing
+    AND             <- '&' Spacing
+    NOT             <- '!' Spacing
+    QUERY           <- '?' Spacing
+    STAR            <- '*' Spacing
+    PLUS            <- '+' Spacing
+    OPEN            <- '(' Spacing
+    CLOSE           <- ')' Spacing
+    DOT             <- '.' Spacing
+    Spacing         <- ( Space / Comment )*
+    Comment         <- '#' ( !EndOfLine . )* EndOfLine
+    Space           <- ' ' / '\\t' / EndOfLine
+    EndOfLine       <- '\\r\\n' / '\\n' / '\\r'
+    EndOfFile       <- !.
+    Action          <- '{' < [^}]* > '}' Spacing
+    BEGIN           <- '<' Spacing
+    END             <- '>' Spacing
+
+.fi
+.SH LEG GRAMMARS
+.I leg
+is a variant of
+.I peg
+that adds some features of
+.IR lex (1)
+and
+.IR yacc (1).
+It differs from
+.I peg
+in the following ways.
+.TP
+.BI %{\  text... \ %}
+A declaration section can appear anywhere that a rule definition is
+expected.  The
+.I text
+between the delimiters '%{' and '%}' is copied verbatim to the
+generated C parser code
+.I before
+the code that implements the parser itself.
+.TP
+.IB name\  = \ pattern
+The 'assignment' operator replaces the left arrow operator '<-'.
+.TP
+.B rule-name
+Hyphens can appear as letters in the names of rules.  Each hyphen is
+converted into an underscore in the generated C source code.  A single
+single hyphen '-' is a legal rule name.
+.nf
+
+    -       = [ \\t\\n\\r]*
+    number  = [0-9]+                 -
+    name    = [a-zA-Z_][a-zA_Z_0-9]* -
+    l-paren = '('                    -
+    r-paren = ')'                    -
+    
+.fi
+This example shows how ignored whitespace can be obvious when reading
+the grammar and yet unobtrusive when placed liberally at the end of
+every rule associated with a lexical element.
+.TP
+.IB seq-1\  | \ seq-2
+The alternation operator is vertical bar '|' rather than forward
+slash '/'.  The
+.I peg
+rule
+.nf
+
+    name <- sequence-1
+          / sequence-2
+          / sequence-3
+
+.fi
+is therefore written
+.nf
+
+    name = sequence-1
+         | sequence-2
+         | sequence-3
+         ;
+
+.fi
+in
+.I leg
+(with the final semicolon being optional, as described next).
+.TP
+.IB exp \ ~ \ {\ action\ }
+A postfix operator
+.BI ~ {\ action\ }
+can be placed after any expression and will behave like a normal
+action (arbitrary C code) except that it is invoked only when
+.I exp
+fails.  It binds less tightly than any other operator except alternation and sequencing, and
+is intended to make error handling and recovery code easier to write.
+Note that
+.I yytext
+and
+.I yyleng
+are not available inside these actions, but the pointer variable
+.I yy
+is available to give the code access to any user-defined members
+of the parser state (see "CUSTOMISING THE PARSER" below).
+Note also that
+.I exp
+is always a single expression; to invoke an error action for any
+failure within a sequence, parentheses must be used to group the
+sequence into a single expression.
+.nf
+
+    rule = e1 e2 e3 ~{ error("e[12] ok; e3 has failed"); }
+         | ...
+
+    rule = (e1 e2 e3) ~{ error("one of e[123] has failed"); }
+         | ...
+.fi
+.TP
+.IB pattern\  ;
+A semicolon punctuator can optionally terminate a
+.IR pattern .
+.TP
+.BI %% \ text...
+A double percent '%%' terminates the rules (and declarations) section of
+the grammar.  All
+.I text
+following '%%' is copied verbatim to the generated C parser code
+.I after
+the parser implementation code.
+.TP
+.BI $$\ = \ value
+A sub-rule can return a semantic
+.I value
+from an action by assigning it to the pseudo-variable '$$'.  All
+semantic values must have the same type (which defaults to 'int').
+This type can be changed by defining YYSTYPE in a declaration section.
+.TP
+.IB identifier : name
+The semantic value returned (by assigning to '$$') from the sub-rule
+.I name
+is associated with the
+.I identifier
+and can be referred to in subsequent actions.
+.PP
+The desk calclator example below illustrates the use of '$$' and ':'.
+.SH LEG EXAMPLE: A DESK CALCULATOR
+The extensions in
+.I leg
+described above allow useful parsers and evaluators (including
+declarations, grammar rules, and supporting C functions such
+as 'main') to be kept within a single source file.  To illustrate this
+we show a simple desk calculator supporting the four common arithmetic
+operators and named variables.  The intermediate results of arithmetic
+evaluation will be accumulated on an implicit stack by returning them
+as semantic values from sub-rules.
+.nf
+
+    %{
+    #include <stdio.h>     /* printf() */
+    #include <stdlib.h>    /* atoi() */
+    int vars[26];
+    %}
+    
+    Stmt    = - e:Expr EOL                  { printf("%d\\n", e); }
+            | ( !EOL . )* EOL               { printf("error\\n"); }
+    
+    Expr    = i:ID ASSIGN s:Sum             { $$ = vars[i] = s; }
+            | s:Sum                         { $$ = s; }
+    
+    Sum     = l:Product
+                    ( PLUS  r:Product       { l += r; }
+                    | MINUS r:Product       { l -= r; }
+                    )*                      { $$ = l; }
+    
+    Product = l:Value
+                    ( TIMES  r:Value        { l *= r; }
+                    | DIVIDE r:Value        { l /= r; }
+                    )*                      { $$ = l; }
+    
+    Value   = i:NUMBER                      { $$ = atoi(yytext); }
+            | i:ID !ASSIGN                  { $$ = vars[i]; }
+            | OPEN i:Expr CLOSE             { $$ = i; }
+    
+    NUMBER  = < [0-9]+ >    -               { $$ = atoi(yytext); }
+    ID      = < [a-z]  >    -               { $$ = yytext[0] - 'a'; }
+    ASSIGN  = '='           -
+    PLUS    = '+'           -
+    MINUS   = '-'           -
+    TIMES   = '*'           -
+    DIVIDE  = '/'           -
+    OPEN    = '('           -
+    CLOSE   = ')'           -
+    
+    -       = [ \\t]*
+    EOL     = '\\n' | '\\r\\n' | '\\r' | ';'
+    
+    %%
+    
+    int main()
+    {
+      while (yyparse())
+        ;
+      return 0;
+    }
+
+.fi
+.SH LEG GRAMMAR FOR LEG GRAMMARS
+The grammar for
+.I leg
+grammars is shown below.  This will both illustrate and formalise the
+above description.
+.nf
+
+    grammar =       -
+                    ( declaration | definition )+
+                    trailer? end-of-file
+    
+    declaration =   '%{' < ( !'%}' . )* > RPERCENT
+    
+    trailer =       '%%' < .* >
+    
+    definition =    identifier EQUAL expression SEMICOLON?
+    
+    expression =    sequence ( BAR sequence )*
+    
+    sequence =      error+
+    
+    error =         prefix ( TILDE action )?
+
+    prefix =        AND action
+    |               ( AND | NOT )? suffix
+    
+    suffix =        primary ( QUERY | STAR | PLUS )?
+    
+    primary =       identifier COLON identifier !EQUAL
+    |               identifier !EQUAL
+    |               OPEN expression CLOSE
+    |               literal
+    |               class
+    |               DOT
+    |               action
+    |               BEGIN
+    |               END
+    
+    identifier =    < [-a-zA-Z_][-a-zA-Z_0-9]* > -
+    
+    literal =       ['] < ( !['] char )* > ['] -
+    |               ["] < ( !["] char )* > ["] -
+    
+    class =         '[' < ( !']' range )* > ']' -
+    
+    range =         char '-' char | char
+    
+    char =          '\\\\' [abefnrtv'"\\[\\]\\\\]
+    |               '\\\\' [0-3][0-7][0-7]
+    |               '\\\\' [0-7][0-7]?
+    |               !'\\\\' .
+    
+    action =        '{' < braces* > '}' -
+    
+    braces =        '{' braces* '}'
+    |               !'}' .
+    
+    EQUAL =         '=' -
+    COLON =         ':' -
+    SEMICOLON =     ';' -
+    BAR =           '|' -
+    AND =           '&' -
+    NOT =           '!' -
+    QUERY =         '?' -
+    STAR =          '*' -
+    PLUS =          '+' -
+    OPEN =          '(' -
+    CLOSE =         ')' -
+    DOT =           '.' -
+    BEGIN =         '<' -
+    END =           '>' -
+    TILDE =         '~' -
+    RPERCENT =      '%}' -
+    
+    - =             ( space | comment )*
+    space =         ' ' | '\\t' | end-of-line
+    comment =       '#' ( !end-of-line . )* end-of-line
+    end-of-line =   '\\r\\n' | '\\n' | '\\r'
+    end-of-file =   !.
+
+.fi
+.SH CUSTOMISING THE PARSER
+The following symbols can be redefined in declaration sections to
+modify the generated parser code.
+.TP
+.B YYSTYPE
+The semantic value type.  The pseudo-variable '$$' and the
+identifiers 'bound' to rule results with the colon operator ':' should
+all be considered as being declared to have this type.  The default
+value is 'int'.
+.TP
+.B YYPARSE
+The name of the main entry point to the parser.  The default value
+is 'yyparse'.
+.TP
+.B YYPARSEFROM
+The name of an alternative entry point to the parser.  This function
+expects one argument: the function corresponding to the rule from
+which the search for a match should begin.  The default
+is 'yyparsefrom'.  Note that yyparse() is defined as
+.nf
+
+    int yyparse() { return yyparsefrom(yy_foo); }
+
+.fi
+where 'foo' is the name of the first rule in the grammar.
+.TP
+.BI YY_INPUT( buf , \ result , \ max_size )
+This macro is invoked by the parser to obtain more input text.
+.I buf
+points to an area of memory that can hold at most
+.I max_size
+characters.  The macro should copy input text to
+.I buf
+and then assign the integer variable
+.I result
+to indicate the number of characters copied.  If no more input is available,
+the macro should assign 0 to
+.IR result .
+By default, the YY_INPUT macro is defined as follows.
+.nf
+
+    #define YY_INPUT(buf, result, max_size)        \\
+    {                                              \\
+      int yyc= getchar();                          \\
+      result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \\
+    }
+
+.fi
+Note that if YY_CTX_LOCAL is defined (see below) then an additional
+first argument, containing the parser context, is passed to YY_INPUT.
+.TP
+.B YY_DEBUG
+If this symbols is defined then additional code will be included in
+the parser that prints vast quantities of arcane information to the
+standard error while the parser is running.
+.TP
+.B YY_BEGIN
+This macro is invoked to mark the start of input text that will be
+made available in actions as 'yytext'.  This corresponds to
+occurrences of '<' in the grammar.  These are converted into
+predicates that are expected to succeed.  The default definition
+.nf
+
+    #define YY_BEGIN (yybegin= yypos, 1)
+
+.fi
+therefore saves the current input position and returns 1 ('true') as
+the result of the predicate.
+.TP
+.B YY_END
+This macros corresponds to '>' in the grammar.  Again, it is a
+predicate so the default definition saves the input position
+before 'succeeding'.
+.nf
+
+    #define YY_END (yyend= yypos, 1)
+
+.fi
+.TP
+.BI YY_PARSE( T )
+This macro declares the parser entry points (yyparse and yyparsefrom)
+to be of type
+.IR T .
+The default definition
+.nf
+
+    #define YY_PARSE(T) T
+
+.fi
+leaves yyparse() and yyparsefrom() with global visibility.  If they
+should not be externally visible in other source files, this macro can
+be redefined to declare them 'static'.
+.nf
+
+    #define YY_PARSE(T) static T
+
+.fi
+.TP
+.B YY_CTX_LOCAL
+If this symbol is defined during compilation of a generated parser
+then global parser state will be kept in a structure of
+type 'yycontext' which can be declared as a local variable.  This
+allows multiple instances of parsers to coexist and to be thread-safe.
+The parsing function
+.IR yyparse ()
+will be declared to expect a first argument of type 'yycontext *', an
+instance of the structure holding the global state for the parser.
+This instance must be allocated and initialised to zero by the client.
+A trivial but complete example is as follows.
+.nf
+
+    #include <stdio.h>
+
+    #define YY_CTX_LOCAL
+
+    #include "the-generated-parser.peg.c"
+
+    int main()
+    {
+      yycontext ctx;
+      memset(&ctx, 0, sizeof(yycontext));
+      while (yyparse(&ctx));
+      return 0;
+    }
+
+.fi
+Note that if this symbol is undefined then the compiled parser will
+statically allocate its global state and will be neither reentrant nor
+thread-safe.
+Note also that the parser yycontext structure is initialised automatically
+the first time
+.IR yyparse ()
+is called; this structure
+.B must
+therefore be properly initliased to zero before the first call to
+.IR yyparse ().
+.TP
+.B YY_CTX_MEMBERS
+If YY_CTX_LOCAL is defined (see above) then the macro YY_CTX_MEMBERS
+can be defined to expand to any additional member field declarations
+that the client would like included in the declaration of
+the 'yycontext' structure type.  These additional members are
+otherwise ignored by the generated parser.  The instance
+of 'yycontext' associated with the currently-active parser is
+available within actions as the pointer variable
+.IR yy .
+.TP
+.B YY_BUFFER_SIZE
+The initial size of the text buffer, in bytes.  The default is 1024
+and the buffer size is doubled whenever required to meet demand during
+parsing.  An application that typically parses much longer strings
+could increase this to avoid unnecessary buffer reallocation.
+.TP
+.B YY_STACK_SIZE
+The initial size of the variable and action stacks.  The default is
+128, which is doubled whenever required to meet demand during parsing.
+Applications that have deep call stacks with many local variables, or
+that perform many actions after a single successful match, could increase
+this to avoid unnecessary buffer reallocation.
+.TP
+.BI YY_MALLOC( YY , \ SIZE )
+The memory allocator for all parser-related storage.  The parameters
+are the current yycontext structure and the number of bytes to
+allocate.  The default definition is:
+.RI malloc( SIZE )
+.TP
+.BI YY_REALLOC( YY , \ PTR , \ SIZE )
+The memory reallocator for dynamically-grown storage (such as text
+buffers and variable stacks).  The parameters are the current
+yycontext structure, the previously-allocated storage, and the number
+of bytes to which that storage should be grown.  The default definition is:
+.RI realloc( PTR , \ SIZE )
+.TP
+.BI YY_FREE( YY , \ PTR )
+The memory deallocator.  The parameters are the current yycontext
+structure and the storage to deallocate.  The default definition is:
+.RI free( PTR )
+.TP
+.B YYRELEASE
+The name of the function that releases all resources held by a
+yycontext structure.  The default value is 'yyrelease'.
+.PP
+The following variables can be reffered to within actions.
+.TP
+.B char *yybuf
+This variable points to the parser's input buffer used to store input
+text that has not yet been matched.
+.TP
+.B int yypos
+This is the offset (in yybuf) of the next character to be matched and
+consumed.
+.TP
+.B char *yytext
+The most recent matched text delimited by '<' and '>' is stored in this variable.
+.TP
+.B int yyleng
+This variable indicates the number of characters in 'yytext'.
+.TP
+.B yycontext *yy
+This variable points to the instance of 'yycontext' associated with
+the currently-active parser.
+.PP
+Programs that wish to release all the resources associated with a
+parser can use the following function.
+.TP
+.BI yyrelease(yycontext * yy )
+Returns all parser-allocated storage associated with
+.I yy
+to the system.  The storage will be reallocated on the next call to
+.IR yyparse ().
+.PP
+Note that the storage for the yycontext structure itself is never
+allocated or reclaimed implicitly.  The application must allocate
+these structures in automatic storage, or use
+.IR calloc ()
+and
+.IR free ()
+to manage them explicitly.  The example in the following section
+demonstrates one approach to resource management.
+.SH LEG EXAMPLE: EXTENDING THE PARSER'S CONTEXT
+The
+.I yy
+variable passed to actions contains the state of the parser plus any
+additional fields defined by YY_CTX_MEMBERS.  Theses fields can be
+used to store application-specific information that is global to a
+particular call of
+.IR yyparse ().
+A trivial but complete
+.I leg
+example follows in which the yycontext
+structure is extended with a
+.I count
+of the number of newline characters
+seen in the input so far (the grammar otherwise consumes and ignores
+the entire input).  The caller of
+.IR yyparse ()
+uses
+.I count
+to print the number of lines of input that were read.
+
+.nf
+
+    %{
+    #define YY_CTX_LOCAL 1
+    #define YY_CTX_MEMBERS \\
+      int count;
+    %}
+
+    Char    = ('\\n' | '\\r\\n' | '\\r')        { yy->count++ }
+            | .
+
+    %%
+
+    #include <stdio.h>
+    #include <string.h>
+
+    int main()
+    {
+        /* create a local parser context in automatic storage */
+        yycontext yy;
+        /* the context *must* be initialised to zero before first use*/
+        memset(&yy, 0, sizeof(yy));
+
+        while (yyparse(&yy))
+            ;
+        printf("%d newlines\\n", yy.count);
+
+        /* release all resources associated with the context */
+        yyrelease(&yy);
+
+        return 0;
+    }
+
+.fi
+.SH DIAGNOSTICS
+.I peg
+and
+.I leg
+warn about the following conditions while converting a grammar into a parser.
+.TP
+.B syntax error
+The input grammar was malformed in some way.  The error message will
+include the text about to be matched (often backed up a huge amount
+from the actual location of the error) and the line number of the most
+recently considered character (which is often the real location of the
+problem).
+.TP
+.B rule 'foo' used but not defined
+The grammar referred to a rule named 'foo' but no definition for it
+was given.  Attempting to use the generated parser will likely result
+in errors from the linker due to undefined symbols associated with the
+missing rule.
+.TP
+.B rule 'foo' defined but not used
+The grammar defined a rule named 'foo' and then ignored it.  The code
+associated with the rule is included in the generated parser which
+will in all other respects be healthy.
+.TP
+.B possible infinite left recursion in rule 'foo'
+There exists at least one path through the grammar that leads from the
+rule 'foo' back to (a recursive invocation of) the same rule without
+consuming any input.
+.PP
+Left recursion, especially that found in standards documents, is
+often 'direct' and implies trivial repetition.
+.nf
+
+    # (6.7.6)
+    direct-abstract-declarator =
+        LPAREN abstract-declarator RPAREN
+    |   direct-abstract-declarator? LBRACKET assign-expr? RBRACKET
+    |   direct-abstract-declarator? LBRACKET STAR RBRACKET
+    |   direct-abstract-declarator? LPAREN param-type-list? RPAREN
+
+.fi
+The recursion can easily be eliminated by converting the parts of the
+pattern following the recursion into a repeatable suffix.
+.nf
+    
+    # (6.7.6)
+    direct-abstract-declarator =
+        direct-abstract-declarator-head?
+        direct-abstract-declarator-tail*
+    
+    direct-abstract-declarator-head =
+        LPAREN abstract-declarator RPAREN
+    
+    direct-abstract-declarator-tail =
+        LBRACKET assign-expr? RBRACKET
+    |   LBRACKET STAR RBRACKET
+    |   LPAREN param-type-list? RPAREN
+
+.fi
+.SH BUGS
+You have to type 'man peg' to read the manual page for
+.IR leg (1).
+.PP
+The 'yy' and 'YY' prefixes cannot be changed.
+.PP
+Left recursion is detected in the input grammar but is not handled
+correctly in the generated parser.
+.PP
+Diagnostics for errors in the input grammar are obscure and not
+particularly helpful.
+.PP
+The operators
+.BR ! \ \c
+and
+.B ~
+should really be named the other way around.
+.PP
+Several commonly-used
+.IR lex (1)
+features (yywrap(), yyin, etc.) are completely absent.
+.PP
+The generated parser foes not contain '#line' directives to direct C
+compiler errors back to the grammar description when appropriate.
+.SH SEE ALSO
+D. Val Schorre,
+.I META II, a syntax-oriented compiler writing language,
+19th ACM National Conference, 1964, pp.\ 41.301--41.311.  Describes a
+self-implementing parser generator for analytic grammars with no
+backtracking.
+.PP
+Alexander Birman,
+.I The TMG Recognition Schema,
+Ph.D. dissertation, Princeton, 1970.  A mathematical treatment of the
+power and complexity of recursive-descent parsing with backtracking.
+.PP
+Bryan Ford,
+.I Parsing Expression Grammars: A Recognition-Based Syntactic Foundation,
+ACM SIGPLAN Symposium on Principles of Programming Languages, 2004.
+Defines PEGs and analyses them in relation to context-free and regular
+grammars.  Introduces the syntax adopted in
+.IR peg .
+.PP
+The standard Unix utilies
+.IR lex (1)
+and
+.IR yacc (1)
+which influenced the syntax and features of
+.IR leg .
+.PP
+The source code for
+.I peg
+and
+.I leg
+whose grammar parsers are written using themselves.
+.PP
+The latest version of this software and documentation:
+.nf
+
+    http://piumarta.com/software/peg
+
+.fi
+.SH AUTHOR
+.IR peg ,
+.I leg
+and this manual page were written by Ian Piumarta (first-name at
+last-name dot com) while investigating the viablility of regular- and
+parsing-expression grammars for efficiently extracting type and
+signature information from C header files.
+.PP
+Please send bug reports and suggestions for improvements to the author
+at the above address.
--- /dev/null
+++ b/src/peg.c
@@ -1,0 +1,173 @@
+/* Copyright (c) 2007 by Ian Piumarta
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the 'Software'),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, provided that the above copyright notice(s) and this
+ * permission notice appear in all copies of the Software.  Acknowledgement
+ * of the use of this Software in supporting documentation would be
+ * appreciated but is not required.
+ * 
+ * THE SOFTWARE IS PROVIDED 'AS IS'.  USE ENTIRELY AT YOUR OWN RISK.
+ * 
+ * Last edited: 2012-05-16 08:55:38 by piumarta on emilia
+ */
+
+#include "tree.h"
+#include "version.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <libgen.h>
+#include <assert.h>
+
+FILE *input= 0;
+
+int   verboseFlag= 0;
+
+static int   lineNumber= 0;
+static char *fileName= 0;
+
+void yyerror(char *message);
+
+#define YY_INPUT(buf, result, max)			\
+{							\
+  int c= getc(input);					\
+  if ('\n' == c || '\r' == c) ++lineNumber;		\
+  result= (EOF == c) ? 0 : (*(buf)= c, 1);		\
+}
+
+#define YY_LOCAL(T)	static T
+#define YY_RULE(T)	static T
+
+#include "peg.peg-c"
+
+void yyerror(char *message)
+{
+  fprintf(stderr, "%s:%d: %s", fileName, lineNumber, message);
+  if (yyctx->__text[0]) fprintf(stderr, " near token '%s'", yyctx->__text);
+  if (yyctx->__pos < yyctx->__limit || !feof(input))
+    {
+      yyctx->__buf[yyctx->__limit]= '\0';
+      fprintf(stderr, " before text \"");
+      while (yyctx->__pos < yyctx->__limit)
+	{
+	  if ('\n' == yyctx->__buf[yyctx->__pos] || '\r' == yyctx->__buf[yyctx->__pos]) break;
+	  fputc(yyctx->__buf[yyctx->__pos++], stderr);
+	}
+      if (yyctx->__pos == yyctx->__limit)
+	{
+	  int c;
+	  while (EOF != (c= fgetc(input)) && '\n' != c && '\r' != c)
+	    fputc(c, stderr);
+	}
+      fputc('\"', stderr);
+    }
+  fprintf(stderr, "\n");
+  exit(1);
+}
+
+static void version(char *name)
+{
+  printf("%s version %d.%d.%d\n", name, PEG_MAJOR, PEG_MINOR, PEG_LEVEL);
+}
+
+static void usage(char *name)
+{
+  version(name);
+  fprintf(stderr, "usage: %s [<option>...] [<file>...]\n", name);
+  fprintf(stderr, "where <option> can be\n");
+  fprintf(stderr, "  -h          print this help information\n");
+  fprintf(stderr, "  -o <ofile>  write output to <ofile>\n");
+  fprintf(stderr, "  -v          be verbose\n");
+  fprintf(stderr, "  -V          print version number and exit\n");
+  fprintf(stderr, "if no <file> is given, input is read from stdin\n");
+  fprintf(stderr, "if no <ofile> is given, output is written to stdout\n");
+  exit(1);
+}
+
+int main(int argc, char **argv)
+{
+  Node *n;
+  int   c;
+
+  output= stdout;
+  input= stdin;
+  lineNumber= 1;
+  fileName= "<stdin>";
+
+  while (-1 != (c= getopt(argc, argv, "Vho:v")))
+    {
+      switch (c)
+	{
+	case 'V':
+	  version(basename(argv[0]));
+	  exit(0);
+
+	case 'h':
+	  usage(basename(argv[0]));
+	  break;
+
+	case 'o':
+	  if (!(output= fopen(optarg, "w")))
+	    {
+	      perror(optarg);
+	      exit(1);
+	    }
+	  break;
+
+	case 'v':
+	  verboseFlag= 1;
+	  break;
+
+	default:
+	  fprintf(stderr, "for usage try: %s -h\n", argv[0]);
+	  exit(1);
+	}
+    }
+  argc -= optind;
+  argv += optind;
+
+  if (argc)
+    {
+      for (;  argc;  --argc, ++argv)
+	{
+	  if (!strcmp(*argv, "-"))
+	    {
+	      input= stdin;
+	      fileName= "<stdin>";
+	    }
+	  else
+	    {
+	      if (!(input= fopen(*argv, "r")))
+		{
+		  perror(*argv);
+		  exit(1);
+		}
+	      fileName= *argv;
+	    }
+	  lineNumber= 1;
+	  if (!yyparse())
+	    yyerror("syntax error");
+	  if (input != stdin)
+	    fclose(input);
+	}
+    }
+  else
+    if (!yyparse())
+      yyerror("syntax error");
+
+  if (verboseFlag)
+    for (n= rules;  n;  n= n->any.next)
+      Rule_print(n);
+
+  Rule_compile_c_header();
+  if (rules) Rule_compile_c(rules);
+
+  return 0;
+}
--- /dev/null
+++ b/src/peg.peg
@@ -1,0 +1,77 @@
+# PE Grammar for PE Grammars
+# 
+# Adapted from [1] by Ian Piumarta <first-name at last-name point com>.
+# 
+# Local modifications (marked '#ikp') to support:
+#     C text in '{ ... }' copied verbatim to output as 'semantic action'
+#     input consumed between '<' and '>' is 'char yytext[]' in semantic actions
+# 
+# Best viewed using 140 columns monospaced with tabs every 8.
+# 
+# [1] Bryan Ford.  "Parsing Expression Grammars: A Recognition-Based Syntactic
+#     Foundation."  Symposium on Principles of Programming Languages,
+#     January 14--16, 2004, Venice, Italy.
+# 
+# Last edited: 2007-05-15 10:32:44 by piumarta on emilia
+
+# Hierarchical syntax
+
+Grammar		<- Spacing Definition+ EndOfFile
+
+Definition	<- Identifier 			{ if (push(beginRule(findRule(yytext)))->rule.expression) fprintf(stderr, "rule '%s' redefined\n", yytext); }
+		     LEFTARROW Expression	{ Node *e= pop();  Rule_setExpression(pop(), e); } &{ YYACCEPT }
+Expression	<- Sequence (SLASH Sequence	{ Node *f= pop();  push(Alternate_append(pop(), f)); }
+			    )*
+Sequence	<- Prefix (Prefix		{ Node *f= pop();  push(Sequence_append(pop(), f)); }	#ikp expanded from 'Seq <- Prefix*'
+			  )*
+		 / 				{ push(makePredicate("1")); }				#ikp added
+Prefix		<- AND Action			{ push(makePredicate(yytext)); }	#ikp added
+		 / AND Suffix			{ push(makePeekFor(pop())); }		#ikp expanded from 'Prefix <- (AND/NOT)? Suffix'
+		 / NOT Suffix			{ push(makePeekNot(pop())); }
+		 /     Suffix
+Suffix		<- Primary (QUESTION		{ push(makeQuery(pop())); }
+			     / STAR		{ push(makeStar (pop())); }
+			     / PLUS		{ push(makePlus (pop())); }
+			   )?
+Primary		<- Identifier !LEFTARROW	{ push(makeName(findRule(yytext))); }
+		 / OPEN Expression CLOSE
+		 / Literal			{ push(makeString(yytext)); }
+		 / Class			{ push(makeClass(yytext)); }
+		 / DOT				{ push(makeDot()); }
+		 / Action			{ push(makeAction(yytext)); }		#ikp added
+		 / BEGIN			{ push(makePredicate("YY_BEGIN")); }	#ikp added
+		 / END				{ push(makePredicate("YY_END")); }	#ikp added
+
+# Lexical syntax
+
+Identifier	<- < IdentStart IdentCont* > Spacing		#ikp inserted < ... >
+IdentStart	<- [a-zA-Z_]
+IdentCont	<- IdentStart / [0-9]
+Literal		<- ['] < (!['] Char )* > ['] Spacing		#ikp inserted < ... >
+		 / ["] < (!["] Char )* > ["] Spacing		#ikp inserted < ... >
+Class		<- '[' < (!']' Range)* > ']' Spacing		#ikp inserted < ... >
+Range		<- Char '-' Char / Char
+Char		<- '\\' [abefnrtv'"\[\]\\]			#ikp added missing ANSI escapes: abefv
+		 / '\\' [0-3][0-7][0-7]
+		 / '\\' [0-7][0-7]?
+		 / '\\' '-'					#ikp added
+		 / !'\\' .
+LEFTARROW	<- '<-' Spacing
+SLASH		<- '/' Spacing
+AND		<- '&' Spacing
+NOT		<- '!' Spacing
+QUESTION	<- '?' Spacing
+STAR		<- '*' Spacing
+PLUS		<- '+' Spacing
+OPEN		<- '(' Spacing
+CLOSE		<- ')' Spacing
+DOT		<- '.' Spacing
+Spacing		<- (Space / Comment)*
+Comment		<- '#' (!EndOfLine .)* EndOfLine
+Space		<- ' ' / '\t' / EndOfLine
+EndOfLine	<- '\r\n' / '\n' / '\r'
+EndOfFile	<- !.
+
+Action		<- '{' < [^}]* > '}' Spacing		#ikp added
+BEGIN		<- '<' Spacing				#ikp added
+END		<- '>' Spacing				#ikp added
--- /dev/null
+++ b/src/peg.peg-c
@@ -1,0 +1,1002 @@
+/* A recursive-descent parser generated by peg 0.1.11 */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define YYRULECOUNT 32
+#ifndef YY_MALLOC
+#define YY_MALLOC(C, N)		malloc(N)
+#endif
+#ifndef YY_REALLOC
+#define YY_REALLOC(C, P, N)	realloc(P, N)
+#endif
+#ifndef YY_FREE
+#define YY_FREE free
+#endif
+#ifndef YY_LOCAL
+#define YY_LOCAL(T)	static T
+#endif
+#ifndef YY_ACTION
+#define YY_ACTION(T)	static T
+#endif
+#ifndef YY_RULE
+#define YY_RULE(T)	static T
+#endif
+#ifndef YY_PARSE
+#define YY_PARSE(T)	T
+#endif
+#ifndef YYPARSE
+#define YYPARSE		yyparse
+#endif
+#ifndef YYPARSEFROM
+#define YYPARSEFROM	yyparsefrom
+#endif
+#ifndef YYRELEASE
+#define YYRELEASE	yyrelease
+#endif
+#ifndef YY_BEGIN
+#define YY_BEGIN	( yy->__begin= yy->__pos, 1)
+#endif
+#ifndef YY_END
+#define YY_END		( yy->__end= yy->__pos, 1)
+#endif
+#ifdef YY_DEBUG
+# define yyprintf(args)	fprintf args
+#else
+# define yyprintf(args)
+#endif
+#ifndef YYSTYPE
+#define YYSTYPE	int
+#endif
+#ifndef YY_STACK_SIZE
+#define YY_STACK_SIZE 128
+#endif
+
+#ifndef YY_BUFFER_SIZE
+#define YY_BUFFER_SIZE 1024
+#endif
+
+#ifndef YY_PART
+
+typedef struct _yycontext yycontext;
+typedef void (*yyaction)(yycontext *yy, char *yytext, int yyleng);
+typedef struct _yythunk { int begin, end;  yyaction  action;  struct _yythunk *next; } yythunk;
+
+struct _yycontext {
+  char     *__buf;
+  int       __buflen;
+  int       __pos;
+  int       __limit;
+  char     *__text;
+  int       __textlen;
+  int       __begin;
+  int       __end;
+  int       __textmax;
+  yythunk  *__thunks;
+  int       __thunkslen;
+  int       __thunkpos;
+  YYSTYPE   __;
+  YYSTYPE  *__val;
+  YYSTYPE  *__vals;
+  int       __valslen;
+#ifdef YY_CTX_MEMBERS
+  YY_CTX_MEMBERS
+#endif
+};
+
+#ifdef YY_CTX_LOCAL
+#define YY_CTX_PARAM_	yycontext *yyctx,
+#define YY_CTX_PARAM	yycontext *yyctx
+#define YY_CTX_ARG_	yyctx,
+#define YY_CTX_ARG	yyctx
+#ifndef YY_INPUT
+#define YY_INPUT(yy, buf, result, max_size)		\
+  {							\
+    int yyc= getchar();					\
+    result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1);	\
+    yyprintf((stderr, "<%c>", yyc));			\
+  }
+#endif
+#else
+#define YY_CTX_PARAM_
+#define YY_CTX_PARAM
+#define YY_CTX_ARG_
+#define YY_CTX_ARG
+yycontext _yyctx= { 0, 0 };
+yycontext *yyctx= &_yyctx;
+#ifndef YY_INPUT
+#define YY_INPUT(buf, result, max_size)			\
+  {							\
+    int yyc= getchar();					\
+    result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1);	\
+    yyprintf((stderr, "<%c>", yyc));			\
+  }
+#endif
+#endif
+
+YY_LOCAL(int) yyrefill(yycontext *yy)
+{
+  int yyn;
+  while (yy->__buflen - yy->__pos < 512)
+    {
+      yy->__buflen *= 2;
+      yy->__buf= (char *)YY_REALLOC(yy, yy->__buf, yy->__buflen);
+    }
+#ifdef YY_CTX_LOCAL
+  YY_INPUT(yy, (yy->__buf + yy->__pos), yyn, (yy->__buflen - yy->__pos));
+#else
+  YY_INPUT((yy->__buf + yy->__pos), yyn, (yy->__buflen - yy->__pos));
+#endif
+  if (!yyn) return 0;
+  yy->__limit += yyn;
+  return 1;
+}
+
+YY_LOCAL(int) yymatchDot(yycontext *yy)
+{
+  if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0;
+  ++yy->__pos;
+  return 1;
+}
+
+YY_LOCAL(int) yymatchChar(yycontext *yy, int c)
+{
+  if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0;
+  if ((unsigned char)yy->__buf[yy->__pos] == c)
+    {
+      ++yy->__pos;
+      yyprintf((stderr, "  ok   yymatchChar(yy, %c) @ %s\n", c, yy->__buf+yy->__pos));
+      return 1;
+    }
+  yyprintf((stderr, "  fail yymatchChar(yy, %c) @ %s\n", c, yy->__buf+yy->__pos));
+  return 0;
+}
+
+YY_LOCAL(int) yymatchString(yycontext *yy, const char *s)
+{
+  int yysav= yy->__pos;
+  while (*s)
+    {
+      if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0;
+      if (yy->__buf[yy->__pos] != *s)
+        {
+          yy->__pos= yysav;
+          return 0;
+        }
+      ++s;
+      ++yy->__pos;
+    }
+  return 1;
+}
+
+YY_LOCAL(int) yymatchClass(yycontext *yy, unsigned char *bits)
+{
+  int c;
+  if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0;
+  c= (unsigned char)yy->__buf[yy->__pos];
+  if (bits[c >> 3] & (1 << (c & 7)))
+    {
+      ++yy->__pos;
+      yyprintf((stderr, "  ok   yymatchClass @ %s\n", yy->__buf+yy->__pos));
+      return 1;
+    }
+  yyprintf((stderr, "  fail yymatchClass @ %s\n", yy->__buf+yy->__pos));
+  return 0;
+}
+
+YY_LOCAL(void) yyDo(yycontext *yy, yyaction action, int begin, int end)
+{
+  while (yy->__thunkpos >= yy->__thunkslen)
+    {
+      yy->__thunkslen *= 2;
+      yy->__thunks= (yythunk *)YY_REALLOC(yy, yy->__thunks, sizeof(yythunk) * yy->__thunkslen);
+    }
+  yy->__thunks[yy->__thunkpos].begin=  begin;
+  yy->__thunks[yy->__thunkpos].end=    end;
+  yy->__thunks[yy->__thunkpos].action= action;
+  ++yy->__thunkpos;
+}
+
+YY_LOCAL(int) yyText(yycontext *yy, int begin, int end)
+{
+  int yyleng= end - begin;
+  if (yyleng <= 0)
+    yyleng= 0;
+  else
+    {
+      while (yy->__textlen < (yyleng + 1))
+	{
+	  yy->__textlen *= 2;
+	  yy->__text= (char *)YY_REALLOC(yy, yy->__text, yy->__textlen);
+	}
+      memcpy(yy->__text, yy->__buf + begin, yyleng);
+    }
+  yy->__text[yyleng]= '\0';
+  return yyleng;
+}
+
+YY_LOCAL(void) yyDone(yycontext *yy)
+{
+  int pos;
+  for (pos= 0;  pos < yy->__thunkpos;  ++pos)
+    {
+      yythunk *thunk= &yy->__thunks[pos];
+      int yyleng= thunk->end ? yyText(yy, thunk->begin, thunk->end) : thunk->begin;
+      yyprintf((stderr, "DO [%d] %p %s\n", pos, thunk->action, yy->__text));
+      thunk->action(yy, yy->__text, yyleng);
+    }
+  yy->__thunkpos= 0;
+}
+
+YY_LOCAL(void) yyCommit(yycontext *yy)
+{
+  if ((yy->__limit -= yy->__pos))
+    {
+      memmove(yy->__buf, yy->__buf + yy->__pos, yy->__limit);
+    }
+  yy->__begin -= yy->__pos;
+  yy->__end -= yy->__pos;
+  yy->__pos= yy->__thunkpos= 0;
+}
+
+YY_LOCAL(int) yyAccept(yycontext *yy, int tp0)
+{
+  if (tp0)
+    {
+      fprintf(stderr, "accept denied at %d\n", tp0);
+      return 0;
+    }
+  else
+    {
+      yyDone(yy);
+      yyCommit(yy);
+    }
+  return 1;
+}
+
+YY_LOCAL(void) yyPush(yycontext *yy, char *text, int count)
+{
+  yy->__val += count;
+  while (yy->__valslen <= yy->__val - yy->__vals)
+    {
+      long offset= yy->__val - yy->__vals;
+      yy->__valslen *= 2;
+      yy->__vals= (YYSTYPE *)YY_REALLOC(yy, yy->__vals, sizeof(YYSTYPE) * yy->__valslen);
+      yy->__val= yy->__vals + offset;
+    }
+}
+YY_LOCAL(void) yyPop(yycontext *yy, char *text, int count)   { yy->__val -= count; }
+YY_LOCAL(void) yySet(yycontext *yy, char *text, int count)   { yy->__val[count]= yy->__; }
+
+#endif /* YY_PART */
+
+#define	YYACCEPT	yyAccept(yy, yythunkpos0)
+
+YY_RULE(int) yy_EndOfLine(yycontext *yy); /* 32 */
+YY_RULE(int) yy_Comment(yycontext *yy); /* 31 */
+YY_RULE(int) yy_Space(yycontext *yy); /* 30 */
+YY_RULE(int) yy_Range(yycontext *yy); /* 29 */
+YY_RULE(int) yy_Char(yycontext *yy); /* 28 */
+YY_RULE(int) yy_IdentCont(yycontext *yy); /* 27 */
+YY_RULE(int) yy_IdentStart(yycontext *yy); /* 26 */
+YY_RULE(int) yy_END(yycontext *yy); /* 25 */
+YY_RULE(int) yy_BEGIN(yycontext *yy); /* 24 */
+YY_RULE(int) yy_DOT(yycontext *yy); /* 23 */
+YY_RULE(int) yy_Class(yycontext *yy); /* 22 */
+YY_RULE(int) yy_Literal(yycontext *yy); /* 21 */
+YY_RULE(int) yy_CLOSE(yycontext *yy); /* 20 */
+YY_RULE(int) yy_OPEN(yycontext *yy); /* 19 */
+YY_RULE(int) yy_PLUS(yycontext *yy); /* 18 */
+YY_RULE(int) yy_STAR(yycontext *yy); /* 17 */
+YY_RULE(int) yy_QUESTION(yycontext *yy); /* 16 */
+YY_RULE(int) yy_Primary(yycontext *yy); /* 15 */
+YY_RULE(int) yy_NOT(yycontext *yy); /* 14 */
+YY_RULE(int) yy_Suffix(yycontext *yy); /* 13 */
+YY_RULE(int) yy_Action(yycontext *yy); /* 12 */
+YY_RULE(int) yy_AND(yycontext *yy); /* 11 */
+YY_RULE(int) yy_Prefix(yycontext *yy); /* 10 */
+YY_RULE(int) yy_SLASH(yycontext *yy); /* 9 */
+YY_RULE(int) yy_Sequence(yycontext *yy); /* 8 */
+YY_RULE(int) yy_Expression(yycontext *yy); /* 7 */
+YY_RULE(int) yy_LEFTARROW(yycontext *yy); /* 6 */
+YY_RULE(int) yy_Identifier(yycontext *yy); /* 5 */
+YY_RULE(int) yy_EndOfFile(yycontext *yy); /* 4 */
+YY_RULE(int) yy_Definition(yycontext *yy); /* 3 */
+YY_RULE(int) yy_Spacing(yycontext *yy); /* 2 */
+YY_RULE(int) yy_Grammar(yycontext *yy); /* 1 */
+
+YY_ACTION(void) yy_7_Primary(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_7_Primary\n"));
+  {
+   push(makePredicate("YY_END")); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_6_Primary(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_6_Primary\n"));
+  {
+   push(makePredicate("YY_BEGIN")); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_5_Primary(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_5_Primary\n"));
+  {
+   push(makeAction(yytext)); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_4_Primary(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_4_Primary\n"));
+  {
+   push(makeDot()); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_3_Primary(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_3_Primary\n"));
+  {
+   push(makeClass(yytext)); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_2_Primary(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_2_Primary\n"));
+  {
+   push(makeString(yytext)); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_1_Primary(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_1_Primary\n"));
+  {
+   push(makeName(findRule(yytext))); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_3_Suffix(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_3_Suffix\n"));
+  {
+   push(makePlus (pop())); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_2_Suffix(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_2_Suffix\n"));
+  {
+   push(makeStar (pop())); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_1_Suffix(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_1_Suffix\n"));
+  {
+   push(makeQuery(pop())); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_3_Prefix(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_3_Prefix\n"));
+  {
+   push(makePeekNot(pop())); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_2_Prefix(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_2_Prefix\n"));
+  {
+   push(makePeekFor(pop())); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_1_Prefix(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_1_Prefix\n"));
+  {
+   push(makePredicate(yytext)); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_2_Sequence(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_2_Sequence\n"));
+  {
+   push(makePredicate("1")); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_1_Sequence(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_1_Sequence\n"));
+  {
+   Node *f= pop();  push(Sequence_append(pop(), f)); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_1_Expression(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_1_Expression\n"));
+  {
+   Node *f= pop();  push(Alternate_append(pop(), f)); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_2_Definition(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_2_Definition\n"));
+  {
+   Node *e= pop();  Rule_setExpression(pop(), e); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+YY_ACTION(void) yy_1_Definition(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_1_Definition\n"));
+  {
+   if (push(beginRule(findRule(yytext)))->rule.expression) fprintf(stderr, "rule '%s' redefined\n", yytext); ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
+
+YY_RULE(int) yy_EndOfLine(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "EndOfLine"));
+  {  int yypos2= yy->__pos, yythunkpos2= yy->__thunkpos;  if (!yymatchString(yy, "\r\n")) goto l3;  goto l2;
+  l3:;	  yy->__pos= yypos2; yy->__thunkpos= yythunkpos2;  if (!yymatchChar(yy, '\n')) goto l4;  goto l2;
+  l4:;	  yy->__pos= yypos2; yy->__thunkpos= yythunkpos2;  if (!yymatchChar(yy, '\r')) goto l1;
+  }
+  l2:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "EndOfLine", yy->__buf+yy->__pos));
+  return 1;
+  l1:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "EndOfLine", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_Comment(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "Comment"));  if (!yymatchChar(yy, '#')) goto l5;
+  l6:;	
+  {  int yypos7= yy->__pos, yythunkpos7= yy->__thunkpos;
+  {  int yypos8= yy->__pos, yythunkpos8= yy->__thunkpos;  if (!yy_EndOfLine(yy)) goto l8;  goto l7;
+  l8:;	  yy->__pos= yypos8; yy->__thunkpos= yythunkpos8;
+  }  if (!yymatchDot(yy)) goto l7;  goto l6;
+  l7:;	  yy->__pos= yypos7; yy->__thunkpos= yythunkpos7;
+  }  if (!yy_EndOfLine(yy)) goto l5;
+  yyprintf((stderr, "  ok   %s @ %s\n", "Comment", yy->__buf+yy->__pos));
+  return 1;
+  l5:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "Comment", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_Space(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "Space"));
+  {  int yypos10= yy->__pos, yythunkpos10= yy->__thunkpos;  if (!yymatchChar(yy, ' ')) goto l11;  goto l10;
+  l11:;	  yy->__pos= yypos10; yy->__thunkpos= yythunkpos10;  if (!yymatchChar(yy, '\t')) goto l12;  goto l10;
+  l12:;	  yy->__pos= yypos10; yy->__thunkpos= yythunkpos10;  if (!yy_EndOfLine(yy)) goto l9;
+  }
+  l10:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "Space", yy->__buf+yy->__pos));
+  return 1;
+  l9:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "Space", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_Range(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "Range"));
+  {  int yypos14= yy->__pos, yythunkpos14= yy->__thunkpos;  if (!yy_Char(yy)) goto l15;  if (!yymatchChar(yy, '-')) goto l15;  if (!yy_Char(yy)) goto l15;  goto l14;
+  l15:;	  yy->__pos= yypos14; yy->__thunkpos= yythunkpos14;  if (!yy_Char(yy)) goto l13;
+  }
+  l14:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "Range", yy->__buf+yy->__pos));
+  return 1;
+  l13:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "Range", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_Char(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "Char"));
+  {  int yypos17= yy->__pos, yythunkpos17= yy->__thunkpos;  if (!yymatchChar(yy, '\\')) goto l18;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\204\000\000\000\000\000\000\070\146\100\124\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l18;  goto l17;
+  l18:;	  yy->__pos= yypos17; yy->__thunkpos= yythunkpos17;  if (!yymatchChar(yy, '\\')) goto l19;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\017\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l19;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l19;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l19;  goto l17;
+  l19:;	  yy->__pos= yypos17; yy->__thunkpos= yythunkpos17;  if (!yymatchChar(yy, '\\')) goto l20;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l20;
+  {  int yypos21= yy->__pos, yythunkpos21= yy->__thunkpos;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l21;  goto l22;
+  l21:;	  yy->__pos= yypos21; yy->__thunkpos= yythunkpos21;
+  }
+  l22:;	  goto l17;
+  l20:;	  yy->__pos= yypos17; yy->__thunkpos= yythunkpos17;  if (!yymatchChar(yy, '\\')) goto l23;  if (!yymatchChar(yy, '-')) goto l23;  goto l17;
+  l23:;	  yy->__pos= yypos17; yy->__thunkpos= yythunkpos17;
+  {  int yypos24= yy->__pos, yythunkpos24= yy->__thunkpos;  if (!yymatchChar(yy, '\\')) goto l24;  goto l16;
+  l24:;	  yy->__pos= yypos24; yy->__thunkpos= yythunkpos24;
+  }  if (!yymatchDot(yy)) goto l16;
+  }
+  l17:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "Char", yy->__buf+yy->__pos));
+  return 1;
+  l16:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "Char", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_IdentCont(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "IdentCont"));
+  {  int yypos26= yy->__pos, yythunkpos26= yy->__thunkpos;  if (!yy_IdentStart(yy)) goto l27;  goto l26;
+  l27:;	  yy->__pos= yypos26; yy->__thunkpos= yythunkpos26;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\377\003\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l25;
+  }
+  l26:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "IdentCont", yy->__buf+yy->__pos));
+  return 1;
+  l25:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "IdentCont", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_IdentStart(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "IdentStart"));  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\000\000\000\000\376\377\377\207\376\377\377\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l28;
+  yyprintf((stderr, "  ok   %s @ %s\n", "IdentStart", yy->__buf+yy->__pos));
+  return 1;
+  l28:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "IdentStart", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_END(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "END"));  if (!yymatchChar(yy, '>')) goto l29;  if (!yy_Spacing(yy)) goto l29;
+  yyprintf((stderr, "  ok   %s @ %s\n", "END", yy->__buf+yy->__pos));
+  return 1;
+  l29:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "END", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_BEGIN(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "BEGIN"));  if (!yymatchChar(yy, '<')) goto l30;  if (!yy_Spacing(yy)) goto l30;
+  yyprintf((stderr, "  ok   %s @ %s\n", "BEGIN", yy->__buf+yy->__pos));
+  return 1;
+  l30:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "BEGIN", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_DOT(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "DOT"));  if (!yymatchChar(yy, '.')) goto l31;  if (!yy_Spacing(yy)) goto l31;
+  yyprintf((stderr, "  ok   %s @ %s\n", "DOT", yy->__buf+yy->__pos));
+  return 1;
+  l31:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "DOT", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_Class(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "Class"));  if (!yymatchChar(yy, '[')) goto l32;  yyText(yy, yy->__begin, yy->__end);  if (!(YY_BEGIN)) goto l32;
+  l33:;	
+  {  int yypos34= yy->__pos, yythunkpos34= yy->__thunkpos;
+  {  int yypos35= yy->__pos, yythunkpos35= yy->__thunkpos;  if (!yymatchChar(yy, ']')) goto l35;  goto l34;
+  l35:;	  yy->__pos= yypos35; yy->__thunkpos= yythunkpos35;
+  }  if (!yy_Range(yy)) goto l34;  goto l33;
+  l34:;	  yy->__pos= yypos34; yy->__thunkpos= yythunkpos34;
+  }  yyText(yy, yy->__begin, yy->__end);  if (!(YY_END)) goto l32;  if (!yymatchChar(yy, ']')) goto l32;  if (!yy_Spacing(yy)) goto l32;
+  yyprintf((stderr, "  ok   %s @ %s\n", "Class", yy->__buf+yy->__pos));
+  return 1;
+  l32:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "Class", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_Literal(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "Literal"));
+  {  int yypos37= yy->__pos, yythunkpos37= yy->__thunkpos;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l38;  yyText(yy, yy->__begin, yy->__end);  if (!(YY_BEGIN)) goto l38;
+  l39:;	
+  {  int yypos40= yy->__pos, yythunkpos40= yy->__thunkpos;
+  {  int yypos41= yy->__pos, yythunkpos41= yy->__thunkpos;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l41;  goto l40;
+  l41:;	  yy->__pos= yypos41; yy->__thunkpos= yythunkpos41;
+  }  if (!yy_Char(yy)) goto l40;  goto l39;
+  l40:;	  yy->__pos= yypos40; yy->__thunkpos= yythunkpos40;
+  }  yyText(yy, yy->__begin, yy->__end);  if (!(YY_END)) goto l38;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l38;  if (!yy_Spacing(yy)) goto l38;  goto l37;
+  l38:;	  yy->__pos= yypos37; yy->__thunkpos= yythunkpos37;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l36;  yyText(yy, yy->__begin, yy->__end);  if (!(YY_BEGIN)) goto l36;
+  l42:;	
+  {  int yypos43= yy->__pos, yythunkpos43= yy->__thunkpos;
+  {  int yypos44= yy->__pos, yythunkpos44= yy->__thunkpos;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l44;  goto l43;
+  l44:;	  yy->__pos= yypos44; yy->__thunkpos= yythunkpos44;
+  }  if (!yy_Char(yy)) goto l43;  goto l42;
+  l43:;	  yy->__pos= yypos43; yy->__thunkpos= yythunkpos43;
+  }  yyText(yy, yy->__begin, yy->__end);  if (!(YY_END)) goto l36;  if (!yymatchClass(yy, (unsigned char *)"\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l36;  if (!yy_Spacing(yy)) goto l36;
+  }
+  l37:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "Literal", yy->__buf+yy->__pos));
+  return 1;
+  l36:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "Literal", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_CLOSE(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "CLOSE"));  if (!yymatchChar(yy, ')')) goto l45;  if (!yy_Spacing(yy)) goto l45;
+  yyprintf((stderr, "  ok   %s @ %s\n", "CLOSE", yy->__buf+yy->__pos));
+  return 1;
+  l45:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "CLOSE", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_OPEN(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "OPEN"));  if (!yymatchChar(yy, '(')) goto l46;  if (!yy_Spacing(yy)) goto l46;
+  yyprintf((stderr, "  ok   %s @ %s\n", "OPEN", yy->__buf+yy->__pos));
+  return 1;
+  l46:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "OPEN", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_PLUS(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "PLUS"));  if (!yymatchChar(yy, '+')) goto l47;  if (!yy_Spacing(yy)) goto l47;
+  yyprintf((stderr, "  ok   %s @ %s\n", "PLUS", yy->__buf+yy->__pos));
+  return 1;
+  l47:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "PLUS", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_STAR(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "STAR"));  if (!yymatchChar(yy, '*')) goto l48;  if (!yy_Spacing(yy)) goto l48;
+  yyprintf((stderr, "  ok   %s @ %s\n", "STAR", yy->__buf+yy->__pos));
+  return 1;
+  l48:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "STAR", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_QUESTION(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "QUESTION"));  if (!yymatchChar(yy, '?')) goto l49;  if (!yy_Spacing(yy)) goto l49;
+  yyprintf((stderr, "  ok   %s @ %s\n", "QUESTION", yy->__buf+yy->__pos));
+  return 1;
+  l49:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "QUESTION", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_Primary(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "Primary"));
+  {  int yypos51= yy->__pos, yythunkpos51= yy->__thunkpos;  if (!yy_Identifier(yy)) goto l52;
+  {  int yypos53= yy->__pos, yythunkpos53= yy->__thunkpos;  if (!yy_LEFTARROW(yy)) goto l53;  goto l52;
+  l53:;	  yy->__pos= yypos53; yy->__thunkpos= yythunkpos53;
+  }  yyDo(yy, yy_1_Primary, yy->__begin, yy->__end);  goto l51;
+  l52:;	  yy->__pos= yypos51; yy->__thunkpos= yythunkpos51;  if (!yy_OPEN(yy)) goto l54;  if (!yy_Expression(yy)) goto l54;  if (!yy_CLOSE(yy)) goto l54;  goto l51;
+  l54:;	  yy->__pos= yypos51; yy->__thunkpos= yythunkpos51;  if (!yy_Literal(yy)) goto l55;  yyDo(yy, yy_2_Primary, yy->__begin, yy->__end);  goto l51;
+  l55:;	  yy->__pos= yypos51; yy->__thunkpos= yythunkpos51;  if (!yy_Class(yy)) goto l56;  yyDo(yy, yy_3_Primary, yy->__begin, yy->__end);  goto l51;
+  l56:;	  yy->__pos= yypos51; yy->__thunkpos= yythunkpos51;  if (!yy_DOT(yy)) goto l57;  yyDo(yy, yy_4_Primary, yy->__begin, yy->__end);  goto l51;
+  l57:;	  yy->__pos= yypos51; yy->__thunkpos= yythunkpos51;  if (!yy_Action(yy)) goto l58;  yyDo(yy, yy_5_Primary, yy->__begin, yy->__end);  goto l51;
+  l58:;	  yy->__pos= yypos51; yy->__thunkpos= yythunkpos51;  if (!yy_BEGIN(yy)) goto l59;  yyDo(yy, yy_6_Primary, yy->__begin, yy->__end);  goto l51;
+  l59:;	  yy->__pos= yypos51; yy->__thunkpos= yythunkpos51;  if (!yy_END(yy)) goto l50;  yyDo(yy, yy_7_Primary, yy->__begin, yy->__end);
+  }
+  l51:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "Primary", yy->__buf+yy->__pos));
+  return 1;
+  l50:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "Primary", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_NOT(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "NOT"));  if (!yymatchChar(yy, '!')) goto l60;  if (!yy_Spacing(yy)) goto l60;
+  yyprintf((stderr, "  ok   %s @ %s\n", "NOT", yy->__buf+yy->__pos));
+  return 1;
+  l60:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "NOT", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_Suffix(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "Suffix"));  if (!yy_Primary(yy)) goto l61;
+  {  int yypos62= yy->__pos, yythunkpos62= yy->__thunkpos;
+  {  int yypos64= yy->__pos, yythunkpos64= yy->__thunkpos;  if (!yy_QUESTION(yy)) goto l65;  yyDo(yy, yy_1_Suffix, yy->__begin, yy->__end);  goto l64;
+  l65:;	  yy->__pos= yypos64; yy->__thunkpos= yythunkpos64;  if (!yy_STAR(yy)) goto l66;  yyDo(yy, yy_2_Suffix, yy->__begin, yy->__end);  goto l64;
+  l66:;	  yy->__pos= yypos64; yy->__thunkpos= yythunkpos64;  if (!yy_PLUS(yy)) goto l62;  yyDo(yy, yy_3_Suffix, yy->__begin, yy->__end);
+  }
+  l64:;	  goto l63;
+  l62:;	  yy->__pos= yypos62; yy->__thunkpos= yythunkpos62;
+  }
+  l63:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "Suffix", yy->__buf+yy->__pos));
+  return 1;
+  l61:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "Suffix", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_Action(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "Action"));  if (!yymatchChar(yy, '{')) goto l67;  yyText(yy, yy->__begin, yy->__end);  if (!(YY_BEGIN)) goto l67;
+  l68:;	
+  {  int yypos69= yy->__pos, yythunkpos69= yy->__thunkpos;  if (!yymatchClass(yy, (unsigned char *)"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\337\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377")) goto l69;  goto l68;
+  l69:;	  yy->__pos= yypos69; yy->__thunkpos= yythunkpos69;
+  }  yyText(yy, yy->__begin, yy->__end);  if (!(YY_END)) goto l67;  if (!yymatchChar(yy, '}')) goto l67;  if (!yy_Spacing(yy)) goto l67;
+  yyprintf((stderr, "  ok   %s @ %s\n", "Action", yy->__buf+yy->__pos));
+  return 1;
+  l67:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "Action", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_AND(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "AND"));  if (!yymatchChar(yy, '&')) goto l70;  if (!yy_Spacing(yy)) goto l70;
+  yyprintf((stderr, "  ok   %s @ %s\n", "AND", yy->__buf+yy->__pos));
+  return 1;
+  l70:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "AND", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_Prefix(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "Prefix"));
+  {  int yypos72= yy->__pos, yythunkpos72= yy->__thunkpos;  if (!yy_AND(yy)) goto l73;  if (!yy_Action(yy)) goto l73;  yyDo(yy, yy_1_Prefix, yy->__begin, yy->__end);  goto l72;
+  l73:;	  yy->__pos= yypos72; yy->__thunkpos= yythunkpos72;  if (!yy_AND(yy)) goto l74;  if (!yy_Suffix(yy)) goto l74;  yyDo(yy, yy_2_Prefix, yy->__begin, yy->__end);  goto l72;
+  l74:;	  yy->__pos= yypos72; yy->__thunkpos= yythunkpos72;  if (!yy_NOT(yy)) goto l75;  if (!yy_Suffix(yy)) goto l75;  yyDo(yy, yy_3_Prefix, yy->__begin, yy->__end);  goto l72;
+  l75:;	  yy->__pos= yypos72; yy->__thunkpos= yythunkpos72;  if (!yy_Suffix(yy)) goto l71;
+  }
+  l72:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "Prefix", yy->__buf+yy->__pos));
+  return 1;
+  l71:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "Prefix", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_SLASH(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "SLASH"));  if (!yymatchChar(yy, '/')) goto l76;  if (!yy_Spacing(yy)) goto l76;
+  yyprintf((stderr, "  ok   %s @ %s\n", "SLASH", yy->__buf+yy->__pos));
+  return 1;
+  l76:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "SLASH", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_Sequence(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "Sequence"));
+  {  int yypos78= yy->__pos, yythunkpos78= yy->__thunkpos;  if (!yy_Prefix(yy)) goto l79;
+  l80:;	
+  {  int yypos81= yy->__pos, yythunkpos81= yy->__thunkpos;  if (!yy_Prefix(yy)) goto l81;  yyDo(yy, yy_1_Sequence, yy->__begin, yy->__end);  goto l80;
+  l81:;	  yy->__pos= yypos81; yy->__thunkpos= yythunkpos81;
+  }  goto l78;
+  l79:;	  yy->__pos= yypos78; yy->__thunkpos= yythunkpos78;  yyDo(yy, yy_2_Sequence, yy->__begin, yy->__end);
+  }
+  l78:;	
+  yyprintf((stderr, "  ok   %s @ %s\n", "Sequence", yy->__buf+yy->__pos));
+  return 1;
+  l77:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "Sequence", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_Expression(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "Expression"));  if (!yy_Sequence(yy)) goto l82;
+  l83:;	
+  {  int yypos84= yy->__pos, yythunkpos84= yy->__thunkpos;  if (!yy_SLASH(yy)) goto l84;  if (!yy_Sequence(yy)) goto l84;  yyDo(yy, yy_1_Expression, yy->__begin, yy->__end);  goto l83;
+  l84:;	  yy->__pos= yypos84; yy->__thunkpos= yythunkpos84;
+  }
+  yyprintf((stderr, "  ok   %s @ %s\n", "Expression", yy->__buf+yy->__pos));
+  return 1;
+  l82:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "Expression", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_LEFTARROW(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "LEFTARROW"));  if (!yymatchString(yy, "<-")) goto l85;  if (!yy_Spacing(yy)) goto l85;
+  yyprintf((stderr, "  ok   %s @ %s\n", "LEFTARROW", yy->__buf+yy->__pos));
+  return 1;
+  l85:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "LEFTARROW", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_Identifier(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "Identifier"));  yyText(yy, yy->__begin, yy->__end);  if (!(YY_BEGIN)) goto l86;  if (!yy_IdentStart(yy)) goto l86;
+  l87:;	
+  {  int yypos88= yy->__pos, yythunkpos88= yy->__thunkpos;  if (!yy_IdentCont(yy)) goto l88;  goto l87;
+  l88:;	  yy->__pos= yypos88; yy->__thunkpos= yythunkpos88;
+  }  yyText(yy, yy->__begin, yy->__end);  if (!(YY_END)) goto l86;  if (!yy_Spacing(yy)) goto l86;
+  yyprintf((stderr, "  ok   %s @ %s\n", "Identifier", yy->__buf+yy->__pos));
+  return 1;
+  l86:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "Identifier", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_EndOfFile(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "EndOfFile"));
+  {  int yypos90= yy->__pos, yythunkpos90= yy->__thunkpos;  if (!yymatchDot(yy)) goto l90;  goto l89;
+  l90:;	  yy->__pos= yypos90; yy->__thunkpos= yythunkpos90;
+  }
+  yyprintf((stderr, "  ok   %s @ %s\n", "EndOfFile", yy->__buf+yy->__pos));
+  return 1;
+  l89:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "EndOfFile", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_Definition(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "Definition"));  if (!yy_Identifier(yy)) goto l91;  yyDo(yy, yy_1_Definition, yy->__begin, yy->__end);  if (!yy_LEFTARROW(yy)) goto l91;  if (!yy_Expression(yy)) goto l91;  yyDo(yy, yy_2_Definition, yy->__begin, yy->__end);  yyText(yy, yy->__begin, yy->__end);  if (!( YYACCEPT )) goto l91;
+  yyprintf((stderr, "  ok   %s @ %s\n", "Definition", yy->__buf+yy->__pos));
+  return 1;
+  l91:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "Definition", yy->__buf+yy->__pos));
+  return 0;
+}
+YY_RULE(int) yy_Spacing(yycontext *yy)
+{
+  yyprintf((stderr, "%s\n", "Spacing"));
+  l93:;	
+  {  int yypos94= yy->__pos, yythunkpos94= yy->__thunkpos;
+  {  int yypos95= yy->__pos, yythunkpos95= yy->__thunkpos;  if (!yy_Space(yy)) goto l96;  goto l95;
+  l96:;	  yy->__pos= yypos95; yy->__thunkpos= yythunkpos95;  if (!yy_Comment(yy)) goto l94;
+  }
+  l95:;	  goto l93;
+  l94:;	  yy->__pos= yypos94; yy->__thunkpos= yythunkpos94;
+  }
+  yyprintf((stderr, "  ok   %s @ %s\n", "Spacing", yy->__buf+yy->__pos));
+  return 1;
+}
+YY_RULE(int) yy_Grammar(yycontext *yy)
+{  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
+  yyprintf((stderr, "%s\n", "Grammar"));  if (!yy_Spacing(yy)) goto l97;  if (!yy_Definition(yy)) goto l97;
+  l98:;	
+  {  int yypos99= yy->__pos, yythunkpos99= yy->__thunkpos;  if (!yy_Definition(yy)) goto l99;  goto l98;
+  l99:;	  yy->__pos= yypos99; yy->__thunkpos= yythunkpos99;
+  }  if (!yy_EndOfFile(yy)) goto l97;
+  yyprintf((stderr, "  ok   %s @ %s\n", "Grammar", yy->__buf+yy->__pos));
+  return 1;
+  l97:;	  yy->__pos= yypos0; yy->__thunkpos= yythunkpos0;
+  yyprintf((stderr, "  fail %s @ %s\n", "Grammar", yy->__buf+yy->__pos));
+  return 0;
+}
+
+#ifndef YY_PART
+
+typedef int (*yyrule)(yycontext *yy);
+
+YY_PARSE(int) YYPARSEFROM(YY_CTX_PARAM_ yyrule yystart)
+{
+  int yyok;
+  if (!yyctx->__buflen)
+    {
+      yyctx->__buflen= YY_BUFFER_SIZE;
+      yyctx->__buf= (char *)YY_MALLOC(yyctx, yyctx->__buflen);
+      yyctx->__textlen= YY_BUFFER_SIZE;
+      yyctx->__text= (char *)YY_MALLOC(yyctx, yyctx->__textlen);
+      yyctx->__thunkslen= YY_STACK_SIZE;
+      yyctx->__thunks= (yythunk *)YY_MALLOC(yyctx, sizeof(yythunk) * yyctx->__thunkslen);
+      yyctx->__valslen= YY_STACK_SIZE;
+      yyctx->__vals= (YYSTYPE *)YY_MALLOC(yyctx, sizeof(YYSTYPE) * yyctx->__valslen);
+      yyctx->__begin= yyctx->__end= yyctx->__pos= yyctx->__limit= yyctx->__thunkpos= 0;
+    }
+  yyctx->__begin= yyctx->__end= yyctx->__pos;
+  yyctx->__thunkpos= 0;
+  yyctx->__val= yyctx->__vals;
+  yyok= yystart(yyctx);
+  if (yyok) yyDone(yyctx);
+  yyCommit(yyctx);
+  return yyok;
+}
+
+YY_PARSE(int) YYPARSE(YY_CTX_PARAM)
+{
+  return YYPARSEFROM(YY_CTX_ARG_ yy_Grammar);
+}
+
+YY_PARSE(yycontext *) YYRELEASE(yycontext *yyctx)
+{
+  if (yyctx->__buflen)
+    {
+      yyctx->__buflen= 0;
+      YY_FREE(yyctx->__buf);
+      YY_FREE(yyctx->__text);
+      YY_FREE(yyctx->__thunks);
+      YY_FREE(yyctx->__vals);
+    }
+  return yyctx;
+}
+
+#endif
--- /dev/null
+++ b/src/tree.c
@@ -1,0 +1,365 @@
+/* Copyright (c) 2007 by Ian Piumarta
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the 'Software'),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, provided that the above copyright notice(s) and this
+ * permission notice appear in all copies of the Software.  Acknowledgement
+ * of the use of this Software in supporting documentation would be
+ * appreciated but is not required.
+ * 
+ * THE SOFTWARE IS PROVIDED 'AS IS'.  USE ENTIRELY AT YOUR OWN RISK.
+ * 
+ * Last edited: 2012-05-15 23:29:12 by piumarta on emilia
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#ifdef WIN32
+# undef inline
+# define inline __inline
+#endif
+
+#include "tree.h"
+
+Node *actions= 0;
+Node *rules= 0;
+Node *thisRule= 0;
+Node *start= 0;
+
+FILE *output= 0;
+
+int actionCount= 0;
+int ruleCount= 0;
+int lastToken= -1;
+
+static inline Node *_newNode(int type, int size)
+{
+  Node *node= calloc(1, size);
+  node->type= type;
+  return node;
+}
+
+#define newNode(T)	_newNode(T, sizeof(struct T))
+
+Node *makeRule(char *name)
+{
+  Node *node= newNode(Rule);
+  node->rule.name= strdup(name);
+  node->rule.id= ++ruleCount;
+  node->rule.flags= 0;
+  node->rule.next= rules;
+  rules= node;
+  return node;
+}
+
+Node *findRule(char *name)
+{
+  Node *n;
+  char *ptr;
+  for (ptr= name;  *ptr;  ptr++) if ('-' == *ptr) *ptr= '_';
+  for (n= rules;  n;  n= n->any.next)
+    {
+      assert(Rule == n->type);
+      if (!strcmp(name, n->rule.name))
+	return n;
+    }
+  return makeRule(name);
+}
+
+Node *beginRule(Node *rule)
+{
+  actionCount= 0;
+  return thisRule= rule;
+}
+
+void Rule_setExpression(Node *node, Node *expression)
+{
+  assert(node);
+#ifdef DEBUG
+  Node_print(node);  fprintf(stderr, " [%d]<- ", node->type);  Node_print(expression);  fprintf(stderr, "\n");
+#endif
+  assert(Rule == node->type);
+  node->rule.expression= expression;
+  if (!start || !strcmp(node->rule.name, "start"))
+    start= node;
+}
+
+Node *makeVariable(char *name)
+{
+  Node *node;
+  assert(thisRule);
+  for (node= thisRule->rule.variables;  node;  node= node->variable.next)
+    if (!strcmp(name, node->variable.name))
+      return node;
+  node= newNode(Variable);
+  node->variable.name= strdup(name);
+  node->variable.next= thisRule->rule.variables;
+  thisRule->rule.variables= node;
+  return node;
+}
+
+Node *makeName(Node *rule)
+{
+  Node *node= newNode(Name);
+  node->name.rule= rule;
+  node->name.variable= 0;
+  rule->rule.flags |= RuleUsed;
+  return node;
+}
+
+Node *makeDot(void)
+{
+  return newNode(Dot);
+}
+
+Node *makeCharacter(char *text)
+{
+  Node *node= newNode(Character);
+  node->character.value= strdup(text);
+  return node;
+}
+
+Node *makeString(char *text)
+{
+  Node *node= newNode(String);
+  node->string.value= strdup(text);
+  return node;
+}
+
+Node *makeClass(char *text)
+{
+  Node *node= newNode(Class);
+  node->cclass.value= (unsigned char *)strdup(text);
+  return node;
+}
+
+Node *makeAction(char *text)
+{
+  Node *node= newNode(Action);
+  char name[1024];
+  assert(thisRule);
+  sprintf(name, "_%d_%s", ++actionCount, thisRule->rule.name);
+  node->action.name= strdup(name);
+  node->action.text= strdup(text);
+  node->action.list= actions;
+  node->action.rule= thisRule;
+  actions= node;
+  {
+    char *ptr;
+    for (ptr= node->action.text;  *ptr;  ++ptr)
+      if ('$' == ptr[0] && '$' == ptr[1])
+	ptr[1]= ptr[0]= '_';
+  }
+  return node;
+}
+
+Node *makePredicate(char *text)
+{
+  Node *node= newNode(Predicate);
+  node->predicate.text= strdup(text);
+  return node;
+}
+
+Node *makeError(Node *e, char *text)
+{
+  Node *node= newNode(Error);
+  node->error.element= e;
+  node->error.text= strdup(text);
+  return node;
+}
+
+Node *makeAlternate(Node *e)
+{
+  if (Alternate != e->type)
+    {
+      Node *node= newNode(Alternate);
+      assert(e);
+      assert(!e->any.next);
+      node->alternate.first=
+	node->alternate.last= e;
+      return node;
+    }
+  return e;
+}
+
+Node *Alternate_append(Node *a, Node *e)
+{
+  assert(a);
+  a= makeAlternate(a);
+  assert(a->alternate.last);
+  assert(e);
+  a->alternate.last->any.next= e;
+  a->alternate.last= e;
+  return a;
+}
+
+Node *makeSequence(Node *e)
+{
+  if (Sequence != e->type)
+    {
+      Node *node= newNode(Sequence);
+      assert(e);
+      assert(!e->any.next);
+      node->sequence.first=
+	node->sequence.last= e;
+      return node;
+    }
+  return e;
+}
+
+Node *Sequence_append(Node *a, Node *e)
+{
+  assert(a);
+  a= makeSequence(a);
+  assert(a->sequence.last);
+  assert(e);
+  a->sequence.last->any.next= e;
+  a->sequence.last= e;
+  return a;
+}
+
+Node *makePeekFor(Node *e)
+{
+  Node *node= newNode(PeekFor);
+  node->peekFor.element= e;
+  return node;
+}
+
+Node *makePeekNot(Node *e)
+{
+  Node *node= newNode(PeekNot);
+  node->peekNot.element= e;
+  return node;
+}
+
+Node *makeQuery(Node *e)
+{
+  Node *node= newNode(Query);
+  node->query.element= e;
+  return node;
+}
+
+Node *makeStar(Node *e)
+{
+  Node *node= newNode(Star);
+  node->star.element= e;
+  return node;
+}
+
+Node *makePlus(Node *e)
+{
+  Node *node= newNode(Plus);
+  node->plus.element= e;
+  return node;
+}
+
+
+static Node  *stack[1024];
+static Node **stackPointer= stack;
+
+
+#ifdef DEBUG
+static void dumpStack(void)
+{
+  Node **p;
+  for (p= stack + 1;  p <= stackPointer;  ++p)
+    {
+      fprintf(stderr, "### %d\t", p - stack);
+      Node_print(*p);
+      fprintf(stderr, "\n");
+    }
+}
+#endif
+
+Node *push(Node *node)
+{
+  assert(node);
+  assert(stackPointer < stack + 1023);
+#ifdef DEBUG
+  dumpStack();  fprintf(stderr, " PUSH ");  Node_print(node);  fprintf(stderr, "\n");
+#endif
+  return *++stackPointer= node;
+}
+
+Node *top(void)
+{
+  assert(stackPointer > stack);
+  return *stackPointer;
+}
+
+Node *pop(void)
+{
+  assert(stackPointer > stack);
+#ifdef DEBUG
+  dumpStack();  fprintf(stderr, " POP\n");
+#endif
+  return *stackPointer--;
+}
+
+
+static void Node_fprint(FILE *stream, Node *node)
+{
+  assert(node);
+  switch (node->type)
+    {
+    case Rule:		fprintf(stream, " %s", node->rule.name);				break;
+    case Name:		fprintf(stream, " %s", node->name.rule->rule.name);			break;
+    case Dot:		fprintf(stream, " .");							break;
+    case Character:	fprintf(stream, " '%s'", node->character.value);			break;
+    case String:	fprintf(stream, " \"%s\"", node->string.value);				break;
+    case Class:		fprintf(stream, " [%s]", node->cclass.value);				break;
+    case Action:	fprintf(stream, " { %s }", node->action.text);				break;
+    case Predicate:	fprintf(stream, " ?{ %s }", node->action.text);				break;
+
+    case Alternate:	node= node->alternate.first;
+			fprintf(stream, " (");
+			Node_fprint(stream, node);
+			while ((node= node->any.next))
+			  {
+			    fprintf(stream, " |");
+			    Node_fprint(stream, node);
+			  }
+			fprintf(stream, " )");
+			break;
+
+    case Sequence:	node= node->sequence.first;
+			fprintf(stream, " (");
+			Node_fprint(stream, node);
+			while ((node= node->any.next))
+			  Node_fprint(stream, node);
+			fprintf(stream, " )");
+			break;
+
+    case PeekFor:	fprintf(stream, "&");  Node_fprint(stream, node->query.element);	break;
+    case PeekNot:	fprintf(stream, "!");  Node_fprint(stream, node->query.element);	break;
+    case Query:		Node_fprint(stream, node->query.element);  fprintf(stream, "?");	break;
+    case Star:		Node_fprint(stream, node->query.element);  fprintf(stream, "*");	break;
+    case Plus:		Node_fprint(stream, node->query.element);  fprintf(stream, "+");	break;
+    default:
+      fprintf(stream, "\nunknown node type %d\n", node->type);
+      exit(1);
+    }
+}
+
+void Node_print(Node *node)	{ Node_fprint(stderr, node); }
+
+static void Rule_fprint(FILE *stream, Node *node)
+{
+  assert(node);
+  assert(Rule == node->type);
+  fprintf(stream, "%s.%d =", node->rule.name, node->rule.id);
+  if (node->rule.expression)
+    Node_fprint(stream, node->rule.expression);
+  else
+    fprintf(stream, " UNDEFINED");
+  fprintf(stream, " ;\n");
+}
+
+void Rule_print(Node *node)	{ Rule_fprint(stderr, node); }
--- /dev/null
+++ b/src/tree.h
@@ -1,0 +1,111 @@
+/* Copyright (c) 2007 by Ian Piumarta
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the 'Software'),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, provided that the above copyright notice(s) and this
+ * permission notice appear in all copies of the Software.  Acknowledgement
+ * of the use of this Software in supporting documentation would be
+ * appreciated but is not required.
+ * 
+ * THE SOFTWARE IS PROVIDED 'AS IS'.  USE ENTIRELY AT YOUR OWN RISK.
+ * 
+ * Last edited: 2012-05-15 22:37:53 by piumarta on emilia
+ */
+
+#include <stdio.h>
+
+enum { Unknown= 0, Rule, Variable, Name, Dot, Character, String, Class, Action, Predicate, Error, Alternate, Sequence, PeekFor, PeekNot, Query, Star, Plus };
+
+enum {
+  RuleUsed	= 1<<0,
+  RuleReached	= 1<<1,
+};
+
+typedef union Node Node;
+
+struct Rule	 { int type;  Node *next;   char *name;	 Node *variables;  Node *expression;  int id;  int flags;	};
+struct Variable	 { int type;  Node *next;   char *name;  Node *value;  int offset;					};
+struct Name	 { int type;  Node *next;   Node *rule;  Node *variable;						};
+struct Dot	 { int type;  Node *next;										};
+struct Character { int type;  Node *next;   char *value;								};
+struct String	 { int type;  Node *next;   char *value;								};
+struct Class	 { int type;  Node *next;   unsigned char *value;							};
+struct Action	 { int type;  Node *next;   char *text;	  Node *list;  char *name;  Node *rule;				};
+struct Predicate { int type;  Node *next;   char *text;									};
+struct Error	 { int type;  Node *next;   Node *element;  char *text;							};
+struct Alternate { int type;  Node *next;   Node *first;  Node *last;							};
+struct Sequence	 { int type;  Node *next;   Node *first;  Node *last;							};
+struct PeekFor	 { int type;  Node *next;   Node *element;								};
+struct PeekNot	 { int type;  Node *next;   Node *element;								};
+struct Query	 { int type;  Node *next;   Node *element;								};
+struct Star	 { int type;  Node *next;   Node *element;								};
+struct Plus	 { int type;  Node *next;   Node *element;								};
+struct Any	 { int type;  Node *next;										};
+
+union Node
+{
+  int			type;
+  struct Rule		rule;
+  struct Variable	variable;
+  struct Name		name;
+  struct Dot		dot;
+  struct Character	character;
+  struct String		string;
+  struct Class		cclass;
+  struct Action		action;
+  struct Predicate	predicate;
+  struct Error		error;
+  struct Alternate	alternate;
+  struct Sequence	sequence;
+  struct PeekFor	peekFor;
+  struct PeekNot	peekNot;
+  struct Query		query;
+  struct Star		star;
+  struct Plus		plus;
+  struct Any		any;
+};
+
+extern Node *actions;
+extern Node *rules;
+extern Node *start;
+
+extern int   ruleCount;
+
+extern FILE *output;
+
+extern Node *makeRule(char *name);
+extern Node *findRule(char *name);
+extern Node *beginRule(Node *rule);
+extern void  Rule_setExpression(Node *rule, Node *expression);
+extern Node *Rule_beToken(Node *rule);
+extern Node *makeVariable(char *name);
+extern Node *makeName(Node *rule);
+extern Node *makeDot(void);
+extern Node *makeCharacter(char *text);
+extern Node *makeString(char *text);
+extern Node *makeClass(char *text);
+extern Node *makeAction(char *text);
+extern Node *makePredicate(char *text);
+extern Node *makeError(Node *e, char *text);
+extern Node *makeAlternate(Node *e);
+extern Node *Alternate_append(Node *e, Node *f);
+extern Node *makeSequence(Node *e);
+extern Node *Sequence_append(Node *e, Node *f);
+extern Node *makePeekFor(Node *e);
+extern Node *makePeekNot(Node *e);
+extern Node *makeQuery(Node *e);
+extern Node *makeStar(Node *e);
+extern Node *makePlus(Node *e);
+extern Node *push(Node *node);
+extern Node *top(void);
+extern Node *pop(void);
+
+extern void  Rule_compile_c_header(void);
+extern void  Rule_compile_c(Node *node);
+
+extern void  Node_print(Node *node);
+extern void  Rule_print(Node *node);
--- /dev/null
+++ b/src/version.h
@@ -1,0 +1,3 @@
+#define PEG_MAJOR	0
+#define PEG_MINOR	1
+#define PEG_LEVEL	11
--- a/tree.c
+++ /dev/null
@@ -1,352 +1,0 @@
-/* Copyright (c) 2007 by Ian Piumarta
- * All rights reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the 'Software'),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, provided that the above copyright notice(s) and this
- * permission notice appear in all copies of the Software.  Acknowledgement
- * of the use of this Software in supporting documentation would be
- * appreciated but is not required.
- * 
- * THE SOFTWARE IS PROVIDED 'AS IS'.  USE ENTIRELY AT YOUR OWN RISK.
- * 
- * Last edited: 2007-05-15 10:32:09 by piumarta on emilia
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "tree.h"
-
-Node *actions= 0;
-Node *rules= 0;
-Node *thisRule= 0;
-Node *start= 0;
-
-FILE *output= 0;
-
-int actionCount= 0;
-int ruleCount= 0;
-int lastToken= -1;
-
-static inline Node *_newNode(int type, int size)
-{
-  Node *node= calloc(1, size);
-  node->type= type;
-  return node;
-}
-
-#define newNode(T)	_newNode(T, sizeof(struct T))
-
-Node *makeRule(char *name)
-{
-  Node *node= newNode(Rule);
-  node->rule.name= strdup(name);
-  node->rule.id= ++ruleCount;
-  node->rule.flags= 0;
-  node->rule.next= rules;
-  rules= node;
-  return node;
-}
-
-Node *findRule(char *name)
-{
-  Node *n;
-  char *ptr;
-  for (ptr= name;  *ptr;  ptr++) if ('-' == *ptr) *ptr= '_';
-  for (n= rules;  n;  n= n->any.next)
-    {
-      assert(Rule == n->type);
-      if (!strcmp(name, n->rule.name))
-	return n;
-    }
-  return makeRule(name);
-}
-
-Node *beginRule(Node *rule)
-{
-  actionCount= 0;
-  return thisRule= rule;
-}
-
-void Rule_setExpression(Node *node, Node *expression)
-{
-  assert(node);
-#ifdef DEBUG
-  Node_print(node);  fprintf(stderr, " [%d]<- ", node->type);  Node_print(expression);  fprintf(stderr, "\n");
-#endif
-  assert(Rule == node->type);
-  node->rule.expression= expression;
-  if (!start || !strcmp(node->rule.name, "start"))
-    start= node;
-}
-
-Node *makeVariable(char *name)
-{
-  Node *node;
-  assert(thisRule);
-  for (node= thisRule->rule.variables;  node;  node= node->variable.next)
-    if (!strcmp(name, node->variable.name))
-      return node;
-  node= newNode(Variable);
-  node->variable.name= strdup(name);
-  node->variable.next= thisRule->rule.variables;
-  thisRule->rule.variables= node;
-  return node;
-}
-
-Node *makeName(Node *rule)
-{
-  Node *node= newNode(Name);
-  node->name.rule= rule;
-  node->name.variable= 0;
-  rule->rule.flags |= RuleUsed;
-  return node;
-}
-
-Node *makeDot(void)
-{
-  return newNode(Dot);
-}
-
-Node *makeCharacter(char *text)
-{
-  Node *node= newNode(Character);
-  node->character.value= strdup(text);
-  return node;
-}
-
-Node *makeString(char *text)
-{
-  Node *node= newNode(String);
-  node->string.value= strdup(text);
-  return node;
-}
-
-Node *makeClass(char *text)
-{
-  Node *node= newNode(Class);
-  node->cclass.value= (unsigned char *)strdup(text);
-  return node;
-}
-
-Node *makeAction(char *text)
-{
-  Node *node= newNode(Action);
-  char name[1024];
-  assert(thisRule);
-  sprintf(name, "_%d_%s", ++actionCount, thisRule->rule.name);
-  node->action.name= strdup(name);
-  node->action.text= strdup(text);
-  node->action.list= actions;
-  node->action.rule= thisRule;
-  actions= node;
-  {
-    char *ptr;
-    for (ptr= node->action.text;  *ptr;  ++ptr)
-      if ('$' == ptr[0] && '$' == ptr[1])
-	ptr[1]= ptr[0]= 'y';
-  }
-  return node;
-}
-
-Node *makePredicate(char *text)
-{
-  Node *node= newNode(Predicate);
-  node->predicate.text= strdup(text);
-  return node;
-}
-
-Node *makeAlternate(Node *e)
-{
-  if (Alternate != e->type)
-    {
-      Node *node= newNode(Alternate);
-      assert(e);
-      assert(!e->any.next);
-      node->alternate.first=
-	node->alternate.last= e;
-      return node;
-    }
-  return e;
-}
-
-Node *Alternate_append(Node *a, Node *e)
-{
-  assert(a);
-  a= makeAlternate(a);
-  assert(a->alternate.last);
-  assert(e);
-  a->alternate.last->any.next= e;
-  a->alternate.last= e;
-  return a;
-}
-
-Node *makeSequence(Node *e)
-{
-  if (Sequence != e->type)
-    {
-      Node *node= newNode(Sequence);
-      assert(e);
-      assert(!e->any.next);
-      node->sequence.first=
-	node->sequence.last= e;
-      return node;
-    }
-  return e;
-}
-
-Node *Sequence_append(Node *a, Node *e)
-{
-  assert(a);
-  a= makeSequence(a);
-  assert(a->sequence.last);
-  assert(e);
-  a->sequence.last->any.next= e;
-  a->sequence.last= e;
-  return a;
-}
-
-Node *makePeekFor(Node *e)
-{
-  Node *node= newNode(PeekFor);
-  node->peekFor.element= e;
-  return node;
-}
-
-Node *makePeekNot(Node *e)
-{
-  Node *node= newNode(PeekNot);
-  node->peekNot.element= e;
-  return node;
-}
-
-Node *makeQuery(Node *e)
-{
-  Node *node= newNode(Query);
-  node->query.element= e;
-  return node;
-}
-
-Node *makeStar(Node *e)
-{
-  Node *node= newNode(Star);
-  node->star.element= e;
-  return node;
-}
-
-Node *makePlus(Node *e)
-{
-  Node *node= newNode(Plus);
-  node->plus.element= e;
-  return node;
-}
-
-
-static Node  *stack[1024];
-static Node **stackPointer= stack;
-
-
-#ifdef DEBUG
-static void dumpStack(void)
-{
-  Node **p;
-  for (p= stack + 1;  p <= stackPointer;  ++p)
-    {
-      fprintf(stderr, "### %d\t", p - stack);
-      Node_print(*p);
-      fprintf(stderr, "\n");
-    }
-}
-#endif
-
-Node *push(Node *node)
-{
-  assert(node);
-  assert(stackPointer < stack + 1023);
-#ifdef DEBUG
-  dumpStack();  fprintf(stderr, " PUSH ");  Node_print(node);  fprintf(stderr, "\n");
-#endif
-  return *++stackPointer= node;
-}
-
-Node *top(void)
-{
-  assert(stackPointer > stack);
-  return *stackPointer;
-}
-
-Node *pop(void)
-{
-  assert(stackPointer > stack);
-#ifdef DEBUG
-  dumpStack();  fprintf(stderr, " POP\n");
-#endif
-  return *stackPointer--;
-}
-
-
-static void Node_fprint(FILE *stream, Node *node)
-{
-  assert(node);
-  switch (node->type)
-    {
-    case Rule:		fprintf(stream, " %s", node->rule.name);				break;
-    case Name:		fprintf(stream, " %s", node->name.rule->rule.name);			break;
-    case Dot:		fprintf(stream, " .");							break;
-    case Character:	fprintf(stream, " '%s'", node->character.value);			break;
-    case String:	fprintf(stream, " \"%s\"", node->string.value);				break;
-    case Class:		fprintf(stream, " [%s]", node->cclass.value);				break;
-    case Action:	fprintf(stream, " { %s }", node->action.text);				break;
-    case Predicate:	fprintf(stream, " ?{ %s }", node->action.text);				break;
-
-    case Alternate:	node= node->alternate.first;
-			fprintf(stream, " (");
-			Node_fprint(stream, node);
-			while ((node= node->any.next))
-			  {
-			    fprintf(stream, " |");
-			    Node_fprint(stream, node);
-			  }
-			fprintf(stream, " )");
-			break;
-
-    case Sequence:	node= node->sequence.first;
-			fprintf(stream, " (");
-			Node_fprint(stream, node);
-			while ((node= node->any.next))
-			  Node_fprint(stream, node);
-			fprintf(stream, " )");
-			break;
-
-    case PeekFor:	fprintf(stream, "&");  Node_fprint(stream, node->query.element);	break;
-    case PeekNot:	fprintf(stream, "!");  Node_fprint(stream, node->query.element);	break;
-    case Query:		Node_fprint(stream, node->query.element);  fprintf(stream, "?");	break;
-    case Star:		Node_fprint(stream, node->query.element);  fprintf(stream, "*");	break;
-    case Plus:		Node_fprint(stream, node->query.element);  fprintf(stream, "+");	break;
-    default:
-      fprintf(stream, "\nunknown node type %d\n", node->type);
-      exit(1);
-    }
-}
-
-void Node_print(Node *node)	{ Node_fprint(stderr, node); }
-
-static void Rule_fprint(FILE *stream, Node *node)
-{
-  assert(node);
-  assert(Rule == node->type);
-  fprintf(stream, "%s.%d =", node->rule.name, node->rule.id);
-  if (node->rule.expression)
-    Node_fprint(stream, node->rule.expression);
-  else
-    fprintf(stream, " UNDEFINED");
-  fprintf(stream, " ;\n");
-}
-
-void Rule_print(Node *node)	{ Rule_fprint(stderr, node); }
--- a/tree.h
+++ /dev/null
@@ -1,108 +1,0 @@
-/* Copyright (c) 2007 by Ian Piumarta
- * All rights reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the 'Software'),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, provided that the above copyright notice(s) and this
- * permission notice appear in all copies of the Software.  Acknowledgement
- * of the use of this Software in supporting documentation would be
- * appreciated but is not required.
- * 
- * THE SOFTWARE IS PROVIDED 'AS IS'.  USE ENTIRELY AT YOUR OWN RISK.
- * 
- * Last edited: 2007-05-15 10:32:05 by piumarta on emilia
- */
-
-#include <stdio.h>
-
-enum { Unknown= 0, Rule, Variable, Name, Dot, Character, String, Class, Action, Predicate, Alternate, Sequence, PeekFor, PeekNot, Query, Star, Plus };
-
-enum {
-  RuleUsed	= 1<<0,
-  RuleReached	= 1<<1,
-};
-
-typedef union Node Node;
-
-struct Rule	 { int type;  Node *next;   char *name;	 Node *variables;  Node *expression;  int id;  int flags;	};
-struct Variable	 { int type;  Node *next;   char *name;  Node *value;  int offset;					};
-struct Name	 { int type;  Node *next;   Node *rule;  Node *variable;						};
-struct Dot	 { int type;  Node *next;										};
-struct Character { int type;  Node *next;   char *value;								};
-struct String	 { int type;  Node *next;   char *value;								};
-struct Class	 { int type;  Node *next;   unsigned char *value;							};
-struct Action	 { int type;  Node *next;   char *text;	  Node *list;  char *name;  Node *rule;				};
-struct Predicate { int type;  Node *next;   char *text;									};
-struct Alternate { int type;  Node *next;   Node *first;  Node *last;							};
-struct Sequence	 { int type;  Node *next;   Node *first;  Node *last;							};
-struct PeekFor	 { int type;  Node *next;   Node *element;								};
-struct PeekNot	 { int type;  Node *next;   Node *element;								};
-struct Query	 { int type;  Node *next;   Node *element;								};
-struct Star	 { int type;  Node *next;   Node *element;								};
-struct Plus	 { int type;  Node *next;   Node *element;								};
-struct Any	 { int type;  Node *next;										};
-
-union Node
-{
-  int			type;
-  struct Rule		rule;
-  struct Variable	variable;
-  struct Name		name;
-  struct Dot		dot;
-  struct Character	character;
-  struct String		string;
-  struct Class		cclass;
-  struct Action		action;
-  struct Predicate	predicate;
-  struct Alternate	alternate;
-  struct Sequence	sequence;
-  struct PeekFor	peekFor;
-  struct PeekNot	peekNot;
-  struct Query		query;
-  struct Star		star;
-  struct Plus		plus;
-  struct Any		any;
-};
-
-extern Node *actions;
-extern Node *rules;
-extern Node *start;
-
-extern int   ruleCount;
-
-extern FILE *output;
-
-extern Node *makeRule(char *name);
-extern Node *findRule(char *name);
-extern Node *beginRule(Node *rule);
-extern void  Rule_setExpression(Node *rule, Node *expression);
-extern Node *Rule_beToken(Node *rule);
-extern Node *makeVariable(char *name);
-extern Node *makeName(Node *rule);
-extern Node *makeDot(void);
-extern Node *makeCharacter(char *text);
-extern Node *makeString(char *text);
-extern Node *makeClass(char *text);
-extern Node *makeAction(char *text);
-extern Node *makePredicate(char *text);
-extern Node *makeAlternate(Node *e);
-extern Node *Alternate_append(Node *e, Node *f);
-extern Node *makeSequence(Node *e);
-extern Node *Sequence_append(Node *e, Node *f);
-extern Node *makePeekFor(Node *e);
-extern Node *makePeekNot(Node *e);
-extern Node *makeQuery(Node *e);
-extern Node *makeStar(Node *e);
-extern Node *makePlus(Node *e);
-extern Node *push(Node *node);
-extern Node *top(void);
-extern Node *pop(void);
-
-extern void  Rule_compile_c_header(void);
-extern void  Rule_compile_c(Node *node);
-
-extern void  Node_print(Node *node);
-extern void  Rule_print(Node *node);
--- a/version.h
+++ /dev/null
@@ -1,3 +1,0 @@
-#define PEG_MAJOR	0
-#define PEG_MINOR	1
-#define PEG_LEVEL	9
--- /dev/null
+++ b/win/getopt.c
@@ -1,0 +1,230 @@
+/*
+ *  pgetopt.c - Portable implementation of getopt() command line args parser, 
+ *              originally made available by IBM and the authors listed below.
+ *     
+ *  Created on 8/8/08.
+ *  Portions of this document are Copyright (C) 2008, PlexFX, 
+ *											               All Rights Reserved.
+ *
+ *  History: 
+ *  Original Date Unknown
+ *              This code is quite old, but it was originally called GETOPT.C 
+ *              in the comments, along with a GETOPT.H thin header, and used the 
+ *              same namespace as the getopt() implementation on my UNIX variant 
+ *              platforms.  The original date has been lost.  It may date back 
+ *              to even pre-ANSI C.  The development team at PlexFX has been 
+ *              using it (primarily for Windows command line tools, but also on
+ *              other platforms for many years.  A search for historical dates
+ *              via web search engines found it widely used, but no date stamps
+ *              on its original form seem to have been preserved.
+ *              It can be found in various forms in open source packages, such 
+ *              as using a search engine on one or both of the author strings 
+ *              shown in the original comment block below.  For example, as of 
+ *              the creation date on this file, a slightly modified verion of 
+ *              it was used in library code found in the CVS tree for 
+ *              OpenSolaris.
+ *
+ *              It was also included on at least some of the MSDN Library discs
+ *              Around the early 2001-2003 time frame.
+ *
+ *  2008-08-08  This version is a modified version of the original IBM code, but
+ *              the filename and namespace used has been altered along with some
+ *              calling convention changes.  As such, it can be used as a drop-
+ *              in replacement for getopt() even on UNIX or Linux systems that 
+ *              have their own getopt() implementations in libc without naming
+ *              collisions.  This means it can be used portably on any OS with
+ *              a conforming C compiler.  It does *not* attempt to implement the
+ *              more long-winded getopt_long() interface.  Naming of APIs, 
+ *              headers and the optarg/optind externs have been prefixed with
+ *              'p' to accomplish this.  Examples: pgetopt(), poptarg, poptind,
+ *              pgetopt.c, pgetopt.h.
+ *              Note: This interface keeps external state (to match original
+ *                    calling conventions).  As such, it is not thread safe,
+ *                    and should be called in only one thread (use from main()
+ *							 before additional threads are started).  As the command
+ *                    line should never change, this should not be an issue.
+ *
+ */
+
+/* Original IBM "AS IS" license follows */
+
+/*****************************************************************************
+ *
+ *  MODULE NAME : GETOPT.C
+ *
+ *  COPYRIGHTS:
+ *             This module contains code made available by IBM
+ *             Corporation on an AS IS basis.  Any one receiving the
+ *             module is considered to be licensed under IBM copyrights
+ *             to use the IBM-provided source code in any way he or she
+ *             deems fit, including copying it, compiling it, modifying
+ *             it, and redistributing it, with or without
+ *             modifications.  No license under any IBM patents or
+ *             patent applications is to be implied from this copyright
+ *             license.
+ *
+ *             A user of the module should understand that IBM cannot
+ *             provide technical support for the module and will not be
+ *             responsible for any consequences of use of the program.
+ *
+ *             Any notices, including this one, are not to be removed
+ *             from the module without the prior written consent of
+ *             IBM.
+ *
+ *  AUTHOR:   Original author:
+ *                 G. R. Blair (BOBBLAIR at AUSVM1)
+ *                 Internet: bobblair@bobblair.austin.ibm.com
+ *
+ *            Extensively revised by:
+ *                 John Q. Walker II, Ph.D. (JOHHQ at RALVM6)
+ *                 Internet: johnq@ralvm6.vnet.ibm.com
+ *
+ *****************************************************************************/
+
+/******************************************************************************
+ * pgetopt()
+ *
+ * The pgetopt() function is a command line parser.  It returns the next
+ * option character in argv that matches an option character in optstring.
+ *
+ * The argv argument points to an array of argc+1 elements containing argc
+ * pointers to character strings followed by a null pointer.
+ *
+ * The optstring argument points to a string of option characters; if an
+ * option character is followed by a colon, the option is expected to have
+ * an argument that may or may not be separated from it by white space.
+ * The external variable poptarg is set to point to the start of the option
+ * argument on return from pgetopt().
+ *
+ * The pgetopt() function places in poptind the argv index of the next argument
+ * to be processed.  The system initializes the external variable poptind to
+ * 1 before the first call to pgetopt().
+ *
+ * When all options have been processed (that is, up to the first nonoption
+ * argument), pgetopt() returns EOF.  The special option "--" may be used to
+ * delimit the end of the options; EOF will be returned, and "--" will be
+ * skipped.
+ *
+ * The pgetopt() function returns a question mark (?) when it encounters an
+ * option character not included in optstring.  This error message can be
+ * disabled by setting popterr to zero.  Otherwise, it returns the option
+ * character that was detected.
+ *
+ * If the special option "--" is detected, or all options have been
+ * processed, EOF is returned.
+ *
+ * Options are marked by either a minus sign (-) or a slash (/).
+ *
+ * No other errors are defined.
+ *****************************************************************************/
+
+#include <stdio.h>                  /* for EOF */
+#include <string.h>                 /* for strchr() */
+#include "getopt.h"						/* getopt() interface and example code */
+
+/* global variables that are specified as exported by getopt() */
+char *optarg = NULL;    /* pointer to the start of the option argument  */
+int   optind = 1;       /* number of the next argv[] to be evaluated    */
+int   opterr = 1;       /* non-zero if a question mark should be returned
+                          * when a non-valid option character is detected */
+
+/* handle possible future character set concerns by putting this in a macro */
+#define _next_char(string)  (char)(*(string+1))
+
+int 
+getopt(int argc, char *argv[], char *optstring)
+{
+	static char *IndexPosition = NULL; /* place inside current argv string */
+	char *ArgString = NULL;        /* where to start from next */
+	char *OptString;               /* the string in our program */
+	
+	
+   if (IndexPosition != NULL) {
+		/* we last left off inside an argv string */
+		if (*(++IndexPosition)) {
+			/* there is more to come in the most recent argv */
+			ArgString = IndexPosition;
+		}
+	}
+	
+	if (ArgString == NULL) {
+		/* we didn't leave off in the middle of an argv string */
+		if (optind >= argc) {
+			/* more command-line arguments than the argument count */
+			IndexPosition = NULL;  /* not in the middle of anything */
+			return EOF;             /* used up all command-line arguments */
+		}
+		
+		/*---------------------------------------------------------------------
+		 * If the next argv[] is not an option, there can be no more options.
+		 *-------------------------------------------------------------------*/
+		ArgString = argv[optind++]; /* set this to the next argument ptr */
+		
+		if (('/' != *ArgString) && /* doesn't start with a slash or a dash? */
+			 ('-' != *ArgString)) {
+			--optind;               /* point to current arg once we're done */
+			optarg = NULL;          /* no argument follows the option */
+			IndexPosition = NULL;  /* not in the middle of anything */
+			return EOF;             /* used up all the command-line flags */
+		}
+		
+		/* check for special end-of-flags markers */
+		if ((strcmp(ArgString, "-") == 0) ||
+			 (strcmp(ArgString, "--") == 0)) {
+			optarg = NULL;          /* no argument follows the option */
+			IndexPosition = NULL;  /* not in the middle of anything */
+			return EOF;             /* encountered the special flag */
+		}
+		
+		ArgString++;               /* look past the / or - */
+	}
+	
+	if (':' == *ArgString) {       /* is it a colon? */
+		/*---------------------------------------------------------------------
+		 * Rare case: if opterr is non-zero, return a question mark;
+		 * otherwise, just return the colon we're on.
+		 *-------------------------------------------------------------------*/
+		return (opterr ? (int)'?' : (int)':');
+	}
+	else if ((OptString = strchr(optstring, *ArgString)) == 0) {
+		/*---------------------------------------------------------------------
+		 * The letter on the command-line wasn't any good.
+		 *-------------------------------------------------------------------*/
+		optarg = NULL;              /* no argument follows the option */
+		IndexPosition = NULL;      /* not in the middle of anything */
+		return (opterr ? (int)'?' : (int)*ArgString);
+	}
+	else {
+		/*---------------------------------------------------------------------
+		 * The letter on the command-line matches one we expect to see
+		 *-------------------------------------------------------------------*/
+		if (':' == _next_char(OptString)) { /* is the next letter a colon? */
+			/* It is a colon.  Look for an argument string. */
+			if ('\0' != _next_char(ArgString)) {  /* argument in this argv? */
+				optarg = &ArgString[1];   /* Yes, it is */
+			}
+			else {
+				/*-------------------------------------------------------------
+				 * The argument string must be in the next argv.
+				 * But, what if there is none (bad input from the user)?
+				 * In that case, return the letter, and optarg as NULL.
+				 *-----------------------------------------------------------*/
+				if (optind < argc)
+					optarg = argv[optind++];
+				else {
+					optarg = NULL;
+					return (opterr ? (int)'?' : (int)*ArgString);
+				}
+			}
+			IndexPosition = NULL;  /* not in the middle of anything */
+		}
+		else {
+			/* it's not a colon, so just return the letter */
+			optarg = NULL;          /* no argument follows the option */
+			IndexPosition = ArgString;    /* point to the letter we're on */
+		}
+		return (int)*ArgString;    /* return the letter that matched */
+	}
+}
+
+
--- /dev/null
+++ b/win/getopt.h
@@ -1,0 +1,134 @@
+/*
+ *  pgetopt.h - Portable implementation of getopt() command line args parser, 
+ *              originally made available by IBM and the authors listed below.
+ *     
+ *  Created on 8/8/08.
+ *  Portions of this document are Copyright (C) 2008, PlexFX, 
+ *											               All Rights Reserved.
+ *
+ *  History: 
+ *  Original Date Unknown
+ *              This code is quite old, but it was originally called GETOPT.H 
+ *              in the comments, along with a GETOPT.C source file, and used the 
+ *              same namespace as the getopt() implementation on my UNIX variant 
+ *              platforms.  The original date has been lost.  It may date back 
+ *              to even pre-ANSI C.  The development team at PlexFX has been 
+ *              using it (primarily for Windows command line tools, but also on
+ *              other platforms for many years.  A search for historical dates
+ *              via web search engines found it widely used, but no date stamps
+ *              on its original form seem to have been preserved.
+ *              It can be found in various forms in open source packages, such 
+ *              as using a search engine on one or both of the author strings 
+ *              shown in the original comment block below.  For example, as of 
+ *              the creation date on this file, a slightly modified verion of 
+ *              it was used in library code found in the CVS tree for 
+ *              OpenSolaris.
+ *
+ *              It was also included on at least some of the MSDN Library discs
+ *              Around the early 2001-2003 time frame.
+ *
+ *  2008-08-08  This version is a modified version of the original IBM code, but
+ *              the filename and namespace used has been altered along with some
+ *              calling convention changes.  As such, it can be used as a drop-
+ *              in replacement for getopt() even on UNIX or Linux systems that 
+ *              have their own getopt() implementations in libc without naming
+ *              collisions.  This means it can be used portably on any OS with
+ *              a conforming C compiler.  It does *not* attempt to implement the
+ *              more long-winded getopt_long() interface.  Naming of APIs, 
+ *              headers and the optarg/optind externs have been prefixed with
+ *              'p' to accomplish this.  Examples: pgetopt(), poptarg, poptind,
+ *              pgetopt.c, pgetopt.h.  Also added some comments to clarify usage
+ *              for the popterr extern.
+ *              Note: This interface keeps external state (to match original
+ *                    calling conventions).  As such, it is not thread safe,
+ *                    and should be called in only one thread (use from main()
+ *							 before additional threads are started).  As the command
+ *                    line should never change, this should not be an issue.
+ *
+ */
+
+/* Original IBM "AS IS" license follows */
+
+/*****************************************************************************
+ *
+ *  MODULE NAME : GETOPT.H
+ *
+ *  COPYRIGHTS:
+ *             This module contains code made available by IBM
+ *             Corporation on an AS IS basis.  Any one receiving the
+ *             module is considered to be licensed under IBM copyrights
+ *             to use the IBM-provided source code in any way he or she
+ *             deems fit, including copying it, compiling it, modifying
+ *             it, and redistributing it, with or without
+ *             modifications.  No license under any IBM patents or
+ *             patent applications is to be implied from this copyright
+ *             license.
+ *
+ *             A user of the module should understand that IBM cannot
+ *             provide technical support for the module and will not be
+ *             responsible for any consequences of use of the program.
+ *
+ *             Any notices, including this one, are not to be removed
+ *             from the module without the prior written consent of
+ *             IBM.
+ *
+ *  AUTHOR:   Original author:
+ *                 G. R. Blair (BOBBLAIR at AUSVM1)
+ *                 Internet: bobblair@bobblair.austin.ibm.com
+ *
+ *            Extensively revised by:
+ *                 John Q. Walker II, Ph.D. (JOHHQ at RALVM6)
+ *                 Internet: johnq@ralvm6.vnet.ibm.com
+ *
+ *****************************************************************************/
+
+#ifndef H_GETOPT
+#define H_GETOPT 1
+
+extern char * optarg;  /* carries the optional argument when a command line
+                         * arg is specified with a ':' after it in the optstring
+                         * and is usually handled by the caller in a switch()
+                         * block. */
+extern int    optind;	/* The caller should not need to adjust this normally */
+extern int    opterr;  /* The getopt() function returns a question mark (?) 
+                         * when it encounters an option character not included in 
+								 * optstring.  This error message can be disabled by 
+                         * setting opterr to zero.  Otherwise, it returns the 
+                         * option character that was detected. */
+
+int getopt(int argc, char *argv[], char *optstring);
+
+/* Example code by PlexFX to demonstrate calling of and parsing optional extra
+ * args.  This is a sample code fragment, untested, minimal or non-existent 
+ * error handling, and some headers variable declarations are omitted.
+ */
+
+#if 0 /* remove, for example purposes only */
+
+/* Note the ':' shown below in the pattern string, to specify additional arg */
+char opt_pattern[] = "s:V?";
+
+while ((c = getopt(argc, argv, opt_pattern)) != -1) 
+{
+	switch(c) 
+	{
+      case 's':      /* specify a /s option with a numeric size parameter 
+							 * which is provided in optarg, a char *
+		                * Example: $ someprogram /s 100
+		                */
+			
+			some_size = atoi(optarg);   /* should use strtol() in new code */
+         break;
+		case 'V':		/* specify a /V version option, with no parameter */
+			puts("someprogram: Version 1.0");
+			break;
+		case '?':		/* explicit allows of -? or /? */
+		default:			/* and give usage any time invalid arguments are given */
+			PrintUsage();						/* call some function to show usage */
+			break;
+	}
+}
+#endif /* 0 */
+
+#endif /* ! H_GETOPT */
+
--- /dev/null
+++ b/win/libgen.h
@@ -1,0 +1,9 @@
+#ifndef _LIBGEN_H
+#define _LIBGEN_H
+
+char * basename (char *fname)
+{
+  return fname;
+}
+
+#endif // _LIBGEN_H
--- /dev/null
+++ b/win/unistd.h
@@ -1,0 +1,6 @@
+#ifndef _UNISTD_H
+#define _UNISTD_H
+
+#include "getopt.h"
+
+#endif // _UNISTD_H