📄 factqpsr.c
字号:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.24 06/05/06 */ /* */ /* FACT-SET QUERIES PARSER MODULE */ /*******************************************************//*************************************************************//* Purpose: Fact_set Queries Parsing Routines *//* *//* Principal Programmer(s): *//* Brian L. Donnell *//* *//* Contributing Programmer(s): *//* Gary D. Riley *//* *//* Revision History: *//* 6.23: Added fact-set queries. *//* *//* Changed name of variable exp to theExp *//* because of Unix compiler warnings of shadowed *//* definitions. *//* *//* 6.24: Renamed BOOLEAN macro type to intBool. *//* *//*************************************************************//* ========================================= ***************************************** EXTERNAL DEFINITIONS ========================================= ***************************************** */#include "setup.h"#if FACT_SET_QUERIES && (! RUN_TIME)#include <string.h>#include "envrnmnt.h"#include "exprnpsr.h"#include "extnfunc.h"#include "factqury.h"#include "modulutl.h"#include "prcdrpsr.h"#include "prntutil.h"#include "router.h"#include "scanner.h"#include "strngrtr.h"#define _FACTQPSR_SOURCE_#include "factqpsr.h"/* ========================================= ***************************************** CONSTANTS ========================================= ***************************************** */#define FACT_SLOT_REF ':'/* ========================================= ***************************************** INTERNALLY VISIBLE FUNCTION HEADERS ========================================= ***************************************** */ /***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/ static EXPRESSION *ParseQueryRestrictions(void *,EXPRESSION *,char *,struct token *); static intBool ReplaceTemplateNameWithReference(void *,EXPRESSION *); static int ParseQueryTestExpression(void *,EXPRESSION *,char *); static int ParseQueryActionExpression(void *,EXPRESSION *,char *,EXPRESSION *,struct token *); static void ReplaceFactVariables(void *,EXPRESSION *,EXPRESSION *,int,int); static void ReplaceSlotReference(void *,EXPRESSION *,EXPRESSION *, struct FunctionDefinition *,int); static int IsQueryFunction(EXPRESSION *);/* ========================================= ***************************************** EXTERNALLY VISIBLE FUNCTIONS ========================================= ***************************************** *//*********************************************************************** NAME : FactParseQueryNoAction DESCRIPTION : Parses the following functions : (any-factp) (find-first-fact) (find-all-facts) INPUTS : 1) The address of the top node of the query function 2) The logical name of the input RETURNS : The completed expression chain, or NULL on errors SIDE EFFECTS : The expression chain is extended, or the "top" node is deleted on errors NOTES : H/L Syntax : (<function> <query-block>) <query-block> :== (<fact-var>+) <query-expression> <fact-var> :== (<var-name> <template-name>+) Parses into following form : <query-function> | V <query-expression> -> <template-1a> -> <template-1b> -> (QDS) -> <template-2a> -> <template-2b> -> (QDS) -> ... ***********************************************************************/globle EXPRESSION *FactParseQueryNoAction( void *theEnv, EXPRESSION *top, char *readSource) { EXPRESSION *factQuerySetVars; struct token queryInputToken; factQuerySetVars = ParseQueryRestrictions(theEnv,top,readSource,&queryInputToken); if (factQuerySetVars == NULL) { return(NULL); } IncrementIndentDepth(theEnv,3); PPCRAndIndent(theEnv); if (ParseQueryTestExpression(theEnv,top,readSource) == FALSE) { DecrementIndentDepth(theEnv,3); ReturnExpression(theEnv,factQuerySetVars); return(NULL); } DecrementIndentDepth(theEnv,3); GetToken(theEnv,readSource,&queryInputToken); if (GetType(queryInputToken) != RPAREN) { SyntaxErrorMessage(theEnv,"fact-set query function"); ReturnExpression(theEnv,top); ReturnExpression(theEnv,factQuerySetVars); return(NULL); } ReplaceFactVariables(theEnv,factQuerySetVars,top->argList,TRUE,0); ReturnExpression(theEnv,factQuerySetVars); return(top); }/*********************************************************************** NAME : FactParseQueryAction DESCRIPTION : Parses the following functions : (do-for-fact) (do-for-all-facts) (delayed-do-for-all-facts) INPUTS : 1) The address of the top node of the query function 2) The logical name of the input RETURNS : The completed expression chain, or NULL on errors SIDE EFFECTS : The expression chain is extended, or the "top" node is deleted on errors NOTES : H/L Syntax : (<function> <query-block> <query-action>) <query-block> :== (<fact-var>+) <query-expression> <fact-var> :== (<var-name> <template-name>+) Parses into following form : <query-function> | V <query-expression> -> <query-action> -> <template-1a> -> <template-1b> -> (QDS) -> <template-2a> -> <template-2b> -> (QDS) -> ... ***********************************************************************/globle EXPRESSION *FactParseQueryAction( void *theEnv, EXPRESSION *top, char *readSource) { EXPRESSION *factQuerySetVars; struct token queryInputToken; factQuerySetVars = ParseQueryRestrictions(theEnv,top,readSource,&queryInputToken); if (factQuerySetVars == NULL) { return(NULL); } IncrementIndentDepth(theEnv,3); PPCRAndIndent(theEnv); if (ParseQueryTestExpression(theEnv,top,readSource) == FALSE) { DecrementIndentDepth(theEnv,3); ReturnExpression(theEnv,factQuerySetVars); return(NULL); } PPCRAndIndent(theEnv); if (ParseQueryActionExpression(theEnv,top,readSource,factQuerySetVars,&queryInputToken) == FALSE) { DecrementIndentDepth(theEnv,3); ReturnExpression(theEnv,factQuerySetVars); return(NULL); } DecrementIndentDepth(theEnv,3); if (GetType(queryInputToken) != RPAREN) { SyntaxErrorMessage(theEnv,"fact-set query function"); ReturnExpression(theEnv,top); ReturnExpression(theEnv,factQuerySetVars); return(NULL); } ReplaceFactVariables(theEnv,factQuerySetVars,top->argList,TRUE,0); ReplaceFactVariables(theEnv,factQuerySetVars,top->argList->nextArg,FALSE,0); ReturnExpression(theEnv,factQuerySetVars); return(top); }/* ========================================= ***************************************** INTERNALLY VISIBLE FUNCTIONS ========================================= ***************************************** *//*************************************************************** NAME : ParseQueryRestrictions DESCRIPTION : Parses the template restrictions for a query INPUTS : 1) The top node of the query expression 2) The logical name of the input 3) Caller's token buffer RETURNS : The fact-variable expressions SIDE EFFECTS : Entire query expression deleted on errors Nodes allocated for restrictions and fact variable expressions Template restrictions attached to query-expression as arguments NOTES : Expects top != NULL ***************************************************************/static EXPRESSION *ParseQueryRestrictions( void *theEnv, EXPRESSION *top, char *readSource, struct token *queryInputToken) { EXPRESSION *factQuerySetVars = NULL,*lastFactQuerySetVars = NULL, *templateExp = NULL,*lastTemplateExp, *tmp,*lastOne = NULL; int error = FALSE; SavePPBuffer(theEnv," "); GetToken(theEnv,readSource,queryInputToken); if (queryInputToken->type != LPAREN) { goto ParseQueryRestrictionsError1; } GetToken(theEnv,readSource,queryInputToken); if (queryInputToken->type != LPAREN) { goto ParseQueryRestrictionsError1; } while (queryInputToken->type == LPAREN) { GetToken(theEnv,readSource,queryInputToken); if (queryInputToken->type != SF_VARIABLE) { goto ParseQueryRestrictionsError1; } tmp = factQuerySetVars; while (tmp != NULL) { if (tmp->value == queryInputToken->value) { PrintErrorID(theEnv,"FACTQPSR",1,FALSE); EnvPrintRouter(theEnv,WERROR,"Duplicate fact member variable name in function "); EnvPrintRouter(theEnv,WERROR,ValueToString(ExpressionFunctionCallName(top))); EnvPrintRouter(theEnv,WERROR,".\n"); goto ParseQueryRestrictionsError2; } tmp = tmp->nextArg; } tmp = GenConstant(theEnv,SF_VARIABLE,queryInputToken->value); if (factQuerySetVars == NULL) { factQuerySetVars = tmp; } else { lastFactQuerySetVars->nextArg = tmp; } lastFactQuerySetVars = tmp; SavePPBuffer(theEnv," "); templateExp = ArgumentParse(theEnv,readSource,&error); if (error) { goto ParseQueryRestrictionsError2; } if (templateExp == NULL) { goto ParseQueryRestrictionsError1; } if (ReplaceTemplateNameWithReference(theEnv,templateExp) == FALSE) { goto ParseQueryRestrictionsError2; } lastTemplateExp = templateExp; SavePPBuffer(theEnv," "); while ((tmp = ArgumentParse(theEnv,readSource,&error)) != NULL) { if (ReplaceTemplateNameWithReference(theEnv,tmp) == FALSE) goto ParseQueryRestrictionsError2; lastTemplateExp->nextArg = tmp; lastTemplateExp = tmp; SavePPBuffer(theEnv," "); } if (error) { goto ParseQueryRestrictionsError2; } PPBackup(theEnv); PPBackup(theEnv); SavePPBuffer(theEnv,")"); tmp = GenConstant(theEnv,SYMBOL,(void *) FactQueryData(theEnv)->QUERY_DELIMETER_SYMBOL); lastTemplateExp->nextArg = tmp; lastTemplateExp = tmp; if (top->argList == NULL) { top->argList = templateExp; } else { lastOne->nextArg = templateExp; } lastOne = lastTemplateExp; templateExp = NULL; SavePPBuffer(theEnv," "); GetToken(theEnv,readSource,queryInputToken); } if (queryInputToken->type != RPAREN) { goto ParseQueryRestrictionsError1; } PPBackup(theEnv); PPBackup(theEnv); SavePPBuffer(theEnv,")"); return(factQuerySetVars);ParseQueryRestrictionsError1: SyntaxErrorMessage(theEnv,"fact-set query function");ParseQueryRestrictionsError2: ReturnExpression(theEnv,templateExp); ReturnExpression(theEnv,top); ReturnExpression(theEnv,factQuerySetVars); return(NULL); }/*************************************************** NAME : ReplaceTemplateNameWithReference
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -