?? rulepsr.c
字號:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.30 10/19/06 */ /* */ /* RULE PARSING MODULE */ /*******************************************************//*************************************************************//* Purpose: Parses a defrule construct. *//* *//* Principal Programmer(s): *//* Gary D. Riley *//* *//* Contributing Programmer(s): *//* *//* Revision History: *//* *//* 6.24: Removed DYNAMIC_SALIENCE, INCREMENTAL_RESET, *//* and LOGICAL_DEPENDENCIES compilation flags. *//* *//* 6.30: Added support for hashed alpha memories. *//* *//*************************************************************/#define _RULEPSR_SOURCE_#include "setup.h"#if DEFRULE_CONSTRUCT#include <stdio.h>#define _STDIO_INCLUDED_#include <string.h>#include "analysis.h"#include "constant.h"#include "constrct.h"#include "cstrcpsr.h"#include "cstrnchk.h"#include "cstrnops.h"#include "engine.h"#include "envrnmnt.h"#include "exprnpsr.h"#include "incrrset.h"#include "memalloc.h"#include "pattern.h"#include "prccode.h"#include "prcdrpsr.h"#include "router.h"#include "rulebld.h"#include "rulebsc.h"#include "rulecstr.h"#include "ruledef.h"#include "ruledlt.h"#include "rulelhs.h"#include "scanner.h"#include "symbol.h"#include "watch.h"#include "lgcldpnd.h"#if DEFTEMPLATE_CONSTRUCT#include "tmpltfun.h"#endif#if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE#include "bload.h"#endif#include "rulepsr.h"/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/#if (! RUN_TIME) && (! BLOAD_ONLY) static struct expr *ParseRuleRHS(void *,char *); static int ReplaceRHSVariable(void *,struct expr *,void *); static struct defrule *ProcessRuleLHS(void *,struct lhsParseNode *,struct expr *,SYMBOL_HN *,int *); static struct defrule *CreateNewDisjunct(void *,SYMBOL_HN *,int,struct expr *, int,unsigned,struct joinNode *); static int RuleComplexity(void *,struct lhsParseNode *); static int ExpressionComplexity(void *,struct expr *); static int LogicalAnalysis(void *,struct lhsParseNode *); static void AddToDefruleList(struct defrule *);#if DEVELOPER && DEBUGGING_FUNCTIONS static void DumpRuleAnalysis(void *,struct lhsParseNode *);#endif#endif/****************************************************//* ParseDefrule: Coordinates all actions necessary *//* for the parsing and creation of a defrule into *//* the current environment. *//****************************************************/globle int ParseDefrule( void *theEnv, char *readSource) {#if (MAC_MCW || IBM_MCW) && (RUN_TIME || BLOAD_ONLY)#pragma unused(theEnv,readSource)#endif#if (! RUN_TIME) && (! BLOAD_ONLY) SYMBOL_HN *ruleName; struct lhsParseNode *theLHS; struct expr *actions; struct token theToken; struct defrule *topDisjunct, *tempPtr; struct defruleModule *theModuleItem; int error; /*================================================*/ /* Flush the buffer which stores the pretty print */ /* representation for a rule. Add the already */ /* parsed keyword defrule to this buffer. */ /*================================================*/ SetPPBufferStatus(theEnv,ON); FlushPPBuffer(theEnv); SavePPBuffer(theEnv,"(defrule "); /*=========================================================*/ /* Rules cannot be loaded when a binary load is in effect. */ /*=========================================================*/#if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE if ((Bloaded(theEnv) == TRUE) && (! ConstructData(theEnv)->CheckSyntaxMode)) { CannotLoadWithBloadMessage(theEnv,"defrule"); return(TRUE); }#endif /*================================================*/ /* Parse the name and comment fields of the rule, */ /* deleting the rule if it already exists. */ /*================================================*/#if DEBUGGING_FUNCTIONS DefruleData(theEnv)->DeletedRuleDebugFlags = 0;#endif ruleName = GetConstructNameAndComment(theEnv,readSource,&theToken,"defrule", EnvFindDefrule,EnvUndefrule,"*",FALSE, TRUE,TRUE); if (ruleName == NULL) return(TRUE); /*============================*/ /* Parse the LHS of the rule. */ /*============================*/ theLHS = ParseRuleLHS(theEnv,readSource,&theToken,ValueToString(ruleName),&error); if (error) { ReturnPackedExpression(theEnv,PatternData(theEnv)->SalienceExpression); PatternData(theEnv)->SalienceExpression = NULL; return(TRUE); } /*============================*/ /* Parse the RHS of the rule. */ /*============================*/ ClearParsedBindNames(theEnv); ExpressionData(theEnv)->ReturnContext = TRUE; actions = ParseRuleRHS(theEnv,readSource); if (actions == NULL) { ReturnPackedExpression(theEnv,PatternData(theEnv)->SalienceExpression); PatternData(theEnv)->SalienceExpression = NULL; ReturnLHSParseNodes(theEnv,theLHS); return(TRUE); } /*=======================*/ /* Process the rule LHS. */ /*=======================*/ topDisjunct = ProcessRuleLHS(theEnv,theLHS,actions,ruleName,&error); ReturnExpression(theEnv,actions); ClearParsedBindNames(theEnv); ReturnLHSParseNodes(theEnv,theLHS); if (error) { ReturnPackedExpression(theEnv,PatternData(theEnv)->SalienceExpression); PatternData(theEnv)->SalienceExpression = NULL; return(TRUE); } /*==============================================*/ /* If we're only checking syntax, don't add the */ /* successfully parsed defrule to the KB. */ /*==============================================*/ if (ConstructData(theEnv)->CheckSyntaxMode) { ReturnPackedExpression(theEnv,PatternData(theEnv)->SalienceExpression); PatternData(theEnv)->SalienceExpression = NULL; return(FALSE); } PatternData(theEnv)->SalienceExpression = NULL; /*======================================*/ /* Save the nice printout of the rules. */ /*======================================*/ SavePPBuffer(theEnv,"\n"); if (EnvGetConserveMemory(theEnv) == TRUE) { topDisjunct->header.ppForm = NULL; } else { topDisjunct->header.ppForm = CopyPPBuffer(theEnv); } /*=======================================*/ /* Store a pointer to the rule's module. */ /*=======================================*/ theModuleItem = (struct defruleModule *) GetModuleItem(theEnv,NULL,FindModuleItem(theEnv,"defrule")->moduleIndex); for (tempPtr = topDisjunct; tempPtr != NULL; tempPtr = tempPtr->disjunct) { tempPtr->header.whichModule = (struct defmoduleItemHeader *) theModuleItem; } /*===============================================*/ /* Rule completely parsed. Add to list of rules. */ /*===============================================*/ AddToDefruleList(topDisjunct); /*========================================================================*/ /* If a rule is redefined, then we want to restore its breakpoint status. */ /*========================================================================*/#if DEBUGGING_FUNCTIONS if (BitwiseTest(DefruleData(theEnv)->DeletedRuleDebugFlags,0)) { EnvSetBreak(theEnv,topDisjunct); } if (BitwiseTest(DefruleData(theEnv)->DeletedRuleDebugFlags,1) || EnvGetWatchItem(theEnv,"activations")) { EnvSetDefruleWatchActivations(theEnv,ON,(void *) topDisjunct); } if (BitwiseTest(DefruleData(theEnv)->DeletedRuleDebugFlags,2) || EnvGetWatchItem(theEnv,"rules")) { EnvSetDefruleWatchFirings(theEnv,ON,(void *) topDisjunct); }#endif /*================================*/ /* Perform the incremental reset. */ /*================================*/ IncrementalReset(theEnv,topDisjunct); /*=============================================*/ /* Return FALSE to indicate no errors occured. */ /*=============================================*/#endif return(FALSE); }#if (! RUN_TIME) && (! BLOAD_ONLY)/**************************************************************//* ProcessRuleLHS: Processes each of the disjuncts of a rule. *//**************************************************************/static struct defrule *ProcessRuleLHS( void *theEnv, struct lhsParseNode *theLHS, struct expr *actions, SYMBOL_HN *ruleName, int *error) { struct lhsParseNode *tempNode = NULL; struct defrule *topDisjunct = NULL, *currentDisjunct, *lastDisjunct = NULL; struct expr *newActions, *packPtr; int logicalJoin; int localVarCnt; int complexity; struct joinNode *lastJoin; intBool emptyLHS; /*================================================*/ /* Initially set the parsing error flag to FALSE. */ /*================================================*/ *error = FALSE; /*===========================================================*/ /* The top level of the construct representing the LHS of a */ /* rule is assumed to be an OR. If the implied OR is at the */ /* top level of the pattern construct, then remove it. */ /*===========================================================*/ if (theLHS == NULL) { emptyLHS = TRUE; } else { emptyLHS = FALSE; if (theLHS->type == OR_CE) theLHS = theLHS->right; } /*=========================================*/ /* Loop through each disjunct of the rule. */ /*=========================================*/ localVarCnt = CountParsedBindNames(theEnv); while ((theLHS != NULL) || (emptyLHS == TRUE)) { /*===================================*/ /* Analyze the LHS of this disjunct. */ /*===================================*/ if (emptyLHS) { tempNode = NULL; } else { if (theLHS->type == AND_CE) tempNode = theLHS->right; else if (theLHS->type == PATTERN_CE) tempNode = theLHS; } if (VariableAnalysis(theEnv,tempNode)) { *error = TRUE; ReturnDefrule(theEnv,topDisjunct); return(NULL); } /*=========================================*/ /* Perform entity dependent post analysis. */ /*=========================================*/ if (PostPatternAnalysis(theEnv,tempNode)) { *error = TRUE; ReturnDefrule(theEnv,topDisjunct); return(NULL); } /*========================================================*/ /* Print out developer information if it's being watched. */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -