?? analysis.c
字號:
if (theSlot->multifieldSlot) { theSlot = theSlot->bottom; while (theSlot != NULL) { if (UnboundVariablesInPattern(theEnv,theSlot,pattern)) { return(TRUE); } theSlot = theSlot->right; } return(FALSE); } /*=======================*/ /* Check a single field. */ /*=======================*/ slotName = theSlot->slot; theField = theSlot->index; theConstraints = theSlot->constraints; /*===========================================*/ /* Loop through each of the '|' constraints. */ /*===========================================*/ for (orField = theSlot->bottom; orField != NULL; orField = orField->bottom) { /*===========================================*/ /* Loop through each of the fields connected */ /* by the '&' within the '|' constraint. */ /*===========================================*/ for (andField = orField; andField != NULL; andField = andField->right) { /*=======================================================*/ /* If this is not a binding occurence of a variable and */ /* there is no previous binding occurence of a variable, */ /* then generate an error message for a variable that is */ /* referred to but not bound. */ /*=======================================================*/ if (((andField->type == SF_VARIABLE) || (andField->type == MF_VARIABLE)) && (andField->referringNode == NULL)) { VariableReferenceErrorMessage(theEnv,(SYMBOL_HN *) andField->value,NULL,pattern, slotName,theField); return(TRUE); } /*==============================================*/ /* Check predicate and return value constraints */ /* to insure that all variables used within the */ /* constraint have been previously bound. */ /*==============================================*/ else if ((andField->type == PREDICATE_CONSTRAINT) || (andField->type == RETURN_VALUE_CONSTRAINT)) { rv = CheckExpression(theEnv,andField->expression,NULL,pattern,slotName,theField); if (rv != NULL) return(TRUE); } /*========================================================*/ /* If static constraint checking is being performed, then */ /* determine if constant values have violated the set of */ /* derived constraints for the slot/field (based on the */ /* deftemplate definition and propagated constraints). */ /*========================================================*/ else if (((andField->type == INTEGER) || (andField->type == FLOAT) || (andField->type == SYMBOL) || (andField->type == STRING) || (andField->type == INSTANCE_NAME)) && EnvGetStaticConstraintChecking(theEnv)) { result = ConstraintCheckValue(theEnv,andField->type,andField->value,theConstraints); if (result != NO_VIOLATION) { ConstraintViolationErrorMessage(theEnv,"A literal restriction value", NULL,FALSE,pattern, slotName,theField,result, theConstraints,TRUE); return(TRUE); } } } } /*===============================*/ /* Return FALSE to indicate that */ /* no errors were detected. */ /*===============================*/ return(FALSE); }/******************************************************************//* CheckExpression: Verifies that variables within an expression *//* have been referenced properly. All variables within an *//* expression must have been previously bound. *//******************************************************************/static struct lhsParseNode *CheckExpression( void *theEnv, struct lhsParseNode *exprPtr, struct lhsParseNode *lastOne, int whichCE, struct symbolHashNode *slotName, int theField) { struct lhsParseNode *rv; int i = 1; while (exprPtr != NULL) { /*===============================================================*/ /* Check that single field variables contained in the expression */ /* were previously defined in the LHS. Also check to see if the */ /* variable has unmatchable constraints. */ /*===============================================================*/ if (exprPtr->type == SF_VARIABLE) { if (exprPtr->referringNode == NULL) { VariableReferenceErrorMessage(theEnv,(SYMBOL_HN *) exprPtr->value,lastOne, whichCE,slotName,theField); return(exprPtr); } else if ((UnmatchableConstraint(exprPtr->constraints)) && EnvGetStaticConstraintChecking(theEnv)) { ConstraintReferenceErrorMessage(theEnv,(SYMBOL_HN *) exprPtr->value,lastOne,i, whichCE,slotName,theField); return(exprPtr); } } /*==================================================*/ /* Check that multifield variables contained in the */ /* expression were previously defined in the LHS. */ /*==================================================*/ else if ((exprPtr->type == MF_VARIABLE) && (exprPtr->referringNode == NULL)) { VariableReferenceErrorMessage(theEnv,(SYMBOL_HN *) exprPtr->value,lastOne, whichCE,slotName,theField); return(exprPtr); } /*=====================================================*/ /* Check that global variables are referenced properly */ /* (i.e. if you reference a global variable, it must */ /* already be defined by a defglobal construct). */ /*=====================================================*/#if DEFGLOBAL_CONSTRUCT else if (exprPtr->type == GBL_VARIABLE) { int count; if (FindImportedConstruct(theEnv,"defglobal",NULL,ValueToString(exprPtr->value), &count,TRUE,NULL) == NULL) { VariableReferenceErrorMessage(theEnv,(SYMBOL_HN *) exprPtr->value,lastOne, whichCE,slotName,theField); return(exprPtr); } }#endif /*============================================*/ /* Recursively check other function calls to */ /* insure variables are referenced correctly. */ /*============================================*/ else if (((exprPtr->type == FCALL)#if DEFGENERIC_CONSTRUCT || (exprPtr->type == GCALL)#endif#if DEFFUNCTION_CONSTRUCT || (exprPtr->type == PCALL)#endif ) && (exprPtr->bottom != NULL)) { if ((rv = CheckExpression(theEnv,exprPtr->bottom,exprPtr,whichCE,slotName,theField)) != NULL) { return(rv); } } /*=============================================*/ /* Move on to the next part of the expression. */ /*=============================================*/ i++; exprPtr = exprPtr->right; } /*================================================*/ /* Return NULL to indicate no error was detected. */ /*================================================*/ return(NULL); }/********************************************************//* VariableReferenceErrorMessage: Generic error message *//* for referencing a variable before it is defined. *//********************************************************/static void VariableReferenceErrorMessage( void *theEnv, struct symbolHashNode *theVariable, struct lhsParseNode *theExpression, int whichCE, struct symbolHashNode *slotName, int theField) { struct expr *temprv; /*=============================*/ /* Print the error message ID. */ /*=============================*/ PrintErrorID(theEnv,"ANALYSIS",4,TRUE); /*=================================*/ /* Print the name of the variable. */ /*=================================*/ EnvPrintRouter(theEnv,WERROR,"Variable ?"); EnvPrintRouter(theEnv,WERROR,ValueToString(theVariable)); EnvPrintRouter(theEnv,WERROR," "); /*=================================================*/ /* If the variable was found inside an expression, */ /* then print the expression. */ /*=================================================*/ if (theExpression != NULL) { temprv = LHSParseNodesToExpression(theEnv,theExpression); ReturnExpression(theEnv,temprv->nextArg); temprv->nextArg = NULL; EnvPrintRouter(theEnv,WERROR,"found in the expression "); PrintExpression(theEnv,WERROR,temprv); EnvPrintRouter(theEnv,WERROR,"\n"); ReturnExpression(theEnv,temprv); } /*====================================================*/ /* Print the CE in which the variable was referenced. */ /*====================================================*/ EnvPrintRouter(theEnv,WERROR,"was referenced in CE #"); PrintLongInteger(theEnv,WERROR,(long int) whichCE); /*=====================================*/ /* Identify the slot or field in which */ /* the variable was found. */ /*=====================================*/ if (slotName == NULL) { if (theField > 0) { EnvPrintRouter(theEnv,WERROR," field #"); PrintLongInteger(theEnv,WERROR,(long int) theField); } } else { EnvPrintRouter(theEnv,WERROR," slot "); EnvPrintRouter(theEnv,WERROR,ValueToString(slotName)); } EnvPrintRouter(theEnv,WERROR," before being defined.\n"); }/************************************************************//* VariableMixingErrorMessage: Prints the error message for *//* the illegal mixing of single and multifield variables *//* on the LHS of a rule. *//************************************************************/static void VariableMixingErrorMessage( void *theEnv, struct symbolHashNode *theVariable) { PrintErrorID(theEnv,"ANALYSIS",3,TRUE); EnvPrintRouter(theEnv,WERROR,"Variable ?"); EnvPrintRouter(theEnv,WERROR,ValueToString(theVariable)); EnvPrintRouter(theEnv,WERROR," is used as both a single and multifield variable in the LHS\n"); }/*************************************************************//* CombineNandExpressions: *//*************************************************************/static void CombineNandExpressions( void *theEnv, struct lhsParseNode *theLHS) { int scanDepth; struct lhsParseNode *thePattern, *lastPattern; struct expr *theNandExpression, *theRightExpression, *theLeftExpression; if (theLHS == NULL) return; lastPattern = theLHS; for (theLHS = theLHS->bottom; theLHS != NULL; theLHS = theLHS->bottom) { if ((theLHS->beginNandDepth == 1) || (theLHS->beginNandDepth == lastPattern->endNandDepth)) { continue; } scanDepth = theLHS->beginNandDepth; thePattern = theLHS; theNandExpression = NULL; theRightExpression = NULL; theLeftExpression = NULL; while (thePattern != NULL) { if (thePattern->beginNandDepth == scanDepth) { theNandExpression = CombineExpressions(theEnv,thePattern->externalNetworkTest,theNandExpression); theLeftExpression = AppendExpressions(thePattern->externalLeftHash,theLeftExpression); theRightExpression = AppendExpressions(thePattern->externalRightHash,theRightExpression); thePattern->externalNetworkTest = NULL; thePattern->externalLeftHash = NULL; thePattern->externalRightHash = NULL; } if (thePattern->endNandDepth < scanDepth) { theLHS->externalNetworkTest = theNandExpression; theLHS->externalLeftHash = theLeftExpression; theLHS->externalRightHash = theRightExpression; break; } thePattern = thePattern->bottom; } } } #endif /* (! RUN_TIME) && (! BLOAD_ONLY) && DEFRULE_CONSTRUCT */
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -