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