#pragma once #include "common.h" namespace antlrSysY { template class ScopeTable { typedef std::map ScopeTableEntry_t; private: std::vector _scope_list; public: // On init, there is already an empty scope ScopeTable() { _scope_list.push_back(ScopeTableEntry_t()); } ~ScopeTable() {} void enter_scope() { _scope_list.push_back(ScopeTableEntry_t()); }; void leave_scope() { if (_scope_list.size() <= 1) throw GrammarException("Unable to leave global scope"); _scope_list.pop_back(); }; void push_name(const std::string &name, const T_V &value) { auto ¤t_scope = _scope_list.back(); if (current_scope.count(name)) throw GrammarException("Duplicate name in current scope"); current_scope[name] = value; }; std::optional get_name(const std::string &name) { for (auto i = _scope_list.size() - 1; i >= 0; --i) { if (_scope_list[i].count(name)) { return {_scope_list[i][name]}; } } return {}; }; std::optional get_name(const std::string &name, int level) { if (_scope_list[level].count(name)) { return {_scope_list[level][name]}; } return {}; }; int get_level() const { return _scope_list.size() - 1; } }; }