error_handling.qbk

来自「Boost provides free peer-reviewed portab」· QBK 代码 · 共 122 行

QBK
122
字号
[/==============================================================================    Copyright (C) 2001-2008 Joel de Guzman    Copyright (C) 2001-2008 Hartmut Kaiser    Distributed under the Boost Software License, Version 1.0. (See accompanying    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)===============================================================================/][section Mini XML - Error Handling]A parser will not be complete without error handling. Spirit2 provides somefacilities to make it easy to adapt a grammar for error handling. We'll wrap upthe Qi tutorial with another version of the mini xml parser, this time, witherror handling.[@../../example/qi/mini_xml1.cpp] and here: [@../../example/qi/mini_xml2.cpp][import ../../example/qi/mini_xml3.cpp]Here's the grammar:[tutorial_xml3_grammar]What's new?[heading Readable Names]First, when we call the base class, we give the grammar a name:    : mini_xml_grammar::base_type(xml, "xml")Then, we name all our rules:    xml.name("xml");    node.name("node");    text.name("text");    start_tag.name("start_tag");    end_tag.name("end_tag");[heading On Error]`on_error` declares our error handler:    on_error<Action>(rule, handler)This will specify what we will do when we get an error. We will print out anerror message using phoenix:    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    );we choose to `fail` in our example for the `Action`: Quit and fail. Return ano_match (false). It can be one of:[table    [[`Action`]     [Description]]    [[fail]         [Quit and fail. Return a no_match.]]    [[retry]        [Attempt error recovery, possibly moving the iterator position.]]    [[accept]       [Force success, moving the iterator position appropriately.]]    [[rethrow]      [Rethrows the error.]]]`rule` is the rule we attach the handler to. In our case, we are attaching to the`xml` rule.`handler` is the actual error handling function. It expects 4 arguments:[table    [[Arg]          [Description]]    [[first]        [The position of the iterator when the rule with the handler was entered.]]    [[last]         [The end of input.]]    [[error-pos]    [The actual position of the iterator where the error occurred.]]    [[what]         [What failed: a string decribing the failure.]]][heading Expectation Points]You might not have noticed it, but some of our expressions changed from usingthe `>>` to `>`. Look, for example:    end_tag =            "</"        >   lit(_r1)        >   '>'    ;What is it? It's the /expectation/ operator. You will have some "deterministicpoints" in the grammar. Those are the places where backtracking *cannot* occur.For our example above, when you get a `"</"`, you definitely must see a validend-tag label next. It should be the one you got from the start-tag. After that,you definitely must have a `'>'` next. Otherwise, there is no point inproceeding forward and trying other branches, regardless where they are. Theinput is definitely erroneous. When this happens, an expectation_failureexception is thrown. Somewhere outward, the error handler will catch theexception.Try building the parser: [@../../example/qi/mini_xml2.cpp]. You can find someexamples in: [@../../example/qi/mini_xml_samples] for testing purposes."4.toyxml" has an error in it:    <foo><bar></foo></bar>Running the example with this gives you:    Error! Expecting "bar" here: "foo></bar>"    Error! Expecting end_tag here: "<bar></foo></bar>"    -------------------------    Parsing failed    -------------------------[endsect]

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?