blob: 9ed8cab8599419b012e6b88a77f30b3ed3dafa3a [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 Rossum85a5fbb1990-10-14 12:07:46 +000053
Guido van Rossum3f5da241990-12-20 15:06:42 +000054/* Forward */
Guido van Rossum86bea461997-04-29 21:03:06 +000055grammar *getgrammar Py_PROTO((char *filename));
Guido van Rossum1d5735e1994-08-30 08:27:36 +000056#ifdef THINK_C
Guido van Rossum86bea461997-04-29 21:03:06 +000057int main Py_PROTO((int, char **));
58char *askfile Py_PROTO((void));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000059#endif
60
Guido van Rossumf1dc5661993-07-05 10:31:29 +000061void
Guido van Rossum86bea461997-04-29 21:03:06 +000062Py_Exit(sts)
Guido van Rossumf1dc5661993-07-05 10:31:29 +000063 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 Rossum86bea461997-04-29 21:03:06 +000082 Py_Exit(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 Rossum86bea461997-04-29 21:03:06 +000090 Py_Exit(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 Rossum86bea461997-04-29 21:03:06 +000098 Py_Exit(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 Rossum86bea461997-04-29 21:03:06 +0000103 Py_Exit(0);
Guido van Rossumfd8a3931996-12-02 18:27:33 +0000104 return 0; /* Make gcc -Wall happy */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000105}
106
Guido van Rossum3f5da241990-12-20 15:06:42 +0000107grammar *
108getgrammar(filename)
109 char *filename;
110{
111 FILE *fp;
112 node *n;
113 grammar *g0, *g;
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000114 perrdetail err;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000115
116 fp = fopen(filename, "r");
117 if (fp == NULL) {
118 perror(filename);
Guido van Rossum86bea461997-04-29 21:03:06 +0000119 Py_Exit(1);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000120 }
121 g0 = meta_grammar();
Guido van Rossum86bea461997-04-29 21:03:06 +0000122 n = PyParser_ParseFile(fp, filename, g0, g0->g_start,
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000123 (char *)NULL, (char *)NULL, &err);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000124 fclose(fp);
125 if (n == NULL) {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000126 fprintf(stderr, "Parsing error %d, line %d.\n",
127 err.error, err.lineno);
128 if (err.text != NULL) {
129 int i;
130 fprintf(stderr, "%s", err.text);
131 i = strlen(err.text);
132 if (i == 0 || err.text[i-1] != '\n')
133 fprintf(stderr, "\n");
134 for (i = 0; i < err.offset; i++) {
135 if (err.text[i] == '\t')
136 putc('\t', stderr);
137 else
138 putc(' ', stderr);
139 }
140 fprintf(stderr, "^\n");
141 free(err.text);
142 }
Guido van Rossum86bea461997-04-29 21:03:06 +0000143 Py_Exit(1);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000144 }
145 g = pgen(n);
146 if (g == NULL) {
147 printf("Bad grammar.\n");
Guido van Rossum86bea461997-04-29 21:03:06 +0000148 Py_Exit(1);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000149 }
150 return g;
151}
152
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000153#ifdef THINK_C
Guido van Rossum3f5da241990-12-20 15:06:42 +0000154char *
155askfile()
156{
157 char buf[256];
158 static char name[256];
159 printf("Input file name: ");
160 if (fgets(buf, sizeof buf, stdin) == NULL) {
161 printf("EOF\n");
Guido van Rossum86bea461997-04-29 21:03:06 +0000162 Py_Exit(1);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000163 }
Guido van Rossum706eea81990-12-20 23:11:02 +0000164 /* XXX The (unsigned char *) case is needed by THINK C 3.0 */
165 if (sscanf(/*(unsigned char *)*/buf, " %s ", name) != 1) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000166 printf("No file\n");
Guido van Rossum86bea461997-04-29 21:03:06 +0000167 Py_Exit(1);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000168 }
169 return name;
170}
171#endif
172
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000173void
Guido van Rossum86bea461997-04-29 21:03:06 +0000174Py_FatalError(msg)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000175 char *msg;
176{
177 fprintf(stderr, "pgen: FATAL ERROR: %s\n", msg);
Guido van Rossum86bea461997-04-29 21:03:06 +0000178 Py_Exit(1);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000179}
180
Guido van Rossum7ebb23c1992-03-27 17:31:35 +0000181#ifdef macintosh
182/* ARGSUSED */
183int
184guesstabsize(path)
185 char *path;
186{
187 return 4;
188}
189#endif
190
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000191/* No-nonsense my_readline() for tokenizer.c */
192
193char *
Guido van Rossum86bea461997-04-29 21:03:06 +0000194PyOS_Readline(prompt)
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000195 char *prompt;
196{
197 int n = 1000;
198 char *p = malloc(n);
199 char *q;
200 if (p == NULL)
201 return NULL;
202 fprintf(stderr, "%s", prompt);
203 q = fgets(p, n, stdin);
204 if (q == NULL) {
205 *p = '\0';
206 return p;
207 }
208 n = strlen(p);
209 if (n > 0 && p[n-1] != '\n')
210 p[n-1] = '\n';
211 return realloc(p, n+1);
212}