![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
The Switch ParserBoost , ,
Переключатели могут использоваться для упрощения определенных конструкций чередования. Рассмотрим следующий код: rule<> rule_overall = ch_p('a') >> parser_a | ch_p('b') >> parser_b // ... | ch_p('n') >> parser_n ; Каждая из альтернатив обычно оценивается последовательно. Это, как правило, неэффективно, особенно для большого количества альтернатив. Чтобы избежать этой неэффективности и дать возможность писать такие конструкции в более читаемой форме, Spirit содержитswitch_p.Семейство парсеров. Парсер switch_p позволяет переписать предыдущую конструкцию следующим образом: rule<> rule_overall = switch_p [ case_p<'a'>(parser_a), case_p<'b'>(parser_b), // ... case_p<'n'>(parser_n) ] ; Этоswitch_pпарсер берет следующий символ (или токен) из входного потока и пытается сопоставить его с заданными интегральными константами времени компиляции, поставляемыми в качестве параметров шаблона вcase_pПарсеры. Если этот персонаж соответствует одному изcase_pветви, ассоциированный парсер выполняется (т.е. если «а» совпадает,парсер_а)выполняется, если «b» совпадает,parser_bвыполняется и так далее. Если нетcase_pветвь соответствует следующему входному символу, общая конструкция не совпадает вообще.
Иногда желательно добавить обработку дела по умолчанию (ни одна из ветвейcase_pне совпадает). Это может быть достигнуто с помощью ветвиdefault_p: rule<> rule_overall = switch_p [ case_p<'a'>(parser_a), case_p<'b'>(parser_b), // ... case_p<'n'>(parser_n), default_p(parser_default) ] ; Эта форма выбирает парсерparser_default, если ни один из случаев не соответствует следующему символу из входного потока. Обратите внимание, что в конструкцию парсераможет быть добавлена только одна ветвьdefault_p. Кроме того, можно опустить скобки и корпус из конструкцииdefault_p, и в этом случае не выполняется дополнительный парсер, а общая конструкцияswitch_pпросто возвращает соответствие на любой символ входного потока, который не соответствует ни одной из ветвейcase_p: rule<> rule_overall = switch_p [ case_p<'a'>(parser_a), case_p<'b'>(parser_b), // ... case_p<'n'>(parser_n), default_p ] ; Существует еще одна форма конструкции switch_p. Эта форма позволяет нам четко указать значение, которое будет использоваться для сопоставления с ветвямиcase_p: rule<> rule_overall = switch_p(cond) [ case_p<'a'>(parser_a), case_p<'b'>(parser_b), // ... case_p<'n'>(parser_n) ] ; гдеcondявляется парсером или нулевой функцией или функциональным объектом (функтором). Если это парсер, то его пробуют и используют его возвращаемое значение для сопоставления с ветвямиcase_p. Если это нулевая функция или функтор, то будет использоваться его обратное значение. Обратите внимание, что во время его компиляции конструкцияswitch_pтрансформируется в реальное утверждение C++switch. Это делает процесс выполнения очень эффективным.
Copyright © 2003-2004 Hartmut Kaiser Статья The Switch Parser раздела может быть полезна для разработчиков на c++ и boost. Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта. :: Главная :: ::
|
|||||||||||||||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 |