summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile15
-rw-r--r--Readme.txt1
-rw-r--r--ast.c18
-rw-r--r--ast.h17
-rw-r--r--grammar.y89
-rw-r--r--lex.l10
-rw-r--r--test/test.test6
7 files changed, 138 insertions, 18 deletions
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 <stdlib.h>
+
+#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 <stdio.h>
+#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 <node> program
+%type <node> function
+%type <node> arguments
+%type <node> argument
+%type <node> return_type
+%type <node> variable_type
+%type <node> statements
+%type <node> statement
+%type <node> expression
+
+%type <node> IDENTIFIER
+%type <node> 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
+}