Из Википедии, бесплатной энциклопедии
  (Перенаправлено из Symbol (вычисления) )
Перейти к навигации Перейти к поиску

В информатике , таблица символов представляет собой структуру данных , используемый язык переводчик , такие как компилятор или интерпретатор , где каждый идентификатор (или символ) в программе в исходном коде связан с информацией , касающейся его заявление или появлениями в источнике. Другими словами, записи таблицы символов хранят информацию, относящуюся к соответствующему символу записи.

Фон [ править ]

Таблица символов может существовать в памяти только во время процесса перевода или может быть встроена в вывод перевода, например, в объектный файл ABI для дальнейшего использования. Например, его можно использовать во время сеанса интерактивной отладки или как ресурс для форматирования диагностического отчета во время или после выполнения программы. [1]

Описание [ править ]

Минимальная информация, содержащаяся в таблице символов, используемой переводчиком, включает имя символа и его местоположение или адрес. Для компилятора, ориентированного на платформу с концепцией перемещаемости, он также будет содержать атрибуты перемещаемости (абсолютные, перемещаемые и т. Д.) И необходимую информацию о перемещении для перемещаемых символов. Таблицы символов для языков программирования высокого уровня могут хранить тип символа: строка, целое число, число с плавающей запятой и т. Д., Его размер, а также его размеры и его границы. Не вся эта информация включена в выходной файл, но может быть предоставлена ​​для использования при отладке . Во многих случаях перекрестная ссылка символаинформация хранится в таблице символов или связана с ней. Большинство компиляторов печатают часть или всю эту информацию в таблице символов и списках перекрестных ссылок в конце перевода.

Реализация [ править ]

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

Компилятор может использовать одну большую таблицу символов для всех символов или использовать отдельные иерархические таблицы символов для различных областей видимости . Например, в языке с ограниченной областью видимости, таком как Algol или PL / I, символ «p» может быть объявлен отдельно в нескольких процедурах, возможно, с разными атрибутами. Объем каждого объявления - это раздел программы, в котором ссылки на «p» соответствуют этому объявлению. Каждое объявление представляет собой уникальный идентификатор «p». Таблица символов должна иметь некоторые средства различения ссылок на разные "p".

Распространенной структурой данных, используемой для реализации таблиц символов, является хеш-таблица . Время поиска в хеш-таблицах не зависит от количества элементов, хранящихся в таблице, поэтому оно эффективно для большого количества элементов. Это также упрощает [ как? ] классификация литералов в табличном формате.

Поскольку лексический анализатор тратит большую часть своего времени на просмотр таблицы символов, это действие имеет решающее влияние на общую скорость компилятора. Таблица символов должна быть организована таким образом, чтобы записи можно было найти как можно быстрее. Хеш-таблицы обычно используются для организации таблицы символов, где ключевое слово или идентификатор «хешируются» для создания нижнего индекса массива. Коллизии неизбежны в хеш-таблице, и распространенный способ их обработки - сохранить синоним в следующем доступном свободном месте в таблице.

Приложения [ править ]

Объектный файл будет содержать таблицу символов идентификаторов , которые он содержит , которые являются видимыми извне. Во время связывания различных объектных файлов компоновщик идентифицирует и разрешает эти ссылки на символы. Обычно все неопределенные внешние символы ищутся в одной или нескольких библиотеках объектов . Если найден модуль, который определяет этот символ, он связан с первым объектным файлом, и любые неопределенные внешние идентификаторы добавляются в список идентификаторов для поиска. Этот процесс продолжается до тех пор, пока не будут разрешены все внешние ссылки. Если одна или несколько проблем остаются нерешенными в конце процесса, это ошибка.

При обратном проектировании исполняемого файла многие инструменты обращаются к таблице символов, чтобы проверить, какие адреса были назначены глобальным переменным и известным функциям. Если таблица символов была удалена или очищена перед преобразованием в исполняемый файл, инструментам будет труднее определить адреса или понять что-либо о программе.

Пример [ править ]

Рассмотрим следующую программу, написанную на C :

// Объявление внешней функции extern  double  bar ( double  x );// Определение публичной функции double  foo ( int  count ) {  double  sum  =  0.0 ; // Суммируем все значения bar (1) в bar (count)  for  ( int  i  =  1 ;  i  <=  count ;  i ++ )  sum  + =  bar (( double )  i );  сумма возврата  ; }

Компилятор AC, который анализирует этот код, будет содержать как минимум следующие записи таблицы символов:

Кроме того, таблица символов также будет содержать записи, сгенерированные компилятором для промежуточных значений выражения (например, выражение, которое iпреобразует переменную цикла в a doubleи возвращаемое значение вызова функции bar()), метки операторов и т. Д.

Пример: SysV ABI [ править ]

Пример таблицы символов можно найти в спецификации двоичного интерфейса приложения SysV (ABI), которая определяет, как символы должны быть размещены в двоичном файле, чтобы различные компиляторы, компоновщики и загрузчики могли последовательно находить и работать с символы в скомпилированном объекте.

SysV ABI реализован в утилите nm GNU binutils . В этом формате используется отсортированное поле адреса памяти, поле «Тип символа» и идентификатор символа (называемый «Имя»). [2]

Типы символов в SysV ABI (и выводе nm) указывают на природу каждой записи в таблице символов. Каждый тип символа представлен одним символом. Например, записи таблицы символов, представляющие инициализированные данные, обозначаются символом «d», а записи таблицы символов для функций имеют тип символа «t» (поскольку исполняемый код расположен в текстовой части объектного файла). Кроме того, заглавные буквы в типе символа указывают на тип связи: строчные буквы указывают, что символ является локальным, а верхний регистр указывает на внешнюю (глобальную) связь.

Пример: таблица символов Python [ править ]

Язык программирования Python включает обширную поддержку для создания таблиц символов и управления ими. [3] Свойства, которые могут быть запрошены, включают, является ли данный символ свободной переменной или связанной переменной , является ли это областью блока или глобальной областью , импортируется ли он и какому пространству имен принадлежит.

Пример: динамические таблицы символов [ править ]

Некоторые языки программирования позволяют манипулировать таблицей символов во время выполнения, так что символы могут быть добавлены в любое время. Ракетка - пример такого языка. [4]

И LISP, и языки программирования Scheme позволяют связывать произвольные общие свойства с каждым символом. [5]

Язык программирования Prolog - это, по сути, язык манипулирования таблицей символов; символы называются атомами , и отношения между символами можно рассуждать. Точно так же OpenCog предоставляет динамическую таблицу символов, называемую атомным пространством , которая используется для представления знаний .

См. Также [ править ]

  • Символ отладки

Ссылки [ править ]

  1. Перейти ↑ Nguyen, Binh (2004). Словарь Linux . п. 1482 . Проверено 14 апреля 2018 года .
  2. ^ "нм" . sourceware.org . Проверено 30 мая 2020 года .
  3. ^ symtable - документация Python
  4. ^ Символы - Документация по ракетке
  5. ^ Символы - Документация Хитрости