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 + -
显示快捷键?