-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrpngenerator.cpp
More file actions
233 lines (212 loc) · 6.67 KB
/
rpngenerator.cpp
File metadata and controls
233 lines (212 loc) · 6.67 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
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
#include "rpngenerator.h"
#include "utils.h"
#include <iostream>
#include <vector>
#include <string>
using namespace std;
void expr(Token &tk, TkList tkList, vector<RPNToken> &tokensout);
void expr1_par(Token &tk, TkList &tkList, vector<RPNToken> &tokensout);
void expr0_val(Token &tk, TkList &tkList, vector<RPNToken> &tokensout);
void expr2_plus1(Token &tk, TkList &tkList, vector<RPNToken> &tokensout);
void expr3_mul(Token &tk, TkList &tkList, vector<RPNToken> &tokensout);
void expr4_plus(Token &tk, TkList &tkList, vector<RPNToken> &tokensout);
void expr6_less(Token &tk, TkList &tkList, vector<RPNToken> &tokensout);
void expr7_eq(Token &tk, TkList &tkList, vector<RPNToken> &tokensout);
void expr13_tst(Token &tk, TkList &tkList, vector<RPNToken> &tokensout);
void printRPN(const vector<RPNToken> &RPNTokens, int tab, int report)
{
if (!report)
return;
cout << "******************** RPN sequence ********************\n";
cout << "opcode : ";
for (const RPNToken &element : RPNTokens)
cout << "\t" << ppOC[static_cast<int>(element.opcode)] << " ";
cout << endl;
cout << "opcode: ";
for (const RPNToken &element : RPNTokens)
cout << "\t" << static_cast<int>(element.opcode) << " ";
cout << endl;
cout << "arity : ";
for (const RPNToken &element : RPNTokens)
cout << "\t" << element.arity << " ";
cout << endl;
cout << "value : ";
for (const RPNToken &element : RPNTokens)
cout << "\t" << element.value << " ";
cout << endl;
}
bool isa(const Token &token, const vector<OC> &allowedTypes)
{
// check if the symbol sym is one of the symbols in the list op
return (count(allowedTypes.begin(), allowedTypes.end(), token.opcode) > 0);
return true;
}
bool precedenceIs2(TkList tkList)
{
// the current operator is "+" or "-".
// we check if it is a binary operator (arity 2, precedence 1) or a unary op (arity 1, precedence 2)
// this depends on the previous token
Token t = tkList.get(-2);
if (isa(t, {OC::NIL}))
return true; // expression starts with + or -
if (isa(t, {OC::PAR_R, OC::VAR, OC::NUM}))
return false;
return true;
}
void pushToken(Token tk, vector<RPNToken> &out)
{
RPNToken newRPNToken;
newRPNToken.opcode = tk.opcode;
newRPNToken.arity = tk.arity;
newRPNToken.value = tk.value;
out.push_back(newRPNToken);
}
vector<RPNToken> makeRPN(vector<Token> tkListIn, int report)
{
// we will move the input token list into a structure TkList, equipped with member funtions
TkList tkList;
tkList.tokens = tkListIn;
vector<RPNToken> tokensout;
tokensout.clear();
Token tk = tkList.pop();
try
{
Token tk = tkList.pop();
expr(tk, tkList, tokensout);
}
catch (const exception &e)
{
cout << "\n\n!!! PARSE ERROR:" << e.what() << endl
<< endl;
;
};
printRPN(tokensout, 5, report);
return tokensout;
}
vector<RPNToken> makeRPN(string textIn,
const map<std::string, Token> &keywords,
VarTable &vartabel, int report)
{
vector<Token> tokens = makeTokenList(textIn, keywords, vartabel, report);
return makeRPN(tokens, report);
}
Token nextToken(TkList &tkList)
{
if (tkList.done())
throw invalid_argument("symbols missing!");
Token next = tkList.pop();
return next;
}
void expr0_val(Token &tk, TkList &tkList, vector<RPNToken> &tokensout)
{
if (isa(tk, {OC::VAR, OC::NUM}))
{
pushToken(tk, tokensout);
tk = tkList.pop();
}
else
expr1_par(tk, tkList, tokensout);
}
void expr1_par(Token &tk, TkList &tkList, vector<RPNToken> &tokensout)
{
if (isa(tk, {OC::PAR_L}))
{
tk = tkList.pop();
expr13_tst(tk, tkList, tokensout);
if (tk.opcode != OC::PAR_R)
throw invalid_argument("received " + static_cast<int>(tk.opcode));
tk = nextToken(tkList);
}
}
void expr2_plus1(Token &tk, TkList &tkList, vector<RPNToken> &tokensout)
{
expr0_val(tk, tkList, tokensout);
if (precedenceIs2(tkList))
{
// this means pass or change sign (unary operator)
tk.arity = 1;
if (tk.opcode == OC::ADD)
tk.opcode = OC::PAS;
else
tk.opcode = OC::CHS; //!!! poor coding
Token save = tk;
tk = tkList.pop();
expr0_val(tk, tkList, tokensout);
pushToken(save, tokensout);
}
}
void expr3_mul(Token &tk, TkList &tkList, vector<RPNToken> &tokensout)
{
expr2_plus1(tk, tkList, tokensout);
if (tk.precedence == 3)
{
Token save = tk;
tk = tkList.pop();
expr3_mul(tk, tkList, tokensout);
pushToken(save, tokensout);
}
}
void expr4_plus(Token &tk, TkList &tkList, vector<RPNToken> &tokensout)
{
expr3_mul(tk, tkList, tokensout);
if (tk.precedence == 4)
{
Token save = tk;
tk = tkList.pop();
expr4_plus(tk, tkList, tokensout);
pushToken(save, tokensout);
}
}
void expr6_less(Token &tk, TkList &tkList, vector<RPNToken> &tokensout)
{
expr4_plus(tk, tkList, tokensout);
if (tk.precedence == 6)
{
Token save = tk;
tk = tkList.pop();
expr6_less(tk, tkList, tokensout);
pushToken(save, tokensout);
}
}
void expr7_eq(Token &tk, TkList &tkList, vector<RPNToken> &tokensout)
{ // TODO !!!
expr6_less(tk, tkList, tokensout);
if (tk.precedence == 7)
{
Token save = tk;
tk = tkList.pop();
expr7_eq(tk, tkList, tokensout);
pushToken(save, tokensout);
}
}
void expr13_tst(Token &tk, TkList &tkList, vector<RPNToken> &tokensout)
{
expr7_eq(tk, tkList, tokensout);
if (tk.precedence == 13)
{
Token save = tk;
tk = tkList.pop();
expr7_eq(tk, tkList, tokensout); // no need to push "?", ":" is ternary, will take care
save = tk;
tk = nextToken(tkList);
expr7_eq(tk, tkList, tokensout);
pushToken(save, tokensout);
}
}
void expr14_assgn(Token &tk, TkList &tkList, vector<RPNToken> &tokensout)
{
Token save = tkList.get(0);
pushToken(tk, tokensout);
tk = tkList.pop();
tk = tkList.pop();
expr13_tst(tk, tkList, tokensout);
pushToken(save, tokensout);
}
void expr(Token &tk, TkList tkList, vector<RPNToken> &tokensout)
{
Token save = tkList.get(0);
if (isa(tk, {OC::VAR}) & (save.precedence == 14))
expr14_assgn(tk, tkList, tokensout);
else
expr13_tst(tk, tkList, tokensout);
}