mirror of
https://github.com/ReactionQuake3/reaction.git
synced 2024-12-02 00:52:36 +00:00
159 lines
3.6 KiB
C
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_
|