Adding tables
This commit is contained in:
@@ -17,7 +17,7 @@ DropStmt = 'Drop Table', Identifier ;
|
|||||||
|
|
||||||
ColumnSpecList = ColumnSpec | ColumnSpecList, ',', ColumnSpec ;
|
ColumnSpecList = ColumnSpec | ColumnSpecList, ',', ColumnSpec ;
|
||||||
ColumnSpec = Identifier, ColumnType | Identifier, ColumnType, ColumnOption ;
|
ColumnSpec = Identifier, ColumnType | Identifier, ColumnType, ColumnOption ;
|
||||||
ColumnType = 'String', '(', number, ')' | 'Int' | 'Integer' ;
|
ColumnType = 'String', '(', integer, ')' | 'Int' | 'Integer' ;
|
||||||
ColumnOption = 'Index' ;
|
ColumnOption = 'Index' ;
|
||||||
|
|
||||||
FieldList = Identifier | FieldList, ',', Identifier ;
|
FieldList = Identifier | FieldList, ',', Identifier ;
|
||||||
@@ -29,4 +29,4 @@ Comparison = Identifier, Comparator, Value;
|
|||||||
Comparator = '=' | '<>';
|
Comparator = '=' | '<>';
|
||||||
|
|
||||||
Identifier = { letter, '_' } , { letter | digit | '_' } ;
|
Identifier = { letter, '_' } , { letter | digit | '_' } ;
|
||||||
Value = "'", string, "'" | '"', string, '"' | number ;
|
Value = "'", string, "'" | '"', string, '"' | integer ;
|
||||||
@@ -7,7 +7,7 @@ add_library(SDBLib STATIC
|
|||||||
scanner.c scanner.h
|
scanner.c scanner.h
|
||||||
parser.c parser.h
|
parser.c parser.h
|
||||||
bplus_tree.c bplus_tree.h
|
bplus_tree.c bplus_tree.h
|
||||||
../lib/MurmurHash3.c ../lib/MurmurHash3.h random.c random.h)
|
../lib/MurmurHash3.c ../lib/MurmurHash3.h random.c random.h Table.c Table.h)
|
||||||
|
|
||||||
add_executable(SDB main.c)
|
add_executable(SDB main.c)
|
||||||
target_link_libraries(SDB SDBLib)
|
target_link_libraries(SDB SDBLib)
|
||||||
30
src/SQL.c
30
src/SQL.c
@@ -5,12 +5,15 @@
|
|||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
#include "SQL.h"
|
#include "SQL.h"
|
||||||
|
#include "MurmurHash3.h"
|
||||||
|
#include "random.h"
|
||||||
|
|
||||||
Value *new_value() {
|
Value *new_value() {
|
||||||
Value *value = malloc(sizeof(Value));
|
Value *value = malloc(sizeof(Value));
|
||||||
value->type = VALUE_NONE;
|
value->type = VALUE_NONE;
|
||||||
value->number = 0;
|
value->integer = 0;
|
||||||
value->string = NULL;
|
value->string = NULL;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@@ -32,7 +35,7 @@ Comparison *new_comparison() {
|
|||||||
|
|
||||||
void free_comparison(Comparison *comparison) {
|
void free_comparison(Comparison *comparison) {
|
||||||
if (comparison->value != NULL) {
|
if (comparison->value != NULL) {
|
||||||
free(comparison->value);
|
free_value(comparison->value);
|
||||||
}
|
}
|
||||||
if (comparison->identifier != NULL) {
|
if (comparison->identifier != NULL) {
|
||||||
free(comparison->identifier);
|
free(comparison->identifier);
|
||||||
@@ -50,7 +53,7 @@ ComparisonGroup *new_comparision_group() {
|
|||||||
void free_comparison_group(ComparisonGroup *group) {
|
void free_comparison_group(ComparisonGroup *group) {
|
||||||
if (group->length > 0) {
|
if (group->length > 0) {
|
||||||
for (size_t i = 0; i < group->length; i++) {
|
for (size_t i = 0; i < group->length; i++) {
|
||||||
free(group->comparisons[i]);
|
free_comparison(group->comparisons[i]);
|
||||||
}
|
}
|
||||||
free(group->comparisons);
|
free(group->comparisons);
|
||||||
group->length = 0;
|
group->length = 0;
|
||||||
@@ -131,6 +134,8 @@ void append_field_list(FieldList *list, char *field) {
|
|||||||
|
|
||||||
ColumnSpec *new_column_spec() {
|
ColumnSpec *new_column_spec() {
|
||||||
ColumnSpec *spec = malloc(sizeof(ColumnSpec));
|
ColumnSpec *spec = malloc(sizeof(ColumnSpec));
|
||||||
|
spec->id = 0;
|
||||||
|
spec->rowOffset = 0;
|
||||||
spec->identifier = NULL;
|
spec->identifier = NULL;
|
||||||
spec->option = COLOPT_NONE;
|
spec->option = COLOPT_NONE;
|
||||||
spec->size = 0;
|
spec->size = 0;
|
||||||
@@ -145,6 +150,17 @@ void free_column_spec(ColumnSpec *spec) {
|
|||||||
free(spec);
|
free(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t column_spec_data_size(ColumnSpec *spec) {
|
||||||
|
switch (spec->type) {
|
||||||
|
case COLTYPE_CHAR:
|
||||||
|
return (sizeof(char) * spec->size) + 1;
|
||||||
|
case COLTYPE_INT:
|
||||||
|
return sizeof(uint64_t);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnSpecList *new_column_spec_list() {
|
ColumnSpecList *new_column_spec_list() {
|
||||||
ColumnSpecList *list = malloc(sizeof(ColumnSpecList));
|
ColumnSpecList *list = malloc(sizeof(ColumnSpecList));
|
||||||
list->length = 0;
|
list->length = 0;
|
||||||
@@ -427,8 +443,8 @@ void print_comparison_group(ComparisonGroup *group) {
|
|||||||
void print_column_spec_list(ColumnSpecList *list) {
|
void print_column_spec_list(ColumnSpecList *list) {
|
||||||
for (size_t i = 0; i < list->length; i++) {
|
for (size_t i = 0; i < list->length; i++) {
|
||||||
ColumnSpec *spec = list->columns[i];
|
ColumnSpec *spec = list->columns[i];
|
||||||
if (spec->type == COLTYPE_STRING) {
|
if (spec->type == COLTYPE_CHAR) {
|
||||||
printf("%s STRING(%ld)", spec->identifier, spec->size);
|
printf("%s CHAR(%ld)", spec->identifier, spec->size);
|
||||||
} else if (spec->type == COLTYPE_INT) {
|
} else if (spec->type == COLTYPE_INT) {
|
||||||
printf("%s INTEGER", spec->identifier);
|
printf("%s INTEGER", spec->identifier);
|
||||||
}
|
}
|
||||||
@@ -469,7 +485,7 @@ void print_value(Value *value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("'");
|
printf("'");
|
||||||
} else if (value->type == VALUE_NUMBER) {
|
} else if (value->type == VALUE_INTEGER) {
|
||||||
printf("%ld", value->number);
|
printf("%ld", value->integer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
10
src/SQL.h
10
src/SQL.h
@@ -11,14 +11,14 @@
|
|||||||
enum ValueType_t {
|
enum ValueType_t {
|
||||||
VALUE_NONE,
|
VALUE_NONE,
|
||||||
VALUE_STRING,
|
VALUE_STRING,
|
||||||
VALUE_NUMBER
|
VALUE_INTEGER
|
||||||
};
|
};
|
||||||
typedef enum ValueType_t ValueType;
|
typedef enum ValueType_t ValueType;
|
||||||
|
|
||||||
struct Value_t {
|
struct Value_t {
|
||||||
ValueType type;
|
ValueType type;
|
||||||
char *string;
|
char *string;
|
||||||
int64_t number;
|
int64_t integer;
|
||||||
};
|
};
|
||||||
typedef struct Value_t Value;
|
typedef struct Value_t Value;
|
||||||
|
|
||||||
@@ -98,12 +98,14 @@ typedef enum ColumnOption_t ColumnOption;
|
|||||||
|
|
||||||
enum ColumnType_t {
|
enum ColumnType_t {
|
||||||
COLTYPE_NONE,
|
COLTYPE_NONE,
|
||||||
COLTYPE_STRING,
|
COLTYPE_CHAR,
|
||||||
COLTYPE_INT
|
COLTYPE_INT
|
||||||
};
|
};
|
||||||
typedef enum ColumnType_t ColumnType;
|
typedef enum ColumnType_t ColumnType;
|
||||||
|
|
||||||
struct ColumnSpec_t {
|
struct ColumnSpec_t {
|
||||||
|
uint16_t id;
|
||||||
|
size_t rowOffset;
|
||||||
char *identifier;
|
char *identifier;
|
||||||
ColumnType type;
|
ColumnType type;
|
||||||
size_t size;
|
size_t size;
|
||||||
@@ -115,6 +117,8 @@ ColumnSpec *new_column_spec();
|
|||||||
|
|
||||||
void free_column_spec(ColumnSpec *spec);
|
void free_column_spec(ColumnSpec *spec);
|
||||||
|
|
||||||
|
size_t column_spec_data_size(ColumnSpec *spec);
|
||||||
|
|
||||||
struct ColumnSpecList_t {
|
struct ColumnSpecList_t {
|
||||||
ColumnSpec **columns;
|
ColumnSpec **columns;
|
||||||
size_t length;
|
size_t length;
|
||||||
|
|||||||
173
src/Table.c
Normal file
173
src/Table.c
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
//
|
||||||
|
// Created by sam on 07/12/2019.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "Table.h"
|
||||||
|
|
||||||
|
TableIndex *new_table_index() {
|
||||||
|
TableIndex *index = malloc(sizeof(TableIndex));
|
||||||
|
index->name = NULL;
|
||||||
|
index->columnId = 0;
|
||||||
|
index->tree = NULL;
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_table_index(TableIndex *index) {
|
||||||
|
if (index->name != NULL) {
|
||||||
|
free(index->name);
|
||||||
|
}
|
||||||
|
if (index->tree != NULL) {
|
||||||
|
free_bplus_tree(index->tree);
|
||||||
|
}
|
||||||
|
free(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
TableIndexList *new_table_index_list() {
|
||||||
|
TableIndexList *list = malloc(sizeof(TableIndexList));
|
||||||
|
list->indexes = NULL;
|
||||||
|
list->length = 0;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_table_index_list(TableIndexList *list) {
|
||||||
|
if (list->length > 0) {
|
||||||
|
for (size_t i = 0; i < list->length; i++) {
|
||||||
|
free_table_index(list->indexes[i]);
|
||||||
|
}
|
||||||
|
free(list->indexes);
|
||||||
|
}
|
||||||
|
free(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
void append_table_index_list(TableIndexList *list, TableIndex *index) {
|
||||||
|
list->length++;
|
||||||
|
list->indexes = realloc(list->indexes, sizeof(TableIndex *) * list->length);
|
||||||
|
list->indexes[list->length - 1] = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void table_index_list_remove(TableIndexList *list, TableIndex *index) {
|
||||||
|
if (list->length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < list->length; i++) {
|
||||||
|
if (list->indexes[i] == index) {
|
||||||
|
while (i + 1 < list->length) {
|
||||||
|
list->indexes[i] = list->indexes[i + 1];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
list->length--;
|
||||||
|
list->indexes = realloc(list->indexes, sizeof(TableIndex *) * list->length);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TableIndex *table_index_list_get(TableIndexList *list, uint16_t columnId) {
|
||||||
|
if (list->length == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < list->length; i++) {
|
||||||
|
if (list->indexes[i]->columnId == columnId) {
|
||||||
|
return list->indexes[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TableRow *new_table_row() {
|
||||||
|
TableRow *row = malloc(sizeof(TableRow));
|
||||||
|
row->rowId = 0;
|
||||||
|
row->data = NULL;
|
||||||
|
row->next = NULL;
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_table_row(TableRow *row) {
|
||||||
|
if (row->data != NULL) {
|
||||||
|
free(row->data);
|
||||||
|
}
|
||||||
|
free(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
Table *new_table() {
|
||||||
|
Table *table = malloc(sizeof(Table));
|
||||||
|
table->name = NULL;
|
||||||
|
table->columns = NULL;
|
||||||
|
table->columnLength = 0;
|
||||||
|
table->indexes = new_table_index_list();
|
||||||
|
table->rowCount = 0;
|
||||||
|
table->rowSize = 0;
|
||||||
|
table->rowFirst = NULL;
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_table(Table *table) {
|
||||||
|
if (table->name != NULL) {
|
||||||
|
free(table->name);
|
||||||
|
}
|
||||||
|
if (table->columns != NULL) {
|
||||||
|
for (size_t i = 0; i < table->columnLength; i++) {
|
||||||
|
free_column_spec(table->columns[i]);
|
||||||
|
}
|
||||||
|
free(table->columns);
|
||||||
|
table->columnLength = 0;
|
||||||
|
}
|
||||||
|
if (table->indexes != NULL) {
|
||||||
|
free_table_index_list(table->indexes);
|
||||||
|
}
|
||||||
|
if (table->rowFirst != NULL) {
|
||||||
|
TableRow *row = table->rowFirst;
|
||||||
|
do {
|
||||||
|
TableRow *temp = row;
|
||||||
|
row = row->next;
|
||||||
|
free_table_row(temp);
|
||||||
|
} while (row == NULL);
|
||||||
|
}
|
||||||
|
free(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t table_determine_row_size(Table *table) {
|
||||||
|
size_t minSize = 0;
|
||||||
|
for (size_t i = 0; i < table->columnLength; i++) {
|
||||||
|
minSize += column_spec_data_size(table->columns[i]);
|
||||||
|
}
|
||||||
|
size_t rowSize = 0;
|
||||||
|
while (minSize > rowSize) rowSize += TABLE_PAGE_SIZE;
|
||||||
|
return rowSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
TableRow *table_new_row(Table *table) {
|
||||||
|
TableRow *row = new_table_row();
|
||||||
|
row->data = calloc(1, table->rowSize);
|
||||||
|
if (table->rowFirst == NULL) {
|
||||||
|
table->rowFirst = row;
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
TableRow *lastRow = table->rowFirst;
|
||||||
|
while (lastRow->next != NULL) {
|
||||||
|
lastRow = lastRow->next;
|
||||||
|
}
|
||||||
|
lastRow->next = row;
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
void table_add_column(Table *table, ColumnSpec *spec) {
|
||||||
|
table->columnLength++;
|
||||||
|
table->columns = realloc(table->columns, sizeof(ColumnSpec) * table->columnLength);
|
||||||
|
table->columns[table->columnLength - 1] = spec;
|
||||||
|
table->rowSize = table_determine_row_size(table);
|
||||||
|
spec->id = table->columnLength - 1;
|
||||||
|
if (spec->id > 0) {
|
||||||
|
ColumnSpec *previousColumn = table->columns[spec->id - 1];
|
||||||
|
spec->rowOffset = previousColumn->rowOffset + column_spec_data_size(previousColumn);
|
||||||
|
} else {
|
||||||
|
spec->rowOffset = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* table_row_column_data(Table *table, TableRow *row, uint16_t columnId) {
|
||||||
|
assert(columnId < table->columnLength);
|
||||||
|
ColumnSpec *columnSpec = table->columns[columnId];
|
||||||
|
return row->data + columnSpec->rowOffset;
|
||||||
|
}
|
||||||
74
src/Table.h
Normal file
74
src/Table.h
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
//
|
||||||
|
// Created by sam on 07/12/2019.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SDB_TABLE_H
|
||||||
|
#define SDB_TABLE_H
|
||||||
|
|
||||||
|
#include "SQL.h"
|
||||||
|
#include "bplus_tree.h"
|
||||||
|
|
||||||
|
#define TABLE_PAGE_SIZE 4096
|
||||||
|
|
||||||
|
struct TableIndex_t {
|
||||||
|
char *name;
|
||||||
|
uint16_t columnId;
|
||||||
|
BPlusTree *tree;
|
||||||
|
};
|
||||||
|
typedef struct TableIndex_t TableIndex;
|
||||||
|
|
||||||
|
TableIndex *new_table_index();
|
||||||
|
|
||||||
|
void free_table_index(TableIndex *index);
|
||||||
|
|
||||||
|
struct TableIndexList_t {
|
||||||
|
TableIndex **indexes;
|
||||||
|
size_t length;
|
||||||
|
};
|
||||||
|
typedef struct TableIndexList_t TableIndexList;
|
||||||
|
|
||||||
|
TableIndexList *new_table_index_list();
|
||||||
|
|
||||||
|
void free_table_index_list(TableIndexList *list);
|
||||||
|
|
||||||
|
void append_table_index_list(TableIndexList *list, TableIndex *index);
|
||||||
|
|
||||||
|
void table_index_list_remove(TableIndexList *list, TableIndex *index);
|
||||||
|
|
||||||
|
TableIndex *table_index_list_get(TableIndexList *list, uint16_t columnId);
|
||||||
|
|
||||||
|
struct TableRow_t {
|
||||||
|
uint64_t rowId;
|
||||||
|
struct TableRow_t *next;
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
typedef struct TableRow_t TableRow;
|
||||||
|
|
||||||
|
TableRow *new_table_row();
|
||||||
|
|
||||||
|
void free_table_row(TableRow *row);
|
||||||
|
|
||||||
|
struct Table_t {
|
||||||
|
char *name;
|
||||||
|
ColumnSpec **columns;
|
||||||
|
size_t columnLength;
|
||||||
|
TableIndexList *indexes;
|
||||||
|
size_t rowSize;
|
||||||
|
size_t rowCount;
|
||||||
|
TableRow *rowFirst;
|
||||||
|
};
|
||||||
|
typedef struct Table_t Table;
|
||||||
|
|
||||||
|
Table *new_table();
|
||||||
|
|
||||||
|
void free_table(Table *table);
|
||||||
|
|
||||||
|
void table_add_column(Table *table, ColumnSpec *spec);
|
||||||
|
|
||||||
|
size_t table_determine_row_size(Table *table);
|
||||||
|
|
||||||
|
TableRow *table_new_row(Table *table);
|
||||||
|
|
||||||
|
void* table_row_column_data(Table *table, TableRow *row, uint16_t columnId);
|
||||||
|
|
||||||
|
#endif //SDB_TABLE_H
|
||||||
@@ -77,7 +77,7 @@ bool bplus_node_insert_kv(BPlusNode *node, BPlusKV *kv) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Find an index where we should insert
|
//Find an tree where we should insert
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < node->keyCount; i++) {
|
for (i = 0; i < node->keyCount; i++) {
|
||||||
if (kv->key < node->keys[i]->key) {
|
if (kv->key < node->keys[i]->key) {
|
||||||
|
|||||||
26
src/parser.c
26
src/parser.c
@@ -163,8 +163,8 @@ ColumnSpecList *parser_node_convert_column_spec_list(ParserNode *node) {
|
|||||||
append_column_spec_list(list, spec);
|
append_column_spec_list(list, spec);
|
||||||
spec->identifier = strdup(specNode->token->valueStr);
|
spec->identifier = strdup(specNode->token->valueStr);
|
||||||
ParserNode *colTypeNode = specNode->children[0];
|
ParserNode *colTypeNode = specNode->children[0];
|
||||||
if (colTypeNode->token->type == T_KW_STRING) {
|
if (colTypeNode->token->type == T_KW_CHAR) {
|
||||||
spec->type = COLTYPE_STRING;
|
spec->type = COLTYPE_CHAR;
|
||||||
spec->size = (size_t)colTypeNode->children[0]->token->valueInt;
|
spec->size = (size_t)colTypeNode->children[0]->token->valueInt;
|
||||||
} else if (colTypeNode->token->type == T_KW_INT) {
|
} else if (colTypeNode->token->type == T_KW_INT) {
|
||||||
spec->type = COLTYPE_INT;
|
spec->type = COLTYPE_INT;
|
||||||
@@ -212,9 +212,9 @@ Value *parser_node_convert_value(ParserNode *node) {
|
|||||||
if (node->token->type == T_STRING) {
|
if (node->token->type == T_STRING) {
|
||||||
value->type = VALUE_STRING;
|
value->type = VALUE_STRING;
|
||||||
value->string = strdup(node->token->valueStr);
|
value->string = strdup(node->token->valueStr);
|
||||||
} else if (node->token->type == T_NUMBER) {
|
} else if (node->token->type == T_INTEGER) {
|
||||||
value->type = VALUE_NUMBER;
|
value->type = VALUE_INTEGER;
|
||||||
value->number = node->token->valueInt;
|
value->integer = node->token->valueInt;
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@@ -536,22 +536,22 @@ ParserNode *parser_parse(Parser *parser, Scanner *scanner) {
|
|||||||
token = NULL;
|
token = NULL;
|
||||||
append_parser_node(node, columnSpec);
|
append_parser_node(node, columnSpec);
|
||||||
NEXT_TOKEN();
|
NEXT_TOKEN();
|
||||||
if (token == NULL || (token->type != T_KW_STRING && token->type != T_KW_INT)) {
|
if (token == NULL || (token->type != T_KW_CHAR && token->type != T_KW_INT)) {
|
||||||
parser_set_error(parser, "Expected one of STRING, INT, INTEGER", token);
|
parser_set_error(parser, "Expected one of STRING, INT, INTEGER", token);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (token->type == T_KW_STRING) {
|
if (token->type == T_KW_CHAR) {
|
||||||
ParserNode *columnType = new_parser_node(NODE_COLUMN_TYPE, token);
|
ParserNode *columnType = new_parser_node(NODE_COLUMN_TYPE, token);
|
||||||
token = NULL;
|
token = NULL;
|
||||||
append_parser_node(columnSpec, columnType);
|
append_parser_node(columnSpec, columnType);
|
||||||
EXPECT(T_PAREN_OPEN);
|
EXPECT(T_PAREN_OPEN);
|
||||||
NEXT_TOKEN();
|
NEXT_TOKEN();
|
||||||
if (token == NULL || token->type != T_NUMBER) {
|
if (token == NULL || token->type != T_INTEGER) {
|
||||||
parser_set_error(parser, "Expected number", token);
|
parser_set_error(parser, "Expected integer", token);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (token->valueInt < 1) {
|
if (token->valueInt < 1) {
|
||||||
parser_set_error(parser, "Expected positive number", token);
|
parser_set_error(parser, "Expected positive integer", token);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
append_parser_node(columnType, new_parser_node(NODE_COLUMN_TYPE_SPECIFIER, token));
|
append_parser_node(columnType, new_parser_node(NODE_COLUMN_TYPE_SPECIFIER, token));
|
||||||
@@ -599,7 +599,7 @@ ParserNode *parser_parse(Parser *parser, Scanner *scanner) {
|
|||||||
append_parser_node(node, assignment);
|
append_parser_node(node, assignment);
|
||||||
EXPECT(T_COMP_EQ);
|
EXPECT(T_COMP_EQ);
|
||||||
NEXT_TOKEN();
|
NEXT_TOKEN();
|
||||||
if (token == NULL || (token->type != T_STRING && token->type != T_NUMBER)) {
|
if (token == NULL || (token->type != T_STRING && token->type != T_INTEGER)) {
|
||||||
parser_set_error(parser, "Expected value", token);
|
parser_set_error(parser, "Expected value", token);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -669,7 +669,7 @@ ParserNode *parser_parse(Parser *parser, Scanner *scanner) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (token->type == T_STRING || token->type == T_NUMBER) {
|
if (token->type == T_STRING || token->type == T_INTEGER) {
|
||||||
append_parser_node(node, new_parser_node(NODE_VALUE, token));
|
append_parser_node(node, new_parser_node(NODE_VALUE, token));
|
||||||
token = NULL;
|
token = NULL;
|
||||||
node->phase = -1;
|
node->phase = -1;
|
||||||
@@ -742,7 +742,7 @@ void parser_print_node_tree(ParserNode *node, size_t indent) {
|
|||||||
case T_STRING:
|
case T_STRING:
|
||||||
printf("<%s>", node->token->valueStr);
|
printf("<%s>", node->token->valueStr);
|
||||||
break;
|
break;
|
||||||
case T_NUMBER:
|
case T_INTEGER:
|
||||||
printf("<%ld>", node->token->valueInt);
|
printf("<%ld>", node->token->valueInt);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -168,10 +168,10 @@ ScannerToken *scanner_next_token(Scanner *scanner, ScannerToken *token) {
|
|||||||
else if (scanner_match(scanner, "create", true)) token->type = T_KW_CREATE;
|
else if (scanner_match(scanner, "create", true)) token->type = T_KW_CREATE;
|
||||||
else if (scanner_match(scanner, "table", true)) token->type = T_KW_TABLE;
|
else if (scanner_match(scanner, "table", true)) token->type = T_KW_TABLE;
|
||||||
else if (scanner_match(scanner, "drop", true)) token->type = T_KW_DROP;
|
else if (scanner_match(scanner, "drop", true)) token->type = T_KW_DROP;
|
||||||
else if (scanner_match(scanner, "string", true)) token->type = T_KW_STRING;
|
else if (scanner_match(scanner, "char", true)) token->type = T_KW_CHAR;
|
||||||
else if (scanner_match(scanner, "int", true)) token->type = T_KW_INT;
|
else if (scanner_match(scanner, "int", true)) token->type = T_KW_INT;
|
||||||
else if (scanner_match(scanner, "integer", true)) token->type = T_KW_INT;
|
else if (scanner_match(scanner, "integer", true)) token->type = T_KW_INT;
|
||||||
else if (scanner_match(scanner, "index", true)) token->type = T_KW_INDEX;
|
else if (scanner_match(scanner, "tree", true)) token->type = T_KW_INDEX;
|
||||||
if (token->type != T_NONE) {
|
if (token->type != T_NONE) {
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
@@ -222,7 +222,7 @@ ScannerToken *scanner_next_token(Scanner *scanner, ScannerToken *token) {
|
|||||||
free_scanner_token(token);
|
free_scanner_token(token);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
token->type = T_NUMBER;
|
token->type = T_INTEGER;
|
||||||
//convert number
|
//convert number
|
||||||
token->valueInt = (int64_t) strtol(intInput, NULL, 10);
|
token->valueInt = (int64_t) strtol(intInput, NULL, 10);
|
||||||
return token;
|
return token;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#define SCANNER_TOKEN_TYPE_LIST \
|
#define SCANNER_TOKEN_TYPE_LIST \
|
||||||
X(T_NONE) \
|
X(T_NONE) \
|
||||||
X(T_STRING) \
|
X(T_STRING) \
|
||||||
X(T_NUMBER) \
|
X(T_INTEGER) \
|
||||||
X(T_IDENTIFIER) \
|
X(T_IDENTIFIER) \
|
||||||
X(T_COMMA) \
|
X(T_COMMA) \
|
||||||
X(T_SEMICOLON) \
|
X(T_SEMICOLON) \
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
X(T_KW_CREATE) \
|
X(T_KW_CREATE) \
|
||||||
X(T_KW_TABLE) \
|
X(T_KW_TABLE) \
|
||||||
X(T_KW_DROP) \
|
X(T_KW_DROP) \
|
||||||
X(T_KW_STRING) \
|
X(T_KW_CHAR) \
|
||||||
X(T_KW_INT) \
|
X(T_KW_INT) \
|
||||||
X(T_KW_INDEX)
|
X(T_KW_INDEX)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user