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

📄 cscanner.c

📁 3D游戏场景编辑器
💻 C
字号:
/****************************************************************************************/
/*  CSCANNER.C                                                                          */
/*                                                                                      */
/*  Author: Eli Boling                                                                  */
/*  Description: C Language specific scanner actions                                    */
/*                                                                                      */
/*  The contents of this file are subject to the Genesis3D Public License               */
/*  Version 1.01 (the "License"); you may not use this file except in                   */
/*  compliance with the License. You may obtain a copy of the License at                */
/*  http://www.genesis3d.com                                                            */
/*                                                                                      */
/*  Software distributed under the License is distributed on an "AS IS"                 */
/*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
/*  the License for the specific language governing rights and limitations              */
/*  under the License.                                                                  */
/*                                                                                      */
/*  The Original Code is Genesis3D, released March 25, 1999.                            */
/*Genesis3D Version 1.1 released November 15, 1999                            */
/*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved           */
/*                                                                                      */
/****************************************************************************************/
#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<assert.h>
#include    <ctype.h>

#include	"CScanner.h"
#include	"util.h"
#include	"ram.h"

#if _MSC_VER
	// disable "unknown pragma" warning for VC
	#pragma warning (disable:4068)
#endif

#define			SkipChar	0
static	int		IllegalChar(Scanner *s, Scanner_Token *t, int c);
static	int		CopyChar(Scanner *s, Scanner_Token *t, int c);

static	int		genIDEN(Scanner *s, Scanner_Token *t, int c);
static	int		genLITERALSTRING(Scanner *s, Scanner_Token *t, int c);
static	int		genICON(Scanner *s, Scanner_Token *t, int c);
static	int		genFCON(Scanner *s, Scanner_Token *t, int c);

static	int		genEOF(Scanner *s, Scanner_Token *t, int c);
static	int		genLBRACE(Scanner *s, Scanner_Token *t, int c);
static	int		genRBRACE(Scanner *s, Scanner_Token *t, int c);
static	int		genLPAREN(Scanner *s, Scanner_Token *t, int c);
static	int		genRPAREN(Scanner *s, Scanner_Token *t, int c);
static	int		genSEMI(Scanner *s, Scanner_Token *t, int c);
static	int		genDOT(Scanner *s, Scanner_Token *t, int c);
static	int		genCOMMA(Scanner *s, Scanner_Token *t, int c);
static	int		genSLASH(Scanner *s, Scanner_Token *t, int c);
static	int		genHYPHEN(Scanner *s, Scanner_Token *t, int c);
static	int		genPLUS(Scanner *s, Scanner_Token *t, int c);
static	int		genBANG(Scanner *s, Scanner_Token *t, int c);
static	int		genTILDE(Scanner *s, Scanner_Token *t, int c);
static	int		genSHARP(Scanner *s, Scanner_Token *t, int c);
static	int		genMOD(Scanner *s, Scanner_Token *t, int c);
static	int		genHAT(Scanner *s, Scanner_Token *t, int c);
static	int		genAMPER(Scanner *s, Scanner_Token *t, int c);
static	int		genSTAR(Scanner *s, Scanner_Token *t, int c);
static	int		genEQUAL(Scanner *s, Scanner_Token *t, int c);


static	Scanner_CharMap	SNull[257];
static	Scanner_CharMap	SLitString[257];
static	Scanner_CharMap	SIden[257];
static	Scanner_CharMap	SNumber[257];
static	Scanner_CharMap	SMaybeHexNumber[257];
static	Scanner_CharMap SHexNumber[257];
static	Scanner_CharMap	SFloat[257];
static	Scanner_CharMap	SMaybeComment[257];
static	Scanner_CharMap	SMaybeEndComment[257];
static	Scanner_CharMap	SOneLineComment[257];
static	Scanner_CharMap	SComment[257];

#define	TERMINATING_CHARS(action) \
	{ ',', ',' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\
	{ '.', '.' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\
	{ '{', '{' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\
	{ '}', '}' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\
	{ '(', '(' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\
	{ ')', ')' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\
	{ ';', ';' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\
	{ '_', '_' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\
	{ '+', '+' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\
	{ '-', '-' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\
	{ '/', '/' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\
	{ '^', '^' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\
	{ '|', '|' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\
	{ '=', '=' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\
	{ '&', '&' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\
	{ '#', '#' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\
	{ '!', '!' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\
	{ '~', '~' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\
	{ 'A', 'Z' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\
	{ 'a', 'z' + 1, SNull, action   , F_CM_PUSHBACKCHAR },	\

static	Scanner_CharMapInitializer	SNullInitializer[] =
{
	{   0,   9, 	SNull, IllegalChar , 0},
	{   9,  10, 	SNull,    SkipChar , 0},
	{  10,  11, 	SNull,    SkipChar , F_CM_BUMPLINENUMBER},
	{  11,  13, 	SNull, IllegalChar , 0},
	{  13,  14, 	SNull,    SkipChar , 0},
	{  14,  32, 	SNull, IllegalChar , 0},
	{  32,  33, 	SNull,    SkipChar , 0},
	{ '_', '_' + 1, SIden,    CopyChar , 0},
	{ 'A', 'Z' + 1, SIden,    CopyChar , 0},
	{ 'a', 'z' + 1, SIden,    CopyChar , 0},
	{ '0', '9' + 1, SNumber,  CopyChar , 0},
	{ '0', '0' + 1, SMaybeHexNumber, CopyChar, 0},
	{ '{', '{' + 1, SNull,    genLBRACE , 0},
	{ '}', '}' + 1, SNull,    genRBRACE , 0},
	{ '(', '(' + 1, SNull,    genLPAREN , 0},
	{ ')', ')' + 1, SNull,    genRPAREN , 0},
	{ ';', ';' + 1, SNull,    genSEMI , 0},
	{ '.', '.' + 1, SNull,    genDOT , 0},
	{ ',', ',' + 1, SNull,    genCOMMA , 0},
	{ '-', '-' + 1, SNull,    genHYPHEN , 0},
	{ '+', '+' + 1, SNull,    genPLUS , 0},
	{ '!', '!' + 1, SNull,    genBANG , 0},
	{ '~', '~' + 1, SNull,    genTILDE , 0},
	{ '#', '#' + 1, SNull,    genSHARP , 0},
	{ '%', '%' + 1, SNull,    genMOD , 0},
	{ '^', '^' + 1, SNull,    genHAT , 0},
	{ '&', '&' + 1, SNull,    genAMPER , 0},
	{ '*', '*' + 1, SNull,    genSTAR , 0},
	{ '=', '=' + 1, SNull,    genEQUAL , 0},
	{ '/', '/' + 1, SMaybeComment, SkipChar, 0},
	{ '"', '"' + 1, SLitString,  SkipChar , 0},
	{ 127, 256, 	SNull, IllegalChar , 0},
	{ 256, 257, 	SNull,    genEOF , 0}
};

static	Scanner_CharMapInitializer	SLitStringInitializer[] =
{
	
	{   0, 256,		SLitString, CopyChar , 0},
	{  13,	14,		SLitString, SkipChar,  0},
	{ '"', '"' + 1,	SNull,		genLITERALSTRING, 0 },
	{ 256, 257, 	SNull,		IllegalChar, 0}
};

static	Scanner_CharMapInitializer	SMaybeCommentInitializer[] =
{
	
	{   0,   256,	SNull, 				genSLASH, 	F_CM_PUSHBACKCHAR},
	{ '*', '*' + 1, SComment,			SkipChar, 	0 },
	{ '/', '/' + 1,	SOneLineComment,	SkipChar, 	0 },
	{ 256, 257, 	SNull, 				IllegalChar,0}
};

static	Scanner_CharMapInitializer	SOneLineCommentInitializer[] =
{
	{   0,   256,	SOneLineComment, 	SkipChar, 	0 },
	{  10,    11,	SNull,				SkipChar, 	F_CM_BUMPLINENUMBER },
	{ 256, 257, 	SNull, 				IllegalChar,0}
};

static	Scanner_CharMapInitializer	SCommentInitializer[] =
{
	{   0,   256,	SComment, 			SkipChar, 	0},
	{  10,    11,	SComment,			SkipChar, 	F_CM_BUMPLINENUMBER },
	{ '*', '*' + 1, SMaybeEndComment,	SkipChar, 	0 },
	{ 256, 257, 	SNull, 				IllegalChar,0}
};

static	Scanner_CharMapInitializer	SMaybeEndCommentInitializer[] =
{
	{   0,   256,	SComment, 			SkipChar, 	0 },
	{  10,    11,	SComment,			SkipChar, 	F_CM_BUMPLINENUMBER },
	{ '/', '/' + 1, SNull,				SkipChar, 	0 },
	{ 256, 257, 	SNull, 				IllegalChar,0}
};

static	Scanner_CharMapInitializer	SIdenInitializer[] =
{
	TERMINATING_CHARS(genIDEN)

	{   0,   9,		SNull, IllegalChar , 0},
	{   9,  10, 	SNull, genIDEN , 0},
	{  10,  11, 	SNull, genIDEN , F_CM_BUMPLINENUMBER},
	{  11,  13, 	SNull, IllegalChar , 0},
	{  13,  14, 	SNull,     genIDEN , 0},
	{  14,  32, 	SNull, IllegalChar , 0},
	{  32,  33, 	SNull,     genIDEN , 0},
	{ ';', ';' + 1, SNull,     genIDEN , F_CM_PUSHBACKCHAR},
	{ '(', '(' + 1, SNull,     genIDEN , F_CM_PUSHBACKCHAR},
	{ ')', ')' + 1, SNull,     genIDEN , F_CM_PUSHBACKCHAR},
	{ '{', '{' + 1, SNull,     genIDEN , F_CM_PUSHBACKCHAR},
	{ '}', '}' + 1, SNull,     genIDEN , F_CM_PUSHBACKCHAR},
	{ '_', '_' + 1, SIden,    CopyChar , 0},
	{ 'A', 'Z' + 1, SIden,    CopyChar , 0},
	{ 'a', 'z' + 1, SIden,    CopyChar , 0},
	{ '0', '9' + 1, SIden,    CopyChar , 0},
	{ 127, 256, 	SNull, IllegalChar , 0},
	{ 256, 257, 	SNull, genIDEN	   , 0}
};

static	Scanner_CharMapInitializer	SNumberInitializer[] =
{
	TERMINATING_CHARS(genICON)

	{   0,   9,		SNull, 	IllegalChar , 0},
	{   9,  10, 	SNull,  genICON , 0},
	{  10,  11, 	SNull,  genICON , F_CM_BUMPLINENUMBER},
	{  11,  13, 	SNull, 	IllegalChar , 0},
	{  13,  14, 	SNull, 	genICON , 0},
	{  14,  32, 	SNull, 	IllegalChar , 0},
	{ '0', '9' + 1, SNumber,   CopyChar , 0},
	{ '.', '.' + 1, SFloat,    CopyChar , 0},
	{ 127, 256, 	SNull, 	IllegalChar , 0},
	{ 256, 257, 	SNull, genICON      , 0}
};

static	Scanner_CharMapInitializer	SMaybeHexNumberInitializer[] =
{
	TERMINATING_CHARS(genICON)
	{   9,  10, 	SNull,  genICON , 0},
	{  10,  11, 	SNull,  genICON , F_CM_BUMPLINENUMBER},
	{  13,  14,		SNull,	genICON , 0},
	{ 'x', 'x' + 1, SHexNumber, CopyChar, 0},
	{ 'X', 'X' + 1, SHexNumber, CopyChar, 0},
	{ '0', '9' + 1, SNumber, CopyChar , 0},
// if you want to do Octal, then 0-7 here would go to octal, rather than decimal
	{ '.', '.' + 1, SFloat, CopyChar, 0},
	{ 256, 257, 	SNull, genICON      , 0}
};

static Scanner_CharMapInitializer SHexNumberInitializer[] =
{
	TERMINATING_CHARS(genICON)
	{   9,  10, 	SNull,  genICON , 0},
	{  10,  11, 	SNull,  genICON , F_CM_BUMPLINENUMBER},
	{  13,  14,		SNull,	genICON , 0},
	{ '0', '9' + 1, SHexNumber, CopyChar, 0},
	{ 'A', 'F' + 1, SHexNumber, CopyChar, 0},
	{ 'a', 'f' + 1, SHexNumber, CopyChar, 0},
	{ 256, 257, 	SNull, genICON      , 0}
};

static	Scanner_CharMapInitializer	SFloatInitializer[] =
{
	TERMINATING_CHARS(genFCON)

	{   9,  10, 	SNull, genICON , 0},
	{  10,  11, 	SNull,    genFCON , F_CM_BUMPLINENUMBER},
	{  13,  14,		SNull, genFCON , 0},
	{ '0', '9' + 1, SFloat,   CopyChar , 0},
	{ 'f', 'f' + 1, SNull, genFCON      , 0},
	{ 256, 257, 	SNull, genFCON      , 0}
};

static Scanner_StateInitializer StateInitializers[] = 
{
	STATEINITIALIZER(SNull, 	 		SNullInitializer),
	STATEINITIALIZER(SLitString, 		SLitStringInitializer),
	STATEINITIALIZER(SIden, 			SIdenInitializer),
	STATEINITIALIZER(SNumber, 			SNumberInitializer),
	STATEINITIALIZER(SMaybeHexNumber,	SMaybeHexNumberInitializer),
	STATEINITIALIZER(SHexNumber,		SHexNumberInitializer),
	STATEINITIALIZER(SFloat,			SFloatInitializer),
	STATEINITIALIZER(SMaybeComment, 	SMaybeCommentInitializer),
	STATEINITIALIZER(SMaybeEndComment, 	SMaybeEndCommentInitializer),
	STATEINITIALIZER(SOneLineComment,	SOneLineCommentInitializer),
	STATEINITIALIZER(SComment, 			SCommentInitializer),
};

static const int NumInitializers = (sizeof (StateInitializers) / sizeof (Scanner_StateInitializer));


Scanner *CScanner_Create (void)
{
	int	i;
	int	j;

	// initialize the tables
	for	(i = 0; i < NumInitializers; i++)
	{
		Scanner_CharMap *	cm;

		cm = StateInitializers[i].siMap;
		for	(j = 0; j < 256; j++)
		{
			cm[j].cmNextState = SNull;
			cm[j].cmAction	  = IllegalChar;
		}

		for	(j = 0; j < StateInitializers[i].siInitializerCount; j++)
		{
			Scanner_CharMapInitializer *	cmi;
			int						k;

			cmi = &(StateInitializers[i].siMapInitializer[j]);
			for	(k = cmi->cmiStartChar; k < cmi->cmiEndChar; k++)
			{
				cm[k].cmNextState = cmi->cmiNextState;
				cm[k].cmAction	  = cmi->cmiAction;
				cm[k].cmFlags	  = cmi->cmiFlags;
			}
		}
	}

	return Scanner_Create (StateInitializers, NumInitializers, SNull);
}


#pragma argsused
#pragma warning (disable:4100)
static	int	IllegalChar(Scanner *s, Scanner_Token *t, int c)
{
	t->tKind = TK_ERROR;
	return 1;
}
#pragma warning (default:4100)

#pragma argsused
#pragma warning (disable:4100)
static	int	CopyChar(Scanner *s, Scanner_Token *t, int c)
{
	assert(c != EOF);
	*t->tTokenDataPtr++ = (char)c;
	return 0;
}
#pragma warning (default:4100)

#pragma argsused
#pragma warning (disable:4100)
static	int	genIDEN(Scanner *s, Scanner_Token *t, int c)
{
	t->tKind = TK_IDEN;
	*t->tTokenDataPtr = 0;
	t->tIden = Scanner_GenerateIdentifier (s, t->tTokenData, (t->tTokenDataPtr - t->tTokenData));
	return 1;
}
#pragma warning (default:4100)

#pragma argsused
#pragma warning (disable:4100)
static	int	genLITERALSTRING(Scanner *s, Scanner_Token *t, int c)
{
	t->tKind = TK_LITERALSTRING;
	*t->tTokenDataPtr = 0;
	return 1;
}
#pragma warning (default:4100)

#pragma argsused
#pragma warning (disable:4100)
static	int	genICON(Scanner *s, Scanner_Token *t, int c)
{
	t->tKind = TK_ICON;
	*t->tTokenDataPtr = 0;
	if	(t->tTokenData[1] == 'x' || t->tTokenData[1] == 'X')
		t->tICONValue = Util_htoi(t->tTokenData);
	else
		t->tICONValue = atoi(t->tTokenData);
	return 1;
}
#pragma warning (default:4100)

#pragma argsused
#pragma warning (disable:4100)
static	int	genFCON(Scanner *s, Scanner_Token *t, int c)
{
	t->tKind = TK_FCON;
	*t->tTokenDataPtr = 0;
	t->tFCONValue = (float)atof(t->tTokenData);
	return 1;
}
#pragma warning (default:4100)

#ifdef __BORLANDC__
	// turn off warnings
	#pragma option -w-
#endif

#if _MSC_VER
	#pragma warning (disable: 4100)
#endif

#define	ONESHOT(func, token) \
	static	int	func(Scanner *s, Scanner_Token *t, int c)	\
	{														\
		t->tKind = token;									\
		return 1;											\
	}

ONESHOT(genEOF, TK_EOF)
ONESHOT(genLBRACE, TK_LBRACE)
ONESHOT(genRBRACE, TK_RBRACE)
ONESHOT(genLPAREN, TK_LPAREN)
ONESHOT(genRPAREN, TK_RPAREN)
ONESHOT(genSEMI, TK_SEMI)
ONESHOT(genDOT, TK_DOT)
ONESHOT(genCOMMA, TK_COMMA)
ONESHOT(genSLASH, TK_SLASH)
ONESHOT(genHYPHEN, TK_HYPHEN)
ONESHOT(genPLUS, TK_PLUS)
ONESHOT(genTILDE, TK_TILDE)
ONESHOT(genSHARP, TK_SHARP)
ONESHOT(genMOD, TK_MOD)
ONESHOT(genHAT, TK_HAT)
ONESHOT(genAMPER, TK_AMPER)
ONESHOT(genSTAR, TK_STAR)
ONESHOT(genEQUAL, TK_EQUAL)
ONESHOT(genBANG, TK_BANG)

⌨️ 快捷键说明

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