parse init

This commit is contained in:
Christian Barthel 2019-06-27 09:23:14 +02:00
parent dab413018e
commit 62cb03ebf0
1 changed files with 105 additions and 17 deletions

View File

@ -3,6 +3,7 @@
* cc lex.yy.c -lfl
*/
%{
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <err.h>
@ -12,12 +13,26 @@ struct token {
union {
char *str;
int num;
} value;
} v;
struct token *next;
};
struct ast;
struct ast {
int type;
union {
struct token *token;
struct ast *list;
} v;
struct ast *next;
};
enum asttype {
AST_TOK = 400,
AST_LIST = 401
};
enum yytokentype {
NUMBER = 258,
NUM = 258,
LPAR = 259,
RPAR = 260,
SYM = 261,
@ -25,7 +40,7 @@ enum yytokentype {
EOL = 263
};
struct token *make_token(int, int, char*);
struct token *make_token(enum yytokentype, int, char*);
int yylval;
char *yystr;
%}
@ -33,7 +48,7 @@ char *yystr;
%%
"(" { return LPAR; }
")" { return RPAR; }
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
[0-9]+ { yylval = atoi(yytext); return NUM; }
\n { return EOL; }
[ \t\n] { /* ignore white space */ }
\".*\" { return STR; }
@ -50,27 +65,95 @@ char *yystr;
* abc Symboles (symeq s1 s2) -> boolean
* 1234 Number/Integer [add,sub,div,mul,mod] -> number
* [lt, numeq] -> boolean
* [num2bool] -> boolean
*
* (define a <symbol,number,#function)
* (lambda (param ..) (.. body ..))
* (def <var> <symbol,number,#function)
* (lambda (<symbol> ..) (<sym..> ))
* (if <bool> <body> <else>)
*/
struct token*
make_token(int type, int num, char* str)
make_token(enum yytokentype type, int num, char* str)
{
struct token *t = (struct token*)calloc(1, sizeof(struct token));
struct token *t =
(struct token*) calloc(1, sizeof(struct token));
if (t == NULL)
err(1, "malloc failed");
t->type = type;
t->next = NULL;
if (type == NUMBER)
t->value.num = num;
if (type == NUM)
t->v.num = num;
else if (type == SYM || type == STR)
t->value.str = strdup(str);
t->v.str = strdup(str);
return t;
}
struct ast*
make_ast(enum asttype type, struct token *t, struct ast *n) {
struct ast *a = (struct ast*) calloc(1, sizeof(struct ast));
if (a == NULL)
err(1, "malloc failed");
a->type = type;
if (type == AST_TOK)
a->v.token = t;
else if (type == AST_LIST)
a->v.list = n;
return a;
}
struct ast*
parse(struct token *t)
{
if (t == NULL)
err(1, "Unexpected token: <NULL>");
if (t->type == LPAR) {
struct ast *head;
struct ast *a = head = make_ast(AST_LIST, NULL, NULL);
t = t->next;
assert (t != NULL);
while (t->type != RPAR) {
a->next = parse(t);
t = t->next;
}
assert(t->type == RPAR);
t = t->next;
return head;
} else if (t->type == NUM) {
printf("is a number %d\n", t->v.num);
return make_ast(AST_TOK, t, NULL);
} else if (t->type == SYM) {
printf("is a sym: %s\n", t->v.str);
return make_ast(AST_TOK, t, NULL);
} else if (t->type == STR) {
printf("is a str: %s\n", t->v.str);
return make_ast(AST_TOK, t, NULL);
}
return NULL;
}
void
debug_token(struct token *x) {
fprintf(stderr, "%d: ", x->type);
if (x->type == NUM) fprintf(stderr, "%d", x->v.num);
if (x->type == STR || x->type == SYM)
fprintf(stderr, "%s", x->v.str);
putc('\n', stderr);
}
void
debug_ast(struct ast *a) {
while (a) {
fprintf(stderr, "AST: %s", (a->type == AST_TOK) ? "AST_TOK" :
"AST_LIST");
fprintf(stderr, " [%p]", (a->type == AST_TOK) ? a->v.list :
a->v.token);
putc('\n', stderr);
if (a->type == AST_LIST) debug_ast(a->v.list);
else if(a->type == AST_TOK)
debug_token(a->v.token);
a = a->next;
}
}
int main(void)
{
int tok;
@ -79,22 +162,27 @@ int main(void)
while(tok = yylex()) {
//printf("token: %d, %d, %s\n", tok, yylval, yytext);
//printf("t=%p\n", t);
//if(t->type == NUMBER) printf(" = %d\n", t->value.num);
//if(t->type == NUMBER) printf(" = %d\n", t->v.num);
/* form=read_form() .. */
/* eval(form) */
t = make_token(tok, yylval, yytext);
if (start == NULL) start = t;
if (u == NULL) u = t;
else u->next = t;
u = t;
if (t->type == EOL) {
/* eval(start) */
struct token *x = start;
printf("eval this: %p\n", x);
while (x != NULL) {
printf("%d\n", x->type);
debug_token(x);
x = x->next;
}
struct ast *tl = parse(start);
debug_ast(tl);
/* XXX: eval(parse(start)) */
start = NULL;
}
}