⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exprnpsr.c

📁 NASA 开发使用的一个专家系统
💻 C
📖 第 1 页 / 共 2 页
字号:
   /*******************************************************/   /*      "C" Language Integrated Production System      */   /*                                                     */   /*             CLIPS Version 6.05  04/09/97            */   /*                                                     */   /*              EXPRESSION PARSER MODULE               */   /*******************************************************//*************************************************************//* Purpose: Provides routines for parsing expressions.       *//*                                                           *//* Principal Programmer(s):                                  *//*      Gary D. Riley                                        *//*                                                           *//* Contributing Programmer(s):                               *//*      Brian L. Donnell                                     *//*                                                           *//* Revision History:                                         *//*                                                           *//*************************************************************/#define _EXPRNPSR_SOURCE_#include "setup.h"#include <stdio.h>#define _CLIPS_STDIO_#if ANSI_COMPILER#include <stdlib.h>#endif#include <string.h>#include <ctype.h>#include "constant.h"#include "router.h"#include "strngrtr.h"#include "scanner.h"#include "clipsmem.h"#include "argacces.h"#include "prntutil.h"#include "cstrnchk.h"#include "extnfunc.h"#include "exprnpsr.h"#include "modulutl.h"#if DEFRULE_CONSTRUCT#include "network.h"#endif#if DEFGENERIC_CONSTRUCT#include "genrccom.h"#endif#if DEFFUNCTION_CONSTRUCT#include "dffnxfun.h"#endif/****************************************//* GLOBAL INTERNAL VARIABLE DEFINITIONS *//****************************************/#if (! RUN_TIME)   globle SAVED_CONTEXTS      *svContexts = NULL;   globle int                  ReturnContext;   globle int                  BreakContext;#endif   globle BOOLEAN              SequenceOpMode = CLIPS_FALSE;#if (! RUN_TIME)/***************************************************//* Function0Parse: Parses a function. Assumes that *//*   none of the function has been parsed yet.     *//***************************************************/globle struct expr *Function0Parse(logicalName)  char *logicalName;  {   struct token theToken;   struct expr *top;   /*=================================*/   /* All functions begin with a '('. */   /*=================================*/   GetToken(logicalName,&theToken);   if (theToken.type != LPAREN)     {      SyntaxErrorMessage("function calls");      return(NULL);     }   /*=================================*/   /* Parse the rest of the function. */   /*=================================*/   top = Function1Parse(logicalName);   return(top);  }/*******************************************************//* Function1Parse: Parses a function. Assumes that the *//*   opening left parenthesis has already been parsed. *//*******************************************************/globle struct expr *Function1Parse(logicalName)  char *logicalName;  {   struct token theToken;   struct expr *top;   /*========================*/   /* Get the function name. */   /*========================*/   GetToken(logicalName,&theToken);   if (theToken.type != SYMBOL)     {      PrintErrorID("EXPRNPSR",1,CLIPS_TRUE);      PrintCLIPS(WERROR,"A function name must be a symbol\n");      return(NULL);     }   /*=================================*/   /* Parse the rest of the function. */   /*=================================*/   top = Function2Parse(logicalName,ValueToString(theToken.value));   return(top);  }/****************************************************//* Function2Parse: Parses a function. Assumes that  *//*   the opening left parenthesis and function name *//*   have already been parsed.                      *//****************************************************/globle struct expr *Function2Parse(logicalName,name)  char *logicalName, *name;  {   struct FunctionDefinition *theFunction;   struct expr *top;#if DEFGENERIC_CONSTRUCT   VOID *gfunc;#endif#if DEFFUNCTION_CONSTRUCT   VOID *dptr;#endif   /*=========================================================*/   /* Module specification cannot be used in a function call. */   /*=========================================================*/      if (FindModuleSeparator(name))     {      IllegalModuleSpecifierMessage();      return(NULL);     }      /*================================*/   /* Has the function been defined? */   /*================================*/   theFunction = FindFunction(name);#if DEFGENERIC_CONSTRUCT   gfunc = (VOID *) LookupDefgenericInScope(name);#endif#if DEFFUNCTION_CONSTRUCT   if ((theFunction == NULL)#if DEFGENERIC_CONSTRUCT        && (gfunc == NULL)#endif     )     dptr = (VOID *) LookupDeffunctionInScope(name);   else     dptr = NULL;#endif   /*=============================*/   /* Define top level structure. */   /*=============================*/#if DEFFUNCTION_CONSTRUCT   if (dptr != NULL)     top = GenConstant(PCALL,dptr);   else#endif#if DEFGENERIC_CONSTRUCT   if (gfunc != NULL)     top = GenConstant(GCALL,gfunc);   else#endif   if (theFunction != NULL)     top = GenConstant(FCALL,theFunction);   else     {            PrintErrorID("EXPRNPSR",3,CLIPS_TRUE);      PrintCLIPS(WERROR,"Missing function declaration for ");      PrintCLIPS(WERROR,name);      PrintCLIPS(WERROR,".\n");      return(NULL);     }         /*=======================================================*/   /* Check to see if function has its own parsing routine. */   /*=======================================================*/      PushRtnBrkContexts();   ReturnContext = CLIPS_FALSE;   BreakContext = CLIPS_FALSE;   #if DEFGENERIC_CONSTRUCT || DEFFUNCTION_CONSTRUCT   if (top->type == FCALL)#endif     {      if (theFunction->parser != NULL)        {         top = (*theFunction->parser)(top,logicalName);         PopRtnBrkContexts();         if (top == NULL) return(NULL);         if (ReplaceSequenceExpansionOps(top->argList,top,FindFunction("(expansion-call)"),                                         FindFunction("expand$")))           {            ReturnExpression(top);            return(NULL);           }         return(top);        }     }   /*========================================*/   /* Default parsing routine for functions. */   /*========================================*/      top = CollectArguments(top,logicalName);   PopRtnBrkContexts();   if (top == NULL) return(NULL);   if (ReplaceSequenceExpansionOps(top->argList,top,FindFunction("(expansion-call)"),                                    FindFunction("expand$")))     {      ReturnExpression(top);      return(NULL);     }        /*============================================================*/   /* If the function call uses the sequence expansion operator, */   /* its arguments cannot be checked until runtime.             */   /*============================================================*/      if (top->value == (VOID *) FindFunction("(expansion-call)"))     { return(top); }        /*============================*/   /* Check for argument errors. */   /*============================*/   if ((top->type == FCALL) && GetStaticConstraintChecking())     {      if (CheckExpressionAgainstRestrictions(top,theFunction->restrictions,name))        {         ReturnExpression(top);         return(NULL);        }     }     #if DEFFUNCTION_CONSTRUCT    else if (top->type == PCALL)     {      if (CheckDeffunctionCall(top->value,CountArguments(top->argList)) == CLIPS_FALSE)        {         ReturnExpression(top);         return(NULL);        }     }#endif           /*========================*/   /* Return the expression. */   /*========================*/      return(top);  }/***********************************************************************  NAME         : ReplaceSequenceExpansionOps  DESCRIPTION  : Replaces function calls which have multifield                   references as arguments into a call to a                    special function which expands the multifield                   into single arguments at run-time.                 Multifield references which are not function                   arguments are errors  INPUTS       : 1) The expression                 2) The current function call                 3) The address of the internal CLIPS function                    (expansion-call)                 4) The address of the CLIPS function expand$  RETURNS      : FALSE if OK, TRUE on errors  SIDE EFFECTS : Function call expressions modified, if necessary  NOTES        : Function calls which truly want a multifield                   to be passed need use only a single-field                   refernce (i.e. ? instead of $? - the $ is                   being treated as a special expansion operator) **********************************************************************/globle BOOLEAN ReplaceSequenceExpansionOps(actions,fcallexp,expcall,expmult)  EXPRESSION *actions,*fcallexp;  VOID *expcall,*expmult;  {   EXPRESSION *exp;      while (actions != NULL)     {      if ((SequenceOpMode == CLIPS_FALSE) && (actions->type == MF_VARIABLE))        actions->type = SF_VARIABLE;      if ((actions->type == MF_VARIABLE) || (actions->type == MF_GBL_VARIABLE) ||          (actions->value == expmult))        {         if ((fcallexp->type != FCALL) ? CLIPS_FALSE :             (((struct FunctionDefinition *) fcallexp->value)->sequenceuseok == CLIPS_FALSE))           {                   PrintErrorID("EXPRNPSR",4,CLIPS_FALSE);            PrintCLIPS(WERROR,"$ Sequence operator not a valid argument for ");            PrintCLIPS(WERROR,ValueToString(((struct FunctionDefinition *)                               fcallexp->value)->callFunctionName));            PrintCLIPS(WERROR,".\n");            return(TRUE);           }         if (fcallexp->value != expcall)           {            exp = GenConstant(fcallexp->type,fcallexp->value);            exp->argList = fcallexp->argList;            exp->nextArg = NULL;            fcallexp->type = FCALL;            fcallexp->value = expcall;            fcallexp->argList = exp;           }         if (actions->value != expmult)           {            exp = GenConstant(SF_VARIABLE,actions->value);            if (actions->type == MF_GBL_VARIABLE)              exp->type = GBL_VARIABLE;            actions->argList = exp;            actions->type = FCALL;            actions->value = expmult;           }        }      if (actions->argList != NULL)        {         if ((actions->type == GCALL) ||             (actions->type == PCALL) ||             (actions->type == FCALL))           exp = actions;         else           exp = fcallexp;         if (ReplaceSequenceExpansionOps(actions->argList,exp,expcall,expmult))           return(TRUE);        }      actions = actions->nextArg;     }   return(FALSE);  }  /*************************************************//* PushRtnBrkContexts: Saves the current context *//*   for the break/return functions.             *//*************************************************/globle VOID PushRtnBrkContexts()  {   SAVED_CONTEXTS *svtmp;      svtmp = get_struct(saved_contexts);   svtmp->rtn = ReturnContext;   svtmp->brk = BreakContext;   svtmp->nxt = svContexts;   svContexts = svtmp;  }  /***************************************************//* PopRtnBrkContexts: Restores the current context *//*   for the break/return functions.               *//***************************************************/globle VOID PopRtnBrkContexts()  {   SAVED_CONTEXTS *svtmp;      ReturnContext = svContexts->rtn;   BreakContext = svContexts->brk;   svtmp = svContexts;   svContexts = svContexts->nxt;   rtn_struct(saved_contexts,svtmp);  }/*****************************************************************//* CheckExpressionAgainstRestrictions: Compares the arguments to *//*   a function to the set of restrictions for that function to  *//*   determine if any incompatibilities exist. If so, the value  *//*   TRUE is returned, otherwise FALSE is returned.              *//*****************************************************************/globle int CheckExpressionAgainstRestrictions(theExpression,restrictions,functionName)  struct expr *theExpression;  char *restrictions;  char *functionName;  {   char theChar[2];   int i = 0, j = 1;   int number1, number2;   int argCount;   char defaultRestriction, argRestriction;   struct expr *argPtr;   int theRestriction;      theChar[0] = '0';    theChar[1] = '\0';      /*============================================*/   /* If there are no restrictions, then there's */   /* no need to check the function.             */   /*============================================*/      if (restrictions == NULL) return(CLIPS_FALSE);   /*=========================================*/   /* Count the number of function arguments. */   /*=========================================*/      argCount = CountArguments(theExpression->argList);   /*======================================*/   /* Get the minimum number of arguments. */   /*======================================*/   theChar[0] = restrictions[i++];   if (isdigit(theChar[0]))     { number1 = atoi(theChar); }   else if (theChar[0] == '*')     { number1 = -1; }   else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -