Нет таблицы символов в Go?
Новый язык Google "Go" говорит на своем веб-сайте:
язык был разработан для легкого анализа и может быть проанализирован без таблицы символов
Я, конечно, не специалист по этим вопросам, но я думал, что таблица символов является базовой конструкцией, общей для всех компиляторов для языков, использующих переменные, и Go явно использует переменные. Что я не понимаю?
Ответы
Ответ 1
Анализ означает просто определение структуры программы: разделение модуля на инструкции/декларации, разбиение выражений на подвыражения и т.д. В итоге вы получаете древовидную структуру, известную как "дерево синтаксического анализа" или "абстрактный синтаксис" дерево "(AST).
По-видимому, для С++ требуется таблица символов.
На этой странице обсуждаются некоторые причины почему С++ требует таблицу символов для синтаксического анализа.
Конечно, разбор является лишь частью компиляции, и вам понадобится таблица символов для полной компиляции.
Однако сам анализ может быть полезен при написании инструментов анализа (например, какой модуль импортирует модули). Таким образом, упрощение процесса разбора означает, что проще писать инструменты анализа кода.
Ответ 2
Интерпретация и компиляция абсолютно требуют таблиц символов или подобных. Это верно для почти всех языков.
В C и С++ даже для разбора языка требуется таблица символов.
Ответ 3
@Правильно. Чтобы немного расшириться, в C единственная реальная сложная часть рассказывает типы, кроме переменных. В частности, когда вы видите это:
T t;
Вам нужно знать, что T
- это тип для юридического анализа. Это то, что вам нужно найти в таблице символов. Это относительно просто понять, пока типы добавляются в таблицу символов, когда синтаксический разбор продолжается. Вам не нужно делать много дополнительной работы в компиляторе: либо T
присутствует в таблице, либо нет.
В С++ все гораздо сложнее. Существует огромное количество двусмысленных или потенциально неоднозначных конструкций. Наиболее очевидным является этот:
B::C (c);
Помимо того, что неясно, если B
является class
, a typedef
или namespace
, также неясно, является ли C
типом и C
объектом этот тип, или если C
является функцией (или конструктором), принимающей C
в качестве аргумента (или даже если C является объектом с operator()
перегруженным). Вам нужна таблица символов для продолжения разбора, хотя по-прежнему можно продолжать достаточно быстро, так как тип символа находится в таблице символов.
Все становится намного, намного, намного хуже, чем когда шаблоны входят в микс. Если C (c)
находится в шаблоне, вы можете не знать в фактическом определении шаблона, если C является типом или функцией/объектом. Это потому, что шаблон может объявлять C
либо типом, либо переменной. Это означает, что вам нужна таблица символов, но у вас ее нет, и вы не можете ее использовать до тех пор, пока шаблон не будет объявлен. Хуже того, не обязательно достаточно иметь только тип символа: вы можете найти ситуации, которые требуют полной информации о типе, который представляет символ, включая размер, выравнивание и другую информацию, относящуюся к машине.
Все это имеет несколько практических эффектов. Два наиболее значительных, которые я бы сказал:
- Компиляция выполняется намного быстрее. Я предполагаю, что Go быстрее компилируется, чем C, а С++ значительно замедляет время компиляции для ситуаций, связанных с множеством шаблонов.
- Вы можете писать парсеры, которые не зависят от наличия полного компилятора. Это очень полезно для анализа кода и для рефакторинга.
Ответ 4
Чтобы анализировать большинство языков, вам нужно знать, когда имена являются переменными, типами или функциями, чтобы устранить неоднозначность определенных конструкций. Go не имеет таких неоднозначных конструкций.
Например:
int x = Foo (bar);
Foo может быть типом или функцией, и они представлены различными типами AST. В принципе, синтаксический анализатор никогда не должен выполнять поиск по символам, чтобы знать, как построить AST. Грамматика и АСТ просто проще большинства языков. Довольно круто.
Ответ 5
Таблицы символов медленны и обычно не нужны. Так что идите, идите с ним. Другим функциональным языкам также не нужно.
Быстрый поиск требует хеша, но для поддержки вложенных областей вам нужно нажать/поп-имена в стек. Простые symtabs реализованы как линейный поиск стека, лучше symtabs как хеш с стеком на символ. Но все же поиск должен выполняться во время выполнения.
Интерпретация и компиляция для языков с лексической областью не требуют абсолютно никаких таблиц символов или аналогичных.
Только символы с динамической областью нуждаются в таблицах символов,
и некоторые компиляторы со строго типизированными языками нуждаются в какой-то внутренней таблице символов для хранения аннотаций типа.
В C и С++ даже для разбора языка требуется таблица символов, потому что вам нужно хранить типы и объявления глобальных переменных и функций.
Символы, привязанные к лексике, не хранятся в symtab, а как индексированный список имен в блочных кадрах, как в функциональных языках. Эти индексы вычисляются во время компиляции. Таким образом, доступ во время работы является немедленным. Выход из области действия делает эти вары недоступными автоматически, поэтому вам не нужно указывать имена/имена из пространств имен /symtabs.
Не так функциональные языки без первоклассных функций часто должны хранить свои имена функций в таблицах символов. В качестве языкового дизайнера вместо этого вы пытаетесь привязать функции к лексике, чтобы избавиться от динамического поиска имен в symtabs.