Перейти к основному содержимому
Chapter content StyleChapter Difficulty17 min

«JS is not going away, so it ought to evolve. As with sharks ... a programming language is either moving forward, or it’s dead».

Brendan Eich,

blog, 20051

Глава 3.1: Грамматика языка спецификации

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

Личная рекомендация

Спецификация ECMAScript Language Specification написана на английском языке. В ней присутствуют различные термины, без которых не получится понять базовые принципы её устройства. В целях соблюдения семантического смысла и сохранения предельной точности выражений перевод этих терминов не рекомендуется. В данном случае потребуется запомнить слова такими, какими они представлены в спецификации. Например, если где-то указано слово "production", рекомендуется запомнить его таким, какое оно есть — без перевода. Это касается всех терминов спецификации. Так мы не только избежим путаниц, но и образуем свой "словарик" терминов, который успешно сможем использовать в любой подходящей ситуации, например, международная конференция.

warning

Разбираемые далее термины никак не относятся к языку ECMAScript! Как было описано в предыдущей главе, мы дифференциировали 2 противоположных направления спецификации ECMAScript, и сейчас рассматриваем язык спецификации.

Теория языка

Как вообще можно создать язык под свои нужны? Можно придумать свой алфавит, но это будет слишком долго, сложно и нерационально, потому что всем придётся учить ваш язык перед прочтением составленного на нём документа. Хорошо бы на уже имеющемся языке, желательно международном, составить нечто похожее на свой отдельный язык, где будут описаны правила, как он работает. Тут можно провести параллель с виртуальной машиной, которая думает, что она отдельная система, но в действительности она работает внутри уже имеющейся системы. Вот такую "подсистему" и решили описать лингвисты в виде формального языка (formal language):

In logic, mathematics, computer science, and linguistics, a formal language consists of words whose letters are taken from an alphabet and are well-formed according to a specific set of rules called a formal grammar.

~ wiki

Как мы видим, formal language обладает набором каких-то правил, что и делает его отдельным языком. Такие правила назвали грамматикой (formal grammar). Если изучить её теорию подробнее, то выйдем на следующие, поначалу непонятные термины:

... и много чего ещё интересного.

Если говорить обобщённо, используя эти термины для какого-то своего языка, то у нас есть какая-то своя грамматика (grammar), наподобие context-free grammar. Эта грамматика описана правилами, называемыми production rules. Каждое правило состоит из своего production. Сам он состоит из набора символов (nonterminal symbols) и, где это употребимо, токенов (tokens). А этот набор, как групповое обобщение частных, неделимых примитивов, базовых единиц, состоит из terminal symbols. Примерно в таком формате можно создать и описать свою языковую модель.

Так уж вышло, что спецификация написана именно в таком стиле. Решили так инженеры или люди, нанятые писать спецификацию, я не знаю. Можно ли было сделать представление стандарта каким-либо другим образом, более лёгким и понятным? Очевидно, что да, можно. Но сейчас спецификация фактически является одной из форм реализации formal language, подчиняющейся базовой грамматике, описанной на страницах стандарта. Это ровно то, что нам и нужно понять, чтобы идти дальше.

Базовая грамматика

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

Все грамматики соответствуют правилам одной общей вида context-free grammar. На её примере предлагаю рассмотреть основные грамматические обозначения, которые в общем случае будут справедливы для всех грамматик. Таких обозначений достаточно много, но для общего понимания не требуется запоминать их все. Как и в прошлой главе, определим, согласно спецификации, ряд общих и частных, из чего состоит условное "предложение", но только с точки зрения терминов стандарта, и сразу рассмотрим их на реальном примере использования грамматики:

Пример №1


Пример типичного production для цикла while
Пример типичного production для цикла while

На картинке мы видим типичное "предложение", но из мира спецификации. Всё это называется production. Из таких и ещё более сложных конструкций состоит почти вся спецификация ECMAScript. На этом лёгком примере мы можем встретить знакомый нам цикл while и что-то, похожее на его синтаксис. Давайте сразу по порядку обозначим то, из чего состоит наш production.

  • WhileStatement — это goal symbol, то есть нечто, что стоит по левую сторону от символа ":", так называемый LeftHandSideSymbol. Одновременно с этим это ещё и nonterminal symbol (так как имеет стиль шрифта italic).
  • Символ ":" — разделяет production на две части, не имеет определения2. Выполняет функцию идентификатора3 для одной из грамматик.
  • while — это token, который указывает, для какой конструкции языка ECMAScript написан данный production. Можно сказать, что с этой строчки вводится описание возможного синтаксиса (часть грамматики) языка ECMAScript, но это далеко не всегда так. Зачастую вы не увидите ничего схожего с синтаксисом JavaScript.
  • Символ "(" — это очередной token, который лекго распознать по стилю шрифта bold. Напоминает открывающуюся скобку синтаксиса объявления цикла while языка JavaScript.
  • Expression — это очередной nonterminal symbol, напоминающий условие работы цикла while.
  • Символ ")" — это такой же token, как и предыдущая скобка. Напоминает закрывающуюся скобку синтаксиса while.
  • Statement — это очередной nonterminal symbol, напоминающий блок кода, выполняемый циклом while.

Следом за этим примером предлагаю разобрать ещё один.

Пример №2


Сокращённый вариант написания VariableDeclaration production
Сокращённый вариант написания VariableDeclaration production

Вот теперь на картинке похожего нет совсем ничего. Давайте коротко опишем данный production:

  • VariableDeclaration — это goal symbol, nonterminal symbol.
  • Символ ":" — это сепаратор, разделитель и идентификатор определённого вида грамматики.
  • BindingIdentifier — это nonterminal symbol.
  • Initializer — это nonterminal symbol, optional symbol
  • opt — это suffix, указывающий на опциональность, что делает рядом стоящий символ необязательным для production-а. Используется только лишь в качестве сокращения. То есть в развёрнутом виде итоговый production будет выглядеть вот так:
Полный вариант написания VariableDeclaration production
Полный вариант написания VariableDeclaration production

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

Terminal symbols

В отличие от nonterminal symbol, который при выборе его в спецификации будет раскрыт на свои составляющие и, возможно, представлять отдельный production, напротив, выбранный terminal symbol — это такая же неделимая, нераскрывающаяся часть, как token, зависящая от того, в какой грамматике она используется. Например, к terminal symbols могут относиться Unicode code points.

Parameters

Параметры или grammatical parameters — это всего лишь разновидности суффиксов (suffix) и префиксов (prefix) для наших nontermanal-ов. Они являются частью грамматики языка спецификации и нужны для всевозможных сокращений потенциально больших по записи production-ов, чтобы из огромных "предложений" сделать такие же по смыслу небольшие "предложения". Мы ограничимся лишь картинками с их разновидностью, и как они раскрываются, но без углубления в детали.

Image with grammarImage with grammarImage with grammarImage with grammar

И другие

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

An interesting fact...

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

Сложно?

Некоторым людям может показаться, что базовая грамматика языка спецификации ECMAScript неоправданно сложна для понимания. Мы ещё не дошли до самых частных реализаций, а терминов уже много. У такого подхода к написанию спецификации есть, как положительные, так и отрицательные стороны. Всё негативное Вы, скорее всего, для себя уже заметили, поэтому я приведу несколько слов "за" этот подход.

  • Предельная точность описания: чем больше и обширнее грамматическая языковая модель4, тем точнее будет описание.
  • Научный подход: редакторы спецификации избрали тяжёлый, но научный, с точки зрения лингвистики, путь создания языка.
  • "Самый непонятый язык": если человек смог постичь спецификацию, он действительно знает, куда идёт по жизни.

К выводу

Подведём итоги вышесказанному и сделаем выводы:

  • Термины спецификации "не любят" локализации на отличный от оригинала язык.
  • Для понимания грамматических конструкций не требуется досконально запоминать все их обозначения.
  • Способов создать свой язык достаточно много. Одним из них является способ представления некого formal language со своей context-free grammar, состоящей из productions, которые комбинируются с помощью nontermainals, termainals и tokens. Язык становится самостоятельным тогда и только тогда, когда приобретает свою неповторимую грамматику.
  • Спецификация ECMAScript наследует весь набор условного formal langiage с добавлением своих кастомных грамматических обозначений и расширяется благодаря комплексному подходу к инкапсулированию грамматик.
  • Вопрос детального описания самих грамматик представлен в следующей главе.

Footnotes

  1. Так в 2005 году в своём блоге Брендан Эйх рассуждал на тему того, что мы хотим подразумевать, когда говорим о JavaScript-е: совокупность "акронимов" или самодостаточный язык?

  2. Согласно спецификации, этот разделитель не имеет своего определения (термина), а очерёдность двоиточий определяется просто как "Productions of the syntactic grammar are distinguished by having just one colon “:” as punctuation."

  3. Имеется в виду грамматический идентификатор, помогающий различать разные грамматики.

  4. Авторский термин. Под грамматической языковой моделью я имею в виду модель (образ) повествования, определения и раскрытия грамматических правил языка.