📄 rulelhs.c
字号:
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(); theNode->right->type = NOT_CE; theNode->right->logical = logical; if (theGroup->bottom != NULL) { theNode->right->right = GetLHSParseNode(); 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(); theNode->right->type = AND_CE; theNode->right->logical = logical; theNode->right->right = theGroup; theGroup = tempNode; theNode->right->right->bottom = GetLHSParseNode(); 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(); tempNode->right->type = AND_CE; tempNode->right->logical = logical; tempNode->right->right = theGroup; } } /*================*/ /* Return the CE. */ /*================*/ return(theNode); }/***********************************************//* GroupPatterns: Groups a series of connected *//* conditional elements together. *//***********************************************/static struct lhsParseNode *GroupPatterns(readSource,terminator,terminatorString, error) int terminator; char *readSource, *terminatorString; int *error; { struct lhsParseNode *lastNode, *newNode, *theNode; lastNode = theNode = NULL; while (CLIPS_TRUE) { /*==================*/ /* Get the next CE. */ /*==================*/ newNode = LHSPattern(readSource,terminator,terminatorString, error,CLIPS_FALSE,NULL,NULL); /*=======================================================*/ /* If an error occurred, release any LHS data structures */ /* previously allocated by this routine. */ /*=======================================================*/ if (*error) { ReturnLHSParseNodes(theNode); return(NULL); } /*===============================================*/ /* A NULL value for the CE just parsed indicates */ /* that the terminator for the group of patterns */ /* was encountered (either a "=>" or a ")". */ /*===============================================*/ if (newNode == NULL) { PPBackup(); PPBackup(); if (terminator == RPAREN) { SavePPBuffer(terminatorString); } else { PPCRAndIndent(); SavePPBuffer(terminatorString); } return(theNode); } /*============================*/ /* Add the new CE to the list */ /* of CEs being grouped. */ /*============================*/ if (lastNode == NULL) { theNode = newNode; } else { lastNode->bottom = newNode; } lastNode = newNode; /*======================================*/ /* Fix the pretty print representation. */ /*======================================*/ PPCRAndIndent(); } }/**************************************************************//* TestPattern: Handles parsing of test conditional elements. *//* *//* <test-CE> ::= (test <function-call>) *//**************************************************************/static struct lhsParseNode *TestPattern(readSource,error) char *readSource; int *error; { struct lhsParseNode *theNode; struct token theToken; struct expr *theExpression; /*================================================*/ /* Create the data specification for the test CE. */ /*================================================*/ SavePPBuffer(" "); theNode = GetLHSParseNode(); theNode->type = TEST_CE; theExpression = Function0Parse(readSource); theNode->expression = ExpressionToLHSParseNodes(theExpression); ReturnExpression(theExpression); if (theNode->expression == NULL) { *error = CLIPS_TRUE; ReturnLHSParseNodes(theNode); return(NULL); } /*=========================================================*/ /* Check for the closing right parenthesis of the test CE. */ /*=========================================================*/ GetToken(readSource,&theToken); if (theToken.type != RPAREN) { SyntaxErrorMessage("test conditional element"); *error = CLIPS_TRUE; ReturnLHSParseNodes(theNode); return(NULL); } /*=====================*/ /* Return the test CE. */ /*=====================*/ return(theNode); }/****************************************************************//* AssignmentParse: Finishes the parsing of pattern conditional *//* elements that have been bound to a variable. *//* *//* <assigned-pattern-CE> ::= ?<variable-symbol> <- <pattern-CE> *//****************************************************************/static struct lhsParseNode *AssignmentParse(readSource,factAddress,error) char *readSource; SYMBOL_HN *factAddress; int *error; { struct lhsParseNode *theNode; struct token theToken; /*=====================================================*/ /* Patterns cannot be bound if they are with a not CE. */ /*=====================================================*/ if (WithinNotCE) { PrintErrorID("RULELHS",2,CLIPS_TRUE); PrintCLIPS(WERROR,"A pattern CE cannot be bound to a pattern-address within a not CE\n"); *error = CLIPS_TRUE; return(NULL); } /*===============================================*/ /* Check for binder token, "<-", after variable. */ /*===============================================*/ SavePPBuffer(" "); GetToken(readSource,&theToken); if ((theToken.type == SYMBOL) ? (strcmp(ValueToString(theToken.value),"<-") != 0) : CLIPS_TRUE) { SyntaxErrorMessage("binding patterns"); *error = CLIPS_TRUE; return(NULL); } SavePPBuffer(" "); /*================================================*/ /* Check for opening left parenthesis of pattern. */ /*================================================*/ GetToken(readSource,&theToken); if (theToken.type != LPAREN) { SyntaxErrorMessage("binding patterns"); *error = CLIPS_TRUE; return(NULL); } /*======================================================*/ /* Parse the pattern and return the data specification. */ /*======================================================*/ GetToken(readSource,&theToken); theNode = SimplePatternParse(readSource,&theToken,error); if (*error == CLIPS_TRUE) { ReturnLHSParseNodes(theNode); return(NULL); } /*=============================================*/ /* Store the name of the variable to which the */ /* pattern is bound and return the pattern. */ /*=============================================*/ theNode->value = (VOID *) factAddress; return(theNode); } /************************************************************//* TagLHSLogicalNodes: Marks all *and*, *or*, and *not* CEs *//* contained within a logical CE as having the properties *//* associated with a logical CE. *//************************************************************/static VOID TagLHSLogicalNodes(nodePtr) struct lhsParseNode *nodePtr; { while (nodePtr != NULL) { nodePtr->logical = CLIPS_TRUE; if ((nodePtr->type == AND_CE) || (nodePtr->type == OR_CE) || (nodePtr->type == NOT_CE)) { TagLHSLogicalNodes(nodePtr->right); } nodePtr = nodePtr->bottom; } } /***********************************************************//* SimplePatternParse: Parses a simple pattern (an opening *//* parenthesis followed by one or more fields followed *//* by a closing parenthesis). *//* *//* <pattern-CE> ::= <ordered-pattern-CE> | *//* <template-pattern-CE> *//***********************************************************/static struct lhsParseNode *SimplePatternParse(readSource,theToken,error) 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("the first field of a pattern"); *error = CLIPS_TRUE; return(NULL); } else if ((strcmp(ValueToString(theToken->value),"=") == 0) || (strcmp(ValueToString(theToken->value),":") == 0)) { SyntaxErrorMessage("the field field of a pattern"); *error = CLIPS_TRUE; return(NULL); } /*===============================================*/ /* Construct the topmost node of the pattern CE. */ /*===============================================*/ theNode = GetLHSParseNode(); theNode->type = PATTERN_CE; theNode->negated = CLIPS_FALSE; /*======================================================*/ /* Search for a pattern parser that claims the pattern. */ /*======================================================*/ for (tempParser = ListOfPatternParsers; tempParser != NULL; tempParser = tempParser->next) { if ((*tempParser->recognizeFunction)(theToken->value)) { theNode->patternType = tempParser; theNode->right = (*tempParser->parseFunction)(readSource,theToken); if (theNode->right == NULL) { *error = CLIPS_TRUE; ReturnLHSParseNodes(theNode); return(NULL); } PropagatePatternType(theNode,tempParser); return(theNode); } } /*=================================*/ /* If a pattern parser couldn't be */ /* found, then signal an error. */ /*=================================*/ *error = CLIPS_TRUE; SyntaxErrorMessage("the field field of a pattern"); ReturnLHSParseNodes(theNode); return(NULL); } /**************************************************************//* PropagatePatternType: Sets the selfPattern field for all *//* lhsParseNodes in a linked list of those data structures. *//**************************************************************/globle VOID PropagatePatternType(theLHS,theParser) struct lhsParseNode *theLHS; struct patternParser *theParser; { while (theLHS != NULL) { theLHS->patternType = theParser; if (theLHS->right != NULL) PropagatePatternType(theLHS->right,theParser); if (theLHS->expression != NULL) PropagatePatternType(theLHS->expression,theParser); theLHS = theLHS->bottom; } } #endif /* (! RUN_TIME) && (! BLOAD_ONLY) && DEFRULE_CONSTRUCT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -