
- •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.5. Операция конкатенации строк
В метаязыке между двумя синтаксическими конструкциями допускается
один и более пробельных символов. Таким образом,
'while''(' эквивалентна 'while' '('
while(
while (
'while' '('
'while'
'('
<tt><h> эквивалентна <tt> <h>
<tt> <h>
d <yy> эквивалентна d <yy>
d<yy>
d <yy>
d <yy>
и так далее.
Однако в некоторых конструкциях необходимо, чтобы между конструк-
циями пробельные символы были недопустимы. Например, идентификатор
языка СИ++ можно записать следующим образом.
<идентификатор> ::= char{az,AZ,_}string{az,AZ,09,_}
В этом случае между первым символом идентификатора и последующими
- 19 -
не может быть пробельных символов. Поэтому приведенная выше запись бу-
дет неверна. Для того, чтобы запретить эти пробельные символы в метая-
зык введена операция конкатенации, обозначаемая метасимволом +. Пра-
вильная запись синтаксиса идентификатора будет следующей
<идентификатор> ::= char{az,AZ,_} + string{az,AZ,09,_}
Запись 'whi'+ le будет эквивалента while или 'while'.
Операция конкатенации также допустима и для запрета пробельных симво-
лов между нетерминальными конструкциями, а также терминальными и не-
терминальными конструкциями. Отсутствие знака + не означает, что прог-
рамма разбора автоматически будет пропускать пробелы. Это означает
лишь то, что они допустимы.
2.5. Круглые скобки
Круглые скобки в метаязыке используются также как и в математи-
ческих выражениях. За круглые скобки можно выносить общую часть раз-
личных представлений (альтернатив) одного и того же нетерминального
символа. Например, в конструкции
<E> ::= <E> + <T>
||= <E> - <T>
||= <T>
можно вынести за скобки <E> в первых двух альтернативах
<E> ::= <E> ( + <T> | - <T>)
||= <T>
Можно выносить за скобки не только влево но и вправо. Продолжая преоб-
разование приведенного выше примера получим
<E> ::= <E> ( + | - ) <T>
||= <T>
- 20 -
2.6. Семантика языка
Для определения смысла той или иной синтаксической конструкции в
метаязыке используются конструкции языка СИ. Это могут быть непосредс-
твенно операторы языка или вызовы функций. Семантика может быть разме-
щена непосредственно за любым терминальным символом, нетерминальным
символом и любой сентенцией, а также за круглыми скобками.
Запись семантики в метаязыке может осуществлятся следующими спо-
собом.
<семантика> ::= '#{' < текст_на_языке_СИ > '}#'
Правильность записи текста семантики и параметров функций прове-
ряется на этапе трансляции сгенерированного текста анализатора компи-
лятором языка СИ.
Фрагмент программы исполняется при условии, что при разборе теку-
щего символа исходного предложения использовался элемент синтаксичес-
кой конструкции, вслед за которой располагается данный фрагмент семан-
тики.
Рассмотрим программу на метаязыке, выполняющую синтаксический
анализ и формирование десятичного числа.
/* -------------------------------------------------------- */
<десятичное число> /*программа разбора десятичного числа*/
::= <число>
semantics { Decimal = Float;}
( .<число> ';'
#{ for (i=1; i <= number; i++;)
Float /= 10;
Decimal += Float;
}#
- 21 -
| ';'
#{ Decimal = Float; }# )
/* -------------------------------------------------------- */
<число> /* разбор целого числа*/
::= <цифра>
#{ Float = Digit;
number = 1;
}#
||= <число> <цифра>
#{ Float = Float * 10 + Digit;
number++; }#
/* -------------------------------------------------------- */
<цифра> /* разбор цифр */
::= '0'
#{ Digit = 0; }#
||= '1'
#{ Digit = 1; }#
||= '2'
#{ Digit = 2; }#
||= '3'
#{ Digit = 3; }#
||= '4'
#{ Digit = 4; }#
||= '5'
#{ Digit = 5; }#
||= '6'
#{ Digit = 6; }#
||= '7'
- 22 -
#{ Digit = 7; }#
||= '8'
#{ Digit = 8; }#
||= '9'
#{ Digit = 9; }#
Описания переменных обычно помещаются в отдельном фрагменте прог-
раммы, но могут быть размещены в первом из фрагментов программы разбо-
ра на метаязыке. Для данной программы они будут следующими