mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-01-18 14:21:36 +00:00
Fixed parsing issues, added some parser tests.
This commit is contained in:
parent
dfa3126233
commit
02e9098d3d
8 changed files with 93 additions and 64 deletions
12
alloc.c
12
alloc.c
|
@ -52,15 +52,3 @@ void memory_d(void *ptrn, unsigned int line, const char *file) {
|
|||
printf("[MEM] released: %08u (bytes) at %s:%u\n", info->byte, file, line);
|
||||
free(data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure the macros are not already defined otherwise the memory
|
||||
* tracker will fail. I hate trying to fix macro bugs, this should
|
||||
* help stop any of that from occuring.
|
||||
*/
|
||||
#ifdef mem_a
|
||||
#undef mem_a
|
||||
#endif
|
||||
#ifdef mem_d
|
||||
#undef mem_d
|
||||
#endif
|
||||
|
|
21
gmqcc.h
21
gmqcc.h
|
@ -155,21 +155,23 @@ struct lex_file {
|
|||
#define TOKEN_GOTO 7
|
||||
#define TOKEN_FOR 8 // extension
|
||||
#define TOKEN_TYPEDEF 9 // extension
|
||||
#define TOKEN_VOID 10
|
||||
#define TOKEN_STRING 11
|
||||
#define TOKEN_FLOAT 12
|
||||
#define TOKEN_VECTOR 13
|
||||
#define TOKEN_ENTITY 14
|
||||
|
||||
|
||||
#define TOKEN_FLOAT 110
|
||||
#define TOKEN_VECTOR 111
|
||||
#define TOKEN_STRING 112
|
||||
#define TOKEN_ENTITY 113
|
||||
#define TOKEN_VOID 114
|
||||
|
||||
/*
|
||||
* Lexer state constants, these are numbers for where exactly in
|
||||
* the lexing the lexer is at. Or where it decided to stop if a lexer
|
||||
* error occurs.
|
||||
*/
|
||||
#define LEX_COMMENT 128 /* higher than ascii */
|
||||
#define LEX_CHRLIT 129
|
||||
#define LEX_STRLIT 130
|
||||
#define LEX_IDENT 131
|
||||
#define LEX_COMMENT 1128 /* higher than ascii */
|
||||
#define LEX_CHRLIT 1129
|
||||
#define LEX_STRLIT 1130
|
||||
#define LEX_IDENT 1131
|
||||
|
||||
int lex_token(struct lex_file *);
|
||||
void lex_reset(struct lex_file *);
|
||||
|
@ -197,6 +199,7 @@ typedef struct typedef_node_t {
|
|||
} typedef_node;
|
||||
|
||||
void typedef_init();
|
||||
void typedef_clear();
|
||||
typedef_node *typedef_find(const char *);
|
||||
int typedef_add (const char *, const char *);
|
||||
|
||||
|
|
31
lex.c
31
lex.c
|
@ -34,14 +34,7 @@
|
|||
static const char *const lex_keywords[] = {
|
||||
"do", "else", "if", "while",
|
||||
"break", "continue", "return", "goto",
|
||||
"for", "typedef",
|
||||
|
||||
/* types */
|
||||
"void",
|
||||
"string",
|
||||
"float",
|
||||
"vector",
|
||||
"entity",
|
||||
"for", "typedef"
|
||||
};
|
||||
|
||||
struct lex_file *lex_open(FILE *fp) {
|
||||
|
@ -289,12 +282,26 @@ int lex_token(struct lex_file *file) {
|
|||
if (!strncmp(file->lastok, lex_keywords[it], sizeof(lex_keywords[it])))
|
||||
return it;
|
||||
|
||||
/* try a type? */
|
||||
#define TEST_TYPE(X) \
|
||||
do { \
|
||||
if (!strncmp(X, "float", sizeof("float"))) \
|
||||
return TOKEN_FLOAT; \
|
||||
if (!strncmp(X, "vector", sizeof("vector"))) \
|
||||
return TOKEN_VECTOR; \
|
||||
if (!strncmp(X, "string", sizeof("string"))) \
|
||||
return TOKEN_STRING; \
|
||||
if (!strncmp(X, "entity", sizeof("entity"))) \
|
||||
return TOKEN_ENTITY; \
|
||||
if (!strncmp(X, "void" , sizeof("void"))) \
|
||||
return TOKEN_VOID; \
|
||||
} while(0)
|
||||
|
||||
TEST_TYPE(file->lastok);
|
||||
|
||||
/* try the hashtable for typedefs? */
|
||||
if (typedef_find(file->lastok))
|
||||
for (it = 0; it < sizeof(lex_keywords)/sizeof(*lex_keywords); it++)
|
||||
if (!strncmp(typedef_find(file->lastok)->name, lex_keywords[it], sizeof(lex_keywords[it])))
|
||||
return it;
|
||||
|
||||
TEST_TYPE(typedef_find(file->lastok)->name);
|
||||
|
||||
return LEX_IDENT;
|
||||
}
|
||||
|
|
40
parse.c
40
parse.c
|
@ -92,34 +92,12 @@
|
|||
"." , "<" , ">" , "&" , "|" ,
|
||||
#endif
|
||||
|
||||
#define STORE(X) { \
|
||||
int total = fill; \
|
||||
while (total-->0) { \
|
||||
putchar(' '); \
|
||||
} \
|
||||
printf(X); \
|
||||
break; \
|
||||
}
|
||||
#define STORE1(X) { \
|
||||
int total = fill; \
|
||||
while (total-->0) { \
|
||||
putchar(' '); \
|
||||
} \
|
||||
fill += 4; \
|
||||
break; \
|
||||
}
|
||||
#define STORE2(X) { \
|
||||
fill -= 4; \
|
||||
int total = fill; \
|
||||
while (total-->0) { \
|
||||
putchar(' '); \
|
||||
} \
|
||||
printf(X); \
|
||||
break; \
|
||||
#define STORE(X) { \
|
||||
printf(X); \
|
||||
break; \
|
||||
}
|
||||
|
||||
void parse_debug(struct parsenode *tree) {
|
||||
int fill = 0;
|
||||
while (tree) {
|
||||
switch (tree->type) {
|
||||
case PARSE_TYPE_ADD: STORE("OPERATOR: ADD \n");
|
||||
|
@ -195,6 +173,9 @@ void parse_clear(struct parsenode *tree) {
|
|||
tree = tree->next;
|
||||
mem_d (temp);
|
||||
}
|
||||
|
||||
/* free any potential typedefs */
|
||||
typedef_clear();
|
||||
}
|
||||
|
||||
int parse(struct lex_file *file) {
|
||||
|
@ -263,8 +244,13 @@ int parse(struct lex_file *file) {
|
|||
typedef_add(f, t);
|
||||
|
||||
/* free stdup strings */
|
||||
mem_d(f);
|
||||
mem_d(t);
|
||||
//mem_d(f);
|
||||
//mem_d(t);
|
||||
free(f);
|
||||
free(t);
|
||||
|
||||
while (token != '\n')
|
||||
token = lex_token(file);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
22
test/tree.qc
Normal file
22
test/tree.qc
Normal file
|
@ -0,0 +1,22 @@
|
|||
if {
|
||||
if {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
for {
|
||||
if {
|
||||
return 2;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
do {
|
||||
if {
|
||||
break;
|
||||
} else {
|
||||
goto finish;
|
||||
}
|
||||
} while ( )
|
||||
}
|
11
test/typedef.qc
Normal file
11
test/typedef.qc
Normal file
|
@ -0,0 +1,11 @@
|
|||
typedef float my_float;
|
||||
typedef vector my_vector;
|
||||
typedef string my_string;
|
||||
typedef entity my_entity;
|
||||
typedef void my_void;
|
||||
|
||||
my_float type_float;
|
||||
my_vector type_vector;
|
||||
my_string type_string;
|
||||
my_entity type_entity;
|
||||
my_void type_void;
|
5
test/types.qc
Normal file
5
test/types.qc
Normal file
|
@ -0,0 +1,5 @@
|
|||
float type_float;
|
||||
vector type_vector;
|
||||
string type_string;
|
||||
entity type_entity;
|
||||
void type_void;
|
15
typedef.c
15
typedef.c
|
@ -160,6 +160,13 @@ typedef_node *typedef_find(const char *s) {
|
|||
return find;
|
||||
}
|
||||
|
||||
void typedef_clear() {
|
||||
int i;
|
||||
for(i = 1024; i > 0; i--)
|
||||
if(typedef_table[i])
|
||||
mem_d(typedef_table[i]);
|
||||
}
|
||||
|
||||
int typedef_add(const char *from, const char *to) {
|
||||
unsigned int hash = typedef_hash(to);
|
||||
typedef_node *find = typedef_table[hash];
|
||||
|
@ -167,11 +174,11 @@ int typedef_add(const char *from, const char *to) {
|
|||
return error(ERROR_PARSE, "typedef for %s already exists\n", to);
|
||||
|
||||
/* check if the type exists first */
|
||||
if (strncmp(from, "void", sizeof("void")) == 0 ||
|
||||
strncmp(from, "string", sizeof("string")) == 0 ||
|
||||
strncmp(from, "float", sizeof("float")) == 0 ||
|
||||
if (strncmp(from, "float", sizeof("float")) == 0 ||
|
||||
strncmp(from, "vector", sizeof("vector")) == 0 ||
|
||||
strncmp(from, "entity", sizeof("entity")) == 0) {
|
||||
strncmp(from, "string", sizeof("string")) == 0 ||
|
||||
strncmp(from, "entity", sizeof("entity")) == 0 ||
|
||||
strncmp(from, "void", sizeof("void")) == 0) {
|
||||
|
||||
typedef_table[hash] = mem_a(sizeof(typedef_node));
|
||||
typedef_table[hash]->name = strdup(from);
|
||||
|
|
Loading…
Reference in a new issue