📄 scanner.c
字号:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.05 04/09/97 */ /* */ /* 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 _CLIPS_STDIO_#include <string.h>#include <limits.h>#include "setup.h"#include "constant.h"#include "router.h"#include "symbol.h"#include "utility.h"#include "clipsmem.h"#include "scanner.h"#if ANSI_COMPILER#include <stdlib.h>#elseextern double atof();extern long atol();#endif/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/#if ANSI_COMPILER static VOID *ScanSymbol(char *,int,int *); static VOID *ScanString(char *); static VOID ScanNumber(char *,struct token *);#else static VOID *ScanSymbol(); static VOID *ScanString(); static VOID ScanNumber();#endif/***************************************//* LOCAL INTERNAL VARIABLE DEFINITIONS *//***************************************/ static char *GlobalString = NULL; static int GlobalMax = 0; static int GlobalPos = 0; static long LineCount = 0;/***************************************//* LOCAL INTERNAL VARIABLE DEFINITIONS *//***************************************/ globle int IgnoreCompletionErrors = CLIPS_FALSE;/***********************************************************************//* 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(logicalName,theToken) char *logicalName; struct token *theToken; { int inchar; int type; /*=======================================*/ /* Set Unknown default values for token. */ /*=======================================*/ theToken->type = UNKNOWN_VALUE; theToken->value = NULL; theToken->printForm = "unknown"; GlobalPos = 0; GlobalMax = 0; /*==============================================*/ /* Remove all white space before processing the */ /* GetToken() request. */ /*==============================================*/ inchar = GetcCLIPS(logicalName); while ((inchar == ' ') || (inchar == '\n') || (inchar == '\f') || (inchar == '\r') || (inchar == ';') || (inchar == '\t')) { /*=======================*/ /* Remove comment lines. */ /*=======================*/ if (inchar == ';') { inchar = GetcCLIPS(logicalName); while ((inchar != '\n') && (inchar != '\r') && (inchar != EOF) ) { inchar = GetcCLIPS(logicalName); } } inchar = GetcCLIPS(logicalName); } /*==========================*/ /* Process Symbolic Tokens. */ /*==========================*/ if (isalpha(inchar)) { theToken->type = SYMBOL; UngetcCLIPS(inchar,logicalName); theToken->value = (VOID *) ScanSymbol(logicalName,0,&type); theToken->printForm = ValueToString(theToken->value); } /*===============================================*/ /* Process Number Tokens beginning with a digit. */ /*===============================================*/ else if (isdigit(inchar)) { UngetcCLIPS(inchar,logicalName); ScanNumber(logicalName,theToken); } else switch (inchar) { /*========================*/ /* Process String Tokens. */ /*========================*/ case '"': theToken->value = (VOID *) ScanString(logicalName); theToken->type = STRING; theToken->printForm = StringPrintForm(ValueToString(theToken->value)); break; /*=======================================*/ /* Process Tokens that might be numbers. */ /*=======================================*/ case '-': case '.': case '+': UngetcCLIPS(inchar,logicalName); ScanNumber(logicalName,theToken); break; /*===================================*/ /* Process ? and ?<variable> Tokens. */ /*===================================*/ case '?': inchar = GetcCLIPS(logicalName); if (isalpha(inchar)#if DEFGLOBAL_CONSTRUCT || (inchar == '*'))#else )#endif { UngetcCLIPS(inchar,logicalName); theToken->value = (VOID *) ScanSymbol(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] == '*')) { int count; theToken->type = GBL_VARIABLE; theToken->printForm = AppendStrings("?",ValueToString(theToken->value)); count = strlen(GlobalString); GlobalString[count-1] = EOS; theToken->value = AddSymbol(GlobalString+1); GlobalString[count-1] = (char) inchar; } else#endif theToken->printForm = AppendStrings("?",ValueToString(theToken->value)); } else { theToken->type = SF_WILDCARD; theToken->value = (VOID *) AddSymbol("?"); UngetcCLIPS(inchar,logicalName); theToken->printForm = "?"; } break; /*=====================================*/ /* Process $? and $?<variable> Tokens. */ /*=====================================*/ case '$': if ((inchar = GetcCLIPS(logicalName)) == '?') { inchar = GetcCLIPS(logicalName); if (isalpha(inchar)#if DEFGLOBAL_CONSTRUCT || (inchar == '*'))#else )#endif { UngetcCLIPS(inchar,logicalName); theToken->value = (VOID *) ScanSymbol(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] == '*')) { int count; theToken->type = MF_GBL_VARIABLE; theToken->printForm = AppendStrings("$?",ValueToString(theToken->value)); count = strlen(GlobalString); GlobalString[count-1] = EOS; theToken->value = AddSymbol(GlobalString+1); GlobalString[count-1] = (char) inchar; } else#endif theToken->printForm = AppendStrings("$?",ValueToString(theToken->value)); } else { theToken->type = MF_WILDCARD; theToken->value = (VOID *) AddSymbol("$?"); theToken->printForm = "$?"; UngetcCLIPS(inchar,logicalName); } } else { theToken->type = SYMBOL; GlobalString = ExpandStringWithChar('$',GlobalString,&GlobalPos,&GlobalMax,GlobalMax+80); UngetcCLIPS(inchar,logicalName); theToken->value = (VOID *) ScanSymbol(logicalName,1,&type); theToken->printForm = ValueToString(theToken->value); } break; /*============================*/ /* Symbols beginning with '<' */ /*============================*/ case '<': theToken->type = SYMBOL; GlobalString = ExpandStringWithChar('<',GlobalString,&GlobalPos,&GlobalMax,GlobalMax+80); theToken->value = (VOID *) ScanSymbol(logicalName,1,&type); theToken->printForm = ValueToString(theToken->value); break; /*=============================================*/ /* Process "(", ")", "~", "|", and "&" Tokens. */ /*=============================================*/ case '(': theToken->type = LPAREN; theToken->value = (VOID *) AddSymbol("("); theToken->printForm = "("; break; case ')': theToken->type= RPAREN; theToken->value = (VOID *) AddSymbol(")"); theToken->printForm = ")"; break; case '~': theToken->type = NOT_CONSTRAINT; theToken->value = (VOID *) AddSymbol("~"); theToken->printForm = "~"; break; case '|': theToken->type = OR_CONSTRAINT; theToken->value = (VOID *) AddSymbol("|"); theToken->printForm = "|"; break; case '&': theToken->type = AND_CONSTRAINT; theToken->value = (VOID *) AddSymbol("&"); theToken->printForm = "&"; break; /*============================*/ /* Process End-of-File Token. */ /*============================*/ case EOF: case 0: case 3: theToken->type = STOP; theToken->value = (VOID *) AddSymbol("stop"); theToken->printForm = ""; break; /*=======================*/ /* Process Other Tokens. */ /*=======================*/ default: if (isprint(inchar)) { UngetcCLIPS(inchar,logicalName); theToken->value = (VOID *) ScanSymbol(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("["); SavePPBuffer(theToken->printForm); SavePPBuffer("]"); } else { SavePPBuffer(theToken->printForm); }#endif /*=========================================================*/ /* Return the temporary memory used in scanning the token. */ /*=========================================================*/ if (GlobalString != NULL) { rm(GlobalString,GlobalMax); GlobalString = NULL; } return; }/*************************************//* ScanSymbol: Scans a symbol token. *//*************************************/static VOID *ScanSymbol(logicalName,count,type) char *logicalName; int count; int *type; { int inchar;#if OBJECT_SYSTEM VOID *symbol;#endif /*=====================================*/ /* Scan characters and add them to the */ /* symbol until a delimiter is found. */ /*=====================================*/ inchar = GetcCLIPS(logicalName);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -