Subversion Repositories PlanixRsrch.SVN

Compare Revisions

Ignore whitespace Rev 253 → Rev 254

/tags/mgen-0.0.1/mgen_print_symlist.c
File deleted
/tags/mgen-0.0.1/algol60.bnf
File deleted
/tags/mgen-0.0.1/mgen_getc.c
File deleted
/tags/mgen-0.0.1/mgen.h
File deleted
/tags/mgen-0.0.1/mgen_ungetc.c
File deleted
/tags/mgen-0.0.1/my.prg
File deleted
/tags/mgen-0.0.1/Makefile
File deleted
/tags/mgen-0.0.1/LICENSE
File deleted
/tags/mgen-0.0.1/algol60.txt
File deleted
/tags/mgen-0.0.1/bnf.c
File deleted
/tags/mgen-0.0.1/mgen_open.c
File deleted
/tags/mgen-0.0.1/my.bnf
File deleted
/tags/mgen-0.0.1/mgen_print_rhs_list.c
File deleted
/tags/mgen-0.0.1/mgen_run.c
File deleted
/tags/mgen-0.0.1/mgen_skip_spaces.c
File deleted
/tags/mgen-0.0.1/mgen_create_rule_set.c
File deleted
/tags/mgen-0.0.1/algol60.raw
File deleted
/tags/mgen-0.0.1/mi.prg
File deleted
/tags/mgen-0.0.1/mipascal.bnf
File deleted
/tags/mgen-0.0.1/README
File deleted
/tags/mgen-0.0.1/example.bnf
File deleted
/tags/mgen-0.0.1/mgen_perror.c
File deleted
/tags/mgen-0.0.1/mgen_parse.c
File deleted
/tags/mgen-0.0.1/mgen_read_rule_set.c
File deleted
/tags/mgen-0.0.1
Property changes:
Deleted: svn:mergeinfo
## -0,2 +0,0 ##
Reverse-merged /branches/bnf/bnf_cleanup:r123-126
Reverse-merged /branches/bnf/mgen:r129-142
Index: mgen/0.0.1/LICENSE
===================================================================
--- mgen/0.0.1/LICENSE (nonexistent)
+++ mgen/0.0.1/LICENSE (revision 254)
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2019,2020, The PLANIX Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
Index: mgen/0.0.1/Makefile
===================================================================
--- mgen/0.0.1/Makefile (nonexistent)
+++ mgen/0.0.1/Makefile (revision 254)
@@ -0,0 +1,23 @@
+
+
+OBJS=bnf.o mgen_getc.o mgen_run.o mgen_open.o mgen_ungetc.o \
+ mgen_skip_spaces.o \
+ mgen_perror.o \
+ mgen_read_rule_set.o \
+ mgen_create_rule_set.o \
+ mgen_print_symlist.o \
+ mgen_print_rhs_list.o \
+ mgen_parse.o
+
+PRG=bnf
+
+.c.o:
+ $(CC) -c $(CFLAGS) $<
+
+$(PRG): $(OBJS)
+ $(CC) $(LDFLAGS) -o $(PRG) $(OBJS) -lmavl
+
+clean:
+ rm -f *.o
+ rm -f $(PRG)
+ rm -f *.core
Index: mgen/0.0.1/README
===================================================================
--- mgen/0.0.1/README (nonexistent)
+++ mgen/0.0.1/README (revision 254)
@@ -0,0 +1 @@
+A simple *true* BNF-Parser in pure ANSI C 89
Index: mgen/0.0.1/algol60.bnf
===================================================================
--- mgen/0.0.1/algol60.bnf (nonexistent)
+++ mgen/0.0.1/algol60.bnf (revision 254)
@@ -0,0 +1,5 @@
+<program> ::= <block> | <compound statement>
+<block> ::= <unlabelled block> | <label>: <block>
+<unlabelled block> ::= <block head> ; <compound tail>
+<block head> ::= begin <declaration> | <block head> ; <declaration>
+<compound statement> ::= <unlabelled compound> | <label>: <compound statement>
Index: mgen/0.0.1/algol60.raw
===================================================================
--- mgen/0.0.1/algol60.raw (nonexistent)
+++ mgen/0.0.1/algol60.raw (revision 254)
@@ -0,0 +1,7 @@
+:
+<program> ::= <block> | <compound statement><block> ::= <unlabelled block> | <label>: <block>
+<unlabelled block> ::= <block head> ;
+<compound tail><block head> ::= begin <declaration> | <block head> ; <declaration>
+<compound statement> ::= <unlabelled compound> | <label>: <compound statement><unlabelled compound> ::= begin <compound tail><compound tail> ::= <statement> end | <statement> ; <compound tail><declaration> ::= <type declaration> | <array declaration> | <switch declaration> | <procedure declaration><type declaration> ::= <local or own type> <type list><local or own type> ::= <type> | own <type><type> ::= real | integer | boolean<type list> ::= <simple variable> | <simple variable> , <type list><array declaration> ::= array <array list> | <local or own type> array <array list><array list> ::= <array segment> | <array list> , <array segment><array segment> ::= <array identifier> [ <bound pair list> ] | <array identifier> , <array segment><array identifier> ::= <identifier><bound pair list> ::= <bound pair> | <bound pair list> , <bound pair><bound pair> ::= <lower bound> : <upper bound><upper bound> ::= <arithmetic expression><lower bound> ::= <arithmetic expression><switch declaration> ::= switch <switch identifier> := <switch list><switch identifier> ::= <identifier><switch list> ::= <designational expression> | <switch list> , <designational expression><procedure declaration> ::= procedure <procedure heading> <procedure body> | <type> procedure <procedure heading> <procedure body><procedure heading> ::= <procedure identifier> <formal parameter part> ; <value part> <specification part><procedure identifier> ::= <identifier><formal parameter part> ::= <empty> | ( <formal parameter list> )<formal parameter list> ::= <formal parameter> | <formal parameter list> <parameter delimiter> <formal parameter><formal parameter> ::= <identifier> <value part> ::= value <identifier list> ; | <empty><specification part> ::= <empty> | <specifier> <identifier list> ; | <specification part> <specifier> <identifier list><specifier> ::= string | <type> | array | <type> array | label | switch | procedure | <type> procedure<identifier list> ::= <identifier> | <identifier list> , <identifier><procedure body> ::= <statement> | <code><statement> ::= <unconditional statement> | <conditional statement> | <for statement><unconditional statement> ::= <basic statement> | <compound statement> | <block><basic statement> ::= <unlabelled basic statement> | <label>: <basic statement><label> ::= <identifier> | <unsigned integer><unlabelled basic statement> ::= <assignment statement> | <go to statement> | <dummy statement> | <procedure statement><assignment statement> ::= <left part list> <arithmetic expression> | <left part list> <Boolean expression><left part list> ::= <left part> | <left part list> <left part><left part> ::= <variable> := | <procedure identifier> :=<go to statement> ::= goto <designational expression><designational expression> ::= <simple designational expression> |<if clause> <simple designational expression> else <designational expression><simple designational expression> ::= <label> | <switch designator> | (<designational expression>)<switch designator> ::= <switch identifier> [<subscript expression>]<dummy statement> ::= <empty><procedure statement> ::= <procedure identifier> <actual parameter part><actual parameter part> ::= <empty> | ( <actual parameter list> )<actual parameter list> ::= <actual parameter> | <actual parameter list> <parameter delimiter> <actual parameter><parameter delimiter> ::= , | ) <letter string> : (<actual parameter> ::= <string> | <expression> | <array identifier> | <switch identifier> | <procedure identifier><conditional statement> ::= <if statement> | <if statement> else <statement> | <if clause> <for statement> | <label>: <conditional statement><if statement> ::= <if clause> <unconditional statement><if clause> ::= if <Boolean expression> then<for statement> ::= <for clause> <statement> | <label>: <for statement><for clause> ::= for <variable> := <for list> do<for list> ::= <for list element> | <for list> , <for list element><for list element> ::= <arithmetic expression> |<arithmetic expression> step <arithmetic expression> until <arithmetic expression> |<arithmetic expression> while <Boolean expression><expression> ::= <arithmetic expression> | <Boolean expression> | <designational expression><arithmetic expression> ::= <simple arithmetic expression> | <if clause> <simple arithmetic expression> else <arithmetic expression><simple arithmetic expression> ::= <term> | <adding operator> <term> | <simple arithmetic expression> <adding operator> <term><adding operator> ::= + | –<term> ::= <factor> | <term> <multiplying operator> <factor><multiplying operator> ::= × | / | ÷<factor> ::= <primary> | <factor> | <factor> ↑ <primary><primary> ::= <unsigned number> | <variable> | <function designator> | ( <arithmetic expression> )<unsigned number> ::= <decimal number> | <exponential part> | <decimal number> <exponential part>
+<decimal number> ::= <unsigned integer> | <decimal fraction> | <unsigned integer> <decimal fraction><unsigned integer> ::= <digit> | <unsigned integer> <digit><decimal fraction> ::= . <unsigned integer><exponential part> ::= 10 <integer><integer> ::= <unsigned integer> | + <unsigned integer> | – <unsigned integer><Boolean expression> ::= <simple Boolean> | <if clause> <simple Boolean> else <Boolean expression><simple Boolean> ::= <implication> | <simple Boolean> ≣ <implication><implication> ::= <Boolean term> | <implication> ⊃ <Boolean term><Boolean term> ::= <Boolean factor> | <Boolean term> ⋁ <Boolean factor><Boolean factor> ::= <Boolean secondary> | <Boolean factor> ⋀ <Boolean secondary><Boolean secondary> ::= <Boolean primary> | ¬ <Boolean primary><Boolean primary> ::= <logical value> | <variable> | <function designator> | <relation> | ( <Boolean expression> )<relation> ::= <simple arithmetic expression> <relational operator> <simple arithmetic expression><relational operator> ::= < | ≤ | = | ≠ | > | ≥<function designator> ::= <procedure identifier> <actual parameter part><variable> ::= <simple variable> | <subscripted variable><simple variable> ::= <variable identifier><variable identifier> ::= <identifier><subscripted variable> ::= <array identifier> [ <subscript list> ]<subscript list> ::= <subscript expression> | <subscript list> , <subscript expression><subscript expression> ::= <arithmetic expression><string> ::= "<open string>"<open string> ::= <proper string> "<open string>" | <open string><open string><proper string> ::= <any sequence of symbols not containing " > | <empty><letter string> ::= <letter> | <letter string> <letter><identifier> ::= letter> | <identifier> <letter> | <identifier> <digit><basic symbol> ::= <letter> | <digit> | <logical value> | <delimiter><letter> ::= a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z |A |B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z<digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 <logical value> ::= true | false<delimiter> ::= <operator> | <separator> | <bracket> | <declarator> | <specificator><operator> ::= <arithmetic operator> | <relational operator> | <logical operator> | <sequential operator><arithmetic operator> ::= + | – | × | / | ÷ | ↑<relational operator> ::= < | ≤ | = | ≠ | > | ≥<logical operator> ::= ≣ | ⊃ | ⋁ | ⋀ | ¬<sequential operator> ::= goto | if | then | else | for | do<separator> ::= , | . | 10 | : | ; | := | _ | step | until | while | comment<bracket> ::= ( | ) | [ | ] | ` | ' | begin | end<declarator> ::= own | boolean | integer | real | array | switch | procedure<specificator> ::= string | label | value
+
Index: mgen/0.0.1/algol60.txt
===================================================================
--- mgen/0.0.1/algol60.txt (nonexistent)
+++ mgen/0.0.1/algol60.txt (revision 254)
@@ -0,0 +1,110 @@
+
+<program> ::= <block> | <compound statement>
+<block> ::= <unlabelled block> | <label>: <block>
+<unlabelled block> ::= <block head> ;
+<compound tail>
+<block head> ::= begin <declaration> | <block head> ; <declaration>
+<compound statement> ::= <unlabelled compound> | <label>: <compound statement>
+<unlabelled compound> ::= begin <compound tail>
+<compound tail> ::= <statement> end | <statement> ;
+<compound tail>
+<declaration> ::=
+ <type declaration> | <array declaration> | <switch declaration> | <procedure declaration>
+
+<type declaration> ::= <local or own type>
+<type list>
+<local or own type> ::= <type> | own
+<type>
+<type> ::= real | integer | boolean
+<type list> ::= <simple variable> | <simple variable> , <type list>
+<array declaration> ::= array <array list> | <local or own type> array <array list>
+<array list> ::= <array segment> | <array list> , <array segment>
+<array segment> ::= <array identifier> [ <bound pair list> ] | <array identifier> , <array segment>
+<array identifier> ::= <identifier>
+<bound pair list> ::= <bound pair> | <bound pair list> , <bound pair>
+<bound pair> ::= <lower bound> : <upper bound>
+<upper bound> ::= <arithmetic expression>
+<lower bound> ::= <arithmetic expression>
+<switch declaration> ::= switch <switch identifier> := <switch list>
+<switch identifier> ::= <identifier>
+<switch list> ::= <designational expression> | <switch list> , <designational expression>
+<procedure declaration> ::= procedure <procedure heading> <procedure body> | <type> procedure <procedure heading> <procedure body>
+<procedure heading> ::= <procedure identifier> <formal parameter part> ; <value part> <specification part>
+<procedure identifier> ::= <identifier>
+<formal parameter part> ::= <empty> | ( <formal parameter list> )
+<formal parameter list> ::= <formal parameter> | <formal parameter list> <parameter delimiter> <formal parameter>
+<formal parameter> ::= <identifier> <value part> ::= value <identifier list> ; | <empty>
+<specification part> ::= <empty> | <specifier> <identifier list> ; | <specification part> <specifier> <identifier list>
+<specifier> ::= string | <type> | array | <type> array | label | switch | procedure | <type> procedure<identifier list> ::= <identifier> | <identifier list> , <identifier>
+<procedure body> ::= <statement> | <code>
+<statement> ::= <unconditional statement> | <conditional statement> | <for statement>
+<unconditional statement> ::= <basic statement> | <compound statement> | <block>
+<basic statement> ::= <unlabelled basic statement> | <label>: <basic statement>
+<label> ::= <identifier> | <unsigned integer>
+<unlabelled basic statement> ::= <assignment statement> | <go to statement> | <dummy statement> | <procedure statement>
+<assignment statement> ::= <left part list> <arithmetic expression> | <left part list> <Boolean expression>
+<left part list> ::= <left part> | <left part list> <left part>
+<left part> ::= <variable> := | <procedure identifier> :=<go to statement> ::= goto <designational expression>
+<designational expression> ::= <simple designational expression> |<if clause> <simple designational expression> else <designational expression>
+<simple designational expression> ::= <label> | <switch designator> | (<designational expression>)
+<switch designator> ::= <switch identifier> [<subscript expression>]
+<dummy statement> ::= <empty>
+<procedure statement> ::= <procedure identifier> <actual parameter part>
+<actual parameter part> ::= <empty> | ( <actual parameter list> )
+<actual parameter list> ::= <actual parameter> | <actual parameter list> <parameter delimiter> <actual parameter>
+
+<parameter delimiter> ::= , | ) <letter string> : (
+<actual parameter> ::= <string> | <expression> | <array identifier> | <switch identifier> | <procedure identifier>
+
+<conditional statement> ::= <if statement> | <if statement> else <statement> |
+ <if clause> <for statement> | <label>: <conditional statement>
+
+<if statement> ::= <if clause> <unconditional statement>
+<if clause> ::= if <Boolean expression> then<for statement> ::= <for clause> <statement> | <label>: <for statement>
+<for clause> ::= for <variable> := <for list> do<for list> ::= <for list element> | <for list> , <for list element>
+<for list element> ::= <arithmetic expression> |<arithmetic expression> step <arithmetic expression> until <arithmetic expression> |<arithmetic expression> while <Boolean expression>
+<expression> ::= <arithmetic expression> | <Boolean expression> | <designational expression>
+<arithmetic expression> ::= <simple arithmetic expression> | <if clause> <simple arithmetic expression> else <arithmetic expression>
+<simple arithmetic expression> ::= <term> | <adding operator> <term> | <simple arithmetic expression> <adding operator> <term>
+<adding operator> ::= + | –<term> ::= <factor> | <term> <multiplying operator> <factor>
+<multiplying operator> ::= × | / | ÷<factor> ::= <primary> | <factor> | <factor> ↑ <primary>
+<primary> ::= <unsigned number> | <variable> | <function designator> | ( <arithmetic expression> )<unsigned number> ::= <decimal number> | <exponential part> | <decimal number> <exponential part>
+<decimal number> ::= <unsigned integer> | <decimal fraction> | <unsigned integer> <decimal fraction>
+<unsigned integer> ::= <digit> | <unsigned integer> <digit>
+<decimal fraction> ::= . <unsigned integer>
+<exponential part> ::= 10 <integer>
+<integer> ::= <unsigned integer> | + <unsigned integer> | – <unsigned integer>
+<Boolean expression> ::= <simple Boolean> | <if clause> <simple Boolean> else <Boolean expression>
+<simple Boolean> ::= <implication> | <simple Boolean> ≣ <implication>
+<implication> ::= <Boolean term> | <implication> ⊃ <Boolean term>
+<Boolean term> ::= <Boolean factor> | <Boolean term> ⋁ <Boolean factor>
+<Boolean factor> ::= <Boolean secondary> | <Boolean factor> ⋀ <Boolean secondary>
+<Boolean secondary> ::= <Boolean primary> | ¬ <Boolean primary>
+<Boolean primary> ::= <logical value> | <variable> | <function designator> | <relation> | ( <Boolean expression> )<relation> ::= <simple arithmetic expression> <relational operator> <simple arithmetic expression>
+<relational operator> ::= < | ≤ | = | ≠ | > | ≥<function designator> ::= <procedure identifier> <actual parameter part>
+<variable> ::= <simple variable> | <subscripted variable>
+<simple variable> ::= <variable identifier>
+<variable identifier> ::= <identifier>
+<subscripted variable> ::= <array identifier> [ <subscript list> ]<subscript list> ::= <subscript expression> | <subscript list> , <subscript expression>
+<subscript expression> ::= <arithmetic expression>
+<string> ::= "<open string>"
+<open string> ::= <proper string> "<open string>" | <open string>
+<open string>
+<proper string> ::= <any sequence of symbols not containing " > | <empty>
+<letter string> ::= <letter> | <letter string> <letter>
+<identifier> ::= letter> | <identifier> <letter> | <identifier> <digit>
+<basic symbol> ::= <letter> | <digit> | <logical value> | <delimiter>
+<letter> ::= a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z |A |B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
+<digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
+<logical value> ::= true | false
+<delimiter> ::= <operator> | <separator> | <bracket> | <declarator> | <specificator>
+<operator> ::= <arithmetic operator> | <relational operator> | <logical operator> | <sequential operator>
+<arithmetic operator> ::= + | – | × | / | ÷ | ↑
+<relational operator> ::= < | ≤ | = | ≠ | > | ≥
+<logical operator> ::= ≣ | ⊃ | ⋁ | ⋀ | ¬
+<sequential operator> ::= goto | if | then | else | for | do
+<separator> ::= , | . | 10 | : | ; | := | _ | step | until | while | comment
+<bracket> ::= ( | ) | [ | ] | ` | ' | begin | end
+<declarator> ::= own | boolean | integer | real | array | switch | procedure
+<specificator> ::= string | label | value
+
Index: mgen/0.0.1/bnf.c
===================================================================
--- mgen/0.0.1/bnf.c (nonexistent)
+++ mgen/0.0.1/bnf.c (revision 254)
@@ -0,0 +1,838 @@
+/*
+ * Copyright 2019, The PLANIX Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <libmavl/mavl.h>
+
+#define MAX_NONTERMINAL 1024
+#define MAX_TERMINAL 1024
+
+#include "mgen.h"
+
+const char * prgname;
+
+/*#define printf (void)printf*/
+
+struct prs {
+ FILE * infile;
+ int line;
+ int col;
+ int prev_col;
+ char * filename;
+ struct mavl *rules;
+ struct mgen_rule * current_rule;
+ struct rhs_elem * current_rhs_elem;
+ struct mgen_sym ** current_sym;
+};
+
+
+
+struct mgen_parser {
+ struct mavl * rules;
+ struct mgen_file * mf;
+ struct mgen_sym * stack[1000];
+ int stackptr;
+};
+
+
+void prgerr(char *text)
+{
+ (void)fprintf(stderr, "%s: error: %s: %s\n",
+ prgname,text,strerror(errno));
+}
+
+int get_char(struct prs * prs)
+{
+ int c;
+ c=fgetc(prs->infile);
+ switch(c) {
+ case '\n':
+ prs->line++;
+ prs->prev_col = prs->col;
+ prs->col=0;
+ break;
+ case '\t':
+ prs->col+=8;
+ break;
+ default:
+ prs->col++;
+ }
+ return c;
+}
+
+
+void
+unget_char(int c, struct prs * prs){
+ (void)ungetc(c,prs->infile);
+ switch(c) {
+ case '\n':
+ prs->line--;
+ prs->col=prs->prev_col;
+ break;
+ case '\t':
+ prs->col-=8;
+ break;
+ default:
+ prs->col--;
+ }
+
+}
+
+struct mgen_sym * append_sym(struct mgen_sym ** next, int type, char *name)
+{
+ struct mgen_sym * sym;
+ sym = malloc( sizeof( struct mgen_sym));
+ if (!sym){
+ prgerr("can't allocate memory");
+ return NULL;
+ }
+ sym->name = malloc( strlen(name)+1);
+ if (!sym->name){
+ prgerr("can't allocate memory");
+ return NULL;
+ }
+ (void)strcpy (sym->name,name);
+ sym->type=type;
+ sym->next=NULL;
+
+ *next = sym;
+ return sym;
+}
+
+struct rhs_elem *
+append_rhs_elem(struct rhs_elem ** next)
+{
+ while (*next!=NULL){
+ next = &((*next)->next);
+ }
+ *next = malloc(sizeof(struct rhs_elem));
+ if (!*next){
+ prgerr("can't allocate memory");
+ return NULL;
+ }
+ (*next)->sym_list=NULL;
+ (*next)->next=NULL;
+ return *next;
+}
+
+int
+skip_spaces(struct prs * prs )
+{
+ int c;
+ while (1) {
+ c=get_char(prs);
+ if ( mgen_isspace(c) ) {
+ continue;
+ }
+ break;
+ };
+ return c;
+}
+
+void
+err(struct prs * prs, char *str)
+{
+ if (prs->filename)
+ (void) fprintf(stderr, "\"%s\", line %d, col %d: error: %s\n",
+ prs->filename,
+ prs->line,
+ prs->col,
+ str
+ );
+ else
+ (void) fprintf(stderr,
+ "line %d, col %d: error: %s\n ",
+ prs->line,
+ prs->col,
+ str);
+}
+
+int
+get_non_terminal(struct prs * prs, char * result)
+{
+ int c;
+ int i;
+
+ c=EOF; /* this eliminates a compiler warning
+ about c may be used unassigned */
+
+ for (i=0; i<MAX_NONTERMINAL; i++){
+ c = get_char(prs);
+ if (c=='>')
+ break;
+ if (c=='\n' || c==EOF){
+ err (prs,"missing '>' at end of non-terminal");
+ return EOF;
+ }
+ result[i]=(char)c;
+ }
+
+ if (i==MAX_NONTERMINAL && c!='>'){
+ err(prs,"non-terminal symbol too long");
+ return EOF;
+ }
+ result[i]=0;
+
+ return c;
+}
+
+int
+get_terminal(struct prs * prs, char * result)
+{
+ int c;
+ int i;
+
+ c=EOF; /* this eliminates a compiler warning
+ about c may be used unassigned */
+
+ for (i=0; i<MAX_TERMINAL; i++){
+ c = get_char(prs);
+ if (c==' ' || c=='\n' || c=='|' || c=='\t' || c=='\r' || c==EOF)
+ break;
+ result[i]=(char)c;
+ }
+
+ if (i==MAX_TERMINAL ){
+ err(prs,"terminal symbol too long");
+ return EOF;
+ }
+ result[i]=0;
+
+ return c;
+}
+
+int
+skip_comment(struct prs * prs)
+{
+ int c;
+ do {
+ c=get_char(prs);
+ }while (c!='\n' && c!=EOF);
+ return c;
+}
+
+int get_left_hand_side(struct prs * prs)
+{
+ int c;
+ char result[MAX_NONTERMINAL+1];
+ struct mgen_rule rule;
+ int exists;
+
+ while(1) {
+ c = skip_spaces(prs);
+ if (c==EOF)
+ return EOF;
+ if (c=='#' && prs->col==1){
+ c=skip_comment(prs);
+ unget_char(c,prs);
+ continue;
+ }
+ break;
+ }
+
+
+ if (c != '<' ){
+ err(prs,"'<' expected.");
+ return EOF;
+ }
+ if (prs->col != 1){
+ err(prs,"left hand side of a rule has to start at column 1.");
+ return EOF;
+ }
+
+ c =get_non_terminal(prs, result);
+ if (c==EOF)
+ return EOF;
+
+ rule.name = malloc(strlen(result)+1);
+ if (!rule.name){
+ prgerr("can't allocate memory");
+ return EOF;
+ }
+ (void)strcpy(rule.name,result);
+ rule.rhs_list=0;
+ rule.line = prs->line;
+ rule.rhs_list = NULL;
+
+/* (void)printf("non-terminal found: %s\n",rule.name);*/
+
+ prs->current_rule =
+ mavl_insert(prs->rules, &rule, &exists);
+
+ if (!prs->current_rule){
+ prgerr("can't allocate memory\n");
+ return EOF;
+ }
+
+ if (exists){
+ char msg[MAX_NONTERMINAL+256];
+ (void)sprintf(msg,"symbol <%s> already defined.",result);
+ err(prs,msg);
+ return EOF;
+ }
+
+ prs->current_rhs_elem =append_rhs_elem(&(prs->current_rule->rhs_list));
+ if (!prs->current_rhs_elem)
+ return EOF;
+ prs->current_sym = &prs->current_rhs_elem->sym_list;
+ return 0;
+}
+
+int get_right_hand_side(struct prs *prs)
+{
+ int c;
+ struct mgen_sym * sym;
+
+ /* int nsyms;
+ * nsyms = 0;*/
+
+ do{
+ c = skip_spaces(prs);
+ switch (c) {
+ case '<': {
+ char result[MAX_NONTERMINAL+1];
+ if (prs->col <= 1){
+ unget_char(c,prs);
+ return c;
+ }
+
+ c = get_non_terminal(prs,result);
+ if (c==EOF)
+ return EOF;
+
+ sym=append_sym(prs->current_sym,MGEN_NT_SYM,result);
+ if (!sym)
+ return EOF;
+
+ prs->current_sym = &sym->next;
+ break;
+ }
+ case '|':
+ prs->current_rhs_elem =append_rhs_elem(&(prs->current_rule->rhs_list));
+ if (!prs->current_rhs_elem)
+ return EOF;
+ prs->current_sym = &prs->current_rhs_elem->sym_list;
+ break;
+
+ default:{
+ char result[MAX_TERMINAL+1];
+ unget_char(c,prs);
+ c=get_terminal(prs,result);
+
+ /*printf("append terminal '%s' to <%s>\n", result,(*prs->current_sym));*/
+ sym=append_sym(prs->current_sym,MGEN_T_SYM,result);
+ if (!sym)
+ return EOF;
+ unget_char(c,prs);
+ prs->current_sym = &sym->next;
+ }
+ }
+
+ }while (c!=EOF);
+
+ return EOF;
+}
+
+/*
+int mgen_skip(struct mgen_file *mf, char *chrlist)
+{
+ int c;
+ c=mgen_getc(mf);
+}
+*/
+
+int get_assignment (struct prs * prs)
+{
+ int c,i,n;
+ char * search = "::=";
+
+ c = skip_spaces(prs);
+
+ i=0; n=(int)strlen(search);
+ do {
+ if (c!=search[i]){
+ err(prs,"'::=' expected.");
+ return EOF;
+ }
+ i++;
+ c=getc(prs->infile);
+ }while(i<n);
+ return c;
+}
+
+static int
+cmp_nonterminal(const void *v1, const void *v2)
+{
+ const char *s1,*s2;
+ s1 = ((struct mgen_rule *)v1)->name;
+ s2 = ((struct mgen_rule *)v2)->name;
+
+ return strcmp(s1,s2);
+}
+
+
+void
+print(struct mavl *t)
+{
+ struct mavliter it;
+ void *data;
+
+ mavliter_init(&it, t);
+ (void)mavliter_seek_set(&it);
+
+ while ((data = mavliter_get(&it)) != NULL) {
+ struct mgen_rule * rule = (struct mgen_rule *)data;
+ struct rhs_elem *e;
+ struct mgen_sym *sym;
+ char * delim_or, *delim_spc;
+
+ delim_or="";
+
+ (void)printf("<%s> ::= ",rule->name);
+ e = rule->rhs_list;
+ while (e!=NULL){
+ sym = e->sym_list;
+ (void)printf("%s",delim_or);
+ delim_or="|";
+ delim_spc="";
+ while (sym!=NULL){
+ if (sym->type == MGEN_NT_SYM)
+ (void)printf("%s<%s>",delim_spc,sym->name);
+ else
+ (void)printf("%s%s",delim_spc,sym->name);
+ sym = sym->next;
+ delim_spc=" ";
+ }
+ e=e->next;
+ }
+ (void)printf("\n");
+
+
+ (void)mavliter_next(&it);
+ }
+}
+
+
+void
+verify(struct prs * prs)
+{
+ struct mavl *t;
+ struct mavliter it;
+ void *data;
+
+ t = prs->rules;
+
+ mavliter_init(&it, t);
+ (void)mavliter_seek_set(&it);
+
+ while ((data = mavliter_get(&it)) != NULL) {
+ struct mgen_rule * rule = (struct mgen_rule *)data;
+ struct rhs_elem *e;
+ struct mgen_sym *sym;
+
+ e = rule->rhs_list;
+ while (e!=NULL){
+ sym = e->sym_list;
+ while (sym!=NULL){
+ if (sym->type == MGEN_NT_SYM){
+ void * r;
+ struct mgen_rule trule;
+ trule.name = sym->name;
+ r = mavl_get(t,&trule);
+ if (!r){
+ char msg[MAX_NONTERMINAL+256];
+ (void)sprintf(msg,"unedfined non-terminal: <%s>",sym->name);
+ prs->line = rule->line;
+ prs->col = 0;
+ err(prs,msg);
+ return;
+ }
+ /* (void)printf("%s<%s>",delim_spc,sym->name);*/
+ }
+ sym = sym->next;
+ }
+ e=e->next;
+ }
+ (void)mavliter_next(&it);
+ }
+}
+
+int check_string(struct mgen_file *mf, char *str)
+{
+ int i,c;
+ i=0;
+
+ (void)printf("CHECK TERMINAL: '%s' - ",str);
+
+ while (str[i] != 0){
+ c=mgen_getc(mf);
+ (void)printf("CMP (%c,%c)",c,str[i]);
+ if (c==str[i]){
+ (void)printf(" ok "),
+ i++;
+ continue;
+ }
+ mgen_ungetc(c,mf);
+ while(i>0){
+ i--;
+ mgen_ungetc(str[i],mf);
+ }
+ (void)printf ("FALSE\n");
+ return 0;
+ }
+ (void)printf ("OK\n");
+ return 1;
+}
+
+
+void unget_string(struct mgen_file *mf, char *str)
+{
+ size_t i;
+/* (void)printf("UNGET %s\n",str);*/
+ i=strlen(str);
+ while(i>0){
+ i--;
+ mgen_ungetc(str[i],mf);
+ }
+}
+
+
+
+int run_rule1(struct mavl * rules, char * rulename, struct mgen_file *mf);
+
+/*
+int check_symlist(struct mavl * rules, struct mgen_sym *sym, struct mgen_file *mf)
+{
+ while (sym!=NULL){
+ switch( sym->type ){
+ case MGEN_NT_SYM:
+ if (!run_rule1(rules,sym->name,mf))
+ return 0;
+ break;
+ case MGEN_T_SYM:
+ if (!check_string(mf,sym->name))
+ return 0;
+
+ break;
+
+ }
+ sym = sym-> next;
+ }
+ return 1;
+}
+*/
+
+
+int run_rule(struct mgen_parser *prs, char *rulename);
+
+struct mgen_sym *
+popsym(struct mgen_parser * prs){
+ struct mgen_sym * sym;
+
+ prs->stackptr--;
+ sym = prs->stack[prs->stackptr];
+ (void)printf("POPSYM: [%d:](%p)\n",prs->stackptr,sym);
+ print_symlist(sym);
+ (void)printf(" - %d \n",prs->stackptr);
+ return sym;
+}
+
+
+void
+pushsym(struct mgen_parser * prs, struct mgen_sym * sym){
+
+ prs->stack[prs->stackptr]=sym;
+ prs->stackptr++;
+ (void)printf("PUSHSYM: ([%d:]%p)\n",prs->stackptr,sym);
+ print_symlist(sym);
+ (void)printf(" - %d \n",prs->stackptr);
+
+}
+
+
+int
+run_sym(struct mgen_parser *prs, struct mgen_sym *sym)
+{
+ int rc;
+ int fpos;
+ fpos = mgen_tell(prs->mf);
+ (void)printf("FPOS: %d\n",fpos);
+
+ (void)printf("ENTER run_sym: prs=%p",prs);
+ print_symlist(sym);
+ (void)printf("\n");
+
+ if (sym == NULL){
+
+ struct mgen_sym *psym;
+ if (prs->stackptr==0){
+ (void)printf("EXIT run_sym (0): TRUE");
+ print_symlist(sym);
+ (void)printf("\n");
+ return 1;
+ }
+
+
+ psym = popsym(prs);
+ rc = run_sym(prs,psym);
+ if (!rc){
+ pushsym(prs,psym);
+ mgen_seek(prs->mf,fpos);
+ (void)printf("SSEK is now: %d\n",mgen_tell(prs->mf));
+ }
+
+ (void)printf("EXIT run_sym (0): X %d",rc);
+ print_symlist(sym);
+ (void)printf("\n");
+ return rc;
+ }
+
+ switch( sym->type ){
+ case MGEN_T_SYM:
+ if (!check_string(prs->mf,sym->name)) {
+ (void)printf("EXIT run_sym(1): FALSE: ");
+ print_symlist(sym);
+ (void)printf("\n");
+ mgen_seek(prs->mf,fpos);
+ return 0;
+ }
+ rc = run_sym(prs,sym->next);
+ if (!rc){
+ mgen_seek(prs->mf,fpos);
+ }
+ return rc;
+
+ case MGEN_NT_SYM:
+ /*print_symlist(sym->next);*/
+ (void)printf("CALL run_rule: <%s>\n",sym->name);
+ pushsym(prs,sym->next);
+ rc = run_rule(prs,sym->name);
+ if (!rc){
+ (void)popsym(prs);
+ print_symlist(prs->stack[prs->stackptr]);
+ (void)printf("\n");
+ (void)printf("EXIT run_sym(2): FALSE: ");
+ print_symlist(sym);
+ (void)printf("\n");
+ mgen_seek(prs->mf,fpos);
+ return 0;
+ }
+ (void)printf("EXIT run_sym (1): TRUE");
+ print_symlist(sym);
+ (void)printf("\n");
+ return 1;
+ }
+
+ (void)printf("EXIT run_sym (2): FALSE: ");
+ print_symlist(sym);
+ (void)printf("\n");
+ mgen_seek(prs->mf,fpos);
+ return 0;
+
+}
+
+
+int
+run_rhs_list(struct mgen_parser *prs, struct rhs_elem * e)
+{
+/* int i,c;*/
+ while (e!=NULL){
+ (void)printf("RUN RHS ELEM: ");
+ print_rhs_list(e);
+ (void)printf("\n");
+
+ if ( run_sym(prs,e->sym_list) ){
+ (void)printf("EXIT RHS ELEM: TRUE: ");
+ print_rhs_list(e);
+ (void)printf("\n");
+ return 1;
+ }
+ (void)printf("THE FPOS IS NOW: %d\n",mgen_tell(prs->mf));
+
+ (void)printf("NEXT RHS ELEM FOR:");
+ print_rhs_list(e);
+ (void)printf("\n");
+
+ e=e->next;
+ }
+
+ (void)printf("EXIT RHS ELEM: FALSE: ");
+ print_rhs_list(e);
+ (void)printf("\n");
+
+ return 0;
+}
+
+static int
+run_rule(struct mgen_parser *prs, char *rulename)
+{
+
+ struct mgen_rule *rule,rs;
+/* struct rhs_elem *e;*/
+
+ rs.name = rulename;
+ rule = mavl_get(prs->rules,&rs);
+ if ( !rule ){
+ (void)printf("Fatal error rule not found %s\n",rulename);
+ return 0;
+ }
+
+/* pushsym(prs,rule->rhs_list->next);*/
+ return run_rhs_list(prs,rule->rhs_list);
+
+}
+
+void
+start(struct mavl * rules, struct mgen_file * mf, char * start_sym)
+{
+ int rc;
+ struct mgen_parser prs;
+
+ struct mgen_rule *rule,rs;
+
+
+ rs.name = start_sym;
+ printf("Start is here %p\n",rules);
+ rule = mavl_get(rules,&rs);
+ if ( !rule ){
+ (void)printf("error\n");
+ return;
+ }
+
+
+ prs.mf = mf;
+ prs.rules = rules;
+ prs.stackptr=0;
+
+ rc= run_rule(&prs,start_sym);
+
+ if (rc)
+ (void) printf("RC: true\n");
+ else
+ (void) printf("RC: false\n");
+
+}
+
+void run(struct mavl *rules, const char * filename)
+{
+ struct mgen_file *mf;
+ (void)printf("Mistart\n");
+
+ mf = mgen_open(filename, prgname);
+ if (mf !=0 ){
+
+ }
+
+ start(rules,mf,"Programm");
+
+}
+
+
+
+int
+main(int argc, char *argv[])
+{
+ int c;
+ struct prs prs;
+ struct mgen_file *mf;
+ struct mgen_rule_set * rules;
+
+ if (argc>0)
+ prgname = argv[0];
+ else
+ prgname ="";
+
+ if (argc==1){
+ prs.infile = stdin;
+ prs.filename = NULL;
+ }
+ else{
+ prs.infile = fopen(argv[1],"rt");
+ prs.filename=argv[1];
+ if (!prs.infile){
+ (void)fprintf(stderr,
+ "%s: error: can't open '%s': %s\n",
+ prgname,prs.filename,strerror(errno)
+ );
+ return errno;
+ }
+
+ }
+
+ mf = mgen_open_stream(prs.infile,prgname);
+ if (!mf){
+ (void)fprintf(stderr,"Error: %s",strerror(errno));
+ return errno;
+ }
+
+ rules = mgen_read_rule_set(mf);
+/*
+ prs.line=1;
+ prs.col=0;
+ prs.rules = mavl_create(cmp_nonterminal,
+ NULL, sizeof (struct mgen_rule) );
+ if (!prs.rules){
+ prgerr("can't allocate memory");
+ return errno;
+ }
+ do {
+ c = get_left_hand_side(&prs);
+ if (c==EOF)
+ break;
+ c = get_assignment(&prs);
+ if (c==EOF)
+ break;
+ c = get_right_hand_side(&prs);
+
+ }while(c!=EOF);
+ verify(&prs);
+*/
+
+
+
+
+
+ if (argc==3){
+ mf = mgen_open(argv[2],prgname);
+ if (!mf){
+ perror("");
+ return 1;
+ }
+printf("call parse\n");
+ mgen_parse(mf,rules,"Programm");
+
+ /*run(rules,argv[2]);*/
+ }
+ (void)printf("------------------------------\n");
+ print(rules);
+
+ return 0;
+}
Index: mgen/0.0.1/example.bnf
===================================================================
--- mgen/0.0.1/example.bnf (nonexistent)
+++ mgen/0.0.1/example.bnf (revision 254)
@@ -0,0 +1,6 @@
+
+<Ziffer ausser Null> ::= 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
+<Ziffer> ::= 0 | <Ziffer ausser Null>
+<Zweistellige Zahl> ::= <Ziffer ausser Null> <Ziffer>
+<Zehn bis Neunzehn> ::= 1 <Ziffer>
+<Zweiundvierzig> ::= 42
Index: mgen/0.0.1/mgen.h
===================================================================
--- mgen/0.0.1/mgen.h (nonexistent)
+++ mgen/0.0.1/mgen.h (revision 254)
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2019, The PLANIX Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MGEN_H
+#define _MGEN_H
+
+
+#include <ctype.h>
+#include <stdio.h>
+#include <libmavl/mavl.h>
+
+#ifndef MGEN_BUF_BLOCK_SIZE
+#define MGEN_BUF_BLOCK_SIZE 1024
+#endif
+
+struct mgen_file {
+ FILE *infile;
+ int line;
+ int prev_col;
+ int col;
+ int tab_size;
+ const char *filename;
+ const char *prgname;
+ char *buf;
+ int bufptr;
+ int bufmax;
+ int buflast;
+ int eof;
+};
+
+enum {
+ MGEN_NT_SYM, /* describes a non-terminal symbol */
+ MGEN_T_SYM /* a terminal symbol */
+};
+
+/* representation of a symbol */
+struct mgen_sym {
+ int type;
+ struct mgen_sym * next;
+ char *name;
+};
+
+/*extern struct rhs_elem;*/
+struct rhs_elem{
+ struct mgen_sym * sym_list;
+ struct rhs_elem * next;
+};
+
+struct mgen_rule {
+ char * name;
+ int line;
+ struct rhs_elem * rhs_list;
+};
+
+
+#define mgen_rule_set mavl
+
+
+int mgen_getc(struct mgen_file * mf);
+struct mgen_file * mgen_open(const char *filename, const char *prgname);
+void mgen_ungetc(int c, struct mgen_file *mf);
+int mgen_skip_spaces(struct mgen_file * mf );
+void mgen_perror(struct mgen_file *mf, char *msg, ...);
+struct mgen_file * mgen_open_stream(FILE *infile, const char *prgname);
+struct mgen_rule_set * mgen_read_rule_set(struct mgen_file *mf);
+struct mgen_rule_set * mgen_create_rule_set();
+int mgen_parse( struct mgen_file *mf,
+ struct mgen_rule_set *rules,
+ const char * start);
+
+
+
+/* debugging stuff */
+void print_symlist(struct mgen_sym * sym);
+void print_rhs_list(struct rhs_elem *e);
+
+#define mgen_isspace(c) isspace(c)
+
+
+#define mgen_tell(mf) (mf->bufptr)
+#define mgen_seek(mf,pos) (mf->bufptr=(pos))
+
+
+#endif
Index: mgen/0.0.1/mgen_create_rule_set.c
===================================================================
--- mgen/0.0.1/mgen_create_rule_set.c (nonexistent)
+++ mgen/0.0.1/mgen_create_rule_set.c (revision 254)
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2019,2020, The PLANIX Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <string.h>
+#include "mgen.h"
+
+static int
+cmp_rules(const void *v1, const void *v2)
+{
+ const char *s1,*s2;
+ s1 = ((struct mgen_rule *)v1)->name;
+ s2 = ((struct mgen_rule *)v2)->name;
+
+ return strcmp(s1,s2);
+}
+
+
+struct mgen_rule_set *
+mgen_create_rule_set()
+{
+ return mavl_create(cmp_rules,
+ NULL, sizeof (struct mgen_rule) );
+}
Index: mgen/0.0.1/mgen_getc.c
===================================================================
--- mgen/0.0.1/mgen_getc.c (nonexistent)
+++ mgen/0.0.1/mgen_getc.c (revision 254)
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2019, The PLANIX Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include "mgen.h"
+
+int
+mgen_getc(struct mgen_file * mf)
+{
+ int c;
+
+ if (mf->eof)
+ return EOF;
+
+ if (mf->bufptr<mf->buflast)
+ c=mf->buf[mf->bufptr++];
+ else{
+ c=fgetc(mf->infile);
+ if (c==EOF){
+ mf->eof=1;
+ return EOF;
+ }
+ mf->buf[mf->bufptr++]=(char)c;
+ mf->buflast++;
+ }
+
+ switch(c) {
+ case '\n':
+ mf->line++;
+ mf->prev_col = mf->col;
+ mf->col=0;
+ break;
+ case '\t':
+ mf->col+=mf->tab_size;
+ break;
+ default:
+ mf->col++;
+ }
+ return c;
+}
+
Index: mgen/0.0.1/mgen_open.c
===================================================================
--- mgen/0.0.1/mgen_open.c (nonexistent)
+++ mgen/0.0.1/mgen_open.c (revision 254)
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2019,2020, The PLANIX Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mgen.h"
+
+static struct mgen_file *
+mgen_file_create()
+{
+ struct mgen_file * mf;
+ mf = malloc(sizeof(struct mgen_file));
+ if (!mf)
+ return NULL;
+
+ mf->buf = malloc(MGEN_BUF_BLOCK_SIZE);
+ if (!mf->buf){
+ free (mf);
+ return NULL;
+ }
+ mf->line = 1;
+ mf->col=0;
+ mf->bufptr=0;
+ mf->buflast=0;
+ mf->bufmax=MGEN_BUF_BLOCK_SIZE;
+ mf->eof=0;
+ return mf;
+}
+
+struct mgen_file *
+mgen_open_stream(FILE *infile, const char *prgname)
+{
+ struct mgen_file * mf;
+ mf = mgen_file_create();
+ if (!mf){
+ return NULL;
+ }
+ mf->prgname = prgname;
+ mf->infile = infile;
+ return mf;
+}
+
+struct mgen_file *
+mgen_open(const char *filename, const char *prgname)
+{
+ FILE * infile;
+ struct mgen_file * mf;
+
+ infile = fopen(filename,"rt");
+ if (infile==NULL)
+ return NULL;
+
+
+ mf = mgen_open_stream(infile,prgname);
+/* mf = mgen_file_create();*/
+ if (!mf){
+ (void)fclose(infile);
+ return NULL;
+ }
+
+/* mf->infile = infile;*/
+ return mf;
+}
+
Index: mgen/0.0.1/mgen_parse.c
===================================================================
--- mgen/0.0.1/mgen_parse.c (nonexistent)
+++ mgen/0.0.1/mgen_parse.c (revision 254)
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2019,2020, The PLANIX Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "mgen.h"
+
+
+struct status {
+ int fpos;
+ int mode;
+ struct rhs_elem * e;
+ int sstackptr;
+
+ union {
+ struct mgen_sym * sym;
+ struct rhs_elem * e;
+ }p;
+};
+
+
+struct mgen_parser {
+ struct mavl * rules;
+ struct mgen_file * mf;
+
+
+
+ struct mgen_sym *sstack[1000];
+ int sstackptr;
+ struct rhs_elem * rstack[1000];
+ int rstackptr;
+ struct status ststack[1000];
+ int ststackptr;
+
+};
+
+
+static void
+pushsym(struct mgen_parser * prs, struct mgen_sym * sym){
+
+ prs->sstack[prs->sstackptr++]=sym;
+
+}
+
+static struct mgen_sym *
+popsym(struct mgen_parser * prs)
+{
+ prs->sstackptr--;
+ return prs->sstack[prs->sstackptr];
+}
+
+
+static int
+check_string(struct mgen_file *mf, char *str)
+{
+ int i,c;
+ i=0;
+
+/* (void)printf("CHECK TERMINAL: '%s' - ",str); */
+
+ while (str[i] != 0){
+ c=mgen_getc(mf);
+/* (void)printf("CMP (%c,%c)",c,str[i]); */
+ if (c==str[i]){
+/* (void)printf(" ok "),*/
+ i++;
+ continue;
+ }
+ mgen_ungetc(c,mf);
+ while(i>0){
+ i--;
+ mgen_ungetc(str[i],mf);
+ }
+/* (void)printf ("FALSE\n");*/
+ return 0;
+ }
+/* (void)printf ("OK\n");*/
+ return 1;
+}
+
+
+
+enum ps{
+ S_TRUE,
+ S_FALSE,
+ S_SPLIT,
+ S_FIN,
+ S_NEXT
+};
+
+
+
+
+static struct rhs_elem *
+get_rhs_list(struct mgen_parser * prs, char *rulename)
+{
+ struct mgen_rule *rule,rs;
+ rs.name = rulename;
+ rule = mavl_get(prs->rules,&rs);
+ if ( !rule ){
+ (void)printf("Fatal error rule not found %s\n",rulename);
+ return 0;
+ }
+
+ return rule->rhs_list;
+}
+
+void pushstatus(struct mgen_parser * prs, struct rhs_elem *e)
+{
+ int i = prs->ststackptr++;
+ prs->ststack[i].fpos = mgen_tell(prs->mf);
+ prs->ststack[i].e = e;
+ prs->ststack[i].sstackptr=prs->sstackptr;
+}
+
+struct status * peekstatus(struct mgen_parser * prs)
+{
+ return &(prs->ststack[prs->ststackptr-1]);
+}
+
+
+static int
+run_rhs_list(struct mgen_parser *prs, struct rhs_elem * e)
+{
+ struct mgen_sym * sym;
+ struct status * st;
+loopx:
+ pushstatus(prs,e);
+next_sym1:
+
+ if (!e) {
+ if (prs->ststackptr==1)
+ return 0;
+ prs->ststackptr--;
+ goto quirk;
+ }
+ sym=e->sym_list;
+
+next_sym:
+
+ if (!sym) {
+ if (prs->sstackptr==0)
+ return 1;
+ sym = popsym(prs);
+ goto next_sym;
+ }
+ switch( sym->type ){
+ case MGEN_T_SYM:
+ if (check_string(prs->mf,sym->name)){
+ sym=sym->next;
+ goto next_sym;
+ }
+quirk:
+ st = peekstatus(prs);
+ /* e=st->e;*/
+
+
+ e=st->e->next;
+ st->e=e;
+ mgen_seek(prs->mf,st->fpos);
+ prs->sstackptr=st->sstackptr;
+ goto next_sym1;
+
+ case MGEN_NT_SYM:
+ e = get_rhs_list(prs,sym->name);
+ pushsym(prs,sym->next);
+ goto loopx;
+ }
+
+ return 0;
+
+}
+
+
+/*
+int
+run_rule(struct mgen_parser *prs, char *rulename)
+{
+
+ struct mgen_rule *rule,rs;
+
+ rs.name = rulename;
+ rule = mavl_get(prs->rules,&rs);
+ if ( !rule ){
+ (void)printf("Fatal error rule not found %s\n",rulename);
+ return 0;
+ }
+
+ return run_rhs_list(prs,rule->rhs_list);
+
+ return 1;
+}
+*/
+
+/*
+
+int run_status(struct mgen_parser * prs, struct status * status)
+{
+ mgen_seek(prs->mf,status->fpos);
+ switch(status->mode){
+ case 0: {
+ struct rhs_elem * e;
+ e = (status->p).e;
+ while (e!=NULL){
+
+ e=e->next;
+ }
+ }
+
+ }
+
+}
+*/
+
+int
+mgen_parse(
+ struct mgen_file *mf,
+ struct mgen_rule_set *rules,
+ const char * start)
+{
+ struct mgen_parser prs;
+ struct status status;
+ int rc;
+
+ prs.rules = rules;
+ prs.mf = mf;
+ prs.sstackptr=0;
+ prs.rstackptr=0;
+ prs.ststackptr=0;
+
+ status.mode=0;
+ status.p.e = get_rhs_list(&prs,(char*)start);
+
+ rc = run_rhs_list(&prs,status.p.e);
+ if (rc){
+ (void)printf("TRUE\n");
+ }
+ else {
+ (void)printf("FALSE\n");
+ }
+
+ return rc;
+}
Index: mgen/0.0.1/mgen_perror.c
===================================================================
--- mgen/0.0.1/mgen_perror.c (nonexistent)
+++ mgen/0.0.1/mgen_perror.c (revision 254)
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019,2020, The PLANIX Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "mgen.h"
+
+void
+mgen_perror(struct mgen_file *mf, char *msg, ...)
+{
+ va_list argp;
+ va_start(argp, msg);
+
+ if (mf->filename){
+ (void)fprintf(stderr,"\"%s\",",mf->filename);
+ }
+
+ (void)fprintf(stderr, "line %d, col %d: error: ",
+ mf->line, mf->col);
+
+ (void)vfprintf(stderr,msg,argp);
+ (void)fprintf(stderr,"\n");
+ va_end(argp);
+}
Index: mgen/0.0.1/mgen_print_rhs_list.c
===================================================================
--- mgen/0.0.1/mgen_print_rhs_list.c (nonexistent)
+++ mgen/0.0.1/mgen_print_rhs_list.c (revision 254)
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2019,2020, The PLANIX Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "mgen.h"
+
+void
+print_rhs_list(struct rhs_elem *e)
+{
+ struct mgen_sym *sym;
+ char * delim_or, *delim_spc;
+ delim_or="";
+ while (e!=NULL){
+ sym = e->sym_list;
+ (void)printf("%s",delim_or);
+ delim_or="|";
+ delim_spc="";
+ while (sym!=NULL){
+ if (sym->type == MGEN_NT_SYM)
+ (void)printf("%s<%s>",delim_spc,sym->name);
+ else
+ (void)printf("%s%s",delim_spc,sym->name);
+ sym = sym->next;
+ delim_spc=" ";
+ }
+ e=e->next;
+ }
+}
+
+
Index: mgen/0.0.1/mgen_print_symlist.c
===================================================================
--- mgen/0.0.1/mgen_print_symlist.c (nonexistent)
+++ mgen/0.0.1/mgen_print_symlist.c (revision 254)
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2019,2020, The PLANIX Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "mgen.h"
+
+void
+print_symlist(struct mgen_sym * sym)
+{
+ char *delim_spc;
+ delim_spc="";
+ while (sym!=NULL){
+ if (sym->type == MGEN_NT_SYM)
+ (void)printf("%s<%s>",delim_spc,sym->name);
+ else
+ (void)printf("%s%s",delim_spc,sym->name);
+ sym = sym->next;
+ delim_spc=" ";
+ }
+}
+
Index: mgen/0.0.1/mgen_read_rule_set.c
===================================================================
--- mgen/0.0.1/mgen_read_rule_set.c (nonexistent)
+++ mgen/0.0.1/mgen_read_rule_set.c (revision 254)
@@ -0,0 +1,379 @@
+/*
+ * Copyright 2019,2020, The PLANIX Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <string.h>
+#include <errno.h>
+
+#include "mgen.h"
+
+#define MAX_NONTERMINAL 1024
+#define MAX_TERMINAL 1024
+
+struct bnf0_prs {
+ struct mgen_rule * current_rule;
+ struct rhs_elem * current_rhs_elem;
+ struct mgen_sym ** current_sym;
+ struct mavl *rules;
+};
+
+static int
+skip_comment(struct mgen_file * mf)
+{
+ int c;
+ do {
+ c=mgen_getc(mf);
+ }while (c!='\n' && c!=EOF);
+ return c;
+}
+
+static int
+get_non_terminal(struct mgen_file * mf, char * result)
+{
+ int c;
+ int i;
+
+ c=EOF; /* this eliminates a compiler warning
+ about c may be used unassigned */
+
+ for (i=0; i<MAX_NONTERMINAL; i++){
+ c = mgen_getc(mf);
+ if (c=='>')
+ break;
+ if (c=='\n' || c==EOF){
+ mgen_perror(mf,"missing '>' at end of non-terminal");
+ return EOF;
+ }
+ result[i]=(char)c;
+ }
+
+ if (i==MAX_NONTERMINAL && c!='>'){
+ mgen_perror(mf,"non-terminal symbol too long");
+ return EOF;
+ }
+ result[i]=0;
+
+ return c;
+}
+
+static int
+get_terminal(struct mgen_file * mf, char * result)
+{
+ int c;
+ int i;
+
+ c=EOF; /* this eliminates a compiler warning
+ about c may be used unassigned */
+
+ for (i=0; i<MAX_TERMINAL; i++){
+ c = mgen_getc(mf);
+ if (c==' ' || c=='\n' || c=='|' ||
+ c=='\t' || c=='\r' || c==EOF)
+ break;
+ result[i]=(char)c;
+ }
+
+ if (i==MAX_TERMINAL ){
+ mgen_perror(mf,"terminal symbol too long");
+ return EOF;
+ }
+ result[i]=0;
+
+ return c;
+}
+
+
+static struct rhs_elem *
+append_rhs_elem(struct rhs_elem ** next)
+{
+ while (*next!=NULL){
+ next = &((*next)->next);
+ }
+ *next = malloc(sizeof(struct rhs_elem));
+ if (!*next)
+ return NULL;
+
+ (*next)->sym_list=NULL;
+ (*next)->next=NULL;
+ return *next;
+}
+
+static struct mgen_sym *
+append_sym(struct mgen_sym ** next, int type, char *name)
+{
+ struct mgen_sym * sym;
+ sym = malloc( sizeof( struct mgen_sym));
+ if (!sym){
+ return NULL;
+ }
+ sym->name = malloc( strlen(name)+1);
+ if (!sym->name){
+ return NULL;
+ }
+ (void)strcpy (sym->name,name);
+ sym->type=type;
+ sym->next=NULL;
+
+ *next = sym;
+ return sym;
+}
+
+
+
+static int
+get_left_hand_side(struct mgen_file * mf, struct bnf0_prs * prs)
+{
+ int c;
+ char result[MAX_NONTERMINAL+1];
+ struct mgen_rule rule;
+ int exists;
+
+ while(1) {
+ c = mgen_skip_spaces(mf);
+ if (c==EOF)
+ return EOF;
+ if (c=='#' && mf->col==1){
+ c=skip_comment(mf);
+ mgen_ungetc(c,mf);
+ continue;
+ }
+ break;
+ }
+
+
+ if (c != '<' ){
+ mgen_perror(mf,"'<' expected.");
+ return EOF;
+ }
+ if (mf->col != 1){
+ mgen_perror(mf,
+ "left hand side of a rule has to start at column 1.");
+ return EOF;
+ }
+
+ c = get_non_terminal(mf, result);
+ if (c==EOF)
+ return EOF;
+
+ rule.name = malloc(strlen(result)+1);
+ if (!rule.name){
+ mgen_perror(mf,"can't allocate memory.");
+ return EOF;
+ }
+ (void)strcpy(rule.name,result);
+ rule.rhs_list=0;
+ rule.line = mf->line;
+ rule.rhs_list = NULL;
+
+/* (void)printf("non-terminal found: %s\n",rule.name);*/
+
+ prs->current_rule =
+ mavl_insert(prs->rules, &rule, &exists);
+
+ if (!prs->current_rule){
+ mgen_perror(mf,"can't allocate memory\n");
+ return EOF;
+ }
+
+ if (exists){
+ char msg[MAX_NONTERMINAL+256];
+ (void)sprintf(msg,"symbol <%s> is already defined.",result);
+ mgen_perror(mf,msg);
+ return EOF;
+ }
+
+ prs->current_rhs_elem =
+ append_rhs_elem(&(prs->current_rule->rhs_list));
+
+ if (!prs->current_rhs_elem)
+ return EOF;
+ prs->current_sym = &prs->current_rhs_elem->sym_list;
+ return 0;
+}
+
+static int
+get_right_hand_side(struct mgen_file *mf, struct bnf0_prs *prs)
+{
+ int c;
+ struct mgen_sym * sym;
+
+ /* int nsyms;
+ * nsyms = 0;*/
+
+ do{
+ c = mgen_skip_spaces(mf);
+ switch (c) {
+ case '<': {
+ char result[MAX_NONTERMINAL+1];
+ if (mf->col <= 1){
+ mgen_ungetc(c,mf);
+ return c;
+ }
+
+ c = get_non_terminal(mf,result);
+ if (c==EOF)
+ return EOF;
+
+ sym=append_sym(
+ prs->current_sym,MGEN_NT_SYM,result
+ );
+
+ if (!sym) {
+ mgen_perror(mf,
+ "Can't allocate memory"
+ );
+ return EOF;
+ }
+
+ prs->current_sym = &sym->next;
+ break;
+ }
+ case '|':
+ prs->current_rhs_elem =
+ append_rhs_elem(
+ &(prs->current_rule->rhs_list)
+ );
+ if (!prs->current_rhs_elem)
+ return EOF;
+ prs->current_sym = &prs->current_rhs_elem->sym_list;
+ break;
+
+ default:{
+ char result[MAX_TERMINAL+1];
+ mgen_ungetc(c,mf);
+ c=get_terminal(mf,result);
+
+ sym=append_sym(
+ prs->current_sym,MGEN_T_SYM,result
+ );
+ if (!sym){
+ mgen_perror(mf,
+ "Can't allocate memory"
+ );
+ return EOF;
+ }
+ mgen_ungetc(c,mf);
+ prs->current_sym = &sym->next;
+ }
+ }
+
+ }while (c!=EOF);
+
+ return EOF;
+}
+
+static int
+get_assignment (struct mgen_file * mf)
+{
+ int c,i,n;
+ char * search = "::=";
+
+ c = mgen_skip_spaces(mf);
+
+ i=0; n=(int)strlen(search);
+ do {
+ if (c!=search[i]){
+ mgen_perror(mf,"'::=' expected.");
+ return EOF;
+ }
+ i++;
+ c=mgen_getc(mf);
+ }while(i<n);
+ return c;
+}
+
+static void
+verify(struct bnf0_prs * prs)
+{
+ struct mavl *t;
+ struct mavliter it;
+ void *data;
+ struct mgen_file mf;
+
+ t = prs->rules;
+
+ mavliter_init(&it, t);
+ (void)mavliter_seek_set(&it);
+
+ while ((data = mavliter_get(&it)) != NULL) {
+ struct mgen_rule * rule = (struct mgen_rule *)data;
+ struct rhs_elem *e;
+ struct mgen_sym *sym;
+
+ e = rule->rhs_list;
+ while (e!=NULL){
+ sym = e->sym_list;
+ while (sym!=NULL){
+ if (sym->type == MGEN_NT_SYM){
+ void * r;
+ struct mgen_rule trule;
+ trule.name = sym->name;
+ r = mavl_get(t,&trule);
+ if (!r){
+ char msg[MAX_NONTERMINAL+256];
+ (void)sprintf(msg,"unedfined non-terminal: <%s>",sym->name);
+ mf.line = rule->line;
+ mf.col = 0;
+ mgen_perror(&mf,msg);
+ return;
+ }
+ /* (void)printf("%s<%s>",delim_spc,sym->name);*/
+ }
+ sym = sym->next;
+ }
+ e=e->next;
+ }
+ (void)mavliter_next(&it);
+ }
+}
+
+
+
+struct mgen_rule_set * mgen_read_rule_set(struct mgen_file *mf)
+{
+ struct bnf0_prs prs;
+ struct mgen_rule_set * rules;
+ int c;
+
+ prs.rules = mgen_create_rule_set();
+ if (!prs.rules){
+ mgen_perror(mf,"can't allocate memory");
+ return NULL;
+ }
+
+ do {
+ c = get_left_hand_side(mf,&prs);
+ if (c==EOF)
+ break;
+ c = get_assignment(mf);
+ if (c==EOF)
+ break;
+ c = get_right_hand_side(mf,&prs);
+
+ }while(c!=EOF);
+ verify(&prs);
+
+ return prs.rules;
+}
Index: mgen/0.0.1/mgen_run.c
===================================================================
--- mgen/0.0.1/mgen_run.c (nonexistent)
+++ mgen/0.0.1/mgen_run.c (revision 254)
@@ -0,0 +1,5 @@
+
+
+int mgen_run()
+{
+}
Index: mgen/0.0.1/mgen_skip_spaces.c
===================================================================
--- mgen/0.0.1/mgen_skip_spaces.c (nonexistent)
+++ mgen/0.0.1/mgen_skip_spaces.c (revision 254)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2019,2020, The PLANIX Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "mgen.h"
+
+int
+mgen_skip_spaces(struct mgen_file * mf )
+{
+ int c;
+ while (1) {
+ c=mgen_getc(mf);
+ if ( mgen_isspace(c) ) {
+ continue;
+ }
+ break;
+ };
+ return c;
+}
+
Index: mgen/0.0.1/mgen_ungetc.c
===================================================================
--- mgen/0.0.1/mgen_ungetc.c (nonexistent)
+++ mgen/0.0.1/mgen_ungetc.c (revision 254)
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2019,2020, The PLANIX Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include "mgen.h"
+
+void
+mgen_ungetc(int c, struct mgen_file *mf)
+{
+ mf->bufptr--;
+ mf->buf[mf->bufptr]=(char)c;
+ mf->eof=0;
+
+ switch(c) {
+ case '\n':
+ mf->line--;
+ mf->col=mf->prev_col;
+ break;
+ case '\t':
+ mf->col-=8;
+ break;
+ default:
+ mf->col--;
+ }
+}
+
+
Index: mgen/0.0.1/mi.prg
===================================================================
--- mgen/0.0.1/mi.prg (nonexistent)
+++ mgen/0.0.1/mi.prg (revision 254)
@@ -0,0 +1 @@
+PROGRAMGgtBEGIN...END.
Index: mgen/0.0.1/mipascal.bnf
===================================================================
--- mgen/0.0.1/mipascal.bnf (nonexistent)
+++ mgen/0.0.1/mipascal.bnf (revision 254)
@@ -0,0 +1,13 @@
+#
+# mini pascal
+#
+
+<Programm> ::= PROGRAM <Bezeichner> BEGIN <Satzfolge> END .
+<Bezeichner> ::= <Buchstabe> <Restbezeichner>
+<Restbezeichner> ::= | <Buchstabe oder Ziffer> <Restbezeichner>
+<Buchstabe oder Ziffer> ::= <Buchstabe> | <Ziffer>
+<Grossbuchstabe> ::= A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z
+<Kleinbuchstabe> ::= a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z
+<Buchstabe> ::= <Grossbuchstabe> | <Kleinbuchstabe>
+<Ziffer> ::= 0|1|2|3|4|5|6|7|8|9
+<Satzfolge> ::= ...
Index: mgen/0.0.1/my.bnf
===================================================================
--- mgen/0.0.1/my.bnf (nonexistent)
+++ mgen/0.0.1/my.bnf (revision 254)
@@ -0,0 +1,8 @@
+<Programm> ::= <Wort> Z u m s e l
+<Buchstabe> ::= <Kleinbuchstabe> | <Grossbuchstabe>
+<Wort> ::= <Buchstabe> <Wortrest> <Delimiter>
+<Wortrest> ::= <Buchstabe> <Wortrest> |
+<Kleinbuchstabe> ::= a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z
+<Grossbuchstabe> ::= A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z
+<Delimiter> ::= _ <Delimiterrest>
+<Delimiterrest> ::= <Delimiter> |
Index: mgen/0.0.1/my.prg
===================================================================
--- mgen/0.0.1/my.prg (nonexistent)
+++ mgen/0.0.1/my.prg (revision 254)
@@ -0,0 +1 @@
+ab_____Zumsel
Index: mgen/0.0.1
===================================================================
--- mgen/0.0.1 (nonexistent)
+++ mgen/0.0.1 (revision 254)
/mgen/0.0.1
Property changes:
Added: svn:mergeinfo
## -0,0 +0,2 ##
Merged /branches/bnf/bnf_cleanup:r123-126
Merged /branches/bnf/mgen:r129-142