jitters: parse: build AST when parsing

This commit is contained in:
Bruno BELANYI 2020-09-28 13:30:08 +02:00
parent 451e34af8b
commit 7090a741bc
3 changed files with 33 additions and 16 deletions

View file

@ -1,14 +1,15 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "ast/ast.h"
#include "parse/parse-jitters.h" #include "parse/parse-jitters.h"
int main(void) int main(void)
{ {
int res; struct ast_node *res;
yydebug = getenv("PARSE") != NULL; yydebug = getenv("PARSE") != NULL;
if (yyparse(&res) == 0) { if (yyparse(&res) == 0) {
printf("%d\n", res); destroy_ast(res);
} }
return 0; return 0;

View file

@ -1,19 +1,30 @@
%code requires
{
#include "ast/ast.h"
}
%{ %{
#include <stdio.h> #include <stdio.h>
#include "ast/ast.h"
int yylex(void); int yylex(void);
void yyerror(int *unused,char const *s); void yyerror(struct ast_node **unused, char const *s);
%} %}
%define api.value.type {int} %union
{
int num;
struct ast_node *node;
}
%define api.token.prefix {TOK_} %define api.token.prefix {TOK_}
%define parse.error verbose %define parse.error verbose
%define parse.trace true %define parse.trace true
%parse-param {int *result} %parse-param {struct ast_node **ast}
%locations %locations
%token EOF 0 "end-of-file" %token EOF 0 "end-of-file"
%token NUM "number" %token <num> NUM "number"
%token %token
PLUS "+" PLUS "+"
MINUS "-" MINUS "-"
@ -26,30 +37,35 @@ void yyerror(int *unused,char const *s);
%left TIMES DIVIDE %left TIMES DIVIDE
%precedence NEG %precedence NEG
// Type of our built AST
%type <node> exp
// Use destructor function when discarding tokens
%destructor { destroy_ast($$); } <node>
%% %%
input: input:
exp EOF exp EOF
{ *result = $1; } { *ast = $1; }
; ;
exp: exp:
NUM NUM
{ $$ = $1; } { $$ = make_num($1); }
| exp PLUS exp | exp PLUS exp
{ $$ = $1 + $3; } { $$ = make_binop(PLUS, $1, $3); }
| exp MINUS exp | exp MINUS exp
{ $$ = $1 - $3; } { $$ = make_binop(MINUS, $1, $3); }
| exp TIMES exp | exp TIMES exp
{ $$ = $1 * $3; } { $$ = make_binop(TIMES, $1, $3); }
| exp DIVIDE exp | exp DIVIDE exp
{ $$ = $1 / $3; } { $$ = make_binop(DIVIDE, $1, $3); }
| PLUS exp %prec NEG | PLUS exp %prec NEG
{ $$ = $2; } { $$ = make_unop(IDENTITY, $2); }
| MINUS exp %prec NEG | MINUS exp %prec NEG
{ $$ = -$2; } { $$ = make_unop(NEGATE, $2); }
| LPAREN exp RPAREN | LPAREN exp RPAREN
{ $$ = $2; } { $$ = $2; }
@ -57,7 +73,7 @@ exp:
%% %%
void yyerror(int *unused, char const *s) void yyerror(struct ast_node **unused, char const *s)
{ {
unused = unused; // Unused unused = unused; // Unused
fprintf(stderr, "%s\n", s); fprintf(stderr, "%s\n", s);

View file

@ -36,7 +36,7 @@ int [0-9]+
")" return TOK_RPAREN; ")" return TOK_RPAREN;
{int} { {int} {
yylval = atoi(yytext); yylval.num = atoi(yytext);
return TOK_NUM; return TOK_NUM;
} }