-
Notifications
You must be signed in to change notification settings - Fork 0
/
SymbolTable.java
313 lines (229 loc) · 8.41 KB
/
SymbolTable.java
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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
import java.util.LinkedHashMap;
import java.util.Iterator;
//The SymbolTable.java file contains all the necessary structures for the implementation of our Symbol Table.
//The Symbol Table class consists of a LinkedHashMap. Each key is the class id and its key the corresponding Class Table.
public class SymbolTable {
LinkedHashMap<String, ClassTable> classId_table;
//Is_child will search throughout the class hierarchy to see if the "child" argument has f_mother as a mother class.
public boolean is_child(String f_mother, String child){
ClassTable current = this.get(child);
if (current.mother == null){
return false;
}else{
if (current.mother == f_mother){
return true;
}else{
return is_child(f_mother, current.mother);
}
}
}
//Find_last_type will search throughout the class hierarchy to get the last type of the first mother class that has a field table.
public String find_last_type(String id){
ClassTable current = this.get(id);
ClassTable mom_table = this.get(current.mother);
if (current.mother == null && current.field_table == null ){
return null;
}
if (mom_table.field_table == null){
return find_last_type(current.mother);
}else{
return mom_table.last_type;
}
}
//Find_field_table will search throughout the class hierarchy to get the field table offset sum of the first mother class that has a field table.
public int find_field_table(String id){
ClassTable current = this.get(id);
ClassTable mom_table = this.get(current.mother);
if (current.mother == null && current.field_table == null ){
return 0;
}
if (mom_table.field_table == null){
return find_field_table(current.mother);
}else{
return mom_table.ot_sum;
}
}
//Find_methodId_table will search throughout the class hierarchy to get the methodId table offset sum of the first mother class that has a methodId table.
public int find_methodId_table(String id){
ClassTable current = this.get(id);
ClassTable mom_table = this.get(current.mother);
if (current.mother == null && current.methodId_table == null ){
return 0;
}
if (mom_table.methodId_table == null){
return find_methodId_table(current.mother);
}else{
if(mom_table.methodId_table.containsKey("main")){
return -1;
}
return mom_table.mt_sum;
}
}
//Mother_search will search throughout the class hierarchy to get the first mother that has the "id" argument.
public String mother_search(String mother, String id){
ClassTable current = this.get(mother);
if (current.mother == null){
return null;
}else{
boolean not_up = false;
ClassTable new_mother = this.get(current.mother);
if (new_mother.methodId_table != null){
if( new_mother.methodId_table.containsKey(id) ){
return current.mother;
}else{
not_up = true;
}
}
if( new_mother.methodId_table == null || not_up == true ){
return mother_search(current.mother,id);
}
}
return null;
}
//Adding a class to the classId table
public void add_class(String id){
if (classId_table == null){
classId_table = new LinkedHashMap<String, ClassTable>();
}
classId_table.put(id, new ClassTable());
}
//Getting the last ClassTable of the classId table
public ClassTable get_last(){
String lKeyLast = null ;
for(String key : classId_table.keySet()){
lKeyLast = key;
}
ClassTable temp = classId_table.get(lKeyLast);
return temp;
}
//Getting the last class id of the classId table
public String get_last_key(){
String lKeyLast = null ;
for(String key : classId_table.keySet()){
lKeyLast = key;
}
return lKeyLast;
}
//Getting the ClassTable of the "id" argument.
public ClassTable get(String id){
ClassTable temp = classId_table.get(id);
return temp;
}
}
//The ClassTable will contain all the fields and method names of a class, as well as some additional information.
class ClassTable{
public String mother; //Mother is the name of the class whom this class extends from. If the class is not a child, this string is null.
public String last_type; //Last type in the field table. It is used for the creation of the Offset Table.
public int ot_sum; //ot_sum contains the sum of the offsets from the fields. Its usage will be explained later on.
public int mt_sum; //Same thing as ot_sum but for the methods.
public LinkedHashMap<String, String> field_table ;
public LinkedHashMap<String, Tuple<String,MethodTable>> methodId_table ;
//GetKey function will return the key (of the field table) that corresponds to the "index" argument.
public String getKey(int index) {
Iterator<String> itr = field_table.keySet().iterator();
for (int i = 0; i < index; i++) {
itr.next();
}
return itr.next();
}
//Same thing as the previous function, but for the methodId table.
public String getKey_m(int index) {
Iterator<String> itr = methodId_table.keySet().iterator();
for (int i = 0; i < index; i++) {
itr.next();
}
return itr.next();
}
//Recurse_lookup will search throughout the class hierarchy to see if the "id" argument exists.
public String recurse_lookup(String id, LinkedHashMap<String, ClassTable> classId_table ){
String Type = null;
if( this.field_table != null ){
if( this.field_table.containsKey(id) ) {
Type = this.field_table.get(id);
return Type;
}else{
if (this.mother != null ){
ClassTable mother_t = classId_table.get(this.mother);
Type = mother_t.recurse_lookup(id,classId_table);
if (Type == null){
return null;
}else{
return Type;
}
}
return null;
}
}else{
if (this.mother != null ){
ClassTable mother_t = classId_table.get(this.mother);
Type = mother_t.recurse_lookup(id,classId_table);
if (Type == null){
return null;
}else{
return Type;
}
}
return null;
}
}
//f_insert adds a variable and its type to the field table.
public void f_insert(String id, String type){
if (field_table == null){
field_table = new LinkedHashMap<String, String>();
}
field_table.put(id, type);
}
//meth_insert adds a variable and its type to the field table. Note that the value of a methodId corresponds to a tuple.
//The tuple consists of a string which is the method type, and a MethodTable object, where parameters and local variables will be stored.
public void meth_insert(String id, String ret_type ){
if (methodId_table == null){
methodId_table = new LinkedHashMap<String, Tuple<String,MethodTable>>();
}
methodId_table.put(id, new Tuple(ret_type,new MethodTable() ) );
}
//Getting the last MethodTable of the methodId table.
public MethodTable get_last_meth(){
String lKeyLast = null ;
for(String key : methodId_table.keySet()){
lKeyLast = key;
}
Tuple<String, MethodTable> temp = methodId_table.get(lKeyLast);
return temp.y;
}
}
//Tuple class is used to store two variables together, it is needed for the methodId table which will be explained later on.
class Tuple<X, Y> {
public final X x;
public final Y y;
public Tuple(X x, Y y) {
this.x = x;
this.y = y;
}
}
//The Method Table is used to store the parameters and local variables of a method (if any)
class MethodTable{
public LinkedHashMap<String, String> param_table ;
public LinkedHashMap<String, String> local_table ;
//GetKey function will return the key (of the parameter table) that corresponds to the "index" argument.
public String getKey(int index) {
Iterator<String> itr = param_table.keySet().iterator();
for (int i = 0; i < index; i++) {
itr.next();
}
return itr.next();
}
//p_insert adds a variable and its type to the parameter table.
public void p_insert(String id, String type){
if (param_table == null){
param_table = new LinkedHashMap<String, String>();
}
param_table.put(id, type);
}
//l_insert adds a variable and its type to the local variables table.
public void l_insert(String id, String type){
if (local_table == null){
local_table = new LinkedHashMap<String, String>();
}
local_table.put(id, type);
}
}