📄 rulepsr.c
字号:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.05 04/09/97 */ /* */ /* RULE PARSING MODULE */ /*******************************************************//*************************************************************//* Purpose: Parses a defrule construct. *//* *//* Principal Programmer(s): *//* Gary D. Riley *//* *//* Contributing Programmer(s): *//* *//* Revision History: *//* *//*************************************************************/#define _RULEPSR_SOURCE_#include "setup.h"#if DEFRULE_CONSTRUCT#include <stdio.h>#define _CLIPS_STDIO_#include <string.h>#include "constant.h"#include "clipsmem.h"#include "symbol.h"#include "scanner.h"#include "router.h"#include "engine.h"#include "rulelhs.h"#include "ruledef.h"#include "rulebld.h" #include "pattern.h"#include "cstrnchk.h"#include "cstrnops.h"#include "exprnpsr.h"#include "analysis.h"#include "prcdrpsr.h"#include "constrct.h"#include "prccode.h"#include "incrrset.h"#include "rulecstr.h"#include "watch.h"#include "ruledlt.h"#include "cstrcpsr.h"#include "rulebsc.h"#if LOGICAL_DEPENDENCIES#include "lgcldpnd.h"#endif#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)#if ANSI_COMPILER static struct expr *ParseRuleRHS(char *); static int ReplaceRHSVariable(struct expr *,VOID *); static struct defrule *ProcessRuleLHS(struct lhsParseNode *,struct expr *,SYMBOL_HN *); static struct defrule *CreateNewDisjunct(SYMBOL_HN *,int,struct expr *, int,int,struct joinNode *); static int RuleComplexity(struct lhsParseNode *); static int ExpressionComplexity(struct expr *);#if LOGICAL_DEPENDENCIES static int LogicalAnalysis(struct lhsParseNode *);#endif static VOID AddToDefruleList(struct defrule *);#else static struct expr *ParseRuleRHS(); static int ReplaceRHSVariable(); static struct defrule *ProcessRuleLHS(); static struct defrule *CreateNewDisjunct(); static int RuleComplexity(); static int ExpressionComplexity();#if LOGICAL_DEPENDENCIES static int LogicalAnalysis();#endif static VOID AddToDefruleList();#endif#endif/****************************************************//* ParseDefrule: Coordinates all actions necessary *//* for the parsing and creation of a defrule into *//* the current environment. *//****************************************************/globle int ParseDefrule(readSource) char *readSource; {#if (MAC_MPW || MAC_MCW) && (RUN_TIME || BLOAD_ONLY)#pragma unused(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; /*================================================*/ /* Flush the buffer which stores the pretty print */ /* representation for a rule. Add the already */ /* parsed keyword defrule to this buffer. */ /*================================================*/ SetPPBufferStatus(ON); FlushPPBuffer(); SavePPBuffer("(defrule "); /*=========================================================*/ /* Rules cannot be loaded when a binary load is in effect. */ /*=========================================================*/#if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE if (Bloaded() == CLIPS_TRUE) { CannotLoadWithBloadMessage("defrule"); return(CLIPS_TRUE); }#endif /*================================================*/ /* Parse the name and comment fields of the rule, */ /* deleting the rule if it already exists. */ /*================================================*/#if DEBUGGING_FUNCTIONS DeletedRuleDebugFlags = 0;#endif ruleName = GetConstructNameAndComment(readSource,&theToken,"defrule", FindDefrule,Undefrule,"*",CLIPS_FALSE, CLIPS_TRUE,CLIPS_TRUE); if (ruleName == NULL) return(CLIPS_TRUE); /*============================*/ /* Parse the LHS of the rule. */ /*============================*/ theLHS = ParseRuleLHS(readSource,&theToken,ValueToString(ruleName)); if (theLHS == NULL) { ReturnPackedExpression(SalienceExpression); SalienceExpression = NULL; return(CLIPS_TRUE); } #if ! DYNAMIC_SALIENCE ReturnPackedExpression(SalienceExpression); SalienceExpression = NULL;#endif /*============================*/ /* Parse the RHS of the rule. */ /*============================*/ ClearParsedBindNames(); ReturnContext = CLIPS_TRUE; actions = ParseRuleRHS(readSource); if (actions == NULL) { ReturnPackedExpression(SalienceExpression); SalienceExpression = NULL; ReturnLHSParseNodes(theLHS); return(CLIPS_TRUE); } /*=======================*/ /* Process the rule LHS. */ /*=======================*/ topDisjunct = ProcessRuleLHS(theLHS,actions,ruleName); ReturnExpression(actions); ClearParsedBindNames(); ReturnLHSParseNodes(theLHS); if (topDisjunct == NULL) { ReturnPackedExpression(SalienceExpression); SalienceExpression = NULL; return(CLIPS_TRUE); } SalienceExpression = NULL; /*======================================*/ /* Save the nice printout of the rules. */ /*======================================*/ SavePPBuffer("\n"); if (GetConserveMemory() == CLIPS_TRUE) { topDisjunct->header.ppForm = NULL; } else { topDisjunct->header.ppForm = CopyPPBuffer(); } /*=======================================*/ /* Store a pointer to the rule's module. */ /*=======================================*/ theModuleItem = (struct defruleModule *) GetModuleItem(NULL,FindModuleItem("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(DeletedRuleDebugFlags,0)) { SetBreak(topDisjunct); } if (BitwiseTest(DeletedRuleDebugFlags,1) || GetWatchItem("activations")) { SetDefruleWatchActivations(ON,(VOID *) topDisjunct); } if (BitwiseTest(DeletedRuleDebugFlags,2) || GetWatchItem("rules")) { SetDefruleWatchFirings(ON,(VOID *) topDisjunct); }#endif /*================================*/ /* Perform the incremental reset. */ /*================================*/#if INCREMENTAL_RESET IncrementalReset(topDisjunct);#endif /*=============================================*/ /* Return FALSE to indicate no errors occured. */ /*=============================================*/#endif return(CLIPS_FALSE); } #if (! RUN_TIME) && (! BLOAD_ONLY)/**************************************************************//* ProcessRuleLHS: Processes each of the disjuncts of a rule. *//**************************************************************/static struct defrule *ProcessRuleLHS(theLHS,actions,ruleName) struct lhsParseNode *theLHS; struct expr *actions; SYMBOL_HN *ruleName; { struct lhsParseNode *tempNode = NULL; struct defrule *topDisjunct = NULL, *currentDisjunct, *lastDisjunct = NULL; struct expr *newActions, *packPtr; int logicalJoin; int localVarCnt; int complexity; struct joinNode *lastJoin; /*===========================================================*/ /* 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->type == OR_CE) theLHS = theLHS->right; /*=========================================*/ /* Loop through each disjunct of the rule. */ /*=========================================*/ localVarCnt = CountParsedBindNames(); while (theLHS != NULL) { /*===================================*/ /* Analyze the LHS of this disjunct. */ /*===================================*/ if (theLHS->type == AND_CE) tempNode = theLHS->right; else if (theLHS->type == PATTERN_CE) tempNode = theLHS; if (VariableAnalysis(tempNode)) { ReturnDefrule(topDisjunct); return(NULL); } /*=========================================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -