?? rulelhs.c
字號:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.22 06/15/04 */ /* */ /* DEFRULE LHS PARSING MODULE */ /*******************************************************//*************************************************************//* Purpose: Coordinates parsing of the LHS conditional *//* elements of a rule. *//* *//* Principal Programmer(s): *//* Gary D. Riley *//* *//* Contributing Programmer(s): *//* *//* Revision History: *//* *//*************************************************************/#define _RULELHS_SOURCE_#include "setup.h"#if (! RUN_TIME) && (! BLOAD_ONLY) && DEFRULE_CONSTRUCT#include <stdio.h>#define _STDIO_INCLUDED_#include <string.h>#include "agenda.h"#include "argacces.h"#include "constant.h"#include "constrct.h"#include "constrnt.h"#include "cstrnchk.h"#include "envrnmnt.h"#include "exprnpsr.h"#include "memalloc.h"#include "pattern.h"#include "reorder.h"#include "router.h"#include "ruledef.h"#include "scanner.h"#include "symbol.h"#include "rulelhs.h"/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/ static struct lhsParseNode *RuleBodyParse(void *,char *,struct token *,char *,int *); static void DeclarationParse(void *,char *,char *,int *); static struct lhsParseNode *LHSPattern(void *,char *,int,char *,int *,int, struct token *,char *); static struct lhsParseNode *ConnectedPatternParse(void *,char *,struct token *,int *); static struct lhsParseNode *GroupPatterns(void *,char *,int,char *,int *); static struct lhsParseNode *TestPattern(void *,char *,int *); static struct lhsParseNode *AssignmentParse(void *,char *,SYMBOL_HN *,int *); static void TagLHSLogicalNodes(struct lhsParseNode *); static struct lhsParseNode *SimplePatternParse(void *,char *,struct token *,int *); static void ParseSalience(void *,char *,char *,int *); static void ParseAutoFocus(void *,char *,int *);/*******************************************************************//* ParseRuleLHS: Coordinates all the actions necessary for parsing *//* the LHS of a rule including the reordering of pattern *//* conditional elements to conform with the KB Rete topology. *//*******************************************************************/globle struct lhsParseNode *ParseRuleLHS( void *theEnv, char *readSource, struct token *theToken, char *ruleName, int *error) { struct lhsParseNode *theLHS; int result; *error = FALSE; /*========================================*/ /* Initialize salience parsing variables. */ /*========================================*/ PatternData(theEnv)->GlobalSalience = 0; PatternData(theEnv)->GlobalAutoFocus = FALSE; PatternData(theEnv)->SalienceExpression = NULL; /*============================*/ /* Set the indentation depth. */ /*============================*/ SetIndentDepth(theEnv,3); /*=====================================================*/ /* Get the raw representation for the LHS of the rule. */ /*=====================================================*/ theLHS = RuleBodyParse(theEnv,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,theLHS,&result); /*================================*/ /* Return the LHS representation. */ /*================================*/ return(theLHS); }/*********************************************************//* RuleBodyParse: Parses the LHS of a rule, but does not *//* reorder any of the LHS patterns to conform with the *//* KB Rete Topology. *//* *//* <rule-body> ::= [<declaration>] *//* <conditional-element>* *//* => *//*********************************************************/static struct lhsParseNode *RuleBodyParse( void *theEnv, char *readSource, struct token *theToken, char *ruleName, int *error) { struct lhsParseNode *theNode, *otherNodes; /*=============================*/ /* Set the error return value. */ /*=============================*/ *error = FALSE; /*==================================================*/ /* If we're already at the separator, "=>", between */ /* the LHS and RHS, then the LHS is empty. */ /*==================================================*/ if ((theToken->type == SYMBOL) ? (strcmp(ValueToString(theToken->value),"=>") == 0) : FALSE) { return(NULL); } /*===========================================*/ /* Parse the first pattern as a special case */ /* (the declare statement is allowed). */ /*===========================================*/ theNode = LHSPattern(theEnv,readSource,SYMBOL,"=>",error,TRUE,theToken,ruleName); if (*error == TRUE) { ReturnLHSParseNodes(theEnv,theNode); return(NULL); } PPCRAndIndent(theEnv); /*======================================*/ /* Parse the other patterns in the LHS. */ /*======================================*/ otherNodes = GroupPatterns(theEnv,readSource,SYMBOL,"=>",error); if (*error == TRUE) { ReturnLHSParseNodes(theEnv,theNode); return(NULL); } /*================================================*/ /* Construct the final LHS by combining the first */ /* pattern with the remaining patterns. */ /*================================================*/ if (theNode == NULL) { theNode = otherNodes; } else { theNode->bottom = otherNodes; } /*=======================*/ /* Return the final LHS. */ /*=======================*/ return(theNode); }/********************************************************//* DeclarationParse: Parses a defrule declaration. *//* *//* <declaration> ::= (declare <rule-property>+) *//* *//* <rule-property> ::= (salience <integer-expression>) *//* <rule-property> ::= (auto-focus TRUE | FALSE) *//********************************************************/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; }/************************************************************//* ParseSalience: Parses the rest of a defrule salience *//* declaration once the salience keyword has been parsed. *//************************************************************/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;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -