mirror of https://github.com/acidanthera/audk.git
329 lines
9.3 KiB
C
329 lines
9.3 KiB
C
|
/*
|
||
|
* egman.c
|
||
|
*
|
||
|
* SOFTWARE RIGHTS
|
||
|
*
|
||
|
* We reserve no LEGAL rights to the Purdue Compiler Construction Tool
|
||
|
* Set (PCCTS) -- PCCTS is in the public domain. An individual or
|
||
|
* company may do whatever they wish with source code distributed with
|
||
|
* PCCTS or the code generated by PCCTS, including the incorporation of
|
||
|
* PCCTS, or its output, into commerical software.
|
||
|
*
|
||
|
* We encourage users to develop software with PCCTS. However, we do ask
|
||
|
* that credit is given to us for developing PCCTS. By "credit",
|
||
|
* we mean that if you incorporate our source code into one of your
|
||
|
* programs (commercial product, research project, or otherwise) that you
|
||
|
* acknowledge this fact somewhere in the documentation, research report,
|
||
|
* etc... If you like PCCTS and have developed a nice tool with the
|
||
|
* output, please mention that you developed it using PCCTS. In
|
||
|
* addition, we ask that this header remain intact in our source code.
|
||
|
* As long as these guidelines are kept, we expect to continue enhancing
|
||
|
* this system and expect to make other tools available as they are
|
||
|
* completed.
|
||
|
*
|
||
|
* ANTLR 1.33MR10
|
||
|
* 2001
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
#include "set.h"
|
||
|
#include "syn.h"
|
||
|
#include "hash.h"
|
||
|
#include "generic.h"
|
||
|
#include "proto.h"
|
||
|
|
||
|
static ExceptionGroup **egArray=NULL; /* ExceptionGroup by BlkLevel */
|
||
|
static LabelEntry **leArray=NULL; /* LabelEntry by BlkLevel */
|
||
|
static Junction **altArray=NULL; /* start of alternates */
|
||
|
static int arraySize=0;
|
||
|
static int highWater=0;
|
||
|
static ExceptionGroup *lastEG=NULL; /* used in altFixup() */
|
||
|
static int lastBlkLevel=0; /* used in altFixup() */
|
||
|
|
||
|
#ifdef __USE_PROTOS
|
||
|
static void arrayCheck(void);
|
||
|
#else
|
||
|
static void arrayCheck();
|
||
|
#endif
|
||
|
|
||
|
/* Called to add an exception group for an alternative EG */
|
||
|
|
||
|
#ifdef __USE_PROTOS
|
||
|
void egAdd(ExceptionGroup * eg)
|
||
|
#else
|
||
|
void egAdd(eg)
|
||
|
ExceptionGroup *eg;
|
||
|
#endif
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
ExceptionGroup *nextEG;
|
||
|
ExceptionGroup *innerEG;
|
||
|
|
||
|
LabelEntry *nextLE;
|
||
|
LabelEntry *innerLE;
|
||
|
|
||
|
Junction *nextAlt;
|
||
|
Junction *innerAlt;
|
||
|
|
||
|
lastEG=eg;
|
||
|
lastBlkLevel=BlkLevel;
|
||
|
|
||
|
arrayCheck();
|
||
|
eg->pendingLink=egArray[BlkLevel];
|
||
|
egArray[BlkLevel]=eg;
|
||
|
|
||
|
/* EG for alternates already have their altID filled in */
|
||
|
|
||
|
for (i=BlkLevel+1; i<=highWater ; i++) {
|
||
|
for (innerEG=egArray[i]; innerEG != NULL ; innerEG=nextEG) {
|
||
|
nextEG=innerEG->pendingLink;
|
||
|
innerEG->pendingLink=NULL;
|
||
|
innerEG->outerEG=eg;
|
||
|
};
|
||
|
egArray[i]=NULL;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* for patching up the LabelEntry you might use an EG for the
|
||
|
* current alternative - unlike patching up an alternative EG
|
||
|
* i.e. start the loop at BlkLevel rather than (BlkLevel+1)
|
||
|
* fill it in only if the EG and the LE are for the very
|
||
|
* same alternative if they're at the same BlkLevel
|
||
|
* it's easier to leave the LE on this list (filled in) rather than
|
||
|
* trying to selectively remove it. It will eventually be
|
||
|
* removed anyway when the BlkLevel gets small enough.
|
||
|
*/
|
||
|
|
||
|
for (i=BlkLevel; i<=highWater ; i++) {
|
||
|
for (innerLE=leArray[i]; innerLE != NULL ; innerLE=nextLE) {
|
||
|
nextLE=innerLE->pendingLink;
|
||
|
if (BlkLevel != i ||
|
||
|
innerLE->curAltNum == CurAltNum_array[BlkLevel]) {
|
||
|
if (innerLE->outerEG == NULL) {
|
||
|
innerLE->outerEG=eg;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
if (BlkLevel != i) leArray[i]=NULL;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* For the start of alternatives it is necessary to make a
|
||
|
* distinction between the exception group for the current
|
||
|
* alternative and the "fallback" EG for the block which
|
||
|
* contains the alternative
|
||
|
*
|
||
|
* The fallback outerEG is used to handle the case where
|
||
|
* no alternative of a block matches. In that case the
|
||
|
* signal is "NoViableAlt" (or "NoSemViableAlt" and the
|
||
|
* generator needs the EG of the block CONTAINING the
|
||
|
* current one.
|
||
|
*
|
||
|
* rule: ( ( ( a
|
||
|
* | b
|
||
|
* )
|
||
|
* | c
|
||
|
* )
|
||
|
* | d
|
||
|
* );
|
||
|
*/
|
||
|
|
||
|
for (i=BlkLevel; i <= highWater ; i++) {
|
||
|
for (innerAlt=altArray[i]; innerAlt != NULL ; innerAlt=nextAlt) {
|
||
|
nextAlt=innerAlt->pendingLink;
|
||
|
|
||
|
/* first fill in the EG for the current alternative */
|
||
|
/* but leave it on the list in order to get the fallback EG */
|
||
|
/* if the EG is at the same LEVEL as the alternative then */
|
||
|
/* fill it in only if in the very same alternative */
|
||
|
/* */
|
||
|
/* rule: ( a */
|
||
|
/* | b */
|
||
|
/* | c exception ... */
|
||
|
/* ) */
|
||
|
/* */
|
||
|
/* if the EG is outside the alternative (e.g. BlkLevel < i) */
|
||
|
/* then it doesn't matter about the alternative */
|
||
|
/* */
|
||
|
/* rule: ( a */
|
||
|
/* | b */
|
||
|
/* | c */
|
||
|
/* ) exception ... */
|
||
|
/* */
|
||
|
|
||
|
#if 0
|
||
|
printf("BlkLevel=%d i=%d altnum=%d CurAltNum=%d altID=%s\n",
|
||
|
BlkLevel,i,innerAlt->curAltNum,CurAltNum_array[BlkLevel],eg->altID);
|
||
|
#endif
|
||
|
if (BlkLevel != i ||
|
||
|
innerAlt->curAltNum == CurAltNum_array[BlkLevel]) {
|
||
|
if (innerAlt->exception_label == NULL) {
|
||
|
innerAlt->exception_label=eg->altID;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
/* ocurs at a later pass then for the exception_label */
|
||
|
/* if an outerEG has been found then fill in the outer EG */
|
||
|
/* remove if from the list when the BlkLevel gets smaller */
|
||
|
|
||
|
if (BlkLevel != i) {
|
||
|
if (innerAlt->outerEG == NULL) {
|
||
|
innerAlt->outerEG=eg;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
if (BlkLevel != i) altArray[i]=NULL;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
#ifdef __USE_PROTOS
|
||
|
void leAdd(LabelEntry * le)
|
||
|
#else
|
||
|
void leAdd(le)
|
||
|
LabelEntry *le;
|
||
|
#endif
|
||
|
|
||
|
{
|
||
|
arrayCheck();
|
||
|
le->pendingLink=leArray[BlkLevel];
|
||
|
le->curAltNum=CurAltNum_array[BlkLevel];
|
||
|
leArray[BlkLevel]=le;
|
||
|
}
|
||
|
|
||
|
#ifdef __USE_PROTOS
|
||
|
void altAdd(Junction *alt)
|
||
|
#else
|
||
|
void altAdd(alt)
|
||
|
Junction *alt;
|
||
|
#endif
|
||
|
|
||
|
{
|
||
|
arrayCheck();
|
||
|
#if 0
|
||
|
printf("BlkLevel=%d CurAltNum=%d\n",
|
||
|
BlkLevel,CurAltNum_array[BlkLevel]);
|
||
|
#endif
|
||
|
alt->curAltNum=CurAltNum_array[BlkLevel];
|
||
|
alt->pendingLink=altArray[BlkLevel];
|
||
|
altArray[BlkLevel]=alt;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
#ifdef __USE_PROTOS
|
||
|
arrayCheck(void)
|
||
|
#else
|
||
|
arrayCheck()
|
||
|
#endif
|
||
|
{
|
||
|
ExceptionGroup **egArrayNew;
|
||
|
LabelEntry **leArrayNew;
|
||
|
Junction **altArrayNew;
|
||
|
int arraySizeNew;
|
||
|
int i;
|
||
|
|
||
|
if (BlkLevel > highWater) highWater=BlkLevel;
|
||
|
|
||
|
if (BlkLevel >= arraySize) {
|
||
|
arraySizeNew=BlkLevel+5; /* MR20 */
|
||
|
egArrayNew=(ExceptionGroup **)
|
||
|
calloc(arraySizeNew,sizeof(ExceptionGroup *));
|
||
|
leArrayNew=(LabelEntry **)
|
||
|
calloc(arraySizeNew,sizeof(LabelEntry *));
|
||
|
altArrayNew=(Junction **)
|
||
|
calloc(arraySizeNew,sizeof(Junction *));
|
||
|
for (i=0; i<arraySize ; i++) {
|
||
|
egArrayNew[i]=egArray[i];
|
||
|
leArrayNew[i]=leArray[i];
|
||
|
altArrayNew[i]=altArray[i];
|
||
|
};
|
||
|
arraySize=arraySizeNew;
|
||
|
if (egArray != NULL) free( (char *) egArray);
|
||
|
if (leArray != NULL) free( (char *) leArray);
|
||
|
if (altArray != NULL) free( (char *) altArray);
|
||
|
egArray=egArrayNew;
|
||
|
leArray=leArrayNew;
|
||
|
altArray=altArrayNew;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
/* always call leFixup() BEFORE egFixup() */
|
||
|
|
||
|
void
|
||
|
#ifdef __USE_PROTOS
|
||
|
egFixup(void)
|
||
|
#else
|
||
|
egFixup()
|
||
|
#endif
|
||
|
{
|
||
|
int i;
|
||
|
ExceptionGroup *nextEG;
|
||
|
ExceptionGroup *innerEG;
|
||
|
|
||
|
for (i=1; i<=highWater ; i++) {
|
||
|
for (innerEG=egArray[i]; innerEG != NULL ; innerEG=nextEG) {
|
||
|
nextEG=innerEG->pendingLink;
|
||
|
innerEG->pendingLink=NULL;
|
||
|
};
|
||
|
egArray[i]=NULL;
|
||
|
};
|
||
|
lastEG=NULL;
|
||
|
lastBlkLevel=0;
|
||
|
}
|
||
|
|
||
|
/* always call leFixup() BEFORE egFixup() */
|
||
|
|
||
|
#ifdef __USE_PROTOS
|
||
|
void leFixup(void)
|
||
|
#else
|
||
|
void leFixup()
|
||
|
#endif
|
||
|
{
|
||
|
|
||
|
int i;
|
||
|
LabelEntry *nextLE;
|
||
|
LabelEntry *innerLE;
|
||
|
|
||
|
for (i=BlkLevel; i<=highWater ; i++) {
|
||
|
for (innerLE=leArray[i]; innerLE != NULL ; innerLE=nextLE) {
|
||
|
nextLE=innerLE->pendingLink;
|
||
|
innerLE->pendingLink=NULL;
|
||
|
};
|
||
|
leArray[i]=NULL;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
/* always call altFixup() BEFORE egFixup() */
|
||
|
|
||
|
#ifdef __USE_PROTOS
|
||
|
void altFixup(void)
|
||
|
#else
|
||
|
void altFixup()
|
||
|
#endif
|
||
|
{
|
||
|
|
||
|
int i;
|
||
|
Junction *nextAlt;
|
||
|
Junction *innerAlt;
|
||
|
|
||
|
for (i=BlkLevel; i<=highWater ; i++) {
|
||
|
for (innerAlt=altArray[i]; innerAlt != NULL ; innerAlt=nextAlt) {
|
||
|
|
||
|
/* if an outerEG has been found then fill in the outer EG */
|
||
|
|
||
|
if (lastBlkLevel <= i) {
|
||
|
if (innerAlt->outerEG == NULL) {
|
||
|
innerAlt->outerEG=lastEG;
|
||
|
};
|
||
|
};
|
||
|
nextAlt=innerAlt->pendingLink;
|
||
|
innerAlt->pendingLink=NULL;
|
||
|
};
|
||
|
altArray[i]=NULL;
|
||
|
};
|
||
|
}
|
||
|
|