From 8335bbefe644ed13718d55d62230f506b981736a Mon Sep 17 00:00:00 2001 From: Sam Stevens Date: Tue, 5 Jun 2018 23:03:15 +0100 Subject: [PATCH] Updated language and started scanner. --- .idea/codeStyles/codeStyleConfig.xml | 5 + CMakeLists.txt | 2 +- Language.txt | 10 +- src/SQL.c | 169 +++++++++++++++--------- src/SQL.h | 189 +++++++++++++++------------ src/scanner.c | 94 +++++++++++++ src/scanner.h | 83 ++++++++++++ 7 files changed, 403 insertions(+), 149 deletions(-) create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 src/scanner.c create mode 100644 src/scanner.h diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 17fe73e..94df92e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,4 +3,4 @@ project(SDB C) set(CMAKE_C_STANDARD 11) -add_executable(SDB src/main.c src/InputBuffer.c src/InputBuffer.h src/SQL.c src/SQL.h) \ No newline at end of file +add_executable(SDB src/main.c src/InputBuffer.c src/InputBuffer.h src/SQL.c src/SQL.h src/scanner.c src/scanner.h) diff --git a/Language.txt b/Language.txt index 1ae9177..ddec3da 100644 --- a/Language.txt +++ b/Language.txt @@ -1,11 +1,13 @@ -Select A, B, C From X Where A = '1' +Select A, B, C From X Where A = '1' AND B <> 2 Insert Into X Set A = '1', B = 2, C = 'C' Update X Set A = '2' Where A = '1' Delete From X Where A = '1' Create Table X (A String(50) Index, B Int, C String(5)) Drop Table X +StatementList = StatementList, Statement | Statement ; Statement = SelectStmt | InsertStmt | UpdateStmt | DeleteStmt | CreateStmt | DropStmt ';' ; + SelectStmt = 'Select', FieldList, 'From', Identifier, AssignmentList ; InsertStmt = 'Insert Into', Identifier, 'Set', AssignmentList ; UpdateStmt = 'Update', Identifier, 'Set', AssignmentList, 'Where', AssignmentList ; @@ -22,5 +24,9 @@ FieldList = Identifier | FieldList, ',', Identifier ; AssignmentList = Assignment | AssignmentList, ',', Assignment ; Assignment = Identifier, '=', Value ; +ComparisonGroup = Comparison | ComparisonList, 'AND', Comparison +Comparison = Identifier, Comparator, Value; +Comparator = '=' | '<>'; + Identifier = { letter, '_' } , { letter | digit | '_' } ; -Value = "'" character ""'" | '"', character, '"' | number ; \ No newline at end of file +Value = "'", string, "'" | '"', string, '"' | number ; \ No newline at end of file diff --git a/src/SQL.c b/src/SQL.c index ef2c952..a2fda27 100644 --- a/src/SQL.c +++ b/src/SQL.c @@ -5,27 +5,66 @@ #include #include "SQL.h" -T_Value *new_t_value() { - T_Value *value = malloc(sizeof(T_Value)); +Value *new_value() { + Value *value = malloc(sizeof(Value)); value->number = 0; value->string = NULL; return value; } -void free_t_value(T_Value *value) { +void free_value(Value *value) { if (value->string != NULL) { free(value->string); } free(value); } -T_Assignment *new_t_assignment() { - T_Assignment *assignment = malloc(sizeof(T_Assignment)); +Comparison *new_comparison() { + Comparison* comparison = malloc(sizeof(Comparison)); + comparison->identifier = NULL; + comparison->value = NULL; + comparison->comp = COMP_NONE; + return comparison; +} +void free_comparison(Comparison *comparison) { + if (comparison->value != NULL) { + free(comparison->value); + } + if(comparison->identifier != NULL) { + free(comparison->identifier); + } + free(comparison); +} + +ComparisonGroup *new_comparision_group() { + ComparisonGroup *group = malloc(sizeof(ComparisonGroup)); + group->comparisons = NULL; + group->length = 0; + return group; +} +void free_comparison_group(ComparisonGroup* group) { + if (group->length > 0) { + for(size_t i=0; ilength; i++) { + free(group->comparisons[i]); + } + free(group->comparisons); + group->length = 0; + } + free(group); +} +void append_comparison_group(ComparisonGroup *group, Comparison *comparison) { + group->length++; + group->comparisons = realloc(group->comparisons, sizeof(Assignment) * group->length); + group->comparisons[group->length - 1] = comparison; +} + +Assignment *new_assignment() { + Assignment *assignment = malloc(sizeof(Assignment)); assignment->value = NULL; assignment->identifier = NULL; } -void free_t_assignment(T_Assignment *assignment) { +void free_assignment(Assignment *assignment) { if (assignment->identifier != NULL) { free(assignment->identifier); } @@ -35,17 +74,17 @@ void free_t_assignment(T_Assignment *assignment) { free(assignment); } -T_AssignmentList *new_t_assignment_list() { - T_AssignmentList *assignmentList = malloc(sizeof(T_AssignmentList)); +AssignmentList *new_assignment_list() { + AssignmentList *assignmentList = malloc(sizeof(AssignmentList)); assignmentList->assignments = NULL; assignmentList->length = 0; return assignmentList; } -void free_t_assignment_list(T_AssignmentList *assignmentList) { +void free_assignment_list(AssignmentList *assignmentList) { if (assignmentList->length > 0) { for (size_t i = 0; i < assignmentList->length; i++) { - free_t_assignment(assignmentList->assignments[i]); + free_assignment(assignmentList->assignments[i]); } free(assignmentList->assignments); assignmentList->length = 0; @@ -53,20 +92,20 @@ void free_t_assignment_list(T_AssignmentList *assignmentList) { free(assignmentList); } -void append_t_assignment_list(T_AssignmentList *list, T_Assignment *assignment) { +void append_assignment_list(AssignmentList *list, Assignment *assignment) { list->length++; - list->assignments = realloc(list->assignments, sizeof(T_Assignment) * list->length); + list->assignments = realloc(list->assignments, sizeof(Assignment) * list->length); list->assignments[list->length - 1] = assignment; } -T_FieldList *new_t_field_list() { - T_FieldList *list = malloc(sizeof(T_FieldList)); +FieldList *new_field_list() { + FieldList *list = malloc(sizeof(FieldList)); list->length = 0; list->fields = NULL; return list; } -void free_t_field_list(T_FieldList *list) { +void free_field_list(FieldList *list) { if (list->length > 0) { for (size_t i = 0; i < list->length; i++) { free(list->fields[i]); @@ -78,14 +117,14 @@ void free_t_field_list(T_FieldList *list) { free(list); } -void append_t_field_list(T_FieldList *list, char *field) { +void append_field_list(FieldList *list, char *field) { list->length++; list->fields = realloc(list->fields, sizeof(char *) * list->length); list->fields[list->length - 1] = field; } -T_ColumnSpec *new_t_column_spec() { - T_ColumnSpec *spec = malloc(sizeof(T_ColumnSpec)); +ColumnSpec *new_column_spec() { + ColumnSpec *spec = malloc(sizeof(ColumnSpec)); spec->identifier = NULL; spec->option = COLOPT_NONE; spec->size = 0; @@ -93,24 +132,24 @@ T_ColumnSpec *new_t_column_spec() { return spec; } -void free_t_column_spec(T_ColumnSpec *spec) { +void free_column_spec(ColumnSpec *spec) { if (spec->identifier != NULL) { free(spec->identifier); } free(spec); } -T_ColumnSpecList *new_t_column_spec_list() { - T_ColumnSpecList *list = malloc(sizeof(T_ColumnSpecList)); +ColumnSpecList *new_column_spec_list() { + ColumnSpecList *list = malloc(sizeof(ColumnSpecList)); list->length = 0; list->columns = NULL; return list; } -void free_t_column_spec_list(T_ColumnSpecList *list) { +void free_column_spec_list(ColumnSpecList *list) { if (list->length > 0) { for (size_t i = 0; i < list->length; i++) { - free_t_column_spec(list->columns[i]); + free_column_spec(list->columns[i]); } free(list->columns); list->columns = NULL; @@ -119,43 +158,43 @@ void free_t_column_spec_list(T_ColumnSpecList *list) { free(list); } -void append_t_column_spec_list(T_ColumnSpecList *list, T_ColumnSpec *spec) { +void append_column_spec_list(ColumnSpecList *list, ColumnSpec *spec) { list->length++; - list->columns = realloc(list->columns, sizeof(T_ColumnSpec) * list->length); + list->columns = realloc(list->columns, sizeof(ColumnSpec) * list->length); list->columns[list->length - 1] = spec; } -T_SelectStmt *new_t_select_stmt() { - T_SelectStmt *stmt = malloc(sizeof(T_SelectStmt)); +SelectStmt *new_select_stmt() { + SelectStmt *stmt = malloc(sizeof(SelectStmt)); stmt->fields = NULL; stmt->tableName = NULL; stmt->where = NULL; return stmt; } -void free_t_select_stmt(T_SelectStmt *stmt) { +void free_select_stmt(SelectStmt *stmt) { if (stmt->where != NULL) { - free_t_assignment_list(stmt->where); + free_assignment_list(stmt->where); } if (stmt->tableName != NULL) { free(stmt->tableName); } if (stmt->fields != NULL) { - free_t_field_list(stmt->fields); + free_field_list(stmt->fields); } free(stmt); } -T_InsertStmt *new_t_insert_stmt() { - T_InsertStmt *stmt = malloc(sizeof(T_InsertStmt)); +InsertStmt *new_insert_stmt() { + InsertStmt *stmt = malloc(sizeof(InsertStmt)); stmt->tableName = NULL; stmt->values = NULL; return stmt; } -void free_t_insert_stmt(T_InsertStmt *stmt) { +void free_insert_stmt(InsertStmt *stmt) { if (stmt->values != NULL) { - free_t_assignment_list(stmt->values); + free_assignment_list(stmt->values); } if (stmt->tableName != NULL) { free(stmt->tableName); @@ -163,99 +202,99 @@ void free_t_insert_stmt(T_InsertStmt *stmt) { free(stmt); } -T_UpdateStmt *new_t_update_stmt() { - T_UpdateStmt *stmt = malloc(sizeof(T_UpdateStmt)); +UpdateStmt *new_update_stmt() { + UpdateStmt *stmt = malloc(sizeof(UpdateStmt)); stmt->tableName = NULL; stmt->values = NULL; stmt->where = NULL; return stmt; } -void free_t_update_stmt(T_UpdateStmt *stmt) { +void free_update_stmt(UpdateStmt *stmt) { if (stmt->tableName != NULL) { free(stmt->tableName); } if (stmt->where != NULL) { - free_t_assignment_list(stmt->where); + free_assignment_list(stmt->where); } if (stmt->values != NULL) { - free_t_assignment_list(stmt->values); + free_assignment_list(stmt->values); } free(stmt); } -T_DeleteStmt *new_t_delete_stmt() { - T_DeleteStmt *stmt = malloc(sizeof(T_DeleteStmt)); +DeleteStmt *new_delete_stmt() { + DeleteStmt *stmt = malloc(sizeof(DeleteStmt)); stmt->tableName = NULL; stmt->where = NULL; } -void free_t_delete_stmt(T_DeleteStmt *stmt) { +void free_delete_stmt(DeleteStmt *stmt) { if (stmt->tableName != NULL) { free(stmt->tableName); } if (stmt->where != NULL) { - free_t_assignment_list(stmt->where); + free_assignment_list(stmt->where); } free(stmt); } -T_CreateStmt *new_t_create_stmt() { - T_CreateStmt *spec = malloc(sizeof(T_CreateStmt)); +CreateStmt *new_create_stmt() { + CreateStmt *spec = malloc(sizeof(CreateStmt)); spec->tableName = NULL; spec->columns = NULL; return spec; } -void free_t_create_stmt(T_CreateStmt *spec) { +void free_create_stmt(CreateStmt *spec) { if (spec->tableName != NULL) { free(spec->tableName); } if (spec->columns != NULL) { - free_t_column_spec_list(spec->columns); + free_column_spec_list(spec->columns); } free(spec); } -T_DropStmt *new_t_drop_stmt() { - T_DropStmt *stmt = malloc(sizeof(T_DropStmt)); +DropStmt *new_drop_stmt() { + DropStmt *stmt = malloc(sizeof(DropStmt)); stmt->tableName = NULL; return stmt; } -void free_t_drop_stmt(T_DropStmt *stmt) { +void free_drop_stmt(DropStmt *stmt) { if (stmt->tableName != NULL) { free(stmt->tableName); } free(stmt); } -T_Statement *new_t_statement() { - T_Statement *stmt = malloc(sizeof(T_Statement)); +Statement *new_statement() { + Statement *stmt = malloc(sizeof(Statement)); stmt->type = STMT_NONE; stmt->stmt = NULL; return stmt; } -void free_t_statement(T_Statement *stmt) { +void free_statement(Statement *stmt) { switch (stmt->type) { case STMT_SELECT: - free_t_select_stmt(stmt->stmt); + free_select_stmt(stmt->stmt); break; case STMT_INSERT: - free_t_insert_stmt(stmt->stmt); + free_insert_stmt(stmt->stmt); break; case STMT_UPDATE: - free_t_update_stmt(stmt->stmt); + free_update_stmt(stmt->stmt); break; case STMT_DELETE: - free_t_delete_stmt(stmt->stmt); + free_delete_stmt(stmt->stmt); break; case STMT_CREATE: - free_t_create_stmt(stmt->stmt); + free_create_stmt(stmt->stmt); break; case STMT_DROP: - free_t_drop_stmt(stmt->stmt); + free_drop_stmt(stmt->stmt); break; default: break; @@ -265,17 +304,17 @@ void free_t_statement(T_Statement *stmt) { free(stmt); } -T_StatementList *new_t_statement_list() { - T_StatementList *list = malloc(sizeof(T_StatementList)); +StatementList *new_statement_list() { + StatementList *list = malloc(sizeof(StatementList)); list->length = 0; list->statements = NULL; return list; } -void free_t_statement_list(T_StatementList *list) { +void free_statement_list(StatementList *list) { if (list->length > 0) { for (size_t i = 0; i < list->length; i++) { - free_t_statement(list->statements[i]); + free_statement(list->statements[i]); } free(list->statements); list->statements = NULL; @@ -284,8 +323,8 @@ void free_t_statement_list(T_StatementList *list) { free(list); } -void append_t_statement_list(T_StatementList *list, T_Statement *statement) { +void append_statement_list(StatementList *list, Statement *statement) { list->length++; - list->statements = realloc(list->statements, sizeof(T_Statement) * list->length); + list->statements = realloc(list->statements, sizeof(Statement) * list->length); list->statements[list->length - 1] = statement; } \ No newline at end of file diff --git a/src/SQL.h b/src/SQL.h index 2722970..9edeebf 100644 --- a/src/SQL.h +++ b/src/SQL.h @@ -7,149 +7,176 @@ #include -union T_Value_t { +union Value_t { char *string; int number; }; -typedef union T_Value_t T_Value; +typedef union Value_t Value; -T_Value *new_t_value(); +Value *new_value(); -void free_t_value(T_Value *value); +void free_value(Value *value); -struct T_Assignment_t { - char *identifier; - T_Value *value; +enum Comparator_t { + COMP_NONE, + COMP_EQ, + COMP_NEQ }; -typedef struct T_Assignment_t T_Assignment; +typedef enum Comparator_t Comparator; -T_Assignment *new_t_assignment(); +struct Comparison_t { + char *identifier; + Comparator comp; + Value *value; +}; +typedef struct Comparison_t Comparison; -void free_t_assignment(T_Assignment *assignment); +Comparison *new_comparison(); +void free_comparison(Comparison *comparison); -struct T_AssignmentList_t { - T_Assignment **assignments; +struct ComparisonGroup_t { + Comparison **comparisons; size_t length; }; -typedef struct T_AssignmentList_t T_AssignmentList; +typedef struct ComparisonGroup_t ComparisonGroup; -T_AssignmentList *new_t_assignment_list(); +ComparisonGroup *new_comparision_group(); +void free_comparison_group(ComparisonGroup* group); +void append_comparison_group(ComparisonGroup *group, Comparison *comparison); -void free_t_assignment_list(T_AssignmentList *assignmentList); +struct Assignment_t { + char *identifier; + Value *value; +}; +typedef struct Assignment_t Assignment; -void append_t_assignment_list(T_AssignmentList *list, T_Assignment *assignment); +Assignment *new_assignment(); -struct T_FieldList_t { +void free_assignment(Assignment *assignment); + +struct AssignmentList_t { + Assignment **assignments; + size_t length; +}; +typedef struct AssignmentList_t AssignmentList; + +AssignmentList *new_assignment_list(); + +void free_assignment_list(AssignmentList *assignmentList); + +void append_assignment_list(AssignmentList *list, Assignment *assignment); + +struct FieldList_t { char **fields; size_t length; }; -typedef struct T_FieldList_t T_FieldList; +typedef struct FieldList_t FieldList; -T_FieldList *new_t_field_list(); +FieldList *new_field_list(); -void free_t_field_list(T_FieldList *list); +void free_field_list(FieldList *list); -void append_t_field_list(T_FieldList *list, char *field); +void append_field_list(FieldList *list, char *field); -enum T_ColumnOption_t { +enum ColumnOption_t { COLOPT_NONE = 0, COLOPT_INDEX = 1 }; -typedef enum T_ColumnOption_t T_ColumnOption; +typedef enum ColumnOption_t ColumnOption; -enum T_ColumnType_t { +enum ColumnType_t { COLTYPE_NONE, COLTYPE_STRING, COLTYPE_INT }; -typedef enum T_ColumnType_t T_ColumnType; +typedef enum ColumnType_t ColumnType; -struct T_ColumnSpec_t { +struct ColumnSpec_t { char *identifier; - T_ColumnType type; + ColumnType type; size_t size; - T_ColumnOption option; + ColumnOption option; }; -typedef struct T_ColumnSpec_t T_ColumnSpec; +typedef struct ColumnSpec_t ColumnSpec; -T_ColumnSpec *new_t_column_spec(); +ColumnSpec *new_column_spec(); -void free_t_column_spec(T_ColumnSpec *spec); +void free_column_spec(ColumnSpec *spec); -struct T_ColumnSpecList_t { - T_ColumnSpec **columns; +struct ColumnSpecList_t { + ColumnSpec **columns; size_t length; }; -typedef struct T_ColumnSpecList_t T_ColumnSpecList; +typedef struct ColumnSpecList_t ColumnSpecList; -T_ColumnSpecList *new_t_column_spec_list(); +ColumnSpecList *new_column_spec_list(); -void free_t_column_spec_list(T_ColumnSpecList *list); +void free_column_spec_list(ColumnSpecList *list); -void append_t_column_spec_list(T_ColumnSpecList *list, T_ColumnSpec *spec); +void append_column_spec_list(ColumnSpecList *list, ColumnSpec *spec); -struct T_SelectStmt_t { - T_FieldList *fields; +struct SelectStmt_t { + FieldList *fields; char *tableName; - T_AssignmentList *where; + AssignmentList *where; }; -typedef struct T_SelectStmt_t T_SelectStmt; +typedef struct SelectStmt_t SelectStmt; -T_SelectStmt *new_t_select_stmt(); +SelectStmt *new_select_stmt(); -void free_t_select_stmt(T_SelectStmt *stmt); +void free_select_stmt(SelectStmt *stmt); -struct T_InsertStmt_t { +struct InsertStmt_t { char *tableName; - T_AssignmentList *values; + AssignmentList *values; }; -typedef struct T_InsertStmt_t T_InsertStmt; +typedef struct InsertStmt_t InsertStmt; -T_InsertStmt *new_t_insert_stmt(); +InsertStmt *new_insert_stmt(); -void free_t_insert_stmt(T_InsertStmt *stmt); +void free_insert_stmt(InsertStmt *stmt); -struct T_UpdateStmt_t { +struct UpdateStmt_t { char *tableName; - T_AssignmentList *values; - T_AssignmentList *where; + AssignmentList *values; + AssignmentList *where; }; -typedef struct T_UpdateStmt_t T_UpdateStmt; +typedef struct UpdateStmt_t UpdateStmt; -T_UpdateStmt *new_t_update_stmt(); +UpdateStmt *new_update_stmt(); -void free_t_update_stmt(T_UpdateStmt *stmt); +void free_update_stmt(UpdateStmt *stmt); -struct T_DeleteStmt_t { +struct DeleteStmt_t { char *tableName; - T_AssignmentList *where; + AssignmentList *where; }; -typedef struct T_DeleteStmt_t T_DeleteStmt; +typedef struct DeleteStmt_t DeleteStmt; -T_DeleteStmt *new_t_delete_stmt(); +DeleteStmt *new_delete_stmt(); -void free_t_delete_stmt(T_DeleteStmt *stmt); +void free_delete_stmt(DeleteStmt *stmt); -struct T_CreateStmt_t { +struct CreateStmt_t { char *tableName; - T_ColumnSpecList *columns; + ColumnSpecList *columns; }; -typedef struct T_CreateStmt_t T_CreateStmt; +typedef struct CreateStmt_t CreateStmt; -T_CreateStmt *new_t_create_stmt(); +CreateStmt *new_create_stmt(); -void free_t_create_stmt(T_CreateStmt *spec); +void free_create_stmt(CreateStmt *spec); -struct T_DropStmt_t { +struct DropStmt_t { char *tableName; }; -typedef struct T_DropStmt_t T_DropStmt; +typedef struct DropStmt_t DropStmt; -T_DropStmt *new_t_drop_stmt(); +DropStmt *new_drop_stmt(); -void free_t_drop_stmt(T_DropStmt *stmt); +void free_drop_stmt(DropStmt *stmt); -enum T_StatementType_t { +enum StatementType_t { STMT_NONE = 0, STMT_SELECT, STMT_INSERT, @@ -158,28 +185,28 @@ enum T_StatementType_t { STMT_CREATE, STMT_DROP }; -typedef enum T_StatementType_t T_StatementType; +typedef enum StatementType_t StatementType; -struct T_Statement_t { - T_StatementType type; +struct Statement_t { + StatementType type; void *stmt; }; -typedef struct T_Statement_t T_Statement; +typedef struct Statement_t Statement; -T_Statement *new_t_statement(); +Statement *new_statement(); -void free_t_statement(T_Statement *stmt); +void free_statement(Statement *stmt); -struct T_StatementList_t { - T_Statement **statements; +struct StatementList_t { + Statement **statements; size_t length; }; -typedef struct T_StatementList_t T_StatementList; +typedef struct StatementList_t StatementList; -T_StatementList *new_t_statement_list(); +StatementList *new_statement_list(); -void free_t_statement_list(T_StatementList *list); +void free_statement_list(StatementList *list); -void append_t_statement_list(T_StatementList *list, T_Statement *statement); +void append_statement_list(StatementList *list, Statement *statement); #endif //SDB_SQL_H diff --git a/src/scanner.c b/src/scanner.c new file mode 100644 index 0000000..0e199a3 --- /dev/null +++ b/src/scanner.c @@ -0,0 +1,94 @@ +// +// Created by Sam on 05/06/2018. +// + +#include +#include +#include +#include +#include "scanner.h" + +Scanner_Result *new_scanner_result() { + Scanner_Result *result = malloc(sizeof(Scanner_Result)); + result->token = T_NONE; + result->value_int = 0; + result->value_str = NULL; + return result; +} + +void free_scanner_result(Scanner_Result *result) { + if (result->value_str != NULL) { + free(result); + } + free(result); +} + +Scanner *new_scanner(char *input) { + Scanner *scanner = malloc(sizeof(Scanner)); + scanner->input = input; + scanner->pos = 0; + scanner->state = SCANSTATE_START; + return scanner; +} + +void free_scanner(Scanner *scanner) { + if (scanner->input != NULL) { + free(scanner->input); + } + free(scanner); +} + +void reuse_scanner(Scanner *scanner, char *input) { + scanner->state = SCANSTATE_START; + if (scanner->input != NULL) { + free(scanner->input); + } + scanner->input = input; + scanner->pos = 0; +} + +Scanner_Result *scanner_next_token(Scanner *scanner, Scanner_Result *result) { + if (scanner->state == SCANSTATE_DONE) { + return NULL; + } + //Consume white space + while (scanner_peek_char(scanner) != NULL && isblank(scanner_peek_char(scanner))) { + scanner->pos++; + } + //Check for end of string + if (scanner_peek_char(scanner) == NULL) { + scanner->state = SCANSTATE_DONE; + return NULL; + } +} + +char scanner_next_char(Scanner *scanner) { + char next = scanner->input[scanner->pos]; + if (next != NULL) { + scanner->pos++; + } + return next; +} + +char scanner_peek_char(Scanner *scanner) { + return scanner->input[scanner->pos]; +} + +bool scanner_match(Scanner *scanner, const char *text) { + char a = NULL; + char b = NULL; + size_t ai = scanner->pos; + size_t bi = 0; + + do { + b = text[bi++]; + //Match if we reach the end of text + if (b == NULL) { + scanner->pos = ai; //consume text from scanner input + return true; + } + a = scanner->input[ai++]; + } while (a != NULL && tolower(a) == tolower(b)); + + return false; +} \ No newline at end of file diff --git a/src/scanner.h b/src/scanner.h new file mode 100644 index 0000000..520d788 --- /dev/null +++ b/src/scanner.h @@ -0,0 +1,83 @@ +// +// Created by Sam on 05/06/2018. +// + +#ifndef SDB_SCANNER_H +#define SDB_SCANNER_H + +#include + +enum Scanner_Token_t { + T_NONE, + + //Values + T_STRING, + T_NUMBER, + T_IDENTIFIER, + + //Punctuation + T_COMMA, + T_SEMICOLON, + + //Comparators + T_COMP_EQ, + T_COMP_NEQ, + T_COMP_AND, + + //Keywords + K_SELECT, + K_FROM, + K_INSERT, + K_INTO, + K_SET, + K_UPDATE, + K_WHERE, + K_DELETE, + K_CREATE, + K_TABLE, + K_DROP, + K_STRING, + K_INT, + K_INDEX +}; +typedef enum Scanner_Token_t Scanner_Token; + +struct Scanner_Result_t { + Scanner_Token token; + char *value_str; + int value_int; +}; +typedef struct Scanner_Result_t Scanner_Result; + +Scanner_Result *new_scanner_result(); + +void free_scanner_result(Scanner_Result *result); + +enum Scanner_State_t { + SCANSTATE_START, + SCANSTATE_DONE +}; +typedef enum Scanner_State_t Scanner_State; + +struct Scanner_t { + char *input; + size_t pos; + Scanner_State state; +}; +typedef struct Scanner_t Scanner; + +Scanner *new_scanner(char *input); + +void free_scanner(Scanner *scanner); + +void reuse_scanner(Scanner *scanner, char *input); + +Scanner_Result *scanner_next_token(Scanner *scanner, Scanner_Result *result); + +char scanner_next_char(Scanner *scanner); + +char scanner_peek_char(Scanner *scanner); + +bool scanner_match(Scanner *scanner, const char *text); + +#endif //SDB_SCANNER_H