Моя задача - создать компилятор, который лексизирует, анализирует и анализирует результирующее абстрактное синтаксическое дерево, чтобы обеспечить сопоставление типов, избежать дублирования объявлений и т. Д.
Нам было поручено создать таблицу символов, которая содержит карту переменных и их типов для каждой области видимости. Я выбрал вектор карт. Я предпочел это, а не стек, так как я могу перебирать его при проверке переменных в любой области.
Я построил операции Push, Pop, Lookup и Insert для этой структуры, как показано ниже, и моя идея заключалась в том, чтобы сохранить ссылку на последнюю карту в векторе и добавить к ней переменные. Когда вводится новая область действия, выполняется операция push, создавая новую карту в векторе, в которой будут храниться массивы.
Когда выходит из области действия, выполняется операция Pop, чтобы удалить карту в конце вектора и получить предыдущую карту, которая теперь находится позади вектора.
Посредством отладки я заметил, что вектор просто не содержит деталей карты, и работа по ссылке, похоже, ничего не делает для обновления вектора, который должен содержать эту карту. Как правильно ссылаться на карту внутри вектора и поддерживать эту структуру?
Таблица символов:
struct SymbolTable {
// Stack defining scopes holding identifier / type details
std::vector<std::map<std::string,std::string>> _scopeVector;
// Tracks current working stack
std::map<std::string,std::string> _currentMap;
SymbolTable() = default;
void Push() {
std::map<std::string,std::string> *_tempMap;
_tempMap = new std::map<std::string,std::string>();
_scopeVector.push_back(*_tempMap);
_currentMap = _scopeVector.back();
}
void Insert(std::string p_name, std::string p_type) {
_currentMap.insert(std::make_pair(p_name,p_type));
}
// Returns type if found, empty if not
std::string Lookup (std::string p_name) {
for (int i = 0; i < _scopeVector.size(); i++) {
if (_scopeVector[i].find(p_name) == _scopeVector[i].end()) {
// No match yet
} else {
return _scopeVector[i].find(p_name)->first; // return var name
}
}
std::cerr << "Type name " << p_name << " not found in all of stack" << std::endl;
return "";
}
void Pop () {
_scopeVector.pop_back();
_currentMap = _scopeVector.back();
}
};
SymbolTable *ST;
Конструктор класса, который устанавливает таблицу символов:
SemanticAnalysisVisitor() {
ST = new SymbolTable();
ST->Push();
}
Изображение отладчика пустой векторной, но заполненной карты