📄 rulelhs.c
字号:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.05 04/09/97 */ /* */ /* 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 _CLIPS_STDIO_#include <string.h>#include "constant.h"#include "symbol.h"#include "clipsmem.h"#include "exprnpsr.h"#include "argacces.h"#include "scanner.h"#include "reorder.h"#include "router.h"#include "ruledef.h"#include "constrct.h"#include "cstrnchk.h"#include "constrnt.h"#include "pattern.h"#include "agenda.h"#include "rulelhs.h"#if ANSI_COMPILER static struct lhsParseNode *RuleBodyParse(char *,struct token *,char *,int *); static VOID DeclarationParse(char *,char *,int *); static struct lhsParseNode *LHSPattern(char *,int,char *,int *,int, struct token *,char *); static struct lhsParseNode *ConnectedPatternParse(char *,struct token *,int *); static struct lhsParseNode *GroupPatterns(char *,int,char *,int *); static struct lhsParseNode *TestPattern(char *,int *); static struct lhsParseNode *AssignmentParse(char *,SYMBOL_HN *,int *); static VOID TagLHSLogicalNodes(struct lhsParseNode *); static struct lhsParseNode *SimplePatternParse(char *,struct token *,int *); static VOID ParseSalience(char *,char *,int *); static VOID ParseAutoFocus(char *,int *);#else static struct lhsParseNode *RuleBodyParse(); static VOID DeclarationParse(); static struct lhsParseNode *LHSPattern(); static struct lhsParseNode *ConnectedPatternParse(); static struct lhsParseNode *GroupPatterns(); static struct lhsParseNode *TestPattern(); static struct lhsParseNode *AssignmentParse(); static VOID TagLHSLogicalNodes(); static struct lhsParseNode *SimplePatternParse(); static VOID ParseSalience(); static VOID ParseAutoFocus();#endif/****************************//* LOCAL INTERNAL VARIABLES *//****************************/ static int WithinNotCE = CLIPS_FALSE;/****************************************//* GLOBAL INTERNAL VARIABLE DEFINITIONS *//****************************************/ globle int GlobalSalience; globle int GlobalAutoFocus; globle struct expr *SalienceExpression = NULL;/*******************************************************************//* ParseRuleLHS: Coordinates all the actions necessary for parsing *//* the LHS of a rule including the reordering of pattern *//* conditional elements to conform with the CLIPS Rete topology. *//*******************************************************************/globle struct lhsParseNode *ParseRuleLHS(readSource,theToken,ruleName) char *readSource; struct token *theToken; char *ruleName; { struct lhsParseNode *theLHS; int result; int error = CLIPS_FALSE; /*========================================*/ /* Initialize salience parsing variables. */ /*========================================*/ GlobalSalience = 0; GlobalAutoFocus = CLIPS_FALSE; SalienceExpression = NULL; /*============================*/ /* Set the indentation depth. */ /*============================*/ SetIndentDepth(3); /*=====================================================*/ /* Get the raw representation for the LHS of the rule. */ /*=====================================================*/ theLHS = RuleBodyParse(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(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 *//* CLIPS Rete Topology. *//* *//* <rule-body> ::= [<declaration>] *//* <conditional-element>* *//* => *//*********************************************************/static struct lhsParseNode *RuleBodyParse(readSource,theToken,ruleName,error) char *readSource; struct token *theToken; char *ruleName; int *error; { struct lhsParseNode *theNode, *otherNodes; /*=============================*/ /* Set the error return value. */ /*=============================*/ *error = CLIPS_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) : CLIPS_FALSE) { return(NULL); } /*===========================================*/ /* Parse the first pattern as a special case */ /* (the declare statement is allowed). */ /*===========================================*/ theNode = LHSPattern(readSource,SYMBOL,"=>",error,CLIPS_TRUE,theToken,ruleName); if (*error == CLIPS_TRUE) { ReturnLHSParseNodes(theNode); return(NULL); } PPCRAndIndent(); /*======================================*/ /* Parse the other patterns in the LHS. */ /*======================================*/ otherNodes = GroupPatterns(readSource,SYMBOL,"=>",error); if (*error == CLIPS_TRUE) { ReturnLHSParseNodes(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. Only *//* salience declarations are currently allowed. *//* *//* <declaration> ::= (declare <rule-property>+) *//* *//* <rule-property> ::= (salience <integer-expression>) *//********************************************************/static VOID DeclarationParse(readSource,ruleName,error) char *readSource; char *ruleName; int *error; { struct token theToken; struct expr *packPtr; int notDone = CLIPS_TRUE; int salienceParsed = CLIPS_FALSE, autoFocusParsed = CLIPS_FALSE; /*===========================*/ /* Next token must be a '('. */ /*===========================*/ SavePPBuffer(" "); GetToken(readSource,&theToken); if (theToken.type != LPAREN) { SyntaxErrorMessage("declare statement"); *error = CLIPS_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(readSource,&theToken); if (theToken.type != SYMBOL) { SyntaxErrorMessage("declare statement"); *error = CLIPS_TRUE; } /*==============================================*/ /* Parse a salience declaration if encountered. */ /*==============================================*/ else if (strcmp(ValueToString(theToken.value),"salience") == 0) { if (salienceParsed) { AlreadyParsedErrorMessage("salience declaration",NULL); *error = CLIPS_TRUE; } else { ParseSalience(readSource,ruleName,error); salienceParsed = CLIPS_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("auto-focus declaration",NULL); *error = CLIPS_TRUE; } else { ParseAutoFocus(readSource,error); autoFocusParsed = CLIPS_TRUE; } } /*==========================================*/ /* Otherwise the symbol does not correspond */ /* to a valid rule property. */ /*==========================================*/ else { SyntaxErrorMessage("declare statement"); *error = CLIPS_TRUE; } /*=====================================*/ /* Return if an error was encountered. */ /*=====================================*/ if (*error) { ReturnExpression(SalienceExpression); SalienceExpression = NULL; return; } /*=======================================*/ /* Both the salience and auto-focus rule */ /* properties are closed with a ')'. */ /*=======================================*/ GetToken(readSource,&theToken); if (theToken.type != RPAREN) { PPBackup(); SavePPBuffer(" "); SavePPBuffer(theToken.printForm); ReturnExpression(SalienceExpression); SalienceExpression = NULL; SyntaxErrorMessage("declare statement"); *error = CLIPS_TRUE; return; } /*=============================================*/ /* The declare statement is closed with a ')'. */ /*=============================================*/ GetToken(readSource,&theToken); if (theToken.type == RPAREN) notDone = CLIPS_FALSE; else if (theToken.type != LPAREN) { ReturnExpression(SalienceExpression); SalienceExpression = NULL; SyntaxErrorMessage("declare statement"); *error = CLIPS_TRUE; return; } else { PPBackup(); SavePPBuffer(" ("); } } /*==========================================*/ /* Return the value of the salience through */ /* the global variable SalienceExpression. */ /*==========================================*/ packPtr = PackExpression(SalienceExpression); ReturnExpression(SalienceExpression); SalienceExpression = packPtr; return; }/************************************************************//* ParseSalience: Parses the rest of a defrule salience *//* declaration once the salience keyword has been parsed. *//************************************************************/static VOID ParseSalience(readSource,ruleName,error) char *readSource; char *ruleName; int *error; { int salience; DATA_OBJECT salienceValue; /*==============================*/ /* Get the salience expression. */ /*==============================*/ SavePPBuffer(" "); SalienceExpression = ParseAtomOrExpression(readSource,NULL); if (SalienceExpression == NULL) { *error = CLIPS_TRUE; return; } /*============================================================*/ /* Evaluate the expression and determine if it is an integer. */ /*============================================================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -