123 lines
4.0 KiB
Plaintext
123 lines
4.0 KiB
Plaintext
[/==============================================================================
|
|
Copyright (C) 2001-2011 Hartmut Kaiser
|
|
Copyright (C) 2001-2011 Joel de Guzman
|
|
Copyright (C) 2011 Aaron Graham
|
|
|
|
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:advance Qi advance Parser]
|
|
|
|
[heading Description]
|
|
|
|
The __qi__ `advance` is a primitive parser component allowing the parser to
|
|
skip (advance) through a specified number of iterations without performing
|
|
unnecessary work:
|
|
|
|
advance(distance)
|
|
|
|
The most obvious existing alternative to this, the `repeat` directive, will
|
|
cause the parser to advance one iterator at a time while usually performing
|
|
operations at each step. In some cases that work is unnecessary, as in the case
|
|
where large binary objects are being parsed. Take, for example, the following
|
|
binary data:
|
|
|
|
[pre
|
|
00 00 00 01 77 fc b4 51 0a b3 b7 ... 1e 60 70 b6 00 00 01 00
|
|
]
|
|
|
|
If the first 4 bytes are a little-endian 32-bit integer describing the length
|
|
of the subsequent data, but the data itself is not relevant to parsing, then the
|
|
repeat directive would cause all of the subsequent 16 MB of data to be consumed
|
|
one byte at a time while generating page faults or other superfluous I/O. If the
|
|
value is large, as it is in this case, the parser becomes very slow.
|
|
|
|
little_dword[_a = _1] >> repeat(_a)[byte_] >> little_dword...
|
|
|
|
The `advance` parser component solves this problem by performing as little work
|
|
as possible to advance the parser's iterator, and will optimize for the case of
|
|
random-access iterators by advancing directly to the desired relative iterator
|
|
position.
|
|
|
|
little_dword[_a = _1] >> advance(_a) >> little_dword...
|
|
|
|
[heading Header]
|
|
|
|
// forwards to <boost/spirit/repository/home/qi/primitive/advance.hpp>
|
|
#include <boost/spirit/repository/include/qi_advance.hpp>
|
|
|
|
[heading Synopsis]
|
|
|
|
advance(distance)
|
|
|
|
[heading Parameters]
|
|
|
|
[table
|
|
[[Parameter] [Description]]
|
|
[['distance'] [The distance that the iterator shall be advanced]]
|
|
]
|
|
|
|
[heading Attribute]
|
|
|
|
The `advance` component exposes no attribute (the exposed attribute type is
|
|
`unused_type`):
|
|
|
|
advance --> unused
|
|
|
|
[heading Example]
|
|
|
|
The following example shows simple use cases of the `advance` component. We will
|
|
illustrate its usage by generating parsers for some binary data (for the full
|
|
example code see
|
|
[@../../example/qi/advance.cpp advance.cpp])
|
|
|
|
[import ../../example/qi/advance.cpp]
|
|
|
|
[heading Prerequisites]
|
|
|
|
In addition to the main header file needed to include the core components
|
|
implemented in __qi__ we add the header file needed for the new `advance`
|
|
component.
|
|
|
|
[qi_advance_includes]
|
|
|
|
In order to make the examples below more readable we introduce or use the
|
|
following namespaces.
|
|
|
|
[qi_advance_namespaces]
|
|
|
|
[heading Setting up the Grammar]
|
|
|
|
This is a very simple grammar that recognizes several fields of a binary stream
|
|
of data. There are two fields explicitly delimited by a field indicating the
|
|
number of bytes that are spanned. They are separated by a literal string.
|
|
|
|
[qi_advance_grammar]
|
|
|
|
Note that the second binary field may either contain the number of specified
|
|
bytes, or the word "qi". If the `advance` parser component fails to advance the
|
|
specified number of bytes before reaching the end of input, it will fail and
|
|
the parser will attempt to descend into alternatives.
|
|
|
|
[heading Parsing a Correctly-delimited String of Data]
|
|
|
|
The data below is correctly delimited and will thus result in a valid parse.
|
|
Note that both random-access and bidirectional iterators are used here.
|
|
|
|
[qi_advance_example1]
|
|
|
|
[heading Parsing the Alternative Representation]
|
|
|
|
The data below is not correctly delimited, but will correctly parse because the
|
|
alternative word "qi" is available.
|
|
|
|
[qi_advance_example2]
|
|
|
|
[heading Notes]
|
|
|
|
The `advance` parser component will fail unconditionally on negative values.
|
|
It will never attempt to advance the iterator in the reverse direction.
|
|
|
|
[endsect]
|