home: hub: minipeg

Download patch

ref: 74b7881f93ea9d2df51931debba10770b7fa9cbc
parent: bc90c2ec4f3d8b0480c4cdb38e11dca49812fe1d
author: Gregory Pakosz <gregory.pakosz@gmail.com>
date: Thu Sep 8 12:55:19 CDT 2016

imported peg-0.1.18

--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2016-07-22  Ian Piumarta  <com -dot- gmail -at- piumarta (backwards)>
+
+	* src/version.h (PEG_LEVEL): Version 0.1.18.
+	* src/tree.h: Rule_compile_c takes nolines argument for option -P.
+	* src/compile.c, src/peg.c, src/leg.leg (main): Add option -P.
+	Generate #line directives for all actions.
+	* src/peg.1: Document option -P.
+
 2016-07-14  Ian Piumarta  <com -dot- gmail -at- piumarta (backwards)>
 
 	* src/version.h: 0.1.17
--- a/README.md
+++ b/README.md
@@ -26,6 +26,9 @@
 
 ## Version history
 
+* **0.1.18** ([zip](../../archive/0.1.18.zip), [tar.gz](../../archive/0.1.18.tar.gz)) &mdash; 2016-07-22  
+Add `-P` option to disable `#line` directives.  
+Emit `#line` directives for all actions.  
 * **0.1.17** ([zip](../../archive/0.1.17.zip), [tar.gz](../../archive/0.1.17.tar.gz)) &mdash; 2016-07-14  
 Emit `#line` directives for header and trailer in the generated source file.
 * **0.1.16** ([zip](../../archive/0.1.16.zip), [tar.gz](../../archive/0.1.16.tar.gz)) &mdash; 2016-06-25  
--- a/src/compile.c
+++ b/src/compile.c
@@ -13,7 +13,7 @@
  * 
  * THE SOFTWARE IS PROVIDED 'AS IS'.  USE ENTIRELY AT YOUR OWN RISK.
  * 
- * Last edited: 2016-02-19 11:08:58 by piumarta on zora
+ * Last edited: 2016-07-22 09:43:05 by piumarta on zora.local
  */
 
 #include <stdio.h>
@@ -800,7 +800,7 @@
 }
 
 
-void Rule_compile_c(Node *node)
+void Rule_compile_c(Node *node, int nolines)
 {
   Node *n;
 
@@ -817,6 +817,8 @@
       defineVariables(n->action.rule->rule.variables);
       fprintf(output, "  yyprintf((stderr, \"do yy%s\\n\"));\n", n->action.name);
       fprintf(output, "  {\n");
+      if (!nolines)
+	fprintf(output, "#line %i\n", n->action.line);
       fprintf(output, "  %s;\n", n->action.text);
       fprintf(output, "  }\n");
       undefineVariables(n->action.rule->rule.variables);
--- a/src/leg.c
+++ b/src/leg.c
@@ -1,4 +1,4 @@
-/* A recursive-descent parser generated by peg 0.1.17 */
+/* A recursive-descent parser generated by peg 0.1.18 */
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -27,9 +27,11 @@
   FILE *input= 0;
 
   int   verboseFlag= 0;
+  int   nolinesFlag= 0;
 
   static int	 lineNumber= 0;
   static int	 headerLine= 0;
+  static int	 actionLine= 0;
   static char	*fileName= 0;
   static int	 trailerLine= 0;
   static char	*trailer= 0;
@@ -365,6 +367,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_1_end_of_line\n"));
   {
+#line 160
    ++lineNumber ;
   }
 #undef yythunkpos
@@ -371,6 +374,20 @@
 #undef yypos
 #undef yy
 }
+YY_ACTION(void) yy_1_action(yycontext *yy, char *yytext, int yyleng)
+{
+#define __ yy->__
+#define yypos yy->__pos
+#define yythunkpos yy->__thunkpos
+  yyprintf((stderr, "do yy_1_action\n"));
+  {
+#line 133
+   actionLine= lineNumber ;
+  }
+#undef yythunkpos
+#undef yypos
+#undef yy
+}
 YY_ACTION(void) yy_9_primary(yycontext *yy, char *yytext, int yyleng)
 {
 #define __ yy->__
@@ -378,6 +395,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_9_primary\n"));
   {
+#line 113
    push(makePredicate("YY_END")); ;
   }
 #undef yythunkpos
@@ -391,6 +409,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_8_primary\n"));
   {
+#line 112
    push(makePredicate("YY_BEGIN")); ;
   }
 #undef yythunkpos
@@ -404,7 +423,8 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_7_primary\n"));
   {
-   push(makeAction(yytext)); ;
+#line 111
+   push(makeAction(actionLine, yytext)); ;
   }
 #undef yythunkpos
 #undef yypos
@@ -417,6 +437,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_6_primary\n"));
   {
+#line 110
    push(makeDot()); ;
   }
 #undef yythunkpos
@@ -430,6 +451,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_5_primary\n"));
   {
+#line 109
    push(makeClass(yytext)); ;
   }
 #undef yythunkpos
@@ -443,6 +465,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_4_primary\n"));
   {
+#line 108
    push(makeString(yytext)); ;
   }
 #undef yythunkpos
@@ -456,6 +479,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_3_primary\n"));
   {
+#line 106
    push(makeName(findRule(yytext))); ;
   }
 #undef yythunkpos
@@ -469,6 +493,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_2_primary\n"));
   {
+#line 105
    Node *name= makeName(findRule(yytext));  name->name.variable= pop();  push(name); ;
   }
 #undef yythunkpos
@@ -482,6 +507,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_1_primary\n"));
   {
+#line 104
    push(makeVariable(yytext)); ;
   }
 #undef yythunkpos
@@ -495,6 +521,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_3_suffix\n"));
   {
+#line 101
    push(makePlus (pop())); ;
   }
 #undef yythunkpos
@@ -508,6 +535,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_2_suffix\n"));
   {
+#line 100
    push(makeStar (pop())); ;
   }
 #undef yythunkpos
@@ -521,6 +549,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_1_suffix\n"));
   {
+#line 99
    push(makeQuery(pop())); ;
   }
 #undef yythunkpos
@@ -534,6 +563,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_4_prefix\n"));
   {
+#line 96
    push(makePeekNot(pop())); ;
   }
 #undef yythunkpos
@@ -547,6 +577,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_3_prefix\n"));
   {
+#line 95
    push(makePeekFor(pop())); ;
   }
 #undef yythunkpos
@@ -560,6 +591,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_2_prefix\n"));
   {
+#line 94
    push(makePredicate(yytext)); ;
   }
 #undef yythunkpos
@@ -573,6 +605,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_1_prefix\n"));
   {
+#line 93
    push(makeInline(yytext)); ;
   }
 #undef yythunkpos
@@ -586,6 +619,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_1_error\n"));
   {
+#line 90
    push(makeError(pop(), yytext)); ;
   }
 #undef yythunkpos
@@ -599,6 +633,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_1_sequence\n"));
   {
+#line 87
    Node *f= pop();  push(Sequence_append(pop(), f)); ;
   }
 #undef yythunkpos
@@ -612,6 +647,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_1_expression\n"));
   {
+#line 84
    Node *f= pop();  push(Alternate_append(pop(), f)); ;
   }
 #undef yythunkpos
@@ -625,6 +661,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_2_definition\n"));
   {
+#line 81
    Node *e= pop();  Rule_setExpression(pop(), e); ;
   }
 #undef yythunkpos
@@ -638,6 +675,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_1_definition\n"));
   {
+#line 79
    if (push(beginRule(findRule(yytext)))->rule.expression)
 							    fprintf(stderr, "rule '%s' redefined\n", yytext); ;
   }
@@ -652,6 +690,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_2_trailer\n"));
   {
+#line 77
    makeTrailer(headerLine, yytext); ;
   }
 #undef yythunkpos
@@ -665,6 +704,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_1_trailer\n"));
   {
+#line 76
    headerLine= lineNumber ;
   }
 #undef yythunkpos
@@ -678,6 +718,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_2_declaration\n"));
   {
+#line 74
    makeHeader(headerLine, yytext); ;
   }
 #undef yythunkpos
@@ -691,6 +732,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_1_declaration\n"));
   {
+#line 72
    headerLine= lineNumber; ;
   }
 #undef yythunkpos
@@ -1022,7 +1064,7 @@
 }
 YY_RULE(int) yy_action(yycontext *yy)
 {  int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos;
-  yyprintf((stderr, "%s\n", "action"));  if (!yymatchChar(yy, '{')) goto l73;  yyText(yy, yy->__begin, yy->__end);  {
+  yyprintf((stderr, "%s\n", "action"));  if (!yymatchChar(yy, '{')) goto l73;  yyDo(yy, yy_1_action, yy->__begin, yy->__end);  yyText(yy, yy->__begin, yy->__end);  {
 #define yytext yy->__text
 #define yyleng yy->__textlen
 if (!(YY_BEGIN)) goto l73;
@@ -1353,7 +1395,7 @@
 }
 
 #endif
-#line 160 "src/leg.leg"
+#line 163 "src/leg.leg"
 
 
 void yyerror(char *message)
@@ -1408,6 +1450,7 @@
   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, "  -P          do not generate #line directives\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");
@@ -1425,7 +1468,7 @@
   lineNumber= 1;
   fileName= "<stdin>";
 
-  while (-1 != (c= getopt(argc, argv, "Vho:v")))
+  while (-1 != (c= getopt(argc, argv, "PVho:v")))
     {
       switch (c)
 	{
@@ -1445,6 +1488,10 @@
 	    }
 	  break;
 
+	case 'P':
+	  nolinesFlag= 1;
+	  break;
+
 	case 'v':
 	  verboseFlag= 1;
 	  break;
@@ -1496,10 +1543,13 @@
     fprintf(output, "#line %i \"%s\"\n%s\n", headers->line, fileName, headers->text);
 
   if (rules)
-    Rule_compile_c(rules);
+    Rule_compile_c(rules, nolinesFlag);
 
-  if (trailer)
-    fprintf(output, "#line %i \"%s\"\n%s\n", trailerLine, fileName, trailer);
+  if (trailer) {
+    if (!nolinesFlag)
+      fprintf(output, "#line %i \"%s\"\n", trailerLine, fileName, trailer);
+    fprintf(output, "%s\n", trailer);
+  }
 
   return 0;
 }
--- a/src/leg.leg
+++ b/src/leg.leg
@@ -15,7 +15,7 @@
 # 
 # THE SOFTWARE IS PROVIDED 'AS IS'.  USE ENTIRELY AT YOUR OWN RISK.
 # 
-# Last edited: 2016-07-14 20:26:22 by piumarta on zora
+# Last edited: 2016-07-22 09:45:53 by piumarta on zora.local
 
 %{
 # include "tree.h"
@@ -39,9 +39,11 @@
   FILE *input= 0;
 
   int   verboseFlag= 0;
+  int   nolinesFlag= 0;
 
   static int	 lineNumber= 0;
   static int	 headerLine= 0;
+  static int	 actionLine= 0;
   static char	*fileName= 0;
   static int	 trailerLine= 0;
   static char	*trailer= 0;
@@ -106,7 +108,7 @@
 |		literal					{ push(makeString(yytext)); }
 |		class					{ push(makeClass(yytext)); }
 |		DOT					{ push(makeDot()); }
-|		action					{ push(makeAction(yytext)); }
+|		action					{ push(makeAction(actionLine, yytext)); }
 |		BEGIN					{ push(makePredicate("YY_BEGIN")); }
 |		END					{ push(makePredicate("YY_END")); }
 
@@ -128,7 +130,8 @@
 |		'\\' [0-7][0-7]?
 |		!'\\' .
 
-action=		'{' < braces* > '}' -
+action=		'{'					{ actionLine= lineNumber }
+		< braces* > '}' -
 
 braces=		'{' braces* '}'
 |		!'}' ( end-of-line | . )
@@ -211,6 +214,7 @@
   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, "  -P          do not generate #line directives\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");
@@ -228,7 +232,7 @@
   lineNumber= 1;
   fileName= "<stdin>";
 
-  while (-1 != (c= getopt(argc, argv, "Vho:v")))
+  while (-1 != (c= getopt(argc, argv, "PVho:v")))
     {
       switch (c)
 	{
@@ -248,6 +252,10 @@
 	    }
 	  break;
 
+	case 'P':
+	  nolinesFlag= 1;
+	  break;
+
 	case 'v':
 	  verboseFlag= 1;
 	  break;
@@ -299,10 +307,13 @@
     fprintf(output, "#line %i \"%s\"\n%s\n", headers->line, fileName, headers->text);
 
   if (rules)
-    Rule_compile_c(rules);
+    Rule_compile_c(rules, nolinesFlag);
 
-  if (trailer)
-    fprintf(output, "#line %i \"%s\"\n%s\n", trailerLine, fileName, trailer);
+  if (trailer) {
+    if (!nolinesFlag)
+      fprintf(output, "#line %i \"%s\"\n", trailerLine, fileName, trailer);
+    fprintf(output, "%s\n", trailer);
+  }
 
   return 0;
 }
--- a/src/peg.1
+++ b/src/peg.1
@@ -13,7 +13,7 @@
 .\" 
 .\" THE SOFTWARE IS PROVIDED 'AS IS'.  USE ENTIRELY AT YOUR OWN RISK.
 .\" 
-.\" Last edited: 2016-06-25 12:38:49 by piumarta on gentoo64.piumarta.com
+.\" Last edited: 2016-07-22 09:47:29 by piumarta on zora.local
 .\"
 .TH PEG 1 "September 2013" "Version 0.1"
 .SH NAME
@@ -82,7 +82,7 @@
 for example.)
 .SH OPTIONS
 .I peg
-and 
+and
 .I leg
 provide the following options:
 .TP
@@ -93,6 +93,9 @@
 writes the generated parser to the file
 .B output
 instead of the standard output.
+.TP
+.B \-P
+suppresses #line directives in the output.
 .TP
 .B \-v
 writes verbose information to standard error while working.
--- a/src/peg.c
+++ b/src/peg.c
@@ -13,7 +13,7 @@
  * 
  * THE SOFTWARE IS PROVIDED 'AS IS'.  USE ENTIRELY AT YOUR OWN RISK.
  * 
- * Last edited: 2012-05-16 08:55:38 by piumarta on emilia
+ * Last edited: 2016-07-22 09:45:47 by piumarta on zora.local
  */
 
 #include "tree.h"
@@ -29,6 +29,7 @@
 FILE *input= 0;
 
 int   verboseFlag= 0;
+int   nolinesFlag= 0;
 
 static int   lineNumber= 0;
 static char *fileName= 0;
@@ -84,6 +85,7 @@
   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, "  -P          do not generate #line directives\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");
@@ -101,7 +103,7 @@
   lineNumber= 1;
   fileName= "<stdin>";
 
-  while (-1 != (c= getopt(argc, argv, "Vho:v")))
+  while (-1 != (c= getopt(argc, argv, "PVho:v")))
     {
       switch (c)
 	{
@@ -121,6 +123,10 @@
 	    }
 	  break;
 
+	case 'P':
+	  nolinesFlag= 1;
+	  break;
+
 	case 'v':
 	  verboseFlag= 1;
 	  break;
@@ -167,7 +173,7 @@
       Rule_print(n);
 
   Rule_compile_c_header();
-  if (rules) Rule_compile_c(rules);
+  if (rules) Rule_compile_c(rules, nolinesFlag);
 
   return 0;
 }
--- a/src/peg.peg
+++ b/src/peg.peg
@@ -12,7 +12,7 @@
 #     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
+# Last edited: 2016-07-15 10:27:27 by piumarta on zora
 
 # Hierarchical syntax
 
@@ -38,7 +38,7 @@
 		 / Literal			{ push(makeString(yytext)); }
 		 / Class			{ push(makeClass(yytext)); }
 		 / DOT				{ push(makeDot()); }
-		 / Action			{ push(makeAction(yytext)); }		#ikp added
+		 / Action			{ push(makeAction(0, yytext)); }	#ikp added
 		 / BEGIN			{ push(makePredicate("YY_BEGIN")); }	#ikp added
 		 / END				{ push(makePredicate("YY_END")); }	#ikp added
 
--- a/src/peg.peg-c
+++ b/src/peg.peg-c
@@ -1,4 +1,4 @@
-/* A recursive-descent parser generated by peg 0.1.17 */
+/* A recursive-descent parser generated by peg 0.1.18 */
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -312,6 +312,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_7_Primary\n"));
   {
+#line 0
    push(makePredicate("YY_END")); ;
   }
 #undef yythunkpos
@@ -325,6 +326,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_6_Primary\n"));
   {
+#line 0
    push(makePredicate("YY_BEGIN")); ;
   }
 #undef yythunkpos
@@ -338,7 +340,8 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_5_Primary\n"));
   {
-   push(makeAction(yytext)); ;
+#line 0
+   push(makeAction(0, yytext)); ;
   }
 #undef yythunkpos
 #undef yypos
@@ -351,6 +354,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_4_Primary\n"));
   {
+#line 0
    push(makeDot()); ;
   }
 #undef yythunkpos
@@ -364,6 +368,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_3_Primary\n"));
   {
+#line 0
    push(makeClass(yytext)); ;
   }
 #undef yythunkpos
@@ -377,6 +382,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_2_Primary\n"));
   {
+#line 0
    push(makeString(yytext)); ;
   }
 #undef yythunkpos
@@ -390,6 +396,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_1_Primary\n"));
   {
+#line 0
    push(makeName(findRule(yytext))); ;
   }
 #undef yythunkpos
@@ -403,6 +410,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_3_Suffix\n"));
   {
+#line 0
    push(makePlus (pop())); ;
   }
 #undef yythunkpos
@@ -416,6 +424,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_2_Suffix\n"));
   {
+#line 0
    push(makeStar (pop())); ;
   }
 #undef yythunkpos
@@ -429,6 +438,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_1_Suffix\n"));
   {
+#line 0
    push(makeQuery(pop())); ;
   }
 #undef yythunkpos
@@ -442,6 +452,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_3_Prefix\n"));
   {
+#line 0
    push(makePeekNot(pop())); ;
   }
 #undef yythunkpos
@@ -455,6 +466,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_2_Prefix\n"));
   {
+#line 0
    push(makePeekFor(pop())); ;
   }
 #undef yythunkpos
@@ -468,6 +480,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_1_Prefix\n"));
   {
+#line 0
    push(makePredicate(yytext)); ;
   }
 #undef yythunkpos
@@ -481,6 +494,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_2_Sequence\n"));
   {
+#line 0
    push(makePredicate("1")); ;
   }
 #undef yythunkpos
@@ -494,6 +508,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_1_Sequence\n"));
   {
+#line 0
    Node *f= pop();  push(Sequence_append(pop(), f)); ;
   }
 #undef yythunkpos
@@ -507,6 +522,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_1_Expression\n"));
   {
+#line 0
    Node *f= pop();  push(Alternate_append(pop(), f)); ;
   }
 #undef yythunkpos
@@ -520,6 +536,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_2_Definition\n"));
   {
+#line 0
    Node *e= pop();  Rule_setExpression(pop(), e); ;
   }
 #undef yythunkpos
@@ -533,6 +550,7 @@
 #define yythunkpos yy->__thunkpos
   yyprintf((stderr, "do yy_1_Definition\n"));
   {
+#line 0
    if (push(beginRule(findRule(yytext)))->rule.expression) fprintf(stderr, "rule '%s' redefined\n", yytext); ;
   }
 #undef yythunkpos
--- a/src/tree.c
+++ b/src/tree.c
@@ -13,7 +13,7 @@
  * 
  * THE SOFTWARE IS PROVIDED 'AS IS'.  USE ENTIRELY AT YOUR OWN RISK.
  * 
- * Last edited: 2016-02-19 11:21:30 by piumarta on zora
+ * Last edited: 2016-07-15 10:25:14 by piumarta on zora
  */
 
 #include <stdio.h>
@@ -140,7 +140,7 @@
   return node;
 }
 
-Node *makeAction(char *text)
+Node *makeAction(int lineNumber, char *text)
 {
   Node *node= newNode(Action);
   char name[1024];
@@ -150,6 +150,7 @@
   node->action.text= strdup(text);
   node->action.list= actions;
   node->action.rule= thisRule;
+  node->action.line= lineNumber;
   actions= node;
   {
     char *ptr;
--- a/src/tree.h
+++ b/src/tree.h
@@ -13,7 +13,7 @@
  * 
  * THE SOFTWARE IS PROVIDED 'AS IS'.  USE ENTIRELY AT YOUR OWN RISK.
  * 
- * Last edited: 2016-02-19 11:06:20 by piumarta on zora
+ * Last edited: 2016-07-22 09:42:48 by piumarta on zora.local
  */
 
 #include <stdio.h>
@@ -34,7 +34,7 @@
 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 Action	 { int type;  Node *next;   char *text;	  Node *list;  char *name;  Node *rule;  int line;		};
 struct Inline    { int type;  Node *next;   char *text;									};
 struct Predicate { int type;  Node *next;   char *text;									};
 struct Error	 { int type;  Node *next;   Node *element;  char *text;							};
@@ -90,7 +90,7 @@
 extern Node *makeCharacter(char *text);
 extern Node *makeString(char *text);
 extern Node *makeClass(char *text);
-extern Node *makeAction(char *text);
+extern Node *makeAction(int lineNumber, char *text);
 extern Node *makeInline(char *text);
 extern Node *makePredicate(char *text);
 extern Node *makeError(Node *e, char *text);
@@ -108,7 +108,7 @@
 extern Node *pop(void);
 
 extern void  Rule_compile_c_header(void);
-extern void  Rule_compile_c(Node *node);
+extern void  Rule_compile_c(Node *node, int nolines);
 
 extern void  Node_print(Node *node);
 extern void  Rule_print(Node *node);
--- a/src/version.h
+++ b/src/version.h
@@ -1,3 +1,3 @@
 #define PEG_MAJOR	0
 #define PEG_MINOR	1
-#define PEG_LEVEL	17
+#define PEG_LEVEL	18