diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | Readme.txt | 3 | ||||
-rw-r--r-- | grammar.y | 53 | ||||
-rw-r--r-- | lex.l | 47 |
5 files changed, 108 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..84c048a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..76b7081 --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ +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 diff --git a/Readme.txt b/Readme.txt new file mode 100644 index 0000000..6d26eb6 --- /dev/null +++ b/Readme.txt @@ -0,0 +1,3 @@ +- https://www.oreilly.com/library/view/flex-bison/9780596805418/ch01.html +- https://raw.githubusercontent.com/richarddzh/gnu-flex-manual/master/flex.pdf +- https://ftp.gnu.org/old-gnu/Manuals/flex-2.5.4/html_node/flex_toc.html diff --git a/grammar.y b/grammar.y new file mode 100644 index 0000000..fd9da47 --- /dev/null +++ b/grammar.y @@ -0,0 +1,53 @@ +%{ +#include <stdio.h> +%} + +%define parse.error verbose + +%token OPERATOR_PLUS +%token OPERATOR_MINUS +%token ASSIGN + +%token FUNCTION +%token IF +%token ELSE +%token RETURN +%token CONST +%token VAR + +%token PARENTHESIS_LEFT +%token PARENTHESIS_RIGHT +%token BRACE_LEFT +%token BRACE_RIGHT +%token BRACKET_LEFT +%token BRACKET_RIGHT + +%token COMMA; + +%token NUMBER; +%token IDENTIFIER +%token COMMENT; + +%token END_OF_LINE; + +%% +program: + | program statement END_OF_LINE + ; + +statement: expression + | RETURN expression + | CONST IDENTIFIER ASSIGN expression + | VAR IDENTIFIER ASSIGN expression + ; + +expression: NUMBER + | IDENTIFIER + ; +%% + +main (int argc, char **argv) +{ + //henshin_lex(); + yyparse(); +} @@ -0,0 +1,47 @@ +%{ +#include "grammar.tab.h" +%} + +%% +"+" { return OPERATOR_PLUS; } +"-" { return OPERATOR_MINUS; } +"=" { return ASSIGN; } + +"function" { return FUNCTION; } +"if" { return IF; } +"else" { return ELSE; } +"return" { return RETURN; } +"const" { return CONST; } +"var" { return VAR; } + +"(" { return PARENTHESIS_LEFT; } +")" { return PARENTHESIS_RIGHT; } +"{" { return BRACE_LEFT; } +"}" { return BRACE_RIGHT; } +"[" { return BRACKET_LEFT; } +"]" { return BRACKET_RIGHT; } + +"," { return COMMA; } + +[0-9]+ { yylval = atoi(yytext); return NUMBER; } +[a-zA-Z]+[a-zA-Z0-9]* { return IDENTIFIER; } +"//".* { return COMMENT; } + +\n { return END_OF_LINE; } +[ \t] {} + +. { printf("undefined: %c\n", *yytext); } +%% + +void henshin_lex(int argc, char **argv) +{ + int tok; + + while (tok = yylex()) { + printf("%d", tok); + if (tok == NUMBER) { + printf(" = %d", yylval); + } + printf("\n"); + } +} |