blob: 72924854309bb8bd69a2dd49456b709c6ae3eb13 [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
Guido van Rossum86bea461997-04-29 21:03:06 +000052int Py_DebugFlag;
Guido van Rossumc0952001998-04-10 19:34:15 +000053int Py_VerboseFlag;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000054
Guido van Rossum3f5da241990-12-20 15:06:42 +000055/* Forward */
Guido van Rossum86bea461997-04-29 21:03:06 +000056grammar *getgrammar Py_PROTO((char *filename));
Guido van Rossum1d5735e1994-08-30 08:27:36 +000057#ifdef THINK_C
Guido van Rossum86bea461997-04-29 21:03:06 +000058int main Py_PROTO((int, char **));
59char *askfile Py_PROTO((void));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000060#endif
61
Guido van Rossumf1dc5661993-07-05 10:31:29 +000062void
Guido van Rossum86bea461997-04-29 21:03:06 +000063Py_Exit(sts)
Guido van Rossumf1dc5661993-07-05 10:31:29 +000064 int sts;
65{
66 exit(sts);
67}
68
Guido van Rossum3f5da241990-12-20 15:06:42 +000069int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000070main(argc, argv)
71 int argc;
72 char **argv;
73{
74 grammar *g;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075 FILE *fp;
76 char *filename;
77
Guido van Rossum1d5735e1994-08-30 08:27:36 +000078#ifdef THINK_C
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000079 filename = askfile();
80#else
81 if (argc != 2) {
82 fprintf(stderr, "usage: %s grammar\n", argv[0]);
Guido van Rossum86bea461997-04-29 21:03:06 +000083 Py_Exit(2);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000084 }
85 filename = argv[1];
86#endif
87 g = getgrammar(filename);
88 fp = fopen("graminit.c", "w");
89 if (fp == NULL) {
90 perror("graminit.c");
Guido van Rossum86bea461997-04-29 21:03:06 +000091 Py_Exit(1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000092 }
93 printf("Writing graminit.c ...\n");
94 printgrammar(g, fp);
95 fclose(fp);
96 fp = fopen("graminit.h", "w");
97 if (fp == NULL) {
98 perror("graminit.h");
Guido van Rossum86bea461997-04-29 21:03:06 +000099 Py_Exit(1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000100 }
101 printf("Writing graminit.h ...\n");
102 printnonterminals(g, fp);
103 fclose(fp);
Guido van Rossum86bea461997-04-29 21:03:06 +0000104 Py_Exit(0);
Guido van Rossumfd8a3931996-12-02 18:27:33 +0000105 return 0; /* Make gcc -Wall happy */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000106}
107
Guido van Rossum3f5da241990-12-20 15:06:42 +0000108grammar *
109getgrammar(filename)
110 char *filename;
111{
112 FILE *fp;
113 node *n;
114 grammar *g0, *g;
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000115 perrdetail err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000116
117 fp = fopen(filename, "r");
118 if (fp == NULL) {
119 perror(filename);
Guido van Rossum86bea461997-04-29 21:03:06 +0000120 Py_Exit(1);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000121 }
122 g0 = meta_grammar();
Guido van Rossum86bea461997-04-29 21:03:06 +0000123 n = PyParser_ParseFile(fp, filename, g0, g0->g_start,
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000124 (char *)NULL, (char *)NULL, &err);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000125 fclose(fp);
126 if (n == NULL) {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000127 fprintf(stderr, "Parsing error %d, line %d.\n",
128 err.error, err.lineno);
129 if (err.text != NULL) {
130 int i;
131 fprintf(stderr, "%s", err.text);
132 i = strlen(err.text);
133 if (i == 0 || err.text[i-1] != '\n')
134 fprintf(stderr, "\n");
135 for (i = 0; i < err.offset; i++) {
136 if (err.text[i] == '\t')
137 putc('\t', stderr);
138 else
139 putc(' ', stderr);
140 }
141 fprintf(stderr, "^\n");
142 free(err.text);
143 }
Guido van Rossum86bea461997-04-29 21:03:06 +0000144 Py_Exit(1);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000145 }
146 g = pgen(n);
147 if (g == NULL) {
148 printf("Bad grammar.\n");
Guido van Rossum86bea461997-04-29 21:03:06 +0000149 Py_Exit(1);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000150 }
151 return g;
152}
153
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000154#ifdef THINK_C
Guido van Rossum3f5da241990-12-20 15:06:42 +0000155char *
156askfile()
157{
158 char buf[256];
159 static char name[256];
160 printf("Input file name: ");
161 if (fgets(buf, sizeof buf, stdin) == NULL) {
162 printf("EOF\n");
Guido van Rossum86bea461997-04-29 21:03:06 +0000163 Py_Exit(1);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000164 }
Guido van Rossum706eea81990-12-20 23:11:02 +0000165 /* XXX The (unsigned char *) case is needed by THINK C 3.0 */
166 if (sscanf(/*(unsigned char *)*/buf, " %s ", name) != 1) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000167 printf("No file\n");
Guido van Rossum86bea461997-04-29 21:03:06 +0000168 Py_Exit(1);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000169 }
170 return name;
171}
172#endif
173
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000174void
Guido van Rossum86bea461997-04-29 21:03:06 +0000175Py_FatalError(msg)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000176 char *msg;
177{
178 fprintf(stderr, "pgen: FATAL ERROR: %s\n", msg);
Guido van Rossum86bea461997-04-29 21:03:06 +0000179 Py_Exit(1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000180}
181
Guido van Rossum7ebb23c1992-03-27 17:31:35 +0000182#ifdef macintosh
183/* ARGSUSED */
184int
185guesstabsize(path)
186 char *path;
187{
188 return 4;
189}
190#endif
191
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000192/* No-nonsense my_readline() for tokenizer.c */
193
194char *
Guido van Rossum86bea461997-04-29 21:03:06 +0000195PyOS_Readline(prompt)
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000196 char *prompt;
197{
198 int n = 1000;
199 char *p = malloc(n);
200 char *q;
201 if (p == NULL)
202 return NULL;
203 fprintf(stderr, "%s", prompt);
204 q = fgets(p, n, stdin);
205 if (q == NULL) {
206 *p = '\0';
207 return p;
208 }
209 n = strlen(p);
210 if (n > 0 && p[n-1] != '\n')
211 p[n-1] = '\n';
212 return realloc(p, n+1);
213}
Guido van Rossum47fbc401998-08-25 18:12:36 +0000214
215#ifdef HAVE_STDARG_PROTOTYPES
216#include <stdarg.h>
217#else
218#include <varargs.h>
219#endif
220
221void
222#ifdef HAVE_STDARG_PROTOTYPES
223PySys_WriteStderr(const char *format, ...)
224#else
225PySys_WriteStderr(va_alist)
226 va_dcl
227#endif
228{
229 va_list va;
230
231#ifdef HAVE_STDARG_PROTOTYPES
232 va_start(va, format);
233#else
234 char *format;
235 va_start(va);
236 format = va_arg(va, char *);
237#endif
238 vfprintf(stderr, format, va);
239 va_end(va);
240}