From f1a6435969593b8dfda70df86e834e100a751372 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Mon, 28 Sep 2020 12:37:40 +0200 Subject: [PATCH] jitters: parse: add parsing module --- Makefile.am | 6 ++++ src/jitters.c | 9 +++++- src/local.am | 8 +++++ src/parse/local.am | 27 +++++++++++++++++ src/parse/parse-jitters.y | 64 +++++++++++++++++++++++++++++++++++++++ src/parse/scan-jitters.l | 45 +++++++++++++++++++++++++++ 6 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 src/parse/local.am create mode 100644 src/parse/parse-jitters.y create mode 100644 src/parse/scan-jitters.l diff --git a/Makefile.am b/Makefile.am index 6443de3..1c0b01d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,4 +5,10 @@ EXTRA_DIST = \ bootstrap \ $(NULL) +# Initialise those variables for use in included files +BUILT_SOURCES = +noinst_LIBRARIES = +# We want to remove those files when `clean` rule is being executed +CLEANFILES = $(BUILT_SOURCES) + include %D%/src/local.am diff --git a/src/jitters.c b/src/jitters.c index 32295be..a3ed4bb 100644 --- a/src/jitters.c +++ b/src/jitters.c @@ -1,8 +1,15 @@ #include +#include + +#include "parse/parse-jitters.h" int main(void) { - puts("Hello World!"); + int res; + yydebug = getenv("PARSE") != NULL; + if (yyparse(&res) == 0) { + printf("%d\n", res); + } return 0; } diff --git a/src/local.am b/src/local.am index dce6ca7..cde0ef2 100644 --- a/src/local.am +++ b/src/local.am @@ -7,3 +7,11 @@ jitters_SOURCES = \ # Add warnings jitters_CFLAGS = $(WARN_CFLAGS) jitters_LDFLAGS = $(WARN_LDFLAGS) + +# Make includes cleaner +AM_CPPFLAGS = -I$(top_builddir)/src -I$(srcdir) + +# Initialise those variables for use in included files +jitters_LDADD = + +include %D%/parse/local.am diff --git a/src/parse/local.am b/src/parse/local.am new file mode 100644 index 0000000..eede5b3 --- /dev/null +++ b/src/parse/local.am @@ -0,0 +1,27 @@ +# Do not warn about YACC compatibility, but do output token codes +AM_YFLAGS = -Wno-yacc -d + +# Add parsing library to `jitters` +jitters_LDADD += \ + libparse.a \ + $(NULL) +# Declare library as non-installable +noinst_LIBRARIES += \ + libparse.a \ + $(NULL) +# Add Flex/Bison sources to parsing library +libparse_a_SOURCES = \ + %D%/parse-jitters.y \ + %D%/scan-jitters.l \ + $(NULL) +# Mark their output files as being built by Flex/Bison +BUILT_SOURCES += \ + %D%/parse-jitters.c \ + %D%/parse-jitters.h \ + %D%/scan-jitters.c \ + $(NULL) + +# Remove problematic warnings from generated files +libparse_a_CFLAGS = \ + -Wno-switch-default \ + $(NULL) diff --git a/src/parse/parse-jitters.y b/src/parse/parse-jitters.y new file mode 100644 index 0000000..840a552 --- /dev/null +++ b/src/parse/parse-jitters.y @@ -0,0 +1,64 @@ +%{ +#include + +int yylex(void); +void yyerror(int *unused,char const *s); +%} + +%define api.value.type {int} +%define api.token.prefix {TOK_} +%define parse.error verbose +%define parse.trace true +%parse-param {int *result} +%locations + +%token EOF 0 "end-of-file" +%token NUM "number" +%token + PLUS "+" + MINUS "-" + TIMES "*" + DIVIDE "/" + LPAREN "(" + RPAREN ")" + +%left PLUS MINUS +%left TIMES DIVIDE +%precedence NEG + +%% + +input: + exp EOF + { *result = $1; } +; + +exp: + NUM + { $$ = $1; } + +| exp PLUS exp + { $$ = $1 + $3; } +| exp MINUS exp + { $$ = $1 - $3; } +| exp TIMES exp + { $$ = $1 * $3; } +| exp DIVIDE exp + { $$ = $1 / $3; } + +| PLUS exp %prec NEG + { $$ = $2; } +| MINUS exp %prec NEG + { $$ = -$2; } + +| LPAREN exp RPAREN + { $$ = $2; } +; + +%% + +void yyerror(int *unused, char const *s) +{ + unused = unused; // Unused + fprintf(stderr, "%s\n", s); +} diff --git a/src/parse/scan-jitters.l b/src/parse/scan-jitters.l new file mode 100644 index 0000000..1312b50 --- /dev/null +++ b/src/parse/scan-jitters.l @@ -0,0 +1,45 @@ +%{ +#include "parse-jitters.h" + +#define YY_USER_ACTION \ + do { \ + yylloc.first_line = yylloc.last_line; \ + yylloc.first_column = yylloc.last_column; \ + for (size_t i = 0; yytext[i] != '\0'; ++i) { \ + if (yytext[i] == '\n') { \ + yylloc.last_line++; \ + yylloc.last_column = 0; \ + } \ + else { \ + yylloc.last_column++; \ + } \ + } \ + } while (0); +%} + +/* Assume single input file */ +%option noyywrap +/* Let Flex track line number */ +%option yylineno + +/* Regex shorthands */ +blank [ \t\n]+ +int [0-9]+ + +%% + +"+" return TOK_PLUS; +"-" return TOK_MINUS; +"*" return TOK_TIMES; +"/" return TOK_DIVIDE; +"(" return TOK_LPAREN; +")" return TOK_RPAREN; + +{int} { + yylval = atoi(yytext); + return TOK_NUM; +} + +{blank} { /* Do noting */ } + +%%