⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compiler.c

📁 mgcp协议源代码和测试程序,还有一个编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
 *
 * 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 + -