forked from rakitzis/rc
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcalc.y
More file actions
164 lines (135 loc) · 3.4 KB
/
calc.y
File metadata and controls
164 lines (135 loc) · 3.4 KB
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
* process with
* byacc -t -v -d [-P] -b calc -p calc calc.y
* or with
* bison -t -v -d -b calc -p calc calc.y
*/
%{
#include <assert.h>
extern int printf(const char *, ...);
#include <stdio.h>
static FILE *eqeq = NULL;
#include "calc_decl.h"
#include "rc.h"
/* The name of the lexer argument for CalcParser() in the body of the macro calcparse():
* CalcParser(lexer, lexData)
* ^^^^^
* must be equal to the function name in the body of the macro calclex():
* lexer(lexData, &calcval)
* ^^^^^
*/
#define calcparse(a) CalcParser(CalcLexerType lexer, CalcLexData *lexData)
#define calcparse_r(a) CalcParser(CalcLexerType lexer, CalcLexData *lexData)
#define calclex(a) lexer(lexData, &calclval)
#define calcerror(s) CalcError(s, lexData);
%}
%union {
CalcValue m_Val;
}
/* Non-terminals */
%type <m_Val> expr assignment
/* Tokens - highest precedence last */
%nonassoc '='
%left CALC_OROR
%left CALC_ANDAND
%left '|'
%left '^'
%left '&'
%left CALC_EQEQ CALC_NEQ
%left '<' '>' CALC_LEQ CALC_GEQ
%left CALC_LSHIFT CALC_RSHIFT
%left '+' '-'
%left '*' '/' '%'
%right '!' '~' CALC_UNARY_PLUSMINUS
%right '@'
%token <m_Val> CALC_NUMBER
%token CALC_VAR
%token CALC_END_TOKEN CALC_BAD_TOKEN
/*%pure-parser*/
%start calc
%%
calc
: expr
{ assert('\0' == lexData->m_Indent[0]);
lexData->m_CalcResult = $1;
}
| assignment
{ assert('\0' != lexData->m_Indent[0]);
lexData->m_CalcResult = $1;
}
;
assignment
: CALC_VAR '=' expr
{ assert('\0' != lexData->m_Indent[0]);
$$ = $3;
}
;
expr: expr CALC_OROR expr { $$ = $1 || $3; }
| expr CALC_ANDAND expr { $$ = $1 && $3; }
| expr '|' expr { $$ = $1 | $3; } ;
| expr '^' expr { $$ = $1 ^ $3; } ;
| expr '&' expr { $$ = $1 & $3; } ;
| expr CALC_EQEQ expr {
if (eqeq == NULL) {
eqeq = fopen("eqeq.txt", "w");
}
fprintf(eqeq, "(Y-Comparing %lld == %lld)\n", (long long)$1, (long long)$3);
fflush(eqeq);
fprint(1, "(Z-Comparing %lld == %lld)\n", (long long)$1, (long long)$3);
fflush(stdout);
$$ = ($1 == $3);
fprintf(eqeq, "(Y-Result of comparison %lld == %lld: %lld)\n", (long long)$1, (long long)$3, (long long)$$);
fflush(eqeq);
fprint(1, "(Z-Result of comparison %lld == %lld: %lld)\n", (long long)$1, (long long)$3, (long long)$$);
fflush(stdout);
}
| expr CALC_NEQ expr { $$ = ($1 != $3); }
| expr '>' expr { $$ = $1 > $3; }
| expr '<' expr { $$ = $1 < $3; }
| expr CALC_LEQ expr { $$ = $1 <= $3; }
| expr CALC_GEQ expr { $$ = $1 >= $3; }
| expr CALC_LSHIFT expr
{ const CalcValue v3 = $3;
$$ = (v3 >= 0) ? ($1 << v3) : ($1 >> (-v3));
}
| expr CALC_RSHIFT expr
{ const CalcValue v3 = $3;
$$ = (v3>=0) ? ($1 >> v3) : ($1 << (-v3));
}
| expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr
{ const CalcValue v3 = $3;
if (v3 == 0) {
calcerror("Division by 0");
YYABORT;
}
$$ = $1 / (v3);
}
| expr '%' expr
{ const CalcValue v3 = $3;
if (v3 == 0) {
calcerror("Module by 0");
YYABORT;
}
$$ = $1 % (v3);
}
| '!' expr { $$ = !$2; }
| '~' expr { $$ = ~$2; }
| '-' expr %prec CALC_UNARY_PLUSMINUS { $$ = -$2; }
| '+' expr %prec CALC_UNARY_PLUSMINUS { $$ = +$2; }
| expr '@' expr
{ const CalcValue v3 = $3;
if (v3 < 0) {
calcerror("Negative power");
YYABORT;
}
$$ = CalcPower($1, v3);
}
| '(' expr ')' { $$ = $2; }
| CALC_NUMBER { $$ = $1; }
;
%%
/*
*/