]>
Commit | Line | Data |
---|---|---|
878ddf1f | 1 | /* output.c, output generator for dlg\r |
2 | *\r | |
3 | * Output Notes:\r | |
4 | *\r | |
5 | * DfaStates == number of dfa nodes in automaton (just a #define)\r | |
6 | * DfaState == type large enough to index every node in automaton\r | |
7 | * <256 unsigned char, <65536 unsigned short, etc.\r | |
8 | *\r | |
9 | * Thus, the elements in each of the automaton states (st%d) are type DfaState\r | |
10 | * and are size appropriately, since they must be able to index the next\r | |
11 | * automaton state.\r | |
12 | *\r | |
13 | * dfa[] == a linear array that points to all the automaton states (st%d)\r | |
14 | * (dfa_base[] should be the same, but isn't right now)\r | |
15 | *\r | |
16 | * accepts[] == Taking a closer look at this one, it probably shouldn't be type\r | |
17 | * DfaState because there is no real requirement that the number of\r | |
18 | * accepts states is less than the number of dfa state. However, if\r | |
19 | * the number of accept states was more than the number of DFA states\r | |
20 | * then the lexical specification would be really ambiguous.\r | |
21 | *\r | |
22 | * Another note. Is that is should be possible to fold accepts[] and\r | |
23 | * actions[] together. If this is done, I would suggest get rid of\r | |
24 | * accept[] and make actions[] have an entry for each state (st%d) in\r | |
25 | * the automaton.\r | |
26 | *\r | |
27 | * dfa_base[] == starting location for each lexical mode. This should be\r | |
28 | * Dfastate type (but isn't right now), since it points to the states\r | |
29 | * in the automaton.\r | |
30 | *\r | |
31 | * dfa_class_no[] == indicates the number of columns each lexical mode has.\r | |
32 | *\r | |
33 | * b_class_no[] == pointer to the start of the translation array used to\r | |
34 | * convert from input character to character class. This could cause\r | |
35 | * problems if there are more than 256 classes\r | |
36 | *\r | |
37 | * shift%d[] == the actual translation arrays that convert the input character\r | |
38 | * into the character class. These will have to change if there are\r | |
39 | * more than 256 character classes.\r | |
40 | *\r | |
41 | * SOFTWARE RIGHTS\r | |
42 | *\r | |
43 | * We reserve no LEGAL rights to the Purdue Compiler Construction Tool\r | |
44 | * Set (PCCTS) -- PCCTS is in the public domain. An individual or\r | |
45 | * company may do whatever they wish with source code distributed with\r | |
46 | * PCCTS or the code generated by PCCTS, including the incorporation of\r | |
47 | * PCCTS, or its output, into commerical software.\r | |
48 | *\r | |
49 | * We encourage users to develop software with PCCTS. However, we do ask\r | |
50 | * that credit is given to us for developing PCCTS. By "credit",\r | |
51 | * we mean that if you incorporate our source code into one of your\r | |
52 | * programs (commercial product, research project, or otherwise) that you\r | |
53 | * acknowledge this fact somewhere in the documentation, research report,\r | |
54 | * etc... If you like PCCTS and have developed a nice tool with the\r | |
55 | * output, please mention that you developed it using PCCTS. In\r | |
56 | * addition, we ask that this header remain intact in our source code.\r | |
57 | * As long as these guidelines are kept, we expect to continue enhancing\r | |
58 | * this system and expect to make other tools available as they are\r | |
59 | * completed.\r | |
60 | *\r | |
61 | * DLG 1.33\r | |
62 | * Will Cohen\r | |
63 | * With mods by Terence Parr; AHPCRC, University of Minnesota\r | |
64 | * 1989-2001\r | |
65 | */\r | |
66 | \r | |
67 | #include <stdio.h>\r | |
68 | #include <string.h>\r | |
69 | #include "dlg.h"\r | |
70 | #ifdef MEMCHK\r | |
71 | #include "trax.h"\r | |
72 | #else\r | |
73 | #ifdef __STDC__\r | |
74 | #include <stdlib.h>\r | |
75 | #else\r | |
76 | #include <malloc.h>\r | |
77 | #endif /* __STDC__ */\r | |
78 | #endif\r | |
79 | \r | |
80 | static char *mode_name[MAX_MODES];\r | |
81 | static int mode_number[MAX_MODES];\r | |
82 | static int cur_mode=0;\r | |
83 | \r | |
84 | int operation_no = 0; /* used to mark nodes so that infinite loops avoided */\r | |
85 | int dfa_basep[MAX_MODES]; /* start of each group of states */\r | |
86 | int dfa_class_nop[MAX_MODES]; /* number of elements in each group of states*/\r | |
87 | \r | |
88 | int gen_ansi = FALSE; /* allows ansi code to be generated */\r | |
89 | \r | |
90 | FILE *input_stream; /* where to read description from */\r | |
91 | FILE *output_stream; /* where to put the output */\r | |
92 | FILE *mode_stream; /* where to put the mode.h stuff */\r | |
93 | FILE *class_stream; /* where to put the scan.h stuff (if gen_cpp) */\r | |
94 | \r | |
95 | /* NOTE: This section is MACHINE DEPENDENT */\r | |
96 | #define DIF_SIZE 4\r | |
97 | #if defined(PC) && !defined(PC32)\r | |
98 | unsigned long typesize[DIF_SIZE] = { 0x7f, 0x7fff, 0x7ffful, 0x7ffffffful }; /* MR20 */\r | |
99 | char t0[] = "unsigned char";\r | |
100 | char t1[] = "unsigned short";\r | |
101 | char t2[] = "unsigned int";\r | |
102 | char t3[] = "unsigned long";\r | |
103 | char *typevar[DIF_SIZE] = { t0, t1, t2, t3};\r | |
104 | #else\r | |
105 | unsigned long typesize[DIF_SIZE] = { 0x7f, 0x7fff, 0x7ffffffful, 0x7ffffffful }; /* MR20 */\r | |
106 | char t0[] = "unsigned char";\r | |
107 | char t1[] = "unsigned short";\r | |
108 | char t2[] = "unsigned int";\r | |
109 | char t3[] = "unsigned long";\r | |
110 | char *typevar[DIF_SIZE] = { t0, t1, t2, t3};\r | |
111 | #endif\r | |
112 | \r | |
113 | /* Added by TJP August 1994 */\r | |
114 | /* Take in MyLexer and return MyLexer_h */\r | |
115 | \r | |
116 | static char *\r | |
117 | #ifdef __USE_PROTOS\r | |
118 | gate_symbol(char *name)\r | |
119 | #else\r | |
120 | gate_symbol(name)\r | |
121 | char *name;\r | |
122 | #endif\r | |
123 | {\r | |
124 | static char buf[100];\r | |
125 | sprintf(buf, "%s_h", name);\r | |
126 | return buf;\r | |
127 | }\r | |
128 | \r | |
129 | /* Added by TJP August 1994 */\r | |
130 | static char *\r | |
131 | #ifdef __USE_PROTOS\r | |
132 | mystrdup(char *s)\r | |
133 | #else\r | |
134 | mystrdup(s)\r | |
135 | char *s;\r | |
136 | #endif\r | |
137 | {\r | |
138 | char *p = (char *)malloc(strlen(s)+1);\r | |
139 | strcpy(p, s);\r | |
140 | return p;\r | |
141 | }\r | |
142 | \r | |
143 | #ifdef __USE_PROTOS\r | |
144 | void p_class_hdr(void)\r | |
145 | #else\r | |
146 | void p_class_hdr() \r | |
147 | #endif\r | |
148 | {\r | |
149 | if ( class_stream == NULL ) return;\r | |
150 | fprintf(class_stream, "#ifndef %s\n", gate_symbol(ClassName("")));\r | |
151 | fprintf(class_stream, "#define %s\n", gate_symbol(ClassName("")));\r | |
152 | fprintf(class_stream, "/*\n");\r | |
153 | fprintf(class_stream, " * D L G L e x e r C l a s s D e f i n i t i o n\n");\r | |
154 | fprintf(class_stream, " *\n");\r | |
155 | fprintf(class_stream, " * Generated from:");\r | |
156 | fprintf(class_stream, " %s", file_str[0]);\r | |
157 | fprintf(class_stream, "\n");\r | |
158 | fprintf(class_stream, " *\n");\r | |
159 | fprintf(class_stream, " * 1989-2001 by Will Cohen, Terence Parr, and Hank Dietz\n");\r | |
160 | fprintf(class_stream, " * Purdue University Electrical Engineering\n");\r | |
161 | fprintf(class_stream, " * DLG Version %s\n", version);\r | |
162 | fprintf(class_stream, " */\n\n");\r | |
163 | fprintf(class_stream, "\n");\r | |
164 | fprintf(class_stream, "#include \"%s\"\n", DLEXERBASE_H);\r | |
165 | }\r | |
166 | \r | |
167 | /* MR1 */\r | |
168 | /* MR1 16-Apr-97 Split printing of class header up into several parts */\r | |
169 | /* MR1 so that #lexprefix <<...>>and #lexmember <<...>> */\r | |
170 | /* MR1 can be inserted in the appropriate spots */\r | |
171 | /* MR1 */\r | |
172 | \r | |
173 | #ifdef __USE_PROTOS\r | |
174 | void p_class_def1(void)\r | |
175 | #else\r | |
176 | void p_class_def1()\r | |
177 | #endif\r | |
178 | {\r | |
179 | if ( class_stream == NULL ) return;\r | |
180 | fprintf(class_stream, "\nclass %s : public DLGLexerBase {\n", ClassName(""));\r | |
181 | fprintf(class_stream, "public:\n");\r | |
182 | }\r | |
183 | \r | |
184 | #ifdef __USE_PROTOS\r | |
185 | void p_class_def2(void)\r | |
186 | #else\r | |
187 | void p_class_def2()\r | |
188 | #endif\r | |
189 | {\r | |
190 | int i, m;\r | |
191 | if ( class_stream == NULL ) return;\r | |
192 | fprintf(class_stream, "public:\n");\r | |
193 | fprintf(class_stream, "\tstatic const int MAX_MODE;\n");\r | |
194 | fprintf(class_stream, "\tstatic const int DfaStates;\n");\r | |
195 | for (i=0; i<cur_mode; i++) {\r | |
196 | fprintf(class_stream, "\tstatic const int %s;\n", mode_name[i]);\r | |
197 | }\r | |
198 | \r | |
199 | fprintf(class_stream, "\ttypedef %s DfaState;\n\n", minsize(dfa_allocated));\r | |
200 | fprintf(class_stream, "\t%s(DLGInputStream *in,\n",ClassName(""));\r | |
201 | fprintf(class_stream, "\t\tunsigned bufsize=2000)\n");\r | |
202 | fprintf(class_stream, "\t\t: DLGLexerBase(in, bufsize, %d)\n", interactive);\r | |
203 | fprintf(class_stream, "\t{\n");\r | |
204 | fprintf(class_stream, "\t;\n");\r | |
205 | fprintf(class_stream, "\t}\n");\r | |
206 | fprintf(class_stream, "\tvoid mode(int);\n");\r | |
207 | fprintf(class_stream, "\tANTLRTokenType nextTokenType(void);\n");\r | |
208 | fprintf(class_stream, "\tvoid advance(void);\n");\r | |
209 | fprintf(class_stream, "protected:\n");\r | |
210 | for (i=1; i<=action_no; ++i) {\r | |
211 | fprintf(class_stream, "\tANTLRTokenType act%d();\n", i);\r | |
212 | }\r | |
213 | \r | |
214 | for(m=0; m<(mode_counter-1); ++m){\r | |
215 | for(i=dfa_basep[m]; i<dfa_basep[m+1]; ++i)\r | |
216 | fprintf(class_stream, "\tstatic DfaState st%d[%d];\n", i-1, dfa_class_nop[m]+1);\r | |
217 | }\r | |
218 | for(i=dfa_basep[m]; i<=dfa_allocated; ++i)\r | |
219 | fprintf(class_stream, "\tstatic DfaState st%d[%d];\n", i-1, dfa_class_nop[m]+1);\r | |
220 | \r | |
221 | fprintf(class_stream, "\tstatic DfaState *dfa[%d];\n", dfa_allocated);\r | |
222 | fprintf(class_stream, "\tstatic DfaState dfa_base[];\n");\r | |
223 | /* fprintf(class_stream, "\tstatic int dfa_base_no[];\n"); */\r | |
224 | fprintf(class_stream, "\tstatic unsigned char *b_class_no[];\n");\r | |
225 | fprintf(class_stream, "\tstatic DfaState accepts[%d];\n",dfa_allocated+1);\r | |
226 | fprintf(class_stream, "\tstatic DLGChar alternatives[%d];\n",dfa_allocated+1);\r | |
227 | /* WARNING: should be ANTLRTokenType for action table, but g++ 2.5.6 is hosed */\r | |
228 | fprintf(class_stream, "\tstatic ANTLRTokenType (%s::*actions[%d])();\n", ClassName(""), action_no+1);\r | |
229 | for(m=0; m<mode_counter; ++m) {\r | |
230 | fprintf(class_stream, "\tstatic unsigned char shift%d[%d];\n",\r | |
231 | m, CHAR_RANGE);\r | |
232 | }\r | |
233 | if (comp_level)\r | |
234 | fprintf(class_stream, "\tint ZZSHIFT(int c) { return b_class_no[automaton][1+c]; }\n");\r | |
235 | else\r | |
236 | fprintf(class_stream, "\tint ZZSHIFT(int c) { return 1+c; }\n");\r | |
237 | \r | |
238 | /* MR1 */\r | |
239 | /* MR1 11-APr-97 Kludge to allow inclusion of user-defined code in */\r | |
240 | /* MR1 DLGLexer class header */\r | |
241 | /* MR1 Deprecated in favor of 133MR1 addition #lexmember <<>> */\r | |
242 | /* MR1 */\r | |
243 | /* MR1 */ fprintf(class_stream,"//\n");\r | |
244 | /* MR1 */ fprintf(class_stream,\r | |
245 | /* MR1 */ "// 133MR1 Deprecated feature to allow inclusion of ");\r | |
246 | /* MR1 */ fprintf(class_stream,\r | |
247 | /* MR1 */ "user-defined code in DLG class header\n");\r | |
248 | /* MR1 */ fprintf(class_stream,"//\n");\r | |
249 | /* MR1 */\r | |
250 | /* MR1 */ fprintf(class_stream,"#ifdef DLGLexerIncludeFile\n");\r | |
251 | /* MR1 */ fprintf(class_stream,"#include DLGLexerIncludeFile\n");\r | |
252 | /* MR1 */ fprintf(class_stream,"#endif\n");\r | |
253 | \r | |
254 | fprintf(class_stream, "};\n");\r | |
255 | \r | |
256 | fprintf(class_stream, "typedef ANTLRTokenType (%s::*Ptr%sMemberFunc)();\n",\r | |
257 | ClassName(""), ClassName(""));\r | |
258 | \r | |
259 | fprintf(class_stream, "#endif\n");\r | |
260 | }\r | |
261 | \r | |
262 | /* generate required header on output */\r | |
263 | \r | |
264 | #ifdef __USE_PROTOS\r | |
265 | void p_head(void)\r | |
266 | #else\r | |
267 | void p_head()\r | |
268 | #endif\r | |
269 | {\r | |
270 | fprintf(OUT, "/*\n");\r | |
271 | fprintf(OUT, " * D L G tables\n");\r | |
272 | fprintf(OUT, " *\n");\r | |
273 | fprintf(OUT, " * Generated from:");\r | |
274 | fprintf(OUT, " %s", file_str[0]);\r | |
275 | fprintf(OUT, "\n");\r | |
276 | fprintf(OUT, " *\n");\r | |
277 | fprintf(OUT, " * 1989-2001 by Will Cohen, Terence Parr, and Hank Dietz\n");\r | |
278 | fprintf(OUT, " * Purdue University Electrical Engineering\n");\r | |
279 | fprintf(OUT, " * DLG Version %s\n", version);\r | |
280 | fprintf(OUT, " */\n\n");\r | |
281 | if ( gen_cpp) fprintf(OUT, "#include \"pcctscfg.h\"\n");\r | |
282 | if ( gen_cpp ) fprintf(OUT, "#include \"pccts_stdio.h\"\n");\r | |
283 | if ( !gen_cpp ) fprintf(OUT, "#include \"%s\"\n\n", mode_file);\r | |
284 | fprintf(OUT,"\n");\r | |
285 | }\r | |
286 | \r | |
287 | #ifdef __USE_PROTOS\r | |
288 | void p_includes(void)\r | |
289 | #else\r | |
290 | void p_includes()\r | |
291 | #endif\r | |
292 | {\r | |
293 | fprintf(OUT, "#include \"%s\"\n", APARSER_H);\r | |
294 | fprintf(OUT, "#include \"%s\"\n", DLEXERBASE_H);\r | |
295 | fprintf(OUT, "#include \"%s\"\n", ClassName(".h"));\r | |
296 | }\r | |
297 | \r | |
298 | /* generate code to tie up any loose ends */\r | |
299 | \r | |
300 | #ifdef __USE_PROTOS\r | |
301 | void p_tail(void) /* MR1 */\r | |
302 | #else\r | |
303 | void p_tail() /* MR1 */\r | |
304 | #endif\r | |
305 | {\r | |
306 | if ( gen_cpp ) {\r | |
307 | if ( strcmp(ClassName(""), DEFAULT_CLASSNAME)!=0 )\r | |
308 | fprintf(OUT, "#define DLGLexer %s\n", ClassName(""));\r | |
309 | fprintf(OUT, "#include \"%s\"\n", DLEXER_H); /* MR23 Rename DLexer.cpp to DLexer.h */\r | |
310 | return;\r | |
311 | }\r | |
312 | fprintf(OUT, "\n");\r | |
313 | fprintf(OUT, "\n");\r | |
314 | if (comp_level)\r | |
315 | fprintf(OUT, "#define ZZSHIFT(c) (b_class_no[zzauto][1+c])\n");\r | |
316 | else\r | |
317 | fprintf(OUT, "#define ZZSHIFT(c) (1+c)\n");\r | |
318 | if ( !gen_cpp ) fprintf(OUT, "#define MAX_MODE %d\n",mode_counter);\r | |
319 | fprintf(OUT, "#include \"dlgauto.h\"\n");\r | |
320 | }\r | |
321 | \r | |
322 | \r | |
323 | /* output the table of DFA for general use */\r | |
324 | \r | |
325 | #ifdef __USE_PROTOS\r | |
326 | void p_tables()\r | |
327 | #else\r | |
328 | void p_tables()\r | |
329 | #endif\r | |
330 | {\r | |
331 | if ( !gen_cpp ) {\r | |
332 | fprintf(OUT, "#define DfaStates\t%d\n", dfa_allocated);\r | |
333 | fprintf(OUT, "typedef %s DfaState;\n\n", minsize(dfa_allocated));\r | |
334 | }\r | |
335 | \r | |
336 | if ( gen_cpp ) {\r | |
337 | int i;\r | |
338 | fprintf(OUT, "\n");\r | |
339 | fprintf(OUT, "const int %s::MAX_MODE=%d;\n",\r | |
340 | ClassName(""),\r | |
341 | mode_counter);\r | |
342 | fprintf(OUT, "const int %s::DfaStates=%d;\n",\r | |
343 | ClassName(""),\r | |
344 | dfa_allocated);\r | |
345 | for (i=0; i<cur_mode; i++) {\r | |
346 | fprintf(OUT, "const int %s::%s=%d;\n",\r | |
347 | ClassName(""), mode_name[i], mode_number[i]);\r | |
348 | }\r | |
349 | fprintf(OUT, "\n");\r | |
350 | }\r | |
351 | \r | |
352 | p_node_table();\r | |
353 | p_dfa_table();\r | |
354 | p_accept_table();\r | |
355 | p_action_table();\r | |
356 | p_base_table();\r | |
357 | p_class_table();\r | |
358 | if (comp_level)\r | |
359 | p_bshift_table();\r | |
360 | if (interactive || gen_cpp )\r | |
361 | p_alternative_table();\r | |
362 | }\r | |
363 | \r | |
364 | \r | |
365 | /* figures out the smallest variable type that will hold the transitions\r | |
366 | */\r | |
367 | \r | |
368 | #ifdef __USE_PROTOS\r | |
369 | char *minsize(int elements)\r | |
370 | #else\r | |
371 | char *minsize(elements)\r | |
372 | int elements;\r | |
373 | #endif\r | |
374 | {\r | |
375 | int i = 0;\r | |
376 | \r | |
377 | while ((unsigned long) elements > typesize[i]) /* MR20 */\r | |
378 | ++i;\r | |
379 | return typevar[i];\r | |
380 | }\r | |
381 | \r | |
382 | \r | |
383 | #ifdef __USE_PROTOS\r | |
384 | void p_node_table(void)\r | |
385 | #else\r | |
386 | void p_node_table()\r | |
387 | #endif\r | |
388 | {\r | |
389 | register int i;\r | |
390 | register int m = 0;\r | |
391 | \r | |
392 | for(m=0; m<(mode_counter-1); ++m){\r | |
393 | for(i=dfa_basep[m]; i<dfa_basep[m+1]; ++i)\r | |
394 | p_single_node(i,dfa_class_nop[m]);\r | |
395 | }\r | |
396 | for(i=dfa_basep[m]; i<=dfa_allocated; ++i)\r | |
397 | p_single_node(i,dfa_class_nop[m]);\r | |
398 | }\r | |
399 | \r | |
400 | \r | |
401 | #ifdef __USE_PROTOS\r | |
402 | void p_single_node(int i,int classes)\r | |
403 | #else\r | |
404 | void p_single_node(i,classes)\r | |
405 | int i,classes;\r | |
406 | #endif\r | |
407 | {\r | |
408 | register int j;\r | |
409 | register int trans, items_on_line;\r | |
410 | \r | |
411 | #if 1\r | |
412 | /* extra state (classes+1) for invalid characters */\r | |
413 | fprintf(OUT, "%sDfaState %sst%d[%d] = {\n ",\r | |
414 | gen_cpp?ClassName("::"):"static ",\r | |
415 | gen_cpp?ClassName("::"):"",(i-1), (classes+1));\r | |
416 | #else\r | |
417 | fprintf(OUT, "static DfaState st%d[%d] = {\n ", (i-1), classes);\r | |
418 | #endif\r | |
419 | items_on_line = MAX_ON_LINE;\r | |
420 | for(j=0; j<classes; ++j){\r | |
421 | DAWDLE;\r | |
422 | trans = DFA(i)->trans[j];\r | |
423 | if (trans == NIL_INDEX)\r | |
424 | trans = dfa_allocated+1;\r | |
425 | /* all of DFA moved down one in array */\r | |
426 | fprintf(OUT, "%d", trans-1);\r | |
427 | fprintf(OUT, ", ");\r | |
428 | if (!(--items_on_line)){\r | |
429 | fprintf(OUT, "\n ");\r | |
430 | items_on_line = MAX_ON_LINE;\r | |
431 | }\r | |
432 | }\r | |
433 | #if 1\r | |
434 | /* put in jump to error state */\r | |
435 | fprintf(OUT, "%d\n};\n\n", dfa_allocated);\r | |
436 | #else\r | |
437 | fprintf(OUT, "\n};\n\n");\r | |
438 | #endif\r | |
439 | }\r | |
440 | \r | |
441 | \r | |
442 | #ifdef __USE_PROTOS\r | |
443 | void p_dfa_table(void)\r | |
444 | #else\r | |
445 | void p_dfa_table()\r | |
446 | #endif\r | |
447 | {\r | |
448 | register int i;\r | |
449 | \r | |
450 | fprintf(OUT, "\n%sDfaState *%sdfa[%d] = {\n",\r | |
451 | gen_cpp?ClassName("::"):"",gen_cpp?ClassName("::"):"", dfa_allocated);\r | |
452 | for (i=0; i<(dfa_allocated-1); ++i){\r | |
453 | fprintf(OUT, "\tst%d,\n", i);\r | |
454 | }\r | |
455 | fprintf(OUT, "\tst%d\n", i);\r | |
456 | fprintf(OUT, "};\n\n");\r | |
457 | }\r | |
458 | \r | |
459 | \r | |
460 | #ifdef __USE_PROTOS\r | |
461 | void p_accept_table(void)\r | |
462 | #else\r | |
463 | void p_accept_table()\r | |
464 | #endif\r | |
465 | {\r | |
466 | register int i = 1;\r | |
467 | register int items_on_line = 0;\r | |
468 | int true_interactive = TRUE;\r | |
469 | \r | |
470 | /* make sure element for one past (zzerraction) -WEC 12/16/92 */\r | |
471 | fprintf(OUT,"\n%sDfaState %saccepts[%d] = {\n ",\r | |
472 | gen_cpp?ClassName("::"):"",\r | |
473 | gen_cpp?ClassName("::"):"",\r | |
474 | dfa_allocated+1);\r | |
475 | /* don't do anything if no dfa nodes */\r | |
476 | if (i>dfa_allocated) goto skip_accepts;\r | |
477 | for (;;) {\r | |
478 | int accept=0; /* MR14a - Manuel Kessler (mlkessle@cip.physik.uni-wuerzburg.de) */\r | |
479 | set accept_set;\r | |
480 | set nfa_states;\r | |
481 | unsigned int *t, *nfa_i;\r | |
482 | unsigned int *q, *regular_expr;\r | |
483 | \r | |
484 | accept_set = empty;\r | |
485 | nfa_states = DFA(i)->nfa_states;\r | |
486 | t = nfa_i = set_pdq(nfa_states);\r | |
487 | /* NOTE: picks lowest accept because accepts monotonic */\r | |
488 | /* with respect to nfa node numbers and set_pdq */\r | |
489 | /* returns in that order */\r | |
490 | while((*nfa_i != nil) && (!(accept = NFA(*nfa_i)->accept))){\r | |
491 | nfa_i++;\r | |
492 | }\r | |
493 | \r | |
494 | /* figure out if more than one accept state there */\r | |
495 | if (warn_ambig ){\r | |
496 | set_orel(accept, &accept_set);\r | |
497 | while(*nfa_i != nil){\r | |
498 | set_orel(NFA(*nfa_i)->accept, &accept_set);\r | |
499 | nfa_i++;\r | |
500 | }\r | |
501 | /* remove error action from consideration */\r | |
502 | set_rm(0, accept_set);\r | |
503 | \r | |
504 | if( set_deg(accept_set)>1){\r | |
505 | fprintf(stderr, "dlg warning: ambiguous regular expression ");\r | |
506 | q = regular_expr = set_pdq(accept_set);\r | |
507 | while(*regular_expr != nil){\r | |
508 | fprintf(stderr," %d ", *regular_expr);\r | |
509 | ++regular_expr;\r | |
510 | }\r | |
511 | fprintf(stderr, "\n");\r | |
512 | free(q);\r | |
513 | }\r | |
514 | }\r | |
515 | \r | |
516 | if ((DFA(i)->alternatives) && (accept != 0)){\r | |
517 | true_interactive = FALSE;\r | |
518 | }\r | |
519 | fprintf(OUT, "%d, ", accept);\r | |
520 | \r | |
521 | /* free up memory before we "break" below -ATG 4/6/95 */\r | |
522 | free(t);\r | |
523 | set_free(accept_set);\r | |
524 | \r | |
525 | if ((++i)>dfa_allocated)\r | |
526 | break;\r | |
527 | if ((++items_on_line)>=MAX_ON_LINE){\r | |
528 | fprintf(OUT,"\n ");\r | |
529 | items_on_line = 0;\r | |
530 | }\r | |
531 | /*\r | |
532 | free(t);\r | |
533 | set_free(accept_set);\r | |
534 | */\r | |
535 | }\r | |
536 | /* make sure element for one past (zzerraction) -WEC 12/16/92 */\r | |
537 | skip_accepts:\r | |
538 | fprintf(OUT, "0\n};\n\n");\r | |
539 | }\r | |
540 | \r | |
541 | \r | |
542 | #ifdef __USE_PROTOS\r | |
543 | void p_action_table(void)\r | |
544 | #else\r | |
545 | void p_action_table()\r | |
546 | #endif\r | |
547 | {\r | |
548 | register int i;\r | |
549 | char* theClassName = ClassName("");\r | |
550 | \r | |
551 | if ( gen_cpp )\r | |
552 | fprintf(OUT, "Ptr%sMemberFunc %s::actions[%d] = {\n", theClassName,\r | |
553 | theClassName, action_no+1);\r | |
554 | else\r | |
555 | fprintf(OUT, "void (*actions[%d])() = {\n", action_no+1);\r | |
556 | if ( gen_cpp )\r | |
557 | /* fprintf(OUT, "\t(Ptr%sMemberFunc)&%s::erraction,\n", theClassName, theClassName);*/\r | |
558 | fprintf(OUT, "\t&%s::erraction,\n", theClassName);\r | |
559 | else\r | |
560 | fprintf(OUT, "\tzzerraction,\n");\r | |
561 | for (i=1; i<action_no; ++i) {\r | |
562 | if ( gen_cpp )\r | |
563 | /* fprintf(OUT,"\t(Ptr%sMemberFunc)&%s::act%d,\n", theClassName, theClassName, i);*/\r | |
564 | fprintf(OUT,"\t&%s::act%d,\n", theClassName, i);\r | |
565 | else\r | |
566 | fprintf(OUT,"\tact%d,\n", i);\r | |
567 | DAWDLE;\r | |
568 | }\r | |
569 | if ( gen_cpp )\r | |
570 | /* fprintf(OUT,"\t(Ptr%sMemberFunc)&%s::act%d\n", theClassName, theClassName, i);*/\r | |
571 | fprintf(OUT,"\t&%s::act%d\n", theClassName, i);\r | |
572 | else\r | |
573 | fprintf(OUT,"\tact%d\n", i);\r | |
574 | fprintf(OUT, "};\n\n");\r | |
575 | }\r | |
576 | \r | |
577 | \r | |
578 | #ifdef __USE_PROTOS\r | |
579 | void p_shift_table(int m) /* MR1 */\r | |
580 | #else\r | |
581 | void p_shift_table(m) /* MR1 */\r | |
582 | int m;\r | |
583 | #endif\r | |
584 | {\r | |
585 | register int i = 0, j;\r | |
586 | register int items_on_line = 0;\r | |
587 | \r | |
588 | fprintf(OUT, "%s unsigned char %sshift%d[%d] = {\n ",\r | |
589 | gen_cpp?"":"static",\r | |
590 | gen_cpp?ClassName("::"):"", m, CHAR_RANGE);\r | |
591 | for (;;) {\r | |
592 | /* find which partition character i is in */\r | |
593 | for (j=0; j<dfa_class_nop[mode_counter]; ++j){\r | |
594 | if (set_el(i,class_sets[j]))\r | |
595 | break;\r | |
596 | }\r | |
597 | fprintf(OUT,"%d",j);\r | |
598 | if ((++i)>=CHAR_RANGE)\r | |
599 | break;\r | |
600 | fprintf(OUT,", ");\r | |
601 | if ((++items_on_line)>=MAX_ON_LINE){\r | |
602 | fprintf(OUT,"\n ");\r | |
603 | items_on_line = 0;\r | |
604 | }\r | |
605 | }\r | |
606 | fprintf(OUT, "\n};\n\n");\r | |
607 | }\r | |
608 | \r | |
609 | \r | |
610 | #ifdef __USE_PROTOS\r | |
611 | void p_base_table(void)\r | |
612 | #else\r | |
613 | void p_base_table()\r | |
614 | #endif\r | |
615 | {\r | |
616 | register int m;\r | |
617 | \r | |
618 | fprintf(OUT, "%sDfaState %sdfa_base[] = {\n",\r | |
619 | gen_cpp?ClassName("::"):"static ",\r | |
620 | gen_cpp?ClassName("::"):"");\r | |
621 | for(m=0; m<(mode_counter-1); ++m)\r | |
622 | fprintf(OUT, "\t%d,\n", dfa_basep[m]-1);\r | |
623 | fprintf(OUT, "\t%d\n};\n\n", dfa_basep[m]-1);\r | |
624 | }\r | |
625 | \r | |
626 | \r | |
627 | #ifdef __USE_PROTOS\r | |
628 | void p_class_table(void) /* MR1 */\r | |
629 | #else\r | |
630 | void p_class_table() /* MR1 */\r | |
631 | #endif\r | |
632 | {\r | |
633 | #if 0\r | |
634 | register int m;\r | |
635 | \r | |
636 | fprintf(OUT,"%s int %sdfa_class_no[] = {\n",\r | |
637 | gen_cpp?"":"static",\r | |
638 | gen_cpp?ClassName("::"):"");\r | |
639 | for(m=0; m<(mode_counter-1); ++m)\r | |
640 | fprintf(OUT,"\t%d,\n", dfa_class_nop[m]);\r | |
641 | fprintf(OUT,"\t%d\n};\n\n", dfa_class_nop[m]);\r | |
642 | #endif\r | |
643 | }\r | |
644 | \r | |
645 | \r | |
646 | #ifdef __USE_PROTOS\r | |
647 | void p_bshift_table(void) /* MR1 */\r | |
648 | #else\r | |
649 | void p_bshift_table() /* MR1 */\r | |
650 | #endif\r | |
651 | {\r | |
652 | register int m;\r | |
653 | \r | |
654 | fprintf(OUT,"%s unsigned char *%sb_class_no[] = {\n",\r | |
655 | gen_cpp?"":"static",\r | |
656 | gen_cpp?ClassName("::"):"");\r | |
657 | for(m=0; m<(mode_counter-1); ++m)\r | |
658 | fprintf(OUT, "\tshift%d,\n", m);\r | |
659 | fprintf(OUT, "\tshift%d\n};\n\n", m);\r | |
660 | }\r | |
661 | \r | |
662 | \r | |
663 | #ifdef __USE_PROTOS\r | |
664 | void p_alternative_table(void) /* MR1 */\r | |
665 | #else\r | |
666 | void p_alternative_table() /* MR1 */\r | |
667 | #endif\r | |
668 | {\r | |
669 | register int i;\r | |
670 | \r | |
671 | if ( !gen_cpp ) fprintf(OUT, "#define ZZINTERACTIVE\n\n");\r | |
672 | if ( gen_cpp )\r | |
673 | fprintf(OUT, "DLGChar %salternatives[%d] = {\n", /* mr23 vhs %sDfaStates+1 */\r | |
674 | ClassName("::"),\r | |
675 | dfa_allocated+1); /* vhs ClassName("::")); */\r | |
676 | else\r | |
677 | fprintf(OUT, "static %s zzalternatives[DfaStates+1] = {\n",\r | |
678 | minsize(dfa_allocated));\r | |
679 | \r | |
680 | for(i=1; i<=dfa_allocated; ++i)\r | |
681 | fprintf(OUT, "\t%d,\n", DFA(i)->alternatives);\r | |
682 | fprintf(OUT, "/* must have 0 for zzalternatives[DfaStates] */\n");\r | |
683 | fprintf(OUT, "\t0\n};\n\n");\r | |
684 | }\r | |
685 | \r | |
686 | \r | |
687 | #ifdef __USE_PROTOS\r | |
688 | void p_mode_def(char *s,int m) /* MR1 */\r | |
689 | #else\r | |
690 | void p_mode_def(s,m) /* MR1 */\r | |
691 | char *s;\r | |
692 | int m;\r | |
693 | #endif\r | |
694 | {\r | |
695 | if ( gen_cpp )\r | |
696 | {\r | |
697 | mode_name[cur_mode] = mystrdup(s);\r | |
698 | mode_number[cur_mode] = m;\r | |
699 | cur_mode++;\r | |
700 | }\r | |
701 | else\r | |
702 | fprintf(mode_stream, "#define %s %d\n", s, m);\r | |
703 | }\r | |
704 | \r | |
705 | #ifdef __USE_PROTOS\r | |
706 | char * ClassName(char *suffix)\r | |
707 | #else\r | |
708 | char * ClassName(suffix)\r | |
709 | char *suffix;\r | |
710 | #endif\r | |
711 | {\r | |
712 | static char buf[200];\r | |
713 | extern char *class_name;\r | |
714 | \r | |
715 | sprintf(buf, "%s%s", class_name, suffix);\r | |
716 | return buf;\r | |
717 | }\r | |
718 | \r | |
719 | #ifdef DEBUG\r | |
720 | \r | |
721 | /* print out a particular nfa node that is pointed to by p */\r | |
722 | \r | |
723 | #ifdef __USE_PROTOS\r | |
724 | void p_nfa_node(nfa_node *p)\r | |
725 | #else\r | |
726 | void p_nfa_node(p)\r | |
727 | nfa_node *p;\r | |
728 | #endif\r | |
729 | {\r | |
730 | register nfa_node *t;\r | |
731 | \r | |
732 | if (p != NIL_INDEX){\r | |
733 | printf("NFA state : %d\naccept state : %d\n",\r | |
734 | NFA_NO(p),p->accept);\r | |
735 | if (p->trans[0] != NIL_INDEX){\r | |
736 | printf("trans[0] => %d on ", NFA_NO(p->trans[0]));\r | |
737 | p_set(p->label);\r | |
738 | printf("\n");\r | |
739 | }\r | |
740 | else\r | |
741 | printf("trans[0] => nil\n");\r | |
742 | if (p->trans[1] != NIL_INDEX)\r | |
743 | printf("trans[1] => %d on epsilon\n",\r | |
744 | NFA_NO(p->trans[1]));\r | |
745 | else\r | |
746 | printf("trans[1] => nil\n");\r | |
747 | printf("\n");\r | |
748 | }\r | |
749 | }\r | |
750 | #endif\r | |
751 | \r | |
752 | #ifdef DEBUG\r | |
753 | \r | |
754 | /* code to print out special structures when using a debugger */\r | |
755 | \r | |
756 | #ifdef __USE_PROTOS\r | |
757 | void p_nfa(p)\r | |
758 | #else\r | |
759 | void p_nfa(nfa_node *p)\r | |
760 | nfa_node *p; /* state number also index into array */\r | |
761 | #endif\r | |
762 | {\r | |
763 | /* each node has a marker on it so it only gets printed once */\r | |
764 | \r | |
765 | operation_no++; /* get new number */\r | |
766 | s_p_nfa(p);\r | |
767 | }\r | |
768 | \r | |
769 | #ifdef __USE_PROTOS\r | |
770 | void s_p_nfa(nfa_node *p)\r | |
771 | #else\r | |
772 | void s_p_nfa(p)\r | |
773 | nfa_node *p; /* state number also index into array */\r | |
774 | #endif\r | |
775 | {\r | |
776 | if ((p != NIL_INDEX) && (p->nfa_set != operation_no)){\r | |
777 | /* so it is only printed once */\r | |
778 | p->nfa_set = operation_no;\r | |
779 | p_nfa_node(p);\r | |
780 | s_p_nfa(p->trans[0]);\r | |
781 | s_p_nfa(p->trans[1]);\r | |
782 | }\r | |
783 | }\r | |
784 | \r | |
785 | #ifdef __USE_PROTOS\r | |
786 | void p_dfa_node(dfa_node *p)\r | |
787 | #else\r | |
788 | void p_dfa_node(p)\r | |
789 | dfa_node *p;\r | |
790 | #endif\r | |
791 | {\r | |
792 | int i;\r | |
793 | \r | |
794 | if (p != NIL_INDEX){\r | |
795 | printf("DFA state :%d\n",NFA_NO(p));\r | |
796 | if (p->done)\r | |
797 | printf("done\n");\r | |
798 | else\r | |
799 | printf("undone\n");\r | |
800 | printf("from nfa states : ");\r | |
801 | p_set(p->nfa_states);\r | |
802 | printf("\n");\r | |
803 | /* NOTE: trans arcs stored as ints rather than pointer*/\r | |
804 | for (i=0; i<class_no; i++){\r | |
805 | printf("%d ",p->trans[i]);\r | |
806 | }\r | |
807 | printf("\n\n");\r | |
808 | }\r | |
809 | }\r | |
810 | \r | |
811 | #ifdef __USE_PROTOS\r | |
812 | void p_dfa(void)\r | |
813 | #else\r | |
814 | void p_dfa()\r | |
815 | #endif\r | |
816 | {\r | |
817 | /* prints out all the dfa nodes actually allocated */\r | |
818 | \r | |
819 | int i;\r | |
820 | \r | |
821 | for (i = 1; i<=dfa_allocated; i++)\r | |
822 | p_dfa_node(NFA(i));\r | |
823 | }\r | |
824 | \r | |
825 | \r | |
826 | /* print out numbers in the set label */\r | |
827 | \r | |
828 | #ifdef __USE_PROTOS\r | |
829 | void p_set(set label)\r | |
830 | #else\r | |
831 | void p_set(label)\r | |
832 | set label;\r | |
833 | #endif\r | |
834 | {\r | |
835 | unsigned *t, *e;\r | |
836 | \r | |
837 | if (set_nil(label)){\r | |
838 | printf("epsilon\n");\r | |
839 | }else{\r | |
840 | t = e = set_pdq(label);\r | |
841 | while(*e != nil){\r | |
842 | printf("%d ", (*e+MIN_CHAR));\r | |
843 | e++;\r | |
844 | }\r | |
845 | printf("\n");\r | |
846 | free(t);\r | |
847 | }\r | |
848 | \r | |
849 | }\r | |
850 | #endif\r |