parser: almost working
This commit is contained in:
113
src/parser.c
113
src/parser.c
@@ -37,34 +37,109 @@ char** tokenize(char* str) {
|
|||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
sc_ast* sc_parse(char* input) {
|
sc_ast* make_node(int tag, char* value) {
|
||||||
char** tokens = tokenize(input);
|
sc_ast* node = malloc(sizeof(sc_ast));
|
||||||
sc_ast* parent = malloc(sizeof(sc_ast));
|
node->tag = tag;
|
||||||
parent->tag = 0;
|
node->value = value;
|
||||||
parent->value = NULL;
|
node->n_children = 0;
|
||||||
parent->children = NULL;
|
node->children = NULL;
|
||||||
parent->n_children = 0;
|
|
||||||
|
|
||||||
while (*tokens) {
|
return node;
|
||||||
parent->n_children++;
|
}
|
||||||
|
|
||||||
sc_ast* child = malloc(sizeof(sc_ast));
|
sc_ast* make_pseudo() {
|
||||||
parent->children = realloc(parent->children, parent->n_children*sizeof(sc_ast*));
|
return make_node(PSEUDO, NULL);
|
||||||
child->tag = 1;
|
}
|
||||||
child->value = *tokens;
|
|
||||||
child->children = NULL;
|
sc_ast* make_list() {
|
||||||
child->n_children = 0;
|
return make_node(LIST, NULL);
|
||||||
parent->children[parent->n_children-1] = child;
|
}
|
||||||
tokens++;
|
|
||||||
|
sc_ast* make_int(char* value) {
|
||||||
|
return make_node(INT, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
sc_ast* make_float(char* value) {
|
||||||
|
return make_node(FLOAT, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
sc_ast* make_atom(char* value) {
|
||||||
|
return make_node(ATOM, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct parse_state {
|
||||||
|
char** tokens;
|
||||||
|
sc_ast* node;
|
||||||
|
} parse_state;
|
||||||
|
|
||||||
|
short is_numerical(char* inp) {
|
||||||
|
int i;
|
||||||
|
int len = strlen(inp);
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) if (!isdigit(inp[i])) return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sc_ast* read_token(char* inp) {
|
||||||
|
if (is_numerical(inp)) return make_int(inp);
|
||||||
|
return make_atom(inp);
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_state* read_tokens(parse_state* state) {
|
||||||
|
char* token = state->tokens[0];
|
||||||
|
state->tokens++;
|
||||||
|
int n = state->node->n_children++;
|
||||||
|
|
||||||
|
state->node->children = realloc(state->node->children, n+1);
|
||||||
|
|
||||||
|
if (!strncmp(token, "(", 2)) {
|
||||||
|
sc_ast* list = make_list();
|
||||||
|
parse_state* nstate = malloc(sizeof(parse_state));
|
||||||
|
nstate->node = list;
|
||||||
|
nstate->tokens = state->tokens;
|
||||||
|
|
||||||
|
while (strncmp(nstate->tokens[0], ")", 2)) {
|
||||||
|
nstate = read_tokens(nstate);
|
||||||
|
}
|
||||||
|
|
||||||
|
state->node->children[n] = nstate->node;
|
||||||
|
state->tokens = nstate->tokens;
|
||||||
|
free(nstate);
|
||||||
|
} else {
|
||||||
|
state->node->children[n] = read_token(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent;
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
sc_ast* sc_parse(char* input) {
|
||||||
|
char** tokens = tokenize(input);
|
||||||
|
parse_state* state = malloc(sizeof(parse_state));
|
||||||
|
state->tokens = tokens;
|
||||||
|
state->node = make_pseudo();
|
||||||
|
|
||||||
|
state = read_tokens(state);
|
||||||
|
|
||||||
|
return state->node->children[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* tag_to_string(int x) {
|
||||||
|
switch(x) {
|
||||||
|
case PSEUDO: return "pseudo";
|
||||||
|
case ATOM: return "atom";
|
||||||
|
case STRING: return "string";
|
||||||
|
case INT: return "int";
|
||||||
|
case FLOAT: return "float";
|
||||||
|
case LIST: return "list";
|
||||||
|
default: {char* t=malloc(3); snprintf(t, 3, "%d", x); return t;}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sc_ast_print(sc_ast* ast) {
|
void sc_ast_print(sc_ast* ast) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
printf("(%d) %s (%lu)\n", ast->tag, ast->value, ast->value ? strlen(ast->value) : 0);
|
printf("%s: %s\n", tag_to_string(ast->tag), ast->value);
|
||||||
|
|
||||||
for (i = 0; i < ast->n_children; ++i) sc_ast_print(ast->children[i]);
|
for (i = 0; i < ast->n_children; ++i) sc_ast_print(ast->children[i]);
|
||||||
}
|
}
|
||||||
|
11
src/parser.h
11
src/parser.h
@@ -1,7 +1,18 @@
|
|||||||
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
enum tag {
|
||||||
|
PSEUDO,
|
||||||
|
ATOM,
|
||||||
|
LIST,
|
||||||
|
INT,
|
||||||
|
FLOAT,
|
||||||
|
STRING,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef struct sc_ast {
|
typedef struct sc_ast {
|
||||||
short tag;
|
short tag;
|
||||||
char* value;
|
char* value;
|
||||||
|
Reference in New Issue
Block a user