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

📄 analysis.c

📁 clips源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
   /*===================================================*/   /* Otherwise a pattern variable is being propagated. */   /*===================================================*/   else     {      theType = thePattern->type;      theVariable = (struct symbolHashNode *) thePattern->value;     }   /*===================================================*/   /* Propagate the variable location to any additional */   /* fields associated with the binding variable.      */   /*===================================================*/   if (thePattern->type != PATTERN_CE)     {      PropagateVariableToNodes(theEnv,thePattern->bottom,theType,theVariable,                               thePattern,patternHead->beginNandDepth,                               TRUE,FALSE);      if (ProcessField(theEnv,thePattern,multifieldHeader,patternHead))        { return(TRUE); }     }   /*=================================================================*/   /* Propagate the constraints to other fields, slots, and patterns. */   /*=================================================================*/   return(PropagateVariableDriver(theEnv,patternHead,thePattern,multifieldHeader,theType,                                  theVariable,thePattern,TRUE));  }/*******************************************//* PropagateVariableDriver: Driver routine *//*   for propagating variable references.  *//*******************************************/static int PropagateVariableDriver(  void *theEnv,  struct lhsParseNode *patternHead,  struct lhsParseNode *theNode,  struct lhsParseNode *multifieldHeader,  int theType,  struct symbolHashNode *variableName,  struct lhsParseNode *theReference,  int assignReference)  {   /*===================================================*/   /* Propagate the variable location to any additional */   /* constraints associated with the binding variable. */   /*===================================================*/   if (multifieldHeader != NULL)     {      if (PropagateVariableToNodes(theEnv,multifieldHeader->right,theType,variableName,                                   theReference,patternHead->beginNandDepth,assignReference,FALSE))        {         VariableMixingErrorMessage(theEnv,variableName);         return(TRUE);        }     }   /*========================================================*/   /* Propagate the variable location to fields/slots in the */   /* same pattern which appear after the binding variable.  */   /*========================================================*/   if (PropagateVariableToNodes(theEnv,theNode->right,theType,variableName,theReference,                                patternHead->beginNandDepth,assignReference,FALSE))     {      VariableMixingErrorMessage(theEnv,variableName);      return(TRUE);     }   /*======================================================*/   /* Propagate values to other patterns if the pattern in */   /* which the variable is found is not a "not" CE or the */   /* last pattern within a nand CE.                       */   /*======================================================*/   if (((patternHead->type == PATTERN_CE) || (patternHead->type == TEST_CE)) &&       (patternHead->negated == FALSE) &&       (patternHead->exists == FALSE) &&       (patternHead->beginNandDepth <= patternHead->endNandDepth))     {      int ignoreVariableMixing;      /*============================================================*/      /* If the variables are propagated from a test CE, then don't */      /* check for mixing of single and multifield variables (since */      /* previously bound multifield variables typically have the $ */      /* removed when passed as an argument to a function unless    */      /* sequence expansion is desired).                            */      /*============================================================*/      if (patternHead->type == TEST_CE) ignoreVariableMixing = TRUE;      else ignoreVariableMixing = FALSE;      /*==========================*/      /* Propagate the reference. */      /*==========================*/      if (PropagateVariableToNodes(theEnv,patternHead->bottom,theType,variableName,theReference,                                   patternHead->beginNandDepth,assignReference,                                   ignoreVariableMixing))       {         VariableMixingErrorMessage(theEnv,variableName);         return(TRUE);        }     }   /*==============================================*/   /* Return FALSE to indicate that no errors were */   /* generated by the variable propagation.       */   /*==============================================*/   return(FALSE);  }/********************************************************//* ProcessField: Processes a field or slot of a pattern *//*   which does not contain a binding variable.         *//********************************************************/static int ProcessField(  void *theEnv,  struct lhsParseNode *thePattern,  struct lhsParseNode *multifieldHeader,  struct lhsParseNode *patternHead)  {   struct lhsParseNode *theList, *tempList;   /*====================================================*/   /* Nothing needs to be done for the node representing */   /* the entire pattern. Return FALSE to indicate that  */   /* no errors were generated.                          */   /*====================================================*/   if (thePattern->type == PATTERN_CE) return(FALSE);   /*====================================================================*/   /* Derive a set of constraints based on values found in the slot or   */   /* field. For example, if a slot can only contain the values 1, 2, or */   /* 3, the field constraint ~2 would generate a constraint record that */   /* only allows the value 1 or 3. Once generated, the constraints are  */   /* propagated to other slots and fields.                              */   /*====================================================================*/   theList = DeriveVariableConstraints(theEnv,thePattern);   for (tempList = theList; tempList != NULL; tempList = tempList->right)     {      if (PropagateVariableDriver(theEnv,patternHead,thePattern,multifieldHeader,tempList->type,                                  (SYMBOL_HN *) tempList->value,tempList,FALSE))        {         ReturnLHSParseNodes(theEnv,theList);         return(TRUE);        }     }   ReturnLHSParseNodes(theEnv,theList);   /*===========================================================*/   /* Check for "variable referenced, but not previously bound" */   /* errors. Return TRUE if this type of error is detected.    */   /*===========================================================*/   if (UnboundVariablesInPattern(theEnv,thePattern,(int) patternHead->whichCE))     { return(TRUE); }   /*==================================================*/   /* Check for constraint errors for this slot/field. */   /* If the slot/field has unmatchable constraints    */   /* then return TRUE to indicate a semantic error.   */   /*==================================================*/   if (ProcessConnectedConstraints(theEnv,thePattern,multifieldHeader,patternHead))     { return(TRUE); }   /*==============================================================*/   /* Convert the slot/field constraint to a series of expressions */   /* that will be used in the pattern and join networks.          */   /*==============================================================*/   FieldConversion(theEnv,thePattern,patternHead);   /*=========================================================*/   /* Return FALSE to indicate that no errors were generated. */   /*=========================================================*/   return(FALSE);  }/*************************************************************//* PropagateVariableToNodes: Propagates variable references  *//*  to all other variables within the semantic scope of the  *//*  bound variable. That is, a variable reference cannot be  *//*  beyond an enclosing not/and CE combination. The          *//*  restriction of propagating variables beyond an enclosing *//*  not CE is handled within the GetVariables function.      *//*************************************************************/static int PropagateVariableToNodes(  void *theEnv,  struct lhsParseNode *theNode,  int theType,  struct symbolHashNode *variableName,  struct lhsParseNode *theReference,  int startDepth,  int assignReference,  int ignoreVariableTypes)  {   struct constraintRecord *tempConstraints;   /*===========================================*/   /* Traverse the nodes using the bottom link. */   /*===========================================*/   while (theNode != NULL)     {      /*==================================================*/      /* If the field/slot contains a predicate or return */      /* value constraint, then propagate the variable to */      /* the expression associated with that constraint.  */      /*==================================================*/      if (theNode->expression != NULL)        {         PropagateVariableToNodes(theEnv,theNode->expression,theType,variableName,                                  theReference,startDepth,assignReference,TRUE);        }      /*======================================================*/      /* If the field/slot is a single or multifield variable */      /* with the same name as the propagated variable,       */      /* then propagate the variable location to this node.   */      /*======================================================*/      else if (((theNode->type == SF_VARIABLE) || (theNode->type == MF_VARIABLE)) &&               (theNode->value == (void *) variableName))        {         /*======================================================*/         /* Check for mixing of single and multifield variables. */         /*======================================================*/         if (ignoreVariableTypes == FALSE)           {            if (((theType == SF_VARIABLE) && (theNode->type == MF_VARIABLE)) ||                ((theType == MF_VARIABLE) && (theNode->type == SF_VARIABLE)))              { return(TRUE); }           }         /*======================================================*/         /* Intersect the propagated variable's constraints with */         /* the current constraints for this field/slot.         */         /*======================================================*/         if ((theReference->constraints != NULL) && (! theNode->negated))           {            tempConstraints = theNode->constraints;            theNode->constraints = IntersectConstraints(theEnv,theReference->constraints,                                                        tempConstraints);            if (theNode->derivedConstraints)              { RemoveConstraint(theEnv,tempConstraints); }            theNode->derivedConstraints = TRUE;           }         /*=====================================================*/         /* Don't propagate the variable if it originates from  */         /* a different type of pattern object and the variable */         /* reference has already been resolved.                */         /*=====================================================*/         if (assignReference)           {            if (theNode->referringNode == NULL)              { theNode->referringNode = theReference; }            else if (theReference->pattern == theNode->pattern)              { theNode->referringNode = theReference; }            else if (theReference->patternType == theNode->patternType)              { theNode->referringNode = theReference; }           }        }      /*========================================================*/      /* If the field/slot is the node representing the entire  */      /* pattern, then propagate the variable location to the   */      /* fact address associated with the pattern (if it is the */      /* same variable name).                                   */      /*========================================================*/      else if ((theNode->type == PATTERN_CE) &&               (theNode->value == (void *) variableName) &&               (assignReference == TRUE))        {         if (theType == MF_VARIABLE) return(TRUE);         theNode->referringNode = theReference;        }      /*=====================================================*/      /* Propagate the variable to other fields contained    */      /* within the same & field constraint or same pattern. */      /*=====================================================*/      if (theNode->right != NULL)        {         if (PropagateVariableToNodes(theEnv,theNode->right,theType,variableName,                                      theReference,startDepth,assignReference,ignoreVariableTypes))           { return(TRUE); }        }      /*============================================================*/      /* Propagate the variable to other patterns within the same   */      /* semantic scope (if dealing with the node for an entire     */      /* pattern) or to the next | field constraint within a field. */      /*============================================================*/      if ((theNode->type == PATTERN_CE) || (theNode->type == TEST_CE))        {         if (theNode->endNandDepth < startDepth) theNode = NULL;         else theNode = theNode->bottom;        }      else        { theNode = theNode->bottom; }     }   /*========================================================*/   /* Return FALSE to indicate that no errors were detected. */   /*========================================================*/   return(FALSE);  }/*************************************************************//* UnboundVariablesInPattern: Verifies that variables within *//*   a slot/field have been referenced properly (i.e. that   *//*   variables have been previously bound if they are not a  *//*   binding occurrence).                                    *//*************************************************************/static intBool UnboundVariablesInPattern(  void *theEnv,  struct lhsParseNode *theSlot,  int pattern)  {   struct lhsParseNode *andField;   struct lhsParseNode *rv;   int result;   struct lhsParseNode *orField;   struct symbolHashNode *slotName;   CONSTRAINT_RECORD *theConstraints;   int theField;   /*===================================================*/   /* If a multifield slot is being checked, then check */   /* each of the fields grouped with the multifield.   */   /*===================================================*/

⌨️ 快捷键说明

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