-
Notifications
You must be signed in to change notification settings - Fork 0
/
row_sum.y
168 lines (142 loc) · 4.37 KB
/
row_sum.y
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
164
165
166
167
168
%{
#include "structs.hpp"
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <map>
//---- Deklaracje funkcji do wykorzystania w pliku lex
int yylex();
int yyerror(const char*);
//---- Stałe globalne
const std::map<std::string, int8_t> typeGroups {
{"NONE" , 0}, {"INTEGER", 1}, {"HEX", 1},
{"FIXED", 2}, {"FLOAT" , 3}
}; //Używane przy sprawdzaniu spójności typów
//---- Zmienne globalne
unsigned int column = 1;
unsigned int codeLine = 1;
//---- Funkcje
inline void sum_line(Line& line);
inline int check_types(const std::vector<Number>& nums);
%}
%union {
Line* line;
std::vector<Number>* nums;
std::string* str;
};
//---- Symbole nieterminalne
%start START
%type<line> LINE
%type<nums> NUMBERS
//---- Symbole terminalne
%token ENDLINE
%token<str> LINE_NUM
%token<str> INT
%token<str> HEX
%token<str> FIXED
%token<str> FLOAT
%token UNK
%%
START : START LINE {
sum_line(*$2); delete $2;
codeLine++;
column = 1;
}
| /*nic*/ { }
;
LINE : INT NUMBERS ENDLINE {
$$ = new Line();
$$->lineNum = stoi(*$1);
$$->numbers = *$2; delete $2;
$2 = new std::vector<Number>;
}
;
NUMBERS : NUMBERS INT {
$$ = $1;
$$->push_back(Number(*$2, "INTEGER")); delete $2;
if(int result = check_types(*$$) != -1) { return result; }
}
| NUMBERS HEX {
$$ = $1;
$$->push_back(Number(*$2, "HEX")); delete $2;
if(int result = check_types(*$$) != -1) { return result; }
}
| NUMBERS FIXED {
$$ = $1;
$$->push_back(Number(*$2, "FIXED")); delete $2;
if(int result = check_types(*$$) != -1) { return result; }
}
| NUMBERS FLOAT {
$$ = $1;
$$->push_back(Number(*$2, "FLOAT")); delete $2;
if(int result = check_types(*$$) != -1) { return result; }
}
| /*nic*/ { $$ = new std::vector<Number>; }
;
%%
int check_types(const std::vector<Number>& nums) {
if(!nums.empty()) {
int firstType = typeGroups.at((nums.end()-1)->type);
for (int i = nums.size()-2; i >= 0; i--) {
if(typeGroups.at(nums[i].type) != firstType){
return yyerror("invalid row data");
}
}
}
return -1;
}
void deduct_type(Line& line){
if(!line.numbers.empty()) {
for (const Number& num : line.numbers) {
if(!num.type.empty() && num.type != "INTEGER") {
line.type = num.type;
return;
}
}
line.type = "INTEGER";
}
}
void sum_line(Line& line) {
deduct_type(line);
std::cout << "\nLine number: " << line.lineNum << '\n';
std::cout << "Numbers: ";
for(const Number& number : line.numbers) {
std::cout << number.val << ' ';
}
std::cout << "\nSum: ";
if (line.type == "INTEGER") {
unsigned int result = 0;
for(const Number& number : line.numbers) {
result += stoi(number.val);
}
std::cout << result;
} //end INTEGER
else if (line.type == "HEX") {
unsigned int result = 0;
for(const Number& number : line.numbers) {
unsigned int temp;
std::istringstream converter(number.val);
converter >> std::hex >> temp;
result += temp;
}
std::ios cout_state(nullptr);
cout_state.copyfmt(std::cout);
std::cout << std::hex << result;
std::cout.copyfmt(cout_state);
} //end HEX
else if (line.type == "FIXED") {
float result = 0;
for(const Number& number : line.numbers) { result += stof(number.val); }
std::cout << result;
} //end FIXED
else if (line.type == "FLOAT") {
double result = 0;
for(const Number& number : line.numbers) { result += stod(number.val); }
std::ios cout_state(nullptr);
cout_state.copyfmt(std::cout);
std::cout << std::scientific << std::setprecision(15) << result;
std::cout.copyfmt(cout_state);
} //end FLOAT
std::cout << '\n';
}