diff --git a/include/lexer.h b/include/lexer.h index 943e4a5..d695d16 100644 --- a/include/lexer.h +++ b/include/lexer.h @@ -73,5 +73,6 @@ LexerErr tokenize(const char* input, ASTNodeArray *out); LexerErr tokenize_number(const char* input, size_t *offset, ASTNode *out); LexerErr string_to_integer(const char buf[], int64_t *number); bool isoperator(int c); +Operator char_to_operator(int c); #endif // !LEXER_H diff --git a/include/parser.h b/include/parser.h index e69de29..be689b0 100644 --- a/include/parser.h +++ b/include/parser.h @@ -0,0 +1,14 @@ +#include "lexer.h" + +typedef struct { + ASTNode *head; +} AST; + +typedef enum { + PARSER_NUD, // Null Denotation + PARSER_LED, // Left Denotation +} ParserState; + +size_t node_lbp(Operator op); +size_t node_rbp(Operator op); +AST parse(ASTNodeArray arr); diff --git a/src/lexer.c b/src/lexer.c index c793c4d..6a1e901 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -141,7 +141,7 @@ LexerErr tokenize(const char *input, ASTNodeArray *out) { } ASTNode new_node = { .type = NODE_BINARY_OP, - .data.binary.op = current, + .data.binary.op = char_to_operator(current), .data.binary.right = NULL, .data.binary.left = NULL, }; @@ -158,6 +158,10 @@ LexerErr tokenize(const char *input, ASTNodeArray *out) { offset++; } + if (arr.len < 1) { + return LEXER_EMPTY_INPUT; + } + *out = arr; return LEXER_OK; } @@ -225,3 +229,22 @@ bool isoperator(int c) { return false; } } + +Operator char_to_operator(int c) { + switch (c) { + case '+': + return OP_ADD; + break; + case '-': + return OP_SUB; + break; + case '*': + return OP_MUL; + break; + case '/': + return OP_DIV; + break; + default: // I mean shouldn't be used, we assume + return -1; + } +} diff --git a/src/parser.c b/src/parser.c index e69de29..238cd0a 100644 --- a/src/parser.c +++ b/src/parser.c @@ -0,0 +1,27 @@ +#include "parser.h" +#include "lexer.h" +#include + +size_t node_lbp(Operator op) { + switch (op) { + case OP_ADD: + case OP_SUB: + return 10; + break; + case OP_DIV: + case OP_MUL: + return 20; + } +} + +size_t node_rbp(Operator op) { + switch (op) { + case OP_ADD: + case OP_SUB: + return 10; + break; + case OP_DIV: + case OP_MUL: + return 20; + } +} diff --git a/test/test_lexer.c b/test/test_lexer.c index 2506441..db9b914 100644 --- a/test/test_lexer.c +++ b/test/test_lexer.c @@ -22,7 +22,7 @@ static void test_tokenize_normal_expresion(void **state) { ASTNodeArray_get(&tokens, 1, &node); assert_int_equal(node.type, NODE_BINARY_OP); - assert_int_equal(node.data.binary.op, '+'); + assert_int_equal(node.data.binary.op, OP_ADD); ASTNodeArray_get(&tokens, 2, &node); assert_int_equal(node.type, NODE_INTEGER); @@ -30,7 +30,7 @@ static void test_tokenize_normal_expresion(void **state) { ASTNodeArray_get(&tokens, 3, &node); assert_int_equal(node.type, NODE_BINARY_OP); - assert_int_equal(node.data.binary.op, '/'); + assert_int_equal(node.data.binary.op, OP_DIV); ASTNodeArray_get(&tokens, 4, &node); assert_int_equal(node.type, NODE_INTEGER); @@ -38,7 +38,7 @@ static void test_tokenize_normal_expresion(void **state) { ASTNodeArray_get(&tokens, 5, &node); assert_int_equal(node.type, NODE_BINARY_OP); - assert_int_equal(node.data.binary.op, '*'); + assert_int_equal(node.data.binary.op, OP_MUL); ASTNodeArray_get(&tokens, 6, &node); assert_int_equal(node.type, NODE_INTEGER);