123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964 |
- [/==============================================================================
- Copyright (C) 2001-2011 Joel de Guzman
- Copyright (C) 2001-2011 Hartmut Kaiser
- Copyright (C) 2011 Bryce Lelbach
- Copyright (C) 2016 Frank Hein, maxence business consulting gmbh
- 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:directive Parser Directives]
- This module includes different directives usable to augment and parameterize
- other parsers. It includes the `no_case`, `lexeme`, `omit`, `raw`, `repeat`,
- `matches`, `no_skip`, `skip`, `hold`, `as<T>`, `as_string` and
- `as_wstring` directives.
- [heading Module Header]
- // forwards to <boost/spirit/home/qi/directive.hpp>
- #include <boost/spirit/include/qi_directive.hpp>
- Also, see __include_structure__.
- [/------------------------------------------------------------------------------]
- [section:lexeme Parser Directive Inhibiting Skipping (`lexeme[]`)]
- [heading Description]
- The `lexeme` directive makes its subject a primitive. In a logical point
- of view, lexemes (and primitives) are minimal atomic units (e.g. words,
- numbers, identifiers, etc). These are the things that you'd normally put
- in the lexer (hinting at the term "lexeme"), but in a lexer-less world,
- you put these in a lexeme. Seeing its subject as a primitive, the
- `lexeme` directive does an initial pre-skip (as all primitives do) and
- turns off white space skipping.
- At the phrase level, the parser ignores white spaces, possibly including
- comments. Use `lexeme` in situations where you want to work at the
- character level instead of the phrase level. Parsers can be made to work
- at the character level by enclosing the pertinent parts inside the
- `lexeme` directive. For example, here's a rule that parses integers:
- integer = lexeme[ -(lit('+') | '-') >> +digit ];
- The `lexeme` directive instructs its subject parser to work on the
- character level. Without it, the `integer` rule would have allowed
- erroneous embedded white spaces in inputs such as `"1 2 345"` which will
- be parsed as `"12345"`.
- [note Keep in mind that `lexeme[]` pre-skips spaces. If this is not
- desired, use the [qi_no_skip `no_skip`] directive instead.]
- [heading Header]
- // forwards to <boost/spirit/home/qi/directive/lexeme.hpp>
- #include <boost/spirit/include/qi_lexeme.hpp>
- Also, see __include_structure__.
- [heading Namespace]
- [table
- [[Name]]
- [[`boost::spirit::lexeme // alias: boost::spirit::qi::lexeme` ]]
- ]
- [heading Model of]
- [:__unary_parser_concept__]
- [variablelist Notation
- [[`a`] [A __parser_concept__.]]
- ]
- [heading Expression Semantics]
- Semantics of an expression is defined only where it differs from, or is
- not defined in __unary_parser_concept__.
- [table
- [[Expression] [Semantics]]
- [[`lexeme[a]`] [Pre-skip and turn off white space skipping for the
- subject parser, `a` (and all its children).]]
- ]
- [heading Attributes]
- See __qi_comp_attr_notation__.
- [table
- [[Expression] [Attribute]]
- [[`lexeme[a]`]
- [``a: A --> lexeme[a]: A
- a: Unused --> lexeme[a]: Unused``]]
- ]
- [heading Complexity]
- [:The complexity is defined by the complexity of the subject parser, `a`]
- [heading Example]
- [note The test harness for the example(s) below is presented in the
- __qi_basics_examples__ section.]
- Some using declarations:
- [reference_using_declarations_lexeme]
- Simple usage of `lexeme[]`:
- [reference_lexeme]
- [endsect]
- [/------------------------------------------------------------------------------]
- [section:no_skip Parser Directive Inhibiting Skipping Without Pre-skip (`no_skip[]`)]
- [heading Description]
- The `no_skip[]` directive turns off white space skipping. The difference to
- __qi_lexeme__ is that it does not do pre-skipping in any case. Otherwise it is
- completely equivalent to the __qi_lexeme__ directive.
- [heading Header]
- // forwards to <boost/spirit/home/qi/directive/no_skip.hpp>
- #include <boost/spirit/include/qi_no_skip.hpp>
- Also, see __include_structure__.
- [heading Namespace]
- [table
- [[Name]]
- [[`boost::spirit::no_skip // alias: boost::spirit::qi::no_skip` ]]
- ]
- [heading Model of]
- [:__unary_parser_concept__]
- [variablelist Notation
- [[`a`] [A __parser_concept__.]]
- ]
- [heading Expression Semantics]
- Semantics of an expression is defined only where it differs from, or is
- not defined in __unary_parser_concept__.
- [table
- [[Expression] [Semantics]]
- [[`no_skip[a]`] [Turns off white space skipping for the
- subject parser, `a` (and all its children). This
- directive does not pre-skips.]]
- ]
- [heading Attributes]
- See __qi_comp_attr_notation__.
- [table
- [[Expression] [Attribute]]
- [[`no_skip[a]`]
- [``a: A --> no_skip[a]: A
- a: Unused --> no_skip[a]: Unused``]]
- ]
- [heading Complexity]
- [:The complexity is defined by the complexity of the subject parser, `a`]
- [heading Example]
- [note The test harness for the example(s) below is presented in the
- __qi_basics_examples__ section.]
- Some using declarations:
- [reference_using_declarations_no_skip]
- Simple usage of `no_skip[]`:
- [reference_no_skip]
- [endsect]
- [/------------------------------------------------------------------------------]
- [section:no_case Parser Directive Inhibiting Case Sensitivity (`no_case[]`)]
- [heading Description]
- The `no_case[]` directive does not consume any input. The actual
- matching is done by its subject parser. It's purpose is to force
- matching of the subject parser (and all its children) to be case
- insensitive.
- [heading Header]
- // forwards to <boost/spirit/home/qi/directive/no_case.hpp>
- #include <boost/spirit/include/qi_no_case.hpp>
- Also, see __include_structure__.
- [heading Namespace]
- [table
- [[Name]]
- [[`ns::no_case`]]
- ]
- In the table above, `ns` represents a __char_encoding_namespace__.
- [heading Model of]
- The model of `no_case` is the model of its subject parser.
- [variablelist Notation
- [[`a`] [A __parser_concept__.]]
- [[`ns`] [A __char_encoding_namespace__.]]
- ]
- [heading Expression Semantics]
- Semantics of an expression is defined only where it differs from, or is
- not defined in the subject's concept.
- [table
- [[Expression] [Semantics]]
- [[`ns::no_case[a]`] [Force matching of the subject parser, `a`
- (and all its children) to be case insensitive]]
- ]
- [heading Attributes]
- See __qi_comp_attr_notation__.
- [table
- [[Expression] [Attribute]]
- [[`ns::no_case[a]`]
- [``a: A --> ns::no_case[a]: A
- a: Unused --> ns::no_case[a]: Unused``]]
- ]
- [heading Complexity]
- [:The complexity is defined by the complexity of the subject parser, `a`]
- [heading Example]
- [note The test harness for the example(s) below is presented in the
- __qi_basics_examples__ section.]
- Some using declarations:
- [reference_using_declarations_no_case]
- Simple usage of `no_case[]`:
- [reference_no_case]
- A more sophisticated use case of `no_case[]` in conjunction with a symbol
- table (see __qi_symbols__ for more details):
- [reference_symbols_with_no_case]
- [endsect]
- [/------------------------------------------------------------------------------]
- [section:omit Parser Directive Ignoring Attribute (`omit[]`)]
- [heading Description]
- The `omit[]` ignores the attribute of its subject parser replacing it
- with __unused__.
- [heading Header]
- // forwards to <boost/spirit/home/qi/directive/omit.hpp>
- #include <boost/spirit/include/qi_omit.hpp>
- Also, see __include_structure__.
- [heading Namespace]
- [table
- [[Name]]
- [[`boost::spirit::omit // alias: boost::spirit::qi::omit` ]]
- ]
- [heading Model of]
- [:__unary_parser_concept__]
- [variablelist Notation
- [[`a`] [A __parser_concept__.]]
- ]
- [heading Expression Semantics]
- Semantics of an expression is defined only where it differs from, or is
- not defined in __unary_parser_concept__.
- [table
- [[Expression] [Semantics]]
- [[`omit[a]`] [Ignore the attribute of the subject parser, `a`]]
- ]
- [heading Attributes]
- [table
- [[Expression] [Attribute]]
- [[`omit[a]`] [__unused_type__]]
- ]
- [heading Complexity]
- [:The complexity is defined by the complexity of the subject parser, `a`]
- [heading Example]
- [note The test harness for the example(s) below is presented in the
- __qi_basics_examples__ section.]
- Some using declarations:
- [reference_using_declarations_omit]
- [reference_omit]
- [endsect]
- [/------------------------------------------------------------------------------]
- [section:raw Directive for Transduction Parsing (`raw[]`)]
- [heading Description]
- The `raw[]` disregards the attribute of its subject parser, instead
- exposing the half-open range `[first, last)` pointing to the matched
- characters from the input stream. The `raw[]` directive brings back the
- classic Spirit transduction (un-attributed) behavior for a subject
- parser.
- [heading Header]
- // forwards to <boost/spirit/home/qi/directive/raw.hpp>
- #include <boost/spirit/include/qi_raw.hpp>
- Also, see __include_structure__.
- [heading Namespace]
- [table
- [[Name]]
- [[`boost::spirit::raw // alias: boost::spirit::qi::raw` ]]
- ]
- [heading Model of]
- [:__unary_parser_concept__]
- [variablelist Notation
- [[`a`] [A __parser_concept__.]]
- [[`Iter`] [A __fwditer__ type.]]
- ]
- [heading Expression Semantics]
- Semantics of an expression is defined only where it differs from, or is
- not defined in __unary_parser_concept__.
- [table
- [[Expression] [Semantics]]
- [[`raw[a]`] [Disregard the attribute of the subject parser, `a`.
- Expose instead the half-open range `[first, last)`
- pointing to the matched characters from the input stream.]]
- ]
- [heading Attributes]
- See __qi_comp_attr_notation__.
- [table
- [[Expression] [Attribute]]
- [[`raw[a]`]
- [``a: A --> raw[a]: boost::iterator_range<Iter>
- a: Unused --> raw[a]: Unused``]]
- ]
- [note See __boost_iterator_range__.]
- [heading Complexity]
- [:The complexity is defined by the complexity of the subject parser, `a`]
- [heading Example]
- [note The test harness for the example(s) below is presented in the
- __qi_basics_examples__ section.]
- Some using declarations:
- [reference_using_declarations_raw]
- [reference_raw]
- [endsect]
- [/------------------------------------------------------------------------------]
- [section:repeat Repetition Parser Directive (`repeat[]`)]
- [heading Description]
- The `repeat[]` provides a more powerful and flexible mechanism for
- repeating a parser. There are grammars that are impractical and
- cumbersome, if not impossible, for the basic EBNF iteration syntax
- (__qi_kleene__ and the __qi_plus__) to specify. Examples:
- * A file name may have a maximum of 255 characters only.
- * A specific bitmap file format has exactly 4096 RGB color information.
- * A 256 bit binary string (1..256 1s or 0s).
- [heading Header]
- // forwards to <boost/spirit/home/qi/directive/repeat.hpp>
- #include <boost/spirit/include/qi_repeat.hpp>
- Also, see __include_structure__.
- [heading Namespace]
- [table
- [[Name]]
- [[`boost::spirit::repeat // alias: boost::spirit::qi::repeat` ]]
- [[`boost::spirit::inf // alias: boost::spirit::qi::inf` ]]
- ]
- [heading Model of]
- [:__unary_parser_concept__]
- [variablelist Notation
- [[`a`] [A __parser_concept__.]]
- [[`n`, `min`, `max`] [An `int` anything that can be converted to an
- `int`, or a __qi_lazy_argument__ that evaluates to
- anything that can be converted to an `int`.]]
- ]
- [heading Expression Semantics]
- Semantics of an expression is defined only where it differs from, or is
- not defined in __unary_parser_concept__.
- [table
- [[Expression] [Semantics]]
- [[`repeat[a]`] [Repeat `a` zero or more times. Same as __qi_kleene__.]]
- [[`repeat(n)[a]`] [Repeat `a` exactly `n` times.]]
- [[`repeat(min, max)[a]`] [Repeat `a` at least `min` times and at most `max` times.]]
- [[`repeat(min, inf)[a]`] [Repeat `a` at least `min` or more (continuing until `a`
- fails or the input is consumed).]]
- ]
- [heading Attributes]
- See __qi_comp_attr_notation__.
- [table
- [[Expression] [Attribute]]
- [[`repeat[a]`]
- [``a: A --> repeat[a]: vector<A>
- a: Unused --> repeat[a]: Unused``]]
- [[`repeat(n)[a]`]
- [``a: A --> repeat(n)[a]: vector<A>
- a: Unused --> repeat(n)[a]: Unused``]]
- [[`repeat(min, max)[a]`]
- [``a: A --> repeat(min, max)[a]: vector<A>
- a: Unused --> repeat(min, max)[a]: Unused``]]
- [[`repeat(min, inf)[a]`]
- [``a: A --> repeat(min, inf)[a]: vector<A>
- a: Unused --> repeat(min, inf)[a]: Unused``]]
- ]
- [heading Complexity]
- [:The overall complexity is defined by the complexity of its subject
- parser. The complexity of `repeat` itself is O(N), where N is the number
- of repetitions to execute.]
- [heading Example]
- [note The test harness for the example(s) below is presented in the
- __qi_basics_examples__ section.]
- Using the repeat directive, we can now write our examples above.
- Some using declarations:
- [reference_using_declarations_repeat]
- [reference_repeat]
- The Loop parsers can be dynamic. Consider the parsing of a binary file
- of Pascal-style length prefixed string, where the first byte determines
- the length of the incoming string. Here's a sample input:
- [:__pascal_string__]
- [reference_repeat_pascal]
- [endsect]
- [/------------------------------------------------------------------------------]
- [section:matches Directive Testing if Parser Succeeded (`matches[]`)]
- [heading Description]
- The `matches[]` directive executes the embedded parser and returns whether it
- succeeded matching.
- [heading Header]
- // forwards to <boost/spirit/home/qi/directive/matches.hpp>
- #include <boost/spirit/include/qi_matches.hpp>
- Also, see __include_structure__.
- [heading Namespace]
- [table
- [[Name]]
- [[`boost::spirit::matches // alias: boost::spirit::qi::matches` ]]
- ]
- [heading Model of]
- [:__unary_parser_concept__]
- [variablelist Notation
- [[`a`] [A __parser_concept__.]]
- ]
- [heading Expression Semantics]
- Semantics of an expression is defined only where it differs from, or is
- not defined in __unary_parser_concept__.
- [table
- [[Expression] [Semantics]]
- [[`matches[a]`] [Execute the subject parser `a`, and return as its
- attribute whether it succeeded. The directive itself
- does always succeed.]]
- ]
- [heading Attributes]
- [table
- [[Expression] [Attribute]]
- [[`matches[a]`] [`bool`]]
- ]
- [heading Complexity]
- [:The complexity is defined by the complexity of the subject parser, `a`]
- [heading Example]
- [note The test harness for the example(s) below is presented in the
- __qi_basics_examples__ section.]
- Some using declarations:
- [reference_using_declarations_matches]
- [reference_matches]
- [endsect]
- [/------------------------------------------------------------------------------]
- [section:skip Parser Directive Re-Establishing Skipping (`skip[]`)]
- [heading Description]
- The `skip` directive is the inverse of __qi_lexeme__ or [qi_no_skip `no_skip`].
- While the __qi_lexeme__ directive turns off white space
- skipping, the `skip` directive turns it on again. This is simply done by
- wrapping the parts inside the `skip` directive:
- skip[a]
- It is also possible to supply a skip parser to the `skip` directive:
- skip(p)[a] // Use `p` as a skipper for parsing `a`
- This makes it possible to:
- * Perform localized phrase level parsing while doing character level parsing.
- * Replace the current skipper anywhere with an entirely different
- skipper while doing phrase level parsing.
- [heading Header]
- // forwards to <boost/spirit/home/qi/directive/skip.hpp>
- #include <boost/spirit/include/qi_skip.hpp>
- Also, see __include_structure__.
- [heading Namespace]
- [table
- [[Name]]
- [[`boost::spirit::skip // alias: boost::spirit::qi::skip` ]]
- ]
- [heading Model of]
- [:__unary_parser_concept__]
- [variablelist Notation
- [[`a`] [A __parser_concept__.]]
- ]
- [heading Expression Semantics]
- Semantics of an expression is defined only where it differs from, or is
- not defined in __unary_parser_concept__.
- [table
- [[Expression] [Semantics]]
- [[`skip[a]`] [Re-establish the skipper that got inhibited by lexeme or no_skip]]
- [[`skip(p)[a]`] [Use `p` as a skipper for parsing `a`]]
- ]
- [heading Attributes]
- See __qi_comp_attr_notation__.
- [table
- [[Expression] [Attribute]]
- [[`skip[a]`]
- [``a: A --> skip[a]: A
- a: Unused --> skip[a]: Unused``]]
- [[`skip(p)[a]`]
- [``a: A --> skip(p)[a]: A
- a: Unused --> skip(p)[a]: Unused``]]
- ]
- [heading Complexity]
- [:The complexity is defined by the complexity of the subject parser, `a`]
- [heading Example]
- [note The test harness for the example(s) below is presented in the
- __qi_basics_examples__ section.]
- Some using declarations:
- [reference_using_declarations_skip]
- Simple usage of `skip[]`:
- [reference_skip]
- [endsect]
- [/------------------------------------------------------------------------------]
- [section:hold Parser Directive for Attribute Commit/Rollback (`hold[]`)]
- [heading Description]
- The `hold[]` directive helps managing attributes, mainly for alternative
- parsers. It instantiates a new attribute instance for the embedded parser. The
- value of that attribute instance is copied to the outer attribute if the
- embedded parser succeeds and it is discarded otherwise. Alternative parsers
- normally do not rollback changes made to the outer attribute by an failed
- alternative. Wrapping those alternatives into a `hold[]` directive ensures that
- only the succeeding alternative gets to modify the attribute.
- [heading Header]
- // forwards to <boost/spirit/home/qi/directive/hold.hpp>
- #include <boost/spirit/include/qi_hold.hpp>
- Also, see __include_structure__.
- [heading Namespace]
- [table
- [[Name]]
- [[`boost::spirit::hold // alias: boost::spirit::qi::hold` ]]
- ]
- [heading Model of]
- [:__unary_parser_concept__]
- [variablelist Notation
- [[`a`] [A __parser_concept__.]]
- ]
- [heading Expression Semantics]
- Semantics of an expression is defined only where it differs from, or is
- not defined in __unary_parser_concept__.
- [table
- [[Expression] [Semantics]]
- [[`hold[a]`] [Create a new attribute instance while parsing `a`,
- copying the result to the outer attribute only after
- `a` succeeds.]]
- ]
- [heading Attributes]
- See __qi_comp_attr_notation__.
- [table
- [[Expression] [Attribute]]
- [[`hold[a]`]
- [``a: A --> hold[a]: A
- a: Unused --> hold[a]: Unused``]]
- ]
- [note The `hold[]` directive uses `swap()` to implement the rollback/commit
- semantics for the attribute. For this reason the attribute type needs to
- to be usable with `boost::swap` (needs to either define a proper overload
- for `swap(attribute_type&, attribute_type&)` or expose a member function
- `attribute_type::swap(attribute_type&)`.]
- [heading Complexity]
- [:The complexity is defined by the complexity of the subject parser, `a`]
- [heading Example]
- [note The test harness for the example(s) below is presented in the
- __qi_basics_examples__ section.]
- Some using declarations:
- [reference_using_declarations_hold]
- [reference_hold]
- [endsect]
- [/------------------------------------------------------------------------------]
- [section:as Parser Directives Forcing Atomic Assignment (`as<T>, as_string[], as_wstring[]`)]
- [heading Description]
- The `as<T>` class forces the atomic assignment of it's subject's synthesized
- attribute. Usually, repetitive parsers (such as __qi_kleene__, etc) or
- sequences exposing a `vector<A>` will assign elements to the container supplied
- as their synthesized attribute by calling __customize_push_back_container__
- repeatedly. In some cases, this may be undesirable. The `as<T>` class creates a
- directive that will pass a temporary object of type `T` to it's subject. If the
- subject parser passes, the temporary object will be assigned to the directive's
- supplied attribute with a single call to __customize_assign_to__. If the
- subject parser fails, the directive's attribute is not mutated.
- [note `T` is required to be a container type. If __customize_is_container__
- does not return true for `T`, a compile-time error will occur.]
- [note The `as<T>` implicitly causes commit/rollback semantics
- similar in nature to the __qi_hold__ directive.]
- [caution The __customize_assign_to__ customization point may end up
- using __customize_push_back_container__ to assign the temporary object to the
- supplied attribute by default, depending on the types involved. Use the
- interface described in __sec_customization_points__ to manipulate the semantics
- of this assignment operation.]
- [heading Header]
- // forwards to <boost/spirit/home/qi/directive/as.hpp>
- #include <boost/spirit/include/qi_as.hpp>
- Also, see __include_structure__.
- [heading Namespace]
- [table
- [[Name]]
- [[`boost::spirit::as // alias: boost::spirit::qi::as` ]]
- [[`boost::spirit::as_string // alias: boost::spirit::qi::as_string` ]]
- [[`boost::spirit::as_wstring // alias: boost::spirit::qi::as_wstring` ]]
- ]
- [heading Synopsis]
- template <typename T>
- struct as;
- [heading Template parameters]
- [table
- [[Parameter] [Description] [Default]]
- [[`T`] [A container type. [none]]
- ]
- [heading Model of]
- [:__unary_parser_concept__]
- [variablelist Notation
- [[`a`] [A __parser_concept__.]]
- [[`t`] [A container of type `T`.]]
- [[`attr`] [The attribute supplied to the directive.]]
- ]
- [heading Expression Semantics]
- Semantics of an expression is defined only where it differs from, or is
- not defined in __unary_parser_concept__.
- [table
- [[Expression] [Semantics]]
- [[`as<T>()[a]`] [Create a temporary object of `t` of type `T`,
- and invoke the subject parser `a`, supplying
- `t` as an attribute. If the subject parser
- passes, assign `t` to `attr`.]]
- [[`as_string[a]`] [Equivalent to `as<std::string>()[a]`]]
- [[`as_wstring[a]`] [Equivalent to `as<std::wstring>()[a]`]]
- ]
- [heading Attributes]
- See __qi_comp_attr_notation__.
- [table
- [[Expression] [Attribute]]
- [[`as<T>()[a]`] [`a: A --> as<T>()[a]: T`]]
- ]
- [heading Complexity]
- [:The complexity is defined by the complexity of the subject parser, `a`, and
- the complexity of the assignment of the container `t` to the supplied
- attribute `attr`.]
- [heading Example]
- [note The test harness for the example(s) below is presented in the
- __qi_basics_examples__ section.]
- Some using declarations:
- [reference_using_declarations_as]
- Simple usage of `as<T>`, `as_string` and `as_wstring`:
- [reference_as]
- [endsect]
- [/------------------------------------------------------------------------------]
- [section:expect Expectation Directive (`expect[]`)]
- [heading Description]
- There are occasions in which it is expected that the input must match a
- particular parser or the input is invalid. Such cases generally arise
- after matching a portion of a grammar, such that the context is fully
- known. In such a situation, failure to match should result in an
- exception. For example, when parsing an e-mail address, a name, an "@"
- and a domain name must be matched or the address is invalid.
- The expect directive requires that the argument parser matches
- the input or an exception is emitted. Using on_error(), that exception
- can be handled by calling a handler with the context at which the
- parsing failed can be reported.
- The expect directive parses an operand parser expression which may be a
- single parser or a complex parser expression like a sequence.
- Single parser:
- expect[a]
- Parser expression:
- expect[a >> b >> ...]
- In the latter case while the plain __qi_sequence__ simply returns a no-match
- (returns `false`) when one of the elements fail, the expect directive
- throws an __qi_expectation_failure__`<Iter>` if any of the parsers
- (even the first parser of a sequence) fails to match.
- [note Spirit provides two ways to handle expectation failures by throwing an expectation exception.
- Use the __qi_expect__ if you do not need an exception to be thrown when the first parser of a sequence fails. ]
- [heading Header]
- // forwards to <boost/spirit/home/qi/directive/expect.hpp>
- #include <boost/spirit/include/qi_expect.hpp>
- Also, see __include_structure__.
- [heading Model of]
- [:__unary_parser_concept__]
- [variablelist Notation
- [[`a`] [A __parser_concept__]]
- [[`Iter`] [A __fwditer__ type]]
- ]
- [heading Expectation Failure]
- When the operand parser fails to match an `expectation_failure<Iter>` is thrown:
- template <typename Iter>
- struct expectation_failure : std::runtime_error
- {
- Iter first; // [first, last) iterator pointing
- Iter last; // to the error position in the input.
- __info__ what_; // Information about the nature of the error.
- };
- [heading Expression Semantics]
- Semantics of an expression is defined only where it differs from, or is not
- defined in __unary_parser_concept__.
- [table
- [[Expression] [Semantics]]
- [[`expect[a]`] [Match `a`. If `a` fails, throw an `expectation_failure<Iter>`]]
- ]
- [heading Attributes]
- See __qi_comp_attr_notation__.
- [table
- [[Expression] [Attribute]]
- [[`expect[a]`]
- [``a: A --> expect[a]: A
- a: Unused --> expect[a] : Unused``]]
- ]
- [heading Complexity]
- [:The overall complexity of the expectation parser is defined by the
- complexity of it's argument parser. The complexity of the expect directive itself is O(1).]
- [heading Example]
- [note The test harness for the example(s) below is presented in the
- __qi_basics_examples__ section.]
- Some using declarations:
- [reference_using_declarations_expectd]
- [reference_expectd]
- [endsect]
- [endsect]
|