Tree-building almost works
[cparser.git] / src / calc.ypp
blob6c5f26fa567658f23eef83848848462f216033d5
1 %{
2 #include <iostream>
3 #include <cstdlib>
4 #include "BinExpr.hpp"
5 #include "Exception.hpp"
7 extern int yylex();
9 typedef Expr* pExpr;
11 // better error reporting
12 #define YYERROR_VERBOSE
14 // bison requires that you supply this function
15 void yyerror(const char *msg)
17         std::cerr << "ERROR(PARSER): " << msg << std::endl;
22 %union {
23     Expr* expr;
24     double dvalue;
25     long ivalue;
28 %token <dvalue> DOUBLE
29 %token <ivalue> INTEGER
30 %type  <expr> number
32 %type <expr> dexpression
33 %type <expr> dterm
35 %type <expr> iexpression
36 %type <expr> iterm
40 statementlist : statement '\n'
41               | statement '\n' statementlist
42               ;
44 statement :     dexpression              { std::cout << "ANS" << $1->eval() << std::endl; }
45               | iexpression              { std::cout << "ANS" << $1->eval() << std::endl; }
46               ;
48 number : DOUBLE                          {$$ = new Number(double($1)); }
49        | INTEGER                         {$$ = new Number(double($1)) ; }
51 dexpression: dexpression '+' number     { $$ = new AddExpr($1, $3); }
52           | iexpression  '+' dterm      { $$ = new AddExpr($1, $3); }
53           | dterm                    { $$ = $1; }
54           ;
56 iexpression: iexpression '+' iterm     { $$ = new AddExpr($1, $3);}
57           | iterm                    { $$ = $1; }
58           ;
60 dterm : dterm '*' number            { $$ = new MulExpr($1, $3); }
61       | iterm '*' DOUBLE             { $$ = new MulExpr($1, new Number($3)); }
63       | dterm '/' DOUBLE            { if ($3==0) {
64                                           throw DivByZero("");
65                                       }
66                                       else {
67                                           $$ = new DivExpr($1, new Number($3));
68                                       }
69                                     }
70       | dterm '/' INTEGER            { if ($3==0) {
71                                           throw DivByZero("");
72                                       }
73                                       else {
74                                           $$ = new DivExpr($1, new Number(long($3)));
75                                       }
76                                     }
77       | iterm '/' DOUBLE            { if ($3==0) {
78                                           throw DivByZero("");
79                                       }
80                                       else {
81                                           $$ = new DivExpr($1, new Number(double($3)));
82                                       }
83                                     }
84        | DOUBLE                     { $$ = new Number(double($1)); }
85      ;
87 iterm : iterm '*' INTEGER            { $$ = new MulExpr($1, new Number(long($3))); }
88      | iterm '/' INTEGER            { if ($3==0) {
89                                           throw DivByZero("");
90                                       }
91                                       else {
92                                           $$ = new DivExpr($1, new Number(long($3)));
93                                       }
94                                     }
95       | INTEGER                     { $$ = new Number(long($1)); }
96      ;
100 main()
102         yyparse();