📄 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 + -