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;
+}