?? scanner.c
字號:
/*******************************************************/ /* "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 + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -