Something kind of works now
This commit is contained in:
parent
10f61474be
commit
978dfb7309
@ -4,7 +4,7 @@
|
|||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "syntax.h"
|
#include "syntax.h"
|
||||||
#include "printtree.h"
|
#include "printtree.h"
|
||||||
|
#include "process.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
FILE *file;
|
FILE *file;
|
||||||
@ -25,6 +25,10 @@ int main(int argc, char *argv[]) {
|
|||||||
fprintf(stderr, "Error during parsing.\n");
|
fprintf(stderr, "Error during parsing.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
printf("Parsed: \n");
|
||||||
|
printtree(code,0);
|
||||||
|
printf("\nProcessed: \n");
|
||||||
|
process(code, NULL);
|
||||||
printtree(code,0);
|
printtree(code,0);
|
||||||
se_free(code);
|
se_free(code);
|
||||||
code = NULL;
|
code = NULL;
|
||||||
|
38
src/parser.c
38
src/parser.c
@ -3,13 +3,16 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#include "printtree.h"
|
||||||
|
#endif
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "extstring.h"
|
#include "extstring.h"
|
||||||
|
|
||||||
tSyntaxElement* parse(FILE* file) {
|
tSyntaxElement* parse(FILE* file) {
|
||||||
tSyntaxElement* syntaxtree = se_create();
|
tSyntaxElement* syntaxtree = se_create();
|
||||||
tSyntaxElement* syntaxtreestart = syntaxtree;
|
tSyntaxElement* syntaxtreestart = syntaxtree;
|
||||||
syntaxtree->type = TREE;
|
syntaxtree->type = NEWTREE;
|
||||||
char symbol;
|
char symbol;
|
||||||
bool intree = false;
|
bool intree = false;
|
||||||
bool incomment = false;
|
bool incomment = false;
|
||||||
@ -19,6 +22,13 @@ tSyntaxElement* parse(FILE* file) {
|
|||||||
tExtstring* extstring = NULL;
|
tExtstring* extstring = NULL;
|
||||||
while (1) {
|
while (1) {
|
||||||
symbol = fgetc(file);
|
symbol = fgetc(file);
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (!isspace(symbol))
|
||||||
|
printf("In parsing. Current symbol: %c\n", symbol);
|
||||||
|
else
|
||||||
|
printf("In parsing. Current symbol: %d\n", symbol);
|
||||||
|
printtree(syntaxtreestart, 0);
|
||||||
|
#endif
|
||||||
if (feof(file))
|
if (feof(file))
|
||||||
break;
|
break;
|
||||||
if (incomment) {
|
if (incomment) {
|
||||||
@ -27,6 +37,7 @@ tSyntaxElement* parse(FILE* file) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (instring) {
|
if (instring) {
|
||||||
|
syntaxtree = se_next(syntaxtree);
|
||||||
if (symbol == '"') {
|
if (symbol == '"') {
|
||||||
if (extstring == NULL) {
|
if (extstring == NULL) {
|
||||||
extstring = malloc(sizeof(tExtstring));
|
extstring = malloc(sizeof(tExtstring));
|
||||||
@ -38,7 +49,6 @@ tSyntaxElement* parse(FILE* file) {
|
|||||||
syntaxtree->content = string;
|
syntaxtree->content = string;
|
||||||
es_free(extstring);
|
es_free(extstring);
|
||||||
extstring = NULL;
|
extstring = NULL;
|
||||||
syntaxtree = se_next(syntaxtree);
|
|
||||||
} else {
|
} else {
|
||||||
if (extstring == NULL) {
|
if (extstring == NULL) {
|
||||||
extstring = malloc(sizeof(tExtstring));
|
extstring = malloc(sizeof(tExtstring));
|
||||||
@ -51,6 +61,7 @@ tSyntaxElement* parse(FILE* file) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (intoken) {
|
if (intoken) {
|
||||||
|
syntaxtree = se_next(syntaxtree);
|
||||||
if (isspace(symbol) || symbol == '(' || symbol == ')') {
|
if (isspace(symbol) || symbol == '(' || symbol == ')') {
|
||||||
intoken = false;
|
intoken = false;
|
||||||
syntaxtree->type = TOKEN;
|
syntaxtree->type = TOKEN;
|
||||||
@ -58,7 +69,6 @@ tSyntaxElement* parse(FILE* file) {
|
|||||||
syntaxtree->content = string;
|
syntaxtree->content = string;
|
||||||
es_free(exttoken);
|
es_free(exttoken);
|
||||||
exttoken = NULL;
|
exttoken = NULL;
|
||||||
syntaxtree = se_next(syntaxtree);
|
|
||||||
} else {
|
} else {
|
||||||
es_addsymbol(exttoken, symbol);
|
es_addsymbol(exttoken, symbol);
|
||||||
continue;
|
continue;
|
||||||
@ -69,19 +79,15 @@ tSyntaxElement* parse(FILE* file) {
|
|||||||
if (intree) {
|
if (intree) {
|
||||||
switch (symbol) {
|
switch (symbol) {
|
||||||
case '(':
|
case '(':
|
||||||
syntaxtree = se_bottom(syntaxtree);
|
|
||||||
break;
|
|
||||||
case ')':
|
|
||||||
if (syntaxtree->top->type == TREE) {
|
|
||||||
intree = false;
|
|
||||||
syntaxtree = syntaxtree->top;
|
|
||||||
syntaxtree = se_next(syntaxtree);
|
|
||||||
syntaxtree->type = NONE;
|
|
||||||
} else {
|
|
||||||
syntaxtree = syntaxtree->top;
|
|
||||||
syntaxtree = se_next(syntaxtree);
|
syntaxtree = se_next(syntaxtree);
|
||||||
syntaxtree->type = TREE;
|
syntaxtree->type = TREE;
|
||||||
}
|
syntaxtree = se_bottom(syntaxtree);
|
||||||
|
syntaxtree->type = NEWTREE;
|
||||||
|
break;
|
||||||
|
case ')':
|
||||||
|
syntaxtree = syntaxtree->top;
|
||||||
|
if (syntaxtree->top == NULL)
|
||||||
|
intree = false;
|
||||||
break;
|
break;
|
||||||
case ';':
|
case ';':
|
||||||
incomment = true;
|
incomment = true;
|
||||||
@ -107,9 +113,10 @@ tSyntaxElement* parse(FILE* file) {
|
|||||||
continue;
|
continue;
|
||||||
case '(':
|
case '(':
|
||||||
intree = true;
|
intree = true;
|
||||||
|
syntaxtree = se_next(syntaxtree);
|
||||||
syntaxtree->type = TREE;
|
syntaxtree->type = TREE;
|
||||||
syntaxtree = se_bottom(syntaxtree);
|
syntaxtree = se_bottom(syntaxtree);
|
||||||
syntaxtree->type = TREE;
|
syntaxtree->type = NEWTREE;
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Expression outside of brackets.\n");
|
fprintf(stderr, "Expression outside of brackets.\n");
|
||||||
@ -121,6 +128,5 @@ tSyntaxElement* parse(FILE* file) {
|
|||||||
fprintf(stderr, "Unexpected EOF.\n");
|
fprintf(stderr, "Unexpected EOF.\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
se_clean(syntaxtreestart);
|
|
||||||
return syntaxtreestart;
|
return syntaxtreestart;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "syntax.h"
|
#include "syntax.h"
|
||||||
|
#include "printtree.h"
|
||||||
|
|
||||||
void printtree(tSyntaxElement* syntaxtree, int depth) {
|
void printtree(tSyntaxElement* syntaxtree, int depth) {
|
||||||
if (syntaxtree == NULL)
|
if (syntaxtree == NULL)
|
||||||
@ -19,13 +20,12 @@ void printtree(tSyntaxElement* syntaxtree, int depth) {
|
|||||||
case STRING:
|
case STRING:
|
||||||
printf("STRING: %s\n", (char*)syntaxtree->content);
|
printf("STRING: %s\n", (char*)syntaxtree->content);
|
||||||
break;
|
break;
|
||||||
case NUMBER:
|
|
||||||
// TODO: printtree NUMBER
|
|
||||||
fprintf(stderr,"TODO: printtree NUMBER\n");
|
|
||||||
exit(1);
|
|
||||||
case NONE:
|
case NONE:
|
||||||
printf("NONE\n");
|
printf("NONE\n");
|
||||||
break;
|
break;
|
||||||
|
case NEWTREE:
|
||||||
|
printf("NEWTREE\n");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (syntaxtree->next != NULL)
|
if (syntaxtree->next != NULL)
|
||||||
printtree(syntaxtree->next, depth);
|
printtree(syntaxtree->next, depth);
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
void printtree(tSyntaxElement* syntaxtree, int depth);
|
void printtree(tSyntaxElement*, int);
|
||||||
|
52
src/process.c
Normal file
52
src/process.c
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "syntax.h"
|
||||||
|
#include "process.h"
|
||||||
|
|
||||||
|
void process(tSyntaxElement* tree, tProcessingData* pdata) {
|
||||||
|
tProcessingData* pd = pdata;
|
||||||
|
bool deffound = false;
|
||||||
|
if (pd == NULL) {
|
||||||
|
pd = calloc(1,sizeof(tProcessingData));
|
||||||
|
}
|
||||||
|
if (se_istraversable(tree))
|
||||||
|
if (((tSyntaxElement*)tree->content)->type == TOKEN && ((tSyntaxElement*)tree->content)->next != NULL) {
|
||||||
|
tSyntaxElement* token = (tSyntaxElement*)tree->content;
|
||||||
|
if (strcmp((char*)token->content,"def") == 0) {
|
||||||
|
char* replacethis = token->next->content;
|
||||||
|
tSyntaxElement* replacewiththis = token->next->next;
|
||||||
|
tProcessingData* npd = malloc(sizeof(tSyntaxElement));
|
||||||
|
npd->replacethis = replacethis;
|
||||||
|
npd->replacewiththis = replacewiththis;
|
||||||
|
npd->prev = pd;
|
||||||
|
pd = npd;
|
||||||
|
deffound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tree->next != NULL) {
|
||||||
|
process(tree->next, pd);
|
||||||
|
}
|
||||||
|
if (!deffound) {
|
||||||
|
if (se_istraversable(tree)) {
|
||||||
|
process((tSyntaxElement*)tree->content, pd);
|
||||||
|
}
|
||||||
|
while (1) {
|
||||||
|
if (pd->replacethis == NULL)
|
||||||
|
break;
|
||||||
|
// Да блядь.
|
||||||
|
if (tree->type == TOKEN)
|
||||||
|
if (strcmp(tree->content, pd->replacethis) == 0) {
|
||||||
|
free(tree->content);
|
||||||
|
tSyntaxElement* clone = se_clone_no_next(pd->replacewiththis, tree);
|
||||||
|
tree->content = clone->content;
|
||||||
|
tree->type = clone->type;
|
||||||
|
}
|
||||||
|
if (pd->prev != NULL)
|
||||||
|
pd = pd->prev;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
src/process.h
Normal file
10
src/process.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include <stdbool.h>
|
||||||
|
#include "syntax.h"
|
||||||
|
|
||||||
|
typedef struct ProcessingData {
|
||||||
|
struct ProcessingData* prev;
|
||||||
|
char* replacethis;
|
||||||
|
tSyntaxElement* replacewiththis;
|
||||||
|
} tProcessingData;
|
||||||
|
|
||||||
|
void process(tSyntaxElement*, tProcessingData*);
|
63
src/syntax.c
63
src/syntax.c
@ -1,4 +1,5 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "syntax.h"
|
#include "syntax.h"
|
||||||
|
|
||||||
@ -23,9 +24,13 @@ tSyntaxElement* se_bottom(tSyntaxElement* syntaxelement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tSyntaxElement* se_next(tSyntaxElement* syntaxelement) {
|
tSyntaxElement* se_next(tSyntaxElement* syntaxelement) {
|
||||||
|
if (syntaxelement->type != NEWTREE) {
|
||||||
syntaxelement->next = se_create();
|
syntaxelement->next = se_create();
|
||||||
syntaxelement->next->top = syntaxelement->top;
|
syntaxelement->next->top = syntaxelement->top;
|
||||||
return syntaxelement->next;
|
return syntaxelement->next;
|
||||||
|
} else {
|
||||||
|
return syntaxelement;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void se_free(tSyntaxElement* syntaxtree) {
|
void se_free(tSyntaxElement* syntaxtree) {
|
||||||
@ -48,29 +53,45 @@ void se_free(tSyntaxElement* syntaxtree) {
|
|||||||
free(syntaxtree);
|
free(syntaxtree);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove NONEs from the syntax tree.
|
tSyntaxElement* se_clone(tSyntaxElement* syntaxelement, tSyntaxElement* newtop) {
|
||||||
void se_clean(tSyntaxElement* syntaxtree) {
|
tSyntaxElement* clone = NULL;
|
||||||
if (syntaxtree->next != NULL) {
|
switch (syntaxelement->type) {
|
||||||
switch (syntaxtree->next->type) {
|
case TREE:
|
||||||
|
clone = se_create();
|
||||||
|
clone->type = TREE;
|
||||||
|
if (syntaxelement->content != NULL)
|
||||||
|
clone->content = se_clone(syntaxelement->content, clone);
|
||||||
|
if (syntaxelement->next != NULL)
|
||||||
|
clone->next = se_clone(syntaxelement->next, newtop);
|
||||||
|
break;
|
||||||
|
case TOKEN:
|
||||||
|
case STRING:
|
||||||
|
clone = se_create();
|
||||||
|
clone->type = syntaxelement->type;
|
||||||
|
clone->content = malloc(strlen(syntaxelement->content));
|
||||||
|
strcpy(clone->content, syntaxelement->content);
|
||||||
|
if (syntaxelement->next != NULL)
|
||||||
|
clone->next = se_clone(syntaxelement->next, newtop);
|
||||||
|
break;
|
||||||
case NONE:
|
case NONE:
|
||||||
free(syntaxtree->next);
|
case NEWTREE:
|
||||||
syntaxtree->next = NULL;
|
clone = se_create();
|
||||||
break;
|
clone->type = syntaxelement->type;
|
||||||
default:
|
clone->top = newtop;
|
||||||
se_clean(syntaxtree->next);
|
if (syntaxelement->next != NULL)
|
||||||
|
clone->next = se_clone(syntaxelement->next, newtop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
return clone;
|
||||||
if (syntaxtree->content != NULL && (syntaxtree->type == TREE)) {
|
|
||||||
switch (((tSyntaxElement*)syntaxtree->content)->type) {
|
|
||||||
case NONE:
|
|
||||||
free(syntaxtree->content);
|
|
||||||
syntaxtree->content = NULL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
se_clean((tSyntaxElement*)syntaxtree->content);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tSyntaxElement* se_clone_no_next(tSyntaxElement* syntaxelement, tSyntaxElement* newtop) {
|
||||||
|
tSyntaxElement* se = malloc(sizeof(tSyntaxElement));
|
||||||
|
se->content = syntaxelement->content;
|
||||||
|
se->top = syntaxelement->top;
|
||||||
|
se->type = syntaxelement->type;
|
||||||
|
se->next = NULL;
|
||||||
|
tSyntaxElement* clone = se_clone(se, newtop);
|
||||||
|
free(se);
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
13
src/syntax.h
13
src/syntax.h
@ -3,10 +3,10 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
enum SyntaxElementType {
|
enum SyntaxElementType {
|
||||||
|
NEWTREE,
|
||||||
TREE,
|
TREE,
|
||||||
TOKEN,
|
TOKEN,
|
||||||
STRING,
|
STRING,
|
||||||
NUMBER,
|
|
||||||
NONE
|
NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -17,11 +17,12 @@ typedef struct SyntaxElement {
|
|||||||
struct SyntaxElement* top;
|
struct SyntaxElement* top;
|
||||||
} tSyntaxElement;
|
} tSyntaxElement;
|
||||||
|
|
||||||
void se_clean(tSyntaxElement* syntaxtree);
|
void se_free(tSyntaxElement*);
|
||||||
bool se_istraversable(tSyntaxElement* syntaxtree);
|
bool se_istraversable(tSyntaxElement*);
|
||||||
tSyntaxElement* se_create(void);
|
tSyntaxElement* se_create(void);
|
||||||
tSyntaxElement* se_init(void);
|
tSyntaxElement* se_init(void);
|
||||||
tSyntaxElement* se_bottom(tSyntaxElement* syntaxelement);
|
tSyntaxElement* se_bottom(tSyntaxElement*);
|
||||||
tSyntaxElement* se_next(tSyntaxElement* syntaxelement);
|
tSyntaxElement* se_next(tSyntaxElement*);
|
||||||
void se_free(tSyntaxElement* syntaxtree);
|
tSyntaxElement* se_clone(tSyntaxElement*, tSyntaxElement*);
|
||||||
|
tSyntaxElement* se_clone_no_next(tSyntaxElement*, tSyntaxElement*);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user