From 7906e6c4a8f52aa5e5769cb35d32b0926e41e0bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?b=CA=B0edoh=E2=82=82=20sw=C3=A9?= Date: Mon, 3 Jun 2024 01:48:09 +0500 Subject: [PATCH] Parser sort of works --- src/extstring.c | 55 +++++++++++++++++++++ src/extstring.h | 14 ++++++ src/main.c | 22 +++++++++ src/parser.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++ src/parser.h | 19 ++++++++ 5 files changed, 235 insertions(+) create mode 100644 src/extstring.c create mode 100644 src/extstring.h create mode 100644 src/main.c create mode 100644 src/parser.c create mode 100644 src/parser.h diff --git a/src/extstring.c b/src/extstring.c new file mode 100644 index 0000000..d4de042 --- /dev/null +++ b/src/extstring.c @@ -0,0 +1,55 @@ +#include +#include "extstring.h" + +void es_addsymbol(struct Extstring* string, char symbol) { + if (string == NULL) + return; + struct Extstring* ptr = string; + while (ptr->next != NULL) { + ptr = ptr->next; + }; + ptr->next = malloc(sizeof(struct Extstring)); + ptr->next->symbol = symbol; + return; +} + +int es_size(struct Extstring* string) { + int size; + struct Extstring* ptr = string; + for (size = 0; ptr != NULL; size++) { + ptr = ptr->next; + } + return size; +} + +void es_free(struct Extstring* string) { + if (string->next == NULL) { + free(string); + return; + } + struct Extstring* ptr = string; + struct Extstring* nextptr = ptr->next; + while (ptr->next != NULL) { + nextptr = ptr->next; + free(ptr); + ptr = nextptr; + } + free(ptr); +} + +struct SString* es_tostring(struct Extstring* string) { + struct Extstring* ptr = string; + int size = es_size(string) + 1; + struct SString* sstring = malloc(sizeof(struct SString)); + sstring->string = malloc(size); + sstring->size = size; + for (int i = 0; i != size; i++) { + if (ptr != NULL) { + sstring->string[i] = ptr->symbol; + ptr = ptr->next; + } + else + sstring->string[i] = 0; + } + return sstring; +} diff --git a/src/extstring.h b/src/extstring.h new file mode 100644 index 0000000..623ef45 --- /dev/null +++ b/src/extstring.h @@ -0,0 +1,14 @@ +struct Extstring { + char symbol; + struct Extstring* next; +}; + +struct SString { + int size; + char* string; +}; + +void es_addsymbol(struct Extstring* string, char symbol); +int es_size(struct Extstring* string); +void es_free(struct Extstring* string); +struct SString* es_tostring(struct Extstring* string); diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..32a6db6 --- /dev/null +++ b/src/main.c @@ -0,0 +1,22 @@ +#include +#include + +#include "parser.h" + + +int main(int argc, char *argv[]) { + FILE *file; + if (argc != 2) { + fprintf(stderr, + "Invalid usage!\n" + "%s FILENAME\n", argv[0]); + return 1; + } + file = fopen(argv[1],"r"); + struct SyntaxElement* code = parse(file); + if (code == NULL) { + fprintf(stderr, "Error during parsing.\n"); + return 1; + } + return 0; +} diff --git a/src/parser.c b/src/parser.c new file mode 100644 index 0000000..6e51529 --- /dev/null +++ b/src/parser.c @@ -0,0 +1,125 @@ +#include +#include +#include +#include + +#include "parser.h" +#include "extstring.h" + +struct SyntaxElement* parse(FILE* file) { + struct SyntaxElement* syntaxtree = malloc(sizeof(struct SyntaxElement)); + struct SyntaxElement* syntaxtreestart = syntaxtree; + syntaxtree->type = TOPTREE; + syntaxtree->next = NULL; + syntaxtree->content = NULL; + syntaxtree->top = NULL; + char symbol; + bool intree = false; + bool incomment = false; + bool instring = false; + bool intoken = false; + struct Extstring* token; + while (1) { + symbol = fgetc(file); + if (feof(file)) + break; + if (incomment) { + if (symbol == '\n') + incomment = false; + continue; + } + if (instring) { + // TODO: String parsing + fprintf(stderr, "TODO: String parsing\n"); + return NULL; + } + if (intoken) { + if (isspace(symbol) || symbol == '(' || symbol == ')') { + intoken = false; + syntaxtree->type = TOKEN; + syntaxtree->content = es_tostring(token)->string; + es_free(token); + token = NULL; + continue; + } else { + es_addsymbol(token, symbol); + continue; + } + } + if (isspace(symbol)) + continue; + if (intree) { + switch (symbol) { + case '(': + syntaxtree->content = malloc(sizeof(struct SyntaxElement)); + ((struct SyntaxElement*)syntaxtree->content)->top = syntaxtree; + syntaxtree = syntaxtree->content; + syntaxtree->content = NULL; + syntaxtree->next = NULL; + syntaxtree->type = TREE; + break; + case ')': + if (syntaxtree->top->type == TOPTREE) { + intree = false; + syntaxtree = syntaxtree->top; + syntaxtree->next = malloc(sizeof(struct SyntaxElement)); + syntaxtree = syntaxtree->next; + syntaxtree->type = TOPTREE; + syntaxtree->content = NULL; + syntaxtree->next = NULL; + syntaxtree->top = NULL; + } else { + syntaxtree = syntaxtree->top; + syntaxtree->next = malloc(sizeof(struct SyntaxElement)); + syntaxtree->next->top = syntaxtree->top; + syntaxtree = syntaxtree->next; + syntaxtree->type = TREE; + syntaxtree->content = NULL; + syntaxtree->next = NULL; + } + break; + default: + token = malloc(sizeof(struct Extstring)); + token->symbol = symbol; + intoken = true; + break; + } + continue; + } else { + switch (symbol) { + case ')': + fprintf(stderr, "Unbalanced brackets.\n"); + return NULL; + case ';': + incomment = true; + continue; + case '(': + intree = true; + syntaxtree->content = malloc(sizeof(struct SyntaxElement)); + ((struct SyntaxElement*)syntaxtree->content)->top = syntaxtree; + syntaxtree = syntaxtree->content; + syntaxtree->content = NULL; + syntaxtree->next = NULL; + syntaxtree->type = TREE; + continue; + default: + fprintf(stderr, "Expression outside of brackets.\n"); + return NULL; + } + } + } + if (intree) { + fprintf(stderr, "Unexpected EOF.\n"); + return NULL; + } + syntaxtree = syntaxtreestart; + while (1) { + if (syntaxtree->next->next == NULL) { + free(syntaxtree->next); + syntaxtree->next = NULL; + break; + } + syntaxtree = syntaxtree->next; + } + return syntaxtreestart; +} diff --git a/src/parser.h b/src/parser.h new file mode 100644 index 0000000..cdb773a --- /dev/null +++ b/src/parser.h @@ -0,0 +1,19 @@ +#include + +enum SyntaxElementType { + TOPTREE, + TREE, + TOKEN, + STRING, + NUMBER, + NONE +}; + +struct SyntaxElement { + enum SyntaxElementType type; + void* content; + struct SyntaxElement* next; + struct SyntaxElement* top; +}; + +struct SyntaxElement* parse(FILE* file);