Makefile
@@ -0,0 +1,2 @@
+all:
+ flex -o lex.yy.cpp scanner.lpp && bison -do parser.tab.cpp parser.ypp && clang++-7 -std=c++17 lex.yy.cpp parser.tab.cpp
\ No newline at end of file
parser.ypp
@@ -0,0 +1,121 @@
+%skeleton "glr.cc"
+
+%define parse.error verbose
+
+%code requires
+{
+#include <memory>
+#include <variant>
+
+class tup;
+
+using expr = std::variant<int, std::unique_ptr<tup>, std::unique_ptr<tup>, std::unique_ptr<tup>, std::unique_ptr<tup>>;
+
+class tup
+{
+public:
+ expr a;
+ expr b;
+};
+}
+
+%code provides
+{
+#define YY_DECL int yylex (yy::parser::semantic_type *yylval)
+YY_DECL;
+}
+
+%code top
+{
+#include <iostream>
+}
+
+%define api.value.type union
+
+%token <int> NUMBER
+
+%%
+
+_start:
+ expr
+ {
+
+ }
+
+%type <expr *> expr;
+
+expr:
+ product
+ {
+ $$ = $1;
+ }
+| expr '+' product
+ {
+ // Some code
+ }
+| expr '-' product
+ {
+ // Some code
+ }
+
+%type <expr *> product;
+
+product:
+ prim
+ {
+ $$ = $1;
+ }
+| product '*' prim
+ {
+ // Some code
+ }
+| product '/' prim
+ {
+ // Some code
+ }
+
+%type <expr *> prim;
+
+prim:
+ NUMBER
+ {
+ // Some code
+ }
+| '(' expr ')'
+ {
+ $$ = $2;
+ }
+
+%%
+
+void
+yy::parser::error (const std::string &m)
+{
+ std::cerr << m << "\n";
+}
+
+int
+main (void)
+{
+ try
+ {
+ yy::parser p;
+
+ if (p.parse () != 0)
+ {
+ return EXIT_FAILURE;
+ }
+
+ return EXIT_SUCCESS;
+ }
+ catch (const std::exception &e)
+ {
+ std::cerr << "Exception from main: " << e.what () << "\n";
+ return EXIT_FAILURE;
+ }
+ catch (...)
+ {
+ std::cerr << "Exception from main\n";
+ return EXIT_FAILURE;
+ }
+}
\ No newline at end of file
scanner.lpp
@@ -0,0 +1,30 @@
+%option noyywrap
+%option warn nodefault
+
+%{
+#include <stdlib.h>
+
+#include <string>
+
+#include "parser.tab.hpp"
+%}
+
+%%
+
+[-+*/()]* {
+ return yytext[0];
+}
+
+[0-9][0-9]* {
+ yylval->NUMBER = atoi (yytext);
+ return yy::parser::token::NUMBER;
+}
+
+[ \t\n]+ {
+}
+
+. {
+ abort ();
+}
+
+%%
\ No newline at end of file