?? generate.c
字號:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.30 10/19/06 */ /* */ /* GENERATE MODULE */ /*******************************************************//*************************************************************//* Purpose: Provides routines for converting field *//* constraints to expressions which can be used *//* in the pattern and join networks. *//* *//* Principal Programmer(s): *//* Gary D. Riley *//* *//* Contributing Programmer(s): *//* *//* Revision History: *//* *//* 6.30: Added support for hashed alpha memories. *//* *//*************************************************************/#define _GENERATE_SOURCE_#include <stdio.h>#define _STDIO_INCLUDED_#include <stdlib.h>#include "setup.h"#if (! RUN_TIME) && (! BLOAD_ONLY) && DEFRULE_CONSTRUCT#include "constant.h"#include "envrnmnt.h"#include "memalloc.h"#include "symbol.h"#include "exprnpsr.h"#include "argacces.h"#include "extnfunc.h"#include "router.h"#include "ruledef.h"#include "pattern.h"#include "generate.h"#if DEFGLOBAL_CONSTRUCT#include "globlpsr.h"#endif/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/ static void ExtractAnds(void *,struct lhsParseNode *,int, struct expr **,struct expr **,struct expr **, struct expr **,struct expr **,int); static void ExtractFieldTest(void *,struct lhsParseNode *,int, struct expr **,struct expr **,struct expr **, struct expr **,struct expr **,int); static struct expr *GetfieldReplace(void *,struct lhsParseNode *); static struct expr *GenPNConstant(void *,struct lhsParseNode *); static struct expr *GenJNConstant(void *,struct lhsParseNode *,int); static struct expr *GenJNColon(void *,struct lhsParseNode *,int); static struct expr *GenPNColon(void *,struct lhsParseNode *); static struct expr *GenJNEq(void *,struct lhsParseNode *,int); static struct expr *GenPNEq(void *,struct lhsParseNode *); static struct expr *GenJNVariableComparison(void *,struct lhsParseNode *, struct lhsParseNode *,int); static struct expr *GenPNVariableComparison(void *,struct lhsParseNode *, struct lhsParseNode *); static int AllVariablesInPattern(struct lhsParseNode *, int); static int AllVariablesInExpression(struct lhsParseNode *, int); static int FieldIsNandTest(struct lhsParseNode *); /*******************************************************//* FieldConversion: Generates join and pattern network *//* expressions for a field constraint. *//*******************************************************/globle void FieldConversion( void *theEnv, struct lhsParseNode *theField, struct lhsParseNode *thePattern) { int testInPatternNetwork = TRUE; struct lhsParseNode *patternPtr; struct expr *headOfPNExpression, *headOfJNExpression, *headOfNandExpression; struct expr *lastPNExpression, *lastJNExpression, *lastNandExpression; struct expr *tempExpression; struct expr *patternNetTest = NULL; struct expr *joinNetTest = NULL; struct expr *nandTest = NULL; struct expr *constantSelector = NULL; struct expr *constantValue = NULL; int nandField; /*==================================================*/ /* Consider a NULL pointer to be an internal error. */ /*==================================================*/ if (theField == NULL) { SystemError(theEnv,"ANALYSIS",3); EnvExitRouter(theEnv,EXIT_FAILURE); } /*========================================================*/ /* Determine if constant testing must be performed in the */ /* join network. Only possible when a field contains an */ /* or ('|') and references are made to variables outside */ /* the pattern. */ /*========================================================*/ if (theField->bottom != NULL) { if (theField->bottom->bottom != NULL) { testInPatternNetwork = AllVariablesInPattern(theField->bottom,theField->pattern); } } /*=========================================================*/ /* Determine if any of the field tests require the network */ /* expression to be evaluted in the nand join. */ /*=========================================================*/ nandField = FieldIsNandTest(theField); /*=============================================================*/ /* Extract pattern and join network expressions. Loop through */ /* the or'ed constraints of the field, extracting pattern and */ /* join network expressions and adding them to a running list. */ /*=============================================================*/ headOfPNExpression = lastPNExpression = NULL; headOfJNExpression = lastJNExpression = NULL; headOfNandExpression = lastNandExpression = NULL; for (patternPtr = theField->bottom; patternPtr != NULL; patternPtr = patternPtr->bottom) { /*=============================================*/ /* Extract pattern and join network tests from */ /* the or'ed constraint being examined. */ /*=============================================*/ ExtractAnds(theEnv,patternPtr,testInPatternNetwork,&patternNetTest,&joinNetTest,&nandTest, &constantSelector,&constantValue,nandField); /*=============================================================*/ /* Constant hashing is only used in the pattern network if the */ /* field doesn't contain an or'ed constraint. For example, the */ /* constaint "red | blue" can not use hashing. */ /*=============================================================*/ if (constantSelector != NULL) { if ((patternPtr == theField->bottom) && (patternPtr->bottom == NULL)) { theField->constantSelector = constantSelector; theField->constantValue = constantValue; } else { ReturnExpression(theEnv,constantSelector); ReturnExpression(theEnv,constantValue); ReturnExpression(theEnv,theField->constantSelector); ReturnExpression(theEnv,theField->constantValue); theField->constantSelector = NULL; theField->constantValue = NULL; } } /*=====================================================*/ /* Add the new pattern network expressions to the list */ /* of pattern network expressions being constructed. */ /*=====================================================*/ if (patternNetTest != NULL) { if (lastPNExpression == NULL) { headOfPNExpression = patternNetTest; } else { lastPNExpression->nextArg = patternNetTest; } lastPNExpression = patternNetTest; } /*==================================================*/ /* Add the new join network expressions to the list */ /* of join network expressions being constructed. */ /*==================================================*/ if (joinNetTest != NULL) { if (lastJNExpression == NULL) { headOfJNExpression = joinNetTest; } else { lastJNExpression->nextArg = joinNetTest; } lastJNExpression = joinNetTest; } /*=======================================================*/ /* Add the new nand join network expressions to the list */ /* of nand join network expressions being constructed. */ /*=======================================================*/ if (nandTest != NULL) { if (lastNandExpression == NULL) { headOfNandExpression = nandTest; } else { lastNandExpression->nextArg = nandTest; } lastNandExpression = nandTest; } } /*==========================================================*/ /* If there was more than one expression generated from the */ /* or'ed field constraints for the pattern network, then */ /* enclose the expressions within an "or" function call. */ /*==========================================================*/ if ((headOfPNExpression != NULL) ? (headOfPNExpression->nextArg != NULL) : FALSE) { tempExpression = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_OR); tempExpression->argList = headOfPNExpression; headOfPNExpression = tempExpression; } /*==========================================================*/ /* If there was more than one expression generated from the */ /* or'ed field constraints for the join network, then */ /* enclose the expressions within an "or" function call. */ /*==========================================================*/ if ((headOfJNExpression != NULL) ? (headOfJNExpression->nextArg != NULL) : FALSE) { tempExpression = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_OR); tempExpression->argList = headOfJNExpression; headOfJNExpression = tempExpression; } /*==========================================================*/ /* If there was more than one expression generated from the */ /* or'ed field constraints for the nand join network, then */ /* enclose the expressions within an "or" function call. */ /*==========================================================*/ if ((headOfNandExpression != NULL) ? (headOfNandExpression->nextArg != NULL) : FALSE) { tempExpression = GenConstant(theEnv,FCALL,ExpressionData(theEnv)->PTR_OR); tempExpression->argList = headOfNandExpression; headOfNandExpression = tempExpression; } /*===============================================================*/ /* If the field constraint binds a variable that was previously */ /* bound somewhere in the LHS of the rule, then generate an */ /* expression to compare this binding occurrence of the variable */ /* to the previous binding occurrence. */ /*===============================================================*/ if (((theField->type == MF_VARIABLE) || (theField->type == SF_VARIABLE)) && (theField->referringNode != NULL)) { /*================================================================*/ /* If the previous variable reference is within the same pattern, */ /* then the variable comparison can occur in the pattern network. */ /*================================================================*/ if (theField->referringNode->pattern == theField->pattern) { tempExpression = GenPNVariableComparison(theEnv,theField,theField->referringNode); headOfPNExpression = CombineExpressions(theEnv,tempExpression,headOfPNExpression); } /*====================================*/ /* Otherwise, the variable comparison */ /* must occur in the join network. */ /*====================================*/ else if (theField->referringNode->pattern > 0) { tempExpression = GenJNVariableComparison(theEnv,theField,theField->referringNode,nandField); if (theField->beginNandDepth > theField->referringNode->beginNandDepth) { headOfNandExpression = CombineExpressions(theEnv,tempExpression,headOfNandExpression); /*==========================*/ /* Generate the hash index. */ /*==========================*/ if (theField->patternType->genGetJNValueFunction)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -