scanner.c

来自「clips源代码」· C语言 代码 · 共 788 行 · 第 1/2 页

C
788
字号
   /*******************************************************/   /*      "C" Language Integrated Production System      */   /*                                                     */   /*             CLIPS Version 6.20  01/31/02            */   /*                                                     */   /*                    SCANNER MODULE                   */   /*******************************************************//*************************************************************//* Purpose: Routines for scanning lexical tokens from an     *//*   input source.                                           *//*                                                           *//* Principal Programmer(s):                                  *//*      Gary D. Riley                                        *//*                                                           *//* Contributing Programmer(s):                               *//*      Chris Culbert                                        *//*      Brian Donnell                                        *//*                                                           *//* Revision History:                                         *//*                                                           *//*************************************************************/#define _SCANNER_SOURCE_#include <ctype.h>#include <stdio.h>#define _STDIO_INCLUDED_#include <string.h>#include <limits.h>#include "setup.h"#include "constant.h"#include "envrnmnt.h"#include "router.h"#include "symbol.h"#include "utility.h"#include "memalloc.h"#include "scanner.h"#include <stdlib.h>/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/   static void                   *ScanSymbol(void *,char *,int,unsigned short *);   static void                   *ScanString(void *,char *);   static void                    ScanNumber(void *,char *,struct token *);   static void                    DeallocateScannerData(void *);/************************************************//* InitializeScannerData: Allocates environment *//*    data for scanner routines.                *//************************************************/globle void InitializeScannerData(  void *theEnv)  {   AllocateEnvironmentData(theEnv,SCANNER_DATA,sizeof(struct scannerData),DeallocateScannerData);  }  /**************************************************//* DeallocateScannerData: Deallocates environment *//*    data for scanner routines.                  *//**************************************************/static void DeallocateScannerData(  void *theEnv)  {   if (ScannerData(theEnv)->GlobalMax !=  0)     { genfree(theEnv,ScannerData(theEnv)->GlobalString,ScannerData(theEnv)->GlobalMax); }  }/***********************************************************************//* GetToken: Reads next token from the input stream. The pointer to    *//*   the token data structure passed as an argument is set to contain  *//*   the type of token (e.g., symbol, string, integer, etc.), the data *//*   value for the token (i.e., a symbol table location if it is a     *//*   symbol or string, an integer table location if it is an integer), *//*   and the pretty print representation.                              *//***********************************************************************/globle void GetToken( void *theEnv, char *logicalName, struct token *theToken) {   int inchar;   unsigned short type;   /*=======================================*/   /* Set Unknown default values for token. */   /*=======================================*/   theToken->type = UNKNOWN_VALUE;   theToken->value = NULL;   theToken->printForm = "unknown";   ScannerData(theEnv)->GlobalPos = 0;   ScannerData(theEnv)->GlobalMax = 0;   /*==============================================*/   /* Remove all white space before processing the */   /* GetToken() request.                          */   /*==============================================*/   inchar = EnvGetcRouter(theEnv,logicalName);   while ((inchar == ' ') || (inchar == '\n') || (inchar == '\f') ||          (inchar == '\r') || (inchar == ';') || (inchar == '\t'))     {      /*=======================*/      /* Remove comment lines. */      /*=======================*/      if (inchar == ';')        {         inchar = EnvGetcRouter(theEnv,logicalName);         while ((inchar != '\n') && (inchar != '\r') && (inchar != EOF) )           { inchar = EnvGetcRouter(theEnv,logicalName); }        }      inchar = EnvGetcRouter(theEnv,logicalName);     }   /*==========================*/   /* Process Symbolic Tokens. */   /*==========================*/   if (isalpha(inchar))     {      theToken->type = SYMBOL;      EnvUngetcRouter(theEnv,inchar,logicalName);      theToken->value = (void *) ScanSymbol(theEnv,logicalName,0,&type);      theToken->printForm = ValueToString(theToken->value);     }   /*===============================================*/   /* Process Number Tokens beginning with a digit. */   /*===============================================*/   else if (isdigit(inchar))     {      EnvUngetcRouter(theEnv,inchar,logicalName);      ScanNumber(theEnv,logicalName,theToken);     }   else switch (inchar)     {      /*========================*/      /* Process String Tokens. */      /*========================*/      case '"':         theToken->value = (void *) ScanString(theEnv,logicalName);         theToken->type = STRING;         theToken->printForm = StringPrintForm(theEnv,ValueToString(theToken->value));         break;      /*=======================================*/      /* Process Tokens that might be numbers. */      /*=======================================*/      case '-':      case '.':      case '+':         EnvUngetcRouter(theEnv,inchar,logicalName);         ScanNumber(theEnv,logicalName,theToken);         break;      /*===================================*/      /* Process ? and ?<variable> Tokens. */      /*===================================*/       case '?':          inchar = EnvGetcRouter(theEnv,logicalName);          if (isalpha(inchar)#if DEFGLOBAL_CONSTRUCT              || (inchar == '*'))#else              )#endif            {             EnvUngetcRouter(theEnv,inchar,logicalName);             theToken->value = (void *) ScanSymbol(theEnv,logicalName,0,&type);             theToken->type = SF_VARIABLE;#if DEFGLOBAL_CONSTRUCT             if ((ValueToString(theToken->value)[0] == '*') &&                 (((int) strlen(ValueToString(theToken->value))) > 1) &&                 (ValueToString(theToken->value)[strlen(ValueToString(theToken->value)) - 1] == '*'))               {                size_t count;                theToken->type = GBL_VARIABLE;                theToken->printForm = AppendStrings(theEnv,"?",ValueToString(theToken->value));                count = strlen(ScannerData(theEnv)->GlobalString);                ScannerData(theEnv)->GlobalString[count-1] = EOS;                theToken->value = EnvAddSymbol(theEnv,ScannerData(theEnv)->GlobalString+1);                ScannerData(theEnv)->GlobalString[count-1] = (char) inchar;               }             else#endif             theToken->printForm = AppendStrings(theEnv,"?",ValueToString(theToken->value));            }          else            {             theToken->type = SF_WILDCARD;             theToken->value = (void *) EnvAddSymbol(theEnv,"?");             EnvUngetcRouter(theEnv,inchar,logicalName);             theToken->printForm = "?";            }          break;      /*=====================================*/      /* Process $? and $?<variable> Tokens. */      /*=====================================*/      case '$':         if ((inchar = EnvGetcRouter(theEnv,logicalName)) == '?')           {            inchar = EnvGetcRouter(theEnv,logicalName);            if (isalpha(inchar)#if DEFGLOBAL_CONSTRUCT                 || (inchar == '*'))#else                 )#endif              {               EnvUngetcRouter(theEnv,inchar,logicalName);               theToken->value = (void *) ScanSymbol(theEnv,logicalName,0,&type);               theToken->type = MF_VARIABLE;#if DEFGLOBAL_CONSTRUCT             if ((ValueToString(theToken->value)[0] == '*') &&                 ((int) (strlen(ValueToString(theToken->value))) > 1) &&                 (ValueToString(theToken->value)[strlen(ValueToString(theToken->value)) - 1] == '*'))               {                size_t count;                theToken->type = MF_GBL_VARIABLE;                theToken->printForm = AppendStrings(theEnv,"$?",ValueToString(theToken->value));                count = strlen(ScannerData(theEnv)->GlobalString);                ScannerData(theEnv)->GlobalString[count-1] = EOS;                theToken->value = EnvAddSymbol(theEnv,ScannerData(theEnv)->GlobalString+1);                ScannerData(theEnv)->GlobalString[count-1] = (char) inchar;               }             else#endif               theToken->printForm = AppendStrings(theEnv,"$?",ValueToString(theToken->value));              }            else              {               theToken->type = MF_WILDCARD;               theToken->value = (void *) EnvAddSymbol(theEnv,"$?");               theToken->printForm = "$?";               EnvUngetcRouter(theEnv,inchar,logicalName);              }           }         else           {            theToken->type = SYMBOL;            ScannerData(theEnv)->GlobalString = ExpandStringWithChar(theEnv,'$',ScannerData(theEnv)->GlobalString,&ScannerData(theEnv)->GlobalPos,&ScannerData(theEnv)->GlobalMax,ScannerData(theEnv)->GlobalMax+80);            EnvUngetcRouter(theEnv,inchar,logicalName);            theToken->value = (void *) ScanSymbol(theEnv,logicalName,1,&type);            theToken->printForm = ValueToString(theToken->value);           }         break;      /*============================*/      /* Symbols beginning with '<' */      /*============================*/      case '<':         theToken->type = SYMBOL;         ScannerData(theEnv)->GlobalString = ExpandStringWithChar(theEnv,'<',ScannerData(theEnv)->GlobalString,&ScannerData(theEnv)->GlobalPos,&ScannerData(theEnv)->GlobalMax,ScannerData(theEnv)->GlobalMax+80);         theToken->value = (void *) ScanSymbol(theEnv,logicalName,1,&type);         theToken->printForm = ValueToString(theToken->value);         break;      /*=============================================*/      /* Process "(", ")", "~", "|", and "&" Tokens. */      /*=============================================*/      case '(':         theToken->type = LPAREN;         theToken->value = (void *) EnvAddSymbol(theEnv,"(");         theToken->printForm = "(";         break;      case ')':         theToken->type= RPAREN;         theToken->value = (void *) EnvAddSymbol(theEnv,")");         theToken->printForm = ")";         break;      case '~':         theToken->type = NOT_CONSTRAINT;         theToken->value = (void *) EnvAddSymbol(theEnv,"~");         theToken->printForm = "~";         break;      case '|':         theToken->type = OR_CONSTRAINT;         theToken->value = (void *) EnvAddSymbol(theEnv,"|");         theToken->printForm = "|";         break;      case '&':         theToken->type =  AND_CONSTRAINT;         theToken->value = (void *) EnvAddSymbol(theEnv,"&");         theToken->printForm = "&";         break;      /*============================*/      /* Process End-of-File Token. */      /*============================*/      case EOF:      case 0:      case 3:         theToken->type = STOP;         theToken->value = (void *) EnvAddSymbol(theEnv,"stop");         theToken->printForm = "";         break;      /*=======================*/      /* Process Other Tokens. */      /*=======================*/      default:         if (isprint(inchar))           {            EnvUngetcRouter(theEnv,inchar,logicalName);            theToken->value = (void *) ScanSymbol(theEnv,logicalName,0,&type);            theToken->type = type;            theToken->printForm = ValueToString(theToken->value);           }         else           { theToken->printForm = "<<<unprintable character>>>"; }         break;     }   /*===============================================*/   /* Put the new token in the pretty print buffer. */   /*===============================================*/#if (! RUN_TIME) && (! BLOAD_ONLY)   if (theToken->type == INSTANCE_NAME)     {      SavePPBuffer(theEnv,"[");      SavePPBuffer(theEnv,theToken->printForm);      SavePPBuffer(theEnv,"]");     }   else     { SavePPBuffer(theEnv,theToken->printForm); }#endif   /*=========================================================*/   /* Return the temporary memory used in scanning the token. */   /*=========================================================*/   if (ScannerData(theEnv)->GlobalString != NULL)     {      rm(theEnv,ScannerData(theEnv)->GlobalString,ScannerData(theEnv)->GlobalMax);      ScannerData(theEnv)->GlobalString = NULL;      ScannerData(theEnv)->GlobalMax = 0;      ScannerData(theEnv)->GlobalPos = 0;     }   return;  }/*************************************//* ScanSymbol: Scans a symbol token. *//*************************************/static void *ScanSymbol(  void *theEnv,  char *logicalName,  int count,  unsigned short *type)  {   int inchar;#if OBJECT_SYSTEM   void *symbol;#endif   /*=====================================*/   /* Scan characters and add them to the */   /* symbol until a delimiter is found.  */   /*=====================================*/   inchar = EnvGetcRouter(theEnv,logicalName);   while ( (inchar != '<') && (inchar != '"') &&           (inchar != '(') && (inchar != ')') &&           (inchar != '&') && (inchar != '|') && (inchar != '~') &&           (inchar != ' ') && (inchar != ';') &&           isprint(inchar) )     {

⌨️ 快捷键说明

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