advance.qbk 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. [/==============================================================================
  2. Copyright (C) 2001-2011 Hartmut Kaiser
  3. Copyright (C) 2001-2011 Joel de Guzman
  4. Copyright (C) 2011 Aaron Graham
  5. Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. ===============================================================================/]
  8. [section:advance Qi advance Parser]
  9. [heading Description]
  10. The __qi__ `advance` is a primitive parser component allowing the parser to
  11. skip (advance) through a specified number of iterations without performing
  12. unnecessary work:
  13. advance(distance)
  14. The most obvious existing alternative to this, the `repeat` directive, will
  15. cause the parser to advance one iterator at a time while usually performing
  16. operations at each step. In some cases that work is unnecessary, as in the case
  17. where large binary objects are being parsed. Take, for example, the following
  18. binary data:
  19. [pre
  20. 00 00 00 01 77 fc b4 51 0a b3 b7 ... 1e 60 70 b6 00 00 01 00
  21. ]
  22. If the first 4 bytes are a little-endian 32-bit integer describing the length
  23. of the subsequent data, but the data itself is not relevant to parsing, then the
  24. repeat directive would cause all of the subsequent 16 MB of data to be consumed
  25. one byte at a time while generating page faults or other superfluous I/O. If the
  26. value is large, as it is in this case, the parser becomes very slow.
  27. little_dword[_a = _1] >> repeat(_a)[byte_] >> little_dword...
  28. The `advance` parser component solves this problem by performing as little work
  29. as possible to advance the parser's iterator, and will optimize for the case of
  30. random-access iterators by advancing directly to the desired relative iterator
  31. position.
  32. little_dword[_a = _1] >> advance(_a) >> little_dword...
  33. [heading Header]
  34. // forwards to <boost/spirit/repository/home/qi/primitive/advance.hpp>
  35. #include <boost/spirit/repository/include/qi_advance.hpp>
  36. [heading Synopsis]
  37. advance(distance)
  38. [heading Parameters]
  39. [table
  40. [[Parameter] [Description]]
  41. [['distance'] [The distance that the iterator shall be advanced]]
  42. ]
  43. [heading Attribute]
  44. The `advance` component exposes no attribute (the exposed attribute type is
  45. `unused_type`):
  46. advance --> unused
  47. [heading Example]
  48. The following example shows simple use cases of the `advance` component. We will
  49. illustrate its usage by generating parsers for some binary data (for the full
  50. example code see
  51. [@../../example/qi/advance.cpp advance.cpp])
  52. [import ../../example/qi/advance.cpp]
  53. [heading Prerequisites]
  54. In addition to the main header file needed to include the core components
  55. implemented in __qi__ we add the header file needed for the new `advance`
  56. component.
  57. [qi_advance_includes]
  58. In order to make the examples below more readable we introduce or use the
  59. following namespaces.
  60. [qi_advance_namespaces]
  61. [heading Setting up the Grammar]
  62. This is a very simple grammar that recognizes several fields of a binary stream
  63. of data. There are two fields explicitly delimited by a field indicating the
  64. number of bytes that are spanned. They are separated by a literal string.
  65. [qi_advance_grammar]
  66. Note that the second binary field may either contain the number of specified
  67. bytes, or the word "qi". If the `advance` parser component fails to advance the
  68. specified number of bytes before reaching the end of input, it will fail and
  69. the parser will attempt to descend into alternatives.
  70. [heading Parsing a Correctly-delimited String of Data]
  71. The data below is correctly delimited and will thus result in a valid parse.
  72. Note that both random-access and bidirectional iterators are used here.
  73. [qi_advance_example1]
  74. [heading Parsing the Alternative Representation]
  75. The data below is not correctly delimited, but will correctly parse because the
  76. alternative word "qi" is available.
  77. [qi_advance_example2]
  78. [heading Notes]
  79. The `advance` parser component will fail unconditionally on negative values.
  80. It will never attempt to advance the iterator in the reverse direction.
  81. [endsect]