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

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

14 голосов
/ 13 ноября 2009

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

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

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

Ответы [ 5 ]

22 голосов
/ 13 ноября 2009

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

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

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

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

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

10 голосов
/ 13 ноября 2009

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

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

9 голосов
/ 13 ноября 2009

@ Справедливость верна. Чтобы немного углубиться в это, в 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 ++ имеет классное медленное время компиляции для ситуаций, связанных с большим количеством шаблонов.
  • Вы можете писать парсеры, которые не зависят от наличия полного компилятора. Это очень полезно для анализа кода и рефакторинга.
2 голосов
/ 29 марта 2012

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

Например:

int x = Foo (бар);

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

0 голосов
/ 18 декабря 2013

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

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

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

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

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

...