parser.y
1.9 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
%token_type { double }
%left PLUS MINUS.
%left DIVIDE TIMES MOD.
%right POW NOT.
%include {
#include <assert.h>
#include <string.h>
#include <math.h>
#include "parser.h"
struct result_t {
enum error_t {
NOT_ACCEPTED,
SYNTAX_ERROR,
DIVIDE_BY_ZERO,
STACK_OVERFLOW,
RESULT_OVERFLOW,
PARSE_ERROR,
UNKNOWN_ERROR,
ACCEPTED
};
double value;
error_t error_type;
result_t() : value(0), error_type(NOT_ACCEPTED) {}
~result_t() {}
void check_val(double val) {
if (!isfinite(val)) {
error_type = RESULT_OVERFLOW;
}
}
};
}
%extra_argument { result_t *result }
%parse_failure {
result->error_type = result_t::PARSE_ERROR;
}
%stack_overflow {
result->error_type = result_t::STACK_OVERFLOW;
}
%syntax_error {
result->error_type = result_t::SYNTAX_ERROR;
}
%parse_accept {
if (result->error_type == result_t::NOT_ACCEPTED) {
result->error_type = result_t::ACCEPTED;
}
}
program ::= expr(A). {
if (result->error_type == result_t::NOT_ACCEPTED &&
isfinite(A)){
result->value = A;
} else {
result->error_type = result_t::RESULT_OVERFLOW;
}
}
expr(A) ::= expr(B) MINUS expr(C). {
A = B - C;
result->check_val(A);
}
expr(A) ::= expr(B) PLUS expr(C). {
A = B + C;
result->check_val(A);
}
expr(A) ::= expr(B) TIMES expr(C). {
A = B * C;
result->check_val(A);
}
expr(A) ::= MINUS expr(B). [NOT] { A = - B; }
expr(A) ::= PLUS expr(B). [NOT] { A = B; }
expr(A) ::= expr(B) POW expr(C). {
A = pow(B, C);
result->check_val(A);
}
expr(A) ::= LP expr(B) RP. { A = B; }
expr(A) ::= expr(B) DIVIDE expr(C). {
if (C != 0.0) {
A = B / C;
result->check_val(A);
} else {
result->error_type = result_t::DIVIDE_BY_ZERO;
}
}
expr(A) ::= expr(B) MOD expr(C). {
if (C != 0.0) {
A = fmod(B, C);
result->check_val(A);
} else {
result->error_type = result_t::DIVIDE_BY_ZERO;
}
}
expr(A) ::= INTEGER(B). { A = B; }