![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
The Lazy ParsersBoost , ,
Закрытие - это круто. Это позволяет нам вводить локальные переменные на основе стека в любом месте нашей иерархии спуска. Как правило, мы храним временные переменные, генерируемые нашими семантическими действиями, в наших переменных закрытия, как средство передачи информации вверх и вниз по рекурсивному спуску. Теперь представьте это... Имея в виду, что переменные закрытия могут быть практически любого типа, мы можем хранить парсер, правило или указатель на парсер или правило в переменной закрытия.Да, верно, так что?Хорошо, подождите... Что, если мы можем использовать эту переменную закрытия, чтобы начать анализ? Подумай об этом на секунду. Вдруг у нас появятся мощные динамические парсеры! Неожиданно мы отправимся в круглую поездку из Фениксаи Духа и обратно!ФениксСемантические действия выбирают правильный парсер Духа и парсеры Духа выбирают правильныйФениксСемантическое действие. О, чувак, какая классная идея, я бы сказал!!! lazy_pВ этом и заключается сутьlazy_p.Парсер.Lazy_pСинтаксис: lazy_p(actor) Феникс— выражение, возвращающее парсера Духа. Этот возвращенный парсер используется в процессе парсинга. Пример: lazy_p(phoenix::val(int_p))[assign_a(result)] Семантические действия, прилагаемые кlazy_pparser, ожидают такой же подписи, как и у возвращаемого parserint_p, в нашем примере выше. lazy_p exampleЧтобы дать вам лучшее представление (см.lazy_parser.cpp), скажите, что вы хотите разобрать входные данные, такие как: dec { гдеbin {...}иdec {...}указывает числовой формат (двоичный или десятичный), который мы ожидаем прочитать. Если мы анализируем входные данные, нам нужна такая грамматика, как:
Мы намеренно исключили правило<
В то время как это нормально, избыточность заставляет нас хотеть найти лучшее решение; в конце концов, мы хотели бы в полной мере использовать возможности динамического анализа Духа. Кроме того, будут случаи, когда набор разборчивого поведения для нашего правилачислане известен, когда написана грамматика. Нам будет предоставлена только карта струнных дескрипторов и соответствующих правил [например (("dec", int_p), ("bin", bin_p)... и т.д.]]. Основная идея состоит в том, чтобы иметь правило для двоичных и десятичных чисел. Это легко сделать (см.цифры). Когдабазаанализируется, в вашем семантическом действии храните указатель на выбранную базу в переменной закрытия (например,block.int_rule). Вот пример:
С этой настройкой ваше правило числа теперь будет выглядеть примерно так:
lazy_parser.cppделает это немного по-другому, изобретательно используя таблицу символовдля отправки правильного правила, но по сути обе стратегии похожи. Эта техника, используя таблицу символов, подробно описана в разделе Техники:nabialek_trick. Как правило, когда вы складываете все правила, результирующая грамматика более сложна, чем жестко закодированная грамматика выше. Тем не менее, для более сложных грамматических шаблонов с большим количеством правил на выбор, дополнительная настройка стоит того.
Copyright © 2003 Joel de Guzman
Статья The Lazy Parsers раздела может быть полезна для разработчиков на c++ и boost. Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта. :: Главная :: ::
|
|||||||||||||||
©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007 |