Format code better
This commit is contained in:
parent
3128d3c646
commit
65e360984d
@ -2,53 +2,81 @@
|
||||
#include "extstring.h"
|
||||
|
||||
void es_addsymbol(tExtstring* string, char symbol) {
|
||||
|
||||
if (string == NULL)
|
||||
return;
|
||||
|
||||
tExtstring* ptr = string;
|
||||
|
||||
while (ptr->next != NULL) {
|
||||
ptr = ptr->next;
|
||||
};
|
||||
|
||||
ptr->next = malloc(sizeof(tExtstring));
|
||||
ptr->next->symbol = symbol;
|
||||
ptr->next->next = NULL;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
int es_size(tExtstring* string) {
|
||||
|
||||
int size = 0;
|
||||
|
||||
tExtstring* ptr = string;
|
||||
|
||||
for (; ptr != NULL; size++) {
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void es_free(tExtstring* string) {
|
||||
|
||||
if (string->next == NULL) {
|
||||
|
||||
free(string);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
tExtstring* ptr = string;
|
||||
tExtstring* nextptr = ptr->next;
|
||||
|
||||
while (ptr->next != NULL) {
|
||||
|
||||
nextptr = ptr->next;
|
||||
free(ptr);
|
||||
ptr = nextptr;
|
||||
|
||||
}
|
||||
|
||||
free(ptr);
|
||||
|
||||
}
|
||||
|
||||
char* es_tostring(tExtstring* string) {
|
||||
|
||||
tExtstring* ptr = string;
|
||||
|
||||
int size = es_size(string) + 1;
|
||||
|
||||
char* cstring = malloc(size);
|
||||
|
||||
for (int i = 0; i != size; i++) {
|
||||
|
||||
if (ptr != NULL) {
|
||||
cstring[i] = ptr->symbol;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
else
|
||||
cstring[i] = 0;
|
||||
}
|
||||
|
||||
return cstring;
|
||||
|
||||
}
|
||||
|
@ -3,7 +3,11 @@ typedef struct Extstring {
|
||||
struct Extstring* next;
|
||||
} tExtstring;
|
||||
|
||||
|
||||
void es_addsymbol(tExtstring* string, char symbol);
|
||||
|
||||
int es_size(tExtstring* string);
|
||||
|
||||
void es_free(tExtstring* string);
|
||||
|
||||
char* es_tostring(tExtstring* string);
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "process.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
FILE *file;
|
||||
if (argc != 2) {
|
||||
fprintf(stderr,
|
||||
@ -14,23 +15,30 @@ int main(int argc, char *argv[]) {
|
||||
"%s FILENAME\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
file = fopen(argv[1],"r");
|
||||
if (file == NULL) {
|
||||
fprintf(stderr,"Unable to open file.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
tSyntaxElement* code = parse(file);
|
||||
fclose(file);
|
||||
|
||||
if (code == NULL) {
|
||||
fprintf(stderr, "Error during parsing.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Parsed: \n");
|
||||
printtree(code,1);
|
||||
|
||||
printf("\nProcessed: \n");
|
||||
process(code, NULL);
|
||||
printtree(code,1);
|
||||
|
||||
se_free(code);
|
||||
code = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
66
src/parser.c
66
src/parser.c
@ -3,130 +3,190 @@
|
||||
#include <stdbool.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "printtree.h"
|
||||
#endif
|
||||
#include "parser.h"
|
||||
#include "extstring.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "printtree.h"
|
||||
#endif
|
||||
|
||||
tSyntaxElement* parse(FILE* file) {
|
||||
|
||||
tSyntaxElement* syntaxtree = se_create();
|
||||
tSyntaxElement* syntaxtreestart = syntaxtree;
|
||||
syntaxtree->type = NEWTREE;
|
||||
|
||||
char symbol;
|
||||
bool intree = false;
|
||||
bool incomment = false;
|
||||
bool instring = false;
|
||||
bool intoken = false;
|
||||
|
||||
tExtstring* exttoken = NULL;
|
||||
tExtstring* extstring = NULL;
|
||||
|
||||
while (1) {
|
||||
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, 1);
|
||||
|
||||
#endif
|
||||
|
||||
if (feof(file))
|
||||
break;
|
||||
|
||||
if (incomment) {
|
||||
if (symbol == '\n')
|
||||
incomment = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (instring) {
|
||||
if (symbol == '"') {
|
||||
|
||||
if (extstring == NULL) {
|
||||
extstring = malloc(sizeof(tExtstring));
|
||||
extstring->next = NULL;
|
||||
}
|
||||
|
||||
instring = false;
|
||||
|
||||
syntaxtree->type = STRING;
|
||||
char* string = es_tostring(extstring);
|
||||
syntaxtree->content.string = string;
|
||||
|
||||
es_free(extstring);
|
||||
extstring = NULL;
|
||||
|
||||
} else {
|
||||
|
||||
if (extstring == NULL) {
|
||||
|
||||
extstring = malloc(sizeof(tExtstring));
|
||||
extstring->symbol = symbol;
|
||||
extstring->next = NULL;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
es_addsymbol(extstring, symbol);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (intoken) {
|
||||
if (isspace(symbol) || symbol == '(' || symbol == ')') {
|
||||
|
||||
intoken = false;
|
||||
|
||||
syntaxtree->type = TOKEN;
|
||||
char* string = es_tostring(exttoken);
|
||||
syntaxtree->content.string = string;
|
||||
|
||||
es_free(exttoken);
|
||||
exttoken = NULL;
|
||||
|
||||
} else {
|
||||
|
||||
es_addsymbol(exttoken, symbol);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (isspace(symbol))
|
||||
continue;
|
||||
|
||||
if (intree) {
|
||||
switch (symbol) {
|
||||
|
||||
case '(':
|
||||
|
||||
syntaxtree = se_next(syntaxtree);
|
||||
syntaxtree->type = TREE;
|
||||
|
||||
syntaxtree = se_bottom(syntaxtree);
|
||||
syntaxtree->type = NEWTREE;
|
||||
|
||||
break;
|
||||
|
||||
case ')':
|
||||
|
||||
syntaxtree = syntaxtree->top;
|
||||
|
||||
if (syntaxtree->top == NULL)
|
||||
intree = false;
|
||||
break;
|
||||
|
||||
case ';':
|
||||
|
||||
incomment = true;
|
||||
continue;
|
||||
|
||||
case '"':
|
||||
|
||||
syntaxtree = se_next(syntaxtree);
|
||||
instring = true;
|
||||
continue;
|
||||
|
||||
default:
|
||||
|
||||
syntaxtree = se_next(syntaxtree);
|
||||
|
||||
exttoken = malloc(sizeof(tExtstring));
|
||||
exttoken->symbol = symbol;
|
||||
exttoken->next = NULL;
|
||||
|
||||
intoken = true;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
|
||||
} else {
|
||||
switch (symbol) {
|
||||
|
||||
case ')':
|
||||
|
||||
fprintf(stderr, "Unbalanced brackets.\n");
|
||||
return NULL;
|
||||
|
||||
case ';':
|
||||
|
||||
incomment = true;
|
||||
continue;
|
||||
|
||||
case '(':
|
||||
|
||||
intree = true;
|
||||
|
||||
syntaxtree = se_next(syntaxtree);
|
||||
syntaxtree->type = TREE;
|
||||
|
||||
syntaxtree = se_bottom(syntaxtree);
|
||||
syntaxtree->type = NEWTREE;
|
||||
|
||||
continue;
|
||||
|
||||
default:
|
||||
|
||||
fprintf(stderr, "Expression outside of brackets.\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (intree) {
|
||||
|
||||
fprintf(stderr, "Unexpected EOF.\n");
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
return syntaxtreestart;
|
||||
}
|
||||
|
@ -5,29 +5,47 @@
|
||||
#include "printtree.h"
|
||||
|
||||
void printtree(tSyntaxElement* syntaxtree, int depth) {
|
||||
|
||||
if (syntaxtree == NULL)
|
||||
return;
|
||||
|
||||
for (int i = 1; i <= depth; i++)
|
||||
putc(' ',stdout);
|
||||
|
||||
switch (syntaxtree->type) {
|
||||
|
||||
case TREE:
|
||||
|
||||
printf("TREE\n");
|
||||
printtree(syntaxtree->content.syntax, depth + 1);
|
||||
|
||||
break;
|
||||
|
||||
case TOKEN:
|
||||
|
||||
printf("TOKEN: %s\n", syntaxtree->content.string);
|
||||
break;
|
||||
|
||||
case STRING:
|
||||
|
||||
printf("STRING: %s\n", syntaxtree->content.string);
|
||||
break;
|
||||
|
||||
case NONE:
|
||||
|
||||
printf("NONE\n");
|
||||
break;
|
||||
|
||||
case NEWTREE:
|
||||
|
||||
printf("NEWTREE\n");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (syntaxtree->next != NULL)
|
||||
printtree(syntaxtree->next, depth);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
@ -1,2 +1,3 @@
|
||||
#include "parser.h"
|
||||
|
||||
void printtree(tSyntaxElement*, int);
|
||||
|
@ -6,76 +6,124 @@
|
||||
#include "process.h"
|
||||
|
||||
bool replace(tSyntaxElement* tree, tProcessingData* pdata) {
|
||||
|
||||
tProcessingData* pd = pdata;
|
||||
|
||||
bool didreplace = false;
|
||||
|
||||
while (1) {
|
||||
|
||||
if (pd->data.replace.replacethis == NULL)
|
||||
break;
|
||||
|
||||
if (tree->type == TOKEN)
|
||||
|
||||
if (strcmp(tree->content.string, pd->data.replace.replacethis) == 0) {
|
||||
|
||||
didreplace = true;
|
||||
|
||||
free(tree->content.none);
|
||||
|
||||
tSyntaxElement* clone = se_clone_no_next(pd->data.replace.replacewiththis, tree);
|
||||
tree->content = clone->content;
|
||||
tree->type = clone->type;
|
||||
|
||||
}
|
||||
|
||||
if (pd->prev != NULL)
|
||||
pd = pd->prev;
|
||||
else
|
||||
break;
|
||||
|
||||
else break;
|
||||
|
||||
}
|
||||
|
||||
return didreplace;
|
||||
|
||||
}
|
||||
|
||||
bool process_find(tSyntaxElement* tree, tProcessingData** p_pdata) {
|
||||
|
||||
tProcessingData* pd = *p_pdata;
|
||||
|
||||
bool deffound = false;
|
||||
|
||||
if (se_istraversable(tree))
|
||||
|
||||
if (tree->content.syntax->type == TOKEN &&
|
||||
tree->content.syntax->next != NULL &&
|
||||
tree->content.syntax->next->next != NULL) {
|
||||
|
||||
tSyntaxElement* token = tree->content.syntax;
|
||||
|
||||
if (strcmp(token->content.string,"def") == 0) {
|
||||
|
||||
char* replacethis = token->next->content.string;
|
||||
|
||||
tSyntaxElement* replacewiththis = token->next->next;
|
||||
|
||||
tProcessingData* npd = malloc(sizeof(tSyntaxElement));
|
||||
|
||||
npd->type = REPLACE;
|
||||
npd->data.replace.replacethis = replacethis;
|
||||
npd->data.replace.replacewiththis = replacewiththis;
|
||||
npd->prev = pd;
|
||||
|
||||
*p_pdata = npd;
|
||||
|
||||
deffound = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return deffound;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void process(tSyntaxElement* tree, tProcessingData* pdata) {
|
||||
|
||||
tProcessingData* pd = pdata;
|
||||
|
||||
bool deffound = false;
|
||||
|
||||
tProcessingData* firstpd = NULL;
|
||||
|
||||
if (pd == NULL) {
|
||||
|
||||
pd = calloc(1,sizeof(tProcessingData));
|
||||
firstpd = pd;
|
||||
|
||||
}
|
||||
|
||||
deffound = process_find(tree, &pd);
|
||||
|
||||
if (tree->next != NULL) {
|
||||
process(tree->next, pd);
|
||||
}
|
||||
|
||||
if (!deffound) {
|
||||
if (se_istraversable(tree)) {
|
||||
|
||||
if (se_istraversable(tree))
|
||||
process(tree->content.syntax, pd);
|
||||
}
|
||||
|
||||
switch (pd->type) {
|
||||
|
||||
case REPLACE:
|
||||
replace(tree, pd);
|
||||
break;
|
||||
case FUNCTION:
|
||||
|
||||
case FUNCTION: // TODO
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (pd != pdata)
|
||||
free(pd);
|
||||
|
||||
if (firstpd != pd && firstpd != NULL)
|
||||
free(firstpd);
|
||||
|
||||
}
|
||||
|
@ -2,33 +2,45 @@
|
||||
#include "syntax.h"
|
||||
|
||||
typedef enum {
|
||||
|
||||
REPLACE,
|
||||
FUNCTION
|
||||
|
||||
} tProcessingType;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
char* replacethis;
|
||||
tSyntaxElement* replacewiththis;
|
||||
|
||||
} tProcessingReplace;
|
||||
|
||||
typedef struct {
|
||||
|
||||
char** args;
|
||||
tSyntaxElement* body;
|
||||
|
||||
} tProcessingFunction;
|
||||
|
||||
|
||||
|
||||
typedef union {
|
||||
|
||||
tProcessingReplace replace;
|
||||
tProcessingFunction function;
|
||||
|
||||
} tuProcessingData;
|
||||
|
||||
typedef struct ProcessingData {
|
||||
|
||||
struct ProcessingData* prev;
|
||||
tProcessingType type;
|
||||
tuProcessingData data;
|
||||
|
||||
} tProcessingData;
|
||||
|
||||
|
||||
|
||||
void process(tSyntaxElement*, tProcessingData*);
|
||||
|
51
src/syntax.c
51
src/syntax.c
@ -4,94 +4,141 @@
|
||||
#include "syntax.h"
|
||||
|
||||
bool se_istraversable(tSyntaxElement* syntaxtree) {
|
||||
|
||||
return syntaxtree->type == TREE && syntaxtree->content.syntax != NULL;
|
||||
|
||||
}
|
||||
|
||||
tSyntaxElement* se_create(void) {
|
||||
|
||||
tSyntaxElement* syntaxelement = malloc(sizeof(tSyntaxElement));
|
||||
|
||||
syntaxelement->type = NONE;
|
||||
syntaxelement->content.none = NULL;
|
||||
syntaxelement->next = NULL;
|
||||
syntaxelement->top = NULL;
|
||||
|
||||
return syntaxelement;
|
||||
|
||||
}
|
||||
|
||||
tSyntaxElement* se_bottom(tSyntaxElement* syntaxelement) {
|
||||
|
||||
syntaxelement->content.syntax = se_create();
|
||||
syntaxelement->content.syntax->top = syntaxelement;
|
||||
|
||||
return syntaxelement->content.syntax;
|
||||
|
||||
}
|
||||
|
||||
tSyntaxElement* se_next(tSyntaxElement* syntaxelement) {
|
||||
|
||||
if (syntaxelement->type != NEWTREE) {
|
||||
|
||||
syntaxelement->next = se_create();
|
||||
syntaxelement->next->top = syntaxelement->top;
|
||||
|
||||
return syntaxelement->next;
|
||||
} else {
|
||||
|
||||
} else
|
||||
return syntaxelement;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void se_free(tSyntaxElement* syntaxtree) {
|
||||
|
||||
switch (syntaxtree->type) {
|
||||
|
||||
case NONE:
|
||||
|
||||
free(syntaxtree);
|
||||
return;
|
||||
|
||||
case TREE:
|
||||
|
||||
if (syntaxtree->content.syntax != NULL) {
|
||||
se_free(syntaxtree->content.syntax);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
free(syntaxtree->content.none);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (syntaxtree->next != NULL) {
|
||||
se_free(syntaxtree->next);
|
||||
}
|
||||
|
||||
free(syntaxtree);
|
||||
|
||||
}
|
||||
|
||||
tSyntaxElement* se_clone(tSyntaxElement* syntaxelement, tSyntaxElement* newtop) {
|
||||
|
||||
tSyntaxElement* clone = NULL;
|
||||
|
||||
switch (syntaxelement->type) {
|
||||
|
||||
case TREE:
|
||||
|
||||
clone = se_create();
|
||||
clone->type = TREE;
|
||||
|
||||
if (syntaxelement->content.syntax != NULL)
|
||||
clone->content.syntax = se_clone(syntaxelement->content.syntax, 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.string = malloc(strlen(syntaxelement->content.string));
|
||||
strcpy(clone->content.string, syntaxelement->content.string);
|
||||
|
||||
if (syntaxelement->next != NULL)
|
||||
clone->next = se_clone(syntaxelement->next, newtop);
|
||||
|
||||
break;
|
||||
|
||||
case NONE:
|
||||
case NEWTREE:
|
||||
|
||||
clone = se_create();
|
||||
clone->type = syntaxelement->type;
|
||||
clone->top = newtop;
|
||||
|
||||
if (syntaxelement->next != NULL)
|
||||
clone->next = se_clone(syntaxelement->next, newtop);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
16
src/syntax.h
16
src/syntax.h
@ -1,34 +1,50 @@
|
||||
#ifndef SYNTAX_H
|
||||
#define SYNTAX_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
enum SyntaxElementType {
|
||||
|
||||
NEWTREE,
|
||||
TREE,
|
||||
TOKEN,
|
||||
STRING,
|
||||
NONE
|
||||
|
||||
};
|
||||
|
||||
typedef union {
|
||||
|
||||
struct SyntaxElement* syntax;
|
||||
char* string;
|
||||
void* none;
|
||||
|
||||
} tSyntaxContent;
|
||||
|
||||
typedef struct SyntaxElement {
|
||||
|
||||
enum SyntaxElementType type;
|
||||
tSyntaxContent content;
|
||||
struct SyntaxElement* next;
|
||||
struct SyntaxElement* top;
|
||||
|
||||
} tSyntaxElement;
|
||||
|
||||
|
||||
void se_free(tSyntaxElement*);
|
||||
|
||||
bool se_istraversable(tSyntaxElement*);
|
||||
|
||||
tSyntaxElement* se_create(void);
|
||||
|
||||
tSyntaxElement* se_init(void);
|
||||
|
||||
tSyntaxElement* se_bottom(tSyntaxElement*);
|
||||
|
||||
tSyntaxElement* se_next(tSyntaxElement*);
|
||||
|
||||
tSyntaxElement* se_clone(tSyntaxElement*, tSyntaxElement*);
|
||||
|
||||
tSyntaxElement* se_clone_no_next(tSyntaxElement*, tSyntaxElement*);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user