Starting with the lexer, i'm starting to comprehend better what pratt parsing is and how to apply it. For now just declaring basic structure and functions
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
25
src/lexer.c
25
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;
|
||||
}
|
||||
}
|
||||
|
||||
27
src/parser.c
27
src/parser.c
@@ -0,0 +1,27 @@
|
||||
#include "parser.h"
|
||||
#include "lexer.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user