This commit was manufactured by cvs2svn to create tag 'release101'.
[python/dscho.git] / Parser / pgenmain.c
blob2a4e725889eabcba72c4fe744cf66fcb0c263df4
1 /***********************************************************
2 Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
3 Amsterdam, The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
25 /* Parser generator main program */
27 /* This expects a filename containing the grammar as argv[1] (UNIX)
28 or asks the console for such a file name (THINK C).
29 It writes its output on two files in the current directory:
30 - "graminit.c" gets the grammar as a bunch of initialized data
31 - "graminit.h" gets the grammar's non-terminals as #defines.
32 Error messages and status info during the generation process are
33 written to stdout, or sometimes to stderr. */
35 /* XXX TO DO:
36 - check for duplicate definitions of names (instead of fatal err)
39 #include "pgenheaders.h"
40 #include "grammar.h"
41 #include "node.h"
42 #include "parsetok.h"
43 #include "pgen.h"
45 int debugging;
47 /* Forward */
48 grammar *getgrammar PROTO((char *filename));
49 #ifdef macintosh
50 int main PROTO((int, char **));
51 char *askfile PROTO((void));
52 #endif
54 void
55 goaway(sts)
56 int sts;
58 exit(sts);
61 int
62 main(argc, argv)
63 int argc;
64 char **argv;
66 grammar *g;
67 node *n;
68 FILE *fp;
69 char *filename;
71 #ifdef macintosh
72 filename = askfile();
73 #else
74 if (argc != 2) {
75 fprintf(stderr, "usage: %s grammar\n", argv[0]);
76 goaway(2);
78 filename = argv[1];
79 #endif
80 g = getgrammar(filename);
81 fp = fopen("graminit.c", "w");
82 if (fp == NULL) {
83 perror("graminit.c");
84 goaway(1);
86 printf("Writing graminit.c ...\n");
87 printgrammar(g, fp);
88 fclose(fp);
89 fp = fopen("graminit.h", "w");
90 if (fp == NULL) {
91 perror("graminit.h");
92 goaway(1);
94 printf("Writing graminit.h ...\n");
95 printnonterminals(g, fp);
96 fclose(fp);
97 goaway(0);
100 grammar *
101 getgrammar(filename)
102 char *filename;
104 FILE *fp;
105 node *n;
106 grammar *g0, *g;
107 perrdetail err;
109 fp = fopen(filename, "r");
110 if (fp == NULL) {
111 perror(filename);
112 goaway(1);
114 g0 = meta_grammar();
115 n = parsefile(fp, filename, g0, g0->g_start,
116 (char *)NULL, (char *)NULL, &err);
117 fclose(fp);
118 if (n == NULL) {
119 fprintf(stderr, "Parsing error %d, line %d.\n",
120 err.error, err.lineno);
121 if (err.text != NULL) {
122 int i;
123 fprintf(stderr, "%s", err.text);
124 i = strlen(err.text);
125 if (i == 0 || err.text[i-1] != '\n')
126 fprintf(stderr, "\n");
127 for (i = 0; i < err.offset; i++) {
128 if (err.text[i] == '\t')
129 putc('\t', stderr);
130 else
131 putc(' ', stderr);
133 fprintf(stderr, "^\n");
134 free(err.text);
136 goaway(1);
138 g = pgen(n);
139 if (g == NULL) {
140 printf("Bad grammar.\n");
141 goaway(1);
143 return g;
146 #ifdef macintosh
147 char *
148 askfile()
150 char buf[256];
151 static char name[256];
152 printf("Input file name: ");
153 if (fgets(buf, sizeof buf, stdin) == NULL) {
154 printf("EOF\n");
155 goaway(1);
157 /* XXX The (unsigned char *) case is needed by THINK C 3.0 */
158 if (sscanf(/*(unsigned char *)*/buf, " %s ", name) != 1) {
159 printf("No file\n");
160 goaway(1);
162 return name;
164 #endif
166 void
167 fatal(msg)
168 char *msg;
170 fprintf(stderr, "pgen: FATAL ERROR: %s\n", msg);
171 goaway(1);
174 #ifdef macintosh
175 /* ARGSUSED */
177 guesstabsize(path)
178 char *path;
180 return 4;
182 #endif
184 /* No-nonsense my_readline() for tokenizer.c */
186 char *
187 my_readline(prompt)
188 char *prompt;
190 int n = 1000;
191 char *p = malloc(n);
192 char *q;
193 if (p == NULL)
194 return NULL;
195 fprintf(stderr, "%s", prompt);
196 q = fgets(p, n, stdin);
197 if (q == NULL) {
198 *p = '\0';
199 return p;
201 n = strlen(p);
202 if (n > 0 && p[n-1] != '\n')
203 p[n-1] = '\n';
204 return realloc(p, n+1);