Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

List Parsers

Boost , ,

  List Parsers

Парсеры списка генерируются специальным предопределенным объектом генератора парсера list_p, который генерирует парсеры, распознающие структуры списка типа

    item >> *(delimiter >> item) >> !end

где item является выражением, делимитер является делимитером, а конец является необязательным выражением закрытия. Как видите, сгенерированный парсер list_p не распознает пустые списки, т.е. парсер должен найти хотя бы один элемент во входном потоке, чтобы вернуть успешное совпадение. Если вы также хотите сопоставить пустой список, вы можете сделать свой список_p необязательным с оператором! Примером полезного парсера утилиты является разбор запятых, разделенных строками C/C++, которые могут быть легко сформулированы как:

    rule<> list_of_c_strings_rule
        =   list_p(confix_p('\"', *c_escape_char_p, '\"'), ',')
        ;

Генераторы парсера confix_p и c_escape_char_p описаны here и here.

Объект парсерного генератора list_p может использоваться для генерации следующих различных типов парсеров списка:

List Parsers
list_p

list_p, используемый сам по себе, анализирует списки, разделенные запятыми, без специального форматирования элементов, то есть все между двумя запятыми сопоставляется с item, не сопоставляется end маркера списка

list_p(delimiter)

генерирует парсер списков, который распознает списки с данным delimiter и сопоставляет все между ними как item, не сопоставляется end токена списка

list_p(item, delimiter)

генерирует парсер списка, который распознает списки с заданным delimiter и сопоставляет элементы на основе заданного парсера элементов, не сопоставляется end маркера списка

list_p(item, delimiter, end)

генерирует парсер списка, который распознает списки с данным delimiter и сопоставляет элементы на основе данного item парсера и дополнительно распознает необязательный end выражение

Все параметры list_p могут быть отдельными символами, строками или, если требуется более сложная логика разбора, вспомогательными парсерами, каждый из которых автоматически преобразуется в соответствующий тип парсера, необходимый для успешного разбора.

Если парсер item является типом action_parser_category (парсер с прилагаемым семантическим действием), мы должны сделать что-то особенное. Это происходит, если пользователь написал что-то вроде:

    list_p(item[func], delim)

где item является парсером, соответствующим одному элементу последовательности списка, и func является функтором, который должен быть вызван после сопоставления одного элемента. Если мы ничего не будем делать, полученный код разберет последовательность следующим образом:

    (item[func] - delim) >> *(delim >> (item[func] - delim))

в большинстве случаев это не то, что ожидает пользователь. (Если это , то, пожалуйста, используйте одну из функций генератора list_p direct(), которая будет препятствовать рефакторингу парсера item). Чтобы сделать список парсера вести себя как ожидалось:

    (item - delim)[func] >> *(delim >> (item - delim)[func])

актер, прикрепленный к парсеру элемента, должен быть повторно прикреплен к конструкции парсера (пункт - делим) , которая заставит результирующий парсер списка «делать правильные вещи». Рефакторинг осуществляется с помощью парсеров Refactoring. Кроме того, следует соблюдать особую осторожность, если парсер является unary_parser_category Тип парсера, например:

    list_p(*anychar_p, ',')

которые без какого-либо рефакторинга привели бы к

        (*anychar_p - ch_p(','))
    >> *( ch_p(',') >> (*anychar_p - ch_p(',')) )

и не даст ожидаемого результата (первый *anychar_p съест весь вход до конца входного потока). Поэтому мы должны реорганизовать это в:

       *(anychar_p - ch_p(','))
    >> *( ch_p(',') >> *(anychar_p - ch_p(',')) )

что даст правильный результат.

Случай, когда парсер является комбинацией двух упомянутых проблем (т.е. парсер является унарным парсером с прилагаемым действием), обрабатывается соответственно:

    list_p((*anychar_p)[func], ',')

будут разобраны, как и ожидалось:

        (*(anychar_p - ch_p(',')))[func]
    >> *( ch_p(',') >> (*(anychar_p - ch_p(',')))[func] )

Необходимый рефакторинг реализуется с помощью Рефакторинг Парсеров.

Summary of List Parser refactorings
You write it as: It is refactored to:
list_p(item, delimiter) (item - delimiter)
>> *(
delimiter >> (item - delimiter))
list_p(item[func], delimiter) (item - delimiter)[func]
>> *(
delimiter >> (item - delimiter)[func])
list_p(*item, delimiter) *(item - delimiter)
>> *(
delimiter >> *(item - delimiter))
list_p((*item)[func], delimiter) (*(item - delimiter))[func]
>> *(
delimiter >> (*(item - delimiter))[func])

list_parser.cpp образец показывает использование парсера утилиты list_p:

  1. разбор простого "," разграниченного списка w/o элемента форматирования
  2. разбор списка CSV (раздельные значения запятой - строки, целые числа или реалы)
  3. анализ списка токенов (выделенные значения токенов - строки, целые числа или реалы)
    с парсером действий, непосредственно прикрепленным к элементной части списка_p сгенерированного парсера

Это часть духовного распределения.



Статья List Parsers раздела может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 04:18:21/0.0063490867614746/1