Проведение ссылки на карту с вектором карт - PullRequest
0 голосов
/ 17 мая 2019

Моя задача - создать компилятор, который лексизирует, анализирует и анализирует результирующее абстрактное синтаксическое дерево, чтобы обеспечить сопоставление типов, избежать дублирования объявлений и т. Д.

Нам было поручено создать таблицу символов, которая содержит карту переменных и их типов для каждой области видимости. Я выбрал вектор карт. Я предпочел это, а не стек, так как я могу перебирать его при проверке переменных в любой области.

Я построил операции 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();
}

Изображение отладчика пустой векторной, но заполненной карты

1 Ответ

1 голос
/ 17 мая 2019

Что касается вашей проблемы (я думаю ), то утверждение

_currentMap = _scopeVector.back();

копирует карту из вектора.

_currentMap всегда будет отдельной и отличной картой, совершенно не связанной с тем, что находится в векторе.

Кажется, вы хотите использовать ссылки, но в этом случае это невозможно (если вы не сделаетеРедизайн).

Вы можете решить эту проблему (и утечку памяти, о которой я упоминал в комментарии), имея вектор («умных») указателей на карты, а также сделать _currentMap («умным») указателем..

...