home: hub: minipeg

Download patch

ref: 9705641244292ed97ef7802438a4fce6bdc75579
parent: 2b4ce69b3848fcf79ebb03306a671eba7cf911a5
author: Andrew Chambers <ac@acha.ninja>
date: Thu Apr 7 21:09:08 CDT 2022

Rename extension from .leg to .peg.

--- a/Makefile
+++ b/Makefile
@@ -28,10 +28,10 @@
 minipeg.c: $(SRC) amalgamate.sh
 	sh amalgamate.sh $(SRC) > $@
 
-peg-new.c: peg.leg minipeg
+peg-new.c: peg.peg minipeg
 	./minipeg -o $@ $<
 
-peg-split.c: peg.leg minipeg-split
+peg-split.c: peg.peg minipeg-split
 	./minipeg-split -o $@ $<
 
 # The checked in peg.c matches the built peg-new.c.
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -1,4 +1,4 @@
-EXAMPLES = test rule accept wc dc dcv calc basic localpeg localleg erract
+EXAMPLES = test rule accept wc dc dcv calc basic local erract
 
 CFLAGS = -g -Wall -O3
 
--- a/peg.c
+++ b/peg.c
@@ -4,7 +4,7 @@
 #include <stdlib.h>
 #include <string.h>
 #define YYRULECOUNT 39
-#line 20 "peg.leg"
+#line 20 "peg.peg"
 
 #include "tree.h"
 #include "version.h"
@@ -1395,7 +1395,7 @@
 }
 
 #endif
-#line 163 "peg.leg"
+#line 163 "peg.peg"
 
 
 void yyerror(char *message)
--- a/peg.leg
+++ /dev/null
@@ -1,319 +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: 2016-07-22 09:45:53 by piumarta on zora.local
-
-%{
-#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 {
-    int	    line;
-    char   *text;
-    Header *next;
-  };
-
-  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;
-  static Header	*headers= 0;
-
-  void makeHeader(int line, char *text);
-  void makeTrailer(int line, 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=	'%{'					{ headerLine= lineNumber; }
-		< ( !'%}' (end-of-line | .) )* >
-		RPERCENT				{ makeHeader(headerLine, yytext); }				#{YYACCEPT}
-
-trailer=	'%%'					{ headerLine= lineNumber }
-		< .* >					{ makeTrailer(headerLine, 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=		AT  action				{ push(makeInline(yytext)); }
-|		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(actionLine, 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'"\[\]\\]
-|		'\\' 'x'[0-9A-Fa-f][0-9A-Fa-f]
-|		'\\' 'x'[0-9A-Fa-f]
-|		'\\' [0-3][0-7][0-7]
-|		'\\' [0-7][0-7]?
-|		!'\\' .
-
-action=		'{'					{ actionLine= lineNumber }
-		< braces* > '}' -
-
-braces=		'{' braces* '}'
-|		!'}' ( end-of-line | . )
-
-EQUAL=		'=' -
-COLON=		':' -
-SEMICOLON=	';' -
-BAR=		'|' -
-AND=		'&' -
-NOT=		'!' -
-AT=		'@' -
-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' )		{ ++lineNumber }
-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(int line, char *text)
-{
-  Header *header= (Header *)malloc(sizeof(Header));
-  header->line= line;
-  header->text= strdup(text);
-  header->next= headers;
-  headers= header;
-}
-
-void makeTrailer(int line, char *text)
-{
-  trailerLine= line;
-  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, "  -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");
-  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, "PVho: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 'P':
-	  nolinesFlag= 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, "#line %i \"%s\"\n%s\n", headers->line, fileName, headers->text);
-
-  if (rules)
-    Rule_compile_c(rules, nolinesFlag);
-
-  if (trailer) {
-    if (!nolinesFlag)
-      fprintf(output, "#line %i \"%s\"\n", trailerLine, fileName, trailer);
-    fprintf(output, "%s\n", trailer);
-  }
-
-  return 0;
-}
--- /dev/null
+++ b/peg.peg
@@ -1,0 +1,319 @@
+# 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: 2016-07-22 09:45:53 by piumarta on zora.local
+
+%{
+#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 {
+    int	    line;
+    char   *text;
+    Header *next;
+  };
+
+  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;
+  static Header	*headers= 0;
+
+  void makeHeader(int line, char *text);
+  void makeTrailer(int line, 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=	'%{'					{ headerLine= lineNumber; }
+		< ( !'%}' (end-of-line | .) )* >
+		RPERCENT				{ makeHeader(headerLine, yytext); }				#{YYACCEPT}
+
+trailer=	'%%'					{ headerLine= lineNumber }
+		< .* >					{ makeTrailer(headerLine, 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=		AT  action				{ push(makeInline(yytext)); }
+|		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(actionLine, 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'"\[\]\\]
+|		'\\' 'x'[0-9A-Fa-f][0-9A-Fa-f]
+|		'\\' 'x'[0-9A-Fa-f]
+|		'\\' [0-3][0-7][0-7]
+|		'\\' [0-7][0-7]?
+|		!'\\' .
+
+action=		'{'					{ actionLine= lineNumber }
+		< braces* > '}' -
+
+braces=		'{' braces* '}'
+|		!'}' ( end-of-line | . )
+
+EQUAL=		'=' -
+COLON=		':' -
+SEMICOLON=	';' -
+BAR=		'|' -
+AND=		'&' -
+NOT=		'!' -
+AT=		'@' -
+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' )		{ ++lineNumber }
+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(int line, char *text)
+{
+  Header *header= (Header *)malloc(sizeof(Header));
+  header->line= line;
+  header->text= strdup(text);
+  header->next= headers;
+  headers= header;
+}
+
+void makeTrailer(int line, char *text)
+{
+  trailerLine= line;
+  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, "  -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");
+  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, "PVho: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 'P':
+	  nolinesFlag= 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, "#line %i \"%s\"\n%s\n", headers->line, fileName, headers->text);
+
+  if (rules)
+    Rule_compile_c(rules, nolinesFlag);
+
+  if (trailer) {
+    if (!nolinesFlag)
+      fprintf(output, "#line %i \"%s\"\n", trailerLine, fileName, trailer);
+    fprintf(output, "%s\n", trailer);
+  }
+
+  return 0;
+}