summaryrefslogtreecommitdiffstats
path: root/Parser
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1990-12-20 15:06:42 (GMT)
committerGuido van Rossum <guido@python.org>1990-12-20 15:06:42 (GMT)
commit3f5da24ea304e674a9abbdcffc4d671e32aa70f1 (patch)
treee932e31cb9381f40b7c87c377638216c043b5cfc /Parser
parent226d79eb4a776dd54c9e4544b17deaf928bcef3a (diff)
downloadcpython-3f5da24ea304e674a9abbdcffc4d671e32aa70f1.zip
cpython-3f5da24ea304e674a9abbdcffc4d671e32aa70f1.tar.gz
cpython-3f5da24ea304e674a9abbdcffc4d671e32aa70f1.tar.bz2
"Compiling" version
Diffstat (limited to 'Parser')
-rw-r--r--Parser/acceler.c77
-rw-r--r--Parser/bitset.c5
-rw-r--r--Parser/firstsets.c38
-rw-r--r--Parser/grammar.c32
-rw-r--r--Parser/grammar1.c3
-rw-r--r--Parser/intrcheck.c6
-rw-r--r--Parser/listnode.c41
-rw-r--r--Parser/metagrammar.c3
-rw-r--r--Parser/node.c34
-rw-r--r--Parser/parser.c34
-rw-r--r--Parser/parser.h5
-rw-r--r--Parser/parsetok.c128
-rw-r--r--Parser/pgen.c6
-rw-r--r--Parser/pgen.h2
-rw-r--r--Parser/pgenmain.c111
-rw-r--r--Parser/printgrammar.c70
-rw-r--r--Parser/tokenizer.c16
17 files changed, 329 insertions, 282 deletions
diff --git a/Parser/acceler.c b/Parser/acceler.c
index 7ff10b2..ce16711 100644
--- a/Parser/acceler.c
+++ b/Parser/acceler.c
@@ -1,11 +1,52 @@
/* Parser accelerator module */
-#include <stdio.h>
+/* The parser as originally conceived had disappointing performance.
+ This module does some precomputation that speeds up the selection
+ of a DFA based upon a token, turning a search through an array
+ into a simple indexing operation. The parser now cannot work
+ without the accelerators installed. Note that the accelerators
+ are installed dynamically when the parser is initialized, they
+ are not part of the static data structure written on graminit.[ch]
+ by the parser generator. */
-#include "PROTO.h"
+#include "pgenheaders.h"
#include "grammar.h"
#include "token.h"
-#include "malloc.h"
+#include "parser.h"
+
+/* Forward references */
+static void fixdfa PROTO((grammar *, dfa *));
+static void fixstate PROTO((grammar *, dfa *, state *));
+
+void
+addaccelerators(g)
+ grammar *g;
+{
+ dfa *d;
+ int i;
+#ifdef DEBUG
+ printf("Adding parser accellerators ...\n");
+#endif
+ d = g->g_dfa;
+ for (i = g->g_ndfas; --i >= 0; d++)
+ fixdfa(g, d);
+ g->g_accel = 1;
+#ifdef DEBUG
+ printf("Done.\n");
+#endif
+}
+
+static void
+fixdfa(g, d)
+ grammar *g;
+ dfa *d;
+{
+ state *s;
+ int j;
+ s = d->d_state;
+ for (j = 0; j < d->d_nstates; j++, s++)
+ fixstate(g, d, s);
+}
static void
fixstate(g, d, s)
@@ -69,33 +110,3 @@ fixstate(g, d, s)
}
DEL(accel);
}
-
-static void
-fixdfa(g, d)
- grammar *g;
- dfa *d;
-{
- state *s;
- int j;
- s = d->d_state;
- for (j = 0; j < d->d_nstates; j++, s++)
- fixstate(g, d, s);
-}
-
-void
-addaccelerators(g)
- grammar *g;
-{
- dfa *d;
- int i;
-#ifdef DEBUG
- printf("Adding parser accellerators ...\n");
-#endif
- d = g->g_dfa;
- for (i = g->g_ndfas; --i >= 0; d++)
- fixdfa(g, d);
- g->g_accel = 1;
-#ifdef DEBUG
- printf("Done.\n");
-#endif
-}
diff --git a/Parser/bitset.c b/Parser/bitset.c
index b43fb82..655240a 100644
--- a/Parser/bitset.c
+++ b/Parser/bitset.c
@@ -1,7 +1,6 @@
-/* Bitset primitives */
+/* Bitset primitives used by the parser generator */
-#include "PROTO.h"
-#include "malloc.h"
+#include "pgenheaders.h"
#include "bitset.h"
bitset
diff --git a/Parser/firstsets.c b/Parser/firstsets.c
index 0f28dd0..b4a9e3c 100644
--- a/Parser/firstsets.c
+++ b/Parser/firstsets.c
@@ -1,14 +1,29 @@
/* Computation of FIRST stets */
-#include <stdio.h>
-
-#include "PROTO.h"
-#include "malloc.h"
+#include "pgenheaders.h"
#include "grammar.h"
#include "token.h"
extern int debugging;
+/* Forward */
+static void calcfirstset PROTO((grammar *, dfa *));
+
+void
+addfirstsets(g)
+ grammar *g;
+{
+ int i;
+ dfa *d;
+
+ printf("Adding FIRST sets ...\n");
+ for (i = 0; i < g->g_ndfas; i++) {
+ d = &g->g_dfa[i];
+ if (d->d_first == NULL)
+ calcfirstset(g, d);
+ }
+}
+
static void
calcfirstset(g, d)
grammar *g;
@@ -92,18 +107,3 @@ calcfirstset(g, d)
printf(" }\n");
}
}
-
-void
-addfirstsets(g)
- grammar *g;
-{
- int i;
- dfa *d;
-
- printf("Adding FIRST sets ...\n");
- for (i = 0; i < g->g_ndfas; i++) {
- d = &g->g_dfa[i];
- if (d->d_first == NULL)
- calcfirstset(g, d);
- }
-}
diff --git a/Parser/grammar.c b/Parser/grammar.c
index ad9c2b0..221bf64 100644
--- a/Parser/grammar.c
+++ b/Parser/grammar.c
@@ -1,10 +1,9 @@
/* Grammar implementation */
-#include <stdio.h>
+#include "pgenheaders.h"
+
#include <ctype.h>
-#include "PROTO.h"
-#include "malloc.h"
#include "assert.h"
#include "token.h"
#include "grammar.h"
@@ -127,6 +126,21 @@ findlabel(ll, type, str)
abort();
}
+/* Forward */
+static void translabel PROTO((grammar *, label *));
+
+void
+translatelabels(g)
+ grammar *g;
+{
+ int i;
+
+ printf("Translating labels ...\n");
+ /* Don't translate EMPTY */
+ for (i = EMPTY+1; i < g->g_ll.ll_nlabels; i++)
+ translabel(g, &g->g_ll.ll_label[i]);
+}
+
static void
translabel(g, lb)
grammar *g;
@@ -193,15 +207,3 @@ translabel(g, lb)
else
printf("Can't translate label '%s'\n", labelrepr(lb));
}
-
-void
-translatelabels(g)
- grammar *g;
-{
- int i;
-
- printf("Translating labels ...\n");
- /* Don't translate EMPTY */
- for (i = EMPTY+1; i < g->g_ll.ll_nlabels; i++)
- translabel(g, &g->g_ll.ll_label[i]);
-}
diff --git a/Parser/grammar1.c b/Parser/grammar1.c
index 0cd66af..6c10158 100644
--- a/Parser/grammar1.c
+++ b/Parser/grammar1.c
@@ -1,7 +1,6 @@
/* Grammar subroutines needed by parser */
-#include "PROTO.h"
-#define NULL 0
+#include "pgenheaders.h"
#include "assert.h"
#include "grammar.h"
#include "token.h"
diff --git a/Parser/intrcheck.c b/Parser/intrcheck.c
index f963208..8c35114 100644
--- a/Parser/intrcheck.c
+++ b/Parser/intrcheck.c
@@ -2,7 +2,7 @@
#ifdef MSDOS
-/* This might work for MS-DOS: */
+/* This might work for MS-DOS (untested though): */
void
initintr()
@@ -37,7 +37,7 @@ initintr()
int
intrcheck()
{
- /* Static to make it faster(?) only */
+ /* Static to make it faster only */
static EventRecord e;
/* XXX This fails if the user first types ahead and then
@@ -59,7 +59,7 @@ intrcheck()
#ifndef OK
-/* Default version -- should work for Unix and Standard C */
+/* Default version -- for real operating systems and for Standard C */
#include <stdio.h>
#include <signal.h>
diff --git a/Parser/listnode.c b/Parser/listnode.c
index e0a979e..9d24c0f 100644
--- a/Parser/listnode.c
+++ b/Parser/listnode.c
@@ -1,13 +1,31 @@
/* List a node on a file */
-#include <stdio.h>
-
-#include "PROTO.h"
+#include "pgenheaders.h"
#include "token.h"
#include "node.h"
+/* Forward */
+static void list1node PROTO((FILE *, node *));
+
+void
+listtree(n)
+ node *n;
+{
+ listnode(stdout, n);
+}
+
static int level, atbol;
+void
+listnode(fp, n)
+ FILE *fp;
+ node *n;
+{
+ level = 0;
+ atbol = 1;
+ list1node(fp, n);
+}
+
static void
list1node(fp, n)
FILE *fp;
@@ -49,20 +67,3 @@ list1node(fp, n)
else
fprintf(fp, "? ");
}
-
-void
-listnode(fp, n)
- FILE *fp;
- node *n;
-{
- level = 0;
- atbol = 1;
- list1node(fp, n);
-}
-
-void
-listtree(n)
- node *n;
-{
- listnode(stdout, n);
-}
diff --git a/Parser/metagrammar.c b/Parser/metagrammar.c
index a7e6364..c4606a5 100644
--- a/Parser/metagrammar.c
+++ b/Parser/metagrammar.c
@@ -1,6 +1,7 @@
-#include "PROTO.h"
+#include "pgenheaders.h"
#include "metagrammar.h"
#include "grammar.h"
+#include "pgen.h"
static arc arcs_0_0[3] = {
{2, 0},
{3, 0},
diff --git a/Parser/node.c b/Parser/node.c
index 264fd9e..024dbd4 100644
--- a/Parser/node.c
+++ b/Parser/node.c
@@ -1,11 +1,10 @@
/* Parse tree node implementation */
-#include "PROTO.h"
-#include "malloc.h"
+#include "pgenheaders.h"
#include "node.h"
node *
-newnode(type)
+newtree(type)
int type;
{
node *n = NEW(node, 1);
@@ -13,6 +12,7 @@ newnode(type)
return NULL;
n->n_type = type;
n->n_str = NULL;
+ n->n_lineno = 0;
n->n_nchildren = 0;
n->n_child = NULL;
return n;
@@ -22,10 +22,11 @@ newnode(type)
#define XXXROUNDUP(n) ((n) == 1 ? 1 : ((n) + XXX - 1) / XXX * XXX)
node *
-addchild(n1, type, str)
+addchild(n1, type, str, lineno)
register node *n1;
int type;
char *str;
+ int lineno;
{
register int nch = n1->n_nchildren;
register int nch1 = nch+1;
@@ -41,11 +42,26 @@ addchild(n1, type, str)
n = &n1->n_child[n1->n_nchildren++];
n->n_type = type;
n->n_str = str;
+ n->n_lineno = lineno;
n->n_nchildren = 0;
n->n_child = NULL;
return n;
}
+/* Forward */
+static void freechildren PROTO((node *));
+
+
+void
+freetree(n)
+ node *n;
+{
+ if (n != NULL) {
+ freechildren(n);
+ DEL(n);
+ }
+}
+
static void
freechildren(n)
node *n;
@@ -58,13 +74,3 @@ freechildren(n)
if (STR(n) != NULL)
DEL(STR(n));
}
-
-void
-freenode(n)
- node *n;
-{
- if (n != NULL) {
- freechildren(n);
- DEL(n);
- }
-}
diff --git a/Parser/parser.c b/Parser/parser.c
index 294c534..831d870 100644
--- a/Parser/parser.c
+++ b/Parser/parser.c
@@ -4,20 +4,17 @@
/* XXX To do: error recovery */
-#include <stdio.h>
+#include "pgenheaders.h"
#include "assert.h"
-
-#include "PROTO.h"
-#include "malloc.h"
#include "token.h"
#include "grammar.h"
#include "node.h"
#include "parser.h"
#include "errcode.h"
-extern int debugging;
#ifdef DEBUG
+extern int debugging;
#define D(x) if (!debugging); else x
#else
#define D(x)
@@ -94,7 +91,7 @@ newparser(g, start)
if (ps == NULL)
return NULL;
ps->p_grammar = g;
- ps->p_tree = newnode(start);
+ ps->p_tree = newtree(start);
if (ps->p_tree == NULL) {
DEL(ps);
return NULL;
@@ -110,24 +107,25 @@ delparser(ps)
{
/* NB If you want to save the parse tree,
you must set p_tree to NULL before calling delparser! */
- freenode(ps->p_tree);
+ freetree(ps->p_tree);
DEL(ps);
}
/* PARSER STACK OPERATIONS */
-static int shift PROTO((stack *, int, char *, int));
+static int shift PROTO((stack *, int, char *, int, int));
static int
-shift(s, type, str, newstate)
+shift(s, type, str, newstate, lineno)
register stack *s;
int type;
char *str;
int newstate;
+ int lineno;
{
assert(!s_empty(s));
- if (addchild(s->s_top->s_parent, type, str) == NULL) {
+ if (addchild(s->s_top->s_parent, type, str, lineno) == NULL) {
fprintf(stderr, "shift: no mem in addchild\n");
return -1;
}
@@ -135,19 +133,20 @@ shift(s, type, str, newstate)
return 0;
}
-static int push PROTO((stack *, int, dfa *, int));
+static int push PROTO((stack *, int, dfa *, int, int));
static int
-push(s, type, d, newstate)
+push(s, type, d, newstate, lineno)
register stack *s;
int type;
dfa *d;
int newstate;
+ int lineno;
{
register node *n;
n = s->s_top->s_parent;
assert(!s_empty(s));
- if (addchild(n, type, (char *)NULL) == NULL) {
+ if (addchild(n, type, (char *)NULL, lineno) == NULL) {
fprintf(stderr, "push: no mem in addchild\n");
return -1;
}
@@ -198,10 +197,11 @@ classify(g, type, str)
}
int
-addtoken(ps, type, str)
+addtoken(ps, type, str, lineno)
register parser_state *ps;
register int type;
char *str;
+ int lineno;
{
register int ilabel;
@@ -230,7 +230,8 @@ addtoken(ps, type, str)
int nt = (x >> 8) + NT_OFFSET;
int arrow = x & ((1<<7)-1);
dfa *d1 = finddfa(ps->p_grammar, nt);
- if (push(&ps->p_stack, nt, d1, arrow) < 0) {
+ if (push(&ps->p_stack, nt, d1,
+ arrow, lineno) < 0) {
D(printf(" MemError: push.\n"));
return E_NOMEM;
}
@@ -239,7 +240,8 @@ addtoken(ps, type, str)
}
/* Shift the token */
- if (shift(&ps->p_stack, type, str, x) < 0) {
+ if (shift(&ps->p_stack, type, str,
+ x, lineno) < 0) {
D(printf(" MemError: shift.\n"));
return E_NOMEM;
}
diff --git a/Parser/parser.h b/Parser/parser.h
index 16eee0e..1ada8cc 100644
--- a/Parser/parser.h
+++ b/Parser/parser.h
@@ -5,7 +5,7 @@
typedef struct _stackentry {
int s_state; /* State in current DFA */
dfa *s_dfa; /* Current DFA */
- node *s_parent; /* Where to add next node */
+ struct _node *s_parent; /* Where to add next node */
} stackentry;
typedef struct _stack {
@@ -22,4 +22,5 @@ typedef struct {
parser_state *newparser PROTO((struct _grammar *g, int start));
void delparser PROTO((parser_state *ps));
-int addtoken PROTO((parser_state *ps, int type, char *str));
+int addtoken PROTO((parser_state *ps, int type, char *str, int lineno));
+void addaccelerators PROTO((grammar *g));
diff --git a/Parser/parsetok.c b/Parser/parsetok.c
index 100ca65..c75656f 100644
--- a/Parser/parsetok.c
+++ b/Parser/parsetok.c
@@ -1,74 +1,19 @@
/* Parser-tokenizer link implementation */
-#include <stdio.h>
-
-#include "PROTO.h"
-#include "malloc.h"
+#include "pgenheaders.h"
#include "tokenizer.h"
#include "node.h"
#include "grammar.h"
#include "parser.h"
+#include "parsetok.h"
#include "errcode.h"
-extern int debugging;
-
-/* Parse input coming from the given tokenizer structure.
- Return error code. */
-
-static int
-parsetok(tok, g, start, n_ret)
- struct tok_state *tok;
- grammar *g;
- int start;
- node **n_ret;
-{
- parser_state *ps;
- int ret;
-
- if ((ps = newparser(g, start)) == NULL) {
- fprintf(stderr, "no mem for new parser\n");
- return E_NOMEM;
- }
-
- for (;;) {
- char *a, *b;
- int type;
- int len;
- char *str;
-
- type = tok_get(tok, &a, &b);
- if (type == ERRORTOKEN) {
- ret = tok->done;
- break;
- }
- len = b - a;
- str = NEW(char, len + 1);
- if (str == NULL) {
- fprintf(stderr, "no mem for next token\n");
- ret = E_NOMEM;
- break;
- }
- strncpy(str, a, len);
- str[len] = '\0';
- ret = addtoken(ps, (int)type, str);
- if (ret != E_OK) {
- if (ret == E_DONE) {
- *n_ret = ps->p_tree;
- ps->p_tree = NULL;
- }
- else if (tok->lineno <= 1 && tok->done == E_EOF)
- ret = E_EOF;
- break;
- }
- }
-
- delparser(ps);
- return ret;
-}
+/* Forward */
+static int parsetok PROTO((struct tok_state *, grammar *, int, node **));
-/* Parse input coming from a string. Return error code. */
+/* Parse input coming from a string. Return error code, print some errors. */
int
parsestring(s, g, start, n_ret)
@@ -94,11 +39,12 @@ parsestring(s, g, start, n_ret)
}
-/* Parse input coming from a file. Return error code. */
+/* Parse input coming from a file. Return error code, print some errors. */
int
-parsefile(fp, g, start, ps1, ps2, n_ret)
+parsefile(fp, filename, g, start, ps1, ps2, n_ret)
FILE *fp;
+ char *filename;
grammar *g;
int start;
char *ps1, *ps2;
@@ -114,7 +60,8 @@ parsefile(fp, g, start, ps1, ps2, n_ret)
ret = parsetok(tok, g, start, n_ret);
if (ret == E_TOKEN || ret == E_SYNTAX) {
char *p;
- fprintf(stderr, "Parsing error at line %d:\n", tok->lineno);
+ fprintf(stderr, "Parsing error: file %s, line %d:\n",
+ filename, tok->lineno);
*tok->inp = '\0';
if (tok->inp > tok->buf && tok->inp[-1] == '\n')
tok->inp[-1] = '\0';
@@ -130,3 +77,58 @@ parsefile(fp, g, start, ps1, ps2, n_ret)
tok_free(tok);
return ret;
}
+
+
+/* Parse input coming from the given tokenizer structure.
+ Return error code. */
+
+static int
+parsetok(tok, g, start, n_ret)
+ struct tok_state *tok;
+ grammar *g;
+ int start;
+ node **n_ret;
+{
+ parser_state *ps;
+ int ret;
+
+ if ((ps = newparser(g, start)) == NULL) {
+ fprintf(stderr, "no mem for new parser\n");
+ return E_NOMEM;
+ }
+
+ for (;;) {
+ char *a, *b;
+ int type;
+ int len;
+ char *str;
+
+ type = tok_get(tok, &a, &b);
+ if (type == ERRORTOKEN) {
+ ret = tok->done;
+ break;
+ }
+ len = b - a;
+ str = NEW(char, len + 1);
+ if (str == NULL) {
+ fprintf(stderr, "no mem for next token\n");
+ ret = E_NOMEM;
+ break;
+ }
+ strncpy(str, a, len);
+ str[len] = '\0';
+ ret = addtoken(ps, (int)type, str, tok->lineno);
+ if (ret != E_OK) {
+ if (ret == E_DONE) {
+ *n_ret = ps->p_tree;
+ ps->p_tree = NULL;
+ }
+ else if (tok->lineno <= 1 && tok->done == E_EOF)
+ ret = E_EOF;
+ break;
+ }
+ }
+
+ delparser(ps);
+ return ret;
+}
diff --git a/Parser/pgen.c b/Parser/pgen.c
index 34d9b71..21795d6 100644
--- a/Parser/pgen.c
+++ b/Parser/pgen.c
@@ -1,12 +1,10 @@
/* Parser generator */
+/* XXX This file is not yet fully PROTOized */
/* For a description, see the comments at end of this file */
-#include <stdio.h>
+#include "pgenheaders.h"
#include "assert.h"
-
-#include "PROTO.h"
-#include "malloc.h"
#include "token.h"
#include "node.h"
#include "grammar.h"
diff --git a/Parser/pgen.h b/Parser/pgen.h
index 7fcf277..45eb2ed 100644
--- a/Parser/pgen.h
+++ b/Parser/pgen.h
@@ -3,4 +3,4 @@
extern grammar gram;
extern grammar *meta_grammar PROTO((void));
-extern grammar *pgen PROTO((node *));
+extern grammar *pgen PROTO((struct _node *));
diff --git a/Parser/pgenmain.c b/Parser/pgenmain.c
index 678be5d..6eae230 100644
--- a/Parser/pgenmain.c
+++ b/Parser/pgenmain.c
@@ -1,8 +1,14 @@
/* Parser generator main program */
-#include <stdio.h>
+/* This expects a filename containing the grammar as argv[1] (UNIX)
+ or asks the console for such a file name (THINK C).
+ It writes its output on two files in the current directory:
+ - "graminit.c" gets the grammar as a bunch of initialized data
+ - "graminit.h" gets the grammar's non-terminals as #defines.
+ Error messages and status info during the generation process are
+ written to stdout, or sometimes to stderr. */
-#include "PROTO.h"
+#include "pgenheaders.h"
#include "grammar.h"
#include "node.h"
#include "parsetok.h"
@@ -10,24 +16,51 @@
int debugging;
+/* Forward */
+grammar *getgrammar PROTO((char *filename));
#ifdef THINK_C
-char *
-askfile()
+int main PROTO((int, char **));
+char *askfile PROTO((void));
+#endif
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
{
- char buf[256];
- static char name[256];
- printf("Input file name: ");
- if (fgets(buf, sizeof buf, stdin) == NULL) {
- printf("EOF\n");
+ grammar *g;
+ node *n;
+ FILE *fp;
+ char *filename;
+
+#ifdef THINK_C
+ filename = askfile();
+#else
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s grammar\n", argv[0]);
+ exit(2);
+ }
+ filename = argv[1];
+#endif
+ g = getgrammar(filename);
+ fp = fopen("graminit.c", "w");
+ if (fp == NULL) {
+ perror("graminit.c");
exit(1);
}
- if (sscanf(buf, " %s ", name) != 1) {
- printf("No file\n");
+ printf("Writing graminit.c ...\n");
+ printgrammar(g, fp);
+ fclose(fp);
+ fp = fopen("graminit.h", "w");
+ if (fp == NULL) {
+ perror("graminit.h");
exit(1);
}
- return name;
+ printf("Writing graminit.h ...\n");
+ printnonterminals(g, fp);
+ fclose(fp);
+ exit(0);
}
-#endif
grammar *
getgrammar(filename)
@@ -44,7 +77,7 @@ getgrammar(filename)
}
g0 = meta_grammar();
n = NULL;
- parsefile(fp, g0, g0->g_start, (char *)NULL, (char *)NULL, &n);
+ parsefile(fp, filename, g0, g0->g_start, (char *)NULL, (char *)NULL, &n);
fclose(fp);
if (n == NULL) {
fprintf(stderr, "Parsing error.\n");
@@ -58,43 +91,25 @@ getgrammar(filename)
return g;
}
-main(argc, argv)
- int argc;
- char **argv;
-{
- grammar *g;
- node *n;
- FILE *fp;
- char *filename;
-
#ifdef THINK_C
- filename = askfile();
-#else
- if (argc != 2) {
- fprintf(stderr, "usage: %s grammar\n", argv[0]);
- exit(2);
- }
- filename = argv[1];
-#endif
- g = getgrammar(filename);
- fp = fopen("graminit.c", "w");
- if (fp == NULL) {
- perror("graminit.c");
+char *
+askfile()
+{
+ char buf[256];
+ static char name[256];
+ printf("Input file name: ");
+ if (fgets(buf, sizeof buf, stdin) == NULL) {
+ printf("EOF\n");
exit(1);
}
- printf("Writing graminit.c ...\n");
- printgrammar(g, fp);
- fclose(fp);
- fp = fopen("graminit.h", "w");
- if (fp == NULL) {
- perror("graminit.h");
+ /* XXX The (unsigned char *) case is needed by THINK C */
+ if (sscanf((unsigned char *)buf, " %s ", name) != 1) {
+ printf("No file\n");
exit(1);
}
- printf("Writing graminit.h ...\n");
- printnonterminals(g, fp);
- fclose(fp);
- exit(0);
+ return name;
}
+#endif
void
fatal(msg)
@@ -104,8 +119,6 @@ fatal(msg)
exit(1);
}
-/* TO DO:
-
- - improve user interface
- - check for duplicate definitions of names (instead of fatal err)
+/* XXX TO DO:
+ - check for duplicate definitions of names (instead of fatal err)
*/
diff --git a/Parser/printgrammar.c b/Parser/printgrammar.c
index f6aa2cc..00a8d47 100644
--- a/Parser/printgrammar.c
+++ b/Parser/printgrammar.c
@@ -1,10 +1,44 @@
/* Print a bunch of C initializers that represent a grammar */
-#include <stdio.h>
-
-#include "PROTO.h"
+#include "pgenheaders.h"
#include "grammar.h"
+/* Forward */
+static void printarcs PROTO((int, dfa *, FILE *));
+static void printstates PROTO((grammar *, FILE *));
+static void printdfas PROTO((grammar *, FILE *));
+static void printlabels PROTO((grammar *, FILE *));
+
+void
+printgrammar(g, fp)
+ grammar *g;
+ FILE *fp;
+{
+ fprintf(fp, "#include \"pgenheaders.h\"\n");
+ fprintf(fp, "#include \"grammar.h\"\n");
+ printdfas(g, fp);
+ printlabels(g, fp);
+ fprintf(fp, "grammar gram = {\n");
+ fprintf(fp, "\t%d,\n", g->g_ndfas);
+ fprintf(fp, "\tdfas,\n");
+ fprintf(fp, "\t{%d, labels},\n", g->g_ll.ll_nlabels);
+ fprintf(fp, "\t%d\n", g->g_start);
+ fprintf(fp, "};\n");
+}
+
+void
+printnonterminals(g, fp)
+ grammar *g;
+ FILE *fp;
+{
+ dfa *d;
+ int i;
+
+ d = g->g_dfa;
+ for (i = g->g_ndfas; --i >= 0; d++)
+ fprintf(fp, "#define %s %d\n", d->d_name, d->d_type);
+}
+
static void
printarcs(i, d, fp)
int i;
@@ -89,33 +123,3 @@ printlabels(g, fp)
}
fprintf(fp, "};\n");
}
-
-void
-printgrammar(g, fp)
- grammar *g;
- FILE *fp;
-{
- fprintf(fp, "#include \"PROTO.h\"\n");
- fprintf(fp, "#include \"grammar.h\"\n");
- printdfas(g, fp);
- printlabels(g, fp);
- fprintf(fp, "grammar gram = {\n");
- fprintf(fp, "\t%d,\n", g->g_ndfas);
- fprintf(fp, "\tdfas,\n");
- fprintf(fp, "\t{%d, labels},\n", g->g_ll.ll_nlabels);
- fprintf(fp, "\t%d\n", g->g_start);
- fprintf(fp, "};\n");
-}
-
-void
-printnonterminals(g, fp)
- grammar *g;
- FILE *fp;
-{
- dfa *d;
- int i;
-
- d = g->g_dfa;
- for (i = g->g_ndfas; --i >= 0; d++)
- fprintf(fp, "#define %s %d\n", d->d_name, d->d_type);
-}
diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c
index 97eda75..ad6f63a 100644
--- a/Parser/tokenizer.c
+++ b/Parser/tokenizer.c
@@ -2,13 +2,14 @@
/* XXX This is rather old, should be restructured perhaps */
/* XXX Need a better interface to report errors than writing to stderr */
+/* XXX Should use editor resource to fetch true tab size on Macintosh */
+
+#include "pgenheaders.h"
-#include <stdio.h>
#include <ctype.h>
#include "string.h"
-#include "PROTO.h"
-#include "malloc.h"
+#include "fgetsintr.h"
#include "tokenizer.h"
#include "errcode.h"
@@ -20,6 +21,11 @@
#define TABSIZE 8
#endif
+/* Forward */
+static struct tok_state *tok_new PROTO((void));
+static int tok_nextc PROTO((struct tok_state *tok));
+static void tok_backup PROTO((struct tok_state *tok, int c));
+
/* Token names */
char *tok_name[] = {
@@ -352,7 +358,9 @@ tok_get(tok, p_start, p_end)
This is also recognized by vi, when it occurs near the
beginning or end of the file. (Will vi never die...?) */
int x;
- if (sscanf(tok->cur, " vi:set tabsize=%d:", &x) == 1 &&
+ /* XXX The case to (unsigned char *) is needed by THINK C */
+ if (sscanf((unsigned char *)tok->cur,
+ " vi:set tabsize=%d:", &x) == 1 &&
x >= 1 && x <= 40) {
fprintf(stderr, "# vi:set tabsize=%d:\n", x);
tok->tabsize = x;