egman.c
上传用户:itx_2006
上传日期:2007-01-06
资源大小:493k
文件大小:9k
源码类别:

编译器/解释器

开发平台:

Others

  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.  * 1998
  26.  *
  27.  */
  28. #include <stdio.h>
  29. #include "set.h"
  30. #include "syn.h"
  31. #include "hash.h"
  32. #include "generic.h"
  33. #include "proto.h"
  34. static ExceptionGroup **egArray=NULL;   /* ExceptionGroup by BlkLevel */
  35. static LabelEntry     **leArray=NULL;   /* LabelEntry by BlkLevel     */
  36. static Junction       **altArray=NULL;  /* start of alternates        */
  37. static int              arraySize=0;
  38. static int              highWater=0;
  39. static ExceptionGroup *lastEG=NULL;     /* used in altFixup()         */
  40. static int             lastBlkLevel=0;  /* used in altFixup()         */
  41. static void arrayCheck();
  42. /* Called to add an exception group for an alternative EG */
  43. #ifdef __USE_PROTOS
  44. void egAdd(ExceptionGroup * eg)
  45. #else
  46. void egAdd(eg)
  47. ExceptionGroup *eg;
  48. #endif
  49. {
  50.   int               i;
  51.   ExceptionGroup    *nextEG;
  52.   ExceptionGroup    *innerEG;
  53.   LabelEntry        *nextLE;
  54.   LabelEntry        *innerLE;
  55.   Junction          *nextAlt;
  56.   Junction          *innerAlt;
  57.   lastEG=eg;
  58.   lastBlkLevel=BlkLevel;
  59.   arrayCheck();
  60.   eg->pendingLink=egArray[BlkLevel];
  61.   egArray[BlkLevel]=eg;
  62.   /* EG for alternates already have their atlID filled in      */
  63.   for (i=BlkLevel+1; i<=highWater ; i++) {
  64.     for (innerEG=egArray[i]; innerEG != NULL ; innerEG=nextEG) {
  65.       nextEG=innerEG->pendingLink;
  66.       innerEG->pendingLink=NULL;
  67.       innerEG->outerEG=eg;
  68.     };
  69.     egArray[i]=NULL;
  70.   };
  71.   /*
  72.    *  for patching up the LabelEntry you might use an EG for the
  73.    *  current alternative - unlike patching up an alternative EG
  74.    *    i.e. start the loop at BlkLevel rather than (BlkLevel+1)
  75.    *  fill it in only if the EG and the LE are for the very
  76.    *    same alternative if they're at the same BlkLevel
  77.    *  it's easier to leave the LE on this list (filled in) rather than
  78.    *    trying to selectively remove it.  It will eventually be
  79.    *    removed anyway when the BlkLevel gets small enough.
  80.    */
  81.   for (i=BlkLevel; i<=highWater ; i++) {
  82.     for (innerLE=leArray[i]; innerLE != NULL ; innerLE=nextLE) {
  83.       nextLE=innerLE->pendingLink;
  84.       if (BlkLevel != i ||
  85.         innerLE->curAltNum == CurAltNum) {
  86.         if (innerLE->outerEG == NULL) {
  87.           innerLE->outerEG=eg;
  88.         };
  89.       };
  90.     };
  91.     if (BlkLevel != i) leArray[i]=NULL;
  92.   };
  93. /*
  94.  * For the start of alternatives it is necessary to make a
  95.  * distinction between the exception group for the current
  96.  * alternative and the "fallback" EG for the block which
  97.  * contains the alternative
  98.  *
  99.  * The fallback outerEG is used to handle the case where
  100.  * no alternative of a block matches.  In that case the
  101.  * signal is "NoViableAlt" (or "NoSemViableAlt" and the
  102.  * generator needs the EG of the block CONTAINING the
  103.  * current one.
  104.  *
  105.  *      rule: ( ( ( a
  106.  *                | b
  107.  *                )
  108.  *              | c
  109.  *              )
  110.  *            | d
  111.  *            );
  112.  */
  113.   for (i=BlkLevel; i <= highWater ; i++) {
  114.     for (innerAlt=altArray[i]; innerAlt != NULL ; innerAlt=nextAlt) {
  115.       nextAlt=innerAlt->pendingLink;
  116.       /*  first fill in the EG for the current alternative         */
  117.       /*  but leave it on the list in order to get the fallback EG */
  118.       /*  if the EG is at the same LEVEL as the alternative then   */
  119.       /*    fill it in only if in the very same alternative        */
  120.       /*                                                           */
  121.       /*        rule: ( a                                          */
  122.       /*              | b                                          */
  123.       /*              | c  exception ...                           */
  124.       /*              )                                            */
  125.       /*                                                           */
  126.       /*  if the EG is outside the alternative (e.g. BlkLevel < i) */
  127.       /*    then it doesn't matter about the alternative           */
  128.       /*                                                           */
  129.       /*        rule: ( a                                          */
  130.       /*              | b                                          */
  131.       /*              | c                                          */
  132.       /*              )   exception ...                            */
  133.       /*                                                           */
  134. #if 0
  135.       printf("BlkLevel=%d i=%d altnum=%d CurAltNum=%d altID=%sn",
  136.         BlkLevel,i,innerAlt->curAltNum,CurAltNum,eg->altID);
  137. #endif
  138.       if (BlkLevel != i ||
  139.           innerAlt->curAltNum == CurAltNum) {
  140.         if (innerAlt->exception_label == NULL) {
  141.           innerAlt->exception_label=eg->altID;
  142.         };
  143.       };
  144.       /*  ocurs at a later pass then for the exception_label       */
  145.       /*  if an outerEG has been found then fill in the outer EG   */
  146.       /*  remove if from the list when the BlkLevel gets smaller   */
  147.       if (BlkLevel != i) {
  148.         if (innerAlt->outerEG == NULL) {
  149.           innerAlt->outerEG=eg;
  150.         };
  151.       };
  152.     };
  153.     if (BlkLevel != i) altArray[i]=NULL;
  154.   };
  155. }
  156. #ifdef __USE_PROTOS
  157. void leAdd(LabelEntry * le)
  158. #else
  159. void leAdd(le)
  160. LabelEntry *le;
  161. #endif
  162. {
  163.   arrayCheck();
  164.   le->pendingLink=leArray[BlkLevel];
  165.   le->curAltNum=CurAltNum;
  166.   leArray[BlkLevel]=le;
  167. }
  168. #ifdef __USE_PROTOS
  169. void altAdd(Junction *alt)
  170. #else
  171. void altAdd(alt)
  172. Junction *alt;
  173. #endif
  174. {
  175.   arrayCheck();
  176. #if 0
  177.   printf("BlkLevel=%d CurAltNum=%dn",
  178.             BlkLevel,CurAltNum);
  179. #endif
  180.   alt->curAltNum=CurAltNum;
  181.   alt->pendingLink=altArray[BlkLevel];
  182.   altArray[BlkLevel]=alt;
  183. }
  184. static void arrayCheck() {
  185.   ExceptionGroup    **egArrayNew;
  186.   LabelEntry        **leArrayNew;
  187.   Junction          **altArrayNew;
  188.   int               arraySizeNew;
  189.   int               i;
  190.   if (BlkLevel > highWater) highWater=BlkLevel;
  191.   if (BlkLevel >= arraySize) {
  192.     arraySizeNew=arraySize+5;
  193.     egArrayNew=(ExceptionGroup **)
  194.         calloc(arraySizeNew,sizeof(ExceptionGroup *));
  195.     leArrayNew=(LabelEntry **)
  196.         calloc(arraySizeNew,sizeof(LabelEntry *));
  197.     altArrayNew=(Junction **)
  198.         calloc(arraySizeNew,sizeof(Junction *));
  199.     for (i=0; i<arraySize ; i++) {
  200.       egArrayNew[i]=egArray[i];
  201.       leArrayNew[i]=leArray[i];
  202.       altArrayNew[i]=altArray[i];
  203.     };
  204.     arraySize=arraySizeNew;
  205.     if (egArray != NULL) free( (char *) egArray);
  206.     if (leArray != NULL) free( (char *) leArray);
  207.     if (altArray != NULL) free( (char *) altArray);
  208.     egArray=egArrayNew;
  209.     leArray=leArrayNew;
  210.     altArray=altArrayNew;
  211.   };
  212. }
  213. /* always call leFixup() BEFORE egFixup() */
  214. void egFixup() {
  215.   int               i;
  216.   ExceptionGroup    *nextEG;
  217.   ExceptionGroup    *innerEG;
  218.   for (i=1; i<=highWater ; i++) {
  219.     for (innerEG=egArray[i]; innerEG != NULL ; innerEG=nextEG) {
  220.       nextEG=innerEG->pendingLink;
  221.       innerEG->pendingLink=NULL;
  222.     };
  223.     egArray[i]=NULL;
  224.   };
  225.   lastEG=NULL;
  226.   lastBlkLevel=0;
  227. }
  228. /* always call leFixup() BEFORE egFixup() */
  229. void leFixup() {
  230.   int               i;
  231.   LabelEntry        *nextLE;
  232.   LabelEntry        *innerLE;
  233.   for (i=BlkLevel; i<=highWater ; i++) {
  234.     for (innerLE=leArray[i]; innerLE != NULL ; innerLE=nextLE) {
  235.       nextLE=innerLE->pendingLink;
  236.       innerLE->pendingLink=NULL;
  237.     };
  238.     leArray[i]=NULL;
  239.   };
  240. }
  241. /* always call altFixup() BEFORE egFixup() */
  242. void altFixup() {
  243.   int               i;
  244.   Junction          *nextAlt;
  245.   Junction          *innerAlt;
  246.   for (i=BlkLevel; i<=highWater ; i++) {
  247.     for (innerAlt=altArray[i]; innerAlt != NULL ; innerAlt=nextAlt) {
  248.       /*  if an outerEG has been found then fill in the outer EG   */
  249.       if (lastBlkLevel <= i) {
  250.         if (innerAlt->outerEG == NULL) {
  251.           innerAlt->outerEG=lastEG;
  252.         };
  253.       };
  254.       nextAlt=innerAlt->pendingLink;
  255.       innerAlt->pendingLink=NULL;
  256.     };
  257.     altArray[i]=NULL;
  258.   };
  259. }