-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathSymTable.cpp
229 lines (208 loc) · 6.27 KB
/
SymTable.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
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
#include "SymTable.h"
using namespace std;
//|------------------main variables-------------------|
std::unordered_map<std::string, SymTabRecord > symbolTable; // the data struct of unordered_map is hashtable
std::stack<int> scopeStack; // store active scope
int curScope;
int maxScope; // use maxScope remeber the max scope
//|-----------------------------------------------|
void initSymTable()
{
curScope = 0;
maxScope = 0;
scopeStack.push(0);
}
//|-----------------------------------------------|
//|--Function: openScope
//|--Description: update maxScope, current scope, scopeStack
//|--Calls: 1) stack.push
//|--Called By: 1) parser
//|------------------------------------------------|
void openScope()
{
maxScope++; //increase maxScope
curScope = maxScope;
scopeStack.push(curScope); //put cur scope number into scope stack
}
//|-----------------------------------------------|
//|--Function: closeScope
//|--Description: update scopeStack and current scope
//|--Calls: 1) stack.pop 2)stack.empty 3) stack.top
//|--Called By: 1) parser
//|------------------------------------------------|
void closeScope()
{
if (!scopeStack.empty()) //check stack
{
scopeStack.pop(); //< pop the top of stack
}
if (!scopeStack.empty()) //check stack
{
curScope = scopeStack.top(); //< set the top of stack as currentScope
}
}
//|------------------------------------------------|
//|--Function: insert
//|--Calls: 1) map.find end insert (C++ STL)
//|--Called By: 1) parser
//|------------------------------------------------|
void insert(char* name, char type, int location, int isVar)
{
getFirst(name,IDLENGTH); // get first 8 char
convertToLittleCase(name);
/* get a key for ST key = currentScope + name */
stringstream ss;
ss << curScope << name;
string key = ss.str();
/* find key in symbolTable */
auto it = symbolTable.find(key);
if (it != symbolTable.end())
{
return; // exist in ST, ignore it
}
else
{ /* insert rec into ST*/
symbolTable.insert(make_pair(key, getSymTabRecord(name, curScope, type, location, isVar)));
}
}
//|----------------------------------------------------|
//|--Function: findInCurScope
//|--Calls: 1) unordered_map.find (C++ STL)
//|--Called By: 1) paser
//|----------------------------------------------------|
SymTabRecord* findInCurScope(char *name)
{
getFirst(name, IDLENGTH); // the first 8 is important
convertToLittleCase(name);
/* get a key key = currentScope + scope */
std::stringstream ss;
ss << curScope << name;
std::string key = ss.str();
/* find key in ST */
auto it = (symbolTable).find(key);
if (it != (symbolTable).end()) //< exist
{
return &(it->second); // a pointer of record in ST
}
else
{
return nullptr; //< no exist
}
}
//|-----------------------------------|
//|--Function: findInAllScopes
//|--Calls: 1) map.find (C++ STL)
//|--Called By: paser
//|-----------------------------------|
SymTabRecord* findInAllScopes(char *name)
{
getFirst(name,IDLENGTH);
convertToLittleCase(name);
/* step 1: get a copy of scopeStack */
std::stack<int> scopeStackCopy = scopeStack;
/* step 2: check active scope is empty */
while (!scopeStackCopy.empty())
{
/* step 2.1: get top scope number, then pop */
int tmpScope = scopeStackCopy.top();
scopeStackCopy.pop();
/* step 2.2 : get a key: tmpScope + name */
stringstream ss;
ss << tmpScope << name;
string key = ss.str();
/* step 2.3: find the key */
auto it = symbolTable.find(key);
if (it != symbolTable.end())
{
return &(it->second); // return pointer of record
}
}
return nullptr; // not found in all visual active scope
}
//|------- function: display ST -------------------|
void displaySymTable()
{
printf( "\n|----------------------SymbolTable---------------------|\n");
for (auto it = symbolTable.begin(); it != symbolTable.end(); it++) {
printf("scope: %-8d name: %-16s type: %-16c location: %-8d isVar: %-8d \n", it->second.scope, it->second.name, it->second.type, it->second.location, it->second.isVar);
}
}
void displaySymTable(FILE * file)
{
fprintf_s(file, "\n|----------------------SymbolTable---------------------|\n");
for (auto it = symbolTable.begin(); it != symbolTable.end(); it++) {
fprintf_s(file, "scope: %-8d name: %-16s type: %-16c location: %-8d isVar: %-8d \n", it->second.scope, it->second.name, it->second.type, it->second.location, it->second.isVar);
}
}
//|----------------------------------- all below is for test ----------------------------------|
void testFindInLocalScope(char *name) {
SymTabRecord *rec = nullptr;
printf("\nWe are now in scope: \"%d\", \tfinding in local scope: \"%s\" \n", curScope, name);
if ((rec = findInCurScope( name)) != nullptr)
{
printf("Result: ^0^ Found it in lcoal\n");
display(rec);
}
else
{
printf("Result: -_- No found in local\n");
}
}
void testFindInAllScopes(char *name) {
SymTabRecord *rec = nullptr;
printf("\nWe are now in scope: \"%d\" \tfinding in all scopes: \"%s\" \n", curScope, name);
if ((rec = findInAllScopes( name)) != nullptr)
{
printf("result: ^0^ Found it in scope: \"%d\"\n", rec->scope);
display(rec);
}
else
{
printf("result: -_- No found in all scopes\n");
}
}
void testST() {
initSymTable();
char name[IDMAXLENGTH] = "";
int in = 8;
SymTabRecord *stPtr = NULL;
do {
printf("\n|----1. openScope 2.insert 3. findinCurScope 4. findinAllScopes ------|\n");
printf( "|----5. closeScope 6. display 7. clear screen 8. exit------------------|\n");
scanf("%d", &in); // get instrction from keyboard
switch (in)
{
case 1:
openScope();
printf("open a scope\n");
break;
case 2:
printf("enter a name\n");
scanf("%s", name);
insert(name, 'i', -12, 1);
break;
case 3:
printf("enter a name\n");
scanf("%s", name);
testFindInLocalScope(name);
break;
case 4:
printf("enter a name\n");
scanf("%s", name);
testFindInAllScopes(name);
break;
case 5:
printf("close a scope\n");
closeScope();
break;
case 6:
displaySymTable();
break;
case 7:
system("cls");
break;
default:
break;
}
} while (8 != in);
}