?? objrtbld.c
字號(hào):
(thePattern->right == NULL) && (tempPattern != NULL)) { endSlot = TRUE; } else { endSlot = FALSE; } /*========================================*/ /* Is there a node in the pattern network */ /* that can be reused (shared)? */ /*========================================*/ newNode = FindObjectPatternNode(currentLevel,thePattern,&nodeSlotGroup,endSlot,FALSE); /*================================================*/ /* If the pattern node cannot be shared, then add */ /* a new pattern node to the pattern network. */ /*================================================*/ if (newNode == NULL) { newNode = CreateNewObjectPatternNode(theEnv,thePattern,nodeSlotGroup,lastLevel,endSlot,FALSE); } if (thePattern->constantSelector != NULL) { currentLevel = newNode->nextLevel; lastLevel = newNode; newNode = FindObjectPatternNode(currentLevel,thePattern,&nodeSlotGroup,endSlot,TRUE); if (newNode == NULL) { newNode = CreateNewObjectPatternNode(theEnv,thePattern,nodeSlotGroup,lastLevel,endSlot,TRUE); } } /*=======================================================*/ /* Move on to the next field in the pattern to be added. */ /*=======================================================*/ if ((thePattern->right == NULL) && (tempPattern != NULL)) { thePattern = tempPattern; tempPattern = NULL; } lastLevel = newNode; currentLevel = newNode->nextLevel; thePattern = thePattern->right; } while ((thePattern != NULL) ? (thePattern->userData == NULL) : FALSE); /*==================================================*/ /* Return the leaf node of the newly added pattern. */ /*==================================================*/ newAlphaNode = lastLevel->alphaNode; while (newAlphaNode != NULL) { if ((newClassBitMap == newAlphaNode->classbmp) && (newSlotBitMap == newAlphaNode->slotbmp) && IdenticalExpression(newAlphaNode->header.rightHash,rightHash)) return((struct patternNodeHeader *) newAlphaNode); newAlphaNode = newAlphaNode->nxtInGroup; } newAlphaNode = get_struct(theEnv,objectAlphaNode); InitializePatternHeader(theEnv,&newAlphaNode->header); newAlphaNode->header.rightHash = AddHashedExpression(theEnv,rightHash); newAlphaNode->matchTimeTag = 0L; newAlphaNode->patternNode = lastLevel; newAlphaNode->classbmp = newClassBitMap; IncrementBitMapCount(newClassBitMap); MarkBitMapClassesBusy(theEnv,newClassBitMap,1); newAlphaNode->slotbmp = newSlotBitMap; if (newSlotBitMap != NULL) IncrementBitMapCount(newSlotBitMap); newAlphaNode->bsaveID = 0L; newAlphaNode->nxtInGroup = lastLevel->alphaNode; lastLevel->alphaNode = newAlphaNode; newAlphaNode->nxtTerminal = ObjectNetworkTerminalPointer(theEnv); SetObjectNetworkTerminalPointer(theEnv,newAlphaNode); return((struct patternNodeHeader *) newAlphaNode); }/************************************************************************ NAME : FindObjectPatternNode DESCRIPTION : Looks for a pattern node at a specified level in the pattern network that can be reused (shared) with a pattern field being added to the pattern network. INPUTS : 1) The current layer of nodes being examined in the object pattern network 2) The intermediate parse representation of the pattern being added 3) A buffer for holding the first node of a group of slots with the same name as the new node 4) An integer code indicating if this is the last fiedl in a slot pattern or not RETURNS : The old pattern network node matching the new node, or NULL if there is none (nodeSlotGroup will hold the place where to attach a new node) SIDE EFFECTS : nodeSlotGroup set NOTES : None ************************************************************************/static OBJECT_PATTERN_NODE *FindObjectPatternNode( OBJECT_PATTERN_NODE *listOfNodes, struct lhsParseNode *thePattern, OBJECT_PATTERN_NODE **nodeSlotGroup, unsigned endSlot, unsigned constantSelector) { struct expr *compareTest; *nodeSlotGroup = NULL; if (constantSelector) { compareTest = thePattern->constantValue; } else if (thePattern->constantSelector != NULL) { compareTest = thePattern->constantSelector; } else { compareTest = thePattern->networkTest; } /*==========================================================*/ /* Loop through the nodes at the given level in the pattern */ /* network looking for a node that can be reused (shared). */ /*==========================================================*/ while (listOfNodes != NULL) { /*=========================================================*/ /* A object pattern node can be shared if the slot name is */ /* the same, the test is on the same field in the pattern, */ /* and the network test expressions are the same. */ /*=========================================================*/ if (((thePattern->type == MF_WILDCARD) || (thePattern->type == MF_VARIABLE)) ? listOfNodes->multifieldNode : (listOfNodes->multifieldNode == 0)) { if ((thePattern->slotNumber == (int) listOfNodes->slotNameID) && (thePattern->index == (int) listOfNodes->whichField) && (thePattern->singleFieldsAfter == listOfNodes->leaveFields) && (endSlot == listOfNodes->endSlot) && IdenticalExpression(listOfNodes->networkTest,compareTest)) return(listOfNodes); } /*===============================================*/ /* Find the beginning of a group of nodes with */ /* the same slot name testing on the same field. */ /*===============================================*/ if ((*nodeSlotGroup == NULL) && (thePattern->index == (int) listOfNodes->whichField) && (thePattern->slotNumber == (int) listOfNodes->slotNameID)) *nodeSlotGroup = listOfNodes; listOfNodes = listOfNodes->rightNode; } /*==============================================*/ /* A shareable pattern node could not be found. */ /*==============================================*/ return(NULL); }/***************************************************************** NAME : CreateNewObjectPatternNode DESCRIPTION : Creates a new pattern node and initializes all of its values. INPUTS : 1) The intermediate parse representation of the new pattern node 2) A pointer to the network node after which to add the new node 3) A pointer to the parent node on the level above to link the new node 4) An integer code indicating if this is the last fiedl in a slot pattern or not RETURNS : A pointer to the new pattern node SIDE EFFECTS : Pattern node allocated, initialized and attached NOTES : None *****************************************************************/static OBJECT_PATTERN_NODE *CreateNewObjectPatternNode( void *theEnv, struct lhsParseNode *thePattern, OBJECT_PATTERN_NODE *nodeSlotGroup, OBJECT_PATTERN_NODE *upperLevel, unsigned endSlot, unsigned constantSelector) { OBJECT_PATTERN_NODE *newNode,*prvNode,*curNode; newNode = get_struct(theEnv,objectPatternNode); newNode->blocked = FALSE; newNode->multifieldNode = FALSE; newNode->alphaNode = NULL; newNode->matchTimeTag = 0L; newNode->nextLevel = NULL; newNode->rightNode = NULL; newNode->leftNode = NULL; newNode->bsaveID = 0L; if ((thePattern->constantSelector != NULL) && (! constantSelector)) { newNode->selector = TRUE; } else { newNode->selector = FALSE; } /*===========================================================*/ /* Install the expression associated with this pattern node. */ /*===========================================================*/ if (constantSelector) { newNode->networkTest = AddHashedExpression(theEnv,thePattern->constantValue); } else if (thePattern->constantSelector != NULL) { newNode->networkTest = AddHashedExpression(theEnv,thePattern->constantSelector); } else { newNode->networkTest = AddHashedExpression(theEnv,thePattern->networkTest); } newNode->whichField = thePattern->index; newNode->leaveFields = thePattern->singleFieldsAfter; /*=========================================*/ /* Install the slot name for the new node. */ /*=========================================*/ newNode->slotNameID = (unsigned) thePattern->slotNumber; if ((thePattern->type == MF_WILDCARD) || (thePattern->type == MF_VARIABLE)) newNode->multifieldNode = TRUE; newNode->endSlot = endSlot; /*===============================================*/ /* Set the upper level pointer for the new node. */ /*===============================================*/ newNode->lastLevel = upperLevel; if ((upperLevel != NULL) && (upperLevel->selector)) { AddHashedPatternNode(theEnv,upperLevel,newNode,newNode->networkTest->type,newNode->networkTest->value); } /*==============================================*/ /* If there are no nodes with this slot name on */ /* this level, simply prepend it to the front. */ /*==============================================*/ if (nodeSlotGroup == NULL) { if (upperLevel == NULL) { newNode->rightNode = ObjectNetworkPointer(theEnv); SetObjectNetworkPointer(theEnv,newNode); } else { newNode->rightNode = upperLevel->nextLevel; upperLevel->nextLevel = newNode; } if (newNode->rightNode != NULL) newNode->rightNode->leftNode = newNode; return(newNode); } /* =========================================================== Group this node with other nodes of the same name testing on the same field in the pattern on this level. This allows us to do some optimization with constant tests on a particular slots. If we put all constant tests for a particular slot/field group at the end of that group, then when one of those test succeeds during pattern-matching, we don't have to test any more of the nodes with that slot/field name to the right. =========================================================== */ prvNode = NULL; curNode = nodeSlotGroup; while ((curNode == NULL) ? FALSE : (curNode->slotNameID == nodeSlotGroup->slotNameID) && (curNode->whichField == nodeSlotGroup->whichField)) { if ((curNode->networkTest == NULL) ? FALSE : ((curNode->networkTest->type != OBJ_PN_CONSTANT) ? FALSE : ((struct ObjectCmpPNConstant *) ValueToBitMap(curNode->networkTest->value))->pass)) break; prvNode = curNode; curNode = curNode->rightNode; } if (curNode != NULL) { newNode->leftNode = curNode->leftNode; newNode->rightNode = curNode; if (curNode->leftNode != NULL) curNode->leftNode->rightNode = newNode; else if (curNode->lastLevel != NULL) curNode->lastLevel->nextLevel = newNode; else SetObjectNetworkPointer(theEnv,newNode); curNode->leftNode = newNode; } else { newNode->leftNode = prvNode; prvNode->rightNode = newNode; } return(newNode); }/******************************************************** NAME : DetachObjectPattern DESCRIPTION : Removes a pattern node and all of its parent nodes from the pattern network. Nodes are only removed if they are no longer shared (i.e. a pattern node that has more than one child node is shared). A pattern from a rule is typically removed by removing the bottom most pattern node used by the pattern and then removing any parent nodes which are not shared by other patterns. Example: Patterns (a b c d) and (a b e f) would be represented by the pattern net shown on the left. If (a b c d) was detached, the resultant pattern net would be the one shown on the right. The '=' represents an end-of-pattern node. a a | | b b | | c--e e | | | d f f | | | = = = INPUTS : The pattern to be removed RETURNS : Nothing useful SIDE EFFECTS : All non-shared nodes associated with the pattern are removed NOTES : None ********************************************************/static void DetachObjectPattern( void *theEnv, struct patternNodeHeader *thePattern) { OBJECT_ALPHA_NODE *alphaPtr,*prv,*terminalPtr; OBJECT_PATTERN_NODE *patternPtr,*upperLevel; /*====================================================*/ /* Get rid of any matches stored in the alpha memory. */ /*====================================================*/ alphaPtr = (OBJECT_ALPHA_NODE *) thePattern; ClearObjectPatternMatches(theEnv,alphaPtr); /*========================================================*/ /* Unmark the classes to which the pattern is applicable */ /* and unmark the class and slot id maps so that they can */ /* become ephemeral. */ /*========================================================*/
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -