📄 compiler.c
字号:
*
* Description : If repetition is GrpRule/OptRule/Opt_Lst type, Create
* a new rule put into the new rule list and replace the
* repetition with the new rule.
*
* Input parameters : pOrigName - pointer to the original name of the repetition
* pGrpOptRep - pointer to the original repetition pointer
* pOriRuleList - pointer to the original rule list pointer
* pNewRuleList - pointer to the pointer of the new rule list
* in which the created new rule to be put
*
* Output parameters : pGrpOptRep - type and name are modified
* pOriRuleList - GroupOption repet are modified
* pNewRuleList - new rule list
*
* Return value : If succeed, return the pointer of created new rule,
* otherwise NULL.
*
* Comments : 1)pRep->pRuleName must be NULL, after create new rule,
* store the name of the new rule
* 2)pRep->iType must be GROUP/OPTION/OPT_LST
*
* History :
* 2005/04/15 : Creation
*
* Date : April 15 2005, Frank Zhang
**************************************************************************/
#define MAX_SEEK_TIMES 255
TRule* CreateNewRule(char *pOrigName,TRepetition *pGrpOptRep,
TRuleList *pOriRuleList, TRuleList *pNewRuleList)
{
int i = 0;
int j,k;
char NewName[100];
TRepetition *pRepInGrp;
TRule *pNewRule = NULL;
/* Flag indicating if dup name in rule list */
BOOL bFlag = FALSE;
/* Type must be ELEMENT_GRP_RULE/ELEMENT_OPT_RULE/ELEMENT_OPT_LST */
Assert(pGrpOptRep->iType == ELEMENT_GRP_RULE
|| pGrpOptRep->iType == ELEMENT_OPT_RULE
|| pGrpOptRep->iType == ELEMENT_OPT_LST);
/* Create a new rule name, to avoid dead loop, only try limited times */
while (i < MAX_SEEK_TIMES)
{
bFlag = FALSE;
sprintf(NewName, "%s_%d", pOrigName, i++);
/* Check if New name is dup in rule list */
for(j = 0; j < pOriRuleList->iCount; j++)
{
if (StrCaseCmp(pOriRuleList->pRule[j].pRuleName, NewName) == 0)
{
bFlag = TRUE;
break;
}
}
if (bFlag) continue;
/* Check if New name is dup in new rule list */
for(k = 0; k < pNewRuleList->iCount; k++)
{
if (StrCaseCmp(pNewRuleList->pRule[k].pRuleName, NewName) == 0)
{
bFlag = TRUE;
break;
}
}
if (bFlag) continue;
else break;
}
/*Fail to create new rule name*/
if (bFlag)
{
printf("\nError! Fail to create new Rule name : %s", pOrigName);
return NULL;
}
/* New Rule Name Ok, Create a new Rule */
pNewRule = AddNewRule(pNewRuleList, NewName);
/* Concatenation num Must be 1 in group/option */
Assert(pGrpOptRep->GroupOption.Rule.iCount == 1);
pNewRule->iCount = pGrpOptRep->GroupOption.Rule.iCount;
pNewRule->iType = pGrpOptRep->iType;
if (pGrpOptRep->iType == ELEMENT_GRP_RULE
|| pGrpOptRep->iType == ELEMENT_OPT_RULE)
{
pNewRule->pConcat = pGrpOptRep->GroupOption.Rule.pConcat;
/* Store the RuleName */
StrClone(&pGrpOptRep->pRuleName, NewName);
/* Remove the Grp repet */
pGrpOptRep->GroupOption.Rule.pConcat = NULL;
pGrpOptRep->GroupOption.Rule.iCount = 0;
}
else if (pGrpOptRep->iType == ELEMENT_OPT_LST)
{
pRepInGrp = ((TConcatenation*)pGrpOptRep->GroupOption.Rule.pConcat)->pRepetition+1;
pNewRule->pConcat = pRepInGrp->GroupOption.Rule.pConcat;
/* Remove the Grp repet in Opt */
pRepInGrp->GroupOption.Rule.pConcat = NULL;
pRepInGrp->GroupOption.Rule.iCount = 0;
/* Change the Repeat*/
pGrpOptRep->iRepMin = pRepInGrp->iRepMin;
pGrpOptRep->iRepMax = pRepInGrp->iRepMax;
StrClone(&pGrpOptRep->pRuleName, NewName);
/* Remove the Group */
FreeGroupOption(&pGrpOptRep->GroupOption);
memset(&pGrpOptRep->GroupOption, 0, sizeof(TGroupOption));
}
return pNewRule;
}
/***************************************************************************
* Function : MergeRules
*
* Description : Merger one rule list into another
*
* Input parameters : pDes - pointer of destination rule list
* pSrc - pointer of merged rule list
*
* Output parameters : pDesFinal - new rules added
* pSrc - rules are deleted
*
* Return value : None
*
* Comments :
*
* History :
* 2005/04/15 : Creation
*
* Date : April 15 2005, Frank Zhang
**************************************************************************/
void MergeRules(TRuleList *pDes, TRuleList *pSrc)
{
if ((pDes != NULL) && (pSrc != NULL))
{
pDes->pRule = realloc(pDes->pRule, (pDes->iCount + pSrc->iCount)*sizeof(TRule));
Assert(pDes->pRule);
memcpy(pDes->pRule + pDes->iCount, pSrc->pRule, pSrc->iCount*sizeof(TRule));
pDes->iCount += pSrc->iCount;
free(pSrc->pRule);
pSrc->iCount = 0;
pSrc->pRule = NULL;
}
}
/***************************************************************************
* Function : IsOneElement
*
* Description : Check if the GroupOption onle contain only one element
* which format is "* (element) " or " *[element] "
*
* Input parameters : pGrp - pointer of GroupOption to be checked
*
* Output parameters : None
*
* Return value : TRUE - GroupOption is one element
* FALSE - GroupOption isn't one element
*
* Comments :
*
* History :
* 2005/04/15 : Creation
*
* Date : April 15 2005, Frank Zhang
**************************************************************************/
BOOL IsOneElement(TGroupOption *pGrp)
{
TConcatenation *pConcat;
TRepetition *pRep;
BOOL bResult = FALSE;
Assert(pGrp);
/* only one concate */
if (pGrp->Rule.iCount == 1)
{
pConcat = (TConcatenation*)pGrp->Rule.pConcat;
/* only one repetition */
if (pConcat->iCount == 1)
{
pRep = pConcat->pRepetition;
if ((pRep->iType != ELEMENT_GROUP) /* Not a group type */
&& (pRep->iType != ELEMENT_OPTION) /* Not a option type */
&& (pRep->iRepMax == 1) /* Repeat is 1 */
&& (pRep->iRepMin == 1))
bResult = TRUE;
}
}
return bResult;
}
/***************************************************************************
* Function : PreProcessRepet
*
* Description : Check if the repetition is OneElement or token type, if
* OneElement type, convert it to be rule type or token type,
* if rule type and capital, change it to be token type
*
* Input parameters : pRep - pointer to Repetition
*
* Output parameters : pRep - Processed repetition
*
* Return value : None
*
* Comments :
*
* History :
* 2005/04/15 : Creation
*
* Date : April 15 2005, Frank Zhang
**************************************************************************/
void PreProcessRepet(TRepetition *pRep)
{
TRepetition *pRepInGrp;
Assert(pRep);
/* Token type ? */
if ((pRep->iType == ELEMENT_RULE) && AllUpperCase(pRep->pName))
{
pRep->iType = ELEMENT_TOKEN;
return;
}
/* Fake group type ? Rule = *(ElementName) */
if ((pRep->iType == ELEMENT_GROUP) && IsOneElement(&pRep->GroupOption))
{
/* Repetition in group */
pRepInGrp = ((TConcatenation*)pRep->GroupOption.Rule.pConcat)->pRepetition;
/* Convert repetiton from Group type to be the type of repetition in group */
pRep->pName = pRepInGrp->pName;
pRepInGrp->pName = NULL;
pRep->iNumbValueStart = pRepInGrp->iNumbValueStart;
pRep->iNumbValueEnd = pRepInGrp->iNumbValueEnd;
if (AllUpperCase(pRep->pName) && pRepInGrp->iType != ELEMENT_STRING)
pRep->iType = ELEMENT_TOKEN;
else
pRep->iType = pRepInGrp->iType;
/* remove the group */
free(pRepInGrp);
free((TConcatenation*)pRep->GroupOption.Rule.pConcat);
pRep->GroupOption.Rule.iCount = 0;
}
/* If One-element option and the element is token type, because Opion type
* must contain one rule name, so convert this type into Token list type
* Rule = [TOKEN] */
if ((pRep->iType == ELEMENT_OPTION) && (IsOneElement(&pRep->GroupOption)))
{
/* Repetition in group */
pRepInGrp = ((TConcatenation*)pRep->GroupOption.Rule.pConcat)->pRepetition;
if (AllUpperCase(pRepInGrp->pName) && pRepInGrp->iType != ELEMENT_STRING)
{
pRep->iType = ELEMENT_TOKEN;
/* Convert repetiton from Option type to be the type of repetition in group */
pRep->pName = pRepInGrp->pName;
pRepInGrp->pName = NULL;
pRep->iNumbValueStart = pRepInGrp->iNumbValueStart;
pRep->iNumbValueEnd = pRepInGrp->iNumbValueEnd;
/* If one-element Option type, because the type has been changed to be
* the element type in the group, so change the repeat to be 0-1 */
pRep->iRepMin = 0;
pRep->iRepMax = 1;
/* remove the group */
free(pRepInGrp);
free((TConcatenation*)pRep->GroupOption.Rule.pConcat);
pRep->GroupOption.Rule.iCount = 0;
}
}
}
/***************************************************************************
* Function : ProcessRep
*
* Description : Check the repetition's validity and decide its type.
*
* Input parameters : pRep - pointer to repetition
* pRuleList - parameter passed to internal function
* pNewRuleList - parameter passed to internal function
*
* Output parameters : pRep - processed repetition
* pRuleList - processed rule list
* pNewRuleList - new rule list
*
* Return value : TRUE - repetiton format is supported
* FALSE - repetiton format is unsupported
*
* Comments :
*
* History :
* 2005/04/15 : Creation
*
* Date : April 15 2005, Frank Zhang
**************************************************************************/
BOOL ProcessRep(TRepetition *pRep, TRuleList *pRuleList,
TRuleList *pNewRuleList)
{
BOOL bRet = TRUE;
/*Process Tokens and OneElem Group */
PreProcessRepet(pRep);
/*Group type*/
if (pRep->iType == ELEMENT_GROUP)
return ProcessGroup(pRep, pRuleList, pNewRuleList);
/*Option type*/
if (pRep->iType == ELEMENT_OPTION)
return ProcessOpt(pRep, pRuleList, pNewRuleList);
/*other type, no need to prodess*/
return bRet;
}
/***************************************************************************
* Function : ProcessConcat
*
* Description : Check the Concatenation's validity and decdied repetitions
* type in it.
*
* Input parameters : pConcat - pointer of Concatenation
* pRuleList - parameter passed to internal function
* pNewRuleList - parameter passed to internal function
*
* Output parameters : pConcat - processed concat
* pRuleList - processed rule list
* pNewRuleList - new rule list
*
* Return value : TRUE - Concatenation format is valid
* FALSE - Concatenation format is invalid
*
* Comments : Compound repetitions includ Opt_Lst and RuleLst:
* Opt_LST = [Rule *(*WSP Rule %d12)]
* RuleLST = Rule *(*WSP Rule %d12)
*
* History :
* 2005/04/15 : Creation
*
* Date : April 15 2005, Frank Zhang
**************************************************************************/
BOOL ProcessConcat(TConcatenation *pConcat, TRuleList *pRuleList,
TRuleList *pNewRuleList)
{
int i,j;
TRepetition *pCurRep, *pNextRep;
/* Check every repetition's validity and decide its type */
for (i = 0; i < pConcat->iCount; i++)
{
if (!ProcessRep(pConcat->pRepetition + i, pRuleList, pNewRuleList))
return FALSE;
}
/* Check if two adjacent repetitions can be compounded into RuleLst type in
* this concatenation, if find, convert it */
for (i = 0; i < pConcat->iCount-1; i++)
{
pCurRep = pConcat->pRepetition + i;
pNextRep = pConcat->pRepetition + i + 1;
if (pCurRep->iType == ELEMENT_RULE
&& pNextRep->iType == ELEMENT_GRP_RULE
&& pCurRep->iRepMin == 1
&& pCurRep->iRepMax == 1)
{
if (StrCaseCmp(pCurRep->pName, pNextRep->pName) == 0)
{
/* Change the Repetition type */
pCurRep->iType = ELEMENT_RULE_LST_RULE;
pNextRep->iType = ELEMENT_RULE_LST_GRP;
}
}
}
/* Check if repetition name in this concatenation is dup; bellow types
* must be checked: */
/*
ELEMENT_RULE
ELEMENT_GRP_RULE
ELEMENT_OPT_RULE
ELEMENT_OPT_LST
ELEMENT_RULE_LST_GRP
*/
for (i = 0; i < pConcat->iCount-1; i++)
{
pCurRep = pConcat->pRepetition + i;
if (pCurRep->iType == ELEMENT_RULE
|| pCurRep->iType == ELEMENT_GRP_RULE
|| pCurRep->iType == ELEMENT_OPT_RULE
|| pCurRep->iType == ELEMENT_OPT_LST
|| pCurRep->iType == ELEMENT_RULE_LST_GRP)
{
for (j =i+1; j < pConcat->iCount; j++)
{
pNextRep = pConcat->pRepetition + j;
if (pNextRep->iType == ELEMENT_RULE
|| pNextRep->iType == ELEMENT_GRP_RULE
|| pNextRep->iType == ELEMENT_OPT_RULE
|| pNextRep->iType == ELEMENT_OPT_LST
|| pNextRep->iType == ELEMENT_RULE_LST_GRP)
{
if (StrCaseCmp(pCurRep->pName, pNextRep->pName) == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -