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

📄 pattern.c

📁 clips源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
   /* of pattern parsers has not been exceeded.  */   /*============================================*/   if (PatternData(theEnv)->NextPosition >= MAX_POSITIONS) return(FALSE);   /*================================*/   /* Create the new pattern parser. */   /*================================*/   newPtr->positionInArray = PatternData(theEnv)->NextPosition;   PatternData(theEnv)->PatternParserArray[PatternData(theEnv)->NextPosition-1] = newPtr;   PatternData(theEnv)->NextPosition++;   /*================================*/   /* Add the parser to the list of  */   /* parsers based on its priority. */   /*================================*/   if (PatternData(theEnv)->ListOfPatternParsers == NULL)     {      newPtr->next = NULL;      PatternData(theEnv)->ListOfPatternParsers = newPtr;      return(TRUE);     }   currentPtr = PatternData(theEnv)->ListOfPatternParsers;   while ((currentPtr != NULL) ? (newPtr->priority < currentPtr->priority) : FALSE)     {      lastPtr = currentPtr;      currentPtr = currentPtr->next;     }   if (lastPtr == NULL)     {      newPtr->next = PatternData(theEnv)->ListOfPatternParsers;      PatternData(theEnv)->ListOfPatternParsers = newPtr;     }   else     {      newPtr->next = currentPtr;      lastPtr->next = newPtr;     }   return(TRUE);  }/****************************************************//* FindPatternParser: Searches for a pattern parser *//*  that can parse a pattern beginning with the     *//*  specified keyword (e.g. "object").              *//****************************************************/globle struct patternParser *FindPatternParser(  void *theEnv,  char *name)  {   struct patternParser *tempParser;   for (tempParser = PatternData(theEnv)->ListOfPatternParsers;        tempParser != NULL;        tempParser = tempParser->next)     { if (strcmp(tempParser->name,name) == 0) return(tempParser); }   return(NULL);  }/******************************************************//* GetPatternParser: Returns a pointer to the pattern *//*    parser for the specified data entity.           *//******************************************************/struct patternParser *GetPatternParser(  void *theEnv,  int rhsType)  {   if (rhsType == 0) return(NULL);      return(PatternData(theEnv)->PatternParserArray[rhsType-1]);  }#if CONSTRUCT_COMPILER && (! RUN_TIME)/*************************************************************//* PatternNodeHeaderToCode: Writes the C code representation *//*   of a patternNodeHeader data structure.                  *//*************************************************************/globle void PatternNodeHeaderToCode(  void *theEnv,  FILE *fp,  struct patternNodeHeader *theHeader,  int imageID,  int maxIndices)  {   fprintf(fp,"{NULL,NULL,");   if (theHeader->entryJoin == NULL)     { fprintf(fp,"NULL,"); }   else     {      fprintf(fp,"&%s%d_%d[%d],",                 JoinPrefix(),imageID,                 (((int) theHeader->entryJoin->bsaveID) / maxIndices) + 1,                 ((int) theHeader->entryJoin->bsaveID) % maxIndices);     }   PrintHashedExpressionReference(theEnv,fp,theHeader->rightHash,imageID,maxIndices);     fprintf(fp,",%d,%d,%d,0,0,%d,%d,%d}",theHeader->singlefieldNode,                                     theHeader->multifieldNode,                                     theHeader->stopNode,                                     theHeader->beginSlot,                                     theHeader->endSlot,                                     theHeader->selector);  }#endif /* CONSTRUCT_COMPILER && (! RUN_TIME) */#if (! RUN_TIME) && (! BLOAD_ONLY)/****************************************************************//* PostPatternAnalysis: Calls the post analysis routines for    *//*   each of the pattern parsers to allow additional processing *//*   by the pattern parser after the variable analysis routines *//*   have analyzed the LHS patterns.                            *//****************************************************************/globle intBool PostPatternAnalysis(  void *theEnv,  struct lhsParseNode *theLHS)  {   struct lhsParseNode *patternPtr;   struct patternParser *tempParser;   for (patternPtr = theLHS; patternPtr != NULL; patternPtr = patternPtr->bottom)     {      if ((patternPtr->type == PATTERN_CE) && (patternPtr->patternType != NULL))        {         tempParser = patternPtr->patternType;         if (tempParser->postAnalysisFunction != NULL)           { if ((*tempParser->postAnalysisFunction)(theEnv,patternPtr)) return(TRUE); }        }     }   return(FALSE);  }/******************************************************************//* RestrictionParse: Parses a single field within a pattern. This *//*    field may either be a single field wildcard, a multifield   *//*    wildcard, a single field variable, a multifield variable,   *//*    or a series of connected constraints.                       *//*                                                                *//* <constraint> ::= ? |                                           *//*                  $? |                                          *//*                  <connected-constraint>                        *//******************************************************************/struct lhsParseNode *RestrictionParse(  void *theEnv,  char *readSource,  struct token *theToken,  int multifieldSlot,  struct symbolHashNode *theSlot,  short slotNumber,  CONSTRAINT_RECORD *theConstraints,  short position)  {   struct lhsParseNode *topNode = NULL, *lastNode = NULL, *nextNode;   int numberOfSingleFields = 0;   int numberOfMultifields = 0;   short startPosition = position;   int error = FALSE;   CONSTRAINT_RECORD *tempConstraints;   /*==================================================*/   /* Keep parsing fields until a right parenthesis is */   /* encountered. This will either indicate the end   */   /* of an instance or deftemplate slot or the end of */   /* an ordered fact.                                 */   /*==================================================*/   while (theToken->type != RPAREN)     {      /*========================================*/      /* Look for either a single or multifield */      /* wildcard or a conjuctive restriction.  */      /*========================================*/      if ((theToken->type == SF_WILDCARD) ||          (theToken->type == MF_WILDCARD))        {         nextNode = GetLHSParseNode(theEnv);         nextNode->type = theToken->type;         nextNode->negated = FALSE;         nextNode->exists = FALSE;         GetToken(theEnv,readSource,theToken);        }      else        {         nextNode = ConjuctiveRestrictionParse(theEnv,readSource,theToken,&error);         if (nextNode == NULL)           {            ReturnLHSParseNodes(theEnv,topNode);            return(NULL);           }        }      /*========================================================*/      /* Fix up the pretty print representation of a multifield */      /* slot so that the fields don't run together.            */      /*========================================================*/      if ((theToken->type != RPAREN) && (multifieldSlot == TRUE))        {         PPBackup(theEnv);         SavePPBuffer(theEnv," ");         SavePPBuffer(theEnv,theToken->printForm);        }      /*========================================*/      /* Keep track of the number of single and */      /* multifield restrictions encountered.   */      /*========================================*/      if ((nextNode->type == SF_WILDCARD) || (nextNode->type == SF_VARIABLE))        { numberOfSingleFields++; }      else        { numberOfMultifields++; }      /*===================================*/      /* Assign the slot name and indices. */      /*===================================*/      nextNode->slot = theSlot;      nextNode->slotNumber = slotNumber;      nextNode->index = position++;      /*==============================================*/      /* If we're not dealing with a multifield slot, */      /* attach the constraints directly to the node  */      /* and return.                                  */      /*==============================================*/      if (! multifieldSlot)        {         if (theConstraints == NULL)           {            if (nextNode->type == SF_VARIABLE)              { nextNode->constraints = GetConstraintRecord(theEnv); }            else nextNode->constraints = NULL;           }         else nextNode->constraints = theConstraints;         return(nextNode);        }      /*====================================================*/      /* Attach the restriction to the list of restrictions */      /* already parsed for this slot or ordered fact.      */      /*====================================================*/      if (lastNode == NULL) topNode = nextNode;      else lastNode->right = nextNode;      lastNode = nextNode;     }   /*=====================================================*/   /* Once we're through parsing, check to make sure that */   /* a single field slot was given a restriction. If the */   /* following test fails, then we know we're dealing    */   /* with a multifield slot.                             */   /*=====================================================*/   if ((topNode == NULL) && (! multifieldSlot))     {      SyntaxErrorMessage(theEnv,"defrule");      return(NULL);     }   /*===============================================*/   /* Loop through each of the restrictions in the  */   /* list of restrictions for the multifield slot. */   /*===============================================*/   for (nextNode = topNode; nextNode != NULL; nextNode = nextNode->right)     {      /*===================================================*/      /* Assign a constraint record to each constraint. If */      /* the slot has an explicit constraint, then copy    */      /* this and store it with the constraint. Otherwise, */      /* create a constraint record for a single field     */      /* constraint and skip the constraint modifications  */      /* for a multifield constraint.                      */      /*===================================================*/      if (theConstraints == NULL)        {         if (nextNode->type == SF_VARIABLE)           { nextNode->constraints = GetConstraintRecord(theEnv); }         else           { continue; }        }      else        { nextNode->constraints = CopyConstraintRecord(theEnv,theConstraints); }      /*==========================================*/      /* Remove the min and max field constraints */      /* for the entire slot from the constraint  */      /* record for this single constraint.       */      /*==========================================*/      ReturnExpression(theEnv,nextNode->constraints->minFields);      ReturnExpression(theEnv,nextNode->constraints->maxFields);      nextNode->constraints->minFields = GenConstant(theEnv,SYMBOL,SymbolData(theEnv)->NegativeInfinity);      nextNode->constraints->maxFields = GenConstant(theEnv,SYMBOL,SymbolData(theEnv)->PositiveInfinity);      nextNode->derivedConstraints = TRUE;      /*====================================================*/      /* If we're not dealing with a multifield constraint, */      /* then no further modifications are needed to the    */      /* min and max constraints for this constraint.       */      /*====================================================*/      if ((nextNode->type != MF_WILDCARD) && (nextNode->type != MF_VARIABLE))        { continue; }      /*==========================================================*/      /* Create a separate constraint record to keep track of the */      /* cardinality information for this multifield constraint.  */      /*==========================================================*/      tempConstraints = GetConstraintRecord(theEnv);      SetConstraintType(MULTIFIELD,tempConstraints);      tempConstraints->singlefieldsAllowed = FALSE;      tempConstraints->multifield = nextNode->constraints;      nextNode->constraints = tempConstraints;      /*=====================================================*/      /* Adjust the min and max field values for this single */      /* multifield constraint based on the min and max      */      /* fields for the entire slot and the number of single */      /* field values contained in the slot.                 */      /*=====================================================*/      if (theConstraints->maxFields->value != SymbolData(theEnv)->PositiveInfinity)        {         ReturnExpression(theEnv,tempConstraints->maxFields);         tempConstraints->maxFields = GenConstant(theEnv,INTEGER,EnvAddLong(theEnv,ValueToLong(theConstraints->maxFields->value) - numberOfSingleFields));        }      if ((numberOfMultifields == 1) && (theConstraints->minFields->value != SymbolData(theEnv)->NegativeInfinity))        {         ReturnExpression(theEnv,tempConstraints->minFields);         tempConstraints->minFields = GenConstant(theEnv,INTEGER,EnvAddLong(theEnv,ValueToLong(theConstraints->minFields->value) - numberOfSingleFields));        }     }   /*================================================*/   /* If a multifield slot is being parsed, place a  */   /* node on top of the list of constraints parsed. */   /*================================================*/   if (multifieldSlot)     {      nextNode = GetLHSParseNode(theEnv);      nextNode->type = MF_WILDCARD;      nextNode->multifieldSlot = TRUE;      nextNode->bottom = topNode;      nextNode->slot = theSlot;      nextNode->slotNumber = slotNumber;      nextNode->index = startPosition;      nextNode->constraints = theConstraints;      topNode = nextNode;      TallyFieldTypes(topNode->bottom);     }   /*=================================*/   /* Return the list of constraints. */   /*=================================*/   return(topNode);  }/***************************************************************//* TallyFieldTypes: Determines the number of single field and  *//*   multifield variables and wildcards that appear before and *//*   after each restriction found in a multifield slot.        *//***************************************************************/static void TallyFieldTypes(  struct lhsParseNode *theRestrictions)  {   struct lhsParseNode *tempNode1, *tempNode2, *tempNode3;   unsigned short totalSingleFields = 0, totalMultiFields = 0;   unsigned short runningSingleFields = 0, runningMultiFields = 0;   /*========================================*/   /* Compute the total number of single and */   /* multifield variables and wildcards.    */   /*========================================*/   for (tempNode1 = theRestrictions; tempNode1 != NULL; tempNode1 = tempNode1->right)     {      if ((tempNode1->type == SF_VARIABLE) || (tempNode1->type == SF_WILDCARD))        { totalSingleFields++; }      else        { totalMultiFields++; }     }   /*======================================================*/   /* Loop through each constraint tallying the numbers of */   /* the variable types before and after along the way.   */   /*======================================================*/   for (tempNode1 = theRestrictions; tempNode1 != NULL; tempNode1 = tempNode1->right)     {      /*===================================*/      /* Assign the values to the "binding */      /* variable" node of the constraint. */      /*===================================*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -