Поделиться через


Лексическая структура

Документы

Документ M — это упорядоченная последовательность символов Юникода. M позволяет различным классам символов Юникода в разных частях документа M. Сведения о классах символов Юникода см. в разделе "Стандартный" в Юникоде версии 3.0, в разделе 4.5.

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

  1. Документ декодируется в соответствии со схемой кодировки символов в последовательности символов Юникода.

  2. Лексический анализ выполняется, тем самым превратив поток символов Юникода в поток токенов. Остальные подразделы этого раздела охватывают лексический анализ.

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

Грамматические соглашения

Лексические и синтаксические грамматики представлены с помощью грамматических производств. Каждая грамматическая рабочая среда определяет неконечный символ и возможные расширения этого нетерминального символа в последовательности символов, отличных от терминала или терминалов. В грамматических правилах неконечные символы обозначаются курсивом, а конечные символы — шрифтом с фиксированной шириной.

Первая строка грамматического правила — это имя определяемого неконечного символа, за которым следует двоеточие. Каждая последовательная отступная строка содержит возможное расширение нетерминального, заданного как последовательность символов, отличных от терминала или терминалов. Например, следующее правило:

if-expression:
      ifУсловие then if true-expressionelsefalse-expression

определяет, что выражение-if состоит из токена if, за которым следуют условие-if, токен then, выражение-true, токен else и выражение-false.

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

список переменных:
      переменная
      Переменная списка
, переменных

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

Подстрочный суффикс "opt" используется для указания необязательного символа. Рабочая среда:

спецификация поля:
      optionalopt 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+000AU+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. Знаки препинания предназначены для группировки и разделения.

оператор-или-знак-препинания: один из
      , ; = < <= > >= <> + - * / & ( ) [ ] { } @ ! ? ?? => .. ...