В среде не только обычных программистов, но даже и некоторых разработчиков, близких к компиляторной тематике, принято пренебрежительное отношение к синтаксису языка программирования как к второстепенной детали, которой противопоставляется семантика, которая только и имеет серьёзное значение. Считается, что в крайнем случае, всегда можно снабдить один язык программирования несколькими синтаксисами и это лишь вопрос вкуса. Но есть одно очевидное соображение, которое, очевидно, оказалось не таким уж очевидным, но которое делает такое отношение абсурдным.
Дело в том, что до тех пор, пока язык остаётся алгоритмически полным, то есть полным по Тьюрингу, в нём можно описать всю ту же семантику, что и в любом другом алгоритмически полном языке. Ключевая разница между языками заключается не в самой возможности выразить семантику, а то, как именно её можно выражать. И главное отличие языков пролегает как раз через различия в синтаксисе. Синтаксис языка задаёт не столько текстовое представление терминалов, сколько основные конструкции языка, формирующие его основные понятия, без которых и мыслить о языке не получится. Выбор синтаксиса совсем не сводится к выбору между фигурными скобками — {}
, ключевыми словами begin end
или значимыми отступами. Этим обычно занимается лексика языка, которую в зависимости от желаемого результата могут как отделять в отдельную дисциплину, так и рассматривать неотделимой частью синтаксиса. В любом случае лексика для синтаксиса второстепенна и не определяет его суть.
Рассмотрим для примера корневые синтаксические уравнения двух языков: Оберона и Си
module = "MODULE" ident ";" [ImportList] [DeclarationSequence] ["BEGIN" StatementSequence] "END" ident "." .
translation_unit = external_declaration {external_declaration} .
Несмотря на минимум информации эти уравнения сразу знакомят нам с совершенно разными понятиями этих языков.
- В случае Оберона программной единицей является именованная сущность, содержащая опциональные списки импорта, объявлений и операторов. Порядок объявления списков строго задан.
- В случае Си единицей трансляции является непустой безымянный список внешних объявлений, равноправных c точки зрения расположения в коде.
Хотя в примере остаётся непрояснённой суть упоминаемых в них нетерминалов и ничего не сказано о смысле уравнений, уже может быть понятно, что конструкции, задаваемые этимм синтаксами, несут в себе разный смысл и не сопоставляются друг с другом напрямую.
Если посмотреть на синтаксис типичного динамически типизированного языка, то скорее всего там не найдётся уравнений для задания и использования типов, но они почти наверняка обнаружатся в синтаксисе статически типизированного языка. Структурность потока управления в операторах Оберона-07 выражается в отсутствии синтаксиса для неструктурных операторов, наподобие break, continue, goto, throw, return[0]. Так, ключевые особенности языка находят своё отображение в его синтаксисе и напрямую от него зависят.
Когда мы говорим, что важна только семантика, понимаем ли мы до конца, что такое семантика? Кто-то скажет, что всё просто — семантика задаёт смысл синтаксических конструкций. Такое прояснение, с одной стороны, при ближайшем рассмотрении может показаться бесполезным, так как задаёт смысл термина используя слово, являющееся его синонимом. С другой стороны, оно хорошо иллюстрирует работу семантики, которая состоит в сопоставлении друг другу разных синтаксических конструкций. Это означает, что для задания семантики нового синтаксиса нужен синтаксис другого языка, семантику которого посчитали базовой, но которая тоже в конечном итоге выражается через сопоставление.
Возможно, с точки зрения мистики смысл чего-либо может иметь некоторое нематериальное духовное происхождение, но в скучном материалистическом мире смысл всегда выражается с помощью материи по некотором правилам. А эти правила неизбежно найдут своё отображение в абстракции под названием «синтаксис». Для задания семантики синтаксиса не только нужен синтаксис языка — донора семантики, но и сами правила сопоставления фрагментов синтаксисов описываются на некотором языке, который, конечно, тоже имеет некий синтаксис. Синтаксис на синтаксисе синтаксисом погоняет.
Итого:
- Для определения языка семантика не только не является более важным понятием, чем синтаксис, но и попросту не существует без синтаксиса, точно так же, как не существует смысла слов без самих слов.
- Одной из причин неправильной оценки синтаксиса является спутывание его с лексикой — его лишь второстепенной частью.
- Один язык не может иметь несколько существенно отличающихся синтаксисов. Относительно безболезненно можно менять лишь лиственную часть синтаксического дерева — той части, что ближе к терминалам. Это можно сравнить с заменой кодировки для передачи текста. И как смена кодировки не считается существенным изменением текста, так и смена терминальной части синтаксиса не должна считаться существенным изменением синтаксиса. Часть же синтаксиса, находящаяся ближе к корню, задаёт представление важных конструкций языка и не может быть существенно изменена без существенного изменения языка.
Понимание этого имеет важное практическое значение.
[0] В Oberon-07 есть лексические элемент RETURN, всегда заверщающий процедуру, возвращающую значение, но это не оператор, который может встречаться наравне с другими операторами, как это было в предыдущих определениях языка.
Комментариев нет:
Отправить комментарий