diff --git a/Syntac/private/book.c b/Syntac/private/book.c new file mode 100644 index 0000000..d73fdd4 --- /dev/null +++ b/Syntac/private/book.c @@ -0,0 +1,96 @@ +#include +#include + +#include "syntac_private.h" +#include "../../helpers/string/handy.h" +#include "../../helpers/log/warn.h" + +//Allocate an Empty Rule Book +SyntacBook * SyntacBookAllocate() { + SyntacBook *book = malloc(sizeof(struct stc_book)); + + book->rules = NULL; + book->rule_count = 0; + + return book; +} + +//Free a rule book (assumes everything within the rulebook and rules is dynamically allocated) +void SyntacBookFree(SyntacBook *book) { + if (book == NULL) { + HLTWarn("SyntacBookFree. Supplied book pointer was null?", 0, 0, HLT_STDWRN); + return; + } + + for (int i = 0; i< book->rule_count; i++){ + struct stc_rule *rule = &book->rules[i]; + if (rule == NULL) { + HLTWarn("SyntacBookFree. Rule pointer was null?", 0, 0, HLT_MJRWRN); + continue; + } + + free(rule->name); rule->name = NULL; + for (int j = 0; rule->elements[j] != NULL; j++) { + free(rule->elements[j]); //free all elements inside + } + free(rule->elements); rule->elements = NULL; //free container + } + + if (book->rules != NULL) free(book->rules); + book->rules = NULL; book->rule_count = 0; + free(book); +} + +void SyntacBookRuleAdd(SyntacBook *book, char *left, char *right) { + if (book == NULL) { + HLTWarn("SyntacBookRuleAdd. Supplied book pointer was null?", 0, 0 HLT_STDWRN); + return; + } + + if (left == NULL || left[0] == '\0') { + HLTWarn("SyntacBookRuleAdd. Supplied left of rule was null/empty?", 0, 0, HLT_STDWRN); + return; + } + + if (right == NULL || left[0] == '\0') { + HLTWarn("SyntacBookRuleAdd. Supplied right of rule was null/empty?", 0, 0, HLT_STDWRN); + return; + } + + struct stc_rule *rule = malloc(sizeof(struct stc_rule)); + rule->name = calloc(strlen(left)+1, sizeof(char)); strcpy(left_copy, left); + + int elm_cnt = 0; bool lstwasSpace = true; + for (int i = 0; i < strlen(right); i++) { + if (isspace(right[i])) { + if (!lstspace) elm_cnt++; + lstwasSpace = true; + } else { + lstwasSpace = false; + } + } + + rule->elements = malloc(sizeof(char *) * (elm_cnt+1)); + rule->elements[elm_cnt] = NULL; + + //TODO: Actually parse out the elements (dynamically allocate them too) +} + +SyntacBook * SyntacBookFromFile(char *file_name, SyntacTreeType type){ + if (file_name == NULL || file_name[0] == '\0') { + HLTWarn("SyntacBookFromFile. Supplied file_name was null/empty?"); + return NULL; + } + + char *cntnts = ftostr(file_name); + + SyntacBook *book = SyntacBookFromString(cntnts); + + free(cntnts); + return book; +} + +SyntacBook * SyntacBookFromString(char *stream, SyntacTreeType type) { + //TODO +} + diff --git a/Syntac/private/syntac_private.h b/Syntac/private/syntac_private.h new file mode 100644 index 0000000..4406566 --- /dev/null +++ b/Syntac/private/syntac_private.h @@ -0,0 +1,21 @@ +#include "../syntac.h" + +#ifndef __HEPH_INTERNAL_PRIVATE_SYNTAC__ +#define __HEPH_INTERNAL_PRIVATE_SYNTAC__ + +//Rule Definition +// left -> right +// a -> b c +struct stc_rule { + char *name; //also the left part of the rule + char **elements; //also the right part of the rule (null-terminated) +}; + +//Rule Book +struct stc_book { + enum stc_parsing_style type; + struct stc_rule *rules; + int rule_count; +}; + +#endif diff --git a/Syntac/private/tree.c b/Syntac/private/tree.c new file mode 100644 index 0000000..d15ceee --- /dev/null +++ b/Syntac/private/tree.c @@ -0,0 +1,29 @@ +#include "syntac_private.h" +#include "../../helpers/log/warn.h" +#include "../../helpers/string/handy.h" + +SyntacTreeNode * SyntacTreeFromTokens(LexicToken *stream, Syntac *book) { + //TODO +} + +SyntacTreeNode * SyntacTreeFromStream(char **stream, SyntacBook *book) { + //TODO +} + +void SyntacTreeFree(SyntacTreeNode *tree) { + if (tree == NULL) { + HLTWarn("SyntacTreeFree. Supplied tree pointer was null?", 0, 0, HLT_STDWRN); + return; + } + + if (tree->children[0] != NULL) { + for (int i = 0; tree->children[i] != NULL; i++) { + SyntacTreeFree(tree->children[i]); + } + } + + free(tree->rule_name); tree->rule_name = NULL; + free(tree->contains); tree->contains = NULL; + + free(tree); +} diff --git a/Syntac/syntac.h b/Syntac/syntac.h index 4f81a14..d92128d 100644 --- a/Syntac/syntac.h +++ b/Syntac/syntac.h @@ -8,23 +8,32 @@ typedef struct lxc_token LexicToken; //Public facing container of grammatical rules typedef struct stc_book SyntacBook; +//Types of Grammar Trees +typedef enum stc_parsing_style { + STC_LL0 = 0, //Top-Down + STC_LL1, //Top-Down w/ Lookahead + STC_SLR, //Bottom-Up + STC_LALR, //Bottom-Up w/ Lookahead +} SyntacTreeType; + typedef struct stc_tree_node { + enum stc_parsing_style type; struct stc_tree_node *children; //null-terminated - char *rule_name; - char *contains; - int line_start; - int col_start; - int line_end; - int col_end; + char *rule_name; //Grammar Rule Name + char *contains; //Children in String Form + + int line_start, col_start; + int line_end, col_end; } SyntacTreeNode; /*----------------------------Books----------------------------*/ //Allocate and Populate a rule book from a file -SyntacBook * SyntacBookFromFile(char *file_name); +//Will verify the grammar rules correctness +SyntacBook * SyntacBookFromFile(char *file_name, SyntacTreeType type); //Allocate and Populate a rule book from a string stream -SyntacBook * SyntacBookFromString(char *stream); +SyntacBook * SyntacBookFromString(char *stream, SyntacTreeType type); //Allocate an empty rule book SyntacBook * SyntacBookAllocate(); @@ -42,7 +51,7 @@ void SyntacBookFree(SyntacBook *); SyntacTreeNode * SyntacTreeFromTokens(LexicToken *stream, SyntacBook *book); //Generate a Syntactical Tree representation of string stream -//Expects token string stream to be null-terminated (stream[x] == NULL) +//Expects token string stream to be null-terminated (stream[x] == NULL || stream[x][0] == 0) SyntacTreeNode * SyntacTreeFromStream(char **stream, SyntacBook *book); //Free a null-terminated Syntactical Tree