![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
LoopsBoost , ,
До сих пор мы представили несколько операторов EBNF, которые занимаются петлей. У нас есть+положительный оператор, который соответствует предыдущему символу один (1) или более раз, а также звезда Клин*, которая соответствует предыдущему символу ноль (0) или более раз. В дальнейшем мы можем захотеть иметь оператора обобщенного цикла. Некоторым это может показаться случаем перебора. Тем не менее, существуют грамматики, которые непрактичны и громоздки, если не невозможно, для базового синтаксиса итерации EBNF. Примеры:
Кроме звезды Клин*, положительное замыкание+и необязательное!, более гибкий механизм зацикливания предусмотрен фреймворком.
Используя парсерrepeat_p, мы можем теперь написать наши примеры выше: Имя файла с максимум 255 символами: valid_fname_chars = /*..*/; filename = repeat_p(1, 255)[valid_fname_chars]; Конкретный формат растрового файла, который имеет ровно 4096 RGB цветовой информации: uint_parser<unsigned, 16, 6, 6> rgb_p; bitmap = repeat_p(4096)[rgb_p]; Что касается 32-битной бинарной строки (1..32 1s или 0s), то, конечно, мы могли бы легко использовать вместо этого числовой парсерbin_p. Однако для демонстрации bin32 = lexeme_d[repeat_p(1, 32)[ch_p('1') | '0']];
Парсеры Loop могут быть динамическими. Рассмотрим разбор двоичного файла префиксированной строки в стиле Паскаля, где первый байт определяет длину входящей строки. Вот образец ввода:
Этот тривиальный пример не может быть практически определен в традиционном EBNF. Хотя некоторые синтаксисы EBNF позволяют создавать более мощные конструкции повторения, чем звезда Клин, мы все еще ограничены разбором фиксированных строк. Природа EBNF заставляет коэффициент повторения быть постоянным. С другой стороны, Spirit позволяет изменять коэффициент повторения во время выполнения. Мы могли бы написать грамматику, которая принимает входную строку выше: int c; r = anychar_p[assign_a(c)] >> repeat_p(boost::ref(c))[anychar_p]; Выражение anychar_p[assign_a(c)] Извлекает первый символ из ввода и помещает его вс. Что интересно, так это то, что в дополнение к константам мы также можем использовать переменные в качестве параметровrepeat_p. repeat_p(boost::ref(c))[anychar_p] Обратите внимание, чтоboost::refиспользуется для ссылки на целое числоc. Это использованиеrepeat_pзаставляет парсер откладывать оценку коэффициента повторения до тех пор, пока он фактически не понадобится. Продолжая наш пример, поскольку значение 11 уже извлечено из входа,repeat_pтеперь, как ожидается, будет зацикливаться ровно 11 раз.
Copyright © 1998-2003 Joel de Guzman Статья Loops раздела может быть полезна для разработчиков на c++ и boost. Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта. :: Главная :: ::
|
|||||||||||||||||||||||||||||||||||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 |