965 lines
26 KiB
Plaintext
965 lines
26 KiB
Plaintext
[/==============================================================================
|
|
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]
|