Home | History | Annotate | Download | only in antlr
      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