]>
Commit | Line | Data |
---|---|---|
30fdf114 LG |
1 | /*\r |
2 | * egman.c\r | |
3 | *\r | |
4 | * SOFTWARE RIGHTS\r | |
5 | *\r | |
6 | * We reserve no LEGAL rights to the Purdue Compiler Construction Tool\r | |
7 | * Set (PCCTS) -- PCCTS is in the public domain. An individual or\r | |
8 | * company may do whatever they wish with source code distributed with\r | |
9 | * PCCTS or the code generated by PCCTS, including the incorporation of\r | |
10 | * PCCTS, or its output, into commerical software.\r | |
11 | *\r | |
12 | * We encourage users to develop software with PCCTS. However, we do ask\r | |
13 | * that credit is given to us for developing PCCTS. By "credit",\r | |
14 | * we mean that if you incorporate our source code into one of your\r | |
15 | * programs (commercial product, research project, or otherwise) that you\r | |
16 | * acknowledge this fact somewhere in the documentation, research report,\r | |
17 | * etc... If you like PCCTS and have developed a nice tool with the\r | |
18 | * output, please mention that you developed it using PCCTS. In\r | |
19 | * addition, we ask that this header remain intact in our source code.\r | |
20 | * As long as these guidelines are kept, we expect to continue enhancing\r | |
21 | * this system and expect to make other tools available as they are\r | |
22 | * completed.\r | |
23 | *\r | |
24 | * ANTLR 1.33MR10\r | |
25 | * 2001\r | |
26 | *\r | |
27 | */\r | |
28 | \r | |
29 | #include <stdio.h>\r | |
30 | #include <stdlib.h>\r | |
31 | \r | |
32 | #include "set.h"\r | |
33 | #include "syn.h"\r | |
34 | #include "hash.h"\r | |
35 | #include "generic.h"\r | |
36 | #include "proto.h"\r | |
37 | \r | |
38 | static ExceptionGroup **egArray=NULL; /* ExceptionGroup by BlkLevel */\r | |
39 | static LabelEntry **leArray=NULL; /* LabelEntry by BlkLevel */\r | |
40 | static Junction **altArray=NULL; /* start of alternates */\r | |
41 | static int arraySize=0;\r | |
42 | static int highWater=0;\r | |
43 | static ExceptionGroup *lastEG=NULL; /* used in altFixup() */\r | |
44 | static int lastBlkLevel=0; /* used in altFixup() */\r | |
45 | \r | |
46 | #ifdef __USE_PROTOS\r | |
47 | static void arrayCheck(void);\r | |
48 | #else\r | |
49 | static void arrayCheck();\r | |
50 | #endif\r | |
51 | \r | |
52 | /* Called to add an exception group for an alternative EG */\r | |
53 | \r | |
54 | #ifdef __USE_PROTOS\r | |
55 | void egAdd(ExceptionGroup * eg)\r | |
56 | #else\r | |
57 | void egAdd(eg)\r | |
58 | ExceptionGroup *eg;\r | |
59 | #endif\r | |
60 | {\r | |
61 | int i;\r | |
62 | \r | |
63 | ExceptionGroup *nextEG;\r | |
64 | ExceptionGroup *innerEG;\r | |
65 | \r | |
66 | LabelEntry *nextLE;\r | |
67 | LabelEntry *innerLE;\r | |
68 | \r | |
69 | Junction *nextAlt;\r | |
70 | Junction *innerAlt;\r | |
71 | \r | |
72 | lastEG=eg;\r | |
73 | lastBlkLevel=BlkLevel;\r | |
74 | \r | |
75 | arrayCheck();\r | |
76 | eg->pendingLink=egArray[BlkLevel];\r | |
77 | egArray[BlkLevel]=eg;\r | |
78 | \r | |
79 | /* EG for alternates already have their altID filled in */\r | |
80 | \r | |
81 | for (i=BlkLevel+1; i<=highWater ; i++) {\r | |
82 | for (innerEG=egArray[i]; innerEG != NULL ; innerEG=nextEG) {\r | |
83 | nextEG=innerEG->pendingLink;\r | |
84 | innerEG->pendingLink=NULL;\r | |
85 | innerEG->outerEG=eg;\r | |
86 | };\r | |
87 | egArray[i]=NULL;\r | |
88 | };\r | |
89 | \r | |
90 | /*\r | |
91 | * for patching up the LabelEntry you might use an EG for the\r | |
92 | * current alternative - unlike patching up an alternative EG\r | |
93 | * i.e. start the loop at BlkLevel rather than (BlkLevel+1)\r | |
94 | * fill it in only if the EG and the LE are for the very\r | |
95 | * same alternative if they're at the same BlkLevel\r | |
96 | * it's easier to leave the LE on this list (filled in) rather than\r | |
97 | * trying to selectively remove it. It will eventually be\r | |
98 | * removed anyway when the BlkLevel gets small enough.\r | |
99 | */\r | |
100 | \r | |
101 | for (i=BlkLevel; i<=highWater ; i++) {\r | |
102 | for (innerLE=leArray[i]; innerLE != NULL ; innerLE=nextLE) {\r | |
103 | nextLE=innerLE->pendingLink;\r | |
104 | if (BlkLevel != i ||\r | |
105 | innerLE->curAltNum == CurAltNum_array[BlkLevel]) {\r | |
106 | if (innerLE->outerEG == NULL) {\r | |
107 | innerLE->outerEG=eg;\r | |
108 | };\r | |
109 | };\r | |
110 | };\r | |
111 | if (BlkLevel != i) leArray[i]=NULL;\r | |
112 | };\r | |
113 | \r | |
114 | /*\r | |
115 | * For the start of alternatives it is necessary to make a\r | |
116 | * distinction between the exception group for the current\r | |
117 | * alternative and the "fallback" EG for the block which\r | |
118 | * contains the alternative\r | |
119 | *\r | |
120 | * The fallback outerEG is used to handle the case where\r | |
121 | * no alternative of a block matches. In that case the\r | |
122 | * signal is "NoViableAlt" (or "NoSemViableAlt" and the\r | |
123 | * generator needs the EG of the block CONTAINING the\r | |
124 | * current one.\r | |
125 | *\r | |
126 | * rule: ( ( ( a\r | |
127 | * | b\r | |
128 | * )\r | |
129 | * | c\r | |
130 | * )\r | |
131 | * | d\r | |
132 | * );\r | |
133 | */\r | |
134 | \r | |
135 | for (i=BlkLevel; i <= highWater ; i++) {\r | |
136 | for (innerAlt=altArray[i]; innerAlt != NULL ; innerAlt=nextAlt) {\r | |
137 | nextAlt=innerAlt->pendingLink;\r | |
138 | \r | |
139 | /* first fill in the EG for the current alternative */\r | |
140 | /* but leave it on the list in order to get the fallback EG */\r | |
141 | /* if the EG is at the same LEVEL as the alternative then */\r | |
142 | /* fill it in only if in the very same alternative */\r | |
143 | /* */\r | |
144 | /* rule: ( a */\r | |
145 | /* | b */\r | |
146 | /* | c exception ... */\r | |
147 | /* ) */\r | |
148 | /* */\r | |
149 | /* if the EG is outside the alternative (e.g. BlkLevel < i) */\r | |
150 | /* then it doesn't matter about the alternative */\r | |
151 | /* */\r | |
152 | /* rule: ( a */\r | |
153 | /* | b */\r | |
154 | /* | c */\r | |
155 | /* ) exception ... */\r | |
156 | /* */\r | |
157 | \r | |
158 | #if 0\r | |
159 | printf("BlkLevel=%d i=%d altnum=%d CurAltNum=%d altID=%s\n",\r | |
160 | BlkLevel,i,innerAlt->curAltNum,CurAltNum_array[BlkLevel],eg->altID);\r | |
161 | #endif\r | |
162 | if (BlkLevel != i ||\r | |
163 | innerAlt->curAltNum == CurAltNum_array[BlkLevel]) {\r | |
164 | if (innerAlt->exception_label == NULL) {\r | |
165 | innerAlt->exception_label=eg->altID;\r | |
166 | };\r | |
167 | };\r | |
168 | \r | |
169 | /* ocurs at a later pass then for the exception_label */\r | |
170 | /* if an outerEG has been found then fill in the outer EG */\r | |
171 | /* remove if from the list when the BlkLevel gets smaller */\r | |
172 | \r | |
173 | if (BlkLevel != i) {\r | |
174 | if (innerAlt->outerEG == NULL) {\r | |
175 | innerAlt->outerEG=eg;\r | |
176 | };\r | |
177 | };\r | |
178 | };\r | |
179 | if (BlkLevel != i) altArray[i]=NULL;\r | |
180 | };\r | |
181 | }\r | |
182 | \r | |
183 | #ifdef __USE_PROTOS\r | |
184 | void leAdd(LabelEntry * le)\r | |
185 | #else\r | |
186 | void leAdd(le)\r | |
187 | LabelEntry *le;\r | |
188 | #endif\r | |
189 | \r | |
190 | {\r | |
191 | arrayCheck();\r | |
192 | le->pendingLink=leArray[BlkLevel];\r | |
193 | le->curAltNum=CurAltNum_array[BlkLevel];\r | |
194 | leArray[BlkLevel]=le;\r | |
195 | }\r | |
196 | \r | |
197 | #ifdef __USE_PROTOS\r | |
198 | void altAdd(Junction *alt)\r | |
199 | #else\r | |
200 | void altAdd(alt)\r | |
201 | Junction *alt;\r | |
202 | #endif\r | |
203 | \r | |
204 | {\r | |
205 | arrayCheck();\r | |
206 | #if 0\r | |
207 | printf("BlkLevel=%d CurAltNum=%d\n",\r | |
208 | BlkLevel,CurAltNum_array[BlkLevel]);\r | |
209 | #endif\r | |
210 | alt->curAltNum=CurAltNum_array[BlkLevel];\r | |
211 | alt->pendingLink=altArray[BlkLevel];\r | |
212 | altArray[BlkLevel]=alt;\r | |
213 | }\r | |
214 | \r | |
215 | static void \r | |
216 | #ifdef __USE_PROTOS\r | |
217 | arrayCheck(void)\r | |
218 | #else\r | |
219 | arrayCheck()\r | |
220 | #endif\r | |
221 | {\r | |
222 | ExceptionGroup **egArrayNew;\r | |
223 | LabelEntry **leArrayNew;\r | |
224 | Junction **altArrayNew;\r | |
225 | int arraySizeNew;\r | |
226 | int i;\r | |
227 | \r | |
228 | if (BlkLevel > highWater) highWater=BlkLevel;\r | |
229 | \r | |
230 | if (BlkLevel >= arraySize) {\r | |
231 | arraySizeNew=BlkLevel+5; /* MR20 */\r | |
232 | egArrayNew=(ExceptionGroup **)\r | |
233 | calloc(arraySizeNew,sizeof(ExceptionGroup *));\r | |
234 | leArrayNew=(LabelEntry **)\r | |
235 | calloc(arraySizeNew,sizeof(LabelEntry *));\r | |
236 | altArrayNew=(Junction **)\r | |
237 | calloc(arraySizeNew,sizeof(Junction *));\r | |
238 | for (i=0; i<arraySize ; i++) {\r | |
239 | egArrayNew[i]=egArray[i];\r | |
240 | leArrayNew[i]=leArray[i];\r | |
241 | altArrayNew[i]=altArray[i];\r | |
242 | };\r | |
243 | arraySize=arraySizeNew;\r | |
244 | if (egArray != NULL) free( (char *) egArray);\r | |
245 | if (leArray != NULL) free( (char *) leArray);\r | |
246 | if (altArray != NULL) free( (char *) altArray);\r | |
247 | egArray=egArrayNew;\r | |
248 | leArray=leArrayNew;\r | |
249 | altArray=altArrayNew;\r | |
250 | };\r | |
251 | }\r | |
252 | \r | |
253 | /* always call leFixup() BEFORE egFixup() */\r | |
254 | \r | |
255 | void \r | |
256 | #ifdef __USE_PROTOS\r | |
257 | egFixup(void) \r | |
258 | #else\r | |
259 | egFixup()\r | |
260 | #endif\r | |
261 | {\r | |
262 | int i;\r | |
263 | ExceptionGroup *nextEG;\r | |
264 | ExceptionGroup *innerEG;\r | |
265 | \r | |
266 | for (i=1; i<=highWater ; i++) {\r | |
267 | for (innerEG=egArray[i]; innerEG != NULL ; innerEG=nextEG) {\r | |
268 | nextEG=innerEG->pendingLink;\r | |
269 | innerEG->pendingLink=NULL;\r | |
270 | };\r | |
271 | egArray[i]=NULL;\r | |
272 | };\r | |
273 | lastEG=NULL;\r | |
274 | lastBlkLevel=0;\r | |
275 | }\r | |
276 | \r | |
277 | /* always call leFixup() BEFORE egFixup() */\r | |
278 | \r | |
279 | #ifdef __USE_PROTOS\r | |
280 | void leFixup(void) \r | |
281 | #else\r | |
282 | void leFixup() \r | |
283 | #endif\r | |
284 | {\r | |
285 | \r | |
286 | int i;\r | |
287 | LabelEntry *nextLE;\r | |
288 | LabelEntry *innerLE;\r | |
289 | \r | |
290 | for (i=BlkLevel; i<=highWater ; i++) {\r | |
291 | for (innerLE=leArray[i]; innerLE != NULL ; innerLE=nextLE) {\r | |
292 | nextLE=innerLE->pendingLink;\r | |
293 | innerLE->pendingLink=NULL;\r | |
294 | };\r | |
295 | leArray[i]=NULL;\r | |
296 | };\r | |
297 | }\r | |
298 | \r | |
299 | /* always call altFixup() BEFORE egFixup() */\r | |
300 | \r | |
301 | #ifdef __USE_PROTOS\r | |
302 | void altFixup(void)\r | |
303 | #else\r | |
304 | void altFixup() \r | |
305 | #endif\r | |
306 | {\r | |
307 | \r | |
308 | int i;\r | |
309 | Junction *nextAlt;\r | |
310 | Junction *innerAlt;\r | |
311 | \r | |
312 | for (i=BlkLevel; i<=highWater ; i++) {\r | |
313 | for (innerAlt=altArray[i]; innerAlt != NULL ; innerAlt=nextAlt) {\r | |
314 | \r | |
315 | /* if an outerEG has been found then fill in the outer EG */\r | |
316 | \r | |
317 | if (lastBlkLevel <= i) {\r | |
318 | if (innerAlt->outerEG == NULL) {\r | |
319 | innerAlt->outerEG=lastEG;\r | |
320 | };\r | |
321 | };\r | |
322 | nextAlt=innerAlt->pendingLink;\r | |
323 | innerAlt->pendingLink=NULL;\r | |
324 | };\r | |
325 | altArray[i]=NULL;\r | |
326 | };\r | |
327 | }\r | |
328 | \r |