reaction/code/game/g_parser.h
2013-01-04 13:27:22 +00:00

159 lines
3.6 KiB
C

//-----------------------------------------------------------------------------
//
// $Id$
//
//-----------------------------------------------------------------------------
//
// $Log$
// Revision 1.5 2007/02/03 19:37:19 jbravo
// Adding CVS headers to new files in CVS.
//
//
//-----------------------------------------------------------------------------
#ifndef _G_PARSER_H_
#define _G_PARSER_H_
///////////////////////////////////////////////////////////////
#include "g_local.h"
#define STATE_STACK_SIZE 32
#define SCRIPT_HASH_SIZE 64
typedef struct
{
int top;
void *states[STATE_STACK_SIZE];
} TStateStack;
typedef int (TParseFunc)(char **tokens, TStateStack *stack);
// Makro - this is to shut lcc up :(
#ifndef Q3_VM
typedef TParseFunc *PParseFunc;
#else
#define PParseFunc TParseFunc*
#endif
#define _NULL_T(type) (*(type*)0)
typedef struct _TParseRule
{
const char *keyword;
PParseFunc handler;
struct _TParseRule *next;
} TParseRule;
#define MAX_RULES_IN_STATE 32
typedef struct
{
const char *name;
void *data;
int initialized;
TParseRule *hashTable[SCRIPT_HASH_SIZE];
TParseRule rules[MAX_RULES_IN_STATE];
} TParseState;
#define SCRIPT_STATE(name, data)\
TParseState name = {\
#name, /* state name */ \
data, /* optional data */ \
0, /* uninitialized */ \
{NULL}, /* hash table */
#define ADD_RULE(exp, func) {exp, &func, NULL},
#define END_STATE_MARKER {NULL, (TParseFunc*)0, (TParseRule*)NULL}\
}
#define NO_DATA NULL
typedef enum
{
SHOW_ALL,
SHOW_WARNING,
SHOW_ERROR,
SHOW_NONE
} TErrorLevel;
///////////////////////////////////////////////////////////////
extern int SCRIPT_SHOW_LEVEL;
#define SCRIPT_INFO(level) if (SCRIPT_SHOW_LEVEL <= (level)) {
#define END_SCRIPT_INFO() }
#define NEEDS_TOKENS(num, name)\
char *name[num];\
{\
int TOKEN_INDEX;\
for (TOKEN_INDEX=0; TOKEN_INDEX<num; TOKEN_INDEX++)\
if ( (name[TOKEN_INDEX] = Script_GetToken(SCRIPT_INPUT)) == NULL)\
{\
SCRIPT_INFO(SHOW_ERROR)\
G_Printf("* ERROR: %s requires %d arguments instead of %d.\n", __SCRIPT_FUNC__, num, TOKEN_INDEX);\
END_SCRIPT_INFO();\
return 0;\
}\
}
#define SCRIPT_FUNC_PROTO(name) int name(char **SCRIPT_INPUT, TStateStack *SCRIPT_STACK)
#define SCRIPT_FUNC_TOKENS(name)\
SCRIPT_FUNC_PROTO(name)\
{\
const char *__SCRIPT_FUNC__ = #name;
#define SCRIPT_FUNC(name)\
SCRIPT_FUNC_PROTO(name)\
{
#define END_SCRIPT_FUNC()\
}
#define FOR_EACH_RULE(state, rule)\
{\
int RULE_INDEX;\
TParseRule *rule;\
for (RULE_INDEX=0, rule = &(state).rules[0]; rule->keyword != NULL && rule->handler != NULL; RULE_INDEX++, rule++)
#define END_FOR_RULE() }
///////////////////////////////////////////////////////////////
int Script_PushState(TStateStack *stack, TParseState *state);
int Script_GetTopState(const TStateStack *stack, TParseState **state);
int Script_PopState(TStateStack *stack, TParseState **state);
char* Script_GetToken(char **str);
PParseFunc Script_FindHandler(char *token, TParseState *state);
void Script_ParseString(char *str, TParseState *baseState);
#define SCRIPT_PUSH_STATE(state) Script_PushState(SCRIPT_STACK, &state)
#define SCRIPT_POP_STATE() Script_PopState(SCRIPT_STACK, NULL)
#define SCRIPT_TRANSITION_TO(Dest) Transition_To_##Dest
#define SCRIPT_TRANSITION_FUNC(Dest)\
SCRIPT_FUNC(SCRIPT_TRANSITION_TO(Dest))\
{\
SCRIPT_PUSH_STATE(Dest);\
return 0;\
}\
END_SCRIPT_FUNC()
SCRIPT_FUNC_PROTO(SFN_SkipComment);
SCRIPT_FUNC_PROTO(SFN_SkipLineComment);
SCRIPT_FUNC_PROTO(SFN_SkipToken);
SCRIPT_FUNC_PROTO(SFN_PopState);
///////////////////////////////////////////////////////////////
#endif //_G_PARSER_H_