📄 tmpltrhs.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.24 06/05/06 */
/* */
/* DEFTEMPLATE RHS PARSING HEADER FILE */
/*******************************************************/
/*************************************************************/
/* Purpose: Parses deftemplate fact patterns used with the */
/* assert function. */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* */
/* Contributing Programmer(s): */
/* */
/* Revision History: */
/* */
/* 6.24: Added additional argument required for */
/* DeriveDefaultFromConstraints. */
/* */
/* Added additional argument required for */
/* InvalidDeftemplateSlotMessage. */
/* */
/*************************************************************/
#define _TMPLTRHS_SOURCE_
#include "setup.h"
#if DEFTEMPLATE_CONSTRUCT
#include <stdio.h>
#define _STDIO_INCLUDED_
#include "memalloc.h"
#include "prntutil.h"
#include "router.h"
#include "tmpltfun.h"
#include "tmpltdef.h"
#include "factrhs.h"
#include "extnfunc.h"
#include "modulutl.h"
#include "default.h"
#include "tmpltutl.h"
#include "tmpltlhs.h"
#include "tmpltrhs.h"
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
static struct expr *ParseAssertSlotValues(void *,char *,struct token *,struct templateSlot *,int *,int);
static struct expr *ReorderAssertSlotValues(void *,struct templateSlot *,struct expr *,int *);
static struct expr *GetSlotAssertValues(void *,struct templateSlot *,struct expr *,int *);
static struct expr *FindAssertSlotItem(struct templateSlot *,struct expr *);
static struct templateSlot *ParseSlotLabel(void *,char *,struct token *,struct deftemplate *,int *,int);
/******************************************************************/
/* ParseAssertTemplate: Parses and builds the list of values that */
/* are used for an assert of a fact with a deftemplate. */
/******************************************************************/
globle struct expr *ParseAssertTemplate(
void *theEnv,
char *readSource,
struct token *theToken,
int *error,
int endType,
int constantsOnly,
struct deftemplate *theDeftemplate)
{
struct expr *firstSlot, *lastSlot, *nextSlot;
struct expr *firstArg, *tempSlot;
struct templateSlot *slotPtr;
firstSlot = NULL;
lastSlot = NULL;
/*==============================================*/
/* Parse each of the slot fields in the assert. */
/*==============================================*/
while ((slotPtr = ParseSlotLabel(theEnv,readSource,theToken,theDeftemplate,error,endType)) != NULL)
{
/*========================================================*/
/* Check to see that the slot hasn't already been parsed. */
/*========================================================*/
for (tempSlot = firstSlot;
tempSlot != NULL;
tempSlot = tempSlot->nextArg)
{
if (tempSlot->value == (void *) slotPtr->slotName)
{
AlreadyParsedErrorMessage(theEnv,"slot ",ValueToString(slotPtr->slotName));
*error = TRUE;
ReturnExpression(theEnv,firstSlot);
return(NULL);
}
}
/*============================================*/
/* Parse the values to be stored in the slot. */
/*============================================*/
nextSlot = ParseAssertSlotValues(theEnv,readSource,theToken,
slotPtr,error,constantsOnly);
if (*error)
{
ReturnExpression(theEnv,firstSlot);
return(NULL);
}
/*============================================*/
/* Check to see if the values to be stored in */
/* the slot violate the slot's constraints. */
/*============================================*/
if (CheckRHSSlotTypes(theEnv,nextSlot->argList,slotPtr,"assert") == 0)
{
*error = TRUE;
ReturnExpression(theEnv,firstSlot);
ReturnExpression(theEnv,nextSlot);
return(NULL);
}
/*===================================================*/
/* Add the slot to the list of slots already parsed. */
/*===================================================*/
if (lastSlot == NULL)
{ firstSlot = nextSlot; }
else
{ lastSlot->nextArg = nextSlot; }
lastSlot = nextSlot;
}
/*=================================================*/
/* Return if an error occured parsing a slot name. */
/*=================================================*/
if (*error)
{
ReturnExpression(theEnv,firstSlot);
return(NULL);
}
/*=============================================================*/
/* Reorder the arguments to the order used by the deftemplate. */
/*=============================================================*/
firstArg = ReorderAssertSlotValues(theEnv,theDeftemplate->slotList,firstSlot,error);
ReturnExpression(theEnv,firstSlot);
/*==============================*/
/* Return the assert arguments. */
/*==============================*/
return(firstArg);
}
/****************************************************************/
/* ParseSlotLabel: Parses the beginning of a slot definition. */
/* Checks for opening left parenthesis and a valid slot name. */
/****************************************************************/
static struct templateSlot *ParseSlotLabel(
void *theEnv,
char *inputSource,
struct token *tempToken,
struct deftemplate *theDeftemplate,
int *error,
int endType)
{
struct templateSlot *slotPtr;
short position;
/*========================*/
/* Initialize error flag. */
/*========================*/
*error = FALSE;
/*============================================*/
/* If token is a right parenthesis, then fact */
/* template definition is complete. */
/*============================================*/
GetToken(theEnv,inputSource,tempToken);
if (tempToken->type == endType)
{ return(NULL); }
/*=======================================*/
/* Put a space between the template name */
/* and the first slot definition. */
/*=======================================*/
PPBackup(theEnv);
SavePPBuffer(theEnv," ");
SavePPBuffer(theEnv,tempToken->printForm);
/*=======================================================*/
/* Slot definition begins with opening left parenthesis. */
/*=======================================================*/
if (tempToken->type != LPAREN)
{
SyntaxErrorMessage(theEnv,"deftemplate pattern");
*error = TRUE;
return(NULL);
}
/*=============================*/
/* Slot name must be a symbol. */
/*=============================*/
GetToken(theEnv,inputSource,tempToken);
if (tempToken->type != SYMBOL)
{
SyntaxErrorMessage(theEnv,"deftemplate pattern");
*error = TRUE;
return(NULL);
}
/*======================================================*/
/* Check that the slot name is valid for this template. */
/*======================================================*/
if ((slotPtr = FindSlot(theDeftemplate,(SYMBOL_HN *) tempToken->value,&position)) == NULL)
{
InvalidDeftemplateSlotMessage(theEnv,ValueToString(tempToken->value),
ValueToString(theDeftemplate->header.name),TRUE);
*error = TRUE;
return(NULL);
}
/*====================================*/
/* Return a pointer to the slot name. */
/*====================================*/
return(slotPtr);
}
/**************************************************************************/
/* ParseAssertSlotValues: Gets a single assert slot value for a template. */
/**************************************************************************/
static struct expr *ParseAssertSlotValues(
void *theEnv,
char *inputSource,
struct token *tempToken,
struct templateSlot *slotPtr,
int *error,
int constantsOnly)
{
struct expr *nextSlot;
struct expr *newField, *valueList, *lastValue;
int printError;
/*=============================*/
/* Handle a single field slot. */
/*=============================*/
if (slotPtr->multislot == FALSE)
{
/*=====================*/
/* Get the slot value. */
/*=====================*/
SavePPBuffer(theEnv," ");
newField = GetAssertArgument(theEnv,inputSource,tempToken,
error,RPAREN,constantsOnly,&printError);
if (*error)
{
if (printError) SyntaxErrorMessage(theEnv,"deftemplate pattern");
return(NULL);
}
/*=================================================*/
/* A single field slot value must contain a value. */
/* Only a multifield slot can be empty. */
/*=================================================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -