1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <fcntl.h>
4
5 #if __MSDOS__ || MSDOS || WIN32 || __WIN32__
6 # include <io.h>
7 #else
8 # include <unistd.h>
9 # define O_BINARY 0
10 #endif
11
12 #if NEXTSTEP
13 # include <sys/file.h>
14 #endif
15
16 #include <string.h>
17 #include "crt.h"
18 #include "crx.h"
19 #include "cra.h"
20 #include "crf.h"
21 #include "crp.h"
22 #include "crs.h"
23
24 struct ErrDesc {
25 int nr, line, col;
26 struct ErrDesc *next;
27 };
28
29 static FILE *lst;
30 static struct ErrDesc *FirstErr = NULL, *LastErr;
31 int Errors = 0;
32 extern Error_Func Custom_Error;
33
34 static char *ErrorMsg[] = {
35 #include "cre.h"
36 "User error number clash",
37 ""
38 };
39
40 static char Version[] = "1.17 (C/C++ Version)";
41 static char ReleaseDate[] = "Sep 17 2002";
42
43 /* --------------------------- Help ------------------------------------------ */
44
Help(void)45 static void Help(void)
46 { fprintf(stdout,
47 "Coco/R - Compiler-Compiler V%s "
48 "(Frankie Arzu, %s)\n\n"
49 "Usage: COCOR [(/|-)Options] <Grammar.atg> for Dos/Windows\n"
50 "Usage: COCOR [-Options] <Grammar.atg> for Unix\n"
51 "Example: COCOR -C -S Test.atg\n\n"
52 "Options:\n"
53 "A - Trace automaton C - Generate compiler module\n"
54 "D - Include source debugging information (#line)\n"
55 "F - Give Start and Follower sets G - Print top-down graph\n"
56 "L - Force listing O - Terminal conditions use OR only\n"
57 "P - Generate parser only S - Print symbol table\n"
58 "T - Grammar tests only Q - Quiet (Edit) mode\n"
59 "X - Generate C++ with classes Z - Force extensions to .hpp and .cpp\n\n"
60 "Environment variables:\n"
61 "CRFRAMES: Search directory for frames file. If not specified,\n"
62 " frames must be in the working directory.\n"
63 "CRHEXT: Extension for the '.h' generated files. If not specified,\n"
64 " '.h' for C, '.hpp' for C++ (Dos and Unix). \n"
65 "CRCEXT: Extension for the '.c' generated files. If not specified,\n"
66 " '.c' for C, '.cpp' for C++ (Dos and Unix). \n"
67 "Frame and extension options may also be set using -Dvarname=value\n",
68 Version, ReleaseDate);
69 }
70
StoreError(int nr,int line,int col,long pos)71 void StoreError(int nr, int line, int col, long pos)
72 /* Store an error message for later printing */
73 { struct ErrDesc *NextErr;
74
75 NextErr = (struct ErrDesc *) malloc(sizeof(struct ErrDesc));
76 NextErr->nr = nr; NextErr->line = line; NextErr->col = col;
77 NextErr->next = NULL;
78 if (FirstErr == NULL) FirstErr = NextErr;
79 else LastErr->next = NextErr;
80 LastErr = NextErr;
81 Errors++;
82 }
83
GetLine(long pos,char * line)84 static long GetLine(long pos, char *line)
85 /* Read a source line. Return empty line if eof */
86 { char ch;
87 int i;
88 int col = 1;
89
90 ch = S_CurrentCh(pos);
91 while (ch && ch != LF_CHAR && ch != EOF_CHAR) {
92 if (ch == TAB_CHAR) {
93 i = TAB_SIZE - (col % TAB_SIZE) + 1;
94 while (i--) { *line++ = ' '; col++; }
95 }
96 else if (ch != CR_CHAR) { *line++ = ch; col++; }
97 pos++;
98 ch = S_CurrentCh(pos);
99 }
100 *line = 0;
101 if (ch != EOF_CHAR) return pos + 1;
102 else return -1;
103 }
104
PrintErrMsg(int nr)105 static void PrintErrMsg(int nr)
106 {
107 if (nr <= MAXERROR) fprintf(lst, "%s", ErrorMsg[nr]);
108 else
109 switch (nr) {
110 case 101:
111 fprintf(lst, "character set may not be empty");
112 break;
113 case 102:
114 fprintf(lst, "string literal may not extend over line end");
115 break;
116 case 103:
117 fprintf(lst, "a literal must not have attributes");
118 break;
119 case 104:
120 fprintf(lst, "this symbol kind not allowed in production");
121 break;
122 case 105:
123 fprintf(lst, "attribute mismatch between declaration and use");
124 break;
125 case 106:
126 fprintf(lst, "undefined string in production");
127 break;
128 case 107:
129 fprintf(lst, "name declared twice");
130 break;
131 case 108:
132 fprintf(lst, "this type not allowed on left side of production");
133 break;
134 case 109:
135 fprintf(lst, "earlier semantic action was not terminated");
136 break;
137 case 111:
138 fprintf(lst, "no production found for grammar name");
139 break;
140 case 112:
141 fprintf(lst, "grammar symbol must not have attributes");
142 break;
143 case 113:
144 fprintf(lst, "a literal must not be declared with a structure");
145 break;
146 case 114:
147 fprintf(lst, "semantic action not allowed here");
148 break;
149 case 115:
150 fprintf(lst, "undefined name");
151 break;
152 case 116:
153 fprintf(lst, "attributes not allowed in token declaration");
154 break;
155 case 117:
156 fprintf(lst, "name does not match name in heading");
157 break;
158 case 118:
159 fprintf(lst, "unacceptable constant value");
160 break;
161 case 119:
162 fprintf(lst, "may not ignore CHR(0)");
163 break;
164 case 120:
165 fprintf(lst, "token might be empty");
166 break;
167 case 121:
168 fprintf(lst, "token must not start with an iteration");
169 break;
170 case 122:
171 fprintf(lst, "comment delimiters may not be structured");
172 break;
173 case 123:
174 fprintf(lst, "only terminals may be weak");
175 break;
176 case 124:
177 fprintf(lst, "literal tokens may not contain white space");
178 break;
179 case 125:
180 fprintf(lst, "comment delimiter must be 1 or 2 characters long");
181 break;
182 case 126:
183 fprintf(lst, "character set contains more than one character");
184 break;
185 case 127:
186 fprintf(lst, "\ncould not make deterministic automaton, check previous token errors");
187 break;
188 case 129:
189 fprintf(lst, "literal tokens may not be empty");
190 break;
191 case 130:
192 fprintf(lst, "IGNORE CASE must appear earlier");
193 break;
194 }
195 fprintf(lst, " (E%d)",nr);
196 }
197
PrintErr(int nr,int col)198 static void PrintErr(int nr, int col)
199 { fprintf(lst, "*****");
200 while (col--) fprintf(lst, " ");
201 fprintf(lst, " ^ ");
202 PrintErrMsg(nr);
203 fprintf(lst, "\n");
204 }
205
PrintListing(void)206 static void PrintListing(void)
207 /* Print a source listing with error messages */
208 { struct ErrDesc *nextErr;
209 int lnr, errC;
210 long srcPos;
211 char line[255];
212
213 fprintf(lst, "Listing:\n\n");
214 srcPos = 0; nextErr = FirstErr;
215 srcPos = GetLine(srcPos, line); lnr = 1; errC = 0;
216 while (srcPos != -1) {
217 fprintf(lst, "%5d %s\n", lnr, line);
218 while (nextErr != NULL && nextErr->line == lnr) {
219 PrintErr(nextErr->nr, nextErr->col); errC++;
220 nextErr = nextErr->next;
221 }
222 srcPos = GetLine(srcPos, line); lnr++;
223 }
224 if (nextErr != NULL) {
225 fprintf(lst, "%5d\n", lnr);
226 while (nextErr != NULL) {
227 PrintErr(nextErr->nr, nextErr->col); errC++;
228 nextErr = nextErr->next;
229 }
230 }
231 fprintf(lst, "\n\n%5d syntax errors\n", errC);
232 }
233
SummarizeErrors(void)234 void SummarizeErrors(void)
235 /* Summarize error messages */
236 { struct ErrDesc *nextErr;
237 nextErr = FirstErr;
238 while (nextErr != NULL) {
239 if (Q_option)
240 fprintf(lst, "%s (%d, %d) ",
241 source_name, nextErr->line, nextErr->col);
242 else
243 fprintf(lst, "\"%s\", Line %d, Col %d: ",
244 source_name, nextErr->line, nextErr->col);
245 PrintErrMsg(nextErr->nr);
246 fprintf(lst, "\n");
247 nextErr = nextErr->next;
248 }
249 }
250
param_options(int argc,char * argv[])251 static void param_options(int argc,char *argv[])
252 { int i;
253 for (i = 1; i < argc; i++)
254 #if __MSDOS__ || MSDOS || WIN32 || __WIN32__
255 if (*argv[i] == '-' || *argv[i] == '/') SetOptions(argv[i]);
256 #else
257 if (*argv[i] == '-') SetOptions(argv[i]);
258 #endif
259 else strcpy(source_name, argv[i]);
260 }
261
FileGetName(char * name,char * filename)262 static void FileGetName(char *name, char *filename)
263 { int i;
264 strcpy(name, filename);
265 i = strlen(name)-1;
266 while (i>0 && name[i] != '.') i--;
267 name[i]='\0';
268 }
269
main(int argc,char * argv[])270 int main(int argc, char *argv[])
271 {
272 char name[100];
273 lst = stderr;
274 if (argc == 1) {
275 Help();
276 exit(EXIT_FAILURE);
277 }
278
279 InitFrameVars();
280 source_name[0] = '\0';
281 param_options(argc, argv);
282
283 /* check on correct parameter usage */
284 if (source_name[0] == 0) {
285 fprintf(stderr, "No input file specified");
286 exit(EXIT_FAILURE);
287 }
288
289 /* open the Source file (Scanner.S_src) */
290 if ((S_src = open(source_name, O_RDONLY|O_BINARY)) == -1) {
291 fprintf(stderr, "Unable to open input file %s\n", source_name);
292 exit(EXIT_FAILURE);
293 }
294
295 /* open the listing file */
296 if (L_option) {
297 FileGetName(name, source_name);
298 strcat(name, ".lst");
299 lstfile = OpenFile(name, "w", 1);
300 } else if (!Q_option) lstfile = stderr; else lstfile = stdout;
301
302 /* install error reporting procedure */
303 Custom_Error = (Error_Func) StoreError;
304
305 InitTab();
306 InitScannerTab();
307 Parse();
308 close(S_src);
309
310 lst = lstfile;
311 if (Errors && !L_option) SummarizeErrors();
312 else if (Errors || L_option) PrintListing();
313
314 if (Errors) { /* Check for Syntax Errors */
315 fclose(lstfile);
316 exit(EXIT_FAILURE);
317 }
318
319 MakeScanner();
320 MakeParser();
321
322 if (Errors) { /* Check for LL(1) Errors, Undeclared Symbols, etc */
323 fclose(lstfile);
324 exit(EXIT_FAILURE);
325 }
326
327 SetupFrameVars();
328 if (!T_option) {
329 if (!P_option) GenScanner();
330 GenParser();
331 GenHeaders();
332 if (C_option) GenCompiler();
333 }
334
335 if (L_option) {
336 if (S_option) {
337 ShowClassTab();
338 ShowTermTab();
339 ShowCommentTab();
340 ShowSymSetTab();
341 ShowNTermTab();
342 }
343 if (A_option) ShowDFA();
344 fclose(lstfile);
345 }
346 DoneTab();
347 DoneScannerTab();
348 return (EXIT_SUCCESS);
349 }
350
351