Move parser constants to new file

This commit is contained in:
Augusto Gunsch 2020-12-21 21:50:55 -03:00
parent bf61fcdd30
commit cf5bef048e
No known key found for this signature in database
GPG Key ID: F7EEFE29825C72DC
7 changed files with 90 additions and 80 deletions

View File

@ -5,23 +5,23 @@
// INTERNAL FUNCTIONS // INTERNAL FUNCTIONS
// Information gathering // Information gathering
bool existstr(STRINGLIST* strs, char* str); bool existstr(STRINGLIST* strs, const char* str);
bool existclass(CLASS* c, char* name); bool existclass(CLASS* c, const char* name);
DEBUGINFO* getdebuginfo(OBJ* obj); DEBUGINFO* getdebuginfo(OBJ* obj);
// Error messages // Error messages
void doubledeclaration(char* name, DEBUGINFO* debug, OBJ* other); void doubledeclaration(const char* name, DEBUGINFO* debug, OBJ* other);
void ensurenoduplicate(SCOPE* s, char* name, DEBUGINFO* debug); void ensurenoduplicate(SCOPE* s, const char* name, DEBUGINFO* debug);
// Scope handling // Scope handling
void popscope(SCOPE** s); // may be removed void popscope(SCOPE** s); // may be removed
// Single type getters // Single type getters
VARDEC* getvardec(SCOPE* s, char* name); VARDEC* getvardec(SCOPE* s, const char* name);
CLASSVARDEC* getclassvardec(SCOPE* s, char* name); CLASSVARDEC* getclassvardec(SCOPE* s, const char* name);
// Generic getters // Generic getters
OBJ* getbynamelist(SCOPE* s, STRINGLIST* names, char** retname); OBJ* getbynamelist(SCOPE* s, STRINGLIST* names, const char** retname);
// Scope adding // Scope adding
void addclassvardec(SCOPE* s, CLASSVARDEC* v); void addclassvardec(SCOPE* s, CLASSVARDEC* v);
@ -31,7 +31,7 @@ void addclass(SCOPE* s, CLASS* c);
// DEFINITIONS // DEFINITIONS
// Information gathering // Information gathering
bool existstr(STRINGLIST* strs, char* str) { bool existstr(STRINGLIST* strs, const char* str) {
while(strs != NULL) { while(strs != NULL) {
if(!strcmp(strs->content, str)) if(!strcmp(strs->content, str))
return true; return true;
@ -40,7 +40,7 @@ bool existstr(STRINGLIST* strs, char* str) {
return false; return false;
} }
bool existclass(CLASS* c, char* name) { bool existclass(CLASS* c, const char* name) {
while(c != NULL) { while(c != NULL) {
if(!strcmp(c->name, name)) if(!strcmp(c->name, name))
return true; return true;
@ -77,14 +77,14 @@ VARDEC* tovardec(OBJ* obj) {
// Error messages // Error messages
void doubledeclaration(char* name, DEBUGINFO* debug, OBJ* other) { void doubledeclaration(const char* name, DEBUGINFO* debug, OBJ* other) {
DEBUGINFO* debugother = other->getdebug(other); DEBUGINFO* debugother = other->getdebug(other);
eprintf("Double declaration of '%s' at '%s', line %i; previously defined at '%s', line %i\n", 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); name, debug->file, debug->definedat, debugother->file, debugother->definedat);
exit(1); 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); eprintf("'%s' not declared; file '%s', line %i\n", name, debug->file, debug->definedat);
exit(1); exit(1);
} }
@ -94,14 +94,14 @@ void invalidparent(SUBROUTCALL* call) {
exit(1); exit(1);
} }
void ensurenoduplicate(SCOPE* s, char* name, DEBUGINFO* debug) { void ensurenoduplicate(SCOPE* s, const char* name, DEBUGINFO* debug) {
OBJ* other = getbyname(s, name); OBJ* other = getbyname(s, name);
if(other != NULL) if(other != NULL)
doubledeclaration(name, debug, other); doubledeclaration(name, debug, other);
} }
void ensurenoduplicates(SCOPE* s, STRINGLIST* names, DEBUGINFO* debug) { void ensurenoduplicates(SCOPE* s, STRINGLIST* names, DEBUGINFO* debug) {
char* othername; const char* othername;
OBJ* other = getbynamelist(s, names, &othername); OBJ* other = getbynamelist(s, names, &othername);
if(other != NULL) if(other != NULL)
doubledeclaration(othername, debug, other); doubledeclaration(othername, debug, other);
@ -126,7 +126,7 @@ void popscope(SCOPE** s) { // might be useless
} }
// Single type getters // Single type getters
VARDEC* getvardec(SCOPE* s, char* name) { VARDEC* getvardec(SCOPE* s, const char* name) {
VARDEC* curr = s->vardecs; VARDEC* curr = s->vardecs;
while(curr != NULL) { while(curr != NULL) {
if(existstr(curr->names, name)) if(existstr(curr->names, name))
@ -138,7 +138,7 @@ VARDEC* getvardec(SCOPE* s, char* name) {
return NULL; return NULL;
} }
CLASSVARDEC* getclassvardec(SCOPE* s, char* name) { CLASSVARDEC* getclassvardec(SCOPE* s, const char* name) {
CLASSVARDEC* curr = s->classvardecs; CLASSVARDEC* curr = s->classvardecs;
while(curr != NULL) { while(curr != NULL) {
if(existstr(curr->base->names, name)) if(existstr(curr->base->names, name))
@ -150,7 +150,7 @@ CLASSVARDEC* getclassvardec(SCOPE* s, char* name) {
return NULL; return NULL;
} }
SUBROUTDEC* getsubroutdec(SCOPE* s, char* name) { SUBROUTDEC* getsubroutdec(SCOPE* s, const char* name) {
SUBROUTDEC* curr = s->subroutines; SUBROUTDEC* curr = s->subroutines;
while(curr != NULL) { while(curr != NULL) {
if(!strcmp(curr->name, name)) if(!strcmp(curr->name, name))
@ -162,7 +162,7 @@ SUBROUTDEC* getsubroutdec(SCOPE* s, char* name) {
return NULL; return NULL;
} }
CLASS* getclass(SCOPE* s, char* name) { CLASS* getclass(SCOPE* s, const char* name) {
CLASS* curr = s->classes; CLASS* curr = s->classes;
while(curr != NULL) { while(curr != NULL) {
if(!strcmp(curr->name, name)) if(!strcmp(curr->name, name))
@ -174,7 +174,7 @@ CLASS* getclass(SCOPE* s, char* name) {
return NULL; return NULL;
} }
SUBROUTDEC* getsubroutdecfromclass(CLASS* c, char* name) { SUBROUTDEC* getsubroutdecfromclass(CLASS* c, const char* name) {
SUBROUTDEC* curr = c->subroutdecs; SUBROUTDEC* curr = c->subroutdecs;
while(curr != NULL) { while(curr != NULL) {
if(!strcmp(curr->name, name)) if(!strcmp(curr->name, name))
@ -218,7 +218,7 @@ SUBROUTDEC* getsubroutdecfromcall(SCOPE* s, SUBROUTCALL* call) {
} }
// Generic getters // Generic getters
OBJ* getbyname(SCOPE* s, char* name) { OBJ* getbyname(SCOPE* s, const char* name) {
OBJ* o = (OBJ*)malloc(sizeof(OBJ)); OBJ* o = (OBJ*)malloc(sizeof(OBJ));
CLASSVARDEC* cvd = getclassvardec(s, name); CLASSVARDEC* cvd = getclassvardec(s, name);
@ -257,7 +257,7 @@ OBJ* getbyname(SCOPE* s, char* name) {
return NULL; return NULL;
} }
OBJ* getbynamelist(SCOPE* s, STRINGLIST* names, char** retname) { OBJ* getbynamelist(SCOPE* s, STRINGLIST* names, const char** retname) {
while(names != NULL) { while(names != NULL) {
OBJ* o = getbyname(s, names->content); OBJ* o = getbyname(s, names->content);
if(o != NULL) { if(o != NULL) {

View File

@ -42,10 +42,10 @@ void addclasses(SCOPE* s, CLASS* c);
SCOPE* mkscope(SCOPE* prev); SCOPE* mkscope(SCOPE* prev);
// Single type getters // Single type getters
SUBROUTDEC* getsubroutdec(SCOPE* s, char* name); SUBROUTDEC* getsubroutdec(SCOPE* s, const char* name);
SUBROUTDEC* getsubroutdecfromcall(SCOPE* s, SUBROUTCALL* call); SUBROUTDEC* getsubroutdecfromcall(SCOPE* s, SUBROUTCALL* call);
CLASS* getclass(SCOPE* s, char* name); CLASS* getclass(SCOPE* s, const char* name);
// Generic getters // Generic getters
OBJ* getbyname(SCOPE* s, char* name); OBJ* getbyname(SCOPE* s, const char* name);
#endif #endif

20
parser-constants.h Normal file
View File

@ -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

View File

@ -3,6 +3,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include "parser.h" #include "parser.h"
#include "parser-constants.h"
char* parseidentifier(PARSER* p); char* parseidentifier(PARSER* p);
STATEMENT* parsestatements(PARSER* p); STATEMENT* parsestatements(PARSER* p);
@ -10,35 +11,6 @@ SUBROUTCALL* parsesubroutcall(PARSER* p);
TERM* parseexpression(PARSER* p); TERM* parseexpression(PARSER* p);
TERM* parseterm(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* getdebug(PARSER* p) {
DEBUGINFO* d = (DEBUGINFO*)malloc(sizeof(DEBUGINFO)); DEBUGINFO* d = (DEBUGINFO*)malloc(sizeof(DEBUGINFO));
d->file = p->file; d->file = p->file;
@ -59,7 +31,7 @@ void restorecp(PARSER* p) {
} }
void unexpectedtoken(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) { void unexpected(PARSER* p) {
@ -75,7 +47,7 @@ void checkcontent(PARSER* p, const char* content) {
void checktype(PARSER* p, TOKENTYPE type) { void checktype(PARSER* p, TOKENTYPE type) {
if(p->current->type != 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); exit(1);
} }
} }
@ -94,8 +66,8 @@ TERM* parsetermnullified(PARSER* p) {
} else if(p->current->type == keyword) { } else if(p->current->type == keyword) {
t->type = keywordconstant; t->type = keywordconstant;
bool valid = false; bool valid = false;
for(int i = 0; i < keywordconstantssize; i++) for(int i = 0; i < keywordconstants.size; i++)
if(!strcmp(p->current->token, keywordconstants[i])) if(!strcmp(p->current->token, keywordconstants.items[i]))
valid = true; valid = true;
if(!valid) if(!valid)
unexpected(p); unexpected(p);
@ -136,8 +108,8 @@ TERM* parsetermnullified(PARSER* p) {
} }
bool isop(TOKEN* t) { bool isop(TOKEN* t) {
for(int i = 0; i < opssize; i++) for(int i = 0; i < operators.size; i++)
if(!strcmp(t->token, ops[i])) if(!strcmp(t->token, operators.items[i]))
return true; return true;
return false; return false;
} }
@ -338,8 +310,8 @@ STATEMENT* parsestatements(PARSER* p) {
char* parsetype(PARSER* p, bool* primitive) { char* parsetype(PARSER* p, bool* primitive) {
char* result = p->current->token; char* result = p->current->token;
if(p->current->type == keyword) if(p->current->type == keyword)
for(int i = 0; i < vardectypessize; i++) { for(int i = 0; i < vartypes.size; i++) {
if(!strcmp(p->current->token, vardectypes[i])) { if(!strcmp(p->current->token, vartypes.items[i])) {
next(p); next(p);
*primitive = true; *primitive = true;
return result; return result;
@ -354,19 +326,19 @@ char* parsetype(PARSER* p, bool* primitive) {
unexpected(p); unexpected(p);
} }
int parsepossibilities(PARSER* p, const char** strings, int sz) { int parsepossibilities(PARSER* p, STRINGARRAY* poss) {
for(int i = 0; i < sz; i++) for(int i = 0; i < poss->size; i++)
if(!strcmp(p->current->token, strings[i])) if(!strcmp(p->current->token, poss->items[i]))
return i; return i;
return -1; return -1;
} }
CLASSVARTYPE parseclassvartype(PARSER* p) { CLASSVARTYPE parseclassvartype(PARSER* p) {
return parsepossibilities(p, classvartypes, classvartypessize); return parsepossibilities(p, &classvartypes);
} }
SUBROUTCLASS parsesubroutclass(PARSER* p) { SUBROUTCLASS parsesubroutclass(PARSER* p) {
return parsepossibilities(p, subroutclasses, subroutclassessize); return parsepossibilities(p, &subroutclasses);
} }
char* parseidentifier(PARSER* p) { char* parseidentifier(PARSER* p) {

View File

@ -3,7 +3,6 @@
#include <stdbool.h> #include <stdbool.h>
#include "tokenizer.h" #include "tokenizer.h"
#include "parser-tree.h" #include "parser-tree.h"
#include "util.h"
typedef struct { typedef struct {
TOKEN* tokens; TOKEN* tokens;

33
util.c
View File

@ -2,20 +2,20 @@
#include <stdlib.h> #include <stdlib.h>
#include "util.h" #include "util.h"
char* heapstr(char* str, int len) { char* heapstr(const char* str, int len) {
int sz = sizeof(char) * (len + 1); int size = sizeof(char) * (len + 1);
char* outstr = (char*)malloc(sz); char* outstr = (char*)malloc(size);
strcpy(outstr, str); strcpy(outstr, str);
return outstr; return outstr;
} }
char* ezheapstr(char* str) { char* ezheapstr(const char* str) {
return heapstr(str, strlen(str)); return heapstr(str, strlen(str));
} }
void* copy(void* v, int sz) { void* copy(void* v, int size) {
void* copy = malloc(sz); void* copy = malloc(size);
memcpy(copy, v, sz); memcpy(copy, v, size);
return copy; return copy;
} }
@ -34,12 +34,25 @@ int countplaces(int n) {
} }
char* itoa(int i) { char* itoa(int i) {
int sz = sizeof(char)*(countplaces(i)+1); int size = sizeof(char)*(countplaces(i)+1);
char* a = (char*)malloc(sz); char* a = (char*)malloc(size);
snprintf(a, sz, "%i", i); snprintf(a, size, "%i", i);
return a; 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) { void printstrlist(STRINGLIST* strlist, FILE* stream) {
while(strlist != NULL) { while(strlist != NULL) {
fprintf(stream, "%s\n", strlist->content); fprintf(stream, "%s\n", strlist->content);

14
util.h
View File

@ -11,16 +11,22 @@
#define strcount(array) count(array, char*) #define strcount(array) count(array, char*)
typedef struct stringlist { typedef struct stringlist {
char* content; const char* content;
struct stringlist* next; struct stringlist* next;
} STRINGLIST; } STRINGLIST;
char* heapstr(char* str, int len); typedef struct {
char* ezheapstr(char* str); const char** items;
const int size;
} STRINGARRAY;
char* heapstr(const char* str, int len);
char* ezheapstr(const char* str);
int countplaces(int n); int countplaces(int n);
char* itoa(int i); 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 printstrlist(STRINGLIST* strlist, FILE* stream);
void freestrlist(STRINGLIST* strlist); void freestrlist(STRINGLIST* strlist);
#endif #endif