Связывание, типизация, вывод типов

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

Обработка кода компилятором

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

Лексический анализ (токенизация - tokenizing)

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

Лексема - это последовательность допустимых символов.

К примеру, рассмотрим следующий код:

ts
var n = 100 + 2 * 3;

Этот код будет разбит на девять лексем: var, n, =, 100, +, 2, *, 3, ;.

Синтаксический анализ (разбор - parsing)

На этапе синтаксического анализа обычно строится дерево разбора путем определения последовательности лексем. Его ещё называют синтаксическим деревом.

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

ts
var n = 100 + 2 * 3;

Семантический анализ

На этапе семантического анализа, который считается самым важным этапом, устанавливается семантика (смысл) построенного на предыдущем шаге дерева разбора.

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

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

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

Связывание (Binding)

Связывание (binding) - это операция ассоциирования конструкций нуждающихся в аннотации типа с типами данных к которым они принадлежат.

Типизация

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

Вывод Типов (type inference)

Вывод типов — это возможность компилятора (интерпретатора) определять тип данных, анализируя выражение.

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

ts
// так разработчик видит
var n = 5 + 5; // так видит компилятор var n: number = 5 + 5;

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