-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinput_parser.cpp
191 lines (153 loc) · 5.72 KB
/
input_parser.cpp
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
//
// Created by tim on 9/8/19.
//
#include "input_parser.h"
#include <iostream>
InputParser::InputParser(string file_name){
try{
file.open(file_name);
if(!file.is_open()){
throw runtime_error("Could not find file!");
}
if(file_name.find(".mdf") == -1){
throw runtime_error("Wrong Meta-Data file extension!");
}
}
catch(std::runtime_error& e){
cerr << "An exception occurred. Could not open Config file at " << file_name << " as listed in the configuration file! Reason: " << e.what() << "\n";
exit(EXIT_FAILURE);
}
}
InputParser::~InputParser(){
file.close();
}
void InputParser::parse(){
string delimiter = ";";
string current_line = " ";
string current_instruction = " ";
size_t instruction_pos = 0;
size_t delimiter_pos = 0;
while(!file.eof()){
getline(file, current_line);
if(current_line.find("Start") == -1 && current_line.find("End") == -1) { //Ignore the starting and ending lines
while (current_line.find(delimiter) != -1 || current_line.find(".") != -1) {
delimiter_pos = current_line.find(delimiter);
//For handling the period at the end
if(current_line.find(delimiter) == -1){
delimiter_pos = current_line.length() - 1;
}
current_instruction = current_line.substr(instruction_pos, delimiter_pos); // don't include delimiter itself
//cout << endl << current_instruction << endl;
instruction_queue.push(validateInput(tupleFromString(current_instruction)));
//More period handling
if(delimiter_pos != current_line.length()) {
current_line.erase(instruction_pos, delimiter_pos + 1);
}
else
{
current_line.erase(instruction_pos, delimiter_pos);
}
}
}
}
}
queue<tuple<char, string, int>> InputParser::retrieveFormattedOutput() const{
return instruction_queue;
}
tuple<char, string, int> InputParser::tupleFromString(string instruction){
char type;
string process;
int cycles;
//Hacky fix for whitespace being passed to the function.
//Will double check parse() at a leter date
for(int i = 0; i < instruction.length(); i++){
type = instruction.c_str()[i];
if(int(type) > 64 && int(type) < 91){
break;
}
}
process = instruction.substr(instruction.find("{")+1, instruction.find("}") - instruction.find("{")-1);
cycles = stoi(removeWhiteSpace(instruction.substr(instruction.find("}") + 1, instruction.length() - instruction.find("}"))));
tuple<char, string, int> output_tuple = {type, process, cycles};
return output_tuple;
}
string InputParser::removeWhiteSpace(string in){
int start = 0;
int end = in.length();
int cursor = 0;
char ch = in.c_str()[start];
while(ch == 9 || ch == 32){ //ASCII 9 is tab, ASCII 32 is space
cursor++;
ch = in.c_str()[cursor];
start = cursor;
}
ch = ' ';
cursor = in.length();
while(ch == 9 || ch == 32){
end = cursor;
cursor--;
ch = in.c_str()[cursor];
}
return in.substr(start, end - start);
}
tuple<char, string, int> InputParser::validateInput(tuple<char, string, int> instruction){
try{
char type = get<0>(instruction);
string process = get<1>(instruction);
int num_cycles = get<2>(instruction);
if(type == 'S'){
if(num_cycles != 0){
throw runtime_error("Operating System Start or End Cycles not Zero!");
}
if(process != "begin" && process != "finish"){
std::cout << process << endl;
throw runtime_error("Incorrect Operating System Call. Must be begin or finish.");
}
}
if(type == 'A'){
if(num_cycles !=0){
throw runtime_error("Application Start or End Cycles not Zero!");
}
if(process != "begin" && process != "finish"){
throw runtime_error("Incorrect Application call. Must be begin or finish.");
}
}
if(type == 'P'){
if(num_cycles <= 0){
throw runtime_error("Incorrect Process Cycle Time! Must be > 0");
}
if(process != "run"){
throw runtime_error("Process Descriptor not run!");
}
}
if(type == 'I'){
if(num_cycles <=0){
throw runtime_error("Incorrect Input Cycle Time! Must be >0");
}
if(process != "hard drive" && process != "keyboard" && process != "mouse"){
throw runtime_error("Incorrect Input device! Must be hard drive, keyboard, or mouse.");
}
}
if(type == 'O'){
if(num_cycles <=0){
throw runtime_error("Incorrect Output Cycle Time! Must be >0");
}
if(process != "hard drive" && process != "monitor" && process != "printer"){
throw runtime_error("Incorrect Output Device! Must be hard drive, monitor, or printer");
}
}
if(type == 'M'){
if(num_cycles <= 0){
throw runtime_error("Incorrect Memory Cycle Time! Must be >0");
}
if(process != "allocate" && process != "block"){
throw runtime_error("Incorrect Memory Operation! Must be allocate or block.");
}
}
}
catch(runtime_error& rte){
cout << "Encountered error validating metadata: " << rte.what() << endl;
exit(EXIT_FAILURE);
}
return instruction;
}