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