Лексическая структура
Документы
Документ M — это упорядоченная последовательность символов Юникода. M позволяет различным классам символов Юникода в разных частях документа M. Сведения о классах символов Юникода см. в разделе "Стандартный" в Юникоде версии 3.0, в разделе 4.5.
Документ состоит из одного выражения или групп определений, организованных в разделы. Разделы подробно описаны в главе 10. Концептуально говоря, для чтения выражения из документа используются следующие шаги:
Документ декодируется в соответствии со схемой кодировки символов в последовательности символов Юникода.
Лексический анализ выполняется, тем самым превратив поток символов Юникода в поток токенов. Остальные подразделы этого раздела охватывают лексический анализ.
Выполняется синтаксический анализ, тем самым преобразуя поток маркеров в форму, которую можно оценить. Этот процесс рассматривается в последующих разделах.
Грамматические соглашения
Лексические и синтаксические грамматики представлены с помощью грамматических производств. Каждая грамматическая рабочая среда определяет неконечный символ и возможные расширения этого нетерминального символа в последовательности символов, отличных от терминала или терминалов. В грамматических правилах неконечные символы обозначаются курсивом, а конечные символы — шрифтом с фиксированной шириной.
Первая строка грамматического правила — это имя определяемого неконечного символа, за которым следует двоеточие. Каждая последовательная отступная строка содержит возможное расширение нетерминального, заданного как последовательность символов, отличных от терминала или терминалов. Например, следующее правило:
if-expression:
if
Условие then
if true-expressionelse
false-expression
определяет, что выражение-if состоит из токена if
, за которым следуют условие-if, токен then
, выражение-true, токен else
и выражение-false.
При наличии более одного возможного расширения неконечного символа альтернативные варианты перечисляются в разных строках. Например, следующее правило:
список переменных:
переменная
Переменная списка ,
переменных
определяет список переменных, состоящий из переменной или состоящий из списка переменных, за которым следует переменная. Другими словами, определение рекурсивно и указывает, что список переменных состоит из одной или нескольких переменных, разделенных запятыми.
Подстрочный суффикс "opt" используется для указания необязательного символа. Рабочая среда:
спецификация поля:
optional
opt field-name =
field-type
является сокращенным вариантом следующего:
спецификация-поля:
тип поля "имя поля" =
optional
имя =
поля тип поля
и определяет спецификацию поля, чтобы при необходимости начинаться с символа optional
терминала, за которым следует имя поля, символ =
терминала и тип поля.
Альтернативные варианты обычно перечислены в отдельных строках, хотя в случаях, когда существует множество альтернативных вариантов, фраза "одна из" может предшествовать списку расширений, заданных в одной строке. Это просто сокращенно для перечисления каждого из альтернативных вариантов в отдельной строке. Например, следующее правило:
десятичный-знак: один из
0 1 2 3 4 5 6 7 8 9
является сокращенным вариантом следующего:
десятичная цифра:
0
1
2
3
4
5
6
7
8
9
Лексический анализ
Лексическая лексическая рабочая среда определяет лексическую грамматику для документа M. Каждый допустимый документ M соответствует этой грамматике.
лексическая-единица:
лексические-элементынеобязательно
лексические-элементы:
лексический-элемент
лексический-элемент
лексические-элементы
лексический-элемент:
пробел
комментарий токена
На лексическом уровне документ M состоит из потока пробелов, комментариев и элементов токена. Каждое из этих правил описываются в следующих разделах. В синтаксической грамматике важны только элементы маркера .
Пробел
Пробелы используются для разделения комментариев и маркеров в документе M. Пробелы включают пробел (который является частью класса Zs Юникода), а также горизонтальные и вертикальные вкладки, веб-канал формы и последовательности символов новой строки. Последовательности символов новой строки включают возврат каретки, канал строки, возврат каретки, а затем канал строки, следующую строку и символы разделителя абзаца.
пробелы:
Любой символ с классом Юникод Zs
Символ горизонтальной вкладки (U+0009
)
Символ вертикальной вкладки (U+000B
)
Символ веб-канала формы (U+000C
)
Возвращаемый символ каретки (U+000D
) и символ канала строки (U+000A
)
новый символ строки
new-line-character:
Возвращаемый символ каретки (U+000D
)
Символ канала строки (U+000A
)
Следующий символ строки (U+0085
)
Символ разделителя строк (U+2028
)
Символ разделителя абзаца (U+2029
)
Для совместимости с средствами редактирования исходного кода, добавляющими маркеры конца файла, и чтобы документ отображался как последовательность правильно завершенных строк, для документа M применяются следующие преобразования:
Если последний символ документа является символом Control-Z (
U+001A
), этот символ удаляется.Символ возврата каретки () добавляется в конец документа, если этот документ не является пустым, а если последний символ документа не является возвратом каретки
U+000D
(), каналом строки (U+000D
), разделителем строк (U+000A
U+2028
) или разделителем абзаца (U+2029
).
Комментарии
Поддерживаются две формы комментариев: одно строковый комментарий и комментарии с разделителями. Одиночные строковый комментарий начинаются с символов //
и расширяются до конца исходной строки. Разделенные комментарии начинаются с символов /*
и заканчиваются символами */
.
Примечания с разделителями могут охватывать несколько строк.
комментарий:
однострочный-комментарий
комментарий-с-разделителями
однострочный-комментарий:
//
Выбрать однострочные символы-комментарии
символы-однострочного-комментария:
символ-однострочного-комментария символы-однострочного-комментариянеобязательно
символ-однострочного-комментария:
Любой символ Юникода, кроме символа-новой-строки
комментарий-с-разделителями:
/*
Разделители-комментарий-текстотбирают звездочки /
текст-комментария-с-разделителями:
раздел-комментария-с-разделителями текст-комментария-с-разделителяминеобязательно
раздел-комментария-с-разделителями:
/
звездочкинеобязательно не-косая-черта-или-звездочка
звездочки:
*
звездочки
не-косая-черта-или-звездочка:
Любой символ Юникода, кроме *
или /
Примечания не вложены. Последовательности символов /*
и */
не имеют специального значения в однострочном комментарии, а последовательности символов //
и /*
не имеют специального значения в комментариях с разделителями.
Комментарии не обрабатываются в текстовых литералах. Пример
/* Hello, world
*/
"Hello, world"
содержит разделенный комментарий.
Пример
// Hello, world
//
"Hello, world" // This is an example of a text literal
отображает несколько одноуровневых строковый комментарий.
Токены
Маркер — это идентификатор, ключевое слово, литерал, оператор или пунктуатор. Пробелы и комментарии используются для разделения токенов, но не считаются маркерами.
токен:
идентификатор
keyword
литерал
оператор-или-знак-препинания
Escape-последовательности символов
Текстовые значения M могут содержать произвольные символы Юникода. Однако текстовые литералы ограничены графическими символами и требуют использования escape-последовательностей для не графических символов. Например, для включения символа возврата каретки, линии или табуляции в текстовый литерал#(cr)
#(lf)
#(tab)
, последовательности и escape-последовательности можно использовать соответственно. Чтобы внедрить начальные символы #(
escapesequence в текстовый литерал, #
сам должен быть экранирован:
#(#)(
Escape-последовательности также могут содержать короткие (четыре шестнадцатеричные цифры) или длинные (восемь шестнадцатеричных цифр) значений кодовой точки Юникода. Таким образом, следующие три escape-последовательности эквивалентны:
#(000D) // short Unicode hexadecimal value
#(0000000D) // long Unicode hexadecimal value
#(cr) // compact escape shorthand for carriage return
Несколько escape-кодов можно включить в одну escape-последовательность, разделенную запятыми; Таким образом, следующие две последовательности эквивалентны:
#(cr,lf)
#(cr)#(lf)
Ниже описан стандартный механизм экранирования символов в документе M.
последовательность символов и escape-последовательностей:
#(
escape-sequence-list )
список-escape-последовательностей:
одиночная-escape-последовательность
список escape-sequence ,
escape-sequence-sequence-list
одиночная-escape-последовательность:
длинная-управляющая-последовательность-Юникода
короткая-управляющая-последовательность-Юникода
escape-последовательность-с-управляющим-символом
escape-escape
длинная-управляющая-последовательность-Юникода:
шестнадцатеричный-знак шестнадцатеричный-знак шестнадцатеричный-знак шестнадцатеричный-знак шестнадцатеричный-знак шестнадцатеричный-знак шестнадцатеричный-знак шестнадцатеричный-знак
короткая-управляющая-последовательность-Юникода:
шестнадцатеричный-знак шестнадцатеричный-знак шестнадцатеричный-знак шестнадцатеричный-знак
escape-последовательность-с-управляющим-символом:
управляющий-символ
управляющий-символ:
cr
lf
tab
escape-escape:
#
Литералы
Литерал является представлением исходного кода значения.
литерал:
логический-литерал
числовой-литерал
текстовый-литерал
литерал-NULL
verbatim-literal
Литералы NULL
Литерал NULL используется для записи null
значения. Значение null
представляет отсутствующее значение.
null-литерал:
null
Логические литералы
Логический литерал используется для записи значений true
и false
создает логическое значение.
логический литерал:
true
false
Числовые литералы
Числовой литерал используется для записи числового значения и создает числовое значение.
числовой-литерал:
десятичный-числовой-литерал
шестнадцатеричный-числовой-литерал
десятичный-числовой-литерал:
десятичные цифры.
с десятичными цифрами экспонентной части
.
десятичные цифры экспонент-частьopt
десятичные-знаки показатель-степенинеобязательно
десятичные-знаки:
десятичный-знак десятичные-знакинеобязательно
десятичный-знак: один из
0 1 2 3 4 5 6 7 8 9
exponent-part:
e
подписатьдесятичные цифры
E
подписатьдесятичные цифры
знак: один из
+ -
шестнадцатеричное число-литерал:
0x
шестнадцатеричные цифры
0X
шестнадцатеричные цифры
шестнадцатеричные-знаки:
шестнадцатеричный-знак шестнадцатеричные-знакинеобязательно
шестнадцатеричный-знак: один из
0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f
Число можно указать в шестнадцатеричном формате, выполнив шестнадцатеричные цифры с символами 0x
. Например:
0xff // 255
Обратите внимание, что если десятичная точка включена в числовой литерал, она должна иметь по крайней мере одну цифру после нее. Например, 1.3
это числовой литерал, но 1.
и 1.e3
нет.
Текстовые литералы
Текстовый литерал используется для записи последовательности символов Юникода и создает текстовое значение.
текстовый литерал:
"
Выбор текстовых литеральных символов "
символы-текстового-литерала:
символ-текстового-литерала символы-текстового-литераланеобязательно
символ-текстового-литерала:
одиночный-текстовый-символ
escape-последовательность-символов
escape-последовательность-двойных-кавычек
одиночный-текстовый-символ:
Любой символ, кроме "
(U+0022
) или (U+0023
) за #
которым следует (
() (U+0028
)
double-quote-escape-sequence:
""
(U+0022
, U+0022
)
Чтобы включить кавычки в текстовое значение, кавычки повторяются следующим образом:
"The ""quoted"" text" // The "quoted" text
Рабочую последовательность символов можно использовать для записи символов в текстовые значения без необходимости напрямую кодировать их как символы Юникода в документе. Например, возврат каретки и канал строк можно записать в текстовое значение следующим образом:
"Hello world#(cr,lf)"
Подробные литералы
Подробный литерал используется для хранения последовательности символов Юникода, введенных пользователем в виде кода, но которые не могут быть правильно проанализированы как код. Во время выполнения он создает значение ошибки.
verbatim-literal:
#!"
Выбор текстовых литеральных символов "
Identifiers
Идентификатор — это имя, используемое для ссылки на значение. Идентификаторы могут быть обычными идентификаторами или кавычками.
идентификатор:
обычный-идентификатор
нестандартный-идентификатор
обычный-идентификатор:
доступный-идентификатор
доступный-идентификатор символ-точки обычный-идентификатор
доступный-идентификатор:
ключевое-слово-или-идентификатор, не являющееся ключевым словом
ключевое-слово-или-идентификатор:
начальный-символ-идентификатора символы-части-идентификаторанеобязательно
начальный-символ-идентификатора:
буквенный-символ
символ-подчеркивания
символы-части-идентификатора:
символ-части-идентификатора символы-части-идентификаторанеобязательно
символ-части-идентификатора:
буквенный-символ
символ-десятичного-знака
символ-подчеркивания
символ-соединения
символ-объединения
символ-форматирования
символ-точки:
.
(U+002E
)
символ подчеркивания:
_
(U+005F
)
буква-символ:
Символ Юникода классов Lu, Ll, Lt, Lm, Lo или Nl
объединение символов:
Символ Юникода классов Mn или Mc
десятичная цифра-символ:
Символ Юникода класса Nd
connecting-character:
Символ Юникода класса Pc
форматирование символа:
Символ Юникода класса Cf
Идентификатор с кавычками можно использовать, чтобы разрешить использовать любую последовательность символов Юникода в качестве идентификатора , включая ключевые слова, пробелы, комментарии, операторы и знаки препинания.
quoted-identifier:
#"
Выбор текстовых литеральных символов "
Обратите внимание, что escape-последовательности и двойные кавычки для escape-кавычки можно использовать в идентификаторе кавычки так же, как в текстовом литерале.
В следующем примере используется кворирование идентификаторов для имен, содержащих символ пробела:
[
#"1998 Sales" = 1000,
#"1999 Sales" = 1100,
#"Total Sales" = #"1998 Sales" + #"1999 Sales"
]
В следующем примере для включения +
оператора в идентификатор используется идентификатор:
[
#"A + B" = A + B,
A = 1,
B = 2
]
Обобщенные идентификаторы
Существует два места в M, где неоднозначность не представлена идентификаторами, содержащими пустые или которые являются ключевыми словами или числовых литералов. Это имена полей записей в литерале записи и в операторе доступа к полям ([ ]
) Там, M разрешает такие идентификаторы без использования кавычек идентификаторов.
[
Data = [ Base Line = 100, Rate = 1.8 ],
Progression = Data[Base Line] * Data[Rate]
]
Идентификаторы, используемые для имен и полей доступа, называются обобщенными идентификаторами и определяются следующим образом:
обобщенный-идентификатор:
часть-обобщенного-идентификатора
обобщенный-идентификатор разделяется только пробелами (U+0020
)
часть-обобщенного-идентификатора
часть-обобщенного-идентификатора:
сегмент-обобщенного-идентификатора
символ-десятичного-знака сегмент-обобщенного-идентификатора
сегмент-обобщенного-идентификатора:
ключевое-слово-или-идентификатор
ключевое слово или идентификатор точки-символа
Ключевые слова
Ключевое слово — это последовательность символов, которая зарезервирована и не может использоваться в качестве идентификатора, за исключением случаев, когда используется механизм идентификатора или где разрешен общий идентификатор.
ключевое слово: один из
and as each else error false if in is let meta not null or otherwise
section shared then true try type #binary #date #datetime
#datetimezone #duration #infinity #nan #sections #shared #table #time
Операторы и пунктуаторы
Существует несколько типов операторов и пунктуаторов. Операторы используются в выражениях для описания операций с участием одного или нескольких операндов. Например, выражение a + b
использует оператор +
для добавления двух операндов a
и b
. Знаки препинания предназначены для группировки и разделения.
оператор-или-знак-препинания: один из
, ; = < <= > >= <> + - * / & ( ) [ ] { } @ ! ? ?? => .. ...