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

Mini XML - Error Handling

Boost , Spirit 2.5.2 , Tutorials

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Парсер не будет полным без обработки ошибок. Spirit2 позволяет легко адаптировать грамматику для обработки ошибок. На этот раз мы завернем учебник Qi другой версией мини-парсера xml с обработкой ошибок.

The full cpp file for this example can be found here: ../../example/qi/mini_xml3.cpp

Вот грамматика:

template <typename Iterator>
struct mini_xml_grammar
  : qi::grammar<Iterator, mini_xml(), qi::locals<std::string>, ascii::space_type>
{
    mini_xml_grammar()
      : mini_xml_grammar::base_type(xml, "xml")
    {
        using qi::lit;
        using qi::lexeme;
        using qi::on_error;
        using qi::fail;
        using ascii::char_;
        using ascii::string;
        using namespace qi::labels;
        using phoenix::construct;
        using phoenix::val;
        text %= lexeme[+(char_ - '<')];
        node %= xml | text;
        start_tag %=
                '<'
            >>  !lit('/')
            >   lexeme[+(char_ - '>')]
            >   '>'
        ;
        end_tag =
                "</"
            >   string(_r1)
            >   '>'
        ;
        xml %=
                start_tag[_a = _1]
            >   *node
            >   end_tag(_a)
        ;
        xml.name("xml");
        node.name("node");
        text.name("text");
        start_tag.name("start_tag");
        end_tag.name("end_tag");
        on_error<fail>
        (
            xml
          , std::cout
                << val("Error! Expecting ")
                << _4                               // what failed?
                << val(" here: \"")
                << construct<std::string>(_3, _2)   // iterators to error-pos, end
                << val("\"")
                << std::endl
        );
    }
    qi::rule<Iterator, mini_xml(), qi::locals<std::string>, ascii::space_type> xml;
    qi::rule<Iterator, mini_xml_node(), ascii::space_type> node;
    qi::rule<Iterator, std::string(), ascii::space_type> text;
    qi::rule<Iterator, std::string(), ascii::space_type> start_tag;
    qi::rule<Iterator, void(std::string), ascii::space_type> end_tag;
};

Что нового?

Readable Names

Во-первых, когда мы называем базовый класс, мы даем грамматике имя:

: mini_xml_grammar::base_type(xml, "xml")

Назовем все наши правила:

xml.name("xml");
node.name("node");
text.name("text");
start_tag.name("start_tag");
end_tag.name("end_tag");
On Success

<on_success>объявляет обработчика, который применяется, когда правило успешно соответствует.

on_success(rule, handler)

Это указывает на то, что обработчик будет вызван, когда правило будет успешно согласовано. Обработчик имеет следующую подпись:

void handler(
	fusion::vector<
		Iterator& first,
		Iterator const& last,
		Iterator const& i> args,
	Context& context)

<first>указывает на положение во входной последовательности до соответствия правилу.<last>указывает на последнюю позицию во входной последовательности.<i>указывает на положение во входной последовательности после последнего символа, который был поглощен правилом.

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

On Error

<on_error>Объявляет обработчик ошибок:

on_error<Action>(rule, handler)

Это будет определять, что мы будем делать, когда получим ошибку. Мы распечатаем сообщение об ошибке с помощью феникса:

on_error<fail>
(
    xml
  , std::cout
        << val("Error! Expecting ")
        << _4                               // what failed?
        << val(" here: \"")
        << construct<std::string>(_3, _2)   // iterators to error-pos, end
        << val("\"")
        << std::endl
);

<fail>В нашем примере<Action>: Бросай и проваливай. Возврат No_match (ложь). Он может быть одним из:

Описание

Отказаться и потерпеть неудачу. Вернуться в No_match

Попытка восстановления ошибки, возможно, перемещение позиции итератора.

Принудительный успех, правильное перемещение позиции итератора.

<rule>является правилом, к которому прилагается обработчик. В нашем случае мы придерживаемся правила<xml>.

<handler>является функцией обработки ошибок. Ожидаются 4 аргумента:

Арг

Описание

Конец входа.

Фактическое положение итератора, в котором произошла ошибка.

Expectation Points

Возможно, вы не заметили этого, но некоторые из наших выражений изменились с<>>>до<>>. Посмотрите, например:

end_tag =
        "</"
    >   lit(_r1)
    >   '>'
;

Что это? Этоожиданиеоператор. В грамматике у вас будут некоторые «детерминированные точки». Это те места, где отступлениене может произойти. Для нашего примера выше, когда вы получаете<"</">, вы определенно должны увидеть действительную конечную метка. Это должно быть то, что вы получили от начальной отметки. После этого у вас обязательно должен быть следующий<'>'>. В противном случае нет смысла продолжать и пробовать другие отрасли, независимо от того, где они находятся. Вклад, безусловно, ошибочен. Когда это происходит, выпадает исключение «ожидание_неудача». Где-то вовне обработчик ошибок поймает исключение.

Попробуйте построить парсер:../../пример/qi/mini_xml3.cpp. Вы можете найти несколько примеров в../../пример/qi/mini_xml_samplesдля целей тестирования. "4.toyxml" имеет ошибку в нем:

<foo><bar></foo></bar>

Приведем пример с этим:

Error! Expecting "bar" here: "foo></bar>"
Error! Expecting end_tag here: "<bar></foo></bar>"
-------------------------
Parsing failed
-------------------------

PrevUpHomeNext

Статья Mini XML - Error Handling раздела Spirit 2.5.2 Tutorials может быть полезна для разработчиков на c++ и boost.




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



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


реклама


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

Время компиляции файла: 2024-08-30 11:47:00
2025-05-19 19:59:46/0.0076069831848145/0