KnigaRead.com/

Алексей Валиков - Технология XSLT

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Алексей Валиков, "Технология XSLT" бесплатно, без регистрации.
Перейти на страницу:

Нотация EBNF определяет язык как набор синтаксических правил, определяющих нетерминалы (конструкции языка) через терминалы (символы языка), а также другие нетерминалы. Правило состоит из двух частей, разделенных символами "::=":

конструкция ::= определение конструкции

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

Терминалы, которые могут быть как отдельными символами, так и их последовательностями, определяются в нотации EBNF следующим образом:

□ #xN, где N — шестнадцатеричный код, соответствует символу Unicode с кодом N. Например, #х410 соответствует символу А кириллического алфавита (см. раздел "Использование Unicode" главы 1).

□ [a-zA-z], [#xN-#xN] — соответствует символу указанного интервала. К примеру, [a-f] соответствует любому из символов а, b, с, d, e, f.

□ [abc], [#xN#xN#xN] — соответствует любому из перечисленных символов. Например, [#х410#х411#х412] соответствует любому из символов А, Б, В. Символьные интервалы и перечисления могут использоваться совместно в одних квадратных скобках.

□ [^a-z], [^#хN-#xN] — соответствует любому символу, кроме символов указанного интервала. К примеру, [^#х410-#x42F] соответствует любому символу, кроме заглавных букв русского алфавита.

□ [^abc], [^#xN#xN#xN] — соответствует любому, кроме перечисленных символов. Например, [^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?)?

                | '.' Digits

Чтобы лучше понять EBNF, попробуем немного упростить эту продукцию. Выражение Digits? внутри круглых скобок означает, что Digits может как присутствовать, так и быть опущенным, то есть ('.' Digits?) ? равносильно '.' ? | ('.' Digits)?. Повторяя еще раз подобное упрощение с каждым из полученных выражений, в итоге преобразуем правило Number к виду:

Number ::= Digits

           | Digits '.' Digits

           | Digits '.'

           | '.' Digits

Следовательно, число имеет четыре варианта синтаксиса:

□ последовательность цифр, например 12345;

□ последовательность цифр, разделенная точкой на целую и дробную части, например 3.14;

□ последовательность цифр, заканчивающаяся точкой, например 6. — что эквивалентно 6.0;

□ последовательность цифр, начинающаяся точкой, например .5, что эквивалентно 0.5.

Разберем еще одну продукцию языка XPath — определение литерала. Литерал в XPath — это последовательность символов, заключаемая в одинарные или двойные кавычки, которая используется в качестве строкового параметра в функциях и т.д. Единственным и вполне логичным ограничением на синтаксис литерала является то, что он не может содержать символ собственных кавычек — в этом случае непонятно, где же на самом деле литерал кончается, а где начинается (например, 'ab'cd').

Конструкция Literal задается следующим образом:

[29] Literal ::= '"' [^"]* '"'

                 | "'" [^']* "'"

В первом случае синтаксис литерала начинается двойными кавычками ('"'), затем идет последовательность, состоящая из любых символов, кроме двойных кавычек ([^"]*), затем закрывающие двойные кавычки ('"'). Во втором случае синтаксис имеет точно такой же вид с точностью до замены одинарных кавычек двойными и наоборот.

Другим очень часто используемым правилом является правило, определяющее пробельное пространство (англ. space или whitespace). Пробельными символами в XML-языках считаются такие символы, как табуляция, перевод строки, возврат каретки и сам пробел. Продукция S пробельного пространства задается, как последовательность из одного или более пробельного символа:

[3] S ::= (#х20 | #х9 | #xD | #хА)+

Как правило, EBNF-продукции языков XML-группы составлены довольно просто, но в некоторых случаях они разбиты на несколько правил, которые определены в разных частях спецификации. В таких случаях мы будем по возможности упрощать продукции, записывая их в раскрытом виде.

Обозначения

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

Прежде всего, код программ и текст XML-документов будет выделяться моноширинным шрифтом Courier. Листингам многих примеров будут предшествовать заголовки вида

Листинг 2.1. Входящий документ

<!-- Текст входящего документа -->

Для того чтобы текст XML-документов был более наглядным, в листингах он будет форматироваться с пробельными отступами, например:

<foo bar="1">

 <FOO/>

</foo>

Еще раз повторим, что это форматирование применяется только в целях наглядности исходного кода, когда это не противоречит смыслу документа. В предыдущем случае документ на самом деле мог выглядеть как:

<?xml version="1.0" encoding="UTF-8"?><foo bar="1"><FOO></foo>

В тех случаях, когда позиции пробельных символов документа важны для повествования, они будут особым образом выделяться. Для обозначения пробела мы будем использовать символ "□", а для обозначения символа переноса строки — символ "¶", например:

<а xmlns:d="urn:d">¶

□□<d:b>¶

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*