
- •2.2. Управляющие последовательности
- •12.3.3. Отсутствие элементов конструкций.
- •2.4. Терминальные символы
- •12.4.1. Символ из множества.
- •12.4.2. Символ, не принадлежащий множеству
- •12.4.3. Строка символов из множества.
- •12.4.4. Строка из одинаковых символов.
- •12.4.5. Операция конкатенации строк
- •2.5. Круглые скобки
- •2.6. Семантика языка
- •Int I, number;
- •Int number_string - номер последней обрабатываемой строки,
- •3. Пример программы разбора
- •14.2. Преобразование грамматики
- •14.3. Примеры преобразования грамматик на метаязыке
12.4.2. Символ, не принадлежащий множеству
Множество символов за исключением указанных обозначают с помощью пре-
дыдущих конструкций с указанием впереди каждой восклицательного знака,
который означает отрицание.
Записи !char {a,bc}, ![a,bc] означают любой символ, не принадле-
жащий указанному множеству. Например, любой символ, который может на-
ходится в тексте комментария, можно описать в виде:
<символ комментария> ::= !char{'/*','*/'}
Данные конструкции также можно использовать совместно с символом
_, который указывает на то, что конструкция может отсутствовать.
Операция ! имеет выше приоритет, чем _. Поэтому запись
!char{'/*','*/'}_
означает, что вся конструкция !char{'/*','*/'} может отсутствовать.
Отдельные символы в множестве можно указывать также с помощью уп-
равляющих последовательностей.
12.4.3. Строка символов из множества.
Конструкция string задает не один символ, а строку символов из элемен-
тов множества в фигурных скобках. Например, строки a, aa, b, ab,bba,
... можно коротко записать в виде:
string{ab} или {ab} или {a,b} или string{a,b}
Множество символов из которых состоит строка задается в фигурных скоб-
ках аналогично множеству в char. Строка, определенная таким образом
должна содержать, как минимум один символ.
С помощью этой конструкции можно записать <целое число> более
простым способом.
<целое> ::= string{09}
что эквивалентно конструкции
<целое> ::= <цифра>
||= <целое><цифра>
- 16 -
В данной конструкции можно использовать операции _ и !. Например,
синтаксис комментария можно записать в виде:
<комментарий> ::= '/*' <текст комментария> '*/'
||= '//' <строчный комментарий>_
<текст комментария>
::= !string{'/*','*/'}_
/* строка из любых символов, не принадлежащих
указанному множеству */
<строчный комментарий>
::= !string{\12,\15}
Отметим, что операция ! имеет приоритет выше, чем _. Таким обра-
зом, !string{'/*','*/'}_ означает, что может отсутствовать вся конс-
трукция !string{'/*','*/'}.
12.4.4. Строка из одинаковых символов.
Строку из одинаковых символов можно записать, используя string. Напри-
мер, строка из n символов a может быть представлена в виде {a}. Число
символов в такой строке от одного до бесконечности. То есть это может
быть a , aa , aaa, aaa... .
Рассмотрим следующую грамматику.
<A> ::= a<A>b
||= y
Нетрудно убедится, что данная грамматика порождает множество
предложений типа aa...ybb..., причем число символов a в каждом предло-
жении равна числу символов b. Eсли мы запишем такое предложение в виде
{a}y{b}, то это будет неправильно, поскольку данная запись допускает
неравное число символов a и b в порождаемой строке.
Для обеспечения возможности представления предложений с одинако-
- 17 -
вым числом символов и предназначена конструкция a^. Эта строка содер-
жит от одного до бесконечного числа символов. Причем, если в строке
находится еще один символ со знаком ^ , то число символов, стоящих
слева от этих знаков в порождаемых строках должны быть равными. Пред-
ложенная выше конструкция может быть записана в виде.
<A> ::= a^yb^
Знак ^ может применяться с группой терминальных символов ('ac'^),
а также с одним нетерминальным символом ( <A>^ ).
Если число повторений символов точно определено, то оно записыва-
ется после знака ^. Например, aaaa можно записать как a^4. Данную опе-
рацию ^ можно применить и к нетерминальному символу. Например,
<цифра>^5 означает строку из пяти цифр
<цифра><цифра><цифра><цифра><цифра>
Любую рекурсивную конструкцию можно представить в одном из трех
видов:
<A> ::= <A><Z>
<A> ::= <Z><A>
<A> ::= <C><A><Z>
путем простого переобозначения правых и левых сентенций в продукциях
нетерминальными символами. Например,
<A> ::= cfg<B><A>f<A>
можно записать в виде
<A> ::= <С><A><Z>
<C> ::= cfg<B>
<Z> ::= f<A>
или
<A> ::= <Z><A>
<Z> ::= cfg<B><A>f
В свою очередь каждый из трех вариантов может быть представлен с
помощью операций ^ и <* *>.
<A> ::= <A><* <Z> *> // <A> ::= <A><Z>
- 18 -
<A> ::= <* <Z> *><A> // <A> ::= <Z><A>
<A> ::= <C>^<A><Z>^ // <A> ::= <C><A><Z>
Операция ^ необходима только для синтаксических конструкций
третьего вида, когда нужно задать равное число повторений. Причем это
требуется только в том случае, если есть неоднозначность при выборе
продукций. В остальных случаях этой операцией пользоваться не рекомен-
дуется.
В качестве дополнительной иллюстрации использования метаязыка в
приложении приведено полное и точное описание метаязыка на метаязыке.