blob: 98b5ac5c03e3e3818c589a3d277feace47e4a87b [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumb9f8d6e1995-01-04 19:08:09 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf70e43a1991-02-19 12:39:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000029
30******************************************************************/
31
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032/* Parser generator main program */
33
Guido van Rossum3f5da241990-12-20 15:06:42 +000034/* This expects a filename containing the grammar as argv[1] (UNIX)
35 or asks the console for such a file name (THINK C).
36 It writes its output on two files in the current directory:
37 - "graminit.c" gets the grammar as a bunch of initialized data
38 - "graminit.h" gets the grammar's non-terminals as #defines.
39 Error messages and status info during the generation process are
40 written to stdout, or sometimes to stderr. */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000041
Guido van Rossum1d5735e1994-08-30 08:27:36 +000042/* XXX TO DO:
43 - check for duplicate definitions of names (instead of fatal err)
44*/
45
Guido van Rossum3f5da241990-12-20 15:06:42 +000046#include "pgenheaders.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000047#include "grammar.h"
48#include "node.h"
49#include "parsetok.h"
50#include "pgen.h"
51
52int debugging;
53
Guido van Rossum3f5da241990-12-20 15:06:42 +000054/* Forward */
55grammar *getgrammar PROTO((char *filename));
Guido van Rossum1d5735e1994-08-30 08:27:36 +000056#ifdef THINK_C
Guido van Rossum3f5da241990-12-20 15:06:42 +000057int main PROTO((int, char **));
58char *askfile PROTO((void));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000059#endif
60
Guido van Rossumf1dc5661993-07-05 10:31:29 +000061void
62goaway(sts)
63 int sts;
64{
65 exit(sts);
66}
67
Guido van Rossum3f5da241990-12-20 15:06:42 +000068int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000069main(argc, argv)
70 int argc;
71 char **argv;
72{
73 grammar *g;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000074 FILE *fp;
75 char *filename;
76
Guido van Rossum1d5735e1994-08-30 08:27:36 +000077#ifdef THINK_C
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000078 filename = askfile();
79#else
80 if (argc != 2) {
81 fprintf(stderr, "usage: %s grammar\n", argv[0]);
Guido van Rossumf1dc5661993-07-05 10:31:29 +000082 goaway(2);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000083 }
84 filename = argv[1];
85#endif
86 g = getgrammar(filename);
87 fp = fopen("graminit.c", "w");
88 if (fp == NULL) {
89 perror("graminit.c");
Guido van Rossumf1dc5661993-07-05 10:31:29 +000090 goaway(1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000091 }
92 printf("Writing graminit.c ...\n");
93 printgrammar(g, fp);
94 fclose(fp);
95 fp = fopen("graminit.h", "w");
96 if (fp == NULL) {
97 perror("graminit.h");
Guido van Rossumf1dc5661993-07-05 10:31:29 +000098 goaway(1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000099 }
100 printf("Writing graminit.h ...\n");
101 printnonterminals(g, fp);
102 fclose(fp);
Guido van Rossumf1dc5661993-07-05 10:31:29 +0000103 goaway(0);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000104}
105
Guido van Rossum3f5da241990-12-20 15:06:42 +0000106grammar *
107getgrammar(filename)
108 char *filename;
109{
110 FILE *fp;
111 node *n;
112 grammar *g0, *g;
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000113 perrdetail err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000114
115 fp = fopen(filename, "r");
116 if (fp == NULL) {
117 perror(filename);
Guido van Rossumf1dc5661993-07-05 10:31:29 +0000118 goaway(1);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000119 }
120 g0 = meta_grammar();
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000121 n = parsefile(fp, filename, g0, g0->g_start,
122 (char *)NULL, (char *)NULL, &err);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000123 fclose(fp);
124 if (n == NULL) {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000125 fprintf(stderr, "Parsing error %d, line %d.\n",
126 err.error, err.lineno);
127 if (err.text != NULL) {
128 int i;
129 fprintf(stderr, "%s", err.text);
130 i = strlen(err.text);
131 if (i == 0 || err.text[i-1] != '\n')
132 fprintf(stderr, "\n");
133 for (i = 0; i < err.offset; i++) {
134 if (err.text[i] == '\t')
135 putc('\t', stderr);
136 else
137 putc(' ', stderr);
138 }
139 fprintf(stderr, "^\n");
140 free(err.text);
141 }
Guido van Rossumf1dc5661993-07-05 10:31:29 +0000142 goaway(1);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000143 }
144 g = pgen(n);
145 if (g == NULL) {
146 printf("Bad grammar.\n");
Guido van Rossumf1dc5661993-07-05 10:31:29 +0000147 goaway(1);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000148 }
149 return g;
150}
151
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000152#ifdef THINK_C
Guido van Rossum3f5da241990-12-20 15:06:42 +0000153char *
154askfile()
155{
156 char buf[256];
157 static char name[256];
158 printf("Input file name: ");
159 if (fgets(buf, sizeof buf, stdin) == NULL) {
160 printf("EOF\n");
Guido van Rossumf1dc5661993-07-05 10:31:29 +0000161 goaway(1);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000162 }
Guido van Rossum706eea81990-12-20 23:11:02 +0000163 /* XXX The (unsigned char *) case is needed by THINK C 3.0 */
164 if (sscanf(/*(unsigned char *)*/buf, " %s ", name) != 1) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000165 printf("No file\n");
Guido van Rossumf1dc5661993-07-05 10:31:29 +0000166 goaway(1);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000167 }
168 return name;
169}
170#endif
171
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000172void
173fatal(msg)
174 char *msg;
175{
176 fprintf(stderr, "pgen: FATAL ERROR: %s\n", msg);
Guido van Rossumf1dc5661993-07-05 10:31:29 +0000177 goaway(1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178}
179
Guido van Rossum7ebb23c1992-03-27 17:31:35 +0000180#ifdef macintosh
181/* ARGSUSED */
182int
183guesstabsize(path)
184 char *path;
185{
186 return 4;
187}
188#endif
189
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000190/* No-nonsense my_readline() for tokenizer.c */
191
192char *
193my_readline(prompt)
194 char *prompt;
195{
196 int n = 1000;
197 char *p = malloc(n);
198 char *q;
199 if (p == NULL)
200 return NULL;
201 fprintf(stderr, "%s", prompt);
202 q = fgets(p, n, stdin);
203 if (q == NULL) {
204 *p = '\0';
205 return p;
206 }
207 n = strlen(p);
208 if (n > 0 && p[n-1] != '\n')
209 p[n-1] = '\n';
210 return realloc(p, n+1);
211}