From f17b517e56503600355de910ce576efab56b1287 Mon Sep 17 00:00:00 2001 From: Daniel Weipert Date: Tue, 6 Dec 2022 13:34:33 +0100 Subject: Tried to create an AST --- Makefile | 15 ++++++++-- Readme.txt | 1 + ast.c | 18 ++++++++++++ ast.h | 17 +++++++++++ grammar.y | 89 +++++++++++++++++++++++++++++++++++++++++++++++++--------- lex.l | 10 +++++-- test/test.test | 6 ++++ 7 files changed, 138 insertions(+), 18 deletions(-) create mode 100644 ast.c create mode 100644 ast.h create mode 100644 test/test.test diff --git a/Makefile b/Makefile index 76b7081..8f87383 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,13 @@ build: grammar.y lex.l - bison -o build/grammar.tab.c -d grammar.y - flex -o build/lex.yy.c lex.l - gcc -o build/henshin build/grammar.tab.c build/lex.yy.c -lfl -ly + bison \ + -o build/grammar.tab.c \ + -d grammar.y \ + #-Wcounterexamples + flex \ + -o build/lex.yy.c \ + lex.l + gcc \ + -o build/henshin \ + build/grammar.tab.c build/lex.yy.c \ + -I ./ \ + -lfl -ly diff --git a/Readme.txt b/Readme.txt index 7ccd854..09f9e49 100644 --- a/Readme.txt +++ b/Readme.txt @@ -5,3 +5,4 @@ - https://www.ecosia.org/search?q=transpiler%20with%20bison%20and%20lex - https://github.com/labis7/Flex_Bison_Transpiler - https://gnuu.org/2009/09/18/writing-your-own-toy-compiler/ +- https://lloydrochester.com/post/flex-bison/json-parse-ast/ diff --git a/ast.c b/ast.c new file mode 100644 index 0000000..d2b8782 --- /dev/null +++ b/ast.c @@ -0,0 +1,18 @@ +#include "ast.h" + + +ast_node* create_node() { + ast_node* node = malloc(sizeof(ast_node)); + + return node; +} + +ast_node* create_program_node(ast_node* previous_node, ast_node* current_node) { + ast_node* node = malloc(sizeof(ast_node)); + + node->type = PROGRAM_NODE; + node->left = previous_node; + node->right = current_node; + + return node; +} diff --git a/ast.h b/ast.h new file mode 100644 index 0000000..3b59d2b --- /dev/null +++ b/ast.h @@ -0,0 +1,17 @@ +#ifndef AST_H +#define AST_H + +#include + +#define PROGRAM_NODE 0 + +typedef struct ast_node { + int type; + void* value; + struct ast_node* left; + struct ast_node* right; +} ast_node; + +ast_node* create_program_node(ast_node* previous_node, ast_node* current_node); + +#endif // AST_H diff --git a/grammar.y b/grammar.y index 446b651..c85da97 100644 --- a/grammar.y +++ b/grammar.y @@ -1,13 +1,24 @@ %{ #include +#include "ast.c" + extern FILE *yyin; + extern int yylex(); extern void yyerror(); + +ast_node* yyast = NULL; %} %define parse.error verbose +%union { + char* string; + int number; + ast_node* node; +} + %token OPERATOR_PLUS %token OPERATOR_MINUS %token ASSIGN @@ -19,6 +30,10 @@ extern void yyerror(); %token CONST %token VAR +%token TYPE_INTEGER +%token TYPE_STRING +%token TYPE_VOID + %token PARENTHESIS_LEFT %token PARENTHESIS_RIGHT %token BRACE_LEFT @@ -27,6 +42,7 @@ extern void yyerror(); %token BRACKET_RIGHT %token COMMA; +%token COLON; %token NUMBER; %token IDENTIFIER @@ -34,20 +50,65 @@ extern void yyerror(); %token END_OF_LINE; +%type program +%type function +%type arguments +%type argument +%type return_type +%type variable_type +%type statements +%type statement +%type expression + +%type IDENTIFIER +%type RETURN + +%start program + %% -program: - | program statement END_OF_LINE - ; - -statement: expression - | RETURN expression - | CONST IDENTIFIER ASSIGN expression - | VAR IDENTIFIER ASSIGN expression - ; - -expression: NUMBER - | IDENTIFIER - ; +program: { $$ = NULL; } + | program statement END_OF_LINE { $$ = create_program_node($1, $2); } + + +// function henshin(): void {} +// function henshin(hen: integer, shin: integer): void {} +function: + | FUNCTION IDENTIFIER PARENTHESIS_LEFT PARENTHESIS_RIGHT COLON return_type BRACE_LEFT statements BRACE_RIGHT + | FUNCTION IDENTIFIER PARENTHESIS_LEFT arguments PARENTHESIS_RIGHT COLON return_type BRACE_LEFT statements BRACE_RIGHT { $$ = create_node(); $$->value = $2; } + +arguments: + | argument + | arguments COMMA argument + +argument: + | IDENTIFIER COLON variable_type + + +return_type: + | TYPE_INTEGER + | TYPE_STRING + | TYPE_VOID + +variable_type: + | TYPE_INTEGER + | TYPE_STRING + + +statements: + | statement + | statements END_OF_LINE statement + +statement: + // const henshin: integer = 2 + | CONST IDENTIFIER COLON variable_type ASSIGN expression + | RETURN expression { $$ = create_node(); $$->left = $1; $$->right = $2; } + | IDENTIFIER PARENTHESIS_LEFT PARENTHESIS_RIGHT + | function + + +expression: + | NUMBER + | IDENTIFIER %% void main (int argc, char **argv) @@ -55,4 +116,6 @@ void main (int argc, char **argv) //henshin_lex(); yyin = fopen(argv[1], "r"); yyparse(); + + printf("%s", yyast); } diff --git a/lex.l b/lex.l index 2f79474..64c3765 100644 --- a/lex.l +++ b/lex.l @@ -1,4 +1,5 @@ %{ +#include "ast.h" #include "grammar.tab.h" %} @@ -14,6 +15,10 @@ "const" { return CONST; } "var" { return VAR; } +"integer" { return TYPE_INTEGER; } +"string" { return TYPE_STRING; } +"void" { return TYPE_VOID; } + "(" { return PARENTHESIS_LEFT; } ")" { return PARENTHESIS_RIGHT; } "{" { return BRACE_LEFT; } @@ -22,9 +27,10 @@ "]" { return BRACKET_RIGHT; } "," { return COMMA; } +":" { return COLON; } -[0-9]+ { yylval = atoi(yytext); return NUMBER; } -[a-zA-Z]+[a-zA-Z0-9]* { return IDENTIFIER; } +[a-zA-Z][a-zA-Z0-9]* { yylval.string = yytext; return IDENTIFIER; } +[0-9]+ { yylval.number = atoi(yytext); return NUMBER; } "//".* { return COMMENT; } \n { return END_OF_LINE; } diff --git a/test/test.test b/test/test.test new file mode 100644 index 0000000..44580c7 --- /dev/null +++ b/test/test.test @@ -0,0 +1,6 @@ +function henshin(hen: integer, shin: integer): void { + const x: integer = 2 + const b: string = x + + return b +} -- cgit v1.2.3