Revisions for untitled paste

View the changes made to this paste.

unlisted ⁨3⁩ ⁨files⁩ 2018-12-08 15:15:27 UTC

Makefile

@@ -0,0 +1,17 @@

+# Public domain
+# Tested with Bison) 3.2.2 and Flex 2.6.4
+# Note that our scanner.ll contains C++ code fragments, but we run Flex in C mode anyway. I. e. we pass C++ code to Flex, but trick it to think it processes C code. Then Flex generates code, which (at its optinion) is C code, but in fact this is C++ code (because it contains unmodified C++ code fragments, written by us), so we write it to file with .cc extension and pass to C++ compiler
+ 
+all: a.out
+ 
+lex.yy.cc lex.yy.hh: scanner.ll
+	flex --header-file=lex.yy.hh -o lex.yy.cc scanner.ll
+ 
+parser.tab.cc parser.tab.hh: parser.yy
+	bison -do parser.tab.cc parser.yy
+ 
+a.out: lex.yy.cc parser.tab.cc
+	c++ lex.yy.cc parser.tab.cc
+ 
+clean:
+	rm -f lex.yy.* parser.tab.* stack.hh a.out
\ No newline at end of file

scanner.ll

@@ -0,0 +1,33 @@

+%option noyywrap
+%option warn nodefault
+ 
+%{
+#include <stdlib.h>
+ 
+#include <stdexcept>
+ 
+#include "parser.tab.hh"
+ 
+#define YY_DECL int \
+  yylex (yy::parser::semantic_type *yylval)
+%}
+ 
+%%
+ 
+[-+*/()] {
+  return yytext[0];
+}
+ 
+[0-9]+ {
+  yylval->build (atoi (yytext));
+  return yy::parser::token::NUMBER;
+}
+ 
+[ \t\n]+ {
+}
+ 
+. {
+  throw std::runtime_error ("Unknown character");
+}
+ 
+%%
\ No newline at end of file

parser.yy

@@ -0,0 +1,66 @@

+%skeleton "lalr1.cc"
+ 
+%code requires{
+// Here you should insert declarations for types you will use in AST, if you will build AST. This will ensure that they will go both to generated parser and to file parser.tab.hh. Then you will include parser.tab.hh everywhere you need this declarations
+}
+ 
+%{
+#include <iostream>
+ 
+#include "parser.tab.hh"
+ 
+int
+yylex (yy::parser::semantic_type *yylval);
+ 
+void
+yy::parser::error (const std::string &m)
+{
+  std::cerr << m << std::endl;
+}
+%}
+ 
+%define api.value.type variant
+ 
+%start document
+ 
+%token <int> NUMBER
+ 
+%%
+ 
+%left '+' '-';
+%left '*' '/';
+ 
+%type <int> expr;
+ 
+expr:
+  NUMBER
+    { $$ = $1; }
+| expr '+' expr
+    { $$ = $1 + $3; }
+| expr '-' expr
+    { $$ = $1 - $3; }
+| expr '*' expr
+    { $$ = $1 * $3; }
+| expr '/' expr
+    { $$ = $1 / $3; }
+| '(' expr ')'
+    { $$ = $2; }
+ 
+document:
+  expr
+    { std::cout << $1 << std::endl; }
+ 
+%%
+ 
+int
+main ()
+{
+  yy::parser p;
+ 
+  if (p.parse () != 0)
+    {
+      return EXIT_FAILURE;
+    }
+ 
+  return EXIT_SUCCESS;
+}
\ No newline at end of file