📄 reorder.c
字号:
{
topNode->right = (*theParser->initialPatternFunction)(theEnv);
PropagatePatternType(topNode,theParser);
return(topNode);
}
/*=============================================*/
/* If neither a pattern type was supplied nor */
/* the initial fact pattern was available, use */
/* any available initial pattern. */
/*=============================================*/
for (theParser = PatternData(theEnv)->ListOfPatternParsers;
theParser != NULL;
theParser = theParser->next)
{
if (theParser->initialPatternFunction != NULL)
{
topNode->right = (*theParser->initialPatternFunction)(theEnv);
PropagatePatternType(topNode,theParser);
return(topNode);
}
}
/*===========================================*/
/* There must be at least one pattern parser */
/* capable of creating an initial pattern. */
/*===========================================*/
SystemError(theEnv,"REORDER",2);
return(NULL);
}
/*****************************************************************/
/* AddRemainingInitialPatterns: Finishes adding initial patterns */
/* where needed on the LHS of a rule. Assumes that an initial */
/* pattern has been added to the beginning of the rule if one */
/* was needed. */
/*****************************************************************/
static void AddRemainingInitialPatterns(
void *theEnv,
struct lhsParseNode *theLHS,
struct patternParser *defaultType)
{
struct lhsParseNode *trackNode, *tempNode, *lastNode;
/*====================================================*/
/* Set the mark flag for each CE in the LHS to FALSE. */
/*====================================================*/
for (trackNode = theLHS; trackNode != NULL; trackNode = trackNode->bottom)
{ trackNode->marked = FALSE; }
/*==================================*/
/* Loop through each CE in the LHS. */
/*==================================*/
lastNode = NULL;
while (theLHS != NULL)
{
/*===================================*/
/* A "not" CE will not propagate its */
/* pattern type to following CEs. */
/*===================================*/
if ((theLHS->negated) && (theLHS->marked))
{ trackNode = NULL; }
/*==================================================*/
/* A "test" or "not" CE was found that has not been */
/* marked. Add an initial pattern before the CE. */
/*==================================================*/
else if (((theLHS->type == TEST_CE) || (theLHS->negated)) &&
(theLHS->marked == FALSE))
{
if (theLHS->negated) tempNode = CreateInitialPattern(theEnv,theLHS->patternType);
else tempNode = CreateInitialPattern(theEnv,defaultType);
tempNode->logical = theLHS->logical;
tempNode->beginNandDepth = theLHS->beginNandDepth;
tempNode->endNandDepth = theLHS->beginNandDepth;
if (lastNode == NULL)
{ SystemError(theEnv,"REORDER",3); }
lastNode->bottom = tempNode;
tempNode->bottom = theLHS;
theLHS = tempNode;
trackNode = theLHS->bottom;
}
/*===================================================*/
/* If a pattern CE is found, then propagate its type */
/* to following test CEs in the same lexical scope. */
/*===================================================*/
else
{ trackNode = theLHS->bottom; }
/*=======================================================*/
/* Mark the pattern type of a "test" or "not" CE as the */
/* same type as the last pattern CE found that is within */
/* the same lexical scope as the "test" or "not" CE. */
/*=======================================================*/
for (;
trackNode != NULL;
trackNode = trackNode->bottom)
{
/*=====================================*/
/* If the CE isn't in the same lexical */
/* scope, move on to the next CE. */
/*=====================================*/
if (trackNode->beginNandDepth != theLHS->beginNandDepth)
{ continue; }
/*=======================================================*/
/* Mark a negated CE that is in the same lexical scope. */
/* This signifies that there is a preceeding non-negated */
/* pattern and thus no need for an initial pattern to be */
/* placed before this CE. */
/*=======================================================*/
else if (trackNode->negated)
{ trackNode->marked = TRUE; }
/*====================================================*/
/* If another non-negated pattern in the same lexical */
/* scope if found, stop propagation of the current */
/* pattern type. */
/*====================================================*/
else if (trackNode->type == PATTERN_CE)
{ break; }
/*====================================================*/
/* A "test" CE in the same lexical scope is marked to */
/* indicate that it has a non-negated pattern that it */
/* can be attached to. */
/*====================================================*/
else if (trackNode->type == TEST_CE)
{
trackNode->marked = TRUE;
trackNode->patternType = theLHS->patternType;
}
}
/*====================================*/
/* Move on to the next CE in the LHS. */
/*====================================*/
lastNode = theLHS;
theLHS = theLHS->bottom;
}
}
/**********************************************/
/* PrintNodes: Debugging routine which prints */
/* the representation of a CE. */
/**********************************************/
static void PrintNodes(
void *theEnv,
char *fileid,
struct lhsParseNode *theNode)
{
if (theNode == NULL) return;
while (theNode != NULL)
{
switch (theNode->type)
{
case PATTERN_CE:
EnvPrintRouter(theEnv,fileid,"(");
if (theNode->negated) EnvPrintRouter(theEnv,fileid,"n");
if (theNode->logical) EnvPrintRouter(theEnv,fileid,"l");
PrintLongInteger(theEnv,fileid,(long) theNode->beginNandDepth);
EnvPrintRouter(theEnv,fileid,"-");
PrintLongInteger(theEnv,fileid,(long) theNode->endNandDepth);
EnvPrintRouter(theEnv,fileid," ");
EnvPrintRouter(theEnv,fileid,ValueToString(theNode->right->bottom->value));
EnvPrintRouter(theEnv,fileid,")");
break;
case TEST_CE:
EnvPrintRouter(theEnv,fileid,"(test ");
PrintLongInteger(theEnv,fileid,(long) theNode->beginNandDepth);
EnvPrintRouter(theEnv,fileid,"-");
PrintLongInteger(theEnv,fileid,(long) theNode->endNandDepth);
EnvPrintRouter(theEnv,fileid,")");
break;
case NOT_CE:
if (theNode->logical) EnvPrintRouter(theEnv,fileid,"(lnot ");
else EnvPrintRouter(theEnv,fileid,"(not ");;
PrintNodes(theEnv,fileid,theNode->right);
EnvPrintRouter(theEnv,fileid,")");
break;
case OR_CE:
if (theNode->logical) EnvPrintRouter(theEnv,fileid,"(lor ");
else EnvPrintRouter(theEnv,fileid,"(or ");
PrintNodes(theEnv,fileid,theNode->right);
EnvPrintRouter(theEnv,fileid,")");
break;
case AND_CE:
if (theNode->logical) EnvPrintRouter(theEnv,fileid,"(land ");
else EnvPrintRouter(theEnv,fileid,"(and ");
PrintNodes(theEnv,fileid,theNode->right);
EnvPrintRouter(theEnv,fileid,")");
break;
default:
EnvPrintRouter(theEnv,fileid,"(unknown)");
break;
}
theNode = theNode->bottom;
if (theNode != NULL) EnvPrintRouter(theEnv,fileid," ");
}
return;
}
/*************************************************************/
/* AssignPatternIndices: For each pattern CE in the LHS of a */
/* rule, determines the pattern index for the CE. A simple */
/* 1 to N numbering can't be used since a join from the */
/* right only counts as a single CE to other CEs outside */
/* the lexical scope of the join from the right. For */
/* example, the patterns in the following LHS */
/* */
/* (a) (not (b) (c) (d)) (e) */
/* */
/* would be assigned the following numbers: a-1, b-2, c-3, */
/* d-4, and e-3. */
/*************************************************************/
static struct lhsParseNode *AssignPatternIndices(
struct lhsParseNode *theLHS,
short startIndex)
{
int depth;
struct lhsParseNode *theField;
depth = theLHS->beginNandDepth;
/*====================================*/
/* Loop through the CEs at this level */
/* assigning each CE a pattern index. */
/*====================================*/
while (theLHS != NULL)
{
/*============================================================*/
/* If we're entering a group of CEs requiring a join from the */
/* right, compute the pattern indices for that group and then */
/* proceed with the next CE in this group. A join from the */
/* right only counts as one CE on this level regardless of */
/* the number of CEs it contains. If the end of this level is */
/* encountered while processing the join from right, then */
/* return to the previous level. */
/*============================================================*/
if (theLHS->beginNandDepth > depth)
{
theLHS = AssignPatternIndices(theLHS,startIndex);
if (theLHS->endNandDepth < depth) return(theLHS);
startIndex++;
}
/*=====================================================*/
/* A test CE is not assigned a pattern index, however, */
/* if it is the last CE at the end of this level, then */
/* return to the previous level. */
/*=====================================================*/
else if (theLHS->type == TEST_CE)
{ if (theLHS->endNandDepth < depth) return(theLHS); }
/*==========================================================*/
/* The fields of a pattern CE need to be assigned a pattern */
/* index, field index, and/or slot names. If this CE is the */
/* last CE at the end of this level, then return to the */
/* previous level. */
/*==========================================================*/
else if (theLHS->type == PATTERN_CE)
{
theLHS->pattern = startIndex;
for (theField = theLHS->right; theField != NULL; theField = theField->right)
{
theField->pattern = startIndex;
PropagateIndexSlotPatternValues(theField,theField->pattern,
theField->index,theField->slot,
theField->slotNumber);
}
if (theLHS->endNandDepth < depth) return(theLHS);
startIndex++;
}
/*=========================*/
/* Move on to the next CE. */
/*=========================*/
theLHS = theLHS->bottom;
}
/*========================================*/
/* There are no more CEs left to process. */
/* Return to the previous level. */
/*========================================*/
return(NULL);
}
/***********************************************************/
/* PropagateIndexSlotPatternValues: Assigns pattern, field */
/* and slot identifiers to a field in a pattern. */
/***********************************************************/
static void PropagateIndexSlotPatternValues(
struct lhsParseNode *theField,
short thePattern,
short theIndex,
struct symbolHashNode *theSlot,
short theSlotNumber)
{
struct lhsParseNode *tmpNode, *andField;
/*=============================================*/
/* A NULL field does not have to be processed. */
/*=============================================*/
if (theField == NULL) return;
/*=====================================================*/
/* Assign the appropriate identifiers for a multifield */
/* slot by calling this routine recursively. */
/*=====================================================*/
if (theField->multifieldSlot)
{
theField->pattern = thePattern;
if (theIndex > 0) theField->index = theIndex;
theField->slot = theSlot;
theField->slotNumber = theSlotNumber;
for (tmpNode = theField->bottom;
tmpNode != NULL;
tmpNode = tmpNode->right)
{
tmpNode->pattern = thePattern;
tmpNode->slot = theSlot;
PropagateIndexSlotPatternValues(tmpNode,thePattern,tmpNode->index,
theSlot,theSlotNumber);
}
return;
}
/*=======================================================*/
/* Loop through each of the or'ed constraints (connected */
/* by a |) in this field of the pattern. */
/*=======================================================*/
for (theField = theField->bottom;
theField != NULL;
theField = theField->bottom)
{
/*===========================================================*/
/* Loop through each of the and'ed constraints (connected by */
/* a &) in this field of the pattern. Assign the pattern, */
/* field, and slot identifiers. */
/*===========================================================*/
for (andField = theField; andField != NULL; andField = andField->right)
{
andField->pattern = thePattern;
if (theIndex > 0) andField->index = theIndex;
andField->slot = theSlot;
andField->slotNumber = theSlotNumber;
}
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -