Исходный текст программы на ECMAScript предварительно преобразуется в последовательность входных элементов четырёх типов: токены, переводы строк, комментарии и пробелы. Исходный текст анализируется слева направо, последовательно выбирая наиболее длинную последовательность символов в качестве следующего входного элемента.
В лексической грамматике определены два начальных символа. Символ ВходнойЭлементДеления используется в тех контекстах синтаксической грамматики, где разрешено использование оператора деления (/) или деления-с-присваиванием (/=). Символ ВходнойЭлементРегВыр используется в прочих контекстах синтаксической грамматики.
Заметим, что существуют такие контексты синтаксической грамматики, где разрешается использование как операции деления, так и ЛитералаРегулярногоВыражения; однако поскольку лексическая грамматика использует в таких случах начальный символ ВходнойЭлементДеления, открывающий слэш (/) в таком контексте не распознаётся как начало регулярного выражения. Чтобы обойти это ограничение, литерал регулярного выражения можно заключить в скобки.
Синтаксис
Символы управления форматом Юникода (например, символы категории "Cf" в базе данных символов Юникода, такие как LEFT-TO-RIGHT MARK и RIGHT-TO-LEFT MARK) являются управляющими кодами, используемыми для управления форматом текстового фрагмента в отсутствии более высокоуровневых протоколов (таких как язык разметки), обычно применяемых для этой цели. Для облегчения редактирования и отображения текста полезно разрешать включение таких символов в исходный текст.
Символы управления форматом могут встречаться где угодно в тексте программы на ECMAScript. Эти символы удаляются из исходного текста перед применением лексической грамматики. Поскольку такие символы удаляются перед обработкой строковых литералов и литералов регулярных выражений, для включения символов форматирования следует использовать юникодную escape-последовательность (см. 7.6) .
Пробелы используются для улучшения читаемости исходного текста и разделения токенов (неделимых лексических единиц). В остальном они не оказывают на исходный текст никакого влияния. Пробелы могут встречаться между любыми двумя токенами, а также внутри строк (где они считаются значащими символами и составляют часть значения строкового литерала), но не могут появляться внутри какого-либо другого токена.
Следующие символы считаются эквивалентными пробелу:
| Код Юникода | Наименование | Формальное наименование |
|---|---|---|
| \u0009 | Табуляция | <TAB> |
| \u000B | Вертикальная табуляция | <VT> |
| \u000C | Перевод страницы | <FF> |
| \u0020 | Пробел | <SP> |
| \u00A0 | Неразрывный пробел | <NBSP> |
| Прочие в категории "Zs" | Прочие "разделители пробела" в Юникоде | <USP> |
Синтаксис
Как и пробелы, символы конца строки используются для улучшения читаемости исходного текста и разделения токенов (неделимых лексических единиц). Однако в отличие от пробелов, разделители строк имеют некоторое влияние на поведение синтаксической грамматики. В основном, разделители строк могут находиться между любыми двумя токенами, но есть ряд мест, где их появление запрещено синтаксической грамматикой. Разделитель строк не может находиться внутри какого-либо токена, даже строкового литерала. Разделители строк также влияют на процесс автоматической вставки точек с запятой (7.9).
Следующие символы считаются эквивалентными концу строки:
| Код Юникода | Наименование | Формальное наименование |
|---|---|---|
| \u000A | Перевод строки | <LF> |
| \u000D | Возврат каретки | <CR> |
| \u2028 | Разделитель строк | <LS> |
| \u2029 | Разделитель абзацев | <PS> |
Синтаксис
Описание
Комментарии бывают двух типов: однострочные и многострочные. Многострочные комментарии не могут быть вложенными.
Поскольку однострочный комментарий может содержать любой символ, кроме КонцаСтроки, и поскольку, согласно общему правилу, в качестве токена всегда берётся последовательность символов наибольшей возможной длины, однострочный комментарий всегда включает в себя все символы от знака // до конца строки. Однако, КонецСтроки не считается частью однострочного комментария, учитывается лексической грамматикой отдельно и становится частью потока входных символов для синтаксической грамматики. Это замечание является очень важным, поскольку подразумевает, что наличие или отсутствие однострочных комментариев не влияет на процесс автоматической вставки точек с запятой (7.9).
Комментарии ведут себя аналогично пробелам и обычно игнорируются. Исключение составляют те случаи, когда МногострочныйКомментарий содержит символ перевода строки. При этом с точки зрения синтаксической грамматики весь комментарий принимается за КонецСтроки.
Синтаксис
Синтаксис
Описание
Зарезервированные слова не могут быть использованы в качестве идентификаторов.
Синтаксис
Следующие токены являются ключевыми словами ECMAScript и не могут быть использованы в программах на ECMAScript.
Синтаксис
Следующие слова используются как ключевые слова в предложенных расширениях для языка и, таким образом, зарезервированы, чтобы обеспечить возможность включения этих расширений в язык в будущем.
Синтаксис
Описание
Идентификаторы обрабатываются согласно грамматике, приведённой в разделе 5.16 стандарта Юникода версии 3.0, с небольшими изменениями. Эта грамматика основывается на нормативных и информативных категориях символов, определённых стандартом Юникода. Символы, принадлежащие к определённым категориям в версии 2.1 стандарта Юникода должны обрабатываться как принадлежащие к этим категориям всеми корректными реализациями ECMAScript. Однако корректные реализации ECMAScript также могут позволять использование в идентификаторах и других символов, основываясь на их категориальной принадлежности в более поздних версиях Юникода.
В данном стандарте имеется единственное отклонение от стандарта Юникода: знак доллара ($) и подчёркивание (_) разрешены к использованию в любом месте идентификатора. Знак доллара предназначается только для использования в автоматически генерируемом коде.
Юникодные escape-последовательности также разрешены к использованию в идентификаторах и трактуются как одиночные символы в составе идентификатора согласно СиЗ ЮникоднойEscapeПоследовательности (см. 7.8.4). Обратный слэш (\), предшествующий ЮникоднойEscapeПоследовательности, не трактуется как символ идентификатора. При помощи ЮникоднойEscapeПоследовательности нельзя вставлять в идентификаторы запрещённые символы. Другими словами, если заменить \ ЮникоднуюEscapeПоследовательность на соответствующее ей СиЗ, результат по-прежнему должен являться корректным идентификатором, состоящим из тех же символов, что и первоначальный Идентификатор.
Два идентификатора, канонически эквивалентные согласно стандарту Юникода, не являются одинаковыми, если они не представлены строго одинаковыми последовательностями кодовых точек (иными словами, корректные реализации ECMAScript должны проводить только побитовое сравнение идентификаторов). Подразумевается, что входной текст был преобразован к нормализованной форме C ещё до того, как был отправлен на вход компилятора.
Синтаксис
Синтаксис
Синтаксис
Синтаксис
Семантика
Значеним null-литерала null является единственное значение типа Null, а именно null.
Синтаксис
Семантика
Значением булевского литерала true является значение типа Boolean, а именно true.
Значением булевского литерала false является значение типа Boolean, а именно false.
Синтаксис
Символ исходного текста, следующий непосредственно за ЧисловымЛитералом, не должен являться НачаломИдентификатора или ДесятичнойЦифрой.
ЗАМЕЧАНИЕ
К примеру, запись
3in
является недопустимой, а не обозначением двух входных элементов: 3 и in.
Семантика
Числовой литерал обозначает значение типа Число. Его значение определяется в два этапа: сначала из литерала получается его математическое значение (МЗ), затем это математическое значение округляется по принципам, описанным ниже.
Как только точное МЗ численного литерала было получено, оно затем округляется к значению типа Number. Если МЗ равно 0, то округлённое значение равняется +0. Иначе, округлённое значение должно равняться численному значению МЗ (согласно определению в разделе 8.5), за исключением тех случаев, когда литерал является ДесятичнымЛитералом и содержит более 20 значащих цифр. Тогда за численное значение принимается либо численное значение МЗ литерала, получаемое заменой каждой значащей цифры после двадцатой на цифру 0, либо численное значение МЗ литерала, получаемое заменой каждой значащей цифры после двадцатой на цифру 0 и затем увеличение литерала на единицу в позиции двадцатой значащей цифры. Цифра является значащей, если она не принадлежит ЭкспоненциальнойЧасти и
Строковой литерал представляет собой ноль или больше символов, заключённых в одиночные или двойные кавычки. Каждый символ может быть представлен escape-последовательностью.
Синтаксис
Определение нетерминала ШестнадцатеричнаяЦифра приведено в разделе 7.8.3. ИсходныйСимвол описан в разделах 2 и 6.
Строковой литерал обозначает значение типа String. Строковое значение (СтЗ) литерала описывается через символьные значения (СиЗ) различных частей строкового литерала. В ходе этого процесса некоторые символы строкового литерала считаются имеющими математическое значение (МЗ) согласно описанию ниже или в разделе 7.8.3.
| Escape-прследовательность | Код Юникода | Наименование | Символ |
|---|---|---|---|
| \b | \u0008 | удаление назад | <BS> |
| \t | \u0009 | горизонтальная табуляция | <HT> |
| \n | \u000A | перевод строки (новая строка) | <LF> |
| \v | \u000B | вертикальная табуляция | <VT> |
| \f | \u000C | перевод страницы | <FF> |
| \r | \u000D | возврат каретки | <CR> |
| \" | \u0022 | двойная кавычка | " |
| \' | \u0027 | одинарная кавычка | ' |
| \\ | \u005C | обратный слэш | \ |
ЗАМЕЧАНИЕ
Символ 'КонецСтроки' не может появиться в строковом литерале, даже если ему предшествует обратный слэш \. Правильным путём включения символа перевода строки в строковой литерал является использование escape-последовательности, такой как \n или \u000A.
Литерал регулярного выражения - это элемент, который в процессе обработки преобразовывается к объекту RegExp (раздел 15.10). Объект создаётся до того, как начинается выполнение содержащей его программы или функции. При выполнении программы литерал возвращает ссылку на этот объект; он не создаёт нового объекта. Два отдельных регулярных выражения в программе преобразутся в два объекта регулярных выражений, которые никогда не сравниваются как === (строго равные) друг другу, даже если содержимое литералов является идентичным. Объект типа RegExp также может быть создан во время выполнения при помощи выражения new RegExp (раздел 15.10.4) или путём вызова конструктора RegExp как функции (раздел 15.10.3).
Приведённые ниже правила описывают синтаксис литерала регулярного выражения и используются обработчиком входных элементов для нахождения конца литерала регулярного выражения. Строки символов, составляющие ТелоРегулярногоВыражения и ФлагиРегулярногоВыражения передаются в необработанном виде конструктору регулярных выражений, который обрабатывает их своей, более строгой грамматикой. Реализации могут расширять грамматику конструктора регулярных выражений, но они не должны расширять правила, определяющие ТелоРегулярногоВыражения и ФлагиРегулярногоВыражения, или какие-либо из правил, использованных в этих правилах.
Синтаксис
ЗАМЕЧАНИЕ
Литералы регулярных выражений не могут быть пустыми; вместо того чтобы представлять пустой литерал регулярного выражения, последовательность // начинает однострочный комментарий. Чтобы указать пустое регулярное выражение, следует использовать /(?:)/.
Семантика
Литерал регулярного выражения обозначает значение типа Object. Это значение определяется в два этапа: сначала символы, распознаваемые правилами грамматики в качестве нетерминалов ТелоРегулярногоВыражения и ФлагиРегулярногоВыражения собираются в необработанном виде в две строки, называетмые, соответственно, Шаблон и Флаги. Затем вызывается конструктор new RegExp с двумя параметрами Шаблон и Флаги, и результат становится значением ЛитералаРегулярногоВыражения. Если вызов new RegExp генерирует ошибку, реализация может по собственному усмотрению либо выдать сообщение об ошибке сразу при разборе исходного текста программы, либо отложить ошибку до того момента, когда к значению регулярного выражения обращается программа в ходе своего исполнения.
Некоторые инструкции ECMAScript (пустая инструкция, объявление переменной, инструкция-выражение, инструкция do-while, инструкция continue, инструкция break, инструкция return, и инструкция throw) должны оканчиваться точками с запятыми. Эти точки с запятыми могут явно указываться в тексте. Однако в некоторых случаях, исходя из соображений удобства, такие точки с запятыми в исходном тексте могут быть опущены. Эти ситуации описываются высказыванием, гласящим, что точки с запятой автоматически вставляются в поток токенов исходного текста в этих ситуациях.
1. Токен-нарушитель отделён от предыдущего токена как минимум одним КонцомСтроки.
2. Токеном-нарушителем является закрывающая фигурная скобка }.
Однако существует одно общее ограничение на предшествующие правила: точка с запятой никогда не вставляется автоматически, если бы эту точку пришлось потом обработать бы как пустую инструкцию или если бы эта точка с запятой стала одной из точек с запятой в заголовке инструкции for (раздел 12.6.3).
ЗАМЕЧАНИЕ
Ниже перечислены все ограниченные правила в грамматике:
На практике эффект от этих ограниченных правил следующий:
Итоговые практические советы программистам на ECMAScript таковы:
Исходный текст
{ 1 2 } 3
не является корректным предложением в грамматике ECMAScript, даже с учётом правил автоматической вставки точек с запятой. Напротив, исходный текст
{ 1
2 } 3
тоже не является корректным предложением ECMAScript, но преобразуется правилами автоматической вставки точек с запятой в следующий:
{ 1
;2 ;} 3;
который является корректным предложением ECMAScript.
Исходный текст
for (a; b
)
не является корректным предложением ECMAScript и не изменяется правилами автоматической вставки точек с запятой, так как точка с запятой подставилась бы в заголовок инструкции for. Автоматическая вставка точек с запятой никогда не вставляет одну или более точек с запятой в заголовок инструкции for.
Исходный текст
return
a + b
преобразуется правилами автоматической вставки точек с запятой в следующий:
return;
a + b;
ЗАМЕЧАНИЕ
Выражение a + b не используется в качестве значения, возвращаемого инструкцией return, так как "КонецСтроки" отделяет его от токена return.
Исходный текст
a = b
++c
преобразуется правилами автоматической вставки точек с запятой в следующий:
a = b;
++c;
ЗАМЕЧАНИЕ
Токен ++ не принимается за постфиксный оператор, применённый к переменной b, поскольку "КонецСтроки" разделяет b и ++.
Исходный текст
if (a > b)
else c = d
не является корректным предложением ECMAScript и не изменяется правилами автоматической вставки точек с запятой перед токеном else, несмотря на то, что ни одно из правил грамматики не применимо в данной точке, потому что автоматически вставленная точка с запятой была бы затем распознана как пустое выражение.
Исходный текст
a = b + c
(d + e).print()
не изменяется правилами автоматической вставки точек с запятой, потому что выражение в скобках, которое начинает вторую строку, может быть распознано как список аргументов для вызова функции:
a = b +c(d + e).print()
В обстоятельствах, когда инструкция присваивания должна начинаться с левой скобки, хорошим решением для программиста будет поставить явную точку с запятой в конце предыдущей инструкции, вместо того чтобы полагаться на автоматическую вставку точек с запятой.