📄 rulelhs.c
字号:
SetEvaluationError(CLIPS_FALSE); if (EvaluateExpression(SalienceExpression,&salienceValue)) { SalienceInformationError(ruleName); *error = CLIPS_TRUE; return; } if (salienceValue.type != INTEGER) { SalienceNonIntegerError(); *error = CLIPS_TRUE; return; } /*=======================================================*/ /* Salience number must be in the range -10000 to 10000. */ /*=======================================================*/ salience = (int) ValueToLong(salienceValue.value); if ((salience > MAX_SALIENCE) || (salience < MIN_SALIENCE)) { SalienceRangeError(); *error = CLIPS_TRUE; return; } /*==========================================*/ /* If the expression is a constant integer, */ /* don't bother storing the expression. */ /*==========================================*/ if (SalienceExpression->type == INTEGER) { ReturnExpression(SalienceExpression); SalienceExpression = NULL; } GlobalSalience = salience; }/**************************************************************//* ParseAutoFocus: Parses the rest of a defrule auto-focus *//* declaration once the auto-focus keyword has been parsed. *//**************************************************************/static VOID ParseAutoFocus(readSource,error) char *readSource; int *error; { struct token theToken; /*========================================*/ /* The auto-focus value must be a symbol. */ /*========================================*/ SavePPBuffer(" "); GetToken(readSource,&theToken); if (theToken.type != SYMBOL) { SyntaxErrorMessage("auto-focus statement"); *error = CLIPS_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) { GlobalAutoFocus = CLIPS_TRUE; } else if (strcmp(ValueToString(theToken.value),"FALSE") == 0) { GlobalAutoFocus = CLIPS_FALSE; } else { SyntaxErrorMessage("auto-focus statement"); *error = CLIPS_TRUE; } } /*****************************************************************//* LHSPattern: Parses a single conditional element found on the *//* LHS of a rule. Conditonal element types include pattern CEs *//* (which may be assigned to a variable), test CEs, not CEs, *//* logical CEs, and CEs, and or CEs. *//* *//* <conditional-element> ::= <pattern-CE> | *//* <assigned-pattern-CE> | *//* <not-CE> | <and-CE> | <or-CE> | *//* <logical-CE> | <test-CE> | *//* <forall-CE> | <exists-CE> *//*****************************************************************/static struct lhsParseNode *LHSPattern(readSource,terminator,terminatorString,error, allowDeclaration,firstToken,ruleName) char *readSource; int terminator; char *terminatorString; int *error; int allowDeclaration; struct token *firstToken; char *ruleName; { struct token theToken; struct lhsParseNode *theNode; /*=========================================================*/ /* Check to see if the first token has already been read. */ /* This should only occur for the first pattern in a rule. */ /*=========================================================*/ if (firstToken == NULL) GetToken(readSource,&theToken); else CopyToken(&theToken,firstToken); /*=====================================================*/ /* A left parenthesis begins all CEs and declarations. */ /*=====================================================*/ if (theToken.type == LPAREN) { /*================================================*/ /* The first field of a pattern must be a symbol. */ /*================================================*/ GetToken(readSource,&theToken); if (theToken.type != SYMBOL) { SyntaxErrorMessage("the first field of a pattern"); *error = CLIPS_TRUE; return(NULL); } /*====================================*/ /* If this is the first CE of a rule, */ /* then a declare statement is valid. */ /*====================================*/ if (allowDeclaration && (strcmp(ValueToString(theToken.value),"declare") == 0)) { if (ruleName == NULL) CLIPSSystemError("RULELHS",1); DeclarationParse(readSource,ruleName,error); theNode = NULL; } /*==================================*/ /* Otherwise check for a *test* CE. */ /*==================================*/ else if (strcmp(ValueToString(theToken.value),"test") == 0) { theNode = TestPattern(readSource,error); } /*============================================*/ /* Otherwise check for an *and*, *or*, *not*, */ /* *logical*, *exists*, or *forall* CE. */ /*============================================*/ else if ((strcmp(ValueToString(theToken.value),"and") == 0) || (strcmp(ValueToString(theToken.value),"logical") == 0) || (strcmp(ValueToString(theToken.value),"not") == 0) || (strcmp(ValueToString(theToken.value),"exists") == 0) || (strcmp(ValueToString(theToken.value),"forall") == 0) || (strcmp(ValueToString(theToken.value),"or") == 0)) { theNode = ConnectedPatternParse(readSource,&theToken,error); } /*=================================*/ /* Otherwise parse a *pattern* CE. */ /*=================================*/ else { theNode = SimplePatternParse(readSource,&theToken,error); } } /*=======================================*/ /* Check for a pattern address variable. */ /*=======================================*/ else if (theToken.type == SF_VARIABLE) { theNode = AssignmentParse(readSource,theToken.value,error); } /*=================================================*/ /* Check for the group terminator (either a "=>" */ /* separating the LHS from the RHS or a ")" ending */ /* a CE containing other CEs such as an *and* CE). */ /*=================================================*/ else if ((theToken.type == terminator) ? (strcmp(theToken.printForm,terminatorString) == 0) : CLIPS_FALSE) { return(NULL); } /*====================================*/ /* Otherwise invalid syntax was used. */ /*====================================*/ else { SyntaxErrorMessage("defrule"); *error = CLIPS_TRUE; return(NULL); } /*================================*/ /* If an error occurred, free any */ /* allocated data structures. */ /*================================*/ if (*error == CLIPS_TRUE) { ReturnLHSParseNodes(theNode); return(NULL); } /*=========================*/ /* Return the LHS pattern. */ /*=========================*/ return(theNode); }/*********************************************************************//* ConnectedPatternParse: Handles parsing of the connected *//* conditional elements (i.e. those conditional elements that may *//* contain one or more other conditional elements). The connected *//* conditional elements include the *and*, *or*, *not*, *logical*, *//* *exists*, and *forall* CEs. This routine is entered with the *//* parsing pointing to the name of the connected CE. It is exited *//* with the parser pointing to the closing right parenthesis of *//* the connected CE. *//* *//* <and-CE> ::= (and <conditional-element>+) *//* *//* <or-CE> ::= (or <conditional-element>+) *//* *//* <logical-CE> ::= (logical <conditional-element>+) *//* *//* <not-CE> ::= (not <conditional-element>) *//* *//* <exists-CE> ::= (exists <conditional-element>+) *//* *//* <forall-CE> ::= (forall <conditional-element> *//* <conditional-element>+) *//*********************************************************************/static struct lhsParseNode *ConnectedPatternParse(readSource,theToken,error) char *readSource; struct token *theToken; int *error; { int connectorValue = 0; struct lhsParseNode *theNode, *tempNode, *theGroup; char *errorCE; int logical = CLIPS_FALSE; int tempValue; /*==========================================================*/ /* Use appropriate spacing for pretty printing of the rule. */ /*==========================================================*/ IncrementIndentDepth(5); if (strcmp(ValueToString(theToken->value),"or") == 0) { connectorValue = OR_CE; errorCE = "the or conditional element"; SavePPBuffer(" "); } else if (strcmp(ValueToString(theToken->value),"and") == 0) { connectorValue = AND_CE; errorCE = "the and conditional element"; SavePPBuffer(" "); } else if (strcmp(ValueToString(theToken->value),"not") == 0) { connectorValue = NOT_CE; errorCE = "the not conditional element"; SavePPBuffer(" "); } else if (strcmp(ValueToString(theToken->value),"exists") == 0) { connectorValue = EXISTS_CE; errorCE = "the exists conditional element"; PPCRAndIndent(); } else if (strcmp(ValueToString(theToken->value),"forall") == 0) { connectorValue = FORALL_CE; errorCE = "the forall conditional element"; PPCRAndIndent(); } else if (strcmp(ValueToString(theToken->value),"logical") == 0) { connectorValue = AND_CE; errorCE = "the logical conditional element"; logical = CLIPS_TRUE; PPCRAndIndent(); } /*=====================================================*/ /* The logical CE cannot be contained within a not CE. */ /*=====================================================*/ if (WithinNotCE && logical) { PrintErrorID("RULELHS",1,CLIPS_TRUE); PrintCLIPS(WERROR,"The logical CE cannot be used within a not/exists/forall CE.\n"); *error = CLIPS_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 = WithinNotCE; if ((connectorValue == NOT_CE) || (connectorValue == EXISTS_CE) || (connectorValue == FORALL_CE)) { WithinNotCE = CLIPS_TRUE; } /*===========================================*/ /* Parse all of the CEs contained with the */ /* CE. A ) will terminate the end of the CE. */ /*===========================================*/ theGroup = GroupPatterns(readSource,RPAREN,")",error); /*====================================*/ /* Restore the "with a *not* CE" flag */ /* and reset the indentation depth. */ /*====================================*/ WithinNotCE = tempValue; DecrementIndentDepth(5); /*============================================*/ /* If an error occured while parsing, return. */ /*============================================*/ if (*error == CLIPS_TRUE) { ReturnLHSParseNodes(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(errorCE); *error = CLIPS_TRUE; return(NULL); } /*============================================*/ /* A not CE may not contain more than one CE. */ /*============================================*/ if ((connectorValue == NOT_CE) && (theGroup->bottom != NULL)) { SyntaxErrorMessage(errorCE); ReturnLHSParseNodes(theGroup); *error = CLIPS_TRUE; return(NULL); } /*============================================*/ /* A forall CE must contain at least two CEs. */ /*============================================*/ if ((connectorValue == FORALL_CE) && (theGroup->bottom == NULL)) { SyntaxErrorMessage(errorCE); ReturnLHSParseNodes(theGroup); *error = CLIPS_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();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -