📄 tmpltpsr.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.23 01/31/05 */
/* */
/* DEFTEMPLATE PARSER MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: Parses the deftemplate construct. */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* */
/* Contributing Programmer(s): */
/* */
/* Revision History: */
/* 6.23: Added support for templates maintaining their */
/* own list of facts. */
/* */
/*************************************************************/
#define _TMPLTPSR_SOURCE_
#include "setup.h"
#if DEFTEMPLATE_CONSTRUCT
#include <stdio.h>
#define _STDIO_INCLUDED_
#include <string.h>
#include "constant.h"
#include "memalloc.h"
#include "symbol.h"
#include "scanner.h"
#include "exprnpsr.h"
#include "router.h"
#include "constrct.h"
#include "envrnmnt.h"
#include "factmngr.h"
#include "cstrnchk.h"
#include "cstrnpsr.h"
#include "cstrcpsr.h"
#if BLOAD || BLOAD_AND_BSAVE
#include "bload.h"
#endif
#include "default.h"
#include "pattern.h"
#include "watch.h"
#include "cstrnutl.h"
#include "tmpltdef.h"
#include "tmpltbsc.h"
#include "tmpltpsr.h"
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
#if (! RUN_TIME) && (! BLOAD_ONLY)
static struct templateSlot *SlotDeclarations(void *,char *,struct token *);
static struct templateSlot *ParseSlot(void *,char *,struct token *,struct templateSlot *);
static struct templateSlot *DefinedSlots(void *,char *,SYMBOL_HN *,int,struct token *);
#endif
/*******************************************************/
/* ParseDeftemplate: Parses the deftemplate construct. */
/*******************************************************/
globle int ParseDeftemplate(
void *theEnv,
char *readSource)
{
#if (MAC_MCW || IBM_MCW) && (RUN_TIME || BLOAD_ONLY)
#pragma unused(readSource)
#endif
#if (! RUN_TIME) && (! BLOAD_ONLY)
SYMBOL_HN *deftemplateName;
struct deftemplate *newDeftemplate;
struct templateSlot *slots;
struct token inputToken;
/*================================================*/
/* Initialize pretty print and error information. */
/*================================================*/
DeftemplateData(theEnv)->DeftemplateError = FALSE;
SetPPBufferStatus(theEnv,ON);
FlushPPBuffer(theEnv);
SavePPBuffer(theEnv,"(deftemplate ");
/*==============================================================*/
/* Deftemplates can not be added when a binary image is loaded. */
/*==============================================================*/
#if BLOAD || BLOAD_AND_BSAVE
if ((Bloaded(theEnv) == TRUE) && (! ConstructData(theEnv)->CheckSyntaxMode))
{
CannotLoadWithBloadMessage(theEnv,"deftemplate");
return(TRUE);
}
#endif
/*=======================================================*/
/* Parse the name and comment fields of the deftemplate. */
/*=======================================================*/
#if DEBUGGING_FUNCTIONS
DeftemplateData(theEnv)->DeletedTemplateDebugFlags = 0;
#endif
deftemplateName = GetConstructNameAndComment(theEnv,readSource,&inputToken,"deftemplate",
EnvFindDeftemplate,EnvUndeftemplate,"%",
TRUE,TRUE,TRUE);
if (deftemplateName == NULL) return(TRUE);
if (ReservedPatternSymbol(theEnv,ValueToString(deftemplateName),"deftemplate"))
{
ReservedPatternSymbolErrorMsg(theEnv,ValueToString(deftemplateName),"a deftemplate name");
return(TRUE);
}
/*===========================================*/
/* Parse the slot fields of the deftemplate. */
/*===========================================*/
slots = SlotDeclarations(theEnv,readSource,&inputToken);
if (DeftemplateData(theEnv)->DeftemplateError == TRUE) return(TRUE);
/*==============================================*/
/* If we're only checking syntax, don't add the */
/* successfully parsed deftemplate to the KB. */
/*==============================================*/
if (ConstructData(theEnv)->CheckSyntaxMode)
{
ReturnSlots(theEnv,slots);
return(FALSE);
}
/*=====================================*/
/* Create a new deftemplate structure. */
/*=====================================*/
newDeftemplate = get_struct(theEnv,deftemplate);
newDeftemplate->header.name = deftemplateName;
newDeftemplate->header.next = NULL;
newDeftemplate->header.usrData = NULL;
newDeftemplate->slotList = slots;
newDeftemplate->implied = FALSE;
newDeftemplate->numberOfSlots = 0;
newDeftemplate->busyCount = 0;
newDeftemplate->watch = 0;
newDeftemplate->inScope = TRUE;
newDeftemplate->patternNetwork = NULL;
newDeftemplate->factList = NULL;
newDeftemplate->lastFact = NULL;
newDeftemplate->header.whichModule = (struct defmoduleItemHeader *)
GetModuleItem(theEnv,NULL,DeftemplateData(theEnv)->DeftemplateModuleIndex);
/*================================*/
/* Determine the number of slots. */
/*================================*/
while (slots != NULL)
{
newDeftemplate->numberOfSlots++;
slots = slots->next;
}
/*====================================*/
/* Store pretty print representation. */
/*====================================*/
if (EnvGetConserveMemory(theEnv) == TRUE)
{ newDeftemplate->header.ppForm = NULL; }
else
{ newDeftemplate->header.ppForm = CopyPPBuffer(theEnv); }
/*=======================================================================*/
/* If a template is redefined, then we want to restore its watch status. */
/*=======================================================================*/
#if DEBUGGING_FUNCTIONS
if ((BitwiseTest(DeftemplateData(theEnv)->DeletedTemplateDebugFlags,0)) || EnvGetWatchItem(theEnv,"facts"))
{ EnvSetDeftemplateWatch(theEnv,ON,(void *) newDeftemplate); }
#endif
/*==============================================*/
/* Add deftemplate to the list of deftemplates. */
/*==============================================*/
AddConstructToModule(&newDeftemplate->header);
InstallDeftemplate(theEnv,newDeftemplate);
#else
#if MAC_MCW || IBM_MCW || MAC_XCD
#pragma unused(theEnv)
#endif
#endif
return(FALSE);
}
#if (! RUN_TIME) && (! BLOAD_ONLY)
/**************************************************************/
/* InstallDeftemplate: Increments all occurrences in the hash */
/* table of symbols found in an deftemplate and adds it to */
/* the hash table. */
/**************************************************************/
globle void InstallDeftemplate(
void *theEnv,
struct deftemplate *theDeftemplate)
{
struct templateSlot *slotPtr;
struct expr *tempExpr;
IncrementSymbolCount(theDeftemplate->header.name);
for (slotPtr = theDeftemplate->slotList;
slotPtr != NULL;
slotPtr = slotPtr->next)
{
IncrementSymbolCount(slotPtr->slotName);
tempExpr = AddHashedExpression(theEnv,slotPtr->defaultList);
ReturnExpression(theEnv,slotPtr->defaultList);
slotPtr->defaultList = tempExpr;
slotPtr->constraints = AddConstraint(theEnv,slotPtr->constraints);
}
}
/********************************************************************/
/* SlotDeclarations: Parses the slot declarations of a deftemplate. */
/********************************************************************/
static struct templateSlot *SlotDeclarations(
void *theEnv,
char *readSource,
struct token *inputToken)
{
struct templateSlot *newSlot, *slotList = NULL, *lastSlot = NULL;
struct templateSlot *multiSlot = NULL;
while (inputToken->type != RPAREN)
{
/*====================================================*/
/* Slots begin with a '(' followed by a slot keyword. */
/*====================================================*/
if (inputToken->type != LPAREN)
{
SyntaxErrorMessage(theEnv,"deftemplate");
ReturnSlots(theEnv,slotList);
ReturnSlots(theEnv,multiSlot);
DeftemplateData(theEnv)->DeftemplateError = TRUE;
return(NULL);
}
GetToken(theEnv,readSource,inputToken);
if (inputToken->type != SYMBOL)
{
SyntaxErrorMessage(theEnv,"deftemplate");
ReturnSlots(theEnv,slotList);
ReturnSlots(theEnv,multiSlot);
DeftemplateData(theEnv)->DeftemplateError = TRUE;
return(NULL);
}
/*=================*/
/* Parse the slot. */
/*=================*/
newSlot = ParseSlot(theEnv,readSource,inputToken,slotList);
if (DeftemplateData(theEnv)->DeftemplateError == TRUE)
{
ReturnSlots(theEnv,newSlot);
ReturnSlots(theEnv,slotList);
ReturnSlots(theEnv,multiSlot);
return(NULL);
}
/*===========================================*/
/* Attach the new slot to the list of slots. */
/*===========================================*/
if (newSlot != NULL)
{
if (lastSlot == NULL)
{ slotList = newSlot; }
else
{ lastSlot->next = newSlot; }
lastSlot = newSlot;
}
/*================================*/
/* Check for closing parenthesis. */
/*================================*/
GetToken(theEnv,readSource,inputToken);
if (inputToken->type != RPAREN)
{
PPBackup(theEnv);
SavePPBuffer(theEnv,"\n ");
SavePPBuffer(theEnv,inputToken->printForm);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -