Соглашения
Расширенная форма Бэкуса-Наура
Несмотря на то, что эта книга главным образом посвящена языку XSLT, в ней также описываются расширяемый язык разметки XML и язык обращения к частям ХМL-документов, называемый XPath. Подробное и точное описание этих языков невозможно без четких определений синтаксических конструкций.
Для описания синтаксиса рассматриваемых языков мы будем использовать расширенные формы Бэкуса-Наура (РФБН, или, по-английски, Extended Backus-Naur Form, EBNF). EBNF — это современная модификация методологии, которая впервые была использована для описания языка программирования Алгол-60. За прошедшие десятилетия формы Бэкуса-Наура были доработаны множеством авторов и сейчас в расширенном виде используются для описания ряда языков программирования различной степени сложности. EBNF-нотация также широко используется в технических рекомендациях Консорциума W3, которые фактически и являются стандартами рассматриваемых нами языков.
Нотация EBNF определяет язык как набор синтаксических правил, определяющих нетерминалы (конструкции языка) через терминалы (символы языка), а также другие нетерминалы. Правило состоит из двух частей, разделенных символами '::=
':
В левой части правила стоит терминал определяемой конструкции, в правой — выражение, определяющее эту конструкцию. Правила EBNF также иногда называют продукциями, и мы тоже часто будем использовать этот термин, чтобы не путать эти правила с шаблонными правилами преобразований, которые главным образом и составляют преобразования в языке XSLT.
Терминалы, которые могут быть как отдельными символами, так и их последовательностями, определяются в нотации EBNF следующим образом:
□ #x
, где
— шестнадцатеричный код, соответствует символу Unicode с кодом
. Например, #х410
соответствует символу А
кириллического алфавита (
□ [a-zA-z]
, [#x
— соответствует символу указанного интервала. К примеру, [a-f]
соответствует любому из символов а
, b
, с
, d
, e
, f
.
□ [abc]
, [#x
— соответствует любому из перечисленных символов. Например, [#х410#х411#х412]
соответствует любому из символов А
, Б
, В
. Символьные интервалы и перечисления могут использоваться совместно в одних квадратных скобках.
□ [^a-z]
, [^#х
— соответствует любому символу, кроме символов указанного интервала. К примеру, [^#х410-#x42F]
соответствует любому символу, кроме заглавных букв русского алфавита.
□ [^abc]
, [^#x
— соответствует любому, кроме перечисленных символов. Например, [^xyz]
соответствует любому символу, кроме символов x
, y
и z
. Аналогично разрешенным интервалам и последовательностям символов, запрещенные интервалы и последовательности также могут использоваться совместно.
□ 'строка'
— соответствует строке, которая приведена в двойных кавычках. Например, 'stylesheet'
соответствует строке stylesheet
.
□ 'строка'
— соответствует строке, которая приведена в одинарных кавычках. Например, 'template'
соответствует строке template
.
Терминалы могут использоваться совместно с нетерминальными конструкциями в более сложных выражениях.
□ A?
означает, что выражение A
необязательно и может быть пропущено.
□ A | B
соответствует либо выражению A
, либо выражению B
, но не им обоим одновременно (строгое 'или'). Выражения такого вида называют иначе
□ A B
означает, что за выражением A
следует выражение B
. Последовательность имеет приоритет по сравнению с выбором — A B | C D
означает последовательность выражений A
и B
или последовательность выражений C
и D
.
□ A - B
соответствует строке, которая соответствует выражению A
, но не выражению B
.
□ A+
означает последовательность из одного или более выражения A
. Оператор '+
' в EBNF старше оператора выбора, A+ | B+
означает последовательность из одного или более выражения A
или последовательность из одного или более выражения B
.
□ A*
означает последовательность из нуля или более выражений A
. Аналогично оператору '+
', оператор '*
' старше оператора выбора
□ (
— круглые скобки используются для группировки выражений. Выражения, заключенные в скобки, рассматриваются, как отдельная единица, которая может быть свободно использована в приведенных выше конструкциях. Например, выражение A B C | B C | A D C | D C | C
можно переписать в виде (A? (B | D) ) C
.
Нотация расширенных форм Бэкуса-Наура может с первого взгляда показаться очень сложной, однако, на самом деле это не так. Достаточно разобрать несколько примеров, как все встанет на свои места.
Рассмотрим реальную продукцию Digits
языка XPath. Digits
— это последовательность из нескольких цифр от 0
до 9
и определяется она следующим образом:
Digits ::= [0-9] +
Как правило, продукции в спецификациях языков пронумерованы для того, чтобы было легче на них ссылаться. Мы будем по возможности приводить эти номера так, как они указаны в технических рекомендациях — в квадратных скобках, например:
[31] Digits ::= [0-9]+
При помощи продукции Digits определяется такая продукция, как Number, которая соответствует числу. Число — это последовательность цифр, разделенная точкой на целую и дробную части:
[30] Number ::= Digits ('.' Digits?)?