Move parser constants to new file
This commit is contained in:
parent
bf61fcdd30
commit
cf5bef048e
|
@ -5,23 +5,23 @@
|
|||
|
||||
// INTERNAL FUNCTIONS
|
||||
// Information gathering
|
||||
bool existstr(STRINGLIST* strs, char* str);
|
||||
bool existclass(CLASS* c, char* name);
|
||||
bool existstr(STRINGLIST* strs, const char* str);
|
||||
bool existclass(CLASS* c, const char* name);
|
||||
DEBUGINFO* getdebuginfo(OBJ* obj);
|
||||
|
||||
// Error messages
|
||||
void doubledeclaration(char* name, DEBUGINFO* debug, OBJ* other);
|
||||
void ensurenoduplicate(SCOPE* s, char* name, DEBUGINFO* debug);
|
||||
void doubledeclaration(const char* name, DEBUGINFO* debug, OBJ* other);
|
||||
void ensurenoduplicate(SCOPE* s, const char* name, DEBUGINFO* debug);
|
||||
|
||||
// Scope handling
|
||||
void popscope(SCOPE** s); // may be removed
|
||||
|
||||
// Single type getters
|
||||
VARDEC* getvardec(SCOPE* s, char* name);
|
||||
CLASSVARDEC* getclassvardec(SCOPE* s, char* name);
|
||||
VARDEC* getvardec(SCOPE* s, const char* name);
|
||||
CLASSVARDEC* getclassvardec(SCOPE* s, const char* name);
|
||||
|
||||
// Generic getters
|
||||
OBJ* getbynamelist(SCOPE* s, STRINGLIST* names, char** retname);
|
||||
OBJ* getbynamelist(SCOPE* s, STRINGLIST* names, const char** retname);
|
||||
|
||||
// Scope adding
|
||||
void addclassvardec(SCOPE* s, CLASSVARDEC* v);
|
||||
|
@ -31,7 +31,7 @@ void addclass(SCOPE* s, CLASS* c);
|
|||
|
||||
// DEFINITIONS
|
||||
// Information gathering
|
||||
bool existstr(STRINGLIST* strs, char* str) {
|
||||
bool existstr(STRINGLIST* strs, const char* str) {
|
||||
while(strs != NULL) {
|
||||
if(!strcmp(strs->content, str))
|
||||
return true;
|
||||
|
@ -40,7 +40,7 @@ bool existstr(STRINGLIST* strs, char* str) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool existclass(CLASS* c, char* name) {
|
||||
bool existclass(CLASS* c, const char* name) {
|
||||
while(c != NULL) {
|
||||
if(!strcmp(c->name, name))
|
||||
return true;
|
||||
|
@ -77,14 +77,14 @@ VARDEC* tovardec(OBJ* obj) {
|
|||
|
||||
// Error messages
|
||||
|
||||
void doubledeclaration(char* name, DEBUGINFO* debug, OBJ* other) {
|
||||
void doubledeclaration(const char* name, DEBUGINFO* debug, OBJ* other) {
|
||||
DEBUGINFO* debugother = other->getdebug(other);
|
||||
eprintf("Double declaration of '%s' at '%s', line %i; previously defined at '%s', line %i\n",
|
||||
name, debug->file, debug->definedat, debugother->file, debugother->definedat);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void notdeclared(char* name, DEBUGINFO* debug) {
|
||||
void notdeclared(const char* name, DEBUGINFO* debug) {
|
||||
eprintf("'%s' not declared; file '%s', line %i\n", name, debug->file, debug->definedat);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -94,14 +94,14 @@ void invalidparent(SUBROUTCALL* call) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
void ensurenoduplicate(SCOPE* s, char* name, DEBUGINFO* debug) {
|
||||
void ensurenoduplicate(SCOPE* s, const char* name, DEBUGINFO* debug) {
|
||||
OBJ* other = getbyname(s, name);
|
||||
if(other != NULL)
|
||||
doubledeclaration(name, debug, other);
|
||||
}
|
||||
|
||||
void ensurenoduplicates(SCOPE* s, STRINGLIST* names, DEBUGINFO* debug) {
|
||||
char* othername;
|
||||
const char* othername;
|
||||
OBJ* other = getbynamelist(s, names, &othername);
|
||||
if(other != NULL)
|
||||
doubledeclaration(othername, debug, other);
|
||||
|
@ -126,7 +126,7 @@ void popscope(SCOPE** s) { // might be useless
|
|||
}
|
||||
|
||||
// Single type getters
|
||||
VARDEC* getvardec(SCOPE* s, char* name) {
|
||||
VARDEC* getvardec(SCOPE* s, const char* name) {
|
||||
VARDEC* curr = s->vardecs;
|
||||
while(curr != NULL) {
|
||||
if(existstr(curr->names, name))
|
||||
|
@ -138,7 +138,7 @@ VARDEC* getvardec(SCOPE* s, char* name) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
CLASSVARDEC* getclassvardec(SCOPE* s, char* name) {
|
||||
CLASSVARDEC* getclassvardec(SCOPE* s, const char* name) {
|
||||
CLASSVARDEC* curr = s->classvardecs;
|
||||
while(curr != NULL) {
|
||||
if(existstr(curr->base->names, name))
|
||||
|
@ -150,7 +150,7 @@ CLASSVARDEC* getclassvardec(SCOPE* s, char* name) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
SUBROUTDEC* getsubroutdec(SCOPE* s, char* name) {
|
||||
SUBROUTDEC* getsubroutdec(SCOPE* s, const char* name) {
|
||||
SUBROUTDEC* curr = s->subroutines;
|
||||
while(curr != NULL) {
|
||||
if(!strcmp(curr->name, name))
|
||||
|
@ -162,7 +162,7 @@ SUBROUTDEC* getsubroutdec(SCOPE* s, char* name) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
CLASS* getclass(SCOPE* s, char* name) {
|
||||
CLASS* getclass(SCOPE* s, const char* name) {
|
||||
CLASS* curr = s->classes;
|
||||
while(curr != NULL) {
|
||||
if(!strcmp(curr->name, name))
|
||||
|
@ -174,7 +174,7 @@ CLASS* getclass(SCOPE* s, char* name) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
SUBROUTDEC* getsubroutdecfromclass(CLASS* c, char* name) {
|
||||
SUBROUTDEC* getsubroutdecfromclass(CLASS* c, const char* name) {
|
||||
SUBROUTDEC* curr = c->subroutdecs;
|
||||
while(curr != NULL) {
|
||||
if(!strcmp(curr->name, name))
|
||||
|
@ -218,7 +218,7 @@ SUBROUTDEC* getsubroutdecfromcall(SCOPE* s, SUBROUTCALL* call) {
|
|||
}
|
||||
|
||||
// Generic getters
|
||||
OBJ* getbyname(SCOPE* s, char* name) {
|
||||
OBJ* getbyname(SCOPE* s, const char* name) {
|
||||
OBJ* o = (OBJ*)malloc(sizeof(OBJ));
|
||||
|
||||
CLASSVARDEC* cvd = getclassvardec(s, name);
|
||||
|
@ -257,7 +257,7 @@ OBJ* getbyname(SCOPE* s, char* name) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
OBJ* getbynamelist(SCOPE* s, STRINGLIST* names, char** retname) {
|
||||
OBJ* getbynamelist(SCOPE* s, STRINGLIST* names, const char** retname) {
|
||||
while(names != NULL) {
|
||||
OBJ* o = getbyname(s, names->content);
|
||||
if(o != NULL) {
|
||||
|
|
|
@ -42,10 +42,10 @@ void addclasses(SCOPE* s, CLASS* c);
|
|||
SCOPE* mkscope(SCOPE* prev);
|
||||
|
||||
// Single type getters
|
||||
SUBROUTDEC* getsubroutdec(SCOPE* s, char* name);
|
||||
SUBROUTDEC* getsubroutdec(SCOPE* s, const char* name);
|
||||
SUBROUTDEC* getsubroutdecfromcall(SCOPE* s, SUBROUTCALL* call);
|
||||
CLASS* getclass(SCOPE* s, char* name);
|
||||
CLASS* getclass(SCOPE* s, const char* name);
|
||||
|
||||
// Generic getters
|
||||
OBJ* getbyname(SCOPE* s, char* name);
|
||||
OBJ* getbyname(SCOPE* s, const char* name);
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef PARSER_CONSTANTS_H
|
||||
#define PARSER_CONSTANTS_H
|
||||
#include "util.h"
|
||||
|
||||
const char* keywordsarr[] = { "true", "false", "null", "this" };
|
||||
const char* opsarr[] = { "+", "-", "*", "/", "&", "|", "<", ">", "=" };
|
||||
const char* classvartypesarr[] = { "static", "field" };
|
||||
const char* vartypesarr[] = { "int", "char", "boolean" };
|
||||
const char* subroutclassesarr[] = { "constructor", "function", "method" };
|
||||
const char* tokentypesarr[] = { "keyword", "identifier", "symbol", "integerConstant", "stringConstant" };
|
||||
|
||||
#define mkstrlist(name, array) STRINGARRAY name = { .items = array, .size = strcount(array) }
|
||||
mkstrlist(keywordconstants, keywordsarr);
|
||||
mkstrlist(operators, opsarr);
|
||||
mkstrlist(classvartypes, classvartypesarr);
|
||||
mkstrlist(vartypes, vartypesarr);
|
||||
mkstrlist(subroutclasses, subroutclassesarr);
|
||||
mkstrlist(tokentypes, tokentypesarr);
|
||||
#undef mkstrlist
|
||||
#endif
|
56
parser.c
56
parser.c
|
@ -3,6 +3,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "parser.h"
|
||||
#include "parser-constants.h"
|
||||
|
||||
char* parseidentifier(PARSER* p);
|
||||
STATEMENT* parsestatements(PARSER* p);
|
||||
|
@ -10,35 +11,6 @@ SUBROUTCALL* parsesubroutcall(PARSER* p);
|
|||
TERM* parseexpression(PARSER* p);
|
||||
TERM* parseterm(PARSER* p);
|
||||
|
||||
const char* keywordconstants[] = {
|
||||
"true", "false", "null", "this"
|
||||
};
|
||||
const int keywordconstantssize = sizeof(keywordconstants) / sizeof(char*);
|
||||
|
||||
const char* ops[] = {
|
||||
"+", "-", "*", "/", "&", "|", "<", ">", "="
|
||||
};
|
||||
const int opssize = sizeof(ops) / sizeof(char*);
|
||||
|
||||
const char* classvartypes[] = {
|
||||
"static", "field"
|
||||
};
|
||||
const int classvartypessize = sizeof(classvartypes) / sizeof(char*);
|
||||
|
||||
const char* vardectypes[] = {
|
||||
"int", "char", "boolean"
|
||||
};
|
||||
const int vardectypessize = sizeof(vardectypes) / sizeof(char*);
|
||||
|
||||
const char* subroutclasses[] = {
|
||||
"constructor", "function", "method"
|
||||
};
|
||||
const int subroutclassessize = sizeof(subroutclasses) / sizeof(char*);
|
||||
|
||||
const char* tokentypes[] = {
|
||||
"keyword", "identifier", "symbol", "integerConstant", "stringConstant"
|
||||
};
|
||||
|
||||
DEBUGINFO* getdebug(PARSER* p) {
|
||||
DEBUGINFO* d = (DEBUGINFO*)malloc(sizeof(DEBUGINFO));
|
||||
d->file = p->file;
|
||||
|
@ -59,7 +31,7 @@ void restorecp(PARSER* p) {
|
|||
}
|
||||
|
||||
void unexpectedtoken(PARSER* p) {
|
||||
fprintf(stderr, "Unexpected token '%s' (of type %s); line %i, file '%s'\n", p->current->token, tokentypes[p->current->type], p->current->definedat, p->file);
|
||||
fprintf(stderr, "Unexpected token '%s' (of type %s); line %i, file '%s'\n", p->current->token, tokentypes.items[p->current->type], p->current->definedat, p->file);
|
||||
}
|
||||
|
||||
void unexpected(PARSER* p) {
|
||||
|
@ -75,7 +47,7 @@ void checkcontent(PARSER* p, const char* content) {
|
|||
|
||||
void checktype(PARSER* p, TOKENTYPE type) {
|
||||
if(p->current->type != type) {
|
||||
fprintf(stderr, "Unexpected %s; line %i, file '%s'\n", tokentypes[p->current->type], p->current->definedat, p->file);
|
||||
fprintf(stderr, "Unexpected %s; line %i, file '%s'\n", tokentypes.items[p->current->type], p->current->definedat, p->file);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
@ -94,8 +66,8 @@ TERM* parsetermnullified(PARSER* p) {
|
|||
} else if(p->current->type == keyword) {
|
||||
t->type = keywordconstant;
|
||||
bool valid = false;
|
||||
for(int i = 0; i < keywordconstantssize; i++)
|
||||
if(!strcmp(p->current->token, keywordconstants[i]))
|
||||
for(int i = 0; i < keywordconstants.size; i++)
|
||||
if(!strcmp(p->current->token, keywordconstants.items[i]))
|
||||
valid = true;
|
||||
if(!valid)
|
||||
unexpected(p);
|
||||
|
@ -136,8 +108,8 @@ TERM* parsetermnullified(PARSER* p) {
|
|||
}
|
||||
|
||||
bool isop(TOKEN* t) {
|
||||
for(int i = 0; i < opssize; i++)
|
||||
if(!strcmp(t->token, ops[i]))
|
||||
for(int i = 0; i < operators.size; i++)
|
||||
if(!strcmp(t->token, operators.items[i]))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -338,8 +310,8 @@ STATEMENT* parsestatements(PARSER* p) {
|
|||
char* parsetype(PARSER* p, bool* primitive) {
|
||||
char* result = p->current->token;
|
||||
if(p->current->type == keyword)
|
||||
for(int i = 0; i < vardectypessize; i++) {
|
||||
if(!strcmp(p->current->token, vardectypes[i])) {
|
||||
for(int i = 0; i < vartypes.size; i++) {
|
||||
if(!strcmp(p->current->token, vartypes.items[i])) {
|
||||
next(p);
|
||||
*primitive = true;
|
||||
return result;
|
||||
|
@ -354,19 +326,19 @@ char* parsetype(PARSER* p, bool* primitive) {
|
|||
unexpected(p);
|
||||
}
|
||||
|
||||
int parsepossibilities(PARSER* p, const char** strings, int sz) {
|
||||
for(int i = 0; i < sz; i++)
|
||||
if(!strcmp(p->current->token, strings[i]))
|
||||
int parsepossibilities(PARSER* p, STRINGARRAY* poss) {
|
||||
for(int i = 0; i < poss->size; i++)
|
||||
if(!strcmp(p->current->token, poss->items[i]))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
CLASSVARTYPE parseclassvartype(PARSER* p) {
|
||||
return parsepossibilities(p, classvartypes, classvartypessize);
|
||||
return parsepossibilities(p, &classvartypes);
|
||||
}
|
||||
|
||||
SUBROUTCLASS parsesubroutclass(PARSER* p) {
|
||||
return parsepossibilities(p, subroutclasses, subroutclassessize);
|
||||
return parsepossibilities(p, &subroutclasses);
|
||||
}
|
||||
|
||||
char* parseidentifier(PARSER* p) {
|
||||
|
|
1
parser.h
1
parser.h
|
@ -3,7 +3,6 @@
|
|||
#include <stdbool.h>
|
||||
#include "tokenizer.h"
|
||||
#include "parser-tree.h"
|
||||
#include "util.h"
|
||||
|
||||
typedef struct {
|
||||
TOKEN* tokens;
|
||||
|
|
33
util.c
33
util.c
|
@ -2,20 +2,20 @@
|
|||
#include <stdlib.h>
|
||||
#include "util.h"
|
||||
|
||||
char* heapstr(char* str, int len) {
|
||||
int sz = sizeof(char) * (len + 1);
|
||||
char* outstr = (char*)malloc(sz);
|
||||
char* heapstr(const char* str, int len) {
|
||||
int size = sizeof(char) * (len + 1);
|
||||
char* outstr = (char*)malloc(size);
|
||||
strcpy(outstr, str);
|
||||
return outstr;
|
||||
}
|
||||
|
||||
char* ezheapstr(char* str) {
|
||||
char* ezheapstr(const char* str) {
|
||||
return heapstr(str, strlen(str));
|
||||
}
|
||||
|
||||
void* copy(void* v, int sz) {
|
||||
void* copy = malloc(sz);
|
||||
memcpy(copy, v, sz);
|
||||
void* copy(void* v, int size) {
|
||||
void* copy = malloc(size);
|
||||
memcpy(copy, v, size);
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
@ -34,12 +34,25 @@ int countplaces(int n) {
|
|||
}
|
||||
|
||||
char* itoa(int i) {
|
||||
int sz = sizeof(char)*(countplaces(i)+1);
|
||||
char* a = (char*)malloc(sz);
|
||||
snprintf(a, sz, "%i", i);
|
||||
int size = sizeof(char)*(countplaces(i)+1);
|
||||
char* a = (char*)malloc(size);
|
||||
snprintf(a, size, "%i", i);
|
||||
return a;
|
||||
}
|
||||
|
||||
STRINGLIST* initstrlist(const char** strs, int count) {
|
||||
STRINGLIST* strlist = (STRINGLIST*)malloc(sizeof(STRINGLIST));
|
||||
STRINGLIST* curr = strlist;
|
||||
for(int i = 0; i < count-1; i++) {
|
||||
curr->content = ezheapstr(strs[i]);
|
||||
curr->next = (STRINGLIST*)malloc(sizeof(STRINGLIST));
|
||||
curr = curr->next;
|
||||
}
|
||||
curr->content = ezheapstr(strs[count-1]);
|
||||
curr->next = NULL;
|
||||
return strlist;
|
||||
}
|
||||
|
||||
void printstrlist(STRINGLIST* strlist, FILE* stream) {
|
||||
while(strlist != NULL) {
|
||||
fprintf(stream, "%s\n", strlist->content);
|
||||
|
|
14
util.h
14
util.h
|
@ -11,16 +11,22 @@
|
|||
#define strcount(array) count(array, char*)
|
||||
|
||||
typedef struct stringlist {
|
||||
char* content;
|
||||
const char* content;
|
||||
struct stringlist* next;
|
||||
} STRINGLIST;
|
||||
|
||||
char* heapstr(char* str, int len);
|
||||
char* ezheapstr(char* str);
|
||||
typedef struct {
|
||||
const char** items;
|
||||
const int size;
|
||||
} STRINGARRAY;
|
||||
|
||||
char* heapstr(const char* str, int len);
|
||||
char* ezheapstr(const char* str);
|
||||
int countplaces(int n);
|
||||
char* itoa(int i);
|
||||
void* copy(void* v, int sz);
|
||||
void* copy(void* v, int size);
|
||||
|
||||
STRINGLIST* initstrlist(const char** strs, int count);
|
||||
void printstrlist(STRINGLIST* strlist, FILE* stream);
|
||||
void freestrlist(STRINGLIST* strlist);
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue