1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
   Copyright (C) 2009-2019 Andreas Franz Borchert
                 2019 Michael Lehn
   ----------------------------------------------------------------------------
   Astl-ULMcalc is free software; you can redistribute it
   and/or modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either version
   2 of the License, or (at your option) any later version.

   Astl-ULMcalc is distributed in the hope that it will be
   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

%{
namespace AstlULMcalc {
   class Scanner;
}

#include <cassert>
#include <memory>
#include <string>
#include <astl/syntax-tree.hpp>
#include "operators.hpp"
#include "scanner.hpp"
#include "yystype.hpp"
#include "yytname.hpp"

using namespace Astl;

/* location which is computed by the YYLLOC_DEFAULT macro
   in case of a reduce before the corresponding action is executed */
#define YYLLOC (yylhs.location)

#define NODE(op) \
   (std::make_shared<Node>(make_loc(YYLLOC), Op::op))
#define UNARY(unop, op1) \
   (std::make_shared<Node>(make_loc(YYLLOC), Op::unop, (op1)))
#define BINARY(binop, op1,op2) \
   (std::make_shared<Node>(make_loc(YYLLOC), Op::binop, (op1), (op2)))
#define TERTIARY(top, op1,op2,op3) \
   (std::make_shared<Node>(make_loc(YYLLOC), Op::top, (op1), (op2), (op3)))
#define QUATERNARY(top, op1,op2,op3,op4) \
   (std::make_shared<Node>(make_loc(YYLLOC), Op::top, \
      (op1), (op2), (op3), (op4)))
#define QUINARY(top, op1,op2,op3,op4,op5) \
   (std::make_shared<Node>(make_loc(YYLLOC), Op::top, \
      (op1), (op2), (op3), (op4), (op5)))

#define LEAF(tk) \
   (std::make_shared<Node>(make_loc(YYLLOC), Token(token::tk, \
      yytname[token::tk - 255])))

#define FLATTEN(node, subnodes, op) \
   (flatten(node, subnodes, Op::op))

NodePtr flatten(NodePtr node, NodePtr subnodes, const Operator& op);

%}

%skeleton "lalr1.cc"
%define api.prefix {astlulmcalc}
%define api.namespace { AstlULMcalc }
%defines
%verbose
%locations
%token-table
%parse-param { Scanner& scanner }
%parse-param { Astl::NodePtr& root }
%lex-param { Scanner& scanner }

/* keywords */

/* identifiers */

/* whitespace */

/* literals */

%token  DECIMAL_CONSTANT

/* delimiters and operators */

%token  LPAREN
%token  MINUS PLUS

%start  start

%%

start: expression
    { root = $1; }

expression: exp
      { $$ = UNARY(expression, $1); }
   ;

exp: term
   | exp PLUS term
      { $$ = BINARY(PLUS, $1, $3); }
   | exp MINUS term
      { $$ = BINARY(MINUS, $1, $3); }
   ;

term: integer
      { $$ = UNARY(integer, $1); }
   ;

integer: DECIMAL_CONSTANT
      { $$ = $1; }
   ;

%%

using namespace AstlULMcalc;