Ответ 1
Большинство учебников по компиляторам расскажут вам о таблицах символов и часто расскажут вам о скромной сложности langauge, такой как Pascal. Вы не найдете информацию о таблицах символов С++ в учебнике; это слишком загадочно.
Мы предлагаем полный интерфейс С++ 14 для нашего инструментария DMS Software Reengineering Toolkit. Он анализирует С++, строит подробные AST и выполняет разрешение имен и типов, которое включает в себя создание точной таблицы символов.
Ниже приведены слайды нашего учебника о том, как использовать DMS, сфокусированный на структурах таблиц символов С++.
OP специально спросила, что происходит с классами. Следующая диаграмма показывает это для крошечной программы на С++ в верхнем левом углу. В остальной части диаграммы показаны поля, которые представляют собой то, что мы называем "пространствами символов" (или "областями" ), которые являются, по существу, хэш-таблицами, отображающими имена символов (каждый ящик содержит список символов, которыми он владеет) к информации, которую DMS знает об этом символе (расположение исходного файла определения, список узлов AST, которые ссылаются на определение, и сложный союз, который представляет тип, и который, в свою очередь, может указывать на другие типы). Стрелки показывают, как связаны пространства символов; стрелка из пространства A в пространство B означает, что "область A содержится в пределах области B". Обычно процесс поиска пространства символов, поиск области A для символа x, продолжит поиск в области B, если x не найден в A. Вы заметите, что стрелки нумеруются с целым числом; это говорит поисковой машине сначала взглянуть в область с наименьшим номером родителя, прежде чем пытаться искать области с помощью стрелок с большими числами. Так упорядочиваются области (обратите внимание, что класс C наследует от A и B; любой поиск поля в классе C, такой как "b", будет вынужден сначала просмотреть область действия A, а затем в области для B. В таким образом, выполняются правила поиска С++.
Обратите внимание, что имена классов записываются в (уникальное) глобальное пространство имен, потому что они объявлены на верхнем уровне. Если бы они были определены в некотором явном пространстве имен, тогда пространство имён имело бы собственное пространство символов, которое записало объявленные классы, а само пространство имен было бы записано в глобальном пространстве символов.
OP не спрашивал, как выглядит таблица символов для тел функций, но у меня просто есть иллюстративный слайд для этого, тоже ниже. Символьные пространства работают одинаково. То, что показано на этом слайде, - это связь между пространством символов и областью области, которую он представляет. Эта привязка фактически реализуется указателем, связанным с пространством символов, с соответствующим AST (s, определения пространства имен могут быть разбросаны по множеству мест).
Обратите внимание, что в этом случае имя функции записывается в глобальное пространство имен, потому что оно объявлено на верхнем уровне. Если он был определен внутри области действия класса, имя функции было бы записано в пространстве символов для тела класса (на предыдущей диаграмме).
Как правило, детали того, как организована таблица символов, полностью зависит от компилятора и от выбора дизайнеров. В нашем случае мы разработали очень общий пакет управления таблицами таблиц, потому что мы планировали (и использовали) один и тот же пакет для обработки нескольких языков (C, С++, Java, COBOL, несколько устаревших языков) единым способом. Однако абстрактные структуры пространств символов и наследования должны быть реализованы по существу эквивалентными способами для компиляторов С++; в конце концов, они должны моделировать ту же информацию. Я бы ожидал подобных структур в компиляторах GCC и Clang (ну, дуги наследования с целыми номерами, возможно, нет:)
Как практически, неважно, сколько "проходов" у вашего компилятора. В значительной степени это необходимо для создания этих структур, чтобы помнить, что он знает о символах, в пределах прохода и через проходы.
Хотя создание синтаксического анализатора С++ очень сложно сам по себе, создание такой таблицы символов намного сложнее. Усилия затмевают усилия по созданию парсера С++. Наш преобразователь имен С++ - это 250K SLOC кода атрибута-грамматики, скомпилированный и исполняемый DMS. Получение прав на информацию - это огромная головная боль; Справочное руководство по С++ является огромным, запутанным, факты разбросаны по всему документу, и в разных местах это противоречиво (мы пытаемся отправить жалобы на это в комитет) и/или несовместимы между компиляторами (у нас есть версии для GCC и Visual Studio 201x).
Обновить март 2017: теперь есть таблицы символов для С++ 2014, причем С++ 2017 происходит на мгновение.