globle void *FindHashedPatternNode( void *theEnv, EXEC_STATUS, void *parent, unsigned short keyType, void *keyValue) { unsigned long hashValue; struct patternNodeHashEntry *hptr; hashValue = GetAtomicHashValue(keyType,keyValue,1) + HashExternalAddress(parent,0); /* TBD mult * 30 */ hashValue = (hashValue % PatternData(theEnv,execStatus)->PatternHashTableSize); for (hptr = PatternData(theEnv,execStatus)->PatternHashTable[hashValue]; hptr != NULL; hptr = hptr->next) { if ((hptr->parent == parent) && (keyType == hptr->type) && (keyValue == hptr->value)) { return(hptr->child); } } return(NULL); }
globle void AddHashedPatternNode( void *theEnv, EXEC_STATUS, void *parent, void *child, unsigned short keyType, void *keyValue) { unsigned long hashValue; struct patternNodeHashEntry *newhash, *temp; hashValue = GetAtomicHashValue(keyType,keyValue,1) + HashExternalAddress(parent,0); /* TBD mult * 30 */ newhash = get_struct(theEnv,execStatus,patternNodeHashEntry); newhash->parent = parent; newhash->child = child; newhash->type = keyType; newhash->value = keyValue; hashValue = (hashValue % PatternData(theEnv,execStatus)->PatternHashTableSize); temp = PatternData(theEnv,execStatus)->PatternHashTable[hashValue]; PatternData(theEnv,execStatus)->PatternHashTable[hashValue] = newhash; newhash->next = temp; }
globle void InitializePatterns( void *theEnv) { AllocateEnvironmentData(theEnv,PATTERN_DATA,sizeof(struct patternData),DeallocatePatternData); PatternData(theEnv)->NextPosition = 1; PatternData(theEnv)->PatternHashTable = CreatePatternHashTable(theEnv,SIZE_PATTERN_HASH); PatternData(theEnv)->PatternHashTableSize = SIZE_PATTERN_HASH; }
globle intBool AddPatternParser( void *theEnv, EXEC_STATUS, struct patternParser *newPtr) { struct patternParser *currentPtr, *lastPtr = NULL; /*============================================*/ /* Check to see that the limit for the number */ /* of pattern parsers has not been exceeded. */ /*============================================*/ if (PatternData(theEnv,execStatus)->NextPosition >= MAX_POSITIONS) return(FALSE); /*================================*/ /* Create the new pattern parser. */ /*================================*/ newPtr->positionInArray = PatternData(theEnv,execStatus)->NextPosition; PatternData(theEnv,execStatus)->PatternParserArray[PatternData(theEnv,execStatus)->NextPosition-1] = newPtr; PatternData(theEnv,execStatus)->NextPosition++; /*================================*/ /* Add the parser to the list of */ /* parsers based on its priority. */ /*================================*/ if (PatternData(theEnv,execStatus)->ListOfPatternParsers == NULL) { newPtr->next = NULL; PatternData(theEnv,execStatus)->ListOfPatternParsers = newPtr; return(TRUE); } currentPtr = PatternData(theEnv,execStatus)->ListOfPatternParsers; while ((currentPtr != NULL) ? (newPtr->priority < currentPtr->priority) : FALSE) { lastPtr = currentPtr; currentPtr = currentPtr->next; } if (lastPtr == NULL) { newPtr->next = PatternData(theEnv,execStatus)->ListOfPatternParsers; PatternData(theEnv,execStatus)->ListOfPatternParsers = newPtr; } else { newPtr->next = currentPtr; lastPtr->next = newPtr; } return(TRUE); }
void DetachPattern( void *theEnv, int rhsType, struct patternNodeHeader *theHeader) { if (PatternData(theEnv)->PatternParserArray[rhsType] != NULL) { FlushAlphaBetaMemory(theEnv,theHeader->alphaMemory); (*PatternData(theEnv)->PatternParserArray[rhsType]->removePatternFunction)(theEnv,theHeader); } }
bool AddPatternParser( Environment *theEnv, struct patternParser *newPtr) { struct patternParser *currentPtr, *lastPtr = NULL; /*============================================*/ /* Check to see that the limit for the number */ /* of pattern parsers has not been exceeded. */ /*============================================*/ if (PatternData(theEnv)->NextPosition >= MAX_POSITIONS) return false; /*================================*/ /* Create the new pattern parser. */ /*================================*/ newPtr->positionInArray = PatternData(theEnv)->NextPosition; PatternData(theEnv)->PatternParserArray[PatternData(theEnv)->NextPosition-1] = newPtr; PatternData(theEnv)->NextPosition++; /*================================*/ /* Add the parser to the list of */ /* parsers based on its priority. */ /*================================*/ if (PatternData(theEnv)->ListOfPatternParsers == NULL) { newPtr->next = NULL; PatternData(theEnv)->ListOfPatternParsers = newPtr; return true; } currentPtr = PatternData(theEnv)->ListOfPatternParsers; while ((currentPtr != NULL) ? (newPtr->priority < currentPtr->priority) : false) { lastPtr = currentPtr; currentPtr = currentPtr->next; } if (lastPtr == NULL) { newPtr->next = PatternData(theEnv)->ListOfPatternParsers; PatternData(theEnv)->ListOfPatternParsers = newPtr; } else { newPtr->next = currentPtr; lastPtr->next = newPtr; } return true; }
void DetachPattern( Environment *theEnv, unsigned short rhsType, struct patternNodeHeader *theHeader) { if (rhsType == 0) return; if (PatternData(theEnv)->PatternParserArray[rhsType-1] != NULL) { FlushAlphaMemory(theEnv,theHeader); (*PatternData(theEnv)->PatternParserArray[rhsType-1]->removePatternFunction)(theEnv,theHeader); } }
void AddReservedPatternSymbol( void *theEnv, char *theSymbol, char *reservedBy) { struct reservedSymbol *newSymbol; newSymbol = get_struct(theEnv,reservedSymbol); newSymbol->theSymbol = theSymbol; newSymbol->reservedBy = reservedBy; newSymbol->next = PatternData(theEnv)->ListOfReservedPatternSymbols; PatternData(theEnv)->ListOfReservedPatternSymbols = newSymbol; }
void DetachPattern( void *theEnv, EXEC_STATUS, int rhsType, struct patternNodeHeader *theHeader) { if (rhsType == 0) return; if (PatternData(theEnv,execStatus)->PatternParserArray[rhsType-1] != NULL) { FlushAlphaMemory(theEnv,execStatus,theHeader); (*PatternData(theEnv,execStatus)->PatternParserArray[rhsType-1]->removePatternFunction)(theEnv,execStatus,theHeader); } }
globle struct lhsParseNode *ParseRuleLHS( void *theEnv, EXEC_STATUS, char *readSource, struct token *theToken, char *ruleName, int *error) { struct lhsParseNode *theLHS; int result; *error = FALSE; /*========================================*/ /* Initialize salience parsing variables. */ /*========================================*/ PatternData(theEnv,execStatus)->GlobalSalience = 0; PatternData(theEnv,execStatus)->GlobalAutoFocus = FALSE; PatternData(theEnv,execStatus)->SalienceExpression = NULL; /*============================*/ /* Set the indentation depth. */ /*============================*/ SetIndentDepth(theEnv,execStatus,3); /*=====================================================*/ /* Get the raw representation for the LHS of the rule. */ /*=====================================================*/ theLHS = RuleBodyParse(theEnv,execStatus,readSource,theToken,ruleName,error); if (*error) return(NULL); /*====================================================*/ /* Reorder the raw representation so that it consists */ /* of at most a single top level OR CE containing one */ /* or more AND CEs. */ /*====================================================*/ theLHS = ReorderPatterns(theEnv,execStatus,theLHS,&result); /*================================*/ /* Return the LHS representation. */ /*================================*/ return(theLHS); }
intBool ReservedPatternSymbol( void *theEnv, EXEC_STATUS, char *theSymbol, char *checkedBy) { struct reservedSymbol *currentSymbol; for (currentSymbol = PatternData(theEnv,execStatus)->ListOfReservedPatternSymbols; currentSymbol != NULL; currentSymbol = currentSymbol->next) { if (strcmp(theSymbol,currentSymbol->theSymbol) == 0) { if ((currentSymbol->reservedBy == NULL) || (checkedBy == NULL)) { return(TRUE); } if (strcmp(checkedBy,currentSymbol->reservedBy) == 0) return(FALSE); return(TRUE); } } return(FALSE); }
struct patternParser *GetPatternParser( Environment *theEnv, unsigned short rhsType) { if (rhsType == 0) return NULL; return(PatternData(theEnv)->PatternParserArray[rhsType-1]); }
struct patternParser *GetPatternParser( void *theEnv, int rhsType) { if (rhsType == 0) return(NULL); return(PatternData(theEnv)->PatternParserArray[rhsType-1]); }
struct patternParser *GetPatternParser( void *theEnv, EXEC_STATUS, int rhsType) { if (rhsType == 0) return(NULL); return(PatternData(theEnv,execStatus)->PatternParserArray[rhsType-1]); }
static void DeallocatePatternData( void *theEnv) { struct reservedSymbol *tmpRSPtr, *nextRSPtr; struct patternParser *tmpPPPtr, *nextPPPtr; tmpRSPtr = PatternData(theEnv)->ListOfReservedPatternSymbols; while (tmpRSPtr != NULL) { nextRSPtr = tmpRSPtr->next; rtn_struct(theEnv,reservedSymbol,tmpRSPtr); tmpRSPtr = nextRSPtr; } tmpPPPtr = PatternData(theEnv)->ListOfPatternParsers; while (tmpPPPtr != NULL) { nextPPPtr = tmpPPPtr->next; rtn_struct(theEnv,patternParser,tmpPPPtr); tmpPPPtr = nextPPPtr; } }
struct patternParser *FindPatternParser( Environment *theEnv, const char *name) { struct patternParser *tempParser; for (tempParser = PatternData(theEnv)->ListOfPatternParsers; tempParser != NULL; tempParser = tempParser->next) { if (strcmp(tempParser->name,name) == 0) return(tempParser); } return NULL; }
globle struct patternParser *FindPatternParser( void *theEnv, char *name) { struct patternParser *tempParser; for (tempParser = PatternData(theEnv)->ListOfPatternParsers; tempParser != NULL; tempParser = tempParser->next) { if (strcmp(tempParser->name,name) == 0) return(tempParser); } return(NULL); }
globle intBool RemoveHashedPatternNode( void *theEnv, EXEC_STATUS, void *parent, void *child, unsigned short keyType, void *keyValue) { unsigned long hashValue; struct patternNodeHashEntry *hptr, *prev; hashValue = GetAtomicHashValue(keyType,keyValue,1) + HashExternalAddress(parent,0); /* TBD mult * 30 */ hashValue = (hashValue % PatternData(theEnv,execStatus)->PatternHashTableSize); for (hptr = PatternData(theEnv,execStatus)->PatternHashTable[hashValue], prev = NULL; hptr != NULL; hptr = hptr->next) { if (hptr->child == child) { if (prev == NULL) { PatternData(theEnv,execStatus)->PatternHashTable[hashValue] = hptr->next; rtn_struct(theEnv,execStatus,patternNodeHashEntry,hptr); return(1); } else { prev->next = hptr->next; rtn_struct(theEnv,execStatus,patternNodeHashEntry,hptr); return(1); } } prev = hptr; } return(0); }
static void ParseAutoFocus( void *theEnv, EXEC_STATUS, char *readSource, int *error) { struct token theToken; /*========================================*/ /* The auto-focus value must be a symbol. */ /*========================================*/ SavePPBuffer(theEnv,execStatus," "); GetToken(theEnv,execStatus,readSource,&theToken); if (theToken.type != SYMBOL) { SyntaxErrorMessage(theEnv,execStatus,"auto-focus statement"); *error = TRUE; return; } /*====================================================*/ /* The auto-focus value must be either TRUE or FALSE. */ /* If a valid value is parsed, then set the value of */ /* the global variable GlobalAutoFocus. */ /*====================================================*/ if (strcmp(ValueToString(theToken.value),"TRUE") == 0) { PatternData(theEnv,execStatus)->GlobalAutoFocus = TRUE; } else if (strcmp(ValueToString(theToken.value),"FALSE") == 0) { PatternData(theEnv,execStatus)->GlobalAutoFocus = FALSE; } else { SyntaxErrorMessage(theEnv,execStatus,"auto-focus statement"); *error = TRUE; } }
bool RemoveHashedPatternNode( Environment *theEnv, void *parent, void *child, unsigned short keyType, void *keyValue) { size_t hashValue; struct patternNodeHashEntry *hptr, *prev; hashValue = GetAtomicHashValue(keyType,keyValue,1) + HashExternalAddress(parent,0); /* TBD mult * 30 */ hashValue = (hashValue % PatternData(theEnv)->PatternHashTableSize); for (hptr = PatternData(theEnv)->PatternHashTable[hashValue], prev = NULL; hptr != NULL; hptr = hptr->next) { if (hptr->child == child) { if (prev == NULL) { PatternData(theEnv)->PatternHashTable[hashValue] = hptr->next; rtn_struct(theEnv,patternNodeHashEntry,hptr); return true; } else { prev->next = hptr->next; rtn_struct(theEnv,patternNodeHashEntry,hptr); return true; } } prev = hptr; } return false; }
void *FindHashedPatternNode( Environment *theEnv, void *parent, unsigned short keyType, void *keyValue) { size_t hashValue; struct patternNodeHashEntry *hptr; hashValue = GetAtomicHashValue(keyType,keyValue,1) + HashExternalAddress(parent,0); /* TBD mult * 30 */ hashValue = (hashValue % PatternData(theEnv)->PatternHashTableSize); for (hptr = PatternData(theEnv)->PatternHashTable[hashValue]; hptr != NULL; hptr = hptr->next) { if ((hptr->parent == parent) && (keyType == hptr->type) && (keyValue == hptr->value)) { return(hptr->child); } } return NULL; }
bool ReservedPatternSymbol( Environment *theEnv, const char *theSymbol, const char *checkedBy) { struct reservedSymbol *currentSymbol; for (currentSymbol = PatternData(theEnv)->ListOfReservedPatternSymbols; currentSymbol != NULL; currentSymbol = currentSymbol->next) { if (strcmp(theSymbol,currentSymbol->theSymbol) == 0) { if ((currentSymbol->reservedBy == NULL) || (checkedBy == NULL)) { return true; } if (strcmp(checkedBy,currentSymbol->reservedBy) == 0) return false; return true; } } return false; }
static void DeallocatePatternData( void *theEnv, EXEC_STATUS) { struct reservedSymbol *tmpRSPtr, *nextRSPtr; struct patternParser *tmpPPPtr, *nextPPPtr; struct patternNodeHashEntry *tmpPNEPtr, *nextPNEPtr; unsigned long i; tmpRSPtr = PatternData(theEnv,execStatus)->ListOfReservedPatternSymbols; while (tmpRSPtr != NULL) { nextRSPtr = tmpRSPtr->next; rtn_struct(theEnv,execStatus,reservedSymbol,tmpRSPtr); tmpRSPtr = nextRSPtr; } tmpPPPtr = PatternData(theEnv,execStatus)->ListOfPatternParsers; while (tmpPPPtr != NULL) { nextPPPtr = tmpPPPtr->next; rtn_struct(theEnv,execStatus,patternParser,tmpPPPtr); tmpPPPtr = nextPPPtr; } for (i = 0; i < PatternData(theEnv,execStatus)->PatternHashTableSize; i++) { tmpPNEPtr = PatternData(theEnv,execStatus)->PatternHashTable[i]; while (tmpPNEPtr != NULL) { nextPNEPtr = tmpPNEPtr->next; rtn_struct(theEnv,execStatus,patternNodeHashEntry,tmpPNEPtr); tmpPNEPtr = nextPNEPtr; } } rm3(theEnv,execStatus,PatternData(theEnv,execStatus)->PatternHashTable, sizeof(struct patternNodeHashEntry *) * PatternData(theEnv,execStatus)->PatternHashTableSize); }
static struct lhsParseNode *SimplePatternParse( void *theEnv, char *readSource, struct token *theToken, int *error) { struct lhsParseNode *theNode; struct patternParser *tempParser; /*=================================================*/ /* The first field of a pattern must be a symbol. */ /* In addition, the symbols ":" and "=" can not */ /* be used because they have special significance. */ /*=================================================*/ if (theToken->type != SYMBOL) { SyntaxErrorMessage(theEnv,"the first field of a pattern"); *error = TRUE; return(NULL); } else if ((strcmp(ValueToString(theToken->value),"=") == 0) || (strcmp(ValueToString(theToken->value),":") == 0)) { SyntaxErrorMessage(theEnv,"the field field of a pattern"); *error = TRUE; return(NULL); } /*===============================================*/ /* Construct the topmost node of the pattern CE. */ /*===============================================*/ theNode = GetLHSParseNode(theEnv); theNode->type = PATTERN_CE; theNode->negated = FALSE; /*======================================================*/ /* Search for a pattern parser that claims the pattern. */ /*======================================================*/ for (tempParser = PatternData(theEnv)->ListOfPatternParsers; tempParser != NULL; tempParser = tempParser->next) { if ((*tempParser->recognizeFunction)((SYMBOL_HN *) theToken->value)) { theNode->patternType = tempParser; theNode->right = (*tempParser->parseFunction)(theEnv,readSource,theToken); if (theNode->right == NULL) { *error = TRUE; ReturnLHSParseNodes(theEnv,theNode); return(NULL); } PropagatePatternType(theNode,tempParser); return(theNode); } } /*=================================*/ /* If a pattern parser couldn't be */ /* found, then signal an error. */ /*=================================*/ *error = TRUE; SyntaxErrorMessage(theEnv,"the field field of a pattern"); ReturnLHSParseNodes(theEnv,theNode); return(NULL); }
globle void IncrementalReset( void *theEnv, struct defrule *tempRule) { #if (MAC_MCW || WIN_MCW) && (RUN_TIME || BLOAD_ONLY) #pragma unused(theEnv,tempRule) #endif #if (! RUN_TIME) && (! BLOAD_ONLY) struct defrule *tempPtr; struct patternParser *theParser; /*================================================*/ /* If incremental reset is disabled, then return. */ /*================================================*/ if (! EnvGetIncrementalReset(theEnv)) return; /*=====================================================*/ /* Mark the pattern and join network data structures */ /* associated with the rule being incrementally reset. */ /*=====================================================*/ MarkNetworkForIncrementalReset(theEnv,tempRule,TRUE); /*==========================*/ /* Begin incremental reset. */ /*==========================*/ EngineData(theEnv)->IncrementalResetInProgress = TRUE; /*============================================================*/ /* If the new rule shares patterns or joins with other rules, */ /* then it is necessary to update its join network based on */ /* existing partial matches it shares with other rules. */ /*============================================================*/ for (tempPtr = tempRule; tempPtr != NULL; tempPtr = tempPtr->disjunct) { CheckForPrimableJoins(theEnv,tempPtr,tempPtr->lastJoin); } /*===============================================*/ /* Filter existing data entities through the new */ /* portions of the pattern and join networks. */ /*===============================================*/ for (theParser = PatternData(theEnv)->ListOfPatternParsers; theParser != NULL; theParser = theParser->next) { if (theParser->incrementalResetFunction != NULL) { (*theParser->incrementalResetFunction)(theEnv); } } /*========================*/ /* End incremental reset. */ /*========================*/ EngineData(theEnv)->IncrementalResetInProgress = FALSE; /*====================================================*/ /* Remove the marks in the pattern and join networks. */ /*====================================================*/ MarkNetworkForIncrementalReset(theEnv,tempRule,FALSE); #endif }
static void DeclarationParse( void *theEnv, char *readSource, char *ruleName, int *error) { struct token theToken; struct expr *packPtr; int notDone = TRUE; int salienceParsed = FALSE, autoFocusParsed = FALSE; /*===========================*/ /* Next token must be a '('. */ /*===========================*/ SavePPBuffer(theEnv," "); GetToken(theEnv,readSource,&theToken); if (theToken.type != LPAREN) { SyntaxErrorMessage(theEnv,"declare statement"); *error = TRUE; return; } /*==========================================*/ /* Continue parsing until there are no more */ /* valid rule property declarations. */ /*==========================================*/ while (notDone) { /*=============================================*/ /* The name of a rule property must be symbol. */ /*=============================================*/ GetToken(theEnv,readSource,&theToken); if (theToken.type != SYMBOL) { SyntaxErrorMessage(theEnv,"declare statement"); *error = TRUE; } /*==============================================*/ /* Parse a salience declaration if encountered. */ /*==============================================*/ else if (strcmp(ValueToString(theToken.value),"salience") == 0) { if (salienceParsed) { AlreadyParsedErrorMessage(theEnv,"salience declaration",NULL); *error = TRUE; } else { ParseSalience(theEnv,readSource,ruleName,error); salienceParsed = TRUE; } } /*=================================================*/ /* Parse an auto-focus declaration if encountered. */ /* A global flag is used to indicate if the */ /* auto-focus feature for a rule was parsed. */ /*=================================================*/ else if (strcmp(ValueToString(theToken.value),"auto-focus") == 0) { if (autoFocusParsed) { AlreadyParsedErrorMessage(theEnv,"auto-focus declaration",NULL); *error = TRUE; } else { ParseAutoFocus(theEnv,readSource,error); autoFocusParsed = TRUE; } } /*==========================================*/ /* Otherwise the symbol does not correspond */ /* to a valid rule property. */ /*==========================================*/ else { SyntaxErrorMessage(theEnv,"declare statement"); *error = TRUE; } /*=====================================*/ /* Return if an error was encountered. */ /*=====================================*/ if (*error) { ReturnExpression(theEnv,PatternData(theEnv)->SalienceExpression); PatternData(theEnv)->SalienceExpression = NULL; return; } /*=======================================*/ /* Both the salience and auto-focus rule */ /* properties are closed with a ')'. */ /*=======================================*/ GetToken(theEnv,readSource,&theToken); if (theToken.type != RPAREN) { PPBackup(theEnv); SavePPBuffer(theEnv," "); SavePPBuffer(theEnv,theToken.printForm); ReturnExpression(theEnv,PatternData(theEnv)->SalienceExpression); PatternData(theEnv)->SalienceExpression = NULL; SyntaxErrorMessage(theEnv,"declare statement"); *error = TRUE; return; } /*=============================================*/ /* The declare statement is closed with a ')'. */ /*=============================================*/ GetToken(theEnv,readSource,&theToken); if (theToken.type == RPAREN) notDone = FALSE; else if (theToken.type != LPAREN) { ReturnExpression(theEnv,PatternData(theEnv)->SalienceExpression); PatternData(theEnv)->SalienceExpression = NULL; SyntaxErrorMessage(theEnv,"declare statement"); *error = TRUE; return; } else { PPBackup(theEnv); SavePPBuffer(theEnv," ("); } } /*==========================================*/ /* Return the value of the salience through */ /* the global variable SalienceExpression. */ /*==========================================*/ packPtr = PackExpression(theEnv,PatternData(theEnv)->SalienceExpression); ReturnExpression(theEnv,PatternData(theEnv)->SalienceExpression); PatternData(theEnv)->SalienceExpression = packPtr; return; }
static void ParseSalience( void *theEnv, char *readSource, char *ruleName, int *error) { int salience; DATA_OBJECT salienceValue; /*==============================*/ /* Get the salience expression. */ /*==============================*/ SavePPBuffer(theEnv," "); PatternData(theEnv)->SalienceExpression = ParseAtomOrExpression(theEnv,readSource,NULL); if (PatternData(theEnv)->SalienceExpression == NULL) { *error = TRUE; return; } /*============================================================*/ /* Evaluate the expression and determine if it is an integer. */ /*============================================================*/ SetEvaluationError(theEnv,FALSE); if (EvaluateExpression(theEnv,PatternData(theEnv)->SalienceExpression,&salienceValue)) { SalienceInformationError(theEnv,"defrule",ruleName); *error = TRUE; return; } if (salienceValue.type != INTEGER) { SalienceNonIntegerError(theEnv); *error = TRUE; return; } /*=======================================================*/ /* Salience number must be in the range -10000 to 10000. */ /*=======================================================*/ salience = (int) ValueToLong(salienceValue.value); if ((salience > MAX_DEFRULE_SALIENCE) || (salience < MIN_DEFRULE_SALIENCE)) { SalienceRangeError(theEnv,MIN_DEFRULE_SALIENCE,MAX_DEFRULE_SALIENCE); *error = TRUE; return; } /*==========================================*/ /* If the expression is a constant integer, */ /* don't bother storing the expression. */ /*==========================================*/ if (PatternData(theEnv)->SalienceExpression->type == INTEGER) { ReturnExpression(theEnv,PatternData(theEnv)->SalienceExpression); PatternData(theEnv)->SalienceExpression = NULL; } PatternData(theEnv)->GlobalSalience = salience; }
globle void GetNextPatternEntity( void *theEnv, struct patternParser **theParser, struct patternEntity **theEntity) { /*=============================================================*/ /* If the current parser is NULL, then we want to retrieve the */ /* very first data entity. The traversal of entities is done */ /* by entity type (e.g. all facts are traversed followed by */ /* all instances). To get the first entity type to traverse, */ /* the current parser is set to the first parser on the list */ /* of pattern parsers. */ /*=============================================================*/ if (*theParser == NULL) { *theParser = PatternData(theEnv)->ListOfPatternParsers; *theEntity = NULL; } /*================================================================*/ /* Otherwise try to retrieve the next entity following the entity */ /* returned by the last call to GetNextEntity. If that entity was */ /* the last of its data type, then move on to the next pattern */ /* parser, otherwise return that entity as the next one. */ /*================================================================*/ else if (theEntity != NULL) { *theEntity = (struct patternEntity *) (*(*theParser)->entityType->base.getNextFunction)(theEnv,*theEntity); if ((*theEntity) != NULL) return; *theParser = (*theParser)->next; } /*===============================================================*/ /* Otherwise, we encountered a situation which should not occur. */ /* Once a NULL entity is returned from GetNextEntity, it should */ /* not be passed back to GetNextEntity. */ /*===============================================================*/ else { SystemError(theEnv,"PATTERN",1); EnvExitRouter(theEnv,EXIT_FAILURE); } /*================================================*/ /* Keep looping through the lists of entities and */ /* pattern parsers until an entity is found. */ /*================================================*/ while ((*theEntity == NULL) && (*theParser != NULL)) { *theEntity = (struct patternEntity *) (*(*theParser)->entityType->base.getNextFunction)(theEnv,*theEntity); if (*theEntity != NULL) return; *theParser = (*theParser)->next; } return; }
static struct lhsParseNode *ConnectedPatternParse( void *theEnv, char *readSource, struct token *theToken, int *error) { unsigned short connectorValue = 0; struct lhsParseNode *theNode, *tempNode, *theGroup; char *errorCE = NULL; int logical = FALSE; int tempValue; /*==========================================================*/ /* Use appropriate spacing for pretty printing of the rule. */ /*==========================================================*/ IncrementIndentDepth(theEnv,5); if (strcmp(ValueToString(theToken->value),"or") == 0) { connectorValue = OR_CE; errorCE = "the or conditional element"; SavePPBuffer(theEnv," "); } else if (strcmp(ValueToString(theToken->value),"and") == 0) { connectorValue = AND_CE; errorCE = "the and conditional element"; SavePPBuffer(theEnv," "); } else if (strcmp(ValueToString(theToken->value),"not") == 0) { connectorValue = NOT_CE; errorCE = "the not conditional element"; SavePPBuffer(theEnv," "); } else if (strcmp(ValueToString(theToken->value),"exists") == 0) { connectorValue = EXISTS_CE; errorCE = "the exists conditional element"; PPCRAndIndent(theEnv); } else if (strcmp(ValueToString(theToken->value),"forall") == 0) { connectorValue = FORALL_CE; errorCE = "the forall conditional element"; PPCRAndIndent(theEnv); } else if (strcmp(ValueToString(theToken->value),"logical") == 0) { connectorValue = AND_CE; errorCE = "the logical conditional element"; logical = TRUE; PPCRAndIndent(theEnv); } /*=====================================================*/ /* The logical CE cannot be contained within a not CE. */ /*=====================================================*/ if (PatternData(theEnv)->WithinNotCE && logical) { PrintErrorID(theEnv,"RULELHS",1,TRUE); EnvPrintRouter(theEnv,WERROR,"The logical CE cannot be used within a not/exists/forall CE.\n"); *error = TRUE; return(NULL); } /*=====================================================*/ /* Remember if we're currently within a *not* CE and */ /* then check to see if we're entering a new *not* CE. */ /*=====================================================*/ tempValue = PatternData(theEnv)->WithinNotCE; if ((connectorValue == NOT_CE) || (connectorValue == EXISTS_CE) || (connectorValue == FORALL_CE)) { PatternData(theEnv)->WithinNotCE = TRUE; } /*===========================================*/ /* Parse all of the CEs contained with the */ /* CE. A ) will terminate the end of the CE. */ /*===========================================*/ theGroup = GroupPatterns(theEnv,readSource,RPAREN,")",error); /*====================================*/ /* Restore the "with a *not* CE" flag */ /* and reset the indentation depth. */ /*====================================*/ PatternData(theEnv)->WithinNotCE = tempValue; DecrementIndentDepth(theEnv,5); /*============================================*/ /* If an error occured while parsing, return. */ /*============================================*/ if (*error == TRUE) { ReturnLHSParseNodes(theEnv,theGroup); return(NULL); } /*=========================================================*/ /* If we parsed a *logical* CE, then mark the logical flag */ /* for all of the CEs contained within the logical CE. */ /*=========================================================*/ if (logical) TagLHSLogicalNodes(theGroup); /*=====================================================*/ /* All the connected CEs must contain at least one CE. */ /*=====================================================*/ if (theGroup == NULL) { SyntaxErrorMessage(theEnv,errorCE); *error = TRUE; return(NULL); } /*============================================*/ /* A not CE may not contain more than one CE. */ /*============================================*/ if ((connectorValue == NOT_CE) && (theGroup->bottom != NULL)) { SyntaxErrorMessage(theEnv,errorCE); ReturnLHSParseNodes(theEnv,theGroup); *error = TRUE; return(NULL); } /*============================================*/ /* A forall CE must contain at least two CEs. */ /*============================================*/ if ((connectorValue == FORALL_CE) && (theGroup->bottom == NULL)) { SyntaxErrorMessage(theEnv,errorCE); ReturnLHSParseNodes(theEnv,theGroup); *error = TRUE; return(NULL); } /*========================================================*/ /* Remove an "and" and "or" CE that only contains one CE. */ /*========================================================*/ if (((connectorValue == AND_CE) || (connectorValue == OR_CE)) && (theGroup->bottom == NULL)) { theGroup->logical = logical; return(theGroup); } /*===========================================================*/ /* Create the top most node which connects the CEs together. */ /*===========================================================*/ theNode = GetLHSParseNode(theEnv); theNode->logical = logical; /*======================================================*/ /* Attach and/or/not CEs directly to the top most node. */ /*======================================================*/ if ((connectorValue == AND_CE) || (connectorValue == OR_CE) || (connectorValue == NOT_CE)) { theNode->type = connectorValue; theNode->right = theGroup; } /*=================================================================*/ /* Wrap two not CEs around the patterns contained in an exists CE. */ /*=================================================================*/ else if (connectorValue == EXISTS_CE) { theNode->type = NOT_CE; theNode->right = GetLHSParseNode(theEnv); theNode->right->type = NOT_CE; theNode->right->logical = logical; if (theGroup->bottom != NULL) { theNode->right->right = GetLHSParseNode(theEnv); theNode->right->right->type = AND_CE; theNode->right->right->logical = logical; theNode->right->right->right = theGroup; } else { theNode->right->right = theGroup; } } /*==================================================*/ /* For a forall CE, wrap a not CE around all of the */ /* CEs and a not CE around the 2nd through nth CEs. */ /*==================================================*/ else if (connectorValue == FORALL_CE) { theNode->type = NOT_CE; tempNode = theGroup->bottom; theGroup->bottom = NULL; theNode->right = GetLHSParseNode(theEnv); theNode->right->type = AND_CE; theNode->right->logical = logical; theNode->right->right = theGroup; theGroup = tempNode; theNode->right->right->bottom = GetLHSParseNode(theEnv); theNode->right->right->bottom->type = NOT_CE; theNode->right->right->bottom->logical = logical; tempNode = theNode->right->right->bottom; if (theGroup->bottom == NULL) { tempNode->right = theGroup; } else { tempNode->right = GetLHSParseNode(theEnv); tempNode->right->type = AND_CE; tempNode->right->logical = logical; tempNode->right->right = theGroup; } } /*================*/ /* Return the CE. */ /*================*/ return(theNode); }
struct patternParser *GetPatternParser( void *theEnv, int rhsType) { return(PatternData(theEnv)->PatternParserArray[rhsType]); }