Нет таблицы символов в Go?

Новый язык Google "Go" говорит на своем сайте:

язык разработан так, чтобы его можно было легко анализировать и анализировать без таблицы символов

Я, конечно, не специалист по этим вопросам, но я думал, что таблица символов - это базовая конструкция, общая для всех компиляторов для языков, которые используют переменные, а Go явно использует переменные. Что я не понимаю?

5 ответов

Решение

Синтаксический анализ означает простое вычисление структуры программы: разделение модуля на операторы / объявления, разбиение выражений на подвыражения и т. Д. В результате получается древовидная структура, известная как "дерево разбора" или "абстрактное синтаксическое дерево" (АСТ).

Очевидно, C++ требует таблицы символов для анализа.

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

Конечно, синтаксический анализ - это только часть компиляции, и вам понадобится таблица символов для полной компиляции.

Однако сам синтаксический анализ может быть полезен при написании инструментов анализа (например, какой модуль импортирует какие модули). Таким образом, упрощение процесса синтаксического анализа означает, что проще писать инструменты анализа кода.

@ Справедливость верна. Чтобы немного углубиться в это, в C единственная сложная часть состоит в том, чтобы отличать типы от переменных. В частности, когда вы видите это:

T t;

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

В C++ все намного сложнее. Существует огромное количество неоднозначных или потенциально неоднозначных конструкций. Наиболее очевидным является следующий:

B::C (c);

Помимо того, что не ясно, если B это class, typedef или namespace, также не ясно, если C это тип и c объект этого типа, или если C это функция (или конструктор), принимающая c в качестве аргумента (или даже если C является объектом с operator() перегружена). Вам нужна таблица символов для продолжения анализа, хотя все еще можно продолжить достаточно быстро, так как тип символа указан в таблице символов.

Все становится намного, намного, намного хуже, чем когда шаблоны попадают в смесь. Если C (c) в шаблоне, вы можете не знать в фактическом определении шаблона, является ли C типом или функцией / объектом. Это потому, что шаблон может объявить C быть либо типом, либо переменной. Это означает, что вам нужна таблица символов, но у вас ее нет - и вы не можете иметь ее, пока шаблон фактически не объявлен. Хуже того, необязательно иметь только тип символа: вы можете столкнуться с ситуациями, когда требуется полная информация о типе символа, включая размер, выравнивание и другую информацию, специфичную для машины.

Все это имеет несколько практических последствий. Два наиболее значимых из них я бы сказал:

  • Компиляция намного быстрее. Я предполагаю, что Go быстрее компилируется, чем C, а C++ имеет классное медленное время компиляции для ситуаций, связанных с большим количеством шаблонов.
  • Вы можете написать парсеры, которые не зависят от наличия полного компилятора. Это очень полезно для анализа кода и рефакторинга.

Для интерпретации и компиляции абсолютно необходимы таблицы символов или аналогичные. Это верно почти для всех языков.

В C и C++ даже для синтаксического анализа языка требуется таблица символов.

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

Например:

int x = Foo (bar);

Foo может быть типом или функцией, и они представлены различными типами AST. По сути, парсер никогда не должен выполнять поиск символов, чтобы знать, как построить AST. Грамматика и AST просто проще, чем большинство языков. Довольно круто на самом деле.

Таблицы символов являются медленными и, как правило, не нужны. Так что иди решили уйти с этим. Другие функциональные языки тоже не нужны. Для быстрого поиска требуется хеш, но для поддержки вложенных областей необходимо поместить / вытолкнуть имена в стек. Простые symtabs реализованы как стек с линейным поиском, а лучше symtabs как хеш со стеком на символ. Но, тем не менее, поиск должен выполняться во время выполнения.

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

В C и C++ даже для синтаксического анализа языка требуется таблица символов, потому что вам нужно хранить типы и объявления глобалов и функций.

Символы с лексической областью хранятся не в symtab, а в виде индексированного списка имен в блочных фреймах, как в функциональных языках. Эти индексы вычисляются во время компиляции. Таким образом, доступ во время выполнения является немедленным. Выход из области действия делает эти переменные недоступными автоматически, поэтому вам не нужно вставлять / извлекать имена из пространств имен / symtabs.

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

Другие вопросы по тегам