Вам необходимо сопоставление идентификаторов типу / значению для каждого экземпляра области, найденного в исходном коде, в соответствии с определением языка. Некоторые люди назвали бы одно такое отдельное отображение «таблицей символов», но я думаю, что это злоупотребление этим термином; Я предпочитаю термин «пространство символов» для таких отдельных карт видимости. Для меня набор отображений областей видимости - это таблица символов.
Идея пространств / таблиц символов не зависит от того, как и когда ваш компилятор создает такие пространства / таблицы символов.
Для классических языков, подобных Паскалю, области видимости могут быть вложены таким образом, чтобы соответствовать синтаксису вложенности программ («лексическая область видимости»). Для таких языков можно создавать пространства символов в виде стека, обрабатывая программу сверху вниз (от наименьшего номера строки до наибольшего номера строки). Когда встречается каждая новая граница области видимости, новое пространство символов помещается в стек. Поиск идентификатора происходит путем поиска в текущем пространстве символов (том, что находится наверху стека), и, если идентификатор не найден, поиск в пространствах символов дальше вниз по стеку. При выходе из области действия это пространство символов может быть удалено (например, вытеснено). Эта схема работает только в том случае, если компилятор обрабатывает программу за один проход. Иногда вы хотите сохранить все пространства символов, чтобы разрешить сложную обработку программы за несколько проходов; в этом случае вы можете создать пробелы символов в том виде, в каком они встречаются, но не можете их удалить.
Во многих языках есть правила области видимости, которые вообще не подходят для пространства стека символов. Очевидным примером являются пространства имен, которые на самом деле представляют собой просто пространства символов, доступные из широко разделенных частей программы.
Я создаю изрядное количество инструментов обработки языка, которым требуются таблицы символов, используя инфраструктуру инструментов (подробности об этом инструменте см. В биографии). В основном я не использую стековый стиль пространств символов, а инфраструктура инструментов упрощает создание (и удаление, если необходимо) пространств символов и обеспечение связей между одним пространством символов и другим. Одна из этих ссылок - это специальная ссылка с лексической областью видимости, позволяющая инфраструктуре записывать, что одно пространство символов лексически встроено в другое. Стандартная схема поиска затем ищет "текущую" область видимости, и, если она не находит соответствующий символ, следует по ссылке лексической области, чтобы продолжить поиск.
Схема на самом деле немного умнее; с каждым пространством символов связана последовательность родительских связей пространства символов; стандартный лексический поиск обращается к родителям (рекурсивно), когда символ не найден в текущей области. При наличии только одной родительской ссылки это то же самое, что и лексическая область видимости. С несколькими родительскими ссылками он прекрасно обрабатывает множественное наследование. Пространства имен обрабатываются с использованием «хорошо известного» пространства символов верхнего уровня, которое содержит символы для пространств имен верхнего уровня и т. Д. Вы можете увидеть, как это выглядит для C ++, в этом ответе SO: https://stackoverflow.com/a/32012786/120163
Пользовательское действие («процедурное вложение») вызывается перед посещением ссылок лексической области видимости; это позволяет действию решить сначала посетить произвольные другие пространства символов. В частности, это позволяет поиску в пространстве символов для Java извлекать исходные файлы / файлы классов из файловой системы, извлекать их символы, а затем продолжать поиск по мере необходимости.
person
Ira Baxter
schedule
05.01.2014