-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParseUtils.cpp
132 lines (121 loc) · 4.69 KB
/
ParseUtils.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
//
// Created by t on 24/12/18.
//
#include "ParseUtils.h"
#include "ConditionParser.h"
#include "ConnectCommand.h"
#include "VarCommand.h"
#include "PrintCommand.h"
#include "SleepCommand.h"
#include "EntercCommand.h"
#include "OpenServerCommand.h"
#include "LoopCondition.h"
#include "IfCondition.h"
#include "ShuntingYard.h"
//parse by delimiter. input is string to delimit, token and vector for output
void ParseUtils::parseByDelimiter(string inputStr, string token, vector<string> *outputVec) {
//go over the inputStr and parses according to to the token
std::size_t prev = 0, pos;
while ((pos = inputStr.find_first_of(token, prev)) != string::npos) {
if (pos > prev) {
//remove
outputVec->push_back(inputStr.substr(prev, pos - prev));
}
prev = pos + 1;
}
//add last word
if (prev < inputStr.length()) {
outputVec->push_back(inputStr.substr(prev, string::npos));
}
}
//lexer. perform the commands in the string input. get a single line
void ParseUtils::lexer(const string *input, vector<string> *inputVec){
string line;
std::istringstream iss(*input);
//if not in while loop or in if condition, delete the vector contents
if (!inputVec->empty() && ((!(inputVec->at(0) == "while" || inputVec->at(0) == "if"))
|| ((inputVec->at(0) == "while" || inputVec->at(0) == "if")
&& inputVec->at(inputVec->size() - 1) == "}"))) {
inputVec->clear();
}
//go over the line and parses according to to the token
while(std::getline(iss,line)){
parseByDelimiter(line," \t", inputVec);
}
}
//parser. perform the commands in the string vector input. get a single line
void ParseUtils::parser(vector <string> *inputVec){
//todo handle the case where { and } are not in their own lines
//if in while loop or in if condition and haven't reached end, return without doing the command
if (!inputVec->empty() && (inputVec->at(0) == "while" || inputVec->at(0) == "if") &&
inputVec->at(inputVec->size() - 1) != "}") {
inputVec->push_back("\n");
return;
}
//do the command
//print test
//for(auto it=inputVec->begin(); it!=inputVec->end(); ++it){
//cout<<' '<<*it<<endl;
//}
//find in commands
Command *c;
if (!inputVec->empty() && (this->commandMap.count(inputVec->at(0)) > 0)) {
//cout << this->commandMap.find(inputVec->at(0))->first <<endl;
c = this->commandMap.find(inputVec->at(0))->second;
c->setSymbolTable(this->symbols);
c->doCommand(inputVec);
} else { //find in variables
if (!inputVec->empty() && symbols->exist(inputVec->at(0))) {
//cout << "found in varsOrder" << endl;
//set the variable bind
string valueStr = "";
for (auto it =inputVec->begin() + 2; it != inputVec->end(); ++it) {
valueStr += (*it);
}
ShuntingYard shunt;
double value = shunt.evaluate(valueStr, this->symbols);
//cout << "var to set: " << inputVec->at(0) << " value: " << value << endl;
symbols->set(inputVec->at(0), value);
} else {
throw "bad input: not a command or a variable";
}
}
}
ParseUtils::ParseUtils(SymbolsTable *symbols1) {
this->symbols = symbols1;
//cout << this->symbols->exist("g") << endl;
//add commands: openServerCommand
OpenServerCommand *server = new OpenServerCommand();
server->setSymbolTable(symbols);
commandMap["openDataServer"] = (Command *) server;
//connect command
ConnectCommand *connect = new ConnectCommand();
connect->setSymbolTable(symbols);
commandMap["connect"] = (Command *) connect;
//var command
VarCommand *varCommand = new VarCommand();
varCommand->setSymbolTable(symbols);
commandMap["var"] = (Command *) varCommand;
//print command
PrintCommand *printCommand = new PrintCommand(symbols);
commandMap["print"] = (Command *) printCommand;
//sleep command
SleepCommand *sleepCommand = new SleepCommand();
commandMap["sleep"] = (Command *) sleepCommand;
//enterc command
EntercCommand *entercCommand = new EntercCommand();
commandMap["enterc"] = (Command *) entercCommand;
//while command
LoopCondition *loopCommand = new LoopCondition();
commandMap["while"] = (Command *) loopCommand;
//if command
IfCondition *ifCommand = new IfCondition();
commandMap["if"] = (Command *) ifCommand;
}
ParseUtils::~ParseUtils() {
//cout << "end of parse utils" << endl;
for(auto it=this->commandMap.begin(); it!=commandMap.end(); ++it){
delete (*it).second;
(*it).second = NULL;
}
}