📄 rulepsr.c
字号:
SyntaxErrorMessage(theEnv,"defrule");
ReturnExpression(theEnv,actions);
return(NULL);
}
/*========================*/
/* Return the rule's RHS. */
/*========================*/
return(actions);
}
/************************************************************/
/* RuleComplexity: Returns the complexity of a rule for use */
/* by the LEX and MEA conflict resolution strategies. */
/************************************************************/
static int RuleComplexity(
void *theEnv,
struct lhsParseNode *theLHS)
{
struct lhsParseNode *thePattern, *tempPattern;
int complexity = 0;
while (theLHS != NULL)
{
complexity += 1; /* Add 1 for each pattern. */
complexity += ExpressionComplexity(theEnv,theLHS->networkTest);
thePattern = theLHS->right;
while (thePattern != NULL)
{
if (thePattern->multifieldSlot)
{
tempPattern = thePattern->bottom;
while (tempPattern != NULL)
{
complexity += ExpressionComplexity(theEnv,tempPattern->networkTest);
tempPattern = tempPattern->right;
}
}
else
{ complexity += ExpressionComplexity(theEnv,thePattern->networkTest); }
thePattern = thePattern->right;
}
theLHS = theLHS->bottom;
}
return(complexity);
}
/********************************************************************/
/* ExpressionComplexity: Determines the complexity of a expression. */
/********************************************************************/
static int ExpressionComplexity(
void *theEnv,
struct expr *exprPtr)
{
int complexity = 0;
while (exprPtr != NULL)
{
if (exprPtr->type == FCALL)
{
/*=========================================*/
/* Logical combinations do not add to the */
/* complexity, but their arguments do. */
/*=========================================*/
if ((exprPtr->value == ExpressionData(theEnv)->PTR_AND) ||
(exprPtr->value == ExpressionData(theEnv)->PTR_NOT) ||
(exprPtr->value == ExpressionData(theEnv)->PTR_OR))
{ complexity += ExpressionComplexity(theEnv,exprPtr->argList); }
/*=========================================*/
/* else other function calls increase the */
/* complexity, but their arguments do not. */
/*=========================================*/
else
{ complexity++; }
}
else if ((EvaluationData(theEnv)->PrimitivesArray[exprPtr->type] != NULL) ?
EvaluationData(theEnv)->PrimitivesArray[exprPtr->type]->addsToRuleComplexity : FALSE)
{ complexity++; }
exprPtr = exprPtr->nextArg;
}
return(complexity);
}
/********************************************/
/* LogicalAnalysis: Analyzes the use of the */
/* logical CE within the LHS of a rule. */
/********************************************/
static int LogicalAnalysis(
void *theEnv,
struct lhsParseNode *patternList)
{
int firstLogical, logicalsFound = FALSE, logicalJoin = 0;
int gap = FALSE;
firstLogical = patternList->logical;
/*===================================================*/
/* Loop through each pattern in the LHS of the rule. */
/*===================================================*/
for (;
patternList != NULL;
patternList = patternList->bottom)
{
/*=======================================*/
/* Skip anything that isn't a pattern CE */
/* or is embedded within a not/and CE. */
/*=======================================*/
if ((patternList->type != PATTERN_CE) || (patternList->endNandDepth != 1))
{ continue; }
/*=====================================================*/
/* If the pattern CE is not contained within a logical */
/* CE, then set the gap flag to TRUE indicating that */
/* any subsequent pattern CE found within a logical CE */
/* represents a gap between logical CEs which is an */
/* error. */
/*=====================================================*/
if (patternList->logical == FALSE)
{
gap = TRUE;
continue;
}
/*=================================================*/
/* If a logical CE is encountered and the first CE */
/* of the rule isn't a logical CE, then indicate */
/* that the first CE must be a logical CE. */
/*=================================================*/
if (! firstLogical)
{
PrintErrorID(theEnv,"RULEPSR",1,TRUE);
EnvPrintRouter(theEnv,WERROR,"Logical CEs must be placed first in a rule\n");
return(-1);
}
/*===================================================*/
/* If a break within the logical CEs was found and a */
/* new logical CE is encountered, then indicate that */
/* there can't be any gaps between logical CEs. */
/*===================================================*/
if (gap)
{
PrintErrorID(theEnv,"RULEPSR",2,TRUE);
EnvPrintRouter(theEnv,WERROR,"Gaps may not exist between logical CEs\n");
return(-1);
}
/*===========================================*/
/* Increment the count of logical CEs found. */
/*===========================================*/
logicalJoin++;
logicalsFound = TRUE;
}
/*============================================*/
/* If logical CEs were found, then return the */
/* join number where the logical information */
/* will be stored in the join network. */
/*============================================*/
if (logicalsFound) return(logicalJoin);
/*=============================*/
/* Return zero indicating that */
/* no logical CE was found. */
/*=============================*/
return(0);
}
/*****************************************************************/
/* FindVariable: Searches for the last occurence of a variable */
/* in the LHS of a rule that is visible from the RHS of a rule. */
/* The last occurence of the variable on the LHS side of the */
/* rule will have the strictest constraints (because it will */
/* have been intersected with all of the other constraints for */
/* the variable on the LHS of the rule). The strictest */
/* constraints are useful for performing type checking on the */
/* RHS of the rule. */
/*****************************************************************/
globle struct lhsParseNode *FindVariable(
SYMBOL_HN *name,
struct lhsParseNode *theLHS)
{
struct lhsParseNode *theFields, *tmpFields = NULL;
struct lhsParseNode *theReturnValue = NULL;
/*==============================================*/
/* Loop through each CE in the LHS of the rule. */
/*==============================================*/
for (;
theLHS != NULL;
theLHS = theLHS->bottom)
{
/*==========================================*/
/* Don't bother searching for the variable */
/* in anything other than a pattern CE that */
/* is not contained within a not CE. */
/*==========================================*/
if ((theLHS->type != PATTERN_CE) ||
(theLHS->negated == TRUE) ||
(theLHS->beginNandDepth > 1))
{ continue; }
/*=====================================*/
/* Check the pattern address variable. */
/*=====================================*/
if (theLHS->value == (void *) name)
{ theReturnValue = theLHS; }
/*============================================*/
/* Check for the variable inside the pattern. */
/*============================================*/
theFields = theLHS->right;
while (theFields != NULL)
{
/*=================================================*/
/* Go one level deeper to check a multifield slot. */
/*=================================================*/
if (theFields->multifieldSlot)
{
tmpFields = theFields;
theFields = theFields->bottom;
}
/*=================================*/
/* See if the field being examined */
/* is the variable being sought. */
/*=================================*/
if (theFields == NULL)
{ /* Do Nothing */ }
else if (((theFields->type == SF_VARIABLE) ||
(theFields->type == MF_VARIABLE)) &&
(theFields->value == (void *) name))
{ theReturnValue = theFields; }
/*============================*/
/* Move on to the next field. */
/*============================*/
if (theFields == NULL)
{
theFields = tmpFields;
tmpFields = NULL;
}
else if ((theFields->right == NULL) && (tmpFields != NULL))
{
theFields = tmpFields;
tmpFields = NULL;
}
theFields = theFields->right;
}
}
/*=========================================================*/
/* Return a pointer to the LHS location where the variable */
/* was found (or a NULL pointer if it wasn't). */
/*=========================================================*/
return(theReturnValue);
}
/**********************************************************/
/* AddToDefruleList: Adds a defrule to the list of rules. */
/**********************************************************/
static void AddToDefruleList(
struct defrule *rulePtr)
{
struct defrule *tempRule;
struct defruleModule *theModuleItem;
theModuleItem = (struct defruleModule *) rulePtr->header.whichModule;
if (theModuleItem->header.lastItem == NULL)
{ theModuleItem->header.firstItem = (struct constructHeader *) rulePtr; }
else
{
tempRule = (struct defrule *) theModuleItem->header.lastItem;
while (tempRule != NULL)
{
tempRule->header.next = (struct constructHeader *) rulePtr;
tempRule = tempRule->disjunct;
}
}
theModuleItem->header.lastItem = (struct constructHeader *) rulePtr;
}
#endif /* (! RUN_TIME) && (! BLOAD_ONLY) */
#endif /* DEFRULE_CONSTRUCT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -