summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/spirit/classic
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/spirit/classic')
-rw-r--r--src/boost/libs/spirit/classic/change_log.html294
-rw-r--r--src/boost/libs/spirit/classic/example/Jamfile300
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/ast_calc.cpp159
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/bind.cpp126
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/boiler_plate.cpp97
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/calc_debug.cpp199
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/calc_plain.cpp129
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/comments.cpp232
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/complex_number.cpp103
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/distinct/distinct_parser.cpp68
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/distinct/distinct_parser_dynamic.cpp64
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/error_handling.cpp55
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/error_reporting.cpp114
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/file_parser.cpp89
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/full_calc.cpp188
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/functor_parser.cpp160
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/list_parser.cpp233
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/matching_tags.cpp115
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/more_calculators/ast_calc2.cpp180
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/more_calculators/calc_with_variables.cpp261
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/more_calculators/phoenix_subrule_calc.cpp142
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/more_calculators/primitive_calc.cpp96
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/more_calculators/rpn_calc.cpp163
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/more_calculators/vmachine_calc.cpp275
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/no_actions.cpp56
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/number_list.cpp93
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/parse_tree_calc1.cpp207
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/parser_context.cpp51
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/phoenix_calc.cpp132
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.cpp173
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.err18
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.err28
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.err38
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.ok8
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/refactoring.cpp214
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/regular_expression.cpp110
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/roman_numerals.cpp189
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/stuff_vector.cpp114
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/stuff_vector2.cpp125
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/subrule_calc.cpp140
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/sum.cpp92
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/thousand_separated.cpp133
-rw-r--r--src/boost/libs/spirit/classic/example/fundamental/tree_calc_grammar.hpp76
-rw-r--r--src/boost/libs/spirit/classic/example/intermediate/ipv4.cpp304
-rw-r--r--src/boost/libs/spirit/classic/example/intermediate/ipv4_opt.cpp213
-rw-r--r--src/boost/libs/spirit/classic/example/intermediate/lazy_parser.cpp126
-rw-r--r--src/boost/libs/spirit/classic/example/intermediate/parameters.cpp216
-rw-r--r--src/boost/libs/spirit/classic/example/intermediate/regex_convert.cpp177
-rw-r--r--src/boost/libs/spirit/classic/example/intermediate/simple_xml/actions.hpp68
-rw-r--r--src/boost/libs/spirit/classic/example/intermediate/simple_xml/driver.cpp43
-rw-r--r--src/boost/libs/spirit/classic/example/intermediate/simple_xml/tag.cpp46
-rw-r--r--src/boost/libs/spirit/classic/example/intermediate/simple_xml/tag.hpp33
-rw-r--r--src/boost/libs/spirit/classic/example/intermediate/simple_xml/xml_g.hpp186
-rw-r--r--src/boost/libs/spirit/classic/example/techniques/dynamic_rule.cpp58
-rw-r--r--src/boost/libs/spirit/classic/example/techniques/epsilon.cpp68
-rw-r--r--src/boost/libs/spirit/classic/example/techniques/multiple_scanners.cpp53
-rw-r--r--src/boost/libs/spirit/classic/example/techniques/nabialek.cpp94
-rw-r--r--src/boost/libs/spirit/classic/example/techniques/no_rules/no_rule1.cpp51
-rw-r--r--src/boost/libs/spirit/classic/example/techniques/no_rules/no_rule2.cpp58
-rw-r--r--src/boost/libs/spirit/classic/example/techniques/no_rules/no_rule3.cpp86
-rw-r--r--src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/opaque_rule_parser.cpp67
-rw-r--r--src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/rule_parser_1_1.cpp103
-rw-r--r--src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/rule_parser_1_2.cpp100
-rw-r--r--src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/rule_parser_2_1.cpp107
-rw-r--r--src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/rule_parser_2_2.cpp142
-rw-r--r--src/boost/libs/spirit/classic/example/techniques/right_recursion.cpp90
-rw-r--r--src/boost/libs/spirit/classic/example/techniques/typeof.cpp41
-rw-r--r--src/boost/libs/spirit/classic/index.html263
-rw-r--r--src/boost/libs/spirit/classic/meta/libraries.json18
-rw-r--r--src/boost/libs/spirit/classic/phoenix/example/Jamfile79
-rw-r--r--src/boost/libs/spirit/classic/phoenix/example/fundamental/closures.cpp66
-rw-r--r--src/boost/libs/spirit/classic/phoenix/example/fundamental/sample10.cpp525
-rw-r--r--src/boost/libs/spirit/classic/phoenix/example/fundamental/sample2.cpp31
-rw-r--r--src/boost/libs/spirit/classic/phoenix/example/fundamental/sample3.cpp43
-rw-r--r--src/boost/libs/spirit/classic/phoenix/example/fundamental/sample4.cpp36
-rw-r--r--src/boost/libs/spirit/classic/phoenix/example/fundamental/sample5.cpp43
-rw-r--r--src/boost/libs/spirit/classic/phoenix/example/fundamental/sample6.cpp88
-rw-r--r--src/boost/libs/spirit/classic/phoenix/example/fundamental/sample7.cpp275
-rw-r--r--src/boost/libs/spirit/classic/phoenix/example/fundamental/sample8.cpp284
-rw-r--r--src/boost/libs/spirit/classic/phoenix/example/fundamental/sample9.cpp311
-rw-r--r--src/boost/libs/spirit/classic/phoenix/index.html180
-rw-r--r--src/boost/libs/spirit/classic/phoenix/test/Jamfile81
-rw-r--r--src/boost/libs/spirit/classic/phoenix/test/binary_tests.cpp98
-rw-r--r--src/boost/libs/spirit/classic/phoenix/test/binders_tests.cpp123
-rw-r--r--src/boost/libs/spirit/classic/phoenix/test/functors_tests.cpp95
-rw-r--r--src/boost/libs/spirit/classic/phoenix/test/iostream_tests.cpp86
-rw-r--r--src/boost/libs/spirit/classic/phoenix/test/mixed_binary_tests.cpp50
-rw-r--r--src/boost/libs/spirit/classic/phoenix/test/more_expressions_tests.cpp104
-rw-r--r--src/boost/libs/spirit/classic/phoenix/test/new_test.cpp46
-rw-r--r--src/boost/libs/spirit/classic/phoenix/test/primitives_tests.cpp42
-rw-r--r--src/boost/libs/spirit/classic/phoenix/test/runtest.sh25
-rw-r--r--src/boost/libs/spirit/classic/phoenix/test/statements_tests.cpp165
-rw-r--r--src/boost/libs/spirit/classic/phoenix/test/stl_tests.cpp95
-rw-r--r--src/boost/libs/spirit/classic/phoenix/test/tuples_tests.cpp57
-rw-r--r--src/boost/libs/spirit/classic/phoenix/test/unary_tests.cpp47
-rw-r--r--src/boost/libs/spirit/classic/test/Jamfile204
-rw-r--r--src/boost/libs/spirit/classic/test/actor/action_tests.cpp26
-rw-r--r--src/boost/libs/spirit/classic/test/actor/action_tests.hpp33
-rw-r--r--src/boost/libs/spirit/classic/test/actor/assign_key_test.cpp116
-rw-r--r--src/boost/libs/spirit/classic/test/actor/assign_test.cpp65
-rw-r--r--src/boost/libs/spirit/classic/test/actor/clear_test.cpp47
-rw-r--r--src/boost/libs/spirit/classic/test/actor/decrement_test.cpp40
-rw-r--r--src/boost/libs/spirit/classic/test/actor/erase_at_test.cpp54
-rw-r--r--src/boost/libs/spirit/classic/test/actor/increment_test.cpp42
-rw-r--r--src/boost/libs/spirit/classic/test/actor/insert_at_test.cpp109
-rw-r--r--src/boost/libs/spirit/classic/test/actor/insert_key_test.cpp116
-rw-r--r--src/boost/libs/spirit/classic/test/actor/push_back_test.cpp56
-rw-r--r--src/boost/libs/spirit/classic/test/actor/push_front_test.cpp53
-rw-r--r--src/boost/libs/spirit/classic/test/actor/swap_test.cpp47
-rw-r--r--src/boost/libs/spirit/classic/test/actor/unit_test.cpp10
-rw-r--r--src/boost/libs/spirit/classic/test/ast_calc_tests.cpp279
-rw-r--r--src/boost/libs/spirit/classic/test/bug_000008.cpp115
-rw-r--r--src/boost/libs/spirit/classic/test/bug_fixes.cpp365
-rw-r--r--src/boost/libs/spirit/classic/test/char_strings_test.cpp32
-rw-r--r--src/boost/libs/spirit/classic/test/char_strings_test_fail.cpp19
-rw-r--r--src/boost/libs/spirit/classic/test/chset_tests.cpp331
-rw-r--r--src/boost/libs/spirit/classic/test/closure_tests.cpp157
-rw-r--r--src/boost/libs/spirit/classic/test/confix_tests.cpp60
-rw-r--r--src/boost/libs/spirit/classic/test/custom_real_parser.cpp33
-rw-r--r--src/boost/libs/spirit/classic/test/directives_tests.cpp189
-rw-r--r--src/boost/libs/spirit/classic/test/distinct_tests.cpp248
-rw-r--r--src/boost/libs/spirit/classic/test/epsilon_tests.cpp136
-rw-r--r--src/boost/libs/spirit/classic/test/escape_char_parser_tests.cpp194
-rw-r--r--src/boost/libs/spirit/classic/test/exception_tests.cpp49
-rw-r--r--src/boost/libs/spirit/classic/test/file_iterator_tests.cpp186
-rw-r--r--src/boost/libs/spirit/classic/test/fixed_size_queue_fail_tests.cpp64
-rw-r--r--src/boost/libs/spirit/classic/test/fixed_size_queue_tests.cpp137
-rw-r--r--src/boost/libs/spirit/classic/test/for_p_as_parser_tests.cpp52
-rw-r--r--src/boost/libs/spirit/classic/test/for_tests.cpp192
-rw-r--r--src/boost/libs/spirit/classic/test/fundamental_tests.cpp94
-rw-r--r--src/boost/libs/spirit/classic/test/grammar_def_test.cpp85
-rw-r--r--src/boost/libs/spirit/classic/test/grammar_mt_tests.cpp318
-rw-r--r--src/boost/libs/spirit/classic/test/grammar_multi_instance_tst.cpp50
-rw-r--r--src/boost/libs/spirit/classic/test/grammar_tests.cpp157
-rw-r--r--src/boost/libs/spirit/classic/test/group_match_bug.cpp49
-rw-r--r--src/boost/libs/spirit/classic/test/if_p_as_parser_tests.cpp39
-rw-r--r--src/boost/libs/spirit/classic/test/if_p_int_as_condition_test.cpp87
-rw-r--r--src/boost/libs/spirit/classic/test/if_tests.cpp250
-rw-r--r--src/boost/libs/spirit/classic/test/impl/sstream.hpp46
-rw-r--r--src/boost/libs/spirit/classic/test/impl/string_length.hpp30
-rw-r--r--src/boost/libs/spirit/classic/test/impl/var.hpp34
-rw-r--r--src/boost/libs/spirit/classic/test/lazy_tests.cpp27
-rw-r--r--src/boost/libs/spirit/classic/test/loops_tests.cpp118
-rw-r--r--src/boost/libs/spirit/classic/test/match_tests.cpp175
-rw-r--r--src/boost/libs/spirit/classic/test/mix_and_match_trees.cpp82
-rw-r--r--src/boost/libs/spirit/classic/test/multi_pass_compile_tests.cpp61
-rw-r--r--src/boost/libs/spirit/classic/test/multi_pass_tests.cpp765
-rw-r--r--src/boost/libs/spirit/classic/test/negated_eps_p_test.cpp39
-rw-r--r--src/boost/libs/spirit/classic/test/numerics_tests.cpp313
-rw-r--r--src/boost/libs/spirit/classic/test/operators_tests.cpp164
-rw-r--r--src/boost/libs/spirit/classic/test/owi_mt_tests.cpp242
-rw-r--r--src/boost/libs/spirit/classic/test/owi_st_tests.cpp88
-rw-r--r--src/boost/libs/spirit/classic/test/parametric_tests.cpp185
-rw-r--r--src/boost/libs/spirit/classic/test/parser_context_test.cpp24
-rw-r--r--src/boost/libs/spirit/classic/test/parser_traits_tests.cpp285
-rw-r--r--src/boost/libs/spirit/classic/test/pch.hpp15
-rw-r--r--src/boost/libs/spirit/classic/test/position_iterator_tests.cpp583
-rw-r--r--src/boost/libs/spirit/classic/test/post_skips.cpp113
-rw-r--r--src/boost/libs/spirit/classic/test/primitives_tests.cpp135
-rw-r--r--src/boost/libs/spirit/classic/test/repeat_ast_tests.cpp95
-rw-r--r--src/boost/libs/spirit/classic/test/rule_tests.cpp264
-rw-r--r--src/boost/libs/spirit/classic/test/scanner_tests.cpp140
-rw-r--r--src/boost/libs/spirit/classic/test/scanner_value_type_tests.cpp139
-rw-r--r--src/boost/libs/spirit/classic/test/scoped_lock_tests.cpp61
-rw-r--r--src/boost/libs/spirit/classic/test/select_p_with_rule.cpp89
-rw-r--r--src/boost/libs/spirit/classic/test/sf_bug_720917.cpp115
-rw-r--r--src/boost/libs/spirit/classic/test/shortest_alternative_tests.cpp58
-rw-r--r--src/boost/libs/spirit/classic/test/subrule_tests.cpp92
-rw-r--r--src/boost/libs/spirit/classic/test/switch_problem.cpp107
-rw-r--r--src/boost/libs/spirit/classic/test/switch_tests_eps_default.cpp327
-rw-r--r--src/boost/libs/spirit/classic/test/switch_tests_general_def.cpp343
-rw-r--r--src/boost/libs/spirit/classic/test/switch_tests_single.cpp350
-rw-r--r--src/boost/libs/spirit/classic/test/switch_tests_wo_default.cpp202
-rw-r--r--src/boost/libs/spirit/classic/test/symbols_add_null.cpp79
-rw-r--r--src/boost/libs/spirit/classic/test/symbols_find_null.cpp35
-rw-r--r--src/boost/libs/spirit/classic/test/symbols_tests.cpp318
-rw-r--r--src/boost/libs/spirit/classic/test/threads_disabled_compile.cpp19
-rw-r--r--src/boost/libs/spirit/classic/test/traverse_tests.cpp517
-rw-r--r--src/boost/libs/spirit/classic/test/tree_tests.cpp383
-rw-r--r--src/boost/libs/spirit/classic/test/tree_to_xml.cpp186
-rw-r--r--src/boost/libs/spirit/classic/test/typeof_support/typeof_actor.cpp13
-rw-r--r--src/boost/libs/spirit/classic/test/typeof_support/typeof_attribute.cpp13
-rw-r--r--src/boost/libs/spirit/classic/test/typeof_support/typeof_core.cpp13
-rw-r--r--src/boost/libs/spirit/classic/test/typeof_support/typeof_debug.cpp15
-rw-r--r--src/boost/libs/spirit/classic/test/typeof_support/typeof_dynamic.cpp17
-rw-r--r--src/boost/libs/spirit/classic/test/typeof_support/typeof_error_handling.cpp13
-rw-r--r--src/boost/libs/spirit/classic/test/typeof_support/typeof_iterator.cpp13
-rw-r--r--src/boost/libs/spirit/classic/test/typeof_support/typeof_symbols.cpp13
-rw-r--r--src/boost/libs/spirit/classic/test/typeof_support/typeof_tree.cpp15
-rw-r--r--src/boost/libs/spirit/classic/test/typeof_support/typeof_utility.cpp18
-rw-r--r--src/boost/libs/spirit/classic/test/while_p_as_parser_tests.cpp42
-rw-r--r--src/boost/libs/spirit/classic/test/while_tests.cpp202
192 files changed, 24480 insertions, 0 deletions
diff --git a/src/boost/libs/spirit/classic/change_log.html b/src/boost/libs/spirit/classic/change_log.html
new file mode 100644
index 00000000..8ed8eed5
--- /dev/null
+++ b/src/boost/libs/spirit/classic/change_log.html
@@ -0,0 +1,294 @@
+<html>
+<head>
+<title>Spirit Change Log</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" href="doc/theme/style.css" type="text/css">
+</head>
+
+<body>
+
+<h2>Spirit Change Log</h2>
+<h2>1.8.11</h2>
+<ul>
+ <li>Fixed <tt>position_iterator</tt> forming reference to local when the
+ underlying iterator dereference operator returns a non-reference type.
+ <a href="https://github.com/boostorg/spirit/pull/422">PR#422</a>
+ <a href="https://svn.boost.org/trac10/ticket/9737">TRAC#9737</a></li>
+ <li>Removed use of deprecated <tt>boost/detail/iterator.hpp</tt> header.
+ <a href="https://github.com/boostorg/spirit/pull/432">GH#432</a></li>
+</ul>
+<h2>1.8.10</h2>
+<ul>
+ <li>Missing visibility mark on exception types.
+ <a href="https://github.com/boostorg/spirit/pull/409">GH#409</a></li>
+</ul>
+<h2>1.8.9</h2>
+<ul>
+ <li>Fixed a regression introduced in
+ <a href="https://github.com/boostorg/spirit/pull/336">GH#336</a>.
+ <a href="https://github.com/boostorg/spirit/pull/386">GH#386</a></li>
+ <li>Minor code improvements.
+ <a href="https://github.com/boostorg/spirit/pull/367">GH#367</a></li>
+</ul>
+<h2>1.8.8</h2>
+<ul>
+ <li>Fixed <tt>remove_reference</tt> usage without a namespace in Phoenix.
+ <a href="https://github.com/boostorg/spirit/pull/274">GH#274</a></li>
+ <li>Fixed <tt>std::complex</tt> usage without the include.
+ <a href="https://github.com/boostorg/spirit/pull/273">GH#273</a></li>
+ <li>Fixed compilation of <tt>match&lt;T&amp;&gt;</tt>.
+ <a href="https://github.com/boostorg/spirit/pull/275">GH#275</a></li>
+ <li>Fixed compilation with <tt>BOOST_DISABLE_THREADS</tt> defined.
+ <a href="https://github.com/boostorg/spirit/pull/323">GH#323</a>
+ <a href="https://svn.boost.org/trac10/ticket/12639">#12639</a></li>
+ <li>Increment scanner through iterator policy.
+ <a href="https://github.com/boostorg/spirit/pull/336">GH#336</a>
+ <a href="https://svn.boost.org/trac10/ticket/7371">TRAC#7371</a></li>
+ <li>Removed deprecated in C++17 <tt>std::iterator</tt> usage.
+ <a href="https://github.com/boostorg/spirit/pull/345">GH#345</a></li>
+</ul>
+<h2>1.8.7</h2>
+<ul>
+ <li>Integrated the Spirit V1.8.x code base with Spirit V2. Spirit V1.8.x is
+ now called
+ <strong>Spirit Classic.</strong> Even if the directory
+ structure has changed (the
+ <strong>Spirit Classic</strong> headers are now moved to the
+ '$BOOST_ROOT/boost/spirit/home/classic' directory), we created forwarding
+ headers allowing to compile existing applications without any change.
+ These forwarding headers are deprecated, though, which will result in
+ corresponding warnings generated for each of the headers. The forwarding
+ headers are expected to be removed in the future.
+ <br />
+ The recommended way of using Spirit Classic is now to include header
+ files from the directory '$BOOST_ROOT/boost/spirit/include'. All files of
+ <strong>Spirit Classic</strong>
+ have now a 'classic_' prefixed to their name. For example the include
+ <br/>
+ <br><code>&nbsp;&nbsp;#include &lt;boost/spirit/core/core.hpp&gt;</code><br/>
+ <br/>
+ now should be written as:
+ <br/>
+ <br/><code>&nbsp;&nbsp;#include &lt;boost/spirit/include/classic_core.hpp&gt;</code><br/>
+ <br/>
+ To avoid namespace conflicts with the new Spirit V2 library we moved <strong>Spirit
+ Classic</strong> into the <tt>namespace boost::spirit::classic</tt>. This change will be automatically&nbsp;deactivated whenever the deprecated include files are
+ being used. This ensures full backwards compatibility for existing applications.
+ <br />
+ For more details about this change please consult the documentation.</li>
+</ul>
+<h2>1.8.6</h2>
+<ul>
+ <li>Fixed a integer overflow bug preventing to fail parsing on certain large integers. This bug was reported and fixed by Michael Andersen Nexø</li>
+</ul>
+<h2>1.8.5</h2>
+<ul>
+ <li>For performance reasons, leaf_node_d/token_node_d have been changed to implicit lexems that create leaf nodes in one shot. The old token_node_d is still available and called reduced_node_d, now.</li>
+ <li>It's now possible to phoenix::bind (version 1) symbols::add.</li>
+</ul>
+<h2>1.8.4</h2>
+<ul>
+ <li>Fixed no_actions bug where no_action is applied recursively.</li>
+ <li>Fixed the regex_p parser for Boost &gt;= V1.33.0 </li>
+ <li>Implemented a workaround for namespace issues VC++ has with Spirit's file_iterators</li>
+ <li>Fixed bug in tree match policies that prevented using gen_pt/ast_node_d,
+ <a href="http://article.gmane.org/gmane.comp.parsers.spirit.general/9013">reported
+ by Jascha Wetzel</a>.</li>
+ <li>Made position_iterator usable with wchar_t based strings. </li>
+</ul>
+<h2>1.8.3</h2>
+<ul>
+ <li>Config correction for Sun C++ by
+
+
+ Steve Clamage (see <a href="https://sourceforge.net/tracker/?func=detail&atid=107586&aid=1220782&group_id=7586">this link</a>). </li>
+ <li>Fixed multi_pass_iterator for 64 platforms, where sizeof(int) != sizeof(ptr_type).Fixed bug that prevents the use of closures with grammars with multiple entry points, <a href="http://article.gmane.org/gmane.comp.parsers.spirit.general/8868">reported by David Pierre</a></li>
+ <li>Fixed bug that prevented embedding of grammars with multiple entry points, <a href="http://article.gmane.org/gmane.comp.parsers.spirit.general/8860">reported by David Pierre</a></li>
+ <li>Added '\0' to the set of valid escaped characters for escape_ch_p.</li>
+ <li>Fixed a switch_p bug when used with a phoenix::actor as the conditional expression.</li>
+ <li>__LINE__ macro now gets expanded in BOOST_SPIRIT_ASSERT_EXCEPTION</li>
+ <li>Fixed a bug in the intersection parser <a href="http://article.gmane.org/gmane.comp.parsers.spirit.general/8544">reported by Yusaku Sugai</a></li>
+ <li>The symbol parser uses the null character internally. Checks were added so that:
+ <ul>
+ <li>tst.add asserts if string contains the null character</li>
+ <li>tst.find doesn't match null characters in the input</li>
+ </ul></li>
+ <li>Fixed match_attr_traits.ipp to allow non-POD to pass through. The previous version taking in the ellipsis &quot;...&quot; does not allow PODs to pass through.</li>
+ <li>Allow evaluation to int as condition to if_p parser.</li>
+ <li>Applied performance improvement changes to the PT/AST code as suggested by Stefan Slapeta. </li>
+ <li>Fixed several problems with AST tree node directives (inner_node_d[], discard_first_node[], discard_last_node[] and infix_node_d[]). </li>
+</ul>
+<h2>1.8.2</h2>
+<p>Maintenance release (almost the same as 1.8.1 plus a few fixes here and there)</p>
+<ul>
+ <li>Added specializations to str_p and ch_p to allow str_p('c') and ch_p("c") thus fixing some non-bugs</li>
+ <li>Fixed bug where a match&lt;T&gt; is a variant.</li>
+ <li>added Jamfile/Jamrules from CVS to spirit-1.8.1/</li>
+ <li>added boost-build.jam from boost to spirit-1.8.1/</li>
+ <li>disabled template multi-threading in libs/spirit/test/Jamfile</li>
+ <li>added a boost-header-include rule (from spirit-header-include) pointing to miniboost in libs/spirit/test/Jamfile</li>
+ <li>Fixed if_p inconsistency</li>
+</ul>
+<h2>1.6.2</h2>
+<p>The Spirit 1.6.2 release is a bug-fix release only, no new features were introduced.</p>
+<ul>
+ <li>wchar_t friendly implementation of graph_p</li>
+ <li>Modified escape_char_parser::parse() to use a static parser instead of a rule. This will make it more friendly to use in trees. It should also be a little more efficient.</li>
+ <li>Moved to
+
+
+ Boost Software license 1.0. </li>
+ <li> workaround for Error 322 name lookup in base class specialization finds type</li>
+ <li> fixed limit_d bug</li>
+ <li> [numerics] Workaround for aC++</li>
+ <li> Fixed a bug in the switch_p parser.</li>
+ <li> Fixed a EOI problem in multi_pass</li>
+ <li>added Jamfile/Jamrules from CVS to spirit-1.6.1/</li>
+ <li>added boost-build.jam from boost to spirit-1.6.1/</li>
+ <li>disabled template multi-threading in libs/spirit/test/Jamfile</li>
+ <li>added a boost-header-include rule (from spirit-header-include) pointing to miniboost in libs/spirit/test/Jamfile</li>
+</ul>
+<h2>1.8.1 (Released with Boost 1.32.0)</h2>
+<p>The Spirit 1.8.1 release is a bug-fix release only, no new features were introduced.</p>
+<ul>
+ <li>Spirit now requires at least Boost 1.32.0 to compile correctly</li>
+ <li>Removed the support for the older iterator adaptor library and </li>
+ <li>Moved to use the new MPL library</li>
+ <li>Spirit was moved to use the Boost Software License 1.0.</li>
+ <li>Fixed several parsers to support post-skips more correctly.</li>
+ <li>Fixed a no_node_d[] bug.</li>
+ <li>Fixed a bug in shortest_d[].</li>
+ <li>Fixed a bug in limit_d[].</li>
+ <li>Fixed parser traversal meta code.</li>
+ <li>Fixed several bugs in switch_p.</li>
+ <li>Fixed AST generating problems, in particular with the loops related parsers.</li>
+ <li>Fixed several bugs in the multi_pass iterator.
+ <ul>
+ <li>Fixed a problem, when the used base iterator returned a value_type and not a reference from its dereferencing operator.</li>
+ <li>Fixed iterator_traits problem</li>
+ <li>Fixed an EOI problem</li>
+ <li>Fixed a bug, when used with std::cin</li>
+ </ul>
+ </li>
+ <li>Found a bug in grammar.ipp when BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE is defined</li>
+ <li>Rewritten safe_bool to use CRTP - now works also on MWCW, fixed several bugs with the implementation.</li>
+ <li>Fixed and extended the debug diagnostics printed by the parse tree code.</li>
+</ul>
+<h2>1.8.0 (Released with Boost 1.31.0; Includes unreleased 1.7.1)</h2>
+<ul>
+ <li>Fixed a wchar_t problem in the regex_p parser.</li>
+ <li>removed code and workarounds for old compilers (VC6/7 and Borland)</li>
+ <li> Changed license to the new boost license.</li>
+ <li> Modified escape_char_parser::parse() to use a static parser instead of a rule. This will make it more friendly to use in trees. It should also be a little more efficient.</li>
+</ul>
+<h2>1.7.1 (Unreleased; becomes 1.8.0)</h2>
+<ul>
+ <li>Added a full suite of predefined actors.</li>
+ <li>Moved rule_alias and stored_rule from core/non-terminal to dynamic.<br>
+ Made as_parser a public API in meta/as_parser.hpp</li>
+ <li>Separated Core.Meta into its own module</li>
+ <li>Refactored Utility module<br>
+ Moved some files into Utility.Parsers</li>
+</ul>
+<blockquote>
+ <ul>
+ <li>utilities
+ <ul>
+ <li>parsers
+ <ul>
+ <li>chset, regex, escape_char<br>
+ confix, list, distinct<br>
+ functor_parser</li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li> support
+ <ul>
+ <li>scoped_lock<br>
+ flush_multi_pass<br>
+ grammar_def</li>
+ </ul>
+ </li>
+ <li> actors
+ <ul>
+ <li>assign</li>
+ </ul>
+ </li>
+ </ul>
+</blockquote>
+<ul>
+ <li>Stored rules</li>
+ <li>Added the switch_p and select_p dynamic parsers.</li>
+ <li>Multiple scanner support for rules.</li>
+ <li>The Rule's Scanner, Context and Tag template parameters can be specified in any order now. If a template parameter is missing, it will assume the defaults. See test/rule_tests.cpp.</li>
+ <li>Introduced the possibility to specify more than one start rule from a grammar.</li>
+ <li>Added an implementation of the file_iterator iterator based on the new Boost iterator_adaptors (submitted originally by Thomas Witt).</li>
+</ul>
+<p><em> [The transition to the new iterator_adaptors should be complete now.]</em></p>
+<ul>
+ <li>Added an implementation of the fixed_size_queue iterator based on the new Boost iterator_adaptors.</li>
+ <li> wchar_t friendly implementation of graph_p</li>
+ <li>made the copy-constructor and assignment-operator of parser_error_base public to clear VC7.1 C4673 warning. Added copy-constructor and assignment operator to parser_error for clarity of intent.</li>
+</ul>
+<h2>1.7.0</h2>
+<ul>
+ <li> assign(string) semantic action now works in VC6</li>
+ <li>parsers need not be default constructible </li>
+ <li>simplified aggregation of binary and unary parsers (more compiler friendly)</li>
+ <li>epsilon workarounds for VC++</li>
+ <li>match's attribute now uses boost.optional</li>
+ <li>subrules can now have closures</li>
+ <li>project wide 64 bit compatibility</li>
+ <li>dynamic_parser_tag, reissue of rule.set_id(id);</li>
+ <li>numerous primitives improvements and workarounds for problematic compilers</li>
+ <li>proper complement (~) of single char parser primitives and chsets</li>
+ <li>intuitive handling of lexeme_d </li>
+ <li>wide_phrase_scanner_t typedef</li>
+ <li>dynamic parser improvements (better support for more compilers)</li>
+ <li>complete rewrite of the file_iterator (using boost.iterator_adapters). Supports
+ memory maps wherever available</li>
+ <li>multi_pass updates (compatibility with more compilers (e.g VC7) and more)</li>
+ <li>position_iterator improvements</li>
+ <li>better phoenix support for more compilers</li>
+ <li>phoenix new_(...) construct</li>
+ <li>new lazy_p parser</li>
+ <li>utility.distinct parser (undocumented)</li>
+ <li>chset operators improvements </li>
+ <li>confix_p streamlining and improvements</li>
+ <li>numerous Boost integration improvements</li>
+</ul>
+<h2>Bug fixes (1.7.0 and 1.6.0)</h2>
+<ul>
+ <li> Fixed. Using MSVC++6 (SP5), calling the assign action with a string value
+ on parsers using the file_iterator will not work. </li>
+ <li> Fixed: using assign semantic action in a grammar with a multi_pass iterator
+ adaptor applied to an std::istream_iterator resulted in a failure to compile
+ under msvc 7.0. </li>
+ <li> Fixed: There is a bug in the &quot;range_run&lt;CharT&gt;::set (range&lt;CharT&gt;
+ const&amp; r)&quot; function in the &quot;boost\spirit\utility\impl\chset\range_run.ipp&quot;.
+ </li>
+ <li> Fixed: handling of trailing whitespace bug (ast_parse/pt_parse related)</li>
+ <li> Fixed: comment_p and end of data bug</li>
+ <li> Fixed: <a href="http://article.gmane.org/gmane.comp.parsers.spirit.general/4029">Most
+ trailing space bug</a>:</li>
+ <li> Fixed:<br>
+ chset&lt;&gt;::operator~(range&lt;&gt;) bug<br>
+ operator&amp;(chset&lt;&gt;, range&lt;&gt;) bug<br>
+ operator&amp;(range&lt;&gt;, chset&lt;&gt;) bug</li>
+ <li> Fixed: <a href="http://sourceforge.net/mailarchive/forum.php?thread_id=2008510&forum_id=25901">impl::detach_clear
+ bug</a></li>
+ <li> Fixed: <a href="http://article.gmane.org/gmane.comp.parsers.spirit.general/3678">mismatch
+ closure return type bug</a></li>
+ <li> Fixed: <a href="http://sf.net/mailarchive/forum.php?thread_id=1963157&forum_id=1595">access_node_d[]</a>
+ and <a href="http://sf.net/mailarchive/forum.php?thread_id=1966224&forum_id=1595">access_match_d[]</a>
+ iterator bugs</li>
+ <li> Fixed a bug regarding threadsafety of Phoenix/Spirit closures.</li>
+ <li> Added missing include files to miniboost</li>
+</ul>
+<p> <font size="2" color="#666666">Copyright &copy; 1998-2005 Joel de Guzman, Hartmut Kaiser</font><br>
+<font size="2"><font color="#666666">Use, modification and distribution is subject to 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) </font> </font></p>
+<p>&nbsp;</p>
+
+</body>
+</html>
diff --git a/src/boost/libs/spirit/classic/example/Jamfile b/src/boost/libs/spirit/classic/example/Jamfile
new file mode 100644
index 00000000..7079152f
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/Jamfile
@@ -0,0 +1,300 @@
+#==============================================================================
+# Copyright (c) 2002 Joel de Guzman
+# http://spirit.sourceforge.net/
+#
+# Use, modification and distribution is subject to 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)
+#==============================================================================
+#
+# Spirit examples boost-jam file
+# Joel de Guzman [Sep 27, 2002] : created
+# Joel de Guzman [Oct 30, 2003] : separated the applications
+# Martin Wille [Jan 15, 2004] : changes for new directory structure
+# Martin Wille [Jan 20, 2004] : more changes for new directory structure
+# Joel de Guzman [Jul 29, 2004] : added calc_debug.cpp
+#
+
+exe ast_calc
+ : fundamental/ast_calc.cpp
+ :
+ ;
+
+exe "bind"
+ : fundamental/bind.cpp
+ :
+ ;
+
+exe boiler_plate
+ : fundamental/boiler_plate.cpp
+ :
+ ;
+
+exe calc_plain
+ : fundamental/calc_plain.cpp
+ :
+ ;
+
+exe calc_debug
+ : fundamental/calc_debug.cpp
+ :
+ ;
+
+exe comments
+ : fundamental/comments.cpp
+ :
+ ;
+
+exe complex_number
+ : fundamental/complex_number.cpp
+ :
+ ;
+
+exe error_handling
+ : fundamental/error_handling.cpp
+ :
+ ;
+
+exe error_reporting
+ : fundamental/error_reporting.cpp
+ :
+ ;
+
+exe file_parser
+ : fundamental/file_parser.cpp
+ :
+ ;
+
+exe full_calc
+ : fundamental/full_calc.cpp
+ :
+ ;
+
+exe functor_parser
+ : fundamental/functor_parser.cpp
+ :
+ ;
+
+exe list_parser
+ : fundamental/list_parser.cpp
+ :
+ ;
+
+exe matching_tags
+ : fundamental/matching_tags.cpp
+ :
+ ;
+
+exe no_actions
+ : fundamental/no_actions.cpp
+ :
+ ;
+
+exe number_list
+ : fundamental/number_list.cpp
+ :
+ ;
+
+exe parse_tree_calc1
+ : fundamental/parse_tree_calc1.cpp
+ :
+ ;
+
+exe parser_context
+ : fundamental/parser_context.cpp
+ :
+ ;
+
+exe phoenix_calc
+ : fundamental/phoenix_calc.cpp
+ :
+ ;
+
+exe position_iterator
+ : fundamental/position_iterator/position_iterator.cpp
+ :
+ ;
+
+exe refactoring
+ : fundamental/refactoring.cpp
+ :
+ ;
+
+exe regular_expression
+ : fundamental/regular_expression.cpp
+ /boost//regex
+ :
+ ;
+
+exe roman_numerals
+ : fundamental/roman_numerals.cpp
+ :
+ ;
+
+exe stuff_vector
+ : fundamental/stuff_vector.cpp
+ :
+ ;
+
+exe stuff_vector2
+ : fundamental/stuff_vector2.cpp
+ :
+ ;
+
+exe subrule_calc
+ : fundamental/subrule_calc.cpp
+ :
+ ;
+
+exe sum
+ : fundamental/sum.cpp
+ :
+ ;
+
+exe thousand_separated
+ : fundamental/thousand_separated.cpp
+ :
+ ;
+
+exe ast_calc2
+ : fundamental/more_calculators/ast_calc2.cpp
+ :
+ ;
+
+exe calc_with_variables
+ : fundamental/more_calculators/calc_with_variables.cpp
+ :
+ ;
+
+exe phoenix_subrule_calc
+ : fundamental/more_calculators/phoenix_subrule_calc.cpp
+ :
+ ;
+
+exe primitive_calc
+ : fundamental/more_calculators/primitive_calc.cpp
+ :
+ ;
+
+exe rpn_calc
+ : fundamental/more_calculators/rpn_calc.cpp
+ :
+ ;
+
+exe vmachine_calc
+ : fundamental/more_calculators/vmachine_calc.cpp
+ :
+ ;
+
+exe distinct_parser
+ : fundamental/distinct/distinct_parser.cpp
+ :
+ ;
+
+exe distinct_parser_dynamic
+ : fundamental/distinct/distinct_parser_dynamic.cpp
+ :
+ ;
+
+################################################################################
+
+exe ipv4
+ : intermediate/ipv4.cpp
+ :
+ ;
+
+exe ipv4_opt
+ : intermediate/ipv4_opt.cpp
+ :
+ ;
+
+exe lazy_parser
+ : intermediate/lazy_parser.cpp
+ :
+ ;
+
+exe parameters
+ : intermediate/parameters.cpp
+ :
+ ;
+
+exe regex_convert
+ : intermediate/regex_convert.cpp
+ /boost//regex
+ :
+ ;
+
+exe simple_xml
+ : intermediate/simple_xml/driver.cpp
+ intermediate/simple_xml/tag.cpp
+ intermediate/simple_xml/tag.cpp
+ :
+ ;
+
+################################################################################
+
+exe dynamic_rule
+ : techniques/dynamic_rule.cpp
+ :
+ ;
+
+exe epsilon
+ : techniques/epsilon.cpp
+ :
+ ;
+
+exe multiple_scanners
+ : techniques/multiple_scanners.cpp
+ :
+ ;
+
+exe nabialek
+ : techniques/nabialek.cpp
+ :
+ ;
+
+exe no_rule1
+ : techniques/no_rules/no_rule1.cpp
+ :
+ ;
+
+exe no_rule2
+ : techniques/no_rules/no_rule2.cpp
+ :
+ ;
+
+exe no_rule3
+ : techniques/no_rules/no_rule3.cpp
+ :
+ ;
+
+exe typeof
+ : techniques/typeof.cpp
+ :
+ ;
+
+exe rule_parser_1_1
+ : techniques/no_rules_with_typeof/rule_parser_1_1.cpp
+ :
+ ;
+
+exe rule_parser_1_2
+ : techniques/no_rules_with_typeof/rule_parser_1_2.cpp
+ :
+ ;
+
+exe rule_parser_2_1
+ : techniques/no_rules_with_typeof/rule_parser_2_1.cpp
+ :
+ ;
+
+exe rule_parser_2_2
+ : techniques/no_rules_with_typeof/rule_parser_2_2.cpp
+ :
+ ;
+
+exe opaque_rule_parser
+ : techniques/no_rules_with_typeof/opaque_rule_parser.cpp
+ :
+ ;
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/ast_calc.cpp b/src/boost/libs/spirit/classic/example/fundamental/ast_calc.cpp
new file mode 100644
index 00000000..33c5e0f1
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/ast_calc.cpp
@@ -0,0 +1,159 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Daniel Nuffer
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// Demonstrates the ASTs. This is discussed in the
+// "Trees" chapter in the Spirit User's Guide.
+//
+///////////////////////////////////////////////////////////////////////////////
+#define BOOST_SPIRIT_DUMP_PARSETREE_AS_XML
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_ast.hpp>
+#include <boost/spirit/include/classic_tree_to_xml.hpp>
+#include <boost/assert.hpp>
+#include "tree_calc_grammar.hpp"
+
+#include <iostream>
+#include <stack>
+#include <functional>
+#include <string>
+
+#if defined(BOOST_SPIRIT_DUMP_PARSETREE_AS_XML)
+#include <map>
+#endif
+
+// This example shows how to use an AST.
+////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+typedef char const* iterator_t;
+typedef tree_match<iterator_t> parse_tree_match_t;
+typedef parse_tree_match_t::tree_iterator iter_t;
+
+////////////////////////////////////////////////////////////////////////////
+long evaluate(parse_tree_match_t hit);
+long eval_expression(iter_t const& i);
+
+long evaluate(tree_parse_info<> info)
+{
+ return eval_expression(info.trees.begin());
+}
+
+long eval_expression(iter_t const& i)
+{
+ cout << "In eval_expression. i->value = " <<
+ string(i->value.begin(), i->value.end()) <<
+ " i->children.size() = " << i->children.size() << endl;
+
+ if (i->value.id() == calculator::integerID)
+ {
+ BOOST_ASSERT(i->children.size() == 0);
+
+ // extract integer (not always delimited by '\0')
+ string integer(i->value.begin(), i->value.end());
+
+ return strtol(integer.c_str(), 0, 10);
+ }
+ else if (i->value.id() == calculator::factorID)
+ {
+ // factor can only be unary minus
+ BOOST_ASSERT(*i->value.begin() == '-');
+ return - eval_expression(i->children.begin());
+ }
+ else if (i->value.id() == calculator::termID)
+ {
+ if (*i->value.begin() == '*')
+ {
+ BOOST_ASSERT(i->children.size() == 2);
+ return eval_expression(i->children.begin()) *
+ eval_expression(i->children.begin()+1);
+ }
+ else if (*i->value.begin() == '/')
+ {
+ BOOST_ASSERT(i->children.size() == 2);
+ return eval_expression(i->children.begin()) /
+ eval_expression(i->children.begin()+1);
+ }
+ else
+ BOOST_ASSERT(0);
+ }
+ else if (i->value.id() == calculator::expressionID)
+ {
+ if (*i->value.begin() == '+')
+ {
+ BOOST_ASSERT(i->children.size() == 2);
+ return eval_expression(i->children.begin()) +
+ eval_expression(i->children.begin()+1);
+ }
+ else if (*i->value.begin() == '-')
+ {
+ BOOST_ASSERT(i->children.size() == 2);
+ return eval_expression(i->children.begin()) -
+ eval_expression(i->children.begin()+1);
+ }
+ else
+ BOOST_ASSERT(0);
+ }
+ else
+ {
+ BOOST_ASSERT(0); // error
+ }
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ // look in tree_calc_grammar for the definition of calculator
+ calculator calc;
+
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tThe simplest working calculator...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "Type an expression...or [q or Q] to quit\n\n";
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ tree_parse_info<> info = ast_parse(str.c_str(), calc);
+
+ if (info.full)
+ {
+#if defined(BOOST_SPIRIT_DUMP_PARSETREE_AS_XML)
+ // dump parse tree as XML
+ std::map<parser_id, std::string> rule_names;
+ rule_names[calculator::integerID] = "integer";
+ rule_names[calculator::factorID] = "factor";
+ rule_names[calculator::termID] = "term";
+ rule_names[calculator::expressionID] = "expression";
+ tree_to_xml(cout, info.trees, str.c_str(), rule_names);
+#endif
+
+ // print the result
+ cout << "parsing succeeded\n";
+ cout << "result = " << evaluate(info) << "\n\n";
+ }
+ else
+ {
+ cout << "parsing failed\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/bind.cpp b/src/boost/libs/spirit/classic/example/fundamental/bind.cpp
new file mode 100644
index 00000000..f38e9c23
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/bind.cpp
@@ -0,0 +1,126 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// Demonstrates use of boost::bind and spirit
+// This is discussed in the "Functional" chapter in the Spirit User's Guide.
+//
+// [ JDG 9/29/2002 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/bind.hpp>
+#include <iostream>
+#include <vector>
+#include <string>
+
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace boost;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Our comma separated list parser
+//
+///////////////////////////////////////////////////////////////////////////////
+class list_parser
+{
+public:
+
+ typedef list_parser self_t;
+
+ bool
+ parse(char const* str)
+ {
+ return BOOST_SPIRIT_CLASSIC_NS::parse(str,
+
+ // Begin grammar
+ (
+ real_p
+ [
+ bind(&self_t::add, this, _1)
+ ]
+
+ >> *( ','
+ >> real_p
+ [
+ bind(&self_t::add, this, _1)
+ ]
+ )
+ )
+ ,
+ // End grammar
+
+ space_p).full;
+ }
+
+ void
+ add(double n)
+ {
+ v.push_back(n);
+ }
+
+ void
+ print() const
+ {
+ for (vector<double>::size_type i = 0; i < v.size(); ++i)
+ cout << i << ": " << v[i] << endl;
+ }
+
+ vector<double> v;
+};
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\tA comma separated list parser for Spirit...\n";
+ cout << "\tDemonstrates use of boost::bind and spirit\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+
+ cout << "Give me a comma separated list of numbers.\n";
+ cout << "The numbers will be inserted in a vector of numbers\n";
+ cout << "Type [q or Q] to quit\n\n";
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ list_parser lp;
+ if (lp.parse(str.c_str()))
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ cout << str << " Parses OK: " << endl;
+
+ lp.print();
+
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "-------------------------\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/boiler_plate.cpp b/src/boost/libs/spirit/classic/example/fundamental/boiler_plate.cpp
new file mode 100644
index 00000000..91c9fc73
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/boiler_plate.cpp
@@ -0,0 +1,97 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// Boiler plate [ A template for writing your parser ]
+//
+// [ JDG 9/17/2002 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <iostream>
+#include <string>
+
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Semantic actions
+//
+///////////////////////////////////////////////////////////////////////////////
+struct my_action
+{
+ template <typename IteratorT>
+ void operator()(IteratorT first, IteratorT last) const
+ {
+ string s(first, last);
+ cout << "\tMy Action got: " << s << endl;
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// My grammar
+//
+///////////////////////////////////////////////////////////////////////////////
+struct my_grammar : public grammar<my_grammar>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(my_grammar const& self)
+ {
+ my_rule =
+ *lexeme_d[(+graph_p)[my_action()]]
+ ;
+ }
+
+ rule<ScannerT> my_rule;
+ rule<ScannerT> const&
+ start() const { return my_rule; }
+ };
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\t A boiler-plate parser...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "Type anything or [q or Q] to quit\n\n";
+
+ my_grammar g;
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ if (parse(str.c_str(), g, space_p).full)
+ {
+ cout << "parsing succeeded\n";
+ }
+ else
+ {
+ cout << "parsing failed\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/calc_debug.cpp b/src/boost/libs/spirit/classic/example/fundamental/calc_debug.cpp
new file mode 100644
index 00000000..f0ddf425
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/calc_debug.cpp
@@ -0,0 +1,199 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Dan Nuffer
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+////////////////////////////////////////////////////////////////////////////
+//
+// Full calculator example using STL functors with debugging enabled.
+// This is discussed in the "Functional" chapter in the Spirit User's Guide
+// and the Debugging chapter.
+//
+// Ported to Spirit v1.5 from v1.2/1.3 example by Dan Nuffer
+// [ JDG 9/18/2002 ]
+// [ JDG 7/29/2004 ]
+//
+////////////////////////////////////////////////////////////////////////////
+
+#define BOOST_SPIRIT_DEBUG
+#include <boost/spirit/include/classic_core.hpp>
+#include <iostream>
+#include <stack>
+#include <functional>
+#include <string>
+
+////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Semantic actions
+//
+////////////////////////////////////////////////////////////////////////////
+struct push_int
+{
+ push_int(stack<long>& eval_)
+ : eval(eval_) {}
+
+ void operator()(char const* str, char const* /*end*/) const
+ {
+ long n = strtol(str, 0, 10);
+ eval.push(n);
+ cout << "push\t" << long(n) << endl;
+ }
+
+ stack<long>& eval;
+};
+
+template <typename op>
+struct do_op
+{
+ do_op(op const& the_op, stack<long>& eval_)
+ : m_op(the_op), eval(eval_) {}
+
+ void operator()(char const*, char const*) const
+ {
+ long rhs = eval.top();
+ eval.pop();
+ long lhs = eval.top();
+ eval.pop();
+
+ cout << "popped " << lhs << " and " << rhs << " from the stack. ";
+ cout << "pushing " << m_op(lhs, rhs) << " onto the stack.\n";
+ eval.push(m_op(lhs, rhs));
+ }
+
+ op m_op;
+ stack<long>& eval;
+};
+
+template <class op>
+do_op<op>
+make_op(op const& the_op, stack<long>& eval)
+{
+ return do_op<op>(the_op, eval);
+}
+
+struct do_negate
+{
+ do_negate(stack<long>& eval_)
+ : eval(eval_) {}
+
+ void operator()(char const*, char const*) const
+ {
+ long lhs = eval.top();
+ eval.pop();
+
+ cout << "popped " << lhs << " from the stack. ";
+ cout << "pushing " << -lhs << " onto the stack.\n";
+ eval.push(-lhs);
+ }
+
+ stack<long>& eval;
+};
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Our calculator grammar
+//
+////////////////////////////////////////////////////////////////////////////
+struct calculator : public grammar<calculator>
+{
+ calculator(stack<long>& eval_)
+ : eval(eval_) {}
+
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(calculator const& self)
+ {
+ integer =
+ lexeme_d[ (+digit_p)[push_int(self.eval)] ]
+ ;
+
+ factor =
+ integer
+ | '(' >> expression >> ')'
+ | ('-' >> factor)[do_negate(self.eval)]
+ | ('+' >> factor)
+ ;
+
+ term =
+ factor
+ >> *( ('*' >> factor)[make_op(multiplies<long>(), self.eval)]
+ | ('/' >> factor)[make_op(divides<long>(), self.eval)]
+ )
+ ;
+
+ expression =
+ term
+ >> *( ('+' >> term)[make_op(plus<long>(), self.eval)]
+ | ('-' >> term)[make_op(minus<long>(), self.eval)]
+ )
+ ;
+
+ BOOST_SPIRIT_DEBUG_NODE(integer);
+ BOOST_SPIRIT_DEBUG_NODE(factor);
+ BOOST_SPIRIT_DEBUG_NODE(term);
+ BOOST_SPIRIT_DEBUG_NODE(expression);
+ }
+
+ rule<ScannerT> expression, term, factor, integer;
+ rule<ScannerT> const&
+ start() const { return expression; }
+ };
+
+ stack<long>& eval;
+};
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tThe simplest working calculator...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "Type an expression...or [q or Q] to quit\n\n";
+
+ stack<long> eval;
+ calculator calc(eval); // Our parser
+ BOOST_SPIRIT_DEBUG_NODE(calc);
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ parse_info<> info = parse(str.c_str(), calc, space_p);
+
+ if (info.full)
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ cout << "result = " << calc.eval.top() << endl;
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "stopped at: \": " << info.stop << "\"\n";
+ cout << "-------------------------\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/calc_plain.cpp b/src/boost/libs/spirit/classic/example/fundamental/calc_plain.cpp
new file mode 100644
index 00000000..520134f3
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/calc_plain.cpp
@@ -0,0 +1,129 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+////////////////////////////////////////////////////////////////////////////
+//
+// Plain calculator example demostrating the grammar and semantic actions.
+// This is discussed in the "Grammar" and "Semantic Actions" chapters in
+// the Spirit User's Guide.
+//
+// [ JDG 5/10/2002 ]
+//
+////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <iostream>
+#include <string>
+
+////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Semantic actions
+//
+////////////////////////////////////////////////////////////////////////////
+namespace
+{
+ void do_int(char const* str, char const* end)
+ {
+ string s(str, end);
+ cout << "PUSH(" << s << ')' << endl;
+ }
+
+ void do_add(char const*, char const*) { cout << "ADD\n"; }
+ void do_subt(char const*, char const*) { cout << "SUBTRACT\n"; }
+ void do_mult(char const*, char const*) { cout << "MULTIPLY\n"; }
+ void do_div(char const*, char const*) { cout << "DIVIDE\n"; }
+ void do_neg(char const*, char const*) { cout << "NEGATE\n"; }
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Our calculator grammar
+//
+////////////////////////////////////////////////////////////////////////////
+struct calculator : public grammar<calculator>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(calculator const& /*self*/)
+ {
+ expression
+ = term
+ >> *( ('+' >> term)[&do_add]
+ | ('-' >> term)[&do_subt]
+ )
+ ;
+
+ term
+ = factor
+ >> *( ('*' >> factor)[&do_mult]
+ | ('/' >> factor)[&do_div]
+ )
+ ;
+
+ factor
+ = lexeme_d[(+digit_p)[&do_int]]
+ | '(' >> expression >> ')'
+ | ('-' >> factor)[&do_neg]
+ | ('+' >> factor)
+ ;
+ }
+
+ rule<ScannerT> expression, term, factor;
+
+ rule<ScannerT> const&
+ start() const { return expression; }
+ };
+};
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tExpression parser...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "Type an expression...or [q or Q] to quit\n\n";
+
+ calculator calc; // Our parser
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ parse_info<> info = parse(str.c_str(), calc, space_p);
+
+ if (info.full)
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "stopped at: \": " << info.stop << "\"\n";
+ cout << "-------------------------\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/comments.cpp b/src/boost/libs/spirit/classic/example/fundamental/comments.cpp
new file mode 100644
index 00000000..9ffb4168
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/comments.cpp
@@ -0,0 +1,232 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// This example shows:
+// 1. Parsing of different comment styles
+// parsing C/C++-style comment
+// parsing C++-style comment
+// parsing PASCAL-style comment
+// 2. Parsing tagged data with the help of the confix_parser
+// 3. Parsing tagged data with the help of the confix_parser but the semantic
+// action is directly attached to the body sequence parser
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <string>
+#include <iostream>
+#include <cassert>
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_confix.hpp>
+#include <boost/spirit/include/classic_chset.hpp>
+
+
+///////////////////////////////////////////////////////////////////////////////
+// used namespaces
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+// actor called after successfully matching a single character
+class actor_string
+{
+public:
+ actor_string(std::string &rstr) :
+ matched(rstr)
+ {
+ }
+
+ void operator() (const char *pbegin, const char *pend) const
+ {
+ matched += std::string(pbegin, pend-pbegin);
+ }
+
+private:
+ std::string &matched;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// actor called after successfully matching a C++-comment
+void actor_cpp (const char *pfirst, const char *plast)
+{
+ cout << "Parsing C++-comment" <<endl;
+ cout << "Matched (" << plast-pfirst << ") characters: ";
+ cout << "\"" << std::string(pfirst, plast) << "\"" << endl;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// main entry point
+int main ()
+{
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// 1. Parsing different comment styles
+// parsing C/C++-style comments (non-nested!)
+//
+///////////////////////////////////////////////////////////////////////////////
+
+ char const* pCComment = "/* This is a /* nested */ C-comment */";
+
+ rule<> cpp_comment;
+
+ cpp_comment =
+ comment_p("/*", "*/") // rule for C-comments
+ | comment_p("//") // rule for C++ comments
+ ;
+
+ std::string comment_c;
+ parse_info<> result;
+
+ result = parse (pCComment, cpp_comment[actor_string(comment_c)]);
+ if (result.hit)
+ {
+ cout << "Parsed C-comment successfully!" << endl;
+ cout << "Matched (" << (int)comment_c.size() << ") characters: ";
+ cout << "\"" << comment_c << "\"" << endl;
+ }
+ else
+ {
+ cout << "Failed to parse C/C++-comment!" << endl;
+ }
+ cout << endl;
+
+ // parsing C++-style comment
+ char const* pCPPComment = "// This is a C++-comment\n";
+ std::string comment_cpp;
+
+ result = parse (pCPPComment, cpp_comment[&actor_cpp]);
+ if (result.hit)
+ cout << "Parsed C++-comment successfully!" << endl;
+ else
+ cout << "Failed to parse C++-comment!" << endl;
+
+ cout << endl;
+
+
+ // parsing PASCAL-style comment (nested!)
+ char const* pPComment = "{ This is a (* nested *) PASCAL-comment }";
+
+ rule<> pascal_comment;
+
+ pascal_comment = // in PASCAL we have two comment styles
+ comment_nest_p('{', '}') // both may be nested
+ | comment_nest_p("(*", "*)")
+ ;
+
+ std::string comment_pascal;
+
+ result = parse (pPComment, pascal_comment[actor_string(comment_pascal)]);
+ if (result.hit)
+ {
+ cout << "Parsed PASCAL-comment successfully!" << endl;
+ cout << "Matched (" << (int)comment_pascal.size() << ") characters: ";
+ cout << "\"" << comment_pascal << "\"" << endl;
+ }
+ else
+ {
+ cout << "Failed to parse PASCAL-comment!" << endl;
+ }
+ cout << endl;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// 2. Parsing tagged data with the help of the confix parser
+//
+///////////////////////////////////////////////////////////////////////////////
+
+ std::string body;
+ rule<> open_tag, html_tag, close_tag, body_text;
+
+ open_tag =
+ str_p("<b>")
+ ;
+
+ body_text =
+ anychar_p
+ ;
+
+ close_tag =
+ str_p("</b>")
+ ;
+
+ html_tag =
+ confix_p (open_tag, (*body_text)[actor_string(body)], close_tag)
+ ;
+
+ char const* pTag = "<b>Body text</b>";
+
+ result = parse (pTag, html_tag);
+ if (result.hit)
+ {
+ cout << "Parsed HTML snippet \"<b>Body text</b>\" successfully "
+ "(with re-attached actor)!" << endl;
+ cout << "Found body (" << (int)body.size() << " characters): ";
+ cout << "\"" << body << "\"" << endl;
+ }
+ else
+ {
+ cout << "Failed to parse HTML snippet (with re-attached actor)!"
+ << endl;
+ }
+ cout << endl;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// 3. Parsing tagged data with the help of the confix_parser but the
+// semantic action is directly attached to the body sequence parser
+// (see comment in confix.hpp) and out of the usage of the 'direct()'
+// construction function no automatic refactoring takes place.
+//
+// As you can see, for successful parsing it is required to refactor the
+// confix parser by hand. To see, how it fails, you can try the following:
+//
+// html_tag_direct =
+// confix_p.direct(
+// str_p("<b>"),
+// (*body_text)[actor_string(bodydirect)],
+// str_p("</b>")
+// )
+// ;
+//
+// Here the *body_text parser eats up all the input up to the end of the
+// input sequence.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+ rule<> html_tag_direct;
+ std::string bodydirect;
+
+ html_tag_direct =
+ confix_p.direct(
+ str_p("<b>"),
+ (*(body_text - str_p("</b>")))[actor_string(bodydirect)],
+ str_p("</b>")
+ )
+ ;
+
+ char const* pTagDirect = "<b>Body text</b>";
+
+ result = parse (pTagDirect, html_tag_direct);
+ if (result.hit)
+ {
+ cout << "Parsed HTML snippet \"<b>Body text</b>\" successfully "
+ "(with direct actor)!" << endl;
+ cout << "Found body (" << (int)bodydirect.size() << " characters): ";
+ cout << "\"" << bodydirect << "\"" << endl;
+ }
+ else
+ {
+ cout << "Failed to parse HTML snippet (with direct actor)!" << endl;
+ }
+ cout << endl;
+
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/example/fundamental/complex_number.cpp b/src/boost/libs/spirit/classic/example/fundamental/complex_number.cpp
new file mode 100644
index 00000000..3cb8d807
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/complex_number.cpp
@@ -0,0 +1,103 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// A complex number micro parser (using subrules)
+//
+// [ JDG 5/10/2002 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <iostream>
+#include <complex>
+#include <string>
+
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Our complex number micro parser
+//
+///////////////////////////////////////////////////////////////////////////////
+bool
+parse_complex(char const* str, complex<double>& c)
+{
+ double rN = 0.0;
+ double iN = 0.0;
+
+ subrule<0> first;
+ subrule<1> r;
+ subrule<2> i;
+
+ if (parse(str,
+
+ // Begin grammar
+ (
+ first = '(' >> r >> !(',' >> i) >> ')' | r,
+ r = real_p[assign(rN)],
+ i = real_p[assign(iN)]
+ )
+ ,
+ // End grammar
+
+ space_p).full)
+ {
+ c = complex<double>(rN, iN);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tA complex number micro parser for Spirit...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+
+ cout << "Give me a complex number of the form r or (r) or (r,i) \n";
+ cout << "Type [q or Q] to quit\n\n";
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ complex<double> c;
+ if (parse_complex(str.c_str(), c))
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ cout << str << " Parses OK: " << c << endl;
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "-------------------------\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/distinct/distinct_parser.cpp b/src/boost/libs/spirit/classic/example/fundamental/distinct/distinct_parser.cpp
new file mode 100644
index 00000000..6b4506d6
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/distinct/distinct_parser.cpp
@@ -0,0 +1,68 @@
+/*=============================================================================
+ Copyright (c) 2003 Vaclav Vesely
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/assert.hpp>
+#include <iostream>
+#include <boost/cstdlib.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_distinct.hpp>
+
+using namespace std;
+using namespace boost;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+// keyword_p for C++
+// (for basic usage instead of std_p)
+const distinct_parser<> keyword_p("0-9a-zA-Z_");
+
+// keyword_d for C++
+// (for mor intricate usage, for example together with symbol tables)
+const distinct_directive<> keyword_d("0-9a-zA-Z_");
+
+struct my_grammar: public grammar<my_grammar>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ typedef rule<ScannerT> rule_t;
+
+ definition(my_grammar const& self)
+ {
+ top
+ =
+ keyword_p("declare") // use keyword_p instead of std_p
+ >> !ch_p(':')
+ >> keyword_d[str_p("ident")] // use keyword_d
+ ;
+ }
+
+ rule_t top;
+
+ rule_t const& start() const
+ {
+ return top;
+ }
+ };
+};
+
+int main()
+{
+ my_grammar gram;
+ parse_info<> info;
+
+ info = parse("declare ident", gram, space_p);
+ BOOST_ASSERT(info.full); // valid input
+
+ info = parse("declare: ident", gram, space_p);
+ BOOST_ASSERT(info.full); // valid input
+
+ info = parse("declareident", gram, space_p);
+ BOOST_ASSERT(!info.hit); // invalid input
+
+ return exit_success;
+}
diff --git a/src/boost/libs/spirit/classic/example/fundamental/distinct/distinct_parser_dynamic.cpp b/src/boost/libs/spirit/classic/example/fundamental/distinct/distinct_parser_dynamic.cpp
new file mode 100644
index 00000000..8e64fd64
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/distinct/distinct_parser_dynamic.cpp
@@ -0,0 +1,64 @@
+/*=============================================================================
+ Copyright (c) 2003 Vaclav Vesely
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/assert.hpp>
+#include <iostream>
+#include <boost/cstdlib.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_distinct.hpp>
+
+using namespace std;
+using namespace boost;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+struct my_grammar: public grammar<my_grammar>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ typedef rule<ScannerT> rule_t;
+
+ // keyword_p for ASN.1
+ dynamic_distinct_parser<ScannerT> keyword_p;
+
+ definition(my_grammar const& self)
+ : keyword_p(alnum_p | ('-' >> ~ch_p('-'))) // ASN.1 has quite complex naming rules
+ {
+ top
+ =
+ keyword_p("asn-declare") // use keyword_p instead of std_p
+ >> !str_p("--")
+ >> keyword_p("ident")
+ ;
+ }
+
+ rule_t top;
+
+ rule_t const& start() const
+ {
+ return top;
+ }
+ };
+};
+
+int main()
+{
+ my_grammar gram;
+ parse_info<> info;
+
+ info = parse("asn-declare ident", gram, space_p);
+ BOOST_ASSERT(info.full); // valid input
+
+ info = parse("asn-declare--ident", gram, space_p);
+ BOOST_ASSERT(info.full); // valid input
+
+ info = parse("asn-declare-ident", gram, space_p);
+ BOOST_ASSERT(!info.hit); // invalid input
+
+ return exit_success;
+}
diff --git a/src/boost/libs/spirit/classic/example/fundamental/error_handling.cpp b/src/boost/libs/spirit/classic/example/fundamental/error_handling.cpp
new file mode 100644
index 00000000..f2efcc24
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/error_handling.cpp
@@ -0,0 +1,55 @@
+/*=============================================================================
+ Copyright (c) 1998-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// This sample demonstrates error handling as seen in the
+// Error Handling" chapter in the User's Guide.
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_exceptions.hpp>
+#include <iostream>
+#include <boost/assert.hpp>
+
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+struct handler
+{
+ template <typename ScannerT, typename ErrorT>
+ error_status<>
+ operator()(ScannerT const& /*scan*/, ErrorT const& /*error*/) const
+ {
+ cout << "exception caught...Test concluded successfully" << endl;
+ return error_status<>(error_status<>::fail);
+ }
+};
+
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tExceptions Test...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+
+ assertion<int> expect(0);
+ guard<int> my_guard;
+
+ rule<> start =
+ my_guard(ch_p('a') >> 'b' >> 'c' >> expect( ch_p('d') ))
+ [
+ handler()
+ ];
+
+ bool r = parse("abcx", start).full;
+
+ BOOST_ASSERT(!r);
+ return 0;
+}
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/error_reporting.cpp b/src/boost/libs/spirit/classic/example/fundamental/error_reporting.cpp
new file mode 100644
index 00000000..4b18781f
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/error_reporting.cpp
@@ -0,0 +1,114 @@
+/*=============================================================================
+ Copyright (c) 2003 Pavel Baranov
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// An alternate error-handling scheme where the parser will
+// complain (but not stop) if input doesn't match.
+//
+// [ Pavel Baranov 8/27/2003 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_functor_parser.hpp>
+#include <iostream>
+#include <string>
+
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+static short errcount = 0;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Error reporting parser
+//
+///////////////////////////////////////////////////////////////////////////////
+struct error_report_parser {
+
+ error_report_parser(const char *msg) : _msg(msg) {}
+
+ typedef nil_t result_t;
+
+ template <typename ScannerT>
+ int operator()(ScannerT const& scan, result_t& /*result*/) const
+ {
+ errcount++;
+ cerr << _msg << endl;
+ return 0;
+ }
+
+private:
+ string _msg;
+};
+
+typedef functor_parser<error_report_parser> error_report_p;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// My grammar
+//
+///////////////////////////////////////////////////////////////////////////////
+struct my_grammar : public grammar<my_grammar>
+{
+ static error_report_p error_missing_semicolon;
+ static error_report_p error_missing_letter;
+
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(my_grammar const& self) :
+ SEMICOLON(';')
+ {
+ my_rule
+ = *(eps_p(alpha_p|SEMICOLON) >>
+ (alpha_p|error_missing_letter) >>
+ (SEMICOLON|error_missing_semicolon))
+ ;
+ }
+
+ chlit<>
+ SEMICOLON;
+
+ rule<ScannerT> my_rule;
+
+ rule<ScannerT> const&
+ start() const { return my_rule; }
+ };
+};
+
+error_report_p my_grammar::error_missing_semicolon("missing semicolon");
+error_report_p my_grammar::error_missing_letter("missing letter");
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << " Error handling demo\n\n";
+ cout << " The parser expects a sequence of letter/semicolon pairs\n";
+ cout << " and will complain (but not stop) if input doesn't match.\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+
+ my_grammar g;
+
+ string str( "a;;b;cd;e;fg;" );
+ cout << "input: " << str << "\n\n";
+
+ if( parse(str.c_str(), g, space_p).full && !errcount )
+ cout << "\nparsing succeeded\n";
+ else
+ cout << "\nparsing failed\n";
+
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/example/fundamental/file_parser.cpp b/src/boost/libs/spirit/classic/example/fundamental/file_parser.cpp
new file mode 100644
index 00000000..cd4036b1
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/file_parser.cpp
@@ -0,0 +1,89 @@
+/*=============================================================================
+ Copyright (c) 2002 Jeff Westfahl
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// A parser that echoes a file
+// See the "File Iterator" chapter in the User's Guide.
+//
+// [ JMW 8/05/2002 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_file_iterator.hpp>
+#include <iostream>
+
+///////////////////////////////////////////////////////////////////////////////
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Types
+//
+////////////////////////////////////////////////////////////////////////////
+typedef char char_t;
+typedef file_iterator<char_t> iterator_t;
+typedef scanner<iterator_t> scanner_t;
+typedef rule<scanner_t> rule_t;
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Actions
+//
+////////////////////////////////////////////////////////////////////////////
+void echo(iterator_t first, iterator_t const& last)
+{
+ while (first != last)
+ std::cout << *first++;
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+////////////////////////////////////////////////////////////////////////////
+int
+main(int argc, char* argv[])
+{
+ if (2 > argc)
+ {
+ std::cout << "Must specify a filename!\n";
+ return -1;
+ }
+
+ // Create a file iterator for this file
+ iterator_t first(argv[1]);
+
+ if (!first)
+ {
+ std::cout << "Unable to open file!\n";
+ return -1;
+ }
+
+ // Create an EOF iterator
+ iterator_t last = first.make_end();
+
+ // A simple rule
+ rule_t r = *(anychar_p);
+
+ // Parse
+ parse_info <iterator_t> info = parse(
+ first,
+ last,
+ r[&echo]
+ );
+
+ // This really shouldn't fail...
+ if (info.full)
+ std::cout << "Parse succeeded!\n";
+ else
+ std::cout << "Parse failed!\n";
+
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/example/fundamental/full_calc.cpp b/src/boost/libs/spirit/classic/example/fundamental/full_calc.cpp
new file mode 100644
index 00000000..e1184d05
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/full_calc.cpp
@@ -0,0 +1,188 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Dan Nuffer
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+////////////////////////////////////////////////////////////////////////////
+//
+// Full calculator example using STL functors
+// This is discussed in the "Functional" chapter in the Spirit User's Guide.
+//
+// Ported to Spirit v1.5 from v1.2/1.3 example by Dan Nuffer
+// [ JDG 9/18/2002 ]
+//
+////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <iostream>
+#include <stack>
+#include <functional>
+#include <string>
+
+////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Semantic actions
+//
+////////////////////////////////////////////////////////////////////////////
+struct push_int
+{
+ push_int(stack<long>& eval_)
+ : eval(eval_) {}
+
+ void operator()(char const* str, char const* /*end*/) const
+ {
+ long n = strtol(str, 0, 10);
+ eval.push(n);
+ cout << "push\t" << long(n) << endl;
+ }
+
+ stack<long>& eval;
+};
+
+template <typename op>
+struct do_op
+{
+ do_op(op const& the_op, stack<long>& eval_)
+ : m_op(the_op), eval(eval_) {}
+
+ void operator()(char const*, char const*) const
+ {
+ long rhs = eval.top();
+ eval.pop();
+ long lhs = eval.top();
+ eval.pop();
+
+ cout << "popped " << lhs << " and " << rhs << " from the stack. ";
+ cout << "pushing " << m_op(lhs, rhs) << " onto the stack.\n";
+ eval.push(m_op(lhs, rhs));
+ }
+
+ op m_op;
+ stack<long>& eval;
+};
+
+template <class op>
+do_op<op>
+make_op(op const& the_op, stack<long>& eval)
+{
+ return do_op<op>(the_op, eval);
+}
+
+struct do_negate
+{
+ do_negate(stack<long>& eval_)
+ : eval(eval_) {}
+
+ void operator()(char const*, char const*) const
+ {
+ long lhs = eval.top();
+ eval.pop();
+
+ cout << "popped " << lhs << " from the stack. ";
+ cout << "pushing " << -lhs << " onto the stack.\n";
+ eval.push(-lhs);
+ }
+
+ stack<long>& eval;
+};
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Our calculator grammar
+//
+////////////////////////////////////////////////////////////////////////////
+struct calculator : public grammar<calculator>
+{
+ calculator(stack<long>& eval_)
+ : eval(eval_) {}
+
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(calculator const& self)
+ {
+ integer =
+ lexeme_d[ (+digit_p)[push_int(self.eval)] ]
+ ;
+
+ factor =
+ integer
+ | '(' >> expression >> ')'
+ | ('-' >> factor)[do_negate(self.eval)]
+ | ('+' >> factor)
+ ;
+
+ term =
+ factor
+ >> *( ('*' >> factor)[make_op(multiplies<long>(), self.eval)]
+ | ('/' >> factor)[make_op(divides<long>(), self.eval)]
+ )
+ ;
+
+ expression =
+ term
+ >> *( ('+' >> term)[make_op(plus<long>(), self.eval)]
+ | ('-' >> term)[make_op(minus<long>(), self.eval)]
+ )
+ ;
+ }
+
+ rule<ScannerT> expression, term, factor, integer;
+ rule<ScannerT> const&
+ start() const { return expression; }
+ };
+
+ stack<long>& eval;
+};
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tThe simplest working calculator...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "Type an expression...or [q or Q] to quit\n\n";
+
+ stack<long> eval;
+ calculator calc(eval); // Our parser
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ parse_info<> info = parse(str.c_str(), calc, space_p);
+
+ if (info.full)
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "stopped at: \": " << info.stop << "\"\n";
+ cout << "-------------------------\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/functor_parser.cpp b/src/boost/libs/spirit/classic/example/fundamental/functor_parser.cpp
new file mode 100644
index 00000000..e9a52f31
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/functor_parser.cpp
@@ -0,0 +1,160 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ Copyright (c) 2002 Juan Carlos Arevalo-Baeza
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_functor_parser.hpp>
+#include <boost/spirit/include/classic_assign_actor.hpp>
+#include <iostream>
+#include <vector>
+#include <string>
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Demonstrates the functor_parser. This is discussed in the
+// "Functor Parser" chapter in the Spirit User's Guide.
+//
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Our parser functor
+//
+///////////////////////////////////////////////////////////////////////////////
+struct number_parser
+{
+ typedef int result_t;
+ template <typename ScannerT>
+ int
+ operator()(ScannerT const& scan, result_t& result) const
+ {
+ if (scan.at_end())
+ return -1;
+
+ char ch = *scan;
+ if (ch < '0' || ch > '9')
+ return -1;
+
+ result = 0;
+ int len = 0;
+
+ do
+ {
+ result = result*10 + int(ch - '0');
+ ++len;
+ ++scan;
+ } while (!scan.at_end() && (ch = *scan, ch >= '0' && ch <= '9'));
+
+ return len;
+ }
+};
+
+functor_parser<number_parser> number_parser_p;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Our number parser functions
+//
+///////////////////////////////////////////////////////////////////////////////
+bool
+parse_number(char const* str, int& n)
+{
+ return parse(str, lexeme_d[number_parser_p[assign_a(n)]], space_p).full;
+}
+
+bool
+parse_numbers(char const* str, std::vector<int>& n)
+{
+ return
+ parse(
+ str,
+ lexeme_d[number_parser_p[push_back_a(n)]]
+ >> *(',' >> lexeme_d[number_parser_p[push_back_a(n)]]),
+ space_p
+ ).full;
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tA number parser implemented as a functor for Spirit...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+
+ cout << "Give me an integer number command\n";
+ cout << "Commands:\n";
+ cout << " A <num> --> parses a single number\n";
+ cout << " B <num>, <num>, ... --> parses a series of numbers ";
+ cout << "separated by commas\n";
+ cout << " Q --> quit\n\n";
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ else if (str[0] == 'a' || str[0] == 'A')
+ {
+ int n;
+ if (parse_number(str.c_str()+1, n))
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ cout << str << " Parses OK: " << n << endl;
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "-------------------------\n";
+ }
+ }
+
+ else if (str[0] == 'b' || str[0] == 'B')
+ {
+ std::vector<int> n;
+ if (parse_numbers(str.c_str()+1, n))
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ int size = n.size();
+ cout << str << " Parses OK: " << size << " number(s): " << n[0];
+ for (int i = 1; i < size; ++i) {
+ cout << ", " << n[i];
+ }
+ cout << endl;
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "-------------------------\n";
+ }
+ }
+
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Unrecognized command!!";
+ cout << "-------------------------\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/example/fundamental/list_parser.cpp b/src/boost/libs/spirit/classic/example/fundamental/list_parser.cpp
new file mode 100644
index 00000000..922fb5d0
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/list_parser.cpp
@@ -0,0 +1,233 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+// This sample shows the usage of the list_p utility parser
+// 1. parsing a simple ',' delimited list w/o item formatting
+// 2. parsing a CSV list (comma separated values - strings, integers or reals)
+// 3. parsing a token list (token separated values - strings, integers or
+// reals)
+// with an action parser directly attached to the item part of the list_p
+// generated parser
+
+#include <string>
+#include <iostream>
+#include <cassert>
+#include <vector>
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_confix.hpp>
+#include <boost/spirit/include/classic_lists.hpp>
+#include <boost/spirit/include/classic_escape_char.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+// actor, attached to the list_p parser
+class list_actor
+{
+public:
+ list_actor (std::vector<std::string> &vec_) : vec(vec_) {}
+
+ // The following operator() is called by the action parser generated by
+ // attaching this actor to a list_p generated list parser.
+
+ template <typename ActionIterT>
+ void operator() (ActionIterT const &first, ActionIterT const &last) const
+ {
+ vec.push_back(std::string(first, last-first));
+ }
+
+private:
+ std::vector<std::string> &vec;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// main entry point
+int main ()
+{
+ // 1. parsing a simple ',' delimited list w/o item formatting
+ char const* plist_wo_item = "element1,element2,element3";
+ rule<> list_wo_item;
+ std::vector<std::string> vec_list;
+
+ list_wo_item =
+ list_p[push_back_a(vec_list)]
+ ;
+
+ parse_info<> result = parse (plist_wo_item, list_wo_item);
+
+ cout << "-----------------------------------------------------------------"
+ << endl;
+
+ if (result.hit)
+ {
+ cout
+ << "Parsing simple list" << endl
+ << "\t" << plist_wo_item << endl
+ << "Parsed successfully!" << endl << endl;
+
+ cout
+ << "Actor was called " << (int)vec_list.size()
+ << " times: " << endl;
+
+ cout
+ << "Results got from the list parser:" << endl;
+ for (std::vector<std::string>::iterator it = vec_list.begin();
+ it != vec_list.end(); ++it)
+ {
+ cout << *it << endl;
+ }
+ }
+ else
+ {
+ cout << "Failed to parse simple list!" << endl;
+ }
+
+ cout << endl;
+
+ // 2. parsing a CSV list (comma separated values - strings, integers or
+ // reals)
+ char const *plist_csv = "\"string\",\"string with an embedded \\\"\","
+ "12345,0.12345e4,,2";
+ rule<> list_csv, list_csv_item;
+ std::vector<std::string> vec_item;
+
+ vec_list.clear();
+
+ list_csv_item =
+ !(
+ confix_p('\"', *c_escape_ch_p, '\"')
+ | longest_d[real_p | int_p]
+ );
+
+ list_csv =
+ list_p(
+ list_csv_item[push_back_a(vec_item)],
+ ','
+ )[push_back_a(vec_list)]
+ ;
+
+ result = parse (plist_csv, list_csv);
+
+ cout << "-----------------------------------------------------------------"
+ << endl;
+ if (result.hit)
+ {
+ cout
+ << "Parsing CSV list (comma separated values) " << endl
+ << "\t" << plist_csv << endl
+ << "Parsed successfully!" << endl << endl;
+
+ if (result.full)
+ {
+ cout << "Matched " << (int)vec_list.size() <<
+ " list elements (full list): " << endl;
+ }
+ else
+ {
+ cout << "Matched " << (int)vec_list.size() <<
+ " list elements: " << endl;
+ }
+
+ cout << "The list parser matched:" << endl;
+ for (std::vector<std::string>::iterator itl = vec_list.begin();
+ itl != vec_list.end(); ++itl)
+ {
+ cout << *itl << endl;
+ }
+
+ cout << endl << "Item(s) got directly from the item parser:" << endl;
+ for (std::vector<std::string>::iterator it = vec_item.begin();
+ it != vec_item.end(); ++it)
+ {
+ cout << *it << endl;
+ }
+
+ }
+ else
+ {
+ cout << "Failed to parse CSV list!" << endl;
+ }
+
+ cout << endl;
+
+ // 3. parsing a token list (token separated values - strings, integers or
+ // reals) with an action parser directly attached to the item part of the
+ // list_p generated parser
+ char const *plist_csv_direct = "\"string\"<par>\"string with an embedded "
+ "\\\"\"<par>12345<par>0.12345e4";
+ rule<> list_csv_direct, list_csv_direct_item;
+
+ vec_list.clear();
+ vec_item.clear();
+
+ // Note: the list parser is here generated through the list_p.direct()
+ // generator function. This inhibits re-attachment of the item_actor_direct
+ // during parser construction (see: comment in utility/lists.hpp)
+ list_csv_direct_item =
+ confix_p('\"', *c_escape_ch_p, '\"')
+ | longest_d[real_p | int_p]
+ ;
+
+ list_csv_direct =
+ list_p.direct(
+ (*list_csv_direct_item)[list_actor(vec_item)],
+ "<par>"
+ )[list_actor(vec_list)]
+ ;
+
+ result = parse (plist_csv_direct, list_csv_direct);
+
+ cout << "-----------------------------------------------------------------"
+ << endl;
+ if (result.hit)
+ {
+ cout
+ << "Parsing CSV list (comma separated values)" << endl
+ << "The list parser was generated with 'list_p.direct()'" << endl
+ << "\t" << plist_csv_direct << endl
+ << "Parsed successfully!" << endl << endl;
+
+ if (result.full)
+ {
+ cout << "Matched " << vec_list.size() <<
+ " list elements (full list): " << endl;
+ }
+ else
+ {
+ cout << "Matched " << vec_list.size() <<
+ " list elements: " << endl;
+ }
+
+ cout << "The list parser matched:" << endl;
+ for (std::vector<std::string>::iterator itl = vec_list.begin();
+ itl != vec_list.end(); ++itl)
+ {
+ cout << *itl << endl;
+ }
+
+ cout << endl << "Items got directly from the item parser:" << endl;
+ for (std::vector<std::string>::iterator it = vec_item.begin();
+ it != vec_item.end(); ++it)
+ {
+ cout << *it << endl;
+ }
+
+ }
+ else
+ {
+ cout << "Failed to parse CSV list!" << endl;
+ }
+
+ cout << endl;
+
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/example/fundamental/matching_tags.cpp b/src/boost/libs/spirit/classic/example/fundamental/matching_tags.cpp
new file mode 100644
index 00000000..14581ff5
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/matching_tags.cpp
@@ -0,0 +1,115 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+////////////////////////////////////////////////////////////////////////////
+//
+// HTML/XML like tag matching grammar
+// Demonstrates phoenix and closures and parametric parsers
+// This is discussed in the "Closures" chapter in the Spirit User's Guide.
+//
+// [ JDG 6/30/2002 ]
+//
+////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_attribute.hpp>
+#include <iostream>
+#include <string>
+
+////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace phoenix;
+
+////////////////////////////////////////////////////////////////////////////
+//
+// HTML/XML like tag matching grammar
+//
+////////////////////////////////////////////////////////////////////////////
+struct tags_closure : BOOST_SPIRIT_CLASSIC_NS::closure<tags_closure, string>
+{
+ member1 tag;
+};
+
+struct tags : public grammar<tags>
+{
+ template <typename ScannerT>
+ struct definition {
+
+ definition(tags const& /*self*/)
+ {
+ element = start_tag >> *element >> end_tag;
+
+ start_tag =
+ '<'
+ >> lexeme_d
+ [
+ (+alpha_p)
+ [
+ // construct string from arg1 and arg2 lazily
+ // and assign to element.tag
+
+ element.tag = construct_<string>(arg1, arg2)
+ ]
+ ]
+ >> '>';
+
+ end_tag = "</" >> f_str_p(element.tag) >> '>';
+ }
+
+ rule<ScannerT, tags_closure::context_t> element;
+ rule<ScannerT> start_tag, end_tag;
+
+ rule<ScannerT, tags_closure::context_t> const&
+ start() const { return element; }
+ };
+};
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tHTML/XML like tag matching parser demo \n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "Type an HTML/XML like nested tag input...or [q or Q] to quit\n\n";
+ cout << "Example: <html><head></head><body></body></html>\n\n";
+
+ tags p; // Our parser
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ parse_info<> info = parse(str.c_str(), p, space_p);
+
+ if (info.full)
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "stopped at: \": " << info.stop << "\"\n";
+ cout << "-------------------------\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/more_calculators/ast_calc2.cpp b/src/boost/libs/spirit/classic/example/fundamental/more_calculators/ast_calc2.cpp
new file mode 100644
index 00000000..a017b65f
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/more_calculators/ast_calc2.cpp
@@ -0,0 +1,180 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Daniel Nuffer
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_ast.hpp>
+#include <boost/assert.hpp>
+
+#include <iostream>
+#include <stack>
+#include <functional>
+#include <string>
+
+// This example shows how to use an AST and tree_iter_node instead of
+// tree_val_node
+////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+typedef char const* iterator_t;
+typedef tree_match<iterator_t, node_iter_data_factory<> >
+ parse_tree_match_t;
+
+typedef parse_tree_match_t::tree_iterator iter_t;
+
+typedef ast_match_policy<iterator_t, node_iter_data_factory<> > match_policy_t;
+typedef scanner<iterator_t, scanner_policies<iter_policy_t, match_policy_t> > scanner_t;
+typedef rule<scanner_t> rule_t;
+
+
+// grammar rules
+rule_t expression, term, factor, integer;
+
+////////////////////////////////////////////////////////////////////////////
+long evaluate(parse_tree_match_t hit);
+long eval_expression(iter_t const& i);
+long eval_term(iter_t const& i);
+long eval_factor(iter_t const& i);
+long eval_integer(iter_t const& i);
+
+long evaluate(parse_tree_match_t hit)
+{
+ return eval_expression(hit.trees.begin());
+}
+
+long eval_expression(iter_t const& i)
+{
+ cout << "In eval_expression. i->value = " <<
+ string(i->value.begin(), i->value.end()) <<
+ " i->children.size() = " << i->children.size() << endl;
+
+ cout << "ID: " << i->value.id().to_long() << endl;
+
+ if (i->value.id() == integer.id())
+ {
+ BOOST_ASSERT(i->children.size() == 0);
+ return strtol(i->value.begin(), 0, 10);
+ }
+ else if (i->value.id() == factor.id())
+ {
+ // factor can only be unary minus
+ BOOST_ASSERT(*i->value.begin() == '-');
+ return - eval_expression(i->children.begin());
+ }
+ else if (i->value.id() == term.id())
+ {
+ if (*i->value.begin() == '*')
+ {
+ BOOST_ASSERT(i->children.size() == 2);
+ return eval_expression(i->children.begin()) *
+ eval_expression(i->children.begin()+1);
+ }
+ else if (*i->value.begin() == '/')
+ {
+ BOOST_ASSERT(i->children.size() == 2);
+ return eval_expression(i->children.begin()) /
+ eval_expression(i->children.begin()+1);
+ }
+ else
+ BOOST_ASSERT(0);
+ }
+ else if (i->value.id() == expression.id())
+ {
+ if (*i->value.begin() == '+')
+ {
+ BOOST_ASSERT(i->children.size() == 2);
+ return eval_expression(i->children.begin()) +
+ eval_expression(i->children.begin()+1);
+ }
+ else if (*i->value.begin() == '-')
+ {
+ BOOST_ASSERT(i->children.size() == 2);
+ return eval_expression(i->children.begin()) -
+ eval_expression(i->children.begin()+1);
+ }
+ else
+ BOOST_ASSERT(0);
+ }
+ else
+ BOOST_ASSERT(0); // error
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ BOOST_SPIRIT_DEBUG_RULE(integer);
+ BOOST_SPIRIT_DEBUG_RULE(factor);
+ BOOST_SPIRIT_DEBUG_RULE(term);
+ BOOST_SPIRIT_DEBUG_RULE(expression);
+ // Start grammar definition
+ integer = leaf_node_d[ lexeme_d[ (!ch_p('-') >> +digit_p) ] ];
+ factor = integer
+ | inner_node_d[ch_p('(') >> expression >> ch_p(')')]
+ | (root_node_d[ch_p('-')] >> factor);
+ term = factor >>
+ *( (root_node_d[ch_p('*')] >> factor)
+ | (root_node_d[ch_p('/')] >> factor)
+ );
+ expression = term >>
+ *( (root_node_d[ch_p('+')] >> term)
+ | (root_node_d[ch_p('-')] >> term)
+ );
+ // End grammar definition
+
+
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tThe simplest working calculator...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "Type an expression...or [q or Q] to quit\n\n";
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ const char* str_begin = str.c_str();
+ const char* str_end = str.c_str();
+ while (*str_end)
+ ++str_end;
+
+ scanner_t scan(str_begin, str_end);
+
+ parse_tree_match_t hit = expression.parse(scan);
+
+
+ if (hit && str_begin == str_end)
+ {
+#if defined(BOOST_SPIRIT_DUMP_PARSETREE_AS_XML)
+ // dump parse tree as XML
+ std::map<rule_id, std::string> rule_names;
+ rule_names[&integer] = "integer";
+ rule_names[&factor] = "factor";
+ rule_names[&term] = "term";
+ rule_names[&expression] = "expression";
+ tree_to_xml(cout, hit.trees, str.c_str(), rule_names);
+#endif
+
+ // print the result
+ cout << "parsing succeeded\n";
+ cout << "result = " << evaluate(hit) << "\n\n";
+ }
+ else
+ {
+ cout << "parsing failed\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/more_calculators/calc_with_variables.cpp b/src/boost/libs/spirit/classic/example/fundamental/more_calculators/calc_with_variables.cpp
new file mode 100644
index 00000000..5e43a7fc
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/more_calculators/calc_with_variables.cpp
@@ -0,0 +1,261 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Dan Nuffer
+ Copyright (c) 2001-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// Full calculator example with variables
+// [ JDG 9/18/2002 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_symbols.hpp>
+#include <iostream>
+#include <stack>
+#include <functional>
+#include <string>
+
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Semantic actions
+//
+///////////////////////////////////////////////////////////////////////////////
+struct push_num
+{
+ push_num(stack<double>& eval_)
+ : eval(eval_) {}
+
+ void operator()(double n) const
+ {
+ eval.push(n);
+ cout << "push\t" << n << endl;
+ }
+
+ stack<double>& eval;
+};
+
+template <typename op>
+struct do_op
+{
+ do_op(op const& the_op, stack<double>& eval_)
+ : m_op(the_op), eval(eval_) {}
+
+ void operator()(char const*, char const*) const
+ {
+ double rhs = eval.top();
+ eval.pop();
+ double lhs = eval.top();
+ eval.pop();
+
+ cout << "popped " << lhs << " and " << rhs << " from the stack. ";
+ cout << "pushing " << m_op(lhs, rhs) << " onto the stack.\n";
+ eval.push(m_op(lhs, rhs));
+ }
+
+ op m_op;
+ stack<double>& eval;
+};
+
+template <class op>
+do_op<op>
+make_op(op const& the_op, stack<double>& eval)
+{
+ return do_op<op>(the_op, eval);
+}
+
+struct do_negate
+{
+ do_negate(stack<double>& eval_)
+ : eval(eval_) {}
+
+ void operator()(char const*, char const*) const
+ {
+ double lhs = eval.top();
+ eval.pop();
+
+ cout << "popped " << lhs << " from the stack. ";
+ cout << "pushing " << -lhs << " onto the stack.\n";
+ eval.push(-lhs);
+ }
+
+ stack<double>& eval;
+};
+
+struct get_var
+{
+ get_var(stack<double>& eval_)
+ : eval(eval_) {}
+
+ void operator()(double n) const
+ {
+ eval.push(n);
+ cout << "push\t" << n << endl;
+ }
+
+ stack<double>& eval;
+};
+
+struct set_var
+{
+ set_var(double*& var_)
+ : var(var_) {}
+
+ void operator()(double& n) const
+ {
+ var = &n;
+ }
+
+ double*& var;
+};
+
+struct redecl_var
+{
+ void operator()(double& /*n*/) const
+ {
+ cout << "Warning. You are attempting to re-declare a var.\n";
+ }
+};
+
+struct do_assign
+{
+ do_assign(double*& var_, stack<double>& eval_)
+ : var(var_), eval(eval_) {}
+
+ void operator()(char const*, char const*) const
+ {
+ if (var != 0)
+ {
+ *var = eval.top();
+ cout << "assigning\n";
+ }
+ }
+
+ double*& var;
+ stack<double>& eval;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Our calculator grammar
+//
+///////////////////////////////////////////////////////////////////////////////
+struct calculator : public grammar<calculator>
+{
+ calculator(stack<double>& eval_)
+ : eval(eval_) {}
+
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(calculator const& self)
+ {
+ factor =
+ real_p[push_num(self.eval)]
+ | vars[get_var(self.eval)]
+ | '(' >> expression >> ')'
+ | ('-' >> factor)[do_negate(self.eval)]
+ ;
+
+ term =
+ factor
+ >> *( ('*' >> factor)[make_op(multiplies<double>(), self.eval)]
+ | ('/' >> factor)[make_op(divides<double>(), self.eval)]
+ )
+ ;
+
+ expression =
+ term
+ >> *( ('+' >> term)[make_op(plus<double>(), self.eval)]
+ | ('-' >> term)[make_op(minus<double>(), self.eval)]
+ )
+ ;
+
+ assignment =
+ vars[set_var(self.var)]
+ >> '=' >> expression[do_assign(self.var, self.eval)]
+ ;
+
+ var_decl =
+ lexeme_d
+ [
+ ((alpha_p >> *(alnum_p | '_'))
+ - vars[redecl_var()])[vars.add]
+ ]
+ ;
+
+ declaration =
+ lexeme_d["var" >> space_p] >> var_decl >> *(',' >> var_decl)
+ ;
+
+ statement =
+ declaration | assignment | '?' >> expression
+ ;
+ }
+
+ symbols<double> vars;
+ rule<ScannerT> statement, declaration, var_decl,
+ assignment, expression, term, factor;
+
+ rule<ScannerT> const&
+ start() const { return statement; }
+ };
+
+ mutable double* var;
+ stack<double>& eval;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tThe calculator with variables...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "Type a statement...or [q or Q] to quit\n\n";
+ cout << "Variables may be declared:\t\tExample: var i, j, k\n";
+ cout << "Assigning to a variable:\t\tExample: i = 10 * j\n";
+ cout << "To evaluate an expression:\t\tExample: ? i * 3.33E-3\n\n";
+
+ stack<double> eval;
+ calculator calc(eval); // Our parser
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ parse_info<> info = parse(str.c_str(), calc, space_p);
+
+ if (info.full)
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "stopped at: \": " << info.stop << "\"\n";
+ cout << "-------------------------\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/more_calculators/phoenix_subrule_calc.cpp b/src/boost/libs/spirit/classic/example/fundamental/more_calculators/phoenix_subrule_calc.cpp
new file mode 100644
index 00000000..9cdfdd04
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/more_calculators/phoenix_subrule_calc.cpp
@@ -0,0 +1,142 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// Full calculator example
+// [ demonstrating phoenix and subrules ]
+//
+// [ Hartmut Kaiser 10/8/2002 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+
+//#define BOOST_SPIRIT_DEBUG // define this for debug output
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_attribute.hpp>
+#include <iostream>
+#include <string>
+
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace phoenix;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Our calculator grammar using phoenix to do the semantics and subrule's
+// as it's working horses
+//
+// Note: The top rule propagates the expression result (value) upwards
+// to the calculator grammar self.val closure member which is
+// then visible outside the grammar (i.e. since self.val is the
+// member1 of the closure, it becomes the attribute passed by
+// the calculator to an attached semantic action. See the
+// driver code that uses the calculator below).
+//
+///////////////////////////////////////////////////////////////////////////////
+struct calc_closure : BOOST_SPIRIT_CLASSIC_NS::closure<calc_closure, double>
+{
+ member1 val;
+};
+
+struct calculator : public grammar<calculator, calc_closure::context_t>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(calculator const& self)
+ {
+ top = (
+ expression =
+ term[self.val = arg1]
+ >> *( ('+' >> term[self.val += arg1])
+ | ('-' >> term[self.val -= arg1])
+ )
+ ,
+
+ term =
+ factor[term.val = arg1]
+ >> *( ('*' >> factor[term.val *= arg1])
+ | ('/' >> factor[term.val /= arg1])
+ )
+ ,
+
+ factor
+ = ureal_p[factor.val = arg1]
+ | '(' >> expression[factor.val = arg1] >> ')'
+ | ('-' >> factor[factor.val = -arg1])
+ | ('+' >> factor[factor.val = arg1])
+ );
+
+ BOOST_SPIRIT_DEBUG_NODE(top);
+ BOOST_SPIRIT_DEBUG_NODE(expression);
+ BOOST_SPIRIT_DEBUG_NODE(term);
+ BOOST_SPIRIT_DEBUG_NODE(factor);
+ }
+
+ subrule<0, calc_closure::context_t> expression;
+ subrule<1, calc_closure::context_t> term;
+ subrule<2, calc_closure::context_t> factor;
+
+ rule<ScannerT> top;
+
+ rule<ScannerT> const&
+ start() const { return top; }
+ };
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tExpression parser using Phoenix...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "Type an expression...or [q or Q] to quit\n\n";
+
+ calculator calc; // Our parser
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ double n = 0;
+ parse_info<> info = parse(str.c_str(), calc[var(n) = arg1], space_p);
+
+ // calc[var(n) = arg1] invokes the calculator and extracts
+ // the result of the computation. See calculator grammar
+ // note above.
+
+ if (info.full)
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ cout << "result = " << n << endl;
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "stopped at: \": " << info.stop << "\"\n";
+ cout << "-------------------------\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/more_calculators/primitive_calc.cpp b/src/boost/libs/spirit/classic/example/fundamental/more_calculators/primitive_calc.cpp
new file mode 100644
index 00000000..22babb52
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/more_calculators/primitive_calc.cpp
@@ -0,0 +1,96 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// A primitive calculator that knows how to add and subtract.
+// [ demonstrating phoenix ]
+//
+// [ JDG 6/28/2002 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_operators.hpp>
+#include <iostream>
+#include <string>
+
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace phoenix;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Our primitive calculator
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename IteratorT>
+bool primitive_calc(IteratorT first, IteratorT last, double& n)
+{
+ return parse(first, last,
+
+ // Begin grammar
+ (
+ real_p[var(n) = arg1]
+ >> *( ('+' >> real_p[var(n) += arg1])
+ | ('-' >> real_p[var(n) -= arg1])
+ )
+ )
+ ,
+ // End grammar
+
+ space_p).full;
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tA primitive calculator...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+
+ cout << "Give me a list of numbers to be added or subtracted.\n";
+ cout << "Example: 1 + 10 + 3 - 4 + 9\n";
+ cout << "The result is computed using Phoenix.\n";
+ cout << "Type [q or Q] to quit\n\n";
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ double n;
+ if (primitive_calc(str.begin(), str.end(), n))
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ cout << str << " Parses OK: " << endl;
+
+ cout << "result = " << n;
+ cout << "\n-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "-------------------------\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/more_calculators/rpn_calc.cpp b/src/boost/libs/spirit/classic/example/fundamental/more_calculators/rpn_calc.cpp
new file mode 100644
index 00000000..844a7915
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/more_calculators/rpn_calc.cpp
@@ -0,0 +1,163 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Hartmut Kaiser
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// This sample shows, how to use Phoenix for implementing a
+// simple (RPN style) calculator [ demonstrating phoenix ]
+//
+// [ HKaiser 2001 ]
+// [ JDG 6/29/2002 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_attribute.hpp>
+#include <boost/spirit/include/phoenix1_functions.hpp>
+#include <iostream>
+#include <string>
+
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace phoenix;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Our RPN calculator grammar using phoenix to do the semantics
+// The class 'RPNCalculator' implements a polish reverse notation
+// calculator which is equivalent to the following YACC description.
+//
+// exp:
+// NUM { $$ = $1; }
+// | exp exp '+' { $$ = $1 + $2; }
+// | exp exp '-' { $$ = $1 - $2; }
+// | exp exp '*' { $$ = $1 * $2; }
+// | exp exp '/' { $$ = $1 / $2; }
+// | exp exp '^' { $$ = pow ($1, $2); } /* Exponentiation */
+// | exp 'n' { $$ = -$1; } /* Unary minus */
+// ;
+//
+// The different notation results from the requirement of LL parsers not to
+// allow left recursion in their grammar (would lead to endless recursion).
+// Therefore the left recursion in the YACC script before is transformated
+// into iteration. To some, this is less intuitive, but once you get used
+// to it, it's very easy to follow.
+//
+// Note: The top rule propagates the expression result (value) upwards
+// to the calculator grammar self.val closure member which is
+// then visible outside the grammar (i.e. since self.val is the
+// member1 of the closure, it becomes the attribute passed by
+// the calculator to an attached semantic action. See the
+// driver code that uses the calculator below).
+//
+///////////////////////////////////////////////////////////////////////////////
+struct pow_
+{
+ template <typename X, typename Y>
+ struct result { typedef X type; };
+
+ template <typename X, typename Y>
+ X operator()(X x, Y y) const
+ {
+ using namespace std;
+ return pow(x, y);
+ }
+};
+
+// Notice how power(x, y) is lazily implemented using Phoenix function.
+function<pow_> power;
+
+struct calc_closure : BOOST_SPIRIT_CLASSIC_NS::closure<calc_closure, double, double>
+{
+ member1 x;
+ member2 y;
+};
+
+struct calculator : public grammar<calculator, calc_closure::context_t>
+{
+ template <typename ScannerT>
+ struct definition {
+
+ definition(calculator const& self)
+ {
+ top = expr [self.x = arg1];
+ expr =
+ real_p [expr.x = arg1]
+ >> *(
+ expr [expr.y = arg1]
+ >> (
+ ch_p('+') [expr.x += expr.y]
+ | ch_p('-') [expr.x -= expr.y]
+ | ch_p('*') [expr.x *= expr.y]
+ | ch_p('/') [expr.x /= expr.y]
+ | ch_p('^') [expr.x = power(expr.x, expr.y)]
+ )
+ | ch_p('n') [expr.x = -expr.x]
+ )
+ ;
+ }
+
+ typedef rule<ScannerT, calc_closure::context_t> rule_t;
+ rule_t expr;
+ rule<ScannerT> top;
+
+ rule<ScannerT> const&
+ start() const { return top; }
+ };
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tExpression parser using Phoenix...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "Type an expression...or [q or Q] to quit\n\n";
+
+ calculator calc; // Our parser
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ double n = 0;
+ parse_info<> info = parse(str.c_str(), calc[var(n) = arg1], space_p);
+
+ // calc[var(n) = arg1] invokes the calculator and extracts
+ // the result of the computation. See calculator grammar
+ // note above.
+
+ if (info.full)
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ cout << "result = " << n << endl;
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "stopped at: \": " << info.stop << "\"\n";
+ cout << "-------------------------\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/more_calculators/vmachine_calc.cpp b/src/boost/libs/spirit/classic/example/fundamental/more_calculators/vmachine_calc.cpp
new file mode 100644
index 00000000..bbcb52df
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/more_calculators/vmachine_calc.cpp
@@ -0,0 +1,275 @@
+/*=============================================================================
+ Copyright (c) 1998-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+////////////////////////////////////////////////////////////////////////////
+//
+// The calculator using a simple virtual machine and compiler.
+//
+// Ported to v1.5 from the original v1.0 code by JDG
+// [ JDG 9/18/2002 ]
+//
+////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <iostream>
+#include <vector>
+#include <string>
+
+////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// The VMachine
+//
+///////////////////////////////////////////////////////////////////////////////
+enum ByteCodes
+{
+ OP_NEG, // negate the top stack entry
+ OP_ADD, // add top two stack entries
+ OP_SUB, // subtract top two stack entries
+ OP_MUL, // multiply top two stack entries
+ OP_DIV, // divide top two stack entries
+ OP_INT, // push constant integer into the stack
+ OP_RET // return from the interpreter
+};
+
+class vmachine
+{
+public:
+ vmachine(unsigned stackSize = 1024)
+ : stack(new int[stackSize]),
+ stackPtr(stack) {}
+ ~vmachine() { delete [] stack; }
+ int top() const { return stackPtr[-1]; };
+ void execute(int code[]);
+
+private:
+
+ int* stack;
+ int* stackPtr;
+};
+
+void
+vmachine::execute(int code[])
+{
+ int const* pc = code;
+ bool running = true;
+ stackPtr = stack;
+
+ while (running)
+ {
+ switch (*pc++)
+ {
+ case OP_NEG:
+ stackPtr[-1] = -stackPtr[-1];
+ break;
+
+ case OP_ADD:
+ stackPtr--;
+ stackPtr[-1] += stackPtr[0];
+ break;
+
+ case OP_SUB:
+ stackPtr--;
+ stackPtr[-1] -= stackPtr[0];
+ break;
+
+ case OP_MUL:
+ stackPtr--;
+ stackPtr[-1] *= stackPtr[0];
+ break;
+
+ case OP_DIV:
+ stackPtr--;
+ stackPtr[-1] /= stackPtr[0];
+ break;
+
+ case OP_INT:
+ // Check stack overflow here!
+ *stackPtr++ = *pc++;
+ break;
+
+ case OP_RET:
+ running = false;
+ break;
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// The Compiler
+//
+///////////////////////////////////////////////////////////////////////////////
+struct push_int
+{
+ push_int(vector<int>& code_)
+ : code(code_) {}
+
+ void operator()(char const* str, char const* /*end*/) const
+ {
+ using namespace std;
+ int n = strtol(str, 0, 10);
+ code.push_back(OP_INT);
+ code.push_back(n);
+ cout << "push\t" << int(n) << endl;
+ }
+
+ vector<int>& code;
+};
+
+struct push_op
+{
+ push_op(int op_, vector<int>& code_)
+ : op(op_), code(code_) {}
+
+ void operator()(char const*, char const*) const
+ {
+ code.push_back(op);
+
+ switch (op) {
+
+ case OP_NEG:
+ cout << "neg\n";
+ break;
+
+ case OP_ADD:
+ cout << "add\n";
+ break;
+
+ case OP_SUB:
+ cout << "sub\n";
+ break;
+
+ case OP_MUL:
+ cout << "mul\n";
+ break;
+
+ case OP_DIV:
+ cout << "div\n";
+ break;
+ }
+ }
+
+ int op;
+ vector<int>& code;
+};
+
+template <typename GrammarT>
+static bool
+compile(GrammarT const& calc, char const* expr)
+{
+ cout << "\n/////////////////////////////////////////////////////////\n\n";
+
+ parse_info<char const*>
+ result = parse(expr, calc, space_p);
+
+ if (result.full)
+ {
+ cout << "\t\t" << expr << " Parses OK\n\n\n";
+ calc.code.push_back(OP_RET);
+ return true;
+ }
+ else
+ {
+ cout << "\t\t" << expr << " Fails parsing\n";
+ cout << "\t\t";
+ for (int i = 0; i < (result.stop - expr); i++)
+ cout << " ";
+ cout << "^--Here\n\n\n";
+ return false;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Our calculator grammar
+//
+////////////////////////////////////////////////////////////////////////////
+struct calculator : public grammar<calculator>
+{
+ calculator(vector<int>& code_)
+ : code(code_) {}
+
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(calculator const& self)
+ {
+ integer =
+ lexeme_d[ (+digit_p)[push_int(self.code)] ]
+ ;
+
+ factor =
+ integer
+ | '(' >> expression >> ')'
+ | ('-' >> factor)[push_op(OP_NEG, self.code)]
+ | ('+' >> factor)
+ ;
+
+ term =
+ factor
+ >> *( ('*' >> factor)[push_op(OP_MUL, self.code)]
+ | ('/' >> factor)[push_op(OP_DIV, self.code)]
+ )
+ ;
+
+ expression =
+ term
+ >> *( ('+' >> term)[push_op(OP_ADD, self.code)]
+ | ('-' >> term)[push_op(OP_SUB, self.code)]
+ )
+ ;
+ }
+
+ rule<ScannerT> expression, term, factor, integer;
+
+ rule<ScannerT> const&
+ start() const { return expression; }
+ };
+
+ vector<int>& code;
+};
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tA simple virtual machine...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "Type an expression...or [q or Q] to quit\n\n";
+
+ vmachine mach; // Our virtual machine
+ vector<int> code; // Our VM code
+ calculator calc(code); // Our parser
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ code.clear();
+ if (compile(calc, str.c_str()))
+ {
+ mach.execute(&*code.begin());
+ cout << "\n\nresult = " << mach.top() << "\n\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/no_actions.cpp b/src/boost/libs/spirit/classic/example/fundamental/no_actions.cpp
new file mode 100644
index 00000000..a57b6e17
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/no_actions.cpp
@@ -0,0 +1,56 @@
+/*=============================================================================
+ Copyright (c) 2003 Vaclav Vesely
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+//
+// This example demonstrates no_actions_d directive.
+//
+// The no_actions_d directive ensures, that semantic actions of the inner
+// parser would NOT be invoked. See the no_actions_scanner in the Scanner
+// and Parsing chapter in the User's Guide.
+//
+//-----------------------------------------------------------------------------
+
+#include <boost/assert.hpp>
+#include <iostream>
+#include <boost/cstdlib.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+
+using namespace std;
+using namespace boost;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+//-----------------------------------------------------------------------------
+
+int main()
+{
+ // To use the rule in the no_action_d directive we must declare it with
+ // the no_actions_scanner scanner
+ rule<no_actions_scanner<>::type> r;
+
+ int i(0);
+
+ // r is the rule with the semantic action
+ r = int_p[assign_a(i)];
+
+ parse_info<> info = parse(
+ "1",
+
+ no_actions_d
+ [
+ r
+ ]
+ );
+
+ BOOST_ASSERT(info.full);
+ // Check, that the action hasn't been invoked
+ BOOST_ASSERT(i == 0);
+
+ return exit_success;
+}
+
+//-----------------------------------------------------------------------------
diff --git a/src/boost/libs/spirit/classic/example/fundamental/number_list.cpp b/src/boost/libs/spirit/classic/example/fundamental/number_list.cpp
new file mode 100644
index 00000000..1756f118
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/number_list.cpp
@@ -0,0 +1,93 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// This sample demontrates a parser for a comma separated list of numbers
+// This is discussed in the "Quick Start" chapter in the Spirit User's Guide.
+//
+// [ JDG 5/10/2002 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_push_back_actor.hpp>
+#include <iostream>
+#include <vector>
+#include <string>
+
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Our comma separated list parser
+//
+///////////////////////////////////////////////////////////////////////////////
+bool
+parse_numbers(char const* str, vector<double>& v)
+{
+ return parse(str,
+
+ // Begin grammar
+ (
+ real_p[push_back_a(v)] >> *(',' >> real_p[push_back_a(v)])
+ )
+ ,
+ // End grammar
+
+ space_p).full;
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tA comma separated list parser for Spirit...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+
+ cout << "Give me a comma separated list of numbers.\n";
+ cout << "The numbers will be inserted in a vector of numbers\n";
+ cout << "Type [q or Q] to quit\n\n";
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ vector<double> v;
+ if (parse_numbers(str.c_str(), v))
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ cout << str << " Parses OK: " << endl;
+
+ for (vector<double>::size_type i = 0; i < v.size(); ++i)
+ cout << i << ": " << v[i] << endl;
+
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "-------------------------\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/parse_tree_calc1.cpp b/src/boost/libs/spirit/classic/example/fundamental/parse_tree_calc1.cpp
new file mode 100644
index 00000000..755810e5
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/parse_tree_calc1.cpp
@@ -0,0 +1,207 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Daniel Nuffer
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// Demonstrates parse trees. This is discussed in the
+// "Trees" chapter in the Spirit User's Guide.
+//
+///////////////////////////////////////////////////////////////////////////////
+#define BOOST_SPIRIT_DUMP_PARSETREE_AS_XML
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_parse_tree.hpp>
+#include <boost/assert.hpp>
+
+#include <iostream>
+#include <stack>
+#include <functional>
+#include <string>
+
+#ifdef BOOST_SPIRIT_DUMP_PARSETREE_AS_XML
+#include <boost/spirit/include/classic_tree_to_xml.hpp>
+#include <map>
+#endif
+
+////////////////////////////////////////////////////////////////////////////
+// This example shows how to use a parse tree
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+// Here's some typedefs to simplify things
+typedef char const* iterator_t;
+typedef tree_match<iterator_t> parse_tree_match_t;
+typedef parse_tree_match_t::const_tree_iterator iter_t;
+
+typedef pt_match_policy<iterator_t> match_policy_t;
+typedef scanner_policies<iteration_policy, match_policy_t, action_policy> scanner_policy_t;
+typedef scanner<iterator_t, scanner_policy_t> scanner_t;
+typedef rule<scanner_t> rule_t;
+
+// grammar rules
+rule_t expression, term, factor, integer;
+
+////////////////////////////////////////////////////////////////////////////
+// Here's the function prototypes that we'll use. One function for each
+// grammar rule.
+long evaluate(const tree_parse_info<>& info);
+long eval_expression(iter_t const& i);
+long eval_term(iter_t const& i);
+long eval_factor(iter_t const& i);
+long eval_integer(iter_t const& i);
+
+long evaluate(const tree_parse_info<>& info)
+{
+ return eval_expression(info.trees.begin());
+}
+
+// i should be pointing to a node created by the expression rule
+long eval_expression(iter_t const& i)
+{
+ parser_id id = i->value.id();
+ BOOST_ASSERT(id == expression.id()); // check the id
+
+ // first child points to a term, so call eval_term on it
+ iter_t chi = i->children.begin();
+ long lhs = eval_term(chi);
+ for (++chi; chi != i->children.end(); ++chi)
+ {
+ // next node points to the operator. The text of the operator is
+ // stored in value (a vector<char>)
+ char op = *(chi->value.begin());
+ ++chi;
+ long rhs = eval_term(chi);
+ if (op == '+')
+ lhs += rhs;
+ else if (op == '-')
+ lhs -= rhs;
+ else
+ BOOST_ASSERT(0);
+ }
+ return lhs;
+}
+
+long eval_term(iter_t const& i)
+{
+ parser_id id = i->value.id();
+ BOOST_ASSERT(id == term.id());
+
+ iter_t chi = i->children.begin();
+ long lhs = eval_factor(chi);
+ for (++chi; chi != i->children.end(); ++chi)
+ {
+ char op = *(chi->value.begin());
+ ++chi;
+ long rhs = eval_factor(chi);
+ if (op == '*')
+ lhs *= rhs;
+ else if (op == '/')
+ lhs /= rhs;
+ else
+ BOOST_ASSERT(0);
+ }
+ return lhs;
+}
+
+long eval_factor(iter_t const& i)
+{
+ parser_id id = i->value.id();
+ BOOST_ASSERT(id == factor.id());
+
+ iter_t chi = i->children.begin();
+ id = chi->value.id();
+ if (id == integer.id())
+ return eval_integer(chi->children.begin());
+ else if (*(chi->value.begin()) == '(')
+ {
+ ++chi;
+ return eval_expression(chi);
+ }
+ else if (*(chi->value.begin()) == '-')
+ {
+ ++chi;
+ return -eval_factor(chi);
+ }
+ else
+ {
+ BOOST_ASSERT(0);
+ return 0;
+ }
+}
+
+long eval_integer(iter_t const& i)
+{
+ // extract integer (not always delimited by '\0')
+ string integer(i->value.begin(), i->value.end());
+
+ return strtol(integer.c_str(), 0, 10);
+}
+
+////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+
+ // Start grammar definition
+ integer = lexeme_d[ token_node_d[ (!ch_p('-') >> +digit_p) ] ];
+ factor = integer
+ | '(' >> expression >> ')'
+ | ('-' >> factor);
+ term = factor >>
+ *( ('*' >> factor)
+ | ('/' >> factor)
+ );
+ expression = term >>
+ *( ('+' >> term)
+ | ('-' >> term)
+ );
+ // End grammar definition
+
+
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tThe simplest working calculator...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "Type an expression...or [q or Q] to quit\n\n";
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ const char* first = str.c_str();
+
+ tree_parse_info<> info = pt_parse(first, expression);
+
+ if (info.full)
+ {
+#if defined(BOOST_SPIRIT_DUMP_PARSETREE_AS_XML)
+ // dump parse tree as XML
+ std::map<parser_id, std::string> rule_names;
+ rule_names[integer.id()] = "integer";
+ rule_names[factor.id()] = "factor";
+ rule_names[term.id()] = "term";
+ rule_names[expression.id()] = "expression";
+ tree_to_xml(cout, info.trees, first, rule_names);
+#endif
+
+ // print the result
+ cout << "parsing succeeded\n";
+ cout << "result = " << evaluate(info) << "\n\n";
+ }
+ else
+ {
+ cout << "parsing failed\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/parser_context.cpp b/src/boost/libs/spirit/classic/example/fundamental/parser_context.cpp
new file mode 100644
index 00000000..d8ed32ba
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/parser_context.cpp
@@ -0,0 +1,51 @@
+/*=============================================================================
+ Copyright (c) 2003 Vaclav Vesely
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+//
+// This example demonstrates usage of the parser_context template with
+// an explicit argument to declare rules with match results different from
+// nil_t. For better understanding, you should read the chapter "In-depth:
+// The Parser Context" in the documentation.
+//
+// The default context of non-terminals is the parser_context.
+// The parser_context is a template with one argument AttrT, which is the type
+// of match attribute.
+//
+// In this example int_rule is declared as rule with int match attribute's
+// type, so in int_rule variable we can hold any parser, which returns int
+// value. For example int_p or bin_p. And the most important is that we can
+// use returned value in the semantic action binded to the int_rule.
+//
+//-----------------------------------------------------------------------------
+#include <iostream>
+#include <boost/cstdlib.hpp>
+#include <boost/spirit/include/phoenix1.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+
+using namespace std;
+using namespace boost;
+using namespace phoenix;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+//-----------------------------------------------------------------------------
+
+int main()
+{
+ rule<parser_context<int> > int_rule = int_p;
+
+ parse(
+ "123",
+ // Using a returned value in the semantic action
+ int_rule[cout << arg1 << endl]
+ );
+
+ return exit_success;
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/phoenix_calc.cpp b/src/boost/libs/spirit/classic/example/fundamental/phoenix_calc.cpp
new file mode 100644
index 00000000..d4f816e6
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/phoenix_calc.cpp
@@ -0,0 +1,132 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+////////////////////////////////////////////////////////////////////////////
+//
+// Full calculator example demonstrating Phoenix
+// This is discussed in the "Closures" chapter in the Spirit User's Guide.
+//
+// [ JDG 6/29/2002 ]
+//
+////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_attribute.hpp>
+#include <iostream>
+#include <string>
+
+////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace phoenix;
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Our calculator grammar using phoenix to do the semantics
+//
+// Note: The top rule propagates the expression result (value) upwards
+// to the calculator grammar self.val closure member which is
+// then visible outside the grammar (i.e. since self.val is the
+// member1 of the closure, it becomes the attribute passed by
+// the calculator to an attached semantic action. See the
+// driver code that uses the calculator below).
+//
+////////////////////////////////////////////////////////////////////////////
+struct calc_closure : BOOST_SPIRIT_CLASSIC_NS::closure<calc_closure, double>
+{
+ member1 val;
+};
+
+struct calculator : public grammar<calculator, calc_closure::context_t>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(calculator const& self)
+ {
+ top = expression[self.val = arg1];
+
+ expression
+ = term[expression.val = arg1]
+ >> *( ('+' >> term[expression.val += arg1])
+ | ('-' >> term[expression.val -= arg1])
+ )
+ ;
+
+ term
+ = factor[term.val = arg1]
+ >> *( ('*' >> factor[term.val *= arg1])
+ | ('/' >> factor[term.val /= arg1])
+ )
+ ;
+
+ factor
+ = ureal_p[factor.val = arg1]
+ | '(' >> expression[factor.val = arg1] >> ')'
+ | ('-' >> factor[factor.val = -arg1])
+ | ('+' >> factor[factor.val = arg1])
+ ;
+ }
+
+ typedef rule<ScannerT, calc_closure::context_t> rule_t;
+ rule_t expression, term, factor;
+ rule<ScannerT> top;
+
+ rule<ScannerT> const&
+ start() const { return top; }
+ };
+};
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tExpression parser using Phoenix...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "Type an expression...or [q or Q] to quit\n\n";
+
+ calculator calc; // Our parser
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ double n = 0;
+ parse_info<> info = parse(str.c_str(), calc[var(n) = arg1], space_p);
+
+ // calc[var(n) = arg1] invokes the calculator and extracts
+ // the result of the computation. See calculator grammar
+ // note above.
+
+ if (info.full)
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ cout << "result = " << n << endl;
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "stopped at: \": " << info.stop << "\"\n";
+ cout << "-------------------------\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.cpp b/src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.cpp
new file mode 100644
index 00000000..94975919
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.cpp
@@ -0,0 +1,173 @@
+/*=============================================================================
+ Copyright (c) 2002 Juan Carlos Arevalo-Baeza
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// A parser for a comma separated list of numbers,
+// with positional error reporting
+// See the "Position Iterator" chapter in the User's Guide.
+//
+// [ JCAB 9/28/2002 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_position_iterator.hpp>
+#include <boost/spirit/include/classic_functor_parser.hpp>
+#include <iostream>
+#include <fstream>
+#include <vector>
+
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Our error reporting parsers
+//
+///////////////////////////////////////////////////////////////////////////////
+std::ostream& operator<<(std::ostream& out, file_position const& lc)
+{
+ return out <<
+ "\nFile:\t" << lc.file <<
+ "\nLine:\t" << lc.line <<
+ "\nCol:\t" << lc.column << endl;
+}
+
+struct error_report_parser {
+ char const* eol_msg;
+ char const* msg;
+
+ error_report_parser(char const* eol_msg_, char const* msg_):
+ eol_msg(eol_msg_),
+ msg (msg_)
+ {}
+
+ typedef nil_t result_t;
+
+ template <typename ScannerT>
+ int
+ operator()(ScannerT const& scan, result_t& /*result*/) const
+ {
+ if (scan.at_end()) {
+ if (eol_msg) {
+ file_position fpos = scan.first.get_position();
+ cerr << fpos << eol_msg << endl;
+ }
+ } else {
+ if (msg) {
+ file_position fpos = scan.first.get_position();
+ cerr << fpos << msg << endl;
+ }
+ }
+
+ return -1; // Fail.
+ }
+
+};
+typedef functor_parser<error_report_parser> error_report_p;
+
+error_report_p
+error_badnumber_or_eol =
+ error_report_parser(
+ "Expecting a number, but found the end of the file\n",
+ "Expecting a number, but found something else\n"
+ );
+
+error_report_p
+error_badnumber =
+ error_report_parser(
+ 0,
+ "Expecting a number, but found something else\n"
+ );
+
+error_report_p
+error_comma =
+ error_report_parser(
+ 0,
+ "Expecting a comma, but found something else\n"
+ );
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Our comma separated list parser
+//
+///////////////////////////////////////////////////////////////////////////////
+bool
+parse_numbers(char const* filename, char const* str, vector<double>& v)
+{
+ typedef position_iterator<char const*> iterator_t;
+ iterator_t begin(str, str + strlen(str), filename);
+ iterator_t end;
+ begin.set_tabchars(8);
+ return parse(begin, end,
+
+ // Begin grammar
+ (
+ (real_p[push_back_a(v)] | error_badnumber)
+ >> *(
+ (',' | error_comma)
+ >> (real_p[push_back_a(v)] | error_badnumber_or_eol)
+ )
+ )
+ ,
+ // End grammar
+
+ space_p).full;
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+////////////////////////////////////////////////////////////////////////////
+int
+main(int argc, char **argv)
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\tAn error-reporting parser for Spirit...\n\n";
+ cout << "Parses a comma separated list of numbers from a file.\n";
+ cout << "The numbers will be inserted in a vector of numbers\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+
+ char str[65536];
+ char const* filename;
+
+ if (argc > 1) {
+ filename = argv[1];
+ ifstream file(filename);
+ file.get(str, sizeof(str), '\0');
+ } else {
+ filename = "<cin>";
+ cin.get(str, sizeof(str), '\0');
+ }
+
+ vector<double> v;
+ if (parse_numbers(filename, str, v))
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ cout << str << " Parses OK: " << endl;
+
+ for (vector<double>::size_type i = 0; i < v.size(); ++i)
+ cout << i << ": " << v[i] << endl;
+
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "-------------------------\n";
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.err1 b/src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.err1
new file mode 100644
index 00000000..d6646b72
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.err1
@@ -0,0 +1,8 @@
+0, 1,2 , 3 a,4
+,5,
+6
+,
+7
+
+
+,08
diff --git a/src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.err2 b/src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.err2
new file mode 100644
index 00000000..012e2738
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.err2
@@ -0,0 +1,8 @@
+0, 1,2 , 3 ,4
+,5,
+6
+,
+7
+
+
+,
diff --git a/src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.err3 b/src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.err3
new file mode 100644
index 00000000..8e011921
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.err3
@@ -0,0 +1,8 @@
+0, 1,2 , a3 ,4
+,5,
+6
+,
+7
+
+
+,08
diff --git a/src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.ok b/src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.ok
new file mode 100644
index 00000000..9bf6f0d1
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/position_iterator/position_iterator.ok
@@ -0,0 +1,8 @@
+0, 1,2 , 3 ,4
+,5,
+6
+,
+7
+
+
+,08
diff --git a/src/boost/libs/spirit/classic/example/fundamental/refactoring.cpp b/src/boost/libs/spirit/classic/example/fundamental/refactoring.cpp
new file mode 100644
index 00000000..701fdbef
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/refactoring.cpp
@@ -0,0 +1,214 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+// This example shows the usage of the refactoring parser family parsers
+// See the "Refactoring Parsers" chapter in the User's Guide.
+
+#include <iostream>
+#include <string>
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_refactoring.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// used namespaces
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+// actor, used by the refactor_action_p test
+struct refactor_action_actor
+{
+ refactor_action_actor (std::string &str_) : str(str_) {}
+
+ template <typename IteratorT>
+ void operator() (IteratorT const &first, IteratorT const &last) const
+ {
+ str = std::string(first, last-first);
+ }
+
+ std::string &str;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// main entry point
+int main()
+{
+ parse_info<> result;
+ char const *test_string = "Some string followed by a newline\n";
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// 1. Testing the refactor_unary_d parser
+//
+// The following test should successfully parse the test string, because the
+//
+// refactor_unary_d[
+// *anychar_p - '\n'
+// ]
+//
+// is refactored into
+//
+// *(anychar_p - '\n').
+//
+///////////////////////////////////////////////////////////////////////////////
+
+ result = parse(test_string, refactor_unary_d[*anychar_p - '\n'] >> '\n');
+
+ if (result.full)
+ {
+ cout << "Successfully refactored an unary!" << endl;
+ }
+ else
+ {
+ cout << "Failed to refactor an unary!" << endl;
+ }
+
+// Parsing the same test string without refactoring fails, because the
+// *anychar_p eats up all the input up to the end of the input string.
+
+ result = parse(test_string, (*anychar_p - '\n') >> '\n');
+
+ if (result.full)
+ {
+ cout
+ << "Successfully parsed test string (should not happen)!"
+ << endl;
+ }
+ else
+ {
+ cout
+ << "Correctly failed parsing the test string (without refactoring)!"
+ << endl;
+ }
+ cout << endl;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// 2. Testing the refactor_action_d parser
+//
+// The following test should successfully parse the test string, because the
+//
+// refactor_action_d[
+// (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'
+// ]
+//
+// is refactored into
+//
+// (*(anychar_p - '$') >> '$')[refactor_action_actor(str)].
+//
+///////////////////////////////////////////////////////////////////////////////
+
+ std::string str;
+ char const *test_string2 = "Some test string ending with a $";
+
+ result =
+ parse(test_string2,
+ refactor_action_d[
+ (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'
+ ]
+ );
+
+ if (result.full && str == std::string(test_string2))
+ {
+ cout << "Successfully refactored an action!" << endl;
+ cout << "Parsed: \"" << str << "\"" << endl;
+ }
+ else
+ {
+ cout << "Failed to refactor an action!" << endl;
+ }
+
+// Parsing the same test string without refactoring fails, because the
+// the attached actor gets called only for the first part of the string
+// (without the '$')
+
+ result =
+ parse(test_string2,
+ (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'
+ );
+
+ if (result.full && str == std::string(test_string2))
+ {
+ cout << "Successfully parsed test string!" << endl;
+ cout << "Parsed: \"" << str << "\"" << endl;
+ }
+ else
+ {
+ cout
+ << "Correctly failed parsing the test string (without refactoring)!"
+ << endl;
+ cout << "Parsed instead: \"" << str << "\"" << endl;
+ }
+ cout << endl;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// 3. Testing the refactor_action_d parser with an embedded (nested)
+// refactor_unary_p parser
+//
+// The following test should successfully parse the test string, because the
+//
+// refactor_action_unary_d[
+// ((*anychar_p)[refactor_action_actor(str)] - '$')
+// ] >> '$'
+//
+// is refactored into
+//
+// (*(anychar_p - '$'))[refactor_action_actor(str)] >> '$'.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+ const refactor_action_gen<refactor_unary_gen<> > refactor_action_unary_d =
+ refactor_action_gen<refactor_unary_gen<> >(refactor_unary_d);
+
+ result =
+ parse(test_string2,
+ refactor_action_unary_d[
+ ((*anychar_p)[refactor_action_actor(str)] - '$')
+ ] >> '$'
+ );
+
+ if (result.full)
+ {
+ cout
+ << "Successfully refactored an action attached to an unary!"
+ << endl;
+ cout << "Parsed: \"" << str << "\"" << endl;
+ }
+ else
+ {
+ cout << "Failed to refactor an action!" << endl;
+ }
+
+// Parsing the same test string without refactoring fails, because the
+// anychar_p eats up all the input up to the end of the string
+
+ result =
+ parse(test_string2,
+ ((*anychar_p)[refactor_action_actor(str)] - '$') >> '$'
+ );
+
+ if (result.full)
+ {
+ cout << "Successfully parsed test string!" << endl;
+ cout << "Parsed: \"" << str << "\"" << endl;
+ }
+ else
+ {
+ cout
+ << "Correctly failed parsing the test string (without refactoring)!"
+ << endl;
+ cout << "Parsed instead: \"" << str << "\"" << endl;
+ }
+ cout << endl;
+
+ return 0;
+}
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/regular_expression.cpp b/src/boost/libs/spirit/classic/example/fundamental/regular_expression.cpp
new file mode 100644
index 00000000..48b33cea
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/regular_expression.cpp
@@ -0,0 +1,110 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// Demonstrate regular expression parser objects
+// See the "Regular Expression Parser" chapter in the User's Guide.
+//
+// This sample requires an installed version of the boost regex library
+// (http://www.boost.org) The sample was tested with boost V1.28.0
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <string>
+#include <iostream>
+
+#include <boost/version.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// The following header must be included, if regular expression support is
+// required for Spirit.
+//
+// The BOOST_SPIRIT_NO_REGEX_LIB PP constant should be defined, if you're
+// using the Boost.Regex library from one translation unit only. Otherwise
+// you have to link with the Boost.Regex library as defined in the related
+// documentation (see. http://www.boost.org).
+//
+// For Boost > V1.32.0 you'll always have to link against the Boost.Regex
+// libraries.
+//
+///////////////////////////////////////////////////////////////////////////////
+#if BOOST_VERSION <= 103200
+#define BOOST_SPIRIT_NO_REGEX_LIB
+#endif
+#include <boost/spirit/include/classic_regex.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// used namespaces
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+// main entry point
+int main()
+{
+ const char *ptest = "123 E 456";
+ const char *prx = "[1-9]+[[:space:]]*E[[:space:]]*";
+
+ cout << "Parse " << ptest << " against regular expression: " << prx
+ << endl;
+
+ // 1. direct use of rxlit<>
+ rxstrlit<> regexpr(prx);
+ parse_info<> result;
+ string str;
+
+ result = parse (ptest, regexpr[assign(str)]);
+ if (result.hit)
+ {
+ cout << "Parsed regular expression successfully!" << endl;
+ cout << "Matched (" << (int)result.length << ") characters: ";
+ cout << "\"" << str << "\"" << endl;
+ }
+ else
+ {
+ cout << "Failed to parse regular expression!" << endl;
+ }
+ cout << endl;
+
+ // 2. use of regex_p predefined parser object
+ str.empty();
+ result = parse (ptest, regex_p(prx)[assign(str)]);
+ if (result.hit)
+ {
+ cout << "Parsed regular expression successfully!" << endl;
+ cout << "Matched (" << (int)result.length << ") characters: ";
+ cout << "\"" << str << "\"" << endl;
+ }
+ else
+ {
+ cout << "Failed to parse regular expression!" << endl;
+ }
+ cout << endl;
+
+ // 3. test the regression reported by Grzegorz Marcin Koczyk (gkoczyk@echostar.pl)
+ string str1;
+ string str2;
+ char const *ptest1 = "Token whatever \nToken";
+
+ result = parse(ptest1, rxstrlit<>("Token")[assign(str1)]
+ >> rxstrlit<>("Token")[assign(str2)]);
+
+ if (!result.hit)
+ cout << "Parsed regular expression successfully!" << endl;
+ else
+ cout << "Failed to parse regular expression!" << endl;
+
+ cout << endl;
+
+ return 0;
+}
+
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/roman_numerals.cpp b/src/boost/libs/spirit/classic/example/fundamental/roman_numerals.cpp
new file mode 100644
index 00000000..32f26d9e
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/roman_numerals.cpp
@@ -0,0 +1,189 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// A Roman Numerals Parser (demonstrating the symbol table). This is
+// discussed in the "Symbols" chapter in the Spirit User's Guide.
+//
+// [ JDG 8/22/2002 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_symbols.hpp>
+#include <iostream>
+#include <string>
+
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Parse roman hundreds (100..900) numerals using the symbol table.
+// Notice that the data associated with each slot is passed
+// to attached semantic actions.
+//
+///////////////////////////////////////////////////////////////////////////////
+struct hundreds : symbols<unsigned>
+{
+ hundreds()
+ {
+ add
+ ("C" , 100)
+ ("CC" , 200)
+ ("CCC" , 300)
+ ("CD" , 400)
+ ("D" , 500)
+ ("DC" , 600)
+ ("DCC" , 700)
+ ("DCCC" , 800)
+ ("CM" , 900)
+ ;
+ }
+
+} hundreds_p;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Parse roman tens (10..90) numerals using the symbol table.
+//
+///////////////////////////////////////////////////////////////////////////////
+struct tens : symbols<unsigned>
+{
+ tens()
+ {
+ add
+ ("X" , 10)
+ ("XX" , 20)
+ ("XXX" , 30)
+ ("XL" , 40)
+ ("L" , 50)
+ ("LX" , 60)
+ ("LXX" , 70)
+ ("LXXX" , 80)
+ ("XC" , 90)
+ ;
+ }
+
+} tens_p;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Parse roman ones (1..9) numerals using the symbol table.
+//
+///////////////////////////////////////////////////////////////////////////////
+struct ones : symbols<unsigned>
+{
+ ones()
+ {
+ add
+ ("I" , 1)
+ ("II" , 2)
+ ("III" , 3)
+ ("IV" , 4)
+ ("V" , 5)
+ ("VI" , 6)
+ ("VII" , 7)
+ ("VIII" , 8)
+ ("IX" , 9)
+ ;
+ }
+
+} ones_p;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Semantic actions
+//
+///////////////////////////////////////////////////////////////////////////////
+struct add_1000
+{
+ add_1000(unsigned& r_) : r(r_) {}
+ void operator()(char) const { r += 1000; }
+ unsigned& r;
+};
+
+struct add_roman
+{
+ add_roman(unsigned& r_) : r(r_) {}
+ void operator()(unsigned n) const { r += n; }
+ unsigned& r;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// roman (numerals) grammar
+//
+///////////////////////////////////////////////////////////////////////////////
+struct roman : public grammar<roman>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(roman const& self)
+ {
+ first
+ = +ch_p('M') [add_1000(self.r)]
+ || hundreds_p [add_roman(self.r)]
+ || tens_p [add_roman(self.r)]
+ || ones_p [add_roman(self.r)];
+
+ // Note the use of the || operator. The expression
+ // a || b reads match a or b and in sequence. Try
+ // defining the roman numerals grammar in YACC or
+ // PCCTS. Spirit rules! :-)
+ }
+
+ rule<ScannerT> first;
+ rule<ScannerT> const&
+ start() const { return first; }
+ };
+
+ roman(unsigned& r_) : r(r_) {}
+ unsigned& r;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main driver code
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tRoman Numerals Parser\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "Type a Roman Numeral ...or [q or Q] to quit\n\n";
+
+ // Start grammar definition
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ unsigned n = 0;
+ roman roman_p(n);
+ if (parse(str.c_str(), roman_p).full)
+ {
+ cout << "parsing succeeded\n";
+ cout << "result = " << n << "\n\n";
+ }
+ else
+ {
+ cout << "parsing failed\n\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/example/fundamental/stuff_vector.cpp b/src/boost/libs/spirit/classic/example/fundamental/stuff_vector.cpp
new file mode 100644
index 00000000..77f51b27
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/stuff_vector.cpp
@@ -0,0 +1,114 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// This sample demontrates a parser for a comma separated list of numbers
+// This is the phoenix version of number_list.cpp.
+// This is discussed in the "Phoenix" chapter in the Spirit User's Guide.
+//
+// [ JDG 1/12/2004 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_operators.hpp>
+#include <boost/spirit/include/phoenix1_functions.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <iostream>
+#include <string>
+
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace phoenix;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Our comma separated list parser
+//
+///////////////////////////////////////////////////////////////////////////////
+struct push_back_impl
+{
+ template <typename Container, typename Item>
+ struct result
+ {
+ typedef void type;
+ };
+
+ template <typename Container, typename Item>
+ void operator()(Container& c, Item const& item) const
+ {
+ c.push_back(item);
+ }
+};
+
+function<push_back_impl> const push_back = push_back_impl();
+
+bool
+parse_numbers(char const* str, vector<double>& v)
+{
+ return parse(str,
+
+ // Begin grammar
+ (
+ real_p[push_back(var(v), arg1)]
+ >> *(',' >> real_p[push_back(var(v), arg1)])
+ )
+ ,
+ // End grammar
+
+ space_p).full;
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tA comma separated list parser for Spirit...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+
+ cout << "Give me a comma separated list of numbers.\n";
+ cout << "The numbers will be inserted in a vector of numbers\n";
+ cout << "Type [q or Q] to quit\n\n";
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ vector<double> v;
+ if (parse_numbers(str.c_str(), v))
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ cout << str << " Parses OK: " << endl;
+
+ for (vector<double>::size_type i = 0; i < v.size(); ++i)
+ cout << i << ": " << v[i] << endl;
+
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "-------------------------\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/stuff_vector2.cpp b/src/boost/libs/spirit/classic/example/fundamental/stuff_vector2.cpp
new file mode 100644
index 00000000..a5a3232c
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/stuff_vector2.cpp
@@ -0,0 +1,125 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// This sample demontrates a parser for a comma separated list of identifiers
+// This is a variation of stuff_vector.cpp.
+// This is discussed in the "Phoenix" chapter in the Spirit User's Guide.
+//
+// [ JDG 1/12/2004 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_operators.hpp>
+#include <boost/spirit/include/phoenix1_functions.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_casts.hpp>
+#include <iostream>
+#include <string>
+
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace phoenix;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Our comma separated list parser
+//
+///////////////////////////////////////////////////////////////////////////////
+struct push_back_impl
+{
+ template <typename Container, typename Item>
+ struct result
+ {
+ typedef void type;
+ };
+
+ template <typename Container, typename Item>
+ void operator()(Container& c, Item const& item) const
+ {
+ c.push_back(item);
+ }
+};
+
+function<push_back_impl> const push_back = push_back_impl();
+
+bool
+parse_identifiers(char const* str, vector<std::string>& v)
+{
+ return parse(str,
+
+ // Begin grammar
+ (
+ (+alpha_p)
+ [
+ push_back(var(v), construct_<std::string>(arg1, arg2))
+ ]
+ >>
+ *(',' >>
+ (+alpha_p)
+ [
+ push_back(var(v), construct_<std::string>(arg1, arg2))
+ ]
+ )
+ )
+ ,
+ // End grammar
+
+ space_p).full;
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tA comma separated list parser for Spirit...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+
+ cout << "Give me a comma separated list of identifiers.\n";
+ cout << "An identifier is comprised of one or more alphabetic characters.\n";
+ cout << "The identifiers will be inserted in a vector of numbers\n";
+ cout << "Type [q or Q] to quit\n\n";
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ vector<std::string> v;
+ if (parse_identifiers(str.c_str(), v))
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ cout << str << " Parses OK: " << endl;
+
+ for (vector<std::string>::size_type i = 0; i < v.size(); ++i)
+ cout << i << ": " << v[i] << endl;
+
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "-------------------------\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/subrule_calc.cpp b/src/boost/libs/spirit/classic/example/fundamental/subrule_calc.cpp
new file mode 100644
index 00000000..238a1299
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/subrule_calc.cpp
@@ -0,0 +1,140 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// This calculator example demontrates the use of subrules.
+// This is discussed in the "Subrule" chapter in the Spirit User's Guide.
+//
+// [ JDG 4/11/2002 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+
+//#define BOOST_SPIRIT_DEBUG // define this for debug output
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <iostream>
+#include <string>
+
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Semantic actions
+//
+///////////////////////////////////////////////////////////////////////////////
+namespace
+{
+ void do_int(char const* str, char const* end)
+ {
+ string s(str, end);
+ cout << "PUSH(" << s << ')' << endl;
+ }
+
+ void do_add(char const*, char const*) { cout << "ADD\n"; }
+ void do_subt(char const*, char const*) { cout << "SUBTRACT\n"; }
+ void do_mult(char const*, char const*) { cout << "MULTIPLY\n"; }
+ void do_div(char const*, char const*) { cout << "DIVIDE\n"; }
+ void do_neg(char const*, char const*) { cout << "NEGATE\n"; }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Our calculator grammar (using subrules)
+//
+///////////////////////////////////////////////////////////////////////////////
+struct calculator : public grammar<calculator>
+{
+ template <typename ScannerT>
+ struct definition {
+
+ definition(calculator const& /*self*/)
+ {
+ first = (
+
+ expression =
+ term
+ >> *( ('+' >> term)[&do_add]
+ | ('-' >> term)[&do_subt]
+ )
+ ,
+
+ term =
+ factor
+ >> *( ('*' >> factor)[&do_mult]
+ | ('/' >> factor)[&do_div]
+ )
+ ,
+
+ factor
+ = lexeme_d[(+digit_p)[&do_int]]
+ | '(' >> expression >> ')'
+ | ('-' >> factor)[&do_neg]
+ | ('+' >> factor)
+ );
+
+ BOOST_SPIRIT_DEBUG_NODE(first);
+ BOOST_SPIRIT_DEBUG_NODE(expression);
+ BOOST_SPIRIT_DEBUG_NODE(term);
+ BOOST_SPIRIT_DEBUG_NODE(factor);
+ }
+
+ subrule<0> expression;
+ subrule<1> term;
+ subrule<2> factor;
+
+ rule<ScannerT> first;
+ rule<ScannerT> const&
+ start() const { return first; }
+ };
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tA calculator using subrules...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "Type an expression...or [q or Q] to quit\n\n";
+
+ calculator calc; // Our parser
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ parse_info<> info = parse(str.c_str(), calc, space_p);
+
+ if (info.full)
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "stopped at: \": " << info.stop << "\"\n";
+ cout << "-------------------------\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/sum.cpp b/src/boost/libs/spirit/classic/example/fundamental/sum.cpp
new file mode 100644
index 00000000..d6dd9c9d
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/sum.cpp
@@ -0,0 +1,92 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// A parser for summing a list of numbers. Demonstrating phoenix
+// This is discussed in the "Phoenix" chapter in the Spirit User's Guide.
+//
+// [ JDG 6/28/2002 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_operators.hpp>
+#include <iostream>
+#include <string>
+
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace phoenix;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Our adder
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename IteratorT>
+bool adder(IteratorT first, IteratorT last, double& n)
+{
+ return parse(first, last,
+
+ // Begin grammar
+ (
+ real_p[var(n) = arg1] >> *(',' >> real_p[var(n) += arg1])
+ )
+ ,
+ // End grammar
+
+ space_p).full;
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tA parser for summing a list of numbers...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+
+ cout << "Give me a comma separated list of numbers.\n";
+ cout << "The numbers are added using Phoenix.\n";
+ cout << "Type [q or Q] to quit\n\n";
+
+ string str;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ double n;
+ if (adder(str.begin(), str.end(), n))
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ cout << str << " Parses OK: " << endl;
+
+ cout << "sum = " << n;
+ cout << "\n-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "-------------------------\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/thousand_separated.cpp b/src/boost/libs/spirit/classic/example/fundamental/thousand_separated.cpp
new file mode 100644
index 00000000..1b84e05b
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/thousand_separated.cpp
@@ -0,0 +1,133 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// A parser for a real number parser that parses thousands separated numbers
+// with at most two decimal places and no exponent. This is discussed in the
+// "Numerics" chapter in the Spirit User's Guide.
+//
+// [ JDG 12/16/2003 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_assign_actor.hpp>
+#include <iostream>
+#include <string>
+
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+template <typename T>
+struct ts_real_parser_policies : public ureal_parser_policies<T>
+{
+ // These policies can be used to parse thousand separated
+ // numbers with at most 2 decimal digits after the decimal
+ // point. e.g. 123,456,789.01
+
+ typedef uint_parser<int, 10, 1, 2> uint2_t;
+ typedef uint_parser<T, 10, 1, -1> uint_parser_t;
+ typedef int_parser<int, 10, 1, -1> int_parser_t;
+
+ ////////////////////////////////// 2 decimal places Max
+ template <typename ScannerT>
+ static typename parser_result<uint2_t, ScannerT>::type
+ parse_frac_n(ScannerT& scan)
+ { return uint2_t().parse(scan); }
+
+ ////////////////////////////////// No exponent
+ template <typename ScannerT>
+ static typename parser_result<chlit<>, ScannerT>::type
+ parse_exp(ScannerT& scan)
+ { return scan.no_match(); }
+
+ ////////////////////////////////// No exponent
+ template <typename ScannerT>
+ static typename parser_result<int_parser_t, ScannerT>::type
+ parse_exp_n(ScannerT& scan)
+ { return scan.no_match(); }
+
+ ////////////////////////////////// Thousands separated numbers
+ template <typename ScannerT>
+ static typename parser_result<uint_parser_t, ScannerT>::type
+ parse_n(ScannerT& scan)
+ {
+ typedef typename parser_result<uint_parser_t, ScannerT>::type RT;
+ static uint_parser<unsigned, 10, 1, 3> uint3_p;
+ static uint_parser<unsigned, 10, 3, 3> uint3_3_p;
+ if (RT hit = uint3_p.parse(scan))
+ {
+ T n;
+ typedef typename ScannerT::iterator_t iterator_t;
+ iterator_t save = scan.first;
+ while (match<> next = (',' >> uint3_3_p[assign_a(n)]).parse(scan))
+ {
+ hit.value((hit.value() * 1000) + n);
+ scan.concat_match(hit, next);
+ save = scan.first;
+ }
+ scan.first = save;
+ return hit;
+
+ // Note: On erroneous input such as "123,45", the result should
+ // be a partial match "123". 'save' is used to makes sure that
+ // the scanner position is placed at the last *valid* parse
+ // position.
+ }
+ return scan.no_match();
+ }
+};
+
+real_parser<double, ts_real_parser_policies<double> > const
+ ts_real_p = real_parser<double, ts_real_parser_policies<double> >();
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tA real number parser that parses thousands separated\n";
+ cout << "\t\tnumbers with at most two decimal places and no exponent...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+
+ cout << "Give me a number.\n";
+ cout << "Type [q or Q] to quit\n\n";
+
+ string str;
+ double n;
+ while (getline(cin, str))
+ {
+ if (str.empty() || str[0] == 'q' || str[0] == 'Q')
+ break;
+
+ if (parse(str.c_str(), ts_real_p[assign_a(n)]).full)
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+ cout << str << " Parses OK: " << endl;
+ cout << "n=" << n << endl;
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing failed\n";
+ cout << "-------------------------\n";
+ }
+ }
+
+ cout << "Bye... :-) \n\n";
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/fundamental/tree_calc_grammar.hpp b/src/boost/libs/spirit/classic/example/fundamental/tree_calc_grammar.hpp
new file mode 100644
index 00000000..26e42261
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/fundamental/tree_calc_grammar.hpp
@@ -0,0 +1,76 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Daniel Nuffer
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#ifndef BOOST_SPIRIT_TREE_CALC_GRAMMAR_HPP_
+#define BOOST_SPIRIT_TREE_CALC_GRAMMAR_HPP_
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Demonstrates the AST and parse trees. This is discussed in the
+// "Trees" chapter in the Spirit User's Guide.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Our calculator grammar
+//
+////////////////////////////////////////////////////////////////////////////
+struct calculator : public grammar<calculator>
+{
+ static const int integerID = 1;
+ static const int factorID = 2;
+ static const int termID = 3;
+ static const int expressionID = 4;
+
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(calculator const& /*self*/)
+ {
+ // Start grammar definition
+ integer = leaf_node_d[ lexeme_d[
+ (!ch_p('-') >> +digit_p)
+ ] ];
+
+ factor = integer
+ | inner_node_d[ch_p('(') >> expression >> ch_p(')')]
+ | (root_node_d[ch_p('-')] >> factor);
+
+ term = factor >>
+ *( (root_node_d[ch_p('*')] >> factor)
+ | (root_node_d[ch_p('/')] >> factor)
+ );
+
+ expression = term >>
+ *( (root_node_d[ch_p('+')] >> term)
+ | (root_node_d[ch_p('-')] >> term)
+ );
+ // End grammar definition
+
+ // turn on the debugging info.
+ BOOST_SPIRIT_DEBUG_RULE(integer);
+ BOOST_SPIRIT_DEBUG_RULE(factor);
+ BOOST_SPIRIT_DEBUG_RULE(term);
+ BOOST_SPIRIT_DEBUG_RULE(expression);
+ }
+
+ rule<ScannerT, parser_context<>, parser_tag<expressionID> > expression;
+ rule<ScannerT, parser_context<>, parser_tag<termID> > term;
+ rule<ScannerT, parser_context<>, parser_tag<factorID> > factor;
+ rule<ScannerT, parser_context<>, parser_tag<integerID> > integer;
+
+ rule<ScannerT, parser_context<>, parser_tag<expressionID> > const&
+ start() const { return expression; }
+ };
+};
+
+#endif
+
diff --git a/src/boost/libs/spirit/classic/example/intermediate/ipv4.cpp b/src/boost/libs/spirit/classic/example/intermediate/ipv4.cpp
new file mode 100644
index 00000000..93453bac
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/intermediate/ipv4.cpp
@@ -0,0 +1,304 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_push_back_actor.hpp>
+#include <boost/spirit/include/classic_if.hpp>
+#include <boost/spirit/include/classic_for.hpp>
+#include <boost/spirit/include/phoenix1.hpp>
+#include <iostream>
+#include <string>
+#include <vector>
+#include <algorithm>
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Sample parser for binary data. This sample highlights the use of dynamic
+// parsing where the result of actions direct the actual parsing behavior.
+// We shall demonstrate 1) the use of phoenix to implement lambda (unnamed)
+// functions, 2) dynamic looping using for_p, 3) the push_back_a actor for
+// stuffing data into a vector, and 4) the if_p parser for choosing parser
+// branches based on semantic conditions.
+//
+// << Sample idea by Florian Weimer >>
+//
+// For simplicity, we shall use bytes as atoms (and not 16-bit quantities
+// in big-endian format or something similar, which would be more realistic)
+// and PASCAL strings.
+//
+// A packet is the literal octet with value 255, followed by a variable
+// octet N (denoting the total length of the packet), followed by N-2 octets
+// (the payload). The payload contains a variable-length header, followed
+// by zero or more elements.
+//
+// The header contains a single PASCAL string.
+//
+// An element is a PASCAL string (alternative: an element is an octet M,
+// followed by [M/8] bytes, i.e. the necessary number of bytes to store M
+// bits).
+//
+// (This data structure is inspired by the format of a BGP UPDATE message.)
+//
+// Packet layout:
+//
+// .-------------------.
+// | 0xff | ^
+// +-------------------+ |
+// | packet length | |
+// +-------------------+ | number of bytes indicated by packet length
+// : : |
+// : payload : |
+// | | v
+// `-------------------'
+//
+// Payload layout:
+//
+// .-------------------.
+// | header length |
+// +-------------------+
+// | header octets | ^
+// : : | number of octets given by header length
+// : : |
+// : : v
+// +-------------------+
+// | IPv4 prefix | ^
+// : : | IPv4 prefixes have variable length (see
+// +-------------------+ | below). The number of prefixes is
+// | IPv4 prefix | | determined by the packet length.
+// : : |
+// +-------------------+ |
+// : : |
+// : : v
+//
+//
+// IPv4 prefix layout comes in five variants, depending on the first
+// octet:
+//
+// .-------------------.
+// | 0x00 | single octet, corresponds to 0.0.0.0/0
+// `-------------------'
+//
+// .-------------------.
+// | 0x01 to 0x08 | two octets, prefix lengths up to /8.
+// +-------------------+
+// | MSB of network |
+// `-------------------'
+//
+// .-------------------.
+// | 0x09 to 0x10 | three octets, prefix lengths up to /16.
+// +-------------------+
+// | MSB of network |
+// +-------------------+
+// | next octet |
+// `-------------------'
+//
+// .-------------------.
+// | 0x11 to 0x18 | four octets, prefix lengths up to /24.
+// +-------------------+
+// | MSB of network |
+// +-------------------+
+// | next octet |
+// +-------------------+
+// | next octet |
+// `-------------------'
+//
+// .-------------------.
+// | 0x19 to 0x20 | five octets, prefix lengths up to /32.
+// +-------------------+
+// | MSB of network |
+// +-------------------+
+// | next octet |
+// +-------------------+
+// | next octet |
+// +-------------------+
+// | LSB of network |
+// `-------------------'
+//
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace phoenix;
+
+struct ipv4_prefix_data
+{
+ char prefix_len, n0, n1, n2, n3;
+
+ ipv4_prefix_data()
+ : prefix_len(0),n0(0),n1(0),n2(0),n3(0) {}
+};
+
+struct ipv4_data
+{
+ char packet_len, header_len;
+ std::string header;
+ std::vector<ipv4_prefix_data> prefixes;
+
+ ipv4_data()
+ : packet_len(0),header_len(0){}
+
+};
+
+struct ipv4 : public grammar<ipv4>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(ipv4 const& self)
+ {
+ packet =
+ '\xff'
+ >> anychar_p[var(self.data.packet_len) = arg1]
+ >> payload
+ ;
+
+ payload =
+ anychar_p[var(self.data.header_len) = arg1]
+ >> for_p(var(i) = 0, var(i) < var(self.data.header_len), ++var(i))
+ [
+ anychar_p[var(self.data.header) += arg1]
+ ]
+ >> *ipv4_prefix
+ ;
+
+ ipv4_prefix =
+ anychar_p
+ [
+ var(temp.prefix_len) = arg1,
+ var(temp.n0) = 0,
+ var(temp.n1) = 0,
+ var(temp.n2) = 0,
+ var(temp.n3) = 0
+ ]
+
+ >> if_p(var(temp.prefix_len) > 0x00)
+ [
+ anychar_p[var(temp.n0) = arg1]
+ >> if_p(var(temp.prefix_len) > 0x08)
+ [
+ anychar_p[var(temp.n1) = arg1]
+ >> if_p(var(temp.prefix_len) > 0x10)
+ [
+ anychar_p[var(temp.n2) = arg1]
+ >> if_p(var(temp.prefix_len) > 0x18)
+ [
+ anychar_p[var(temp.n3) = arg1]
+ ]
+ ]
+ ]
+ ]
+ [
+ push_back_a(self.data.prefixes, temp)
+ ]
+ ;
+ }
+
+ int i;
+ ipv4_prefix_data temp;
+ rule<ScannerT> packet, payload, ipv4_prefix;
+ rule<ScannerT> const&
+ start() const { return packet; }
+ };
+
+ ipv4(ipv4_data& data)
+ : data(data) {}
+
+ ipv4_data& data;
+};
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+////////////////////////////////////////////////////////////////////////////
+int
+as_byte(char n)
+{
+ if (n < 0)
+ return n + 256;
+ return n;
+}
+
+void
+print_prefix(ipv4_prefix_data const& prefix)
+{
+ cout << "prefix length = " << as_byte(prefix.prefix_len) << endl;
+ cout << "n0 = " << as_byte(prefix.n0) << endl;
+ cout << "n1 = " << as_byte(prefix.n1) << endl;
+ cout << "n2 = " << as_byte(prefix.n2) << endl;
+ cout << "n3 = " << as_byte(prefix.n3) << endl;
+}
+
+void
+parse_ipv4(char const* str, unsigned len)
+{
+ ipv4_data data;
+ ipv4 g(data);
+ parse_info<> info = parse(str, str+len, g);
+
+ if (info.full)
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+
+ cout << "packet length = " << as_byte(data.packet_len) << endl;
+ cout << "header length = " << as_byte(data.header_len) << endl;
+ cout << "header = " << data.header << endl;
+
+ for_each(data.prefixes.begin(), data.prefixes.end(), print_prefix);
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "Parsing failed\n";
+ cout << "stopped at:";
+ for (char const* s = info.stop; s != str+len; ++s)
+ cout << static_cast<int>(*s) << endl;
+ }
+}
+
+// Test inputs:
+
+// The string in the header is "empty", the prefix list is empty.
+char const i1[8] =
+{
+ 0xff,0x08,0x05,
+ 'e','m','p','t','y'
+};
+
+// The string in the header is "default route", the prefix list
+// has just one element, 0.0.0.0/0.
+char const i2[17] =
+{
+ 0xff,0x11,0x0d,
+ 'd','e','f','a','u','l','t',' ',
+ 'r','o','u','t','e',
+ 0x00
+};
+
+// The string in the header is "private address space", the prefix list
+// has the elements 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16.
+char const i3[32] =
+{
+ 0xff,0x20,0x15,
+ 'p','r','i','v','a','t','e',' ',
+ 'a','d','d','r','e','s','s',' ',
+ 's','p','a','c','e',
+ 0x08,0x0a,
+ 0x0c,0xac,0x10,
+ 0x10,0xc0,0xa8
+};
+
+int
+main()
+{
+ parse_ipv4(i1, sizeof(i1));
+ parse_ipv4(i2, sizeof(i2));
+ parse_ipv4(i3, sizeof(i3));
+ return 0;
+}
+
diff --git a/src/boost/libs/spirit/classic/example/intermediate/ipv4_opt.cpp b/src/boost/libs/spirit/classic/example/intermediate/ipv4_opt.cpp
new file mode 100644
index 00000000..ed5429fd
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/intermediate/ipv4_opt.cpp
@@ -0,0 +1,213 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_push_back_actor.hpp>
+#include <boost/spirit/include/classic_if.hpp>
+#include <boost/spirit/include/classic_for.hpp>
+#include <boost/spirit/include/phoenix1.hpp>
+#include <iostream>
+#include <string>
+#include <vector>
+#include <algorithm>
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Please check it out ipv4.cpp sample first!
+// << See ipv4.cpp sample for details >>
+//
+// This is a variation of the ipv4.cpp sample. The original ipv4.cpp code
+// compiles to 36k on MSVC7.1. Not bad! Yet, we want to shave a little bit
+// more. Is it possible? Yes! This time, we'll use subrules and just store
+// the rules in a plain old struct. We are parsing at the char level anyway,
+// so we know what type of rule we'll need: a plain rule<>. The result: we
+// shaved off another 20k. Now the code compiles to 16k on MSVC7.1.
+//
+// Could we have done better? Yes, but only if only we had typeof! << See
+// the techniques section of the User's guide >> ... Someday... :-)
+//
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace phoenix;
+
+struct ipv4_prefix_data
+{
+ char prefix_len, n0, n1, n2, n3;
+
+ ipv4_prefix_data()
+ : prefix_len(0),n0(0),n1(0),n2(0),n3(0) {}
+};
+
+struct ipv4_data
+{
+ char packet_len, header_len;
+ std::string header;
+ std::vector<ipv4_prefix_data> prefixes;
+
+ ipv4_data()
+ : packet_len(0),header_len(0){}
+
+};
+
+struct ipv4
+{
+ ipv4(ipv4_data& data)
+ : data(data)
+ {
+ start =
+ (
+ packet =
+ '\xff'
+ >> anychar_p[var(data.packet_len) = arg1]
+ >> payload
+ ,
+
+ payload =
+ anychar_p[var(data.header_len) = arg1]
+ >> for_p(var(i) = 0, var(i) < var(data.header_len), ++var(i))
+ [
+ anychar_p[var(data.header) += arg1]
+ ]
+ >> *ipv4_prefix
+ ,
+
+ ipv4_prefix =
+ anychar_p
+ [
+ var(temp.prefix_len) = arg1,
+ var(temp.n0) = 0,
+ var(temp.n1) = 0,
+ var(temp.n2) = 0,
+ var(temp.n3) = 0
+ ]
+
+ >> if_p(var(temp.prefix_len) > 0x00)
+ [
+ anychar_p[var(temp.n0) = arg1]
+ >> if_p(var(temp.prefix_len) > 0x08)
+ [
+ anychar_p[var(temp.n1) = arg1]
+ >> if_p(var(temp.prefix_len) > 0x10)
+ [
+ anychar_p[var(temp.n2) = arg1]
+ >> if_p(var(temp.prefix_len) > 0x18)
+ [
+ anychar_p[var(temp.n3) = arg1]
+ ]
+ ]
+ ]
+ ]
+ [
+ push_back_a(data.prefixes, temp)
+ ]
+ );
+ }
+
+ int i;
+ ipv4_prefix_data temp;
+
+ rule<> start;
+ subrule<0> packet;
+ subrule<1> payload;
+ subrule<2> ipv4_prefix;
+ ipv4_data& data;
+};
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Main program
+//
+////////////////////////////////////////////////////////////////////////////
+int
+as_byte(char n)
+{
+ if (n < 0)
+ return n + 256;
+ return n;
+}
+
+void
+print_prefix(ipv4_prefix_data const& prefix)
+{
+ cout << "prefix length = " << as_byte(prefix.prefix_len) << endl;
+ cout << "n0 = " << as_byte(prefix.n0) << endl;
+ cout << "n1 = " << as_byte(prefix.n1) << endl;
+ cout << "n2 = " << as_byte(prefix.n2) << endl;
+ cout << "n3 = " << as_byte(prefix.n3) << endl;
+}
+
+void
+parse_ipv4(char const* str, unsigned len)
+{
+ ipv4_data data;
+ ipv4 g(data);
+ parse_info<> info = parse(str, str+len, g.start);
+
+ if (info.full)
+ {
+ cout << "-------------------------\n";
+ cout << "Parsing succeeded\n";
+
+ cout << "packet length = " << as_byte(data.packet_len) << endl;
+ cout << "header length = " << as_byte(data.header_len) << endl;
+ cout << "header = " << data.header << endl;
+
+ for_each(data.prefixes.begin(), data.prefixes.end(), print_prefix);
+ cout << "-------------------------\n";
+ }
+ else
+ {
+ cout << "Parsing failed\n";
+ cout << "stopped at:";
+ for (char const* s = info.stop; s != str+len; ++s)
+ cout << static_cast<int>(*s) << endl;
+ }
+}
+
+// Test inputs:
+
+// The string in the header is "empty", the prefix list is empty.
+char const i1[8] =
+{
+ 0xff,0x08,0x05,
+ 'e','m','p','t','y'
+};
+
+// The string in the header is "default route", the prefix list
+// has just one element, 0.0.0.0/0.
+char const i2[17] =
+{
+ 0xff,0x11,0x0d,
+ 'd','e','f','a','u','l','t',' ',
+ 'r','o','u','t','e',
+ 0x00
+};
+
+// The string in the header is "private address space", the prefix list
+// has the elements 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16.
+char const i3[32] =
+{
+ 0xff,0x20,0x15,
+ 'p','r','i','v','a','t','e',' ',
+ 'a','d','d','r','e','s','s',' ',
+ 's','p','a','c','e',
+ 0x08,0x0a,
+ 0x0c,0xac,0x10,
+ 0x10,0xc0,0xa8
+};
+
+int
+main()
+{
+ parse_ipv4(i1, sizeof(i1));
+ parse_ipv4(i2, sizeof(i2));
+ parse_ipv4(i3, sizeof(i3));
+ return 0;
+}
+
diff --git a/src/boost/libs/spirit/classic/example/intermediate/lazy_parser.cpp b/src/boost/libs/spirit/classic/example/intermediate/lazy_parser.cpp
new file mode 100644
index 00000000..6035fd80
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/intermediate/lazy_parser.cpp
@@ -0,0 +1,126 @@
+/*=============================================================================
+ Copyright (c) 2003 Vaclav Vesely
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+//
+// This example demonstrates the lazy_p parser. You should read
+// "The Lazy Parser" in the documentation.
+//
+// We want to parse nested blocks of numbers like this:
+//
+// dec {
+// 1 2 3
+// bin {
+// 1 10 11
+// }
+// 4 5 6
+// }
+//
+// where the numbers in the "dec" block are wrote in the decimal system and
+// the numbers in the "bin" block are wrote in the binary system. We want
+// parser to return the overall sum.
+//
+// To achive this when base ("bin" or "dec") is parsed, in semantic action
+// we store a pointer to the appropriate numeric parser in the closure
+// variable block.int_rule. Than, when we need to parse a number we use lazy_p
+// parser to invoke the parser stored in the block.int_rule pointer.
+//
+//-----------------------------------------------------------------------------
+#include <boost/assert.hpp>
+#include <boost/cstdlib.hpp>
+#include <boost/spirit/include/phoenix1.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_symbols.hpp>
+#include <boost/spirit/include/classic_attribute.hpp>
+#include <boost/spirit/include/classic_dynamic.hpp>
+
+using namespace boost;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace phoenix;
+
+//-----------------------------------------------------------------------------
+// my grammar
+
+struct my_grammar
+ : public grammar<my_grammar, parser_context<int> >
+{
+ // grammar definition
+ template<typename ScannerT>
+ struct definition
+ {
+ typedef rule<ScannerT> rule_t;
+ typedef stored_rule<ScannerT, parser_context<int> > number_rule_t;
+
+ struct block_closure;
+ typedef boost::spirit::classic::closure<
+ block_closure,
+ int,
+ typename number_rule_t::alias_t>
+ closure_base_t;
+
+ struct block_closure : closure_base_t
+ {
+ typename closure_base_t::member1 sum;
+ typename closure_base_t::member2 int_rule;
+ };
+
+ // block rule type
+ typedef rule<ScannerT, typename block_closure::context_t> block_rule_t;
+
+ block_rule_t block;
+ rule_t block_item;
+ symbols<number_rule_t> base;
+
+ definition(my_grammar const& self)
+ {
+ block =
+ base[
+ block.sum = 0,
+ // store a number rule in a closure member
+ block.int_rule = arg1
+ ]
+ >> "{"
+ >> *block_item
+ >> "}"
+ ;
+
+ block_item =
+ // use the stored rule
+ lazy_p(block.int_rule)[block.sum += arg1]
+ | block[block.sum += arg1]
+ ;
+
+ // bind base keywords and number parsers
+ base.add
+ ("bin", bin_p)
+ ("dec", uint_p)
+ ;
+ }
+
+ block_rule_t const& start() const
+ {
+ return block;
+ }
+ };
+};
+
+//-----------------------------------------------------------------------------
+
+int main()
+{
+ my_grammar gram;
+ parse_info<> info;
+
+ int result;
+ info = parse("bin{1 dec{1 2 3} 10}", gram[var(result) = arg1], space_p);
+ BOOST_ASSERT(info.full);
+ BOOST_ASSERT(result == 9);
+
+ return exit_success;
+}
+
+//-----------------------------------------------------------------------------
diff --git a/src/boost/libs/spirit/classic/example/intermediate/parameters.cpp b/src/boost/libs/spirit/classic/example/intermediate/parameters.cpp
new file mode 100644
index 00000000..b93fb0ec
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/intermediate/parameters.cpp
@@ -0,0 +1,216 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+// This sample show the usage of parser parameters.
+//
+// Parser parameters are used to pass some values from the outer parsing scope
+// to the next inner scope. They can be imagined as the opposite to the return
+// value paradigm, which returns some value from the inner to the next outer
+// scope. See the "Closures" chapter in the User's Guide.
+
+#include <string>
+#include <iostream>
+#include <cassert>
+
+#if defined(_MSC_VER) /*&& !defined(__COMO__)*/
+#pragma warning(disable: 4244)
+#pragma warning(disable: 4355)
+#endif // defined(_MSC_VER) && !defined(__COMO__)
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_symbols.hpp>
+#include <boost/spirit/include/classic_closure.hpp>
+
+#include <boost/spirit/include/phoenix1_tuples.hpp>
+#include <boost/spirit/include/phoenix1_tuple_helpers.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// used namespaces
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace phoenix;
+using namespace std;
+
+///////////////////////////////////////////////////////////////////////////////
+// Helper class for encapsulation of the type for the parsed variable names
+class declaration_type
+{
+public:
+ enum vartype {
+ vartype_unknown = 0, // unknown variable type
+ vartype_int = 1, // 'int'
+ vartype_real = 2 // 'real'
+ };
+
+ declaration_type() : type(vartype_unknown)
+ {
+ }
+ template <typename ItT>
+ declaration_type(ItT const &first, ItT const &last)
+ {
+ init(string(first, last-first-1));
+ }
+ declaration_type(declaration_type const &type_) : type(type_.type)
+ {
+ }
+ declaration_type(string const &type_) : type(vartype_unknown)
+ {
+ init(type_);
+ }
+
+// access to the variable type
+ operator vartype const &() const { return type; }
+ operator string ()
+ {
+ switch(type) {
+ default:
+ case vartype_unknown: break;
+ case vartype_int: return string("int");
+ case vartype_real: return string("real");
+ }
+ return string ("unknown");
+ }
+
+ void swap(declaration_type &s) { std::swap(type, s.type); }
+
+protected:
+ void init (string const &type_)
+ {
+ if (type_ == "int")
+ type = vartype_int;
+ else if (type_ == "real")
+ type = vartype_real;
+ else
+ type = vartype_unknown;
+ }
+
+private:
+ vartype type;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// used closure type
+//
+///////////////////////////////////////////////////////////////////////////////
+struct var_decl_closure : BOOST_SPIRIT_CLASSIC_NS::closure<var_decl_closure, declaration_type>
+{
+ member1 val;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// symbols_with_data
+//
+// Helper class for inserting an item with data into a symbol table
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename T, typename InitT>
+class symbols_with_data
+{
+public:
+ typedef
+ symbol_inserter<T, BOOST_SPIRIT_CLASSIC_NS::impl::tst<T, char> >
+ symbol_inserter_t;
+
+ symbols_with_data(symbol_inserter_t const &add_, InitT const &data_) :
+ add(add_), data(as_actor<InitT>::convert(data_))
+ {
+ }
+
+ template <typename IteratorT>
+ symbol_inserter_t const &
+ operator()(IteratorT const &first_, IteratorT const &last) const
+ {
+ IteratorT first = first_;
+ return add(first, last, data());
+ }
+
+private:
+ symbol_inserter_t const &add;
+ typename as_actor<InitT>::type data;
+};
+
+template <typename T, typename CharT, typename InitT>
+inline
+symbols_with_data<T, InitT>
+symbols_gen(symbol_inserter<T, BOOST_SPIRIT_CLASSIC_NS::impl::tst<T, CharT> > const &add_,
+ InitT const &data_)
+{
+ return symbols_with_data<T, InitT>(add_, data_);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// The var_decl_list grammar parses variable declaration list
+
+struct var_decl_list :
+ public grammar<var_decl_list, var_decl_closure::context_t>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(var_decl_list const &self)
+ {
+ // pass variable type returned from 'type' to list closure member 0
+ decl = type[self.val = arg1] >> +space_p >> list(self.val);
+
+ // m0 to access arg 0 of list --> passing variable type down to ident
+ list = ident(list.val) >> *(',' >> ident(list.val));
+
+ // store identifier and type into the symbol table
+ ident = (*alnum_p)[symbols_gen(symtab.add, ident.val)];
+
+ // the type of the decl is returned in type's closure member 0
+ type =
+ str_p("int")[type.val = construct_<string>(arg1, arg2)]
+ | str_p("real")[type.val = construct_<string>(arg1, arg2)]
+ ;
+
+ BOOST_SPIRIT_DEBUG_RULE(decl);
+ BOOST_SPIRIT_DEBUG_RULE(list);
+ BOOST_SPIRIT_DEBUG_RULE(ident);
+ BOOST_SPIRIT_DEBUG_RULE(type);
+ }
+
+ rule<ScannerT> const&
+ start() const { return decl; }
+
+ private:
+ typedef rule<ScannerT, var_decl_closure::context_t> rule_t;
+ rule_t type;
+ rule_t list;
+ rule_t ident;
+ symbols<declaration_type> symtab;
+
+ rule<ScannerT> decl; // start rule
+ };
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// main entry point
+int main()
+{
+var_decl_list decl;
+declaration_type type;
+char const *pbegin = "int var1";
+
+ if (parse (pbegin, decl[assign(type)]).full) {
+ cout << endl
+ << "Parsed variable declarations successfully!" << endl
+ << "Detected type: " << declaration_type::vartype(type)
+ << " (" << string(type) << ")"
+ << endl;
+ } else {
+ cout << endl
+ << "Parsing the input stream failed!"
+ << endl;
+ }
+ return 0;
+}
+
diff --git a/src/boost/libs/spirit/classic/example/intermediate/regex_convert.cpp b/src/boost/libs/spirit/classic/example/intermediate/regex_convert.cpp
new file mode 100644
index 00000000..e167c2e3
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/intermediate/regex_convert.cpp
@@ -0,0 +1,177 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+// vim:ts=4:sw=4:et
+//
+// Demonstrate regular expression parsers for match based text conversion
+//
+// This sample requires an installed version of the boost regex library
+// (http://www.boost.org) The sample was tested with boost V1.29.0
+//
+// Note: - there is no error handling in this example
+// - this program isn't particularly useful
+//
+// This example shows one way build a kind of filter program.
+// It reads input from std::cin and uses a grammar and actions
+// to print out a modified version of the input.
+//
+// [ Martin Wille, 10/18/2002 ]
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <string>
+#include <iostream>
+#include <streambuf>
+#include <sstream>
+#include <deque>
+#include <iterator>
+
+#include <boost/function.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// The following header must be included, if regular expression support is
+// required for Spirit.
+//
+// The BOOST_SPIRIT_NO_REGEX_LIB PP constant should be defined, if you're using the
+// Boost.Regex library from one translation unit only. Otherwise you have to
+// link with the Boost.Regex library as defined in the related documentation
+// (see. http://www.boost.org).
+//
+///////////////////////////////////////////////////////////////////////////////
+#define BOOST_SPIRIT_NO_REGEX_LIB
+#include <boost/spirit/include/classic_regex.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace std;
+
+namespace {
+ long triple(long val)
+ {
+ return 3*val;
+ }
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // actions
+ //
+ struct emit_constant
+ {
+ emit_constant(string const &text)
+ : msg(text)
+ {}
+
+ template<typename Iterator>
+ void operator()(Iterator b, Iterator e) const
+ {
+ cout.rdbuf()->sputn(msg.data(), msg.size());
+ }
+
+ private:
+
+ string msg;
+ };
+
+ void
+ copy_unmodified(char letter)
+ {
+ cout.rdbuf()->sputc(letter);
+ }
+
+ struct emit_modified_subscript
+ {
+ emit_modified_subscript(boost::function<long (long)> const &f)
+ : modifier(f)
+ {}
+
+ template<typename Iterator>
+ void operator()(Iterator b, Iterator e) const
+ {
+ string tmp(b+1,e-1);
+ long val = strtol(tmp.c_str(),0, 0);
+ ostringstream os;
+ os << modifier(val);
+ tmp = os.str();
+ cout.rdbuf()->sputc('[');
+ cout.rdbuf()->sputn(tmp.c_str(), tmp.size());
+ cout.rdbuf()->sputc(']');
+ }
+
+ private:
+
+ boost::function<long (long)> modifier;
+ };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// The grammar 'conversion_grammar' serves as a working horse for match based
+// text conversion. It does the following:
+//
+// - converts the word "class" into the word "struct"
+// - multiplies any integer number enclosed in square brackets with 3
+// - any other input is simply copied to the output
+
+struct conversion_grammar
+ : grammar<conversion_grammar>
+{
+ template<class ScannerT>
+ struct definition
+ {
+ typedef ScannerT scanner_t;
+
+ definition(conversion_grammar const &)
+ {
+ static const char expr[] = "\\[\\d+\\]";
+ first = (
+ /////////////////////////////////////////////////////////////
+ // note that "fallback" is the last alternative here !
+ top = *(class2struct || subscript || fallback),
+ /////////////////////////////////////////////////////////////
+ // replace any occurrence of "class" by "struct"
+ class2struct = str_p("class") [emit_constant("struct")],
+ /////////////////////////////////////////////////////////////
+ // if the input maches "[some_number]"
+ // "some_number" is multiplied by 3 before printing
+ subscript = regex_p(expr) [emit_modified_subscript(&triple)],
+ /////////////////////////////////////////////////////////////
+ // if nothing else can be done with the input
+ // then it will be printed without modifications
+ fallback = anychar_p [&copy_unmodified]
+ );
+ }
+
+ rule<scanner_t> const & start() { return first; }
+
+ private:
+
+ subrule<0> top;
+ subrule<1> class2struct;
+ subrule<2> subscript;
+ subrule<3> fallback;
+ rule<scanner_t> first;
+ };
+};
+
+int
+main()
+{
+ // this would print "struct foo {}; foo bar[9];":
+ // parse("class foo {}; foo bar[3];", conversion_grammar());
+
+ // Note: the regular expression parser contained in the
+ // grammar requires a bidirectional iterator. Therefore,
+ // we cannot use sdt::istreambuf_iterator as one would
+ // do with other Spirit parsers.
+ istreambuf_iterator<char> input_iterator(cin);
+ std::deque<char> input(input_iterator, istreambuf_iterator<char>());
+
+ parse(input.begin(), input.end(), conversion_grammar());
+ return 0;
+}
+
diff --git a/src/boost/libs/spirit/classic/example/intermediate/simple_xml/actions.hpp b/src/boost/libs/spirit/classic/example/intermediate/simple_xml/actions.hpp
new file mode 100644
index 00000000..285edf21
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/intermediate/simple_xml/actions.hpp
@@ -0,0 +1,68 @@
+// Copyright (c) 2005 Carl Barron. 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)
+
+#ifndef ACTIONS_H
+#define ACTIONS_H
+#include <boost/spirit/include/phoenix1.hpp>
+#include <boost/variant.hpp>
+#include "tag.hpp"
+
+struct push_child_impl
+{
+ template <class T,class A>
+ struct result {typedef void type;};
+
+ template <class T,class A>
+ void operator () (T &list, const A &value) const
+ {
+ typename tag::variant_type p(value);
+ list.push_back(p);
+ }
+};
+
+struct store_in_map_impl
+{
+ template <class T,class A>
+ struct result{typedef void type;};
+
+ template <class T,class A>
+ void operator () (T &map,const A &value)const
+ {
+ typedef typename T::value_type value_type;
+ map.insert(value_type(value));
+ }
+};
+
+struct push_back_impl
+{
+ template <class T,class A>
+ struct result {typedef void type;};
+
+ template <class T,class A>
+ void operator () (T &list,const A &value)const
+ {
+ list.push_back(value);
+ }
+};
+
+struct store_tag_impl
+{
+ template <class T,class A,class B,class C>
+ struct result {typedef void type;};
+
+ template <class T,class A,class B,class C>
+ void operator ()(T &t,const A &a,const B &b,const C &c)const
+ {
+ t.id = a;
+ t.attributes = b;
+ t.children = c;
+ }
+};
+
+
+typedef phoenix::function<push_back_impl> push_back_f;
+typedef phoenix::function<store_in_map_impl>store_in_map_f;
+typedef phoenix::function<push_child_impl> push_child_f;
+typedef phoenix::function<store_tag_impl> store_tag_f;
+#endif
diff --git a/src/boost/libs/spirit/classic/example/intermediate/simple_xml/driver.cpp b/src/boost/libs/spirit/classic/example/intermediate/simple_xml/driver.cpp
new file mode 100644
index 00000000..57ad6f20
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/intermediate/simple_xml/driver.cpp
@@ -0,0 +1,43 @@
+// Copyright (c) 2005 Carl Barron. 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)
+
+#include "xml_g.hpp"
+#include <boost/spirit/include/classic_utility.hpp>
+#include <iostream>
+
+namespace std
+{
+ std::ostream & operator << (std::ostream &os,std::pair<std::string,std::string> const &p)
+ {
+ return os << p.first << '=' << p.second;
+ }
+
+ std::ostream & operator << (std::ostream &os,const tag &t)
+ {
+ return os << t.id;
+ }
+
+}
+
+int main()
+{
+ const char *test =
+ // "<A x=\"1\" y=\"2\"> test 1 </A>"
+ // "<B x=\"3\" y= \"4\" z = \"10\"> test 3 </B>"
+ // "<C><A></A><V><W></W></V></C>"
+ // "<D x=\"4\"/>"
+ "<E>xxx<F>yyy</F>zzz</E>"
+ ;
+ std::list<tag> tags;
+ xml_g g(tags);
+
+ if(SP::parse(test,g,SP::comment_p("<---","--->")).full)
+ {
+ std::for_each(tags.begin(),tags.end(),walk_data());
+ }
+ else
+ {
+ std::cout << "parse failed\n";
+ }
+}
diff --git a/src/boost/libs/spirit/classic/example/intermediate/simple_xml/tag.cpp b/src/boost/libs/spirit/classic/example/intermediate/simple_xml/tag.cpp
new file mode 100644
index 00000000..088f3a00
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/intermediate/simple_xml/tag.cpp
@@ -0,0 +1,46 @@
+// Copyright (c) 2005 Carl Barron. 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)
+
+#include "tag.hpp"
+#include <iostream>
+#include <algorithm>
+
+namespace
+{
+ struct print_pair
+ {
+ template <class P>
+ void operator () (const P &x)
+ {
+ std::cout << '\t' << x.first << ':' << x.second <<'\n';
+ }
+ };
+
+}
+
+void walk_data::operator () (const std::string &x)
+{
+ std::cout << "String:" << x <<'\n';
+}
+
+void walk_data::operator () (const tag &t)
+{
+ std::cout << "Tag:" << t.id << '\n';
+ std::cout << "Attributes\n";
+
+ std::for_each
+ (
+ t.attributes.begin(),
+ t.attributes.end(),
+ print_pair()
+ );
+ std::cout << "Children:\n";
+ std::for_each
+ (
+ t.children.begin(),
+ t.children.end(),
+ boost::apply_visitor(*this)
+ );
+ std::cout << "End of tag:" << t.id << '\n';
+}
diff --git a/src/boost/libs/spirit/classic/example/intermediate/simple_xml/tag.hpp b/src/boost/libs/spirit/classic/example/intermediate/simple_xml/tag.hpp
new file mode 100644
index 00000000..15f97593
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/intermediate/simple_xml/tag.hpp
@@ -0,0 +1,33 @@
+// Copyright (c) 2005 Carl Barron. 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)
+
+#ifndef SIMPLE_XML_TAG_H
+#define SIMPLE_XML_TAG_H
+
+#include <boost/variant.hpp>
+#include <list>
+#include <map>
+#include <string>
+
+struct tag
+{
+ std::string id;
+ std::map<std::string,std::string> attributes;
+ typedef boost::variant<
+ std::string,
+ boost::recursive_wrapper<tag>
+ >
+ variant_type;
+ std::list<variant_type> children;
+};
+
+
+struct walk_data
+{
+ typedef void result_type;
+ void operator () (const std::string &x);
+ void operator () (const tag &t);
+};
+
+#endif
diff --git a/src/boost/libs/spirit/classic/example/intermediate/simple_xml/xml_g.hpp b/src/boost/libs/spirit/classic/example/intermediate/simple_xml/xml_g.hpp
new file mode 100644
index 00000000..fb0a4c61
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/intermediate/simple_xml/xml_g.hpp
@@ -0,0 +1,186 @@
+// Copyright (c) 2005 Carl Barron. 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)
+
+#ifndef XML_G_H
+#define XML_G_H
+#define BOOST_SPIRIT_DEBUG
+#ifndef BOOST_SPIRIT_CLOSURE_LIMIT
+#define BOOST_SPIRIT_CLOSURE_LIMIT 10
+#endif
+
+#ifndef PHOENIX_LIMIT
+#define PHOENIX_LIMIT 10
+#endif
+
+#if BOOST_SPIRIT_CLOSURE_LIMIT < 6
+#undef BOOST_SPIRIT_CLOSURE_LIMIT
+#define BOOST_SPIRIT_CLOSURE_LIMIT 6
+#endif
+
+#if PHOENIX_LIMIT < BOOST_SPIRIT_CLOSURE_LIMIT
+#undef PHOENIX_LIMIT
+#define PHOENIX_LIMIT BOOST_SPIRIT_CLOSURE_LIMIT
+#endif
+
+#if 0
+#ifdef BOOST_SPIRIT_DEBUG_FLAGS
+#undef BOOST_SPIRIT_DEBUG_FLAGS
+#endif
+#define BOOST_SPIRIT_DEBUG_FLAGS (BOOST_SPIRIT_DEBUG_FLAGS_MAX - BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES)
+#endif
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_attribute.hpp>
+#include <boost/spirit/include/phoenix1.hpp>
+#include "tag.hpp"
+#include "actions.hpp"
+#include <boost/variant.hpp>
+
+#include <string>
+#include <utility>
+
+namespace SP = BOOST_SPIRIT_CLASSIC_NS;
+using phoenix::arg1;
+using phoenix::arg2;
+using phoenix::construct_;
+using phoenix::var;
+
+struct str_cls:SP::closure<str_cls,std::string>
+{ member1 value;};
+
+struct attrib_cls:SP::closure
+<
+ attrib_cls,
+ std::pair<std::string,std::string>,
+ std::string,
+ std::string
+>
+{
+ member1 value;
+ member2 first;
+ member3 second;
+};
+
+struct tagged_cls:SP::closure
+<
+ tagged_cls,
+ tag,
+ std::string,
+ std::map<std::string,std::string>,
+ std::list<typename tag::variant_type>
+>
+{
+ member1 value;
+ member2 ID;
+ member3 attribs;
+ member4 children;
+};
+
+struct xml_g:SP::grammar<xml_g>
+{
+ std::list<tag> &tags;
+ xml_g(std::list<tag> &a):tags(a){}
+ template <class Scan>
+ struct definition
+ {
+ definition(const xml_g &s)
+ {
+ white = +SP::space_p
+ ;
+
+ tagged = (start_tag
+ >> *inner
+ >> end_tag
+ | simple_start_tag
+ )
+ [store_tag(tagged.value,tagged.ID,tagged.attribs,
+ tagged.children)]
+ ;
+
+ end_tag = SP::str_p("</")
+ >> SP::f_str_p(tagged.ID)
+ >> '>'
+ ;
+
+ inner = (tagged
+ | str) [push_child(tagged.children,arg1)]
+ ;
+
+ str = SP::lexeme_d[+(SP::anychar_p - '<')]
+ [str.value=construct_<std::string>(arg1,arg2)]
+ ;
+
+ top = +tagged
+ [push_back(var(s.tags),arg1)]
+ ;
+
+ starter = SP::ch_p('<')
+ >> SP::lexeme_d[+SP::alpha_p]
+ [tagged.ID = construct_<std::string>(arg1,arg2)]
+ >> *attrib
+ [store_in_map(tagged.attribs,arg1)]
+ >> !white
+ ;
+ start_tag = starter
+ >> '>'
+ ;
+
+ simple_start_tag = starter
+ >> "/>"
+ ;
+
+ attrib = white
+ >>SP::lexeme_d[+SP::alpha_p]
+ [attrib.first = construct_<std::string>(arg1,arg2)]
+ >> !white
+ >> '='
+ >> !white
+ >> '"'
+ >> SP::lexeme_d[+(SP::anychar_p - '"')]
+ [attrib.second = construct_<std::string>(arg1,arg2)]
+ >> SP::ch_p('"')
+ [attrib.value = construct_
+ <
+ std::pair
+ <
+ std::string,
+ std::string
+ >
+ >(attrib.first,attrib.second)]
+ ;
+ BOOST_SPIRIT_DEBUG_RULE(tagged);
+ BOOST_SPIRIT_DEBUG_RULE(end_tag);
+ BOOST_SPIRIT_DEBUG_RULE(inner);
+ BOOST_SPIRIT_DEBUG_RULE(str);
+ BOOST_SPIRIT_DEBUG_RULE(top);
+ BOOST_SPIRIT_DEBUG_RULE(start_tag);
+ BOOST_SPIRIT_DEBUG_RULE(attrib);
+ BOOST_SPIRIT_DEBUG_RULE(white);
+ BOOST_SPIRIT_DEBUG_RULE(starter);
+ BOOST_SPIRIT_DEBUG_RULE(simple_start_tag);
+ }
+
+ // actions
+ push_back_f push_back;
+ push_child_f push_child;
+ store_in_map_f store_in_map;
+ store_tag_f store_tag;
+ // rules
+ SP::rule<Scan,tagged_cls::context_t> tagged;
+ SP::rule<Scan> end_tag;
+ SP::rule<Scan> inner;
+ SP::rule<Scan,str_cls::context_t> str;
+ SP::rule<Scan> top;
+ SP::rule<Scan> starter;
+ SP::rule<Scan> simple_start_tag;
+ SP::rule<Scan> start_tag;
+ SP::rule<Scan> white;
+ SP::rule<Scan,attrib_cls::context_t> attrib;
+ SP::rule<Scan> const &start() const
+ { return top;}
+ };
+};
+
+#endif
+
diff --git a/src/boost/libs/spirit/classic/example/techniques/dynamic_rule.cpp b/src/boost/libs/spirit/classic/example/techniques/dynamic_rule.cpp
new file mode 100644
index 00000000..d3e1a086
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/techniques/dynamic_rule.cpp
@@ -0,0 +1,58 @@
+/*=============================================================================
+ Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+// This example shows how the assign operator can be used to modify
+// rules with semantic actions
+//
+// First we show the basic spirit without (without any dynamic feature),
+// then we show how to use assign_a to make it dynamic,
+//
+// the grammar has to parse abcabc... sequences
+///////////////////////////////////////////////////////////////////////////////
+#include <iostream>
+
+#define BOOST_SPIRIT_DEBUG
+#include <boost/spirit.hpp>
+
+#include <boost/spirit/include/classic_assign_actor.hpp>
+
+int main()
+{
+ using namespace BOOST_SPIRIT_CLASSIC_NS;
+ using namespace std;
+
+ rule<> a,b,c,next;
+ const char* str="abcabc";
+ parse_info<> hit;
+ BOOST_SPIRIT_DEBUG_NODE(next);
+ BOOST_SPIRIT_DEBUG_NODE(a);
+ BOOST_SPIRIT_DEBUG_NODE(b);
+ BOOST_SPIRIT_DEBUG_NODE(c);
+
+ // basic spirit gram
+ a = ch_p('a') >> !b;
+ b = ch_p('b') >> !c;
+ c = ch_p('c') >> !a;
+
+ hit = parse(str, a);
+ cout<<"hit :"<<( hit.hit ? "yes" : "no")<<", "
+ <<(hit.full ? "full": "not full")
+ <<endl;
+
+ // using assign_a
+ a = ch_p('a')[ assign_a( next, b)] >> !next;
+ b = ch_p('b')[ assign_a( next, c)] >> !next;
+ c = ch_p('c')[ assign_a( next, a)] >> !next;
+ hit = parse(str, a);
+ cout<<"hit :"<<( hit.hit ? "yes" : "no")<<", "
+ <<(hit.full ? "full": "not full")
+ <<endl;
+
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/example/techniques/epsilon.cpp b/src/boost/libs/spirit/classic/example/techniques/epsilon.cpp
new file mode 100644
index 00000000..b331774d
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/techniques/epsilon.cpp
@@ -0,0 +1,68 @@
+/*=============================================================================
+ Copyright (c) 2003 Vaclav Vesely
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+//
+// This example demonstrates the behaviour of epsilon_p when used as parser
+// generator.
+//
+// The "r" is the rule, which is passed as a subject to the epsilon_p parser
+// generator. The "r" is the rule with binded semantic actions. But epsilon_p
+// parser generator is intended for looking forward and we don't want to
+// invoke semantic actions of subject parser. Hence the epsilon_p uses
+// the no_actions policy.
+//
+// Because we want to use the "r" rule both in the epsilon_p and outside of it
+// we need the "r" to support two differant scanners, one with no_actions
+// action policy and one with the default action policy. To achieve this
+// we declare the "r" with the no_actions_scanner_list scanner type.
+//
+//-----------------------------------------------------------------------------
+#define BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT 2
+
+#include <boost/assert.hpp>
+#include <iostream>
+#include <boost/cstdlib.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/phoenix1.hpp>
+
+using namespace std;
+using namespace boost;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace phoenix;
+
+//-----------------------------------------------------------------------------
+
+int main()
+{
+ rule<
+ // Support both the default phrase_scanner_t and the modified version
+ // with no_actions action_policy
+ no_actions_scanner_list<phrase_scanner_t>::type
+ > r;
+
+ int i(0);
+
+ r = int_p[var(i) += arg1];
+
+ parse_info<> info = parse(
+ "1",
+
+ // r rule is used twice but the semantic action is invoked only once
+ epsilon_p(r) >> r,
+
+ space_p
+ );
+
+ BOOST_ASSERT(info.full);
+ // Check, that the semantic action was invoked only once
+ BOOST_ASSERT(i == 1);
+
+ return exit_success;
+}
+
+//-----------------------------------------------------------------------------
diff --git a/src/boost/libs/spirit/classic/example/techniques/multiple_scanners.cpp b/src/boost/libs/spirit/classic/example/techniques/multiple_scanners.cpp
new file mode 100644
index 00000000..c7d48215
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/techniques/multiple_scanners.cpp
@@ -0,0 +1,53 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+// *** See the section "Rule With Multiple Scanners" in
+// *** chapter "Techniques" of the Spirit documentation
+// *** for information regarding this snippet
+
+#define BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT 3
+
+#include <iostream>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/assert.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+struct my_grammar : grammar<my_grammar>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(my_grammar const& self)
+ {
+ r = lower_p;
+ rr = +(lexeme_d[r] >> as_lower_d[r] >> r);
+ }
+
+ typedef scanner_list<
+ ScannerT
+ , typename lexeme_scanner<ScannerT>::type
+ , typename as_lower_scanner<ScannerT>::type
+ > scanners;
+
+ rule<scanners> r;
+ rule<ScannerT> rr;
+ rule<ScannerT> const& start() const { return rr; }
+ };
+};
+
+int
+main()
+{
+ my_grammar g;
+ bool success = parse("abcdef aBc d e f aBc d E f", g, space_p).full;
+ BOOST_ASSERT(success);
+ std::cout << "SUCCESS!!!\n";
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/example/techniques/nabialek.cpp b/src/boost/libs/spirit/classic/example/techniques/nabialek.cpp
new file mode 100644
index 00000000..c2fbd1a0
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/techniques/nabialek.cpp
@@ -0,0 +1,94 @@
+/*=============================================================================
+ Copyright (c) 2003 Sam Nabialek
+ Copyright (c) 2003-2004 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+
+#define BOOST_SPIRIT_DEBUG
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_error_handling.hpp>
+#include <boost/spirit/include/classic_iterator.hpp>
+#include <boost/spirit/include/classic_symbols.hpp>
+#include <boost/spirit/include/classic_utility.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+template <typename Rule>
+struct SetRest
+{
+ SetRest(Rule& the_rule)
+ : m_the_rule(the_rule)
+ {
+ }
+
+ void operator()(Rule* new_rule) const
+ {
+ m_the_rule = *new_rule;
+ }
+
+private:
+
+ Rule& m_the_rule;
+};
+
+
+struct nabialek_trick : public grammar<nabialek_trick>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ typedef rule<ScannerT> rule_t;
+
+ rule_t name;
+ rule_t line;
+ rule_t rest;
+ rule_t main;
+ rule_t one;
+ rule_t two;
+
+ symbols<rule_t*> continuations;
+
+ definition(nabialek_trick const& self)
+ {
+ name = lexeme_d[repeat_p(1,20)[alnum_p | '_']];
+
+ one = name;
+ two = name >> ',' >> name;
+
+ continuations.add
+ ("one", &one)
+ ("two", &two)
+ ;
+
+ line = continuations[SetRest<rule_t>(rest)] >> rest;
+ main = *line;
+
+ BOOST_SPIRIT_DEBUG_RULE(name);
+ BOOST_SPIRIT_DEBUG_RULE(line);
+ BOOST_SPIRIT_DEBUG_RULE(rest);
+ BOOST_SPIRIT_DEBUG_RULE(main);
+ BOOST_SPIRIT_DEBUG_RULE(one);
+ BOOST_SPIRIT_DEBUG_RULE(two);
+ }
+
+ rule_t const&
+ start() const
+ {
+ return main;
+ }
+ };
+};
+
+int
+main()
+{
+ nabialek_trick g;
+ parse("one only\none again\ntwo first,second", g, space_p);
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/example/techniques/no_rules/no_rule1.cpp b/src/boost/libs/spirit/classic/example/techniques/no_rules/no_rule1.cpp
new file mode 100644
index 00000000..547ee978
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/techniques/no_rules/no_rule1.cpp
@@ -0,0 +1,51 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+// *** See the section "Look Ma' No Rules" in
+// *** chapter "Techniques" of the Spirit documentation
+// *** for information regarding this snippet
+
+#include <iostream>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/assert.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+ struct skip_grammar : grammar<skip_grammar>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(skip_grammar const& /*self*/)
+ {
+ skip
+ = space_p
+ | "//" >> *(anychar_p - '\n') >> '\n'
+ | "/*" >> *(anychar_p - "*/") >> "*/"
+ ;
+ }
+
+ rule<ScannerT> skip;
+
+ rule<ScannerT> const&
+ start() const { return skip; }
+ };
+ };
+
+int
+main()
+{
+ skip_grammar g;
+ bool success = parse(
+ "/*this is a comment*/\n//this is a c++ comment\n\n",
+ *g).full;
+ BOOST_ASSERT(success);
+ std::cout << "SUCCESS!!!\n";
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/example/techniques/no_rules/no_rule2.cpp b/src/boost/libs/spirit/classic/example/techniques/no_rules/no_rule2.cpp
new file mode 100644
index 00000000..ddd37d50
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/techniques/no_rules/no_rule2.cpp
@@ -0,0 +1,58 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+// *** See the section "Look Ma' No Rules" in
+// *** chapter "Techniques" of the Spirit documentation
+// *** for information regarding this snippet
+
+#include <iostream>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/assert.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+struct skip_grammar : grammar<skip_grammar>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(skip_grammar const& /*self*/)
+ : skip
+ ( space_p
+ | "//" >> *(anychar_p - '\n') >> '\n'
+ | "/*" >> *(anychar_p - "*/") >> "*/"
+ )
+ {
+ }
+
+ typedef
+ alternative<alternative<space_parser, sequence<sequence<
+ strlit<const char*>, kleene_star<difference<anychar_parser,
+ chlit<char> > > >, chlit<char> > >, sequence<sequence<
+ strlit<const char*>, kleene_star<difference<anychar_parser,
+ strlit<const char*> > > >, strlit<const char*> > >
+ skip_t;
+ skip_t skip;
+
+ skip_t const&
+ start() const { return skip; }
+ };
+};
+
+int
+main()
+{
+ skip_grammar g;
+ bool success = parse(
+ "/*this is a comment*/\n//this is a c++ comment\n\n",
+ *g).full;
+ BOOST_ASSERT(success);
+ std::cout << "SUCCESS!!!\n";
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/example/techniques/no_rules/no_rule3.cpp b/src/boost/libs/spirit/classic/example/techniques/no_rules/no_rule3.cpp
new file mode 100644
index 00000000..bbdde085
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/techniques/no_rules/no_rule3.cpp
@@ -0,0 +1,86 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+// *** See the section "Look Ma' No Rules" in
+// *** chapter "Techniques" of the Spirit documentation
+// *** for information regarding this snippet
+
+#include <iostream>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/assert.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+namespace boost { namespace spirit
+{
+ template <typename DerivedT>
+ struct sub_grammar : parser<DerivedT>
+ {
+ typedef sub_grammar self_t;
+ typedef DerivedT const& embed_t;
+
+ template <typename ScannerT>
+ struct result
+ {
+ typedef typename parser_result<
+ typename DerivedT::start_t, ScannerT>::type
+ type;
+ };
+
+ DerivedT const& derived() const
+ { return *static_cast<DerivedT const*>(this); }
+
+ template <typename ScannerT>
+ typename parser_result<self_t, ScannerT>::type
+ parse(ScannerT const& scan) const
+ {
+ return derived().start.parse(scan);
+ }
+ };
+}}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Client code
+//
+///////////////////////////////////////////////////////////////////////////////
+struct skip_grammar : boost::spirit::sub_grammar<skip_grammar>
+{
+ typedef
+ alternative<alternative<space_parser, sequence<sequence<
+ strlit<const char*>, kleene_star<difference<anychar_parser,
+ chlit<char> > > >, chlit<char> > >, sequence<sequence<
+ strlit<const char*>, kleene_star<difference<anychar_parser,
+ strlit<const char*> > > >, strlit<const char*> > >
+ start_t;
+
+ skip_grammar()
+ : start
+ (
+ space_p
+ | "//" >> *(anychar_p - '\n') >> '\n'
+ | "/*" >> *(anychar_p - "*/") >> "*/"
+ )
+ {}
+
+ start_t start;
+};
+
+int
+main()
+{
+ skip_grammar g;
+
+ bool success = parse(
+ "/*this is a comment*/\n//this is a c++ comment\n\n",
+ *g).full;
+ BOOST_ASSERT(success);
+ std::cout << "SUCCESS!!!\n";
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/opaque_rule_parser.cpp b/src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/opaque_rule_parser.cpp
new file mode 100644
index 00000000..7525bd95
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/opaque_rule_parser.cpp
@@ -0,0 +1,67 @@
+/*==============================================================================
+ Copyright (c) 2006 Tobias Schwinger
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+//------------------------------------------------------------------------------
+// This example demonstrates the opaque rule parser.
+// See boost/spirit/include/rule_parser.hpp for details.
+//------------------------------------------------------------------------------
+#include <iostream>
+
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_typeof.hpp>
+
+#include <boost/spirit/include/classic_rule_parser.hpp>
+
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+
+namespace my_project { namespace my_grammar {
+
+ using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+ #define BOOST_SPIRIT__NAMESPACE (2,(my_project,my_grammar))
+
+ BOOST_SPIRIT_OPAQUE_RULE_PARSER(word,
+ (1,( ((char const *),str) )),
+ -,
+
+ lexeme_d[ str >> +space_p ]
+ )
+
+ BOOST_SPIRIT_OPAQUE_RULE_PARSER(main,
+ -,-,
+
+ *( word("dup") | word("swap") | word("drop") | word("rot") | word("tuck") )
+ )
+
+ #undef BOOST_SPIRIT__NAMESPACE
+
+} } // namespace my_project::my_grammar
+
+
+
+int main()
+{
+ std::string str;
+ while (std::getline(std::cin, str))
+ {
+ if (str.empty())
+ break;
+
+ str += '\n';
+
+ if (BOOST_SPIRIT_CLASSIC_NS::parse(str.c_str(), my_project::my_grammar::main).full)
+ std::cout << "\nOK." << std::endl;
+ else
+ std::cout << "\nERROR." << std::endl;
+ }
+ return 0;
+}
+
+
diff --git a/src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/rule_parser_1_1.cpp b/src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/rule_parser_1_1.cpp
new file mode 100644
index 00000000..54d1a5d6
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/rule_parser_1_1.cpp
@@ -0,0 +1,103 @@
+/*==============================================================================
+ Copyright (c) 2006 Tobias Schwinger
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+//------------------------------------------------------------------------------
+// This example uses typeof to build a nonrecursive grammar.
+// See boost/spirit/include/rule_parser.hpp for details.
+//------------------------------------------------------------------------------
+#include <string>
+#include <iostream>
+
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_typeof.hpp>
+
+#include <boost/spirit/include/classic_confix.hpp>
+#include <boost/spirit/include/classic_typeof.hpp>
+
+#include <boost/spirit/include/classic_rule_parser.hpp>
+
+// It's important to create an own registration group, even if there are no
+// manual Typeof registrations like in this case.
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+
+
+namespace my_project { namespace my_module {
+
+ using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+
+ // A semantic action.
+ void echo_uint(unsigned i) { std::cout << "- " << i << std::endl; }
+
+
+ #define BOOST_SPIRIT__NAMESPACE (2,(my_project,my_module))
+
+ // C/C++ comment and whitespace skip parser..
+ BOOST_SPIRIT_RULE_PARSER(skipper,
+ -,-,-,
+
+ ( confix_p("//",*anychar_p,eol_p)
+ | confix_p("/*",*anychar_p,"*/")
+ | space_p
+ )
+ )
+
+ // Parser for unsigned decimal, hexadecimal and binary literals.
+ BOOST_SPIRIT_RULE_PARSER(uint_literal,
+ -,-,-,
+
+ "0x" >> hex_p[ & echo_uint ]
+ | "0b" >> bin_p[ & echo_uint ]
+ | uint_p[ & echo_uint ]
+ )
+
+ // A generic list parser (in some ways similar to Spirit's list_p utility or
+ // the % operator) with two parameters.
+ BOOST_SPIRIT_RULE_PARSER(enumeration_parser,
+ (2,( element_parser, delimiter_parser )),-,-,
+
+ element_parser >> *(delimiter_parser >> element_parser)
+ )
+
+ // Parse an optional, comma separated list of uints with explicit post-skip.
+ BOOST_SPIRIT_RULE_PARSER(line,
+ -,-,-,
+ ! enumeration_parser(uint_literal,',')
+ >> lexeme_d[ !skipper ]
+ )
+
+ bool parse_line(char const * str)
+ {
+ return BOOST_SPIRIT_CLASSIC_NS::parse(str,line,skipper).full;
+ }
+
+ #undef BOOST_SPIRIT__NAMESPACE
+
+} } // namespace ::my_project::my_module
+
+
+int main()
+{
+ std::string str;
+ while (std::getline(std::cin, str))
+ {
+ if (str.empty())
+ break;
+
+ str += '\n';
+
+ if (my_project::my_module::parse_line(str.c_str()))
+ std::cout << "\nOK." << std::endl;
+ else
+ std::cout << "\nERROR." << std::endl;
+ }
+ return 0;
+}
+
diff --git a/src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/rule_parser_1_2.cpp b/src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/rule_parser_1_2.cpp
new file mode 100644
index 00000000..c80e49fc
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/rule_parser_1_2.cpp
@@ -0,0 +1,100 @@
+/*==============================================================================
+ Copyright (c) 2006 Tobias Schwinger
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+//------------------------------------------------------------------------------
+// This example uses typeof to build a nonrecursive grammar.
+// See boost/spirit/include/rule_parser.hpp for details.
+//------------------------------------------------------------------------------
+#include <string>
+#include <iostream>
+
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_typeof.hpp>
+
+#include <boost/spirit/include/classic_confix.hpp>
+#include <boost/spirit/include/classic_typeof.hpp>
+
+#include <boost/spirit/include/classic_rule_parser.hpp>
+
+// It's important to create an own registration group, even if there are no
+// manual Typeof registrations like in this case.
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+namespace my_project { namespace my_module {
+
+ // Semantic actions.
+ void echo_uint(unsigned i) { std::cout << i; }
+ void comma(unsigned) { std::cout << ','; }
+
+ #define BOOST_SPIRIT__NAMESPACE (2,(my_project,my_module))
+
+ // Define the action placeholders we use.
+ BOOST_SPIRIT_ACTION_PLACEHOLDER(uint_action)
+ BOOST_SPIRIT_ACTION_PLACEHOLDER(next_action)
+
+ // Parser for unsigned decimal, hexadecimal and binary literals.
+ // Takes a function pointer as its parameter.
+ BOOST_SPIRIT_RULE_PARSER(uint_literal
+ ,-,(1,( uint_action )),-,
+
+ str_p("0x") >> hex_p[ uint_action ]
+ | str_p("0b") >> bin_p[ uint_action ]
+ | uint_p[ uint_action ]
+ )
+
+ // Parser for a list of (dec/hex/bin) uints.
+ BOOST_SPIRIT_RULE_PARSER(uint_list,
+ -,(2,( uint_action, next_action )),-,
+
+ uint_literal[uint_action] >> *(',' >> uint_literal[next_action][uint_action])
+ )
+
+ // Parse an optional, comma separated list of uints with explicit post-skip.
+ // Note that we have to put the rule into parentheses here, because it
+ // contains an unparenthesized comma.
+ BOOST_SPIRIT_RULE_PARSER(line,
+ -,-,-,
+
+ (
+ ! uint_list[ (uint_action = & echo_uint), (next_action = & comma) ]
+ >> lexeme_d[ !space_p ]
+ )
+ )
+
+ bool parse_line(char const * str)
+ {
+ return BOOST_SPIRIT_CLASSIC_NS::parse(str,line,space_p).full;
+ }
+
+ #undef BOOST_SPIRIT__NAMESPACE
+
+} } // namespace ::my_project::my_module
+
+
+int main()
+{
+ std::string str;
+ while (std::getline(std::cin, str))
+ {
+ if (str.empty())
+ break;
+
+ str += '\n';
+
+ if (my_project::my_module::parse_line(str.c_str()))
+ std::cout << "\nOK." << std::endl;
+ else
+ std::cout << "\nERROR." << std::endl;
+ }
+ return 0;
+}
+
diff --git a/src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/rule_parser_2_1.cpp b/src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/rule_parser_2_1.cpp
new file mode 100644
index 00000000..356bc505
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/rule_parser_2_1.cpp
@@ -0,0 +1,107 @@
+/*==============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ Copyright (c) 2006 Tobias Schwinger
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+//------------------------------------------------------------------------------
+// This example shows a recursive grammar built using subrules and typeof.
+// See boost/spirit/include/rule_parser.hpp for details.
+// This example is based on subrule_calc.cpp.
+//------------------------------------------------------------------------------
+#include <string>
+#include <iostream>
+
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_typeof.hpp>
+
+#include <boost/spirit/include/classic_rule_parser.hpp>
+
+// Don't forget to
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+// Semantic actions
+namespace
+{
+ void do_int(int v) { std::cout << "PUSH(" << v << ')' << std::endl; }
+ void do_add(char const*, char const*) { std::cout << "ADD" << std::endl; }
+ void do_sub(char const*, char const*) { std::cout << "SUB" << std::endl; }
+ void do_mul(char const*, char const*) { std::cout << "MUL" << std::endl; }
+ void do_div(char const*, char const*) { std::cout << "DIV" << std::endl; }
+ void do_neg(char const*, char const*) { std::cout << "NEG" << std::endl; }
+}
+
+// Operating at root namespace...
+#define BOOST_SPIRIT__NAMESPACE -
+
+
+// Our calculator grammar using subrules in a rule parser.
+BOOST_SPIRIT_RULE_PARSER( calc,
+ -,
+ -,
+ (3,( ((subrule<0>),expression,()),
+ ((subrule<1>),term,()),
+ ((subrule<2>),factor,() )) ),
+ (
+ expression =
+ term
+ >> *( ('+' >> term)[&do_add]
+ | ('-' >> term)[&do_sub]
+ )
+ ,
+
+ term =
+ factor
+ >> *( ('*' >> factor)[&do_mul]
+ | ('/' >> factor)[&do_div]
+ )
+ ,
+
+ factor =
+ int_p[&do_int]
+ | ('(' >> expression >> ')')
+ | ('-' >> factor)[&do_neg]
+ | ('+' >> factor)
+ )
+)
+
+#undef BOOST_SPIRIT__NAMESPACE
+
+
+// Main program
+int main()
+{
+ std::cout
+ << "/////////////////////////////////////////////////////////\n"
+ << "\t\tA ruleless calculator using subrules...\n"
+ << "/////////////////////////////////////////////////////////\n"
+ << "Type an expression...or an empty line to quit\n"
+ << std::endl;
+
+ std::string str;
+ while (std::getline(std::cin, str))
+ {
+ if (str.empty()) break;
+
+ parse_info<> info = parse(str.c_str(), calc, space_p);
+
+ if (info.full)
+ std::cout
+ << "OK."
+ << std::endl;
+ else
+ std::cout
+ << "ERROR.\n"
+ << "Stopped at: \": " << info.stop << "\".\n"
+ << std::endl;
+ }
+ return 0;
+}
+
diff --git a/src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/rule_parser_2_2.cpp b/src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/rule_parser_2_2.cpp
new file mode 100644
index 00000000..3ae9738a
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/techniques/no_rules_with_typeof/rule_parser_2_2.cpp
@@ -0,0 +1,142 @@
+/*==============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ Copyright (c) 2006 Tobias Schwinger
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+//------------------------------------------------------------------------------
+// This example demonstrates how to make recursive grammars scale with typeof.
+// It uses a rule parser with member variables and the parser_reference utility.
+// See boost/spirit/include/rule_parser.hpp for details.
+// This example is based on subrule_calc.cpp.
+//------------------------------------------------------------------------------
+#include <string>
+#include <iostream>
+
+#include <boost/config.hpp>
+
+#if defined(BOOST_MSVC)
+// Disable MSVC's "'this' used in base/member initializer" warning.
+// It's perfectly safe to use 'this' in a base/member initializer [ 12.6.2-7 ].
+// The warning tries to prevent undefined behaviour when the 'this'-pointer is
+// used to do illegal things during construction [ 12.6.2-8 ] -- we don't.
+# pragma warning(disable:4355)
+#endif
+
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_typeof.hpp>
+
+#include <boost/spirit/include/classic_rule_parser.hpp>
+
+
+// Don't forget to
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+// Semantic actions
+namespace
+{
+ void do_int(int v) { std::cout << "PUSH(" << v << ')' << std::endl; }
+ void do_add(char const*, char const*) { std::cout << "ADD" << std::endl; }
+ void do_sub(char const*, char const*) { std::cout << "SUB" << std::endl; }
+ void do_mul(char const*, char const*) { std::cout << "MUL" << std::endl; }
+ void do_div(char const*, char const*) { std::cout << "DIV" << std::endl; }
+ void do_neg(char const*, char const*) { std::cout << "NEG" << std::endl; }
+}
+
+// Operating at root namespace...
+#define BOOST_SPIRIT__NAMESPACE -
+
+// Our calculator grammar using paramterized rule parsers.
+// Subrules are passed to the rule parsers as arguments to allow recursion.
+
+BOOST_SPIRIT_RULE_PARSER(expression,
+ (1,(term)),
+ -,
+ -,
+
+ term
+ >> *( ('+' >> term)[ &do_add ]
+ | ('-' >> term)[ &do_sub ]
+ )
+)
+
+BOOST_SPIRIT_RULE_PARSER(term,
+ (1,(factor)),
+ -,
+ -,
+
+ factor
+ >> *( ('*' >> factor)[ &do_mul ]
+ | ('/' >> factor)[ &do_div ]
+ )
+)
+
+// This rule parser uses the 'parser_reference' utility to refer to itself.
+// Note that here is another recursive loop, however, the self-reference, unlike
+// a subrule, cannot be passed to contained parsers because we would end up with
+// an endless loop at compile time finding the type.
+BOOST_SPIRIT_RULE_PARSER(factor,
+ (1,(expression)),
+ -,
+ (1,( ((parser_reference<factor_t>),factor,(*this)) )),
+
+ ( int_p[& do_int]
+ | ('(' >> expression >> ')')
+ | ('-' >> factor)[&do_neg]
+ | ('+' >> factor)
+ )
+)
+
+
+// This rule parser implements recursion between the other ones.
+BOOST_SPIRIT_RULE_PARSER( calc,
+ -,
+ -,
+ (3,( ((subrule<0>),sr_expression,()),
+ ((subrule<1>),sr_term,()),
+ ((subrule<2>),sr_factor,() )) ),
+
+ (
+ sr_expression = expression(sr_term),
+ sr_term = term(sr_factor),
+ sr_factor = factor(sr_expression)
+ )
+)
+
+// Main program
+int main()
+{
+ std::cout
+ << "/////////////////////////////////////////////////////////////\n"
+ << "\t\tA ruleless calculator using rule parsers and subrules...\n"
+ << "/////////////////////////////////////////////////////////////\n"
+ << "Type an expression...or an empty line to quit\n"
+ << std::endl;
+
+ std::string str;
+ while (std::getline(std::cin, str))
+ {
+ if (str.empty()) break;
+
+ parse_info<> info = parse(str.c_str(), calc, space_p);
+
+ if (info.full)
+ std::cout
+ << "OK."
+ << std::endl;
+ else
+ std::cout
+ << "ERROR.\n"
+ << "Stopped at: \": " << info.stop << "\".\n"
+ << std::endl;
+ }
+ return 0;
+}
+
diff --git a/src/boost/libs/spirit/classic/example/techniques/right_recursion.cpp b/src/boost/libs/spirit/classic/example/techniques/right_recursion.cpp
new file mode 100644
index 00000000..132b0dc5
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/techniques/right_recursion.cpp
@@ -0,0 +1,90 @@
+/*=============================================================================
+ Copyright (c) 2005 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+
+#define BOOST_SPIRIT_DEBUG
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/assert.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+struct non_greedy_kleene : public grammar<non_greedy_kleene>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ typedef rule<ScannerT> rule_t;
+ rule_t r;
+
+ definition(non_greedy_kleene const& self)
+ {
+ r = (alnum_p >> r) | digit_p;
+ BOOST_SPIRIT_DEBUG_RULE(r);
+ }
+
+ rule_t const&
+ start() const
+ {
+ return r;
+ }
+ };
+};
+
+struct non_greedy_plus : public grammar<non_greedy_plus>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ typedef rule<ScannerT> rule_t;
+ rule_t r;
+
+ definition(non_greedy_plus const& self)
+ {
+ r = alnum_p >> (r | digit_p);
+ BOOST_SPIRIT_DEBUG_RULE(r);
+ }
+
+ rule_t const&
+ start() const
+ {
+ return r;
+ }
+ };
+};
+int
+main()
+{
+ bool success;
+ {
+ non_greedy_kleene k;
+ success = parse("3", k).full;
+ BOOST_ASSERT(success);
+ success = parse("abcdef3", k).full;
+ BOOST_ASSERT(success);
+ success = parse("abc2def3", k).full;
+ BOOST_ASSERT(success);
+ success = parse("abc", k).full;
+ BOOST_ASSERT(!success);
+ }
+
+ {
+ non_greedy_plus p;
+ success = parse("3", p).full;
+ BOOST_ASSERT(!success);
+ success = parse("abcdef3", p).full;
+ BOOST_ASSERT(success);
+ success = parse("abc2def3", p).full;
+ BOOST_ASSERT(success);
+ success = parse("abc", p).full;
+ BOOST_ASSERT(!success);
+ }
+
+ std::cout << "SUCCESS!!!\n";
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/example/techniques/typeof.cpp b/src/boost/libs/spirit/classic/example/techniques/typeof.cpp
new file mode 100644
index 00000000..5aacd758
--- /dev/null
+++ b/src/boost/libs/spirit/classic/example/techniques/typeof.cpp
@@ -0,0 +1,41 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+// *** See the section "typeof" in chapter "Techniques" of
+// *** the Spirit documentation for information regarding
+// *** this snippet.
+
+#include <iostream>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/assert.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+#define RULE(name, definition) BOOST_TYPEOF(definition) name = definition
+
+int
+main()
+{
+ RULE(
+ skipper,
+ ( space_p
+ | "//" >> *(anychar_p - '\n') >> '\n'
+ | "/*" >> *(anychar_p - "*/") >> "*/"
+ )
+ );
+
+ bool success = parse(
+ "/*this is a comment*/\n//this is a c++ comment\n\n",
+ *skipper).full;
+ BOOST_ASSERT(success);
+ std::cout << "SUCCESS!!!\n";
+ return 0;
+}
+
diff --git a/src/boost/libs/spirit/classic/index.html b/src/boost/libs/spirit/classic/index.html
new file mode 100644
index 00000000..d789969b
--- /dev/null
+++ b/src/boost/libs/spirit/classic/index.html
@@ -0,0 +1,263 @@
+<html>
+<head>
+<title>Spirit User's Guide</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link rel="stylesheet" href="doc/theme/style.css" type="text/css">
+</head>
+
+<body>
+<table width="100%" border="0" background="doc/theme/bkd2.gif" cellspacing="2">
+ <tr>
+ <td width="10">
+ <h1></h1>
+ </td>
+ <td width="85%"> <font face="Verdana, Arial, Helvetica, sans-serif"><b><font size="6">Spirit
+ User's Guide</font></b></font></td>
+ <td width="112"><a href="http://spirit.sf.net"><img src="doc/theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td>
+ </tr>
+</table>
+<br>
+<table width="75%" border="0" align="center">
+ <tr>
+ <td class="table_title">Table of Contents</td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><a href="doc/preface.html">Preface</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><a href="doc/introduction.html">Introduction</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><a href="doc/quick_start.html">Quick Start</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><a href="doc/basic_concepts.html">Basic Concepts</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><a href="doc/organization.html">Organization</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><a href="change_log.html">What's New </a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><b><font face="Geneva, Arial, Helvetica, san-serif">Core</font></b></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/primitives.html">Primitives</a> </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/operators.html">Operators</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/numerics.html">Numerics</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/rule.html">The Rule</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/epsilon.html">Epsilon</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/directives.html">Directives</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/scanner.html">The Scanner and Parsing</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/grammar.html">The Grammar</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/subrules.html">Subrules</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/semantic_actions.html">Semantic Actions</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/indepth_the_parser.html">In-depth: The
+ Parser</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/indepth_the_scanner.html">In-depth:
+ The Scanner</a> </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/indepth_the_parser_context.html">In-depth:
+ The Parser Context</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><strong>Actors</strong></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/predefined_actors.html">Predefined Actions</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><b>Attribute</b></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/parametric_parsers.html">Parametric
+ Parsers</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/functional.html">Functional</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/phoenix.html">Phoenix</a><a href="doc/parametric_parsers.html"></a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/closures.html">Closures</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><strong>Dynamic</strong></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/dynamic_parsers.html">Dynamic Parsers</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/stored_rule.html">Storable Rules</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/the_lazy_parser.html">The Lazy Parser</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/select_parser.html">The Select Parser</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/switch_parser.html">The Switch Parser</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><b>Utility</b></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/escape_char_parser.html">Escape Character
+ Parsers</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/loops.html">Loop Parsers</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/character_sets.html">Character Set Parser</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/confix.html">Confix and Comment Parsers</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/list_parsers.html">List Parsers</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/functor_parser.html">Functor Parser</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/refactoring.html">Refactoring Parsers</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/regular_expression_parser.html">Regular
+ Expression Parser</a> </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/scoped_lock.html">Scoped Lock</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/distinct.html">Distinct Parser </a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><b>Symbols</b></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/symbols.html">The Symbol Table</a></td>
+ </tr>
+ <tr>
+ <td class="table_cells"><b>Trees</b></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/trees.html">Parse Trees and ASTs</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><b>Iterator</b></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/multi_pass.html">Multi Pass </a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/file_iterator.html">File Iterator</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1"><a href="doc/position_iterator.html">Position Iterator
+ </a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><a href="doc/debugging.html">Debugging</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><a href="doc/error_handling.html">Error Handling</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><a href="doc/quickref.html">Quick Reference</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><a href="doc/includes.html">Includes</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><a href="doc/portability.html">Portability</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><a href="doc/style_guide.html">Style Guide</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><a href="doc/techniques.html">Techniques</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><a href="doc/faq.html">FAQ</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><a href="doc/rationale.html">Rationale</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><a href="doc/acknowledgments.html">Acknowledgments</a></td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0"><a href="doc/references.html">References</a></td>
+ </tr>
+</table>
+<br>
+<table width="50%" border="0" align="center">
+ <tr>
+ <td>
+ <div align="center"><font size="2" color="#666666">Copyright &copy; 1998-2003
+ Joel de Guzman</font><font size="2"><br>
+ <br>
+ Portions of this document: <br>
+ <font color="#666666">Copyright &copy; 2001-2003 Hartmut Kaiser<br>
+ Copyright &copy; 2001-2002 Daniel C. Nuffer<br>
+ Copyright &copy; 2002 Chris Uzdavinis<br>
+ Copyright &copy; 2002 Jeff Westfahl<br>
+ Copyright &copy; 2002 Juan Carlos Arevalo-Baeza<br>
+ </font><font size="2"><font color="#666666">Copyright &copy; 2003 Martin
+ Wille <br>
+ Copyright &copy; 2003 Ross Smith<br>
+ <font size="2"><font size="2">Copyright &copy; 2003</font></font></font>
+ <font color="#666666">Jonathan de Halleux </font></font></font></div>
+ <p><font size="2"> <font color="#666666"> Use, modification and distribution is subject to 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)
+ </font> </font></p>
+ </td>
+ </tr>
+</table>
+<br>
+<table width="35%" border="0" align="center">
+ <tr>
+ <td>
+ <div align="center"><font size="2">Spirit is hosted by <a href="http://sourceforge.net">SourceForge</a></font><br>
+ <font size="2"><a href="http://spirit.sourceforge.net/">http://spirit.sourceforge.net/
+ </a></font> <br>
+ <br>
+ <a href="http://sourceforge.net"><img src="http://sourceforge.net/sflogo.php?group_id=28447" width="88" height="31" border="0" alt="SourceForge Logo"></a></div>
+ </td>
+ </tr>
+</table>
+<br>
+<p>&nbsp;</p>
+</body>
+</html>
diff --git a/src/boost/libs/spirit/classic/meta/libraries.json b/src/boost/libs/spirit/classic/meta/libraries.json
new file mode 100644
index 00000000..8c1f7abd
--- /dev/null
+++ b/src/boost/libs/spirit/classic/meta/libraries.json
@@ -0,0 +1,18 @@
+{
+ "key": "spirit/classic",
+ "name": "Spirit Classic",
+ "authors": [
+ "Joel de Guzman",
+ "Hartmut Kaiser",
+ "Dan Nuffer"
+ ],
+ "description": "LL parser framework represents parsers directly as EBNF grammars in inlined C++.",
+ "category": [
+ "Parsing",
+ "String"
+ ],
+ "maintainers": [
+ "Joel de Guzman <joel -at- boost-consulting.com>",
+ "Hartmut Kaiser <hartmut.kaiser -at- gmail.com>"
+ ]
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/example/Jamfile b/src/boost/libs/spirit/classic/phoenix/example/Jamfile
new file mode 100644
index 00000000..1790816f
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/example/Jamfile
@@ -0,0 +1,79 @@
+#==============================================================================
+# Copyright (c) 2002 Joel de Guzman
+# http://spirit.sourceforge.net/
+#
+# Use, modification and distribution is subject to 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)
+#==============================================================================
+#
+# Phoenix examples boost-jam file
+# Joel de Guzman [Sept 27, 2002]
+#
+
+#unit-test sample1
+# : fundamental/sample1.cpp
+# :
+# :
+# ;
+
+unit-test sample2
+ : fundamental/sample2.cpp
+ :
+ :
+ ;
+
+unit-test sample3
+ : fundamental/sample3.cpp
+ :
+ :
+ ;
+
+unit-test sample4
+ : fundamental/sample4.cpp
+ :
+ :
+ ;
+
+unit-test sample5
+ : fundamental/sample5.cpp
+ :
+ :
+ ;
+
+unit-test sample6
+ : fundamental/sample6.cpp
+ :
+ :
+ ;
+
+unit-test sample7
+ : fundamental/sample7.cpp
+ :
+ :
+ ;
+
+unit-test sample8
+ : fundamental/sample8.cpp
+ :
+ :
+ ;
+
+unit-test sample9
+ : fundamental/sample9.cpp
+ :
+ :
+ ;
+
+unit-test sample10
+ : fundamental/sample10.cpp
+ :
+ :
+ ;
+
+unit-test closures
+ : fundamental/closures.cpp
+ :
+ :
+ ;
+
diff --git a/src/boost/libs/spirit/classic/phoenix/example/fundamental/closures.cpp b/src/boost/libs/spirit/classic/phoenix/example/fundamental/closures.cpp
new file mode 100644
index 00000000..1255ab6b
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/example/fundamental/closures.cpp
@@ -0,0 +1,66 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <vector>
+#include <algorithm>
+#include <iostream>
+#include <cassert>
+
+#define PHOENIX_LIMIT 15
+#include <boost/spirit/include/phoenix1_operators.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_composite.hpp>
+#include <boost/spirit/include/phoenix1_special_ops.hpp>
+#include <boost/spirit/include/phoenix1_statements.hpp>
+#include <boost/spirit/include/phoenix1_functions.hpp>
+#include <boost/spirit/include/phoenix1_closures.hpp>
+
+//////////////////////////////////
+using namespace phoenix;
+
+//////////////////////////////////
+int
+main()
+{
+ struct my_closure : closure<int, std::string, double> {
+
+ member1 num;
+ member2 message;
+ member3 real;
+ };
+
+ my_closure clos;
+
+ { // First stack frame
+ closure_frame<my_closure::self_t> frame(clos);
+ (clos.num = 123)();
+ (clos.num += 456)();
+ (clos.real = clos.num / 56.5)();
+ (clos.message = "Hello " + std::string("World "))();
+
+ { // Second stack frame
+ closure_frame<my_closure::self_t> frame(clos);
+ (clos.num = 987)();
+ (clos.message = "Abracadabra ")();
+ (clos.real = clos.num * 1e30)();
+
+ { // Third stack frame
+ tuple<int, char const*, double> init(-1, "Direct Init ", 3.14);
+ closure_frame<my_closure::self_t> frame(clos, init);
+
+ (std::cout << clos.message << clos.num << ", " << clos.real << '\n')();
+ }
+
+ (std::cout << clos.message << clos.num << ", " << clos.real << '\n')();
+ }
+
+ (std::cout << clos.message << clos.num << ", " << clos.real << '\n')();
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample10.cpp b/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample10.cpp
new file mode 100644
index 00000000..ae59adf1
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample10.cpp
@@ -0,0 +1,525 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <vector>
+#include <algorithm>
+#include <iostream>
+
+#define PHOENIX_LIMIT 5
+#include <boost/spirit/include/phoenix1_operators.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_composite.hpp>
+#include <boost/spirit/include/phoenix1_special_ops.hpp>
+#include <boost/spirit/include/phoenix1_statements.hpp>
+#include <boost/spirit/include/phoenix1_functions.hpp>
+
+namespace phoenix {
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// local_tuple
+//
+// This *is a* tuple like the one we see in TupleT in any actor
+// base class' eval member function. local_tuple should look and
+// feel the same as a tupled-args, that's why it is derived from
+// TupleArgsT. It has an added member, locs which is another tuple
+// where the local variables will be stored. locs is mutable to
+// allow read-write access to our locals regardless of
+// local_tuple's constness (The eval member function accepts it as
+// a const argument).
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename TupleArgsT, typename TupleLocsT>
+struct local_tuple : public TupleArgsT {
+
+ local_tuple(TupleArgsT const& args, TupleLocsT const& locs_)
+ : TupleArgsT(args), locs(locs_) {}
+
+ mutable TupleLocsT locs;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// local_var_result
+//
+// This is a return type computer. Given a constant integer N, a
+// parent index and a tuple, get the Nth local variable type. The
+// parent index is an integer specifying which parent scope to
+// access; 0==current scope, 1==parent scope, 2==parent's parent
+// scope etc.
+//
+// This is a metaprogram with partial specializations. There is a
+// general case, a special case for local_tuples and a terminating
+// special case for local_tuples.
+//
+// General case: If TupleT is not really a local_tuple, we just return nil_t.
+//
+// local_tuples case:
+// Parent index is 0: We get the Nth local variable.
+// Otherwise: We subclass from local_tuples<N, Parent-1, TupleArgsT>
+//
+///////////////////////////////////////////////////////////////////////////////
+template <int N, int Parent, typename TupleT>
+struct local_var_result {
+
+ typedef nil_t type;
+};
+
+//////////////////////////////////
+template <int N, int Parent, typename TupleArgsT, typename TupleLocsT>
+struct local_var_result<N, Parent, local_tuple<TupleArgsT, TupleLocsT> >
+: public local_var_result<N, Parent-1, TupleArgsT> {};
+
+//////////////////////////////////
+template <int N, typename TupleArgsT, typename TupleLocsT>
+struct local_var_result<N, 0, local_tuple<TupleArgsT, TupleLocsT> > {
+
+ typedef typename tuple_element<N, TupleLocsT>::type& type;
+
+ static type get(local_tuple<TupleArgsT, TupleLocsT> const& tuple)
+ { return tuple.locs[tuple_index<N>()]; }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// local_var
+//
+// This class looks so curiously like the argument class. local_var
+// provides access to the Nth local variable packed in the tuple
+// duo local_tuple above. Parent specifies the Nth parent scope.
+// 0==current scope, 1==parent scope, 2==parent's parent scope etc.
+// The member function parent<N>() may be called to provide access
+// to outer scopes.
+//
+// Note that the member function eval expects a local_tuple
+// argument. Otherwise there will be acompile-time error. local_var
+// primitives only work within the context of a context_composite
+// (see below).
+//
+// Provided are some predefined local_var actors for 0..N local
+// variable access: lvar1..locN.
+//
+///////////////////////////////////////////////////////////////////////////////
+template <int N, int Parent = 0>
+struct local_var {
+
+ typedef local_var<N, Parent> self_t;
+
+ template <typename TupleT>
+ struct result {
+
+ typedef typename local_var_result<N, Parent, TupleT>::type type;
+ };
+
+ template <typename TupleT>
+ typename actor_result<self_t, TupleT>::type
+ eval(TupleT const& tuple) const
+ {
+ return local_var_result<N, Parent, TupleT>::get(tuple);
+ }
+
+ template <int PIndex>
+ actor<local_var<N, Parent+PIndex> >
+ parent() const
+ {
+ return local_var<N, Parent+PIndex>();
+ }
+};
+
+//////////////////////////////////
+namespace locals {
+
+ actor<local_var<0> > const result = local_var<0>();
+ actor<local_var<1> > const lvar1 = local_var<1>();
+ actor<local_var<2> > const lvar2 = local_var<2>();
+ actor<local_var<3> > const lvar3 = local_var<3>();
+ actor<local_var<4> > const lvar4 = local_var<4>();
+}
+
+
+
+
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+template <int N, int Parent, typename TupleT>
+struct local_func_result {
+
+ typedef nil_t type;
+};
+
+//////////////////////////////////
+template <int N, int Parent, typename TupleArgsT, typename TupleLocsT>
+struct local_func_result<N, Parent, local_tuple<TupleArgsT, TupleLocsT> >
+: public local_func_result<N, Parent-1, TupleArgsT> {};
+
+//////////////////////////////////
+template <int N, typename TupleArgsT, typename TupleLocsT>
+struct local_func_result<N, 0, local_tuple<TupleArgsT, TupleLocsT> > {
+
+ typedef typename actor_result<
+ typename tuple_element<N, TupleLocsT>::type,
+ local_tuple<TupleArgsT, TupleLocsT>
+ >::type type;
+
+ template <typename ArgsT>
+ static type eval(local_tuple<ArgsT, TupleLocsT> const& tuple)
+ { return tuple.locs[tuple_index<N>()].eval(tuple); }
+};
+
+
+
+
+
+
+
+
+template <
+ int N, int Parent,
+ typename A0 = nil_t,
+ typename A1 = nil_t,
+ typename A2 = nil_t,
+ typename A3 = nil_t,
+ typename A4 = nil_t
+>
+struct local_function_actor;
+
+//////////////////////////////////
+template <int N, int Parent>
+struct local_function_base {
+
+ template <typename TupleT>
+ struct result {
+
+ typedef typename local_func_result<N, Parent, TupleT>::type type;
+ };
+};
+
+//////////////////////////////////
+template <int N, int Parent>
+struct local_function_actor<N, Parent, nil_t, nil_t, nil_t, nil_t, nil_t>
+: public local_function_base<N, Parent> {
+
+ template <typename TupleArgsT, typename TupleLocsT>
+ typename local_func_result<
+ N, Parent, local_tuple<TupleArgsT, TupleLocsT> >::type
+ eval(local_tuple<TupleArgsT, TupleLocsT> const& args) const
+ {
+ typedef local_tuple<TupleArgsT, TupleLocsT> local_tuple_t;
+ typedef tuple<> tuple_t;
+ tuple_t local_args;
+
+ local_tuple<tuple_t, TupleLocsT> local_context(local_args, args.locs);
+ return local_func_result<
+ N, Parent, local_tuple_t>
+ ::eval(local_context);
+ }
+};
+
+//////////////////////////////////
+template <int N, int Parent,
+ typename A0>
+struct local_function_actor<N, Parent, A0, nil_t, nil_t, nil_t, nil_t>
+: public local_function_base<N, Parent> {
+
+ local_function_actor(
+ A0 const& _0)
+ : a0(_0) {}
+
+ template <typename TupleArgsT, typename TupleLocsT>
+ typename local_func_result<
+ N, Parent, local_tuple<TupleArgsT, TupleLocsT> >::type
+ eval(local_tuple<TupleArgsT, TupleLocsT> const& args) const
+ {
+ typedef local_tuple<TupleArgsT, TupleLocsT> local_tuple_t;
+ typename actor_result<A0, local_tuple_t>::type r0 = a0.eval(args);
+
+ typedef tuple<
+ typename actor_result<A0, local_tuple_t>::type
+ > tuple_t;
+ tuple_t local_args(r0);
+
+ local_tuple<tuple_t, TupleLocsT> local_context(local_args, args.locs);
+ return local_func_result<
+ N, Parent, local_tuple_t>
+ ::eval(local_context);
+ }
+
+ A0 a0; // actors
+};
+
+namespace impl {
+
+ template <
+ int N, int Parent,
+ typename T0 = nil_t,
+ typename T1 = nil_t,
+ typename T2 = nil_t,
+ typename T3 = nil_t,
+ typename T4 = nil_t
+ >
+ struct make_local_function_actor {
+
+ typedef local_function_actor<
+ N, Parent,
+ typename as_actor<T0>::type,
+ typename as_actor<T1>::type,
+ typename as_actor<T2>::type,
+ typename as_actor<T3>::type,
+ typename as_actor<T4>::type
+ > composite_type;
+
+ typedef actor<composite_type> type;
+ };
+}
+
+
+
+template <int N, int Parent = 0>
+struct local_function {
+
+ actor<local_function_actor<N, Parent> >
+ operator()() const
+ {
+ return local_function_actor<N, Parent>();
+ }
+
+ template <typename T0>
+ typename impl::make_local_function_actor<N, Parent, T0>::type
+ operator()(T0 const& _0) const
+ {
+ return impl::make_local_function_actor<N, Parent, T0>::composite_type(_0);
+ }
+
+ template <int PIndex>
+ local_function<N, Parent+PIndex>
+ parent() const
+ {
+ return local_function<N, Parent+PIndex>();
+ }
+};
+
+//////////////////////////////////
+namespace locals {
+
+ local_function<1> const lfun1 = local_function<1>();
+ local_function<2> const lfun2 = local_function<2>();
+ local_function<3> const lfun3 = local_function<3>();
+ local_function<4> const lfun4 = local_function<4>();
+}
+
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// context_composite
+//
+// This class encapsulates an actor and some local variable
+// initializers packed in a tuple.
+//
+// context_composite is just like a proxy and delegates the actual
+// evaluation to the actor. The actor does the actual work. In the
+// eval member function, before invoking the embedded actor's eval
+// member function, we first stuff an instance of our locals and
+// bundle both 'args' and 'locals' in a local_tuple. This
+// local_tuple instance is created in the stack initializing it
+// with our locals member. We then pass this local_tuple instance
+// as an argument to the actor's eval member function.
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename ActorT, typename LocsT>
+struct context_composite {
+
+ typedef context_composite<ActorT, LocsT> self_t;
+
+ template <typename TupleT>
+ struct result { typedef typename tuple_element<0, LocsT>::type type; };
+
+ context_composite(ActorT const& actor_, LocsT const& locals_)
+ : actor(actor_), locals(locals_) {}
+
+ template <typename TupleT>
+ typename tuple_element<0, LocsT>::type
+ eval(TupleT const& args) const
+ {
+ local_tuple<TupleT, LocsT> local_context(args, locals);
+ actor.eval(local_context);
+ return local_context.locs[tuple_index<0>()];
+ }
+
+ ActorT actor;
+ LocsT locals;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// context_gen
+//
+// At construction time, this class is given some local var-
+// initializers packed in a tuple. We just store this for later.
+// The operator[] of this class creates the actual context_composite
+// given an actor. This is responsible for the construct
+// context<types>[actor].
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename LocsT>
+struct context_gen {
+
+ context_gen(LocsT const& locals_)
+ : locals(locals_) {}
+
+ template <typename ActorT>
+ actor<context_composite<typename as_actor<ActorT>::type, LocsT> >
+ operator[](ActorT const& actor)
+ {
+ return context_composite<typename as_actor<ActorT>::type, LocsT>
+ (as_actor<ActorT>::convert(actor), locals);
+ }
+
+ LocsT locals;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Front end generator functions. These generators are overloaded for
+// 1..N local variables. context<T0,... TN>(i0,...iN) generate
+// context_gen objects (see above).
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename T0>
+inline context_gen<tuple<T0> >
+context()
+{
+ typedef tuple<T0> tuple_t;
+ return context_gen<tuple_t>(tuple_t(T0()));
+}
+
+//////////////////////////////////
+template <typename T0, typename T1>
+inline context_gen<tuple<T0, T1> >
+context(
+ T1 const& _1 = T1()
+)
+{
+ typedef tuple<T0, T1> tuple_t;
+ return context_gen<tuple_t>(tuple_t(T0(), _1));
+}
+
+//////////////////////////////////
+template <typename T0, typename T1, typename T2>
+inline context_gen<tuple<T0, T1, T2> >
+context(
+ T1 const& _1 = T1(),
+ T2 const& _2 = T2()
+)
+{
+ typedef tuple<T0, T1, T2> tuple_t;
+ return context_gen<tuple_t>(tuple_t(T0(), _1, _2));
+}
+
+//////////////////////////////////
+template <typename T0, typename T1, typename T2, typename T3>
+inline context_gen<tuple<T0, T1, T2, T3> >
+context(
+ T1 const& _1 = T1(),
+ T2 const& _2 = T2(),
+ T3 const& _3 = T3()
+)
+{
+ typedef tuple<T0, T1, T2, T3> tuple_t;
+ return context_gen<tuple_t>(tuple_t(T0(), _1, _2, _3));
+}
+
+//////////////////////////////////
+template <typename T0, typename T1, typename T2, typename T3, typename T4>
+inline context_gen<tuple<T0, T1, T2, T3, T4> >
+context(
+ T1 const& _1 = T1(),
+ T2 const& _2 = T2(),
+ T3 const& _3 = T3(),
+ T4 const& _4 = T4()
+)
+{
+ typedef tuple<T0, T1, T2, T3, T4> tuple_t;
+ return context_gen<tuple_t>(tuple_t(T0(), _1, _2, _3, _4));
+}
+
+
+
+
+
+
+
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+}
+
+//////////////////////////////////
+using namespace std;
+using namespace phoenix;
+using namespace phoenix::locals;
+
+//////////////////////////////////
+int
+main()
+{
+ int _10 = 10;
+
+#ifndef __BORLANDC__
+
+ context<nil_t>
+ (
+ 1000, // lvar1: local int variable
+ cout << arg1 << '\n', // lfun2: local function w/ 1 argument (arg1)
+ lvar1 * 2, // lfun3: local function that accesses local variable lvar1
+ lfun2(2 * arg1) // lfun4: local function that calls local function lfun2
+ )
+ [
+ lfun2(arg1 + 2000),
+ lfun2(val(5000) * 2),
+ lfun2(lvar1 + lfun3()),
+ lfun4(val(55)),
+ cout << lvar1 << '\n',
+ cout << lfun3() << '\n',
+ cout << val("bye bye\n")
+ ]
+
+ (_10);
+
+#else // Borland does not like local variables w/ local functions
+ // we can have local variables (see sample 7..9) *OR*
+ // local functions (this: sample 10) but not both
+ // Sigh... Borland :-{
+
+ context<nil_t>
+ (
+ 12345,
+ cout << arg1 << '\n'
+ )
+ [
+ lfun2(arg1 + 687),
+ lfun2(val(9999) * 2),
+ cout << val("bye bye\n")
+ ]
+
+ (_10);
+
+#endif
+
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample2.cpp b/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample2.cpp
new file mode 100644
index 00000000..d8dc195d
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample2.cpp
@@ -0,0 +1,31 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <vector>
+#include <algorithm>
+#include <iostream>
+#include <boost/spirit/include/phoenix1_operators.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+
+using namespace std;
+using namespace phoenix;
+
+int
+main()
+{
+ int init[] = { 2, 10, 4, 5, 1, 6, 8, 3, 9, 7 };
+ vector<int> c(init, init + 10);
+ typedef vector<int>::iterator iterator;
+
+ // Find the first odd number in container c
+ iterator it = find_if(c.begin(), c.end(), arg1 % 2 == 1);
+
+ if (it != c.end())
+ cout << *it; // if found, print the result
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample3.cpp b/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample3.cpp
new file mode 100644
index 00000000..49ff8628
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample3.cpp
@@ -0,0 +1,43 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <vector>
+#include <algorithm>
+#include <iostream>
+#include <boost/spirit/include/phoenix1_functions.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+
+using namespace std;
+using namespace phoenix;
+
+struct is_odd_ {
+
+ template <typename ArgT>
+ struct result { typedef bool type; };
+
+ template <typename ArgT>
+ bool operator()(ArgT arg1) const
+ { return arg1 % 2 == 1; }
+};
+
+function<is_odd_> is_odd;
+
+int
+main()
+{
+ int init[] = { 2, 10, 4, 5, 1, 6, 8, 3, 9, 7 };
+ vector<int> c(init, init + 10);
+ typedef vector<int>::iterator iterator;
+
+ // Find the first odd number in container c
+ iterator it = find_if(c.begin(), c.end(), is_odd(arg1));
+
+ if (it != c.end())
+ cout << *it; // if found, print the result
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample4.cpp b/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample4.cpp
new file mode 100644
index 00000000..27fa7720
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample4.cpp
@@ -0,0 +1,36 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <vector>
+#include <algorithm>
+#include <iostream>
+#include <boost/spirit/include/phoenix1_operators.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_statements.hpp>
+#include <boost/spirit/include/phoenix1_special_ops.hpp>
+
+using namespace std;
+using namespace phoenix;
+
+int
+main()
+{
+ int init[] = { 2, 10, 4, 5, 1, 6, 8, 3, 9, 7 };
+ vector<int> c(init, init + 10);
+ typedef vector<int>::iterator iterator;
+
+ // Print all odd contents of an stl container c
+ for_each(c.begin(), c.end(),
+ if_(arg1 % 2 == 1)
+ [
+ cout << arg1 << ' '
+ ]
+ );
+
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample5.cpp b/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample5.cpp
new file mode 100644
index 00000000..ed2b4ae7
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample5.cpp
@@ -0,0 +1,43 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <vector>
+#include <algorithm>
+#include <iostream>
+#include <boost/spirit/include/phoenix1_operators.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+
+using namespace std;
+using namespace phoenix;
+
+//////////////////////////////////
+template <int N>
+struct static_int {
+
+ template <typename TupleT>
+ struct result { typedef int type; };
+
+ template <typename TupleT>
+ int eval(TupleT const&) const { return N; }
+};
+
+//////////////////////////////////
+template <int N>
+phoenix::actor<static_int<N> >
+int_const()
+{
+ return static_int<N>();
+}
+
+//////////////////////////////////
+int
+main()
+{
+ cout << (int_const<5>() + int_const<6>())() << endl;
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample6.cpp b/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample6.cpp
new file mode 100644
index 00000000..1c1f7fd4
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample6.cpp
@@ -0,0 +1,88 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <vector>
+#include <algorithm>
+#include <iostream>
+#include <boost/spirit/include/phoenix1_operators.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_composite.hpp>
+#include <boost/spirit/include/phoenix1_special_ops.hpp>
+
+using namespace std;
+using namespace phoenix;
+
+//////////////////////////////////
+template <typename CondT, typename TrueT, typename FalseT>
+struct if_else_composite {
+
+ typedef if_else_composite<CondT, TrueT, FalseT> self_t;
+
+ template <typename TupleT>
+ struct result {
+
+ typedef typename higher_rank<
+ typename actor_result<TrueT, TupleT>::plain_type,
+ typename actor_result<FalseT, TupleT>::plain_type
+ >::type type;
+ };
+
+ if_else_composite(
+ CondT const& cond_, TrueT const& true__, FalseT const& false__)
+ : cond(cond_), true_(true__), false_(false__) {}
+
+ template <typename TupleT>
+ typename actor_result<self_t, TupleT>::type
+ eval(TupleT const& args) const
+ {
+ return cond.eval(args) ? true_.eval(args) : false_.eval(args);
+ }
+
+ CondT cond; TrueT true_; FalseT false_; // actors
+};
+
+//////////////////////////////////
+template <typename CondT, typename TrueT, typename FalseT>
+inline actor<if_else_composite<
+ typename as_actor<CondT>::type,
+ typename as_actor<TrueT>::type,
+ typename as_actor<FalseT>::type> >
+if_else_(CondT const& cond, TrueT const& true_, FalseT const& false_)
+{
+ typedef if_else_composite<
+ typename as_actor<CondT>::type,
+ typename as_actor<TrueT>::type,
+ typename as_actor<FalseT>::type>
+ result;
+
+ return result(
+ as_actor<CondT>::convert(cond),
+ as_actor<TrueT>::convert(true_),
+ as_actor<FalseT>::convert(false_));
+}
+
+//////////////////////////////////
+int
+main()
+{
+ int init[] = { 2, 10, 4, 5, 1, 6, 8, 3, 9, 7 };
+ vector<int> c(init, init + 10);
+ typedef vector<int>::iterator iterator;
+
+ // Print all contents of an stl container c and
+ // prefix " is odd" or " is even" appropriately.
+
+ for_each(c.begin(), c.end(),
+ cout
+ << arg1
+ << if_else_(arg1 % 2 == 1, " is odd", " is even")
+ << val('\n')
+ );
+
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample7.cpp b/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample7.cpp
new file mode 100644
index 00000000..713121f3
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample7.cpp
@@ -0,0 +1,275 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <vector>
+#include <algorithm>
+#include <iostream>
+
+#define PHOENIX_LIMIT 5
+#include <boost/spirit/include/phoenix1_operators.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_composite.hpp>
+#include <boost/spirit/include/phoenix1_special_ops.hpp>
+#include <boost/spirit/include/phoenix1_statements.hpp>
+
+namespace phoenix {
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// local_tuple
+//
+// This *is a* tuple like the one we see in TupleT in any actor
+// base class' eval member function. local_tuple should look and
+// feel the same as a tupled-args, that's why it is derived from
+// TupleArgsT. It has an added member, locs which is another tuple
+// where the local variables will be stored. locs is mutable to
+// allow read-write access to our locals regardless of
+// local_tuple's constness (The eval member function accepts it as
+// a const argument).
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename TupleArgsT, typename TupleLocsT>
+struct local_tuple : public TupleArgsT {
+
+ typedef TupleLocsT local_vars_t;
+
+ local_tuple(TupleArgsT const& args, TupleLocsT const& locs_)
+ : TupleArgsT(args), locs(locs_) {}
+
+ mutable TupleLocsT locs;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// local_var_result
+//
+// This is a return type computer. Given a constant integer N and a
+// tuple, get the Nth local variable type. If TupleT is not really
+// a local_tuple, we just return nil_t. Otherwise we get the Nth
+// local variable type.
+//
+///////////////////////////////////////////////////////////////////////////////
+template <int N, typename TupleT>
+struct local_var_result {
+
+ typedef nil_t type;
+};
+
+//////////////////////////////////
+template <int N, typename TupleArgsT, typename TupleLocsT>
+struct local_var_result<N, local_tuple<TupleArgsT, TupleLocsT> > {
+
+ typedef typename tuple_element<N, TupleLocsT>::type& type;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// local_var
+//
+// This class looks so curiously like the argument class. local_var
+// provides access to the Nth local variable packed in the tuple
+// duo local_tuple above. Note that the member function eval
+// expects a local_tuple argument. Otherwise the expression
+// 'tuple.locs' will fail (compile-time error). local_var
+// primitives only work within the context of a locals_composite
+// (see below).
+//
+// Provided are some predefined local_var actors for 0..N local
+// variable access: loc1..locN.
+//
+///////////////////////////////////////////////////////////////////////////////
+template <int N>
+struct local_var {
+
+ template <typename TupleT>
+ struct result {
+
+ typedef typename local_var_result<N, TupleT>::type type;
+ };
+
+ template <typename TupleT>
+ typename local_var_result<N, TupleT>::type
+ eval(TupleT const& tuple) const
+ {
+ return tuple.locs[tuple_index<N>()];
+ }
+};
+
+//////////////////////////////////
+actor<local_var<0> > const loc1 = local_var<0>();
+actor<local_var<1> > const loc2 = local_var<1>();
+actor<local_var<2> > const loc3 = local_var<2>();
+actor<local_var<3> > const loc4 = local_var<3>();
+actor<local_var<4> > const loc5 = local_var<4>();
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// locals_composite
+//
+// This class encapsulates an actor and some local variable
+// initializers packed in a tuple.
+//
+// locals_composite is just like a proxy and delegates the actual
+// evaluation to the actor. The actor does the actual work. In the
+// eval member function, before invoking the embedded actor's eval
+// member function, we first stuff an instance of our locals and
+// bundle both 'args' and 'locals' in a local_tuple. This
+// local_tuple instance is created in the stack initializing it
+// with our locals member. We then pass this local_tuple instance
+// as an argument to the actor's eval member function.
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename ActorT, typename LocsT>
+struct locals_composite {
+
+ typedef locals_composite<ActorT, LocsT> self_t;
+
+ template <typename TupleT>
+ struct result { typedef typename actor_result<ActorT, TupleT>::type type; };
+
+ locals_composite(ActorT const& actor_, LocsT const& locals_)
+ : actor(actor_), locals(locals_) {}
+
+ template <typename TupleT>
+ typename actor_result<ActorT, TupleT>::type
+ eval(TupleT const& args) const
+ {
+ actor.eval(local_tuple<TupleT, LocsT>(args, locals));
+ }
+
+ ActorT actor;
+ LocsT locals;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// locals_gen
+//
+// At construction time, this class is given some local var-
+// initializers packed in a tuple. We just store this for later.
+// The operator[] of this class creates the actual locals_composite
+// given an actor. This is responsible for the construct
+// locals<types>[actor].
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename LocsT>
+struct locals_gen {
+
+ locals_gen(LocsT const& locals_)
+ : locals(locals_) {}
+
+ template <typename ActorT>
+ actor<locals_composite<typename as_actor<ActorT>::type, LocsT> >
+ operator[](ActorT const& actor)
+ {
+ return locals_composite<typename as_actor<ActorT>::type, LocsT>
+ (as_actor<ActorT>::convert(actor), locals);
+ }
+
+ LocsT locals;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Front end generator functions. These generators are overloaded for
+// 1..N local variables. locals<T0,... TN>(i0,...iN) generate locals_gen
+// objects (see above).
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename T0>
+inline locals_gen<tuple<T0> >
+locals(
+ T0 const& _0 = T0()
+)
+{
+ typedef tuple<T0> tuple_t;
+ return locals_gen<tuple_t>(tuple_t(_0));
+}
+
+//////////////////////////////////
+template <typename T0, typename T1>
+inline locals_gen<tuple<T0, T1> >
+locals(
+ T0 const& _0 = T0(),
+ T1 const& _1 = T1()
+)
+{
+ typedef tuple<T0, T1> tuple_t;
+ return locals_gen<tuple_t>(tuple_t(_0, _1));
+}
+
+//////////////////////////////////
+template <typename T0, typename T1, typename T2>
+inline locals_gen<tuple<T0, T1, T2> >
+locals(
+ T0 const& _0 = T0(),
+ T1 const& _1 = T1(),
+ T2 const& _2 = T2()
+)
+{
+ typedef tuple<T0, T1, T2> tuple_t;
+ return locals_gen<tuple_t>(tuple_t(_0, _1, _2));
+}
+
+//////////////////////////////////
+template <typename T0, typename T1, typename T2, typename T3>
+inline locals_gen<tuple<T0, T1, T2, T3> >
+locals(
+ T0 const& _0 = T0(),
+ T1 const& _1 = T1(),
+ T2 const& _2 = T2(),
+ T3 const& _3 = T3()
+)
+{
+ typedef tuple<T0, T1, T2, T3> tuple_t;
+ return locals_gen<tuple_t>(tuple_t(_0, _1, _2, _3));
+}
+
+//////////////////////////////////
+template <typename T0, typename T1, typename T2, typename T3, typename T4>
+inline locals_gen<tuple<T0, T1, T2, T3, T4> >
+locals(
+ T0 const& _0 = T0(),
+ T1 const& _1 = T1(),
+ T2 const& _2 = T2(),
+ T3 const& _3 = T3(),
+ T4 const& _4 = T4()
+)
+{
+ typedef tuple<T0, T1, T2, T3> tuple_t;
+ return locals_gen<tuple_t>(tuple_t(_0, _1, _2, _3, _4));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+}
+
+//////////////////////////////////
+using namespace std;
+using namespace phoenix;
+
+//////////////////////////////////
+int
+main()
+{
+ int init[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+ vector<int> c(init, init + 10);
+ typedef vector<int>::iterator iterator;
+
+ for_each(c.begin(), c.end(),
+ locals<int, char const*>(0, "...That's all\n")
+ [
+ for_(loc1 = 0, loc1 < arg1, ++loc1)
+ [
+ cout << loc1 << ", "
+ ],
+ cout << loc2
+ ]
+ );
+
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample8.cpp b/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample8.cpp
new file mode 100644
index 00000000..eef462d3
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample8.cpp
@@ -0,0 +1,284 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <vector>
+#include <algorithm>
+#include <iostream>
+
+#define PHOENIX_LIMIT 5
+#include <boost/spirit/include/phoenix1_operators.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_composite.hpp>
+#include <boost/spirit/include/phoenix1_special_ops.hpp>
+#include <boost/spirit/include/phoenix1_statements.hpp>
+
+namespace phoenix {
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// local_tuple
+//
+// This *is a* tuple like the one we see in TupleT in any actor
+// base class' eval member function. local_tuple should look and
+// feel the same as a tupled-args, that's why it is derived from
+// TupleArgsT. It has an added member, locs which is another tuple
+// where the local variables will be stored. locs is mutable to
+// allow read-write access to our locals regardless of
+// local_tuple's constness (The eval member function accepts it as
+// a const argument).
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename TupleArgsT, typename TupleLocsT>
+struct local_tuple : public TupleArgsT {
+
+ typedef TupleLocsT local_vars_t;
+
+ local_tuple(TupleArgsT const& args, TupleLocsT const& locs_)
+ : TupleArgsT(args), locs(locs_) {}
+
+ mutable TupleLocsT locs;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// local_var_result
+//
+// This is a return type computer. Given a constant integer N and a
+// tuple, get the Nth local variable type. If TupleT is not really
+// a local_tuple, we just return nil_t. Otherwise we get the Nth
+// local variable type.
+//
+///////////////////////////////////////////////////////////////////////////////
+template <int N, typename TupleT>
+struct local_var_result {
+
+ typedef nil_t type;
+};
+
+//////////////////////////////////
+template <int N, typename TupleArgsT, typename TupleLocsT>
+struct local_var_result<N, local_tuple<TupleArgsT, TupleLocsT> > {
+
+ typedef typename tuple_element<N, TupleLocsT>::type& type;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// local_var
+//
+// This class looks so curiously like the argument class. local_var
+// provides access to the Nth local variable packed in the tuple
+// duo local_tuple above. Note that the member function eval
+// expects a local_tuple argument. Otherwise the expression
+// 'tuple.locs' will fail (compile-time error). local_var
+// primitives only work within the context of a context_composite
+// (see below).
+//
+// Provided are some predefined local_var actors for 0..N local
+// variable access: loc1..locN.
+//
+///////////////////////////////////////////////////////////////////////////////
+template <int N>
+struct local_var {
+
+ template <typename TupleT>
+ struct result {
+
+ typedef typename local_var_result<N, TupleT>::type type;
+ };
+
+ template <typename TupleT>
+ typename local_var_result<N, TupleT>::type
+ eval(TupleT const& tuple) const
+ {
+ return tuple.locs[tuple_index<N>()];
+ }
+};
+
+//////////////////////////////////
+namespace locals {
+
+ actor<local_var<0> > const result = local_var<0>();
+ actor<local_var<1> > const loc1 = local_var<1>();
+ actor<local_var<2> > const loc2 = local_var<2>();
+ actor<local_var<3> > const loc3 = local_var<3>();
+ actor<local_var<4> > const loc4 = local_var<4>();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// context_composite
+//
+// This class encapsulates an actor and some local variable
+// initializers packed in a tuple.
+//
+// context_composite is just like a proxy and delegates the actual
+// evaluation to the actor. The actor does the actual work. In the
+// eval member function, before invoking the embedded actor's eval
+// member function, we first stuff an instance of our locals and
+// bundle both 'args' and 'locals' in a local_tuple. This
+// local_tuple instance is created in the stack initializing it
+// with our locals member. We then pass this local_tuple instance
+// as an argument to the actor's eval member function.
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename ActorT, typename LocsT>
+struct context_composite {
+
+ typedef context_composite<ActorT, LocsT> self_t;
+
+ template <typename TupleT>
+ struct result { typedef typename tuple_element<0, LocsT>::type type; };
+
+ context_composite(ActorT const& actor_, LocsT const& locals_)
+ : actor(actor_), locals(locals_) {}
+
+ template <typename TupleT>
+ typename tuple_element<0, LocsT>::type
+ eval(TupleT const& args) const
+ {
+ local_tuple<TupleT, LocsT> local_context(args, locals);
+ actor.eval(local_context);
+ return local_context.locs[tuple_index<0>()];
+ }
+
+ ActorT actor;
+ LocsT locals;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// context_gen
+//
+// At construction time, this class is given some local var-
+// initializers packed in a tuple. We just store this for later.
+// The operator[] of this class creates the actual context_composite
+// given an actor. This is responsible for the construct
+// context<types>[actor].
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename LocsT>
+struct context_gen {
+
+ context_gen(LocsT const& locals_)
+ : locals(locals_) {}
+
+ template <typename ActorT>
+ actor<context_composite<typename as_actor<ActorT>::type, LocsT> >
+ operator[](ActorT const& actor)
+ {
+ return context_composite<typename as_actor<ActorT>::type, LocsT>
+ (as_actor<ActorT>::convert(actor), locals);
+ }
+
+ LocsT locals;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Front end generator functions. These generators are overloaded for
+// 1..N local variables. context<T0,... TN>(i0,...iN) generate context_gen
+// objects (see above).
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename T0>
+inline context_gen<tuple<T0> >
+context()
+{
+ typedef tuple<T0> tuple_t;
+ return context_gen<tuple_t>(tuple_t(T0()));
+}
+
+//////////////////////////////////
+template <typename T0, typename T1>
+inline context_gen<tuple<T0, T1> >
+context(
+ T1 const& _1 = T1()
+)
+{
+ typedef tuple<T0, T1> tuple_t;
+ return context_gen<tuple_t>(tuple_t(T0(), _1));
+}
+
+//////////////////////////////////
+template <typename T0, typename T1, typename T2>
+inline context_gen<tuple<T0, T1, T2> >
+context(
+ T1 const& _1 = T1(),
+ T2 const& _2 = T2()
+)
+{
+ typedef tuple<T0, T1, T2> tuple_t;
+ return context_gen<tuple_t>(tuple_t(T0(), _1, _2));
+}
+
+//////////////////////////////////
+template <typename T0, typename T1, typename T2, typename T3>
+inline context_gen<tuple<T0, T1, T2, T3> >
+context(
+ T1 const& _1 = T1(),
+ T2 const& _2 = T2(),
+ T3 const& _3 = T3()
+)
+{
+ typedef tuple<T0, T1, T2, T3> tuple_t;
+ return context_gen<tuple_t>(tuple_t(T0(), _1, _2, _3));
+}
+
+//////////////////////////////////
+template <typename T0, typename T1, typename T2, typename T3, typename T4>
+inline context_gen<tuple<T0, T1, T2, T3, T4> >
+context(
+ T1 const& _1 = T1(),
+ T2 const& _2 = T2(),
+ T3 const& _3 = T3(),
+ T4 const& _4 = T4()
+)
+{
+ typedef tuple<T0, T1, T2, T3> tuple_t;
+ return context_gen<tuple_t>(tuple_t(T0(), _1, _2, _3, _4));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+}
+
+//////////////////////////////////
+using namespace std;
+using namespace phoenix;
+using namespace phoenix::locals;
+
+//////////////////////////////////
+int
+main()
+{
+ int init[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+ vector<int> c(init, init + 10);
+ typedef vector<int>::iterator iterator;
+
+ // find the first element > 5, print each element
+ // as we traverse the container c. Print the result
+ // if one is found.
+
+ find_if(c.begin(), c.end(),
+ context<bool>()
+ [
+ cout << arg1,
+ result = arg1 > 5,
+ if_(!result)
+ [
+ cout << val(", ")
+ ]
+ .else_
+ [
+ cout << val(" found result == ") << arg1
+ ]
+ ]
+ );
+
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample9.cpp b/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample9.cpp
new file mode 100644
index 00000000..f67a6d04
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/example/fundamental/sample9.cpp
@@ -0,0 +1,311 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <vector>
+#include <algorithm>
+#include <iostream>
+
+#define PHOENIX_LIMIT 5
+#include <boost/spirit/include/phoenix1_operators.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_composite.hpp>
+#include <boost/spirit/include/phoenix1_special_ops.hpp>
+#include <boost/spirit/include/phoenix1_statements.hpp>
+
+namespace phoenix {
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// local_tuple
+//
+// This *is a* tuple like the one we see in TupleT in any actor
+// base class' eval member function. local_tuple should look and
+// feel the same as a tupled-args, that's why it is derived from
+// TupleArgsT. It has an added member, locs which is another tuple
+// where the local variables will be stored. locs is mutable to
+// allow read-write access to our locals regardless of
+// local_tuple's constness (The eval member function accepts it as
+// a const argument).
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename TupleArgsT, typename TupleLocsT>
+struct local_tuple : public TupleArgsT {
+
+ typedef TupleLocsT local_vars_t;
+ typedef TupleArgsT parent_t;
+
+ local_tuple(TupleArgsT const& args, TupleLocsT const& locs_)
+ : TupleArgsT(args), locs(locs_) {}
+
+ TupleArgsT& parent() { return *this; }
+ TupleArgsT const& parent() const { return *this; }
+
+ mutable TupleLocsT locs;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// local_var_result
+//
+// This is a return type computer. Given a constant integer N, a
+// parent index and a tuple, get the Nth local variable type. The
+// parent index is an integer specifying which parent scope to
+// access; 0==current scope, 1==parent scope, 2==parent's parent
+// scope.
+//
+// This is a metaprogram with partial specializations. There is a
+// general case, a special case for local_tuples and a terminating
+// special case for local_tuples.
+//
+// General case: If TupleT is not really a local_tuple, we just return nil_t.
+//
+// local_tuples case:
+// Parent index is 0: We get the Nth local variable.
+// Otherwise: We subclass from local_tuples<N, Parent-1, TupleArgsT>
+//
+///////////////////////////////////////////////////////////////////////////////
+template <int N, int Parent, typename TupleT>
+struct local_var_result {
+
+ typedef nil_t type;
+};
+
+//////////////////////////////////
+template <int N, int Parent, typename TupleArgsT, typename TupleLocsT>
+struct local_var_result<N, Parent, local_tuple<TupleArgsT, TupleLocsT> >
+: public local_var_result<N, Parent-1, TupleArgsT> {};
+
+//////////////////////////////////
+template <int N, typename TupleArgsT, typename TupleLocsT>
+struct local_var_result<N, 0, local_tuple<TupleArgsT, TupleLocsT> > {
+
+ typedef typename tuple_element<
+ N, TupleLocsT
+ >::type& type;
+
+ static type get(local_tuple<TupleArgsT, TupleLocsT> const& tuple)
+ { return tuple.locs[tuple_index<N>()]; }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// local_var
+//
+// This class looks so curiously like the argument class. local_var
+// provides access to the Nth local variable packed in the tuple
+// duo local_tuple above. Parent specifies the Nth parent scope.
+// 0==current scope, 1==parent scope, 2==parent's parent scope. The
+// member function parent<N>() may be called to provide access to
+// outer scopes.
+//
+// Note that the member function eval expects a local_tuple
+// argument. Otherwise there will be acompile-time error. local_var
+// primitives only work within the context of a context_composite
+// (see below).
+//
+// Provided are some predefined local_var actors for 0..N local
+// variable access: loc1..locN.
+//
+///////////////////////////////////////////////////////////////////////////////
+template <int N, int Parent = 0>
+struct local_var {
+
+ template <typename TupleT>
+ struct result {
+
+ typedef typename local_var_result<N, Parent, TupleT>::type type;
+ };
+
+ template <typename TupleT>
+ typename local_var_result<N, Parent, TupleT>::type
+ eval(TupleT const& tuple) const
+ {
+ return local_var_result<N, Parent, TupleT>::get(tuple);
+ }
+
+ template <int PIndex>
+ actor<local_var<N, Parent+PIndex> >
+ parent() const
+ {
+ return local_var<N, Parent+PIndex>();
+ }
+};
+
+//////////////////////////////////
+namespace locals {
+
+ actor<local_var<0> > const result = local_var<0>();
+ actor<local_var<1> > const loc1 = local_var<1>();
+ actor<local_var<2> > const loc2 = local_var<2>();
+ actor<local_var<3> > const loc3 = local_var<3>();
+ actor<local_var<4> > const loc4 = local_var<4>();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// context_composite
+//
+// This class encapsulates an actor and some local variable
+// initializers packed in a tuple.
+//
+// context_composite is just like a proxy and delegates the actual
+// evaluation to the actor. The actor does the actual work. In the
+// eval member function, before invoking the embedded actor's eval
+// member function, we first stuff an instance of our locals and
+// bundle both 'args' and 'locals' in a local_tuple. This
+// local_tuple instance is created in the stack initializing it
+// with our locals member. We then pass this local_tuple instance
+// as an argument to the actor's eval member function.
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename ActorT, typename LocsT>
+struct context_composite {
+
+ typedef context_composite<ActorT, LocsT> self_t;
+
+ template <typename TupleT>
+ struct result { typedef typename tuple_element<0, LocsT>::type type; };
+
+ context_composite(ActorT const& actor_, LocsT const& locals_)
+ : actor(actor_), locals(locals_) {}
+
+ template <typename TupleT>
+ typename tuple_element<0, LocsT>::type
+ eval(TupleT const& args) const
+ {
+ local_tuple<TupleT, LocsT> local_context(args, locals);
+ actor.eval(local_context);
+ return local_context.locs[tuple_index<0>()];
+ }
+
+ ActorT actor;
+ LocsT locals;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// context_gen
+//
+// At construction time, this class is given some local var-
+// initializers packed in a tuple. We just store this for later.
+// The operator[] of this class creates the actual context_composite
+// given an actor. This is responsible for the construct
+// context<types>[actor].
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename LocsT>
+struct context_gen {
+
+ context_gen(LocsT const& locals_)
+ : locals(locals_) {}
+
+ template <typename ActorT>
+ actor<context_composite<typename as_actor<ActorT>::type, LocsT> >
+ operator[](ActorT const& actor)
+ {
+ return context_composite<typename as_actor<ActorT>::type, LocsT>
+ (as_actor<ActorT>::convert(actor), locals);
+ }
+
+ LocsT locals;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Front end generator functions. These generators are overloaded for
+// 1..N local variables. context<T0,... TN>(i0,...iN) generate context_gen
+// objects (see above).
+//
+///////////////////////////////////////////////////////////////////////////////
+template <typename T0>
+inline context_gen<tuple<T0> >
+context()
+{
+ typedef tuple<T0> tuple_t;
+ return context_gen<tuple_t>(tuple_t(T0()));
+}
+
+//////////////////////////////////
+template <typename T0, typename T1>
+inline context_gen<tuple<T0, T1> >
+context(
+ T1 const& _1 = T1()
+)
+{
+ typedef tuple<T0, T1> tuple_t;
+ return context_gen<tuple_t>(tuple_t(T0(), _1));
+}
+
+//////////////////////////////////
+template <typename T0, typename T1, typename T2>
+inline context_gen<tuple<T0, T1, T2> >
+context(
+ T1 const& _1 = T1(),
+ T2 const& _2 = T2()
+)
+{
+ typedef tuple<T0, T1, T2> tuple_t;
+ return context_gen<tuple_t>(tuple_t(T0(), _1, _2));
+}
+
+//////////////////////////////////
+template <typename T0, typename T1, typename T2, typename T3>
+inline context_gen<tuple<T0, T1, T2, T3> >
+context(
+ T1 const& _1 = T1(),
+ T2 const& _2 = T2(),
+ T3 const& _3 = T3()
+)
+{
+ typedef tuple<T0, T1, T2, T3> tuple_t;
+ return context_gen<tuple_t>(tuple_t(T0(), _1, _2, _3));
+}
+
+//////////////////////////////////
+template <typename T0, typename T1, typename T2, typename T3, typename T4>
+inline context_gen<tuple<T0, T1, T2, T3, T4> >
+context(
+ T1 const& _1 = T1(),
+ T2 const& _2 = T2(),
+ T3 const& _3 = T3(),
+ T4 const& _4 = T4()
+)
+{
+ typedef tuple<T0, T1, T2, T3> tuple_t;
+ return context_gen<tuple_t>(tuple_t(T0(), _1, _2, _3, _4));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+}
+
+//////////////////////////////////
+using namespace std;
+using namespace phoenix;
+using namespace phoenix::locals;
+
+//////////////////////////////////
+int
+main()
+{
+ context<nil_t>(1)
+ [
+ cout << loc1 << '\n',
+ context<nil_t>(2)
+ [
+ cout << loc1.parent<1>() << ' ' << loc1 << '\n',
+ context<nil_t>(3)
+ [
+ cout << loc1.parent<2>() << ' ' << loc1.parent<1>() << ' ' << loc1 << '\n'
+ ]
+ ]
+ ]
+
+ ();
+
+ return 0;
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/index.html b/src/boost/libs/spirit/classic/phoenix/index.html
new file mode 100644
index 00000000..0f556ec5
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/index.html
@@ -0,0 +1,180 @@
+<html>
+<head>
+<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
+<title>Phoenix V1.2.1</title>
+<link rel="stylesheet" href="doc/theme/style.css" type="text/css">
+<link rel="next" href="doc/preface.html">
+</head>
+<body>
+<table width="100%" height="48" border="0" background="doc/theme/bkd2.gif" cellspacing="2">
+ <tr>
+ <td width="10">
+ </td>
+ <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Phoenix
+ v1.2.1</b></font> </td>
+ <td width="112"><a href="http://spirit.sf.net"><img src="doc/theme/spirit.gif" align="right" border="0"></a></td>
+ </tr>
+</table>
+<br>
+<table width="80%" border="0" align="center">
+ <tr>
+ <td class="toc_title">Table of contents</td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0">
+ <a href="doc/preface.html">Preface</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0">
+ <a href="doc/introduction.html">Introduction</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0">
+ <a href="doc/quick_start.html">Quick start</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0">
+ <a href="doc/basic_concepts.html">Basic Concepts</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0">
+ <a href="doc/architecture.html">Architecture</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/lazy_functions.html">Lazy functions</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/place_holders.html">Place holders</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/polymorphic_functions.html">Polymorphic functions</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/organization.html">Organization</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0">
+ <a href="doc/actors.html">Actors</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0">
+ <a href="doc/primitives.html">Primitives</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/arguments.html">Arguments</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/values.html">Values</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/variables.html">Variables</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0">
+ <a href="doc/composites.html">Composites</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/functions.html">Functions</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/operators.html">Operators</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/statements.html">Statements</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/binders.html">Binders</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/adaptable_closures.html">Adaptable closures</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/lazy_construction.html">Lazy Construction and Conversions</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0">
+ <a href="doc/efficiency.html">Efficiency</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0">
+ <a href="doc/inside_phoenix.html">Inside Phoenix</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/tuples.html">Tuples</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/actors_revisited.html">Actors revisited</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/composites_revisited.html">Composites revisited</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/operators_revisited.html">Operators revisited</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L1">
+ <a href="doc/interfacing.html">Interfacing</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0">
+ <a href="doc/wrap_up.html">Wrap up</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="toc_cells_L0">
+ <a href="doc/references.html">References</a>
+ </td>
+ </tr>
+</table>
+<br>
+<hr size="1"><p class="copyright">Copyright &copy; 2001-2002 Joel de Guzman<br><br>
+<font size="2">Use, modification and distribution is subject to 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) </font> </p>
+</body>
+</html>
diff --git a/src/boost/libs/spirit/classic/phoenix/test/Jamfile b/src/boost/libs/spirit/classic/phoenix/test/Jamfile
new file mode 100644
index 00000000..cfc1b0cd
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/test/Jamfile
@@ -0,0 +1,81 @@
+#==============================================================================
+# Copyright (c) 2002 Joel de Guzman
+# http://spirit.sourceforge.net/
+#
+# Use, modification and distribution is subject to 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)
+#==============================================================================
+#
+# Phoenix examples boost-jam file
+# Joel de Guzman [Sept 27, 2002]
+#
+
+unit-test binary_tests
+ : binary_tests.cpp
+ :
+ ;
+
+unit-test binders_tests
+ : binders_tests.cpp
+ :
+ ;
+
+unit-test functors_tests
+ : functors_tests.cpp
+ :
+ ;
+
+unit-test iostream_tests
+ : iostream_tests.cpp
+ :
+ ;
+
+
+unit-test mixed_binary_tests
+ : mixed_binary_tests.cpp
+ :
+ ;
+
+
+unit-test more_expressions_tests
+ : more_expressions_tests.cpp
+ :
+ ;
+
+
+unit-test primitives_tests
+ : primitives_tests.cpp
+ :
+ ;
+
+
+unit-test statements_tests
+ : statements_tests.cpp
+ :
+ ;
+
+
+unit-test stl_tests
+ : stl_tests.cpp
+ :
+ ;
+
+
+unit-test tuples_tests
+ : tuples_tests.cpp
+ :
+ ;
+
+
+unit-test unary_tests
+ : unary_tests.cpp
+ :
+ ;
+
+
+unit-test new_tests
+ : new_test.cpp
+ :
+ ;
+
diff --git a/src/boost/libs/spirit/classic/phoenix/test/binary_tests.cpp b/src/boost/libs/spirit/classic/phoenix/test/binary_tests.cpp
new file mode 100644
index 00000000..56725316
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/test/binary_tests.cpp
@@ -0,0 +1,98 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#ifdef __GNUC__ // Darn these relops!
+#ifndef __SGI_STL_INTERNAL_RELOPS
+#define __SGI_STL_INTERNAL_RELOPS
+#endif
+#endif
+
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+#define PHOENIX_LIMIT 15
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_operators.hpp>
+
+using namespace phoenix;
+using namespace std;
+
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ int i2 = 2, i3 = 3, i = 5;
+ const char* world = " world";
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Binary operators
+//
+///////////////////////////////////////////////////////////////////////////////
+ BOOST_TEST((var(i) = var(i))() == 5);
+ BOOST_TEST((var(i) = 3)() == 3);
+ BOOST_TEST(i == 3);
+ i = 5;
+ int x, y, z;
+ (var(x) = var(y) = var(z) = 10)();
+ BOOST_TEST(x == 10 && y == 10 && z == 10);
+ BOOST_TEST((val(world)[3])() == world[3]);
+
+ BOOST_TEST((var(i) += 5)() == 10);
+ BOOST_TEST((var(i) -= 5)() == 5);
+ BOOST_TEST((var(i) *= 5)() == 25);
+ BOOST_TEST((var(i) /= 5)() == 5);
+ BOOST_TEST((var(i) %= 2)() == 1);
+
+ BOOST_TEST((var(i) <<= 3)() == 8);
+ BOOST_TEST((var(i) >>= 1)() == 4);
+ BOOST_TEST((var(i) |= 0xFF)() == 0xFF);
+ BOOST_TEST((var(i) &= 0xF0)() == 0xF0);
+ BOOST_TEST((var(i) ^= 0xFFFFFFFF)() == int(0xFFFFFF0F));
+
+ BOOST_TEST((val(5) == val(5))());
+ BOOST_TEST((val(5) == 5)());
+
+ BOOST_TEST((arg1 + arg2)(i2, i3) == i2 + i3);
+ BOOST_TEST((arg1 - arg2)(i2, i3) == i2 - i3);
+ BOOST_TEST((arg1 * arg2)(i2, i3) == i2 * i3);
+ BOOST_TEST((arg1 / arg2)(i2, i3) == i2 / i3);
+ BOOST_TEST((arg1 % arg2)(i2, i3) == i2 % i3);
+ BOOST_TEST((arg1 & arg2)(i2, i3) == (i2 & i3));
+ BOOST_TEST((arg1 | arg2)(i2, i3) == (i2 | i3));
+ BOOST_TEST((arg1 ^ arg2)(i2, i3) == (i2 ^ i3));
+ BOOST_TEST((arg1 << arg2)(i2, i3) == i2 << i3);
+ BOOST_TEST((arg1 >> arg2)(i2, i3) == i2 >> i3);
+
+ BOOST_TEST((val(5) != val(6))());
+ BOOST_TEST((val(5) < val(6))());
+ BOOST_TEST(!(val(5) > val(6))());
+ BOOST_TEST((val(5) < val(6))());
+ BOOST_TEST((val(5) <= val(6))());
+ BOOST_TEST((val(5) <= val(5))());
+ BOOST_TEST((val(7) >= val(6))());
+ BOOST_TEST((val(7) >= val(7))());
+
+ BOOST_TEST((val(false) && val(false))() == false);
+ BOOST_TEST((val(true) && val(false))() == false);
+ BOOST_TEST((val(false) && val(true))() == false);
+ BOOST_TEST((val(true) && val(true))() == true);
+
+ BOOST_TEST((val(false) || val(false))() == false);
+ BOOST_TEST((val(true) || val(false))() == true);
+ BOOST_TEST((val(false) || val(true))() == true);
+ BOOST_TEST((val(true) || val(true))() == true);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// End asserts
+//
+///////////////////////////////////////////////////////////////////////////////
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/test/binders_tests.cpp b/src/boost/libs/spirit/classic/phoenix/test/binders_tests.cpp
new file mode 100644
index 00000000..c73ce5cc
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/test/binders_tests.cpp
@@ -0,0 +1,123 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <iostream>
+#include <functional>
+#include <boost/detail/lightweight_test.hpp>
+
+#define PHOENIX_LIMIT 15
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_composite.hpp>
+#include <boost/spirit/include/phoenix1_binders.hpp>
+
+using namespace phoenix;
+using std::cout;
+using std::endl;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ struct print_ { // a typical STL style monomorphic functor
+
+ typedef void result_type;
+ void operator()() { cout << "got no args\n"; }
+ void operator()(int n0) { cout << "got 1 arg " << n0 << " \n"; }
+ void operator()(int n0, int n1) { cout << "got 2 args " << n0 << ", " << n1 << " \n"; }
+
+ void foo0() const { cout << "print_::foo0\n"; }
+ void foo1(int n0) { cout << "print_::foo1 " << n0 << " \n"; }
+ void foo2(int n0, int n1) { cout << "print_::foo2 " << n0 << ", " << n1 << " \n"; }
+
+ int x;
+ };
+
+ functor<print_> print = print_();
+ member_function_ptr<void, print_, int> print_foo1 = &print_::foo1;
+ member_function_ptr<void, print_, int, int> print_foo2 = &print_::foo2;
+ member_var_ptr<int, print_> print_x = &print_::x;
+ print_ p;
+ bound_member<void, print_, int> bound_print_foo1(p,&print_::foo1);
+ bound_member<void, print_, int, int> bound_print_foo2(&p,&print_::foo2);
+
+ ///////////////////////////////////////////////////////////////////////////////
+ void foo0() // a function w/ 0 args
+ { cout << "foo0\n"; }
+
+ void foo1(int n0) // a function w/ 1 arg
+ { cout << "foo1 " << n0 << " \n"; }
+
+ void foo2(int n0, int n1) // a function w/ 2 args
+ { cout << "foo2 " << n0 << ", " << n1 << " \n"; }
+
+ void foo3_(int n0, int n1, int n2) // a function w/ 3 args
+ { cout << "foo3 " << n0 << ", " << n1 << ", " << n2 << " \n"; }
+
+ function_ptr<void, int, int, int> foo3 = &foo3_;
+
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ int i50 = 50, i20 = 20, i100 = 100;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Binders
+//
+///////////////////////////////////////////////////////////////////////////////
+
+// Functor binders
+
+ print()();
+ print(111)();
+ print(111, arg1)(i100);
+ print(111, 222)();
+ cout << bind(std::negate<int>())(arg1)(i20) << endl;
+ cout << bind(std::plus<int>())(arg1, arg2)(i20, i50) << endl;
+
+// Function binders
+
+ bind(&foo0)()();
+ bind(&foo1)(111)();
+ bind(&foo2)(111, arg1)(i100);
+ bind(&foo2)(111, 222)();
+
+ foo3(111, 222, 333)();
+ foo3(arg1, arg2, arg3)(i20, i50, i100);
+ foo3(111, arg1, arg2)(i50, i100);
+
+// Member function binders
+
+ print_ printer;
+ bind(&print_::foo0)(arg1)(printer);
+
+ bind(&print_::foo1)(arg1, 111)(printer);
+ print_foo1(arg1, 111)(printer);
+ print_foo1(var(printer), 111)();
+ print_foo2(var(printer), 111, 222)();
+ print_foo2(var(printer), 111, arg1)(i100);
+
+// Member var binders
+
+ printer.x = 3;
+ BOOST_TEST(bind(&print_::x)(arg1)(printer) == 3);
+ BOOST_TEST(print_x(arg1)(printer) == 3);
+ BOOST_TEST(print_x(printer)() == 3);
+ BOOST_TEST(0 != (print_x(var(printer))() = 4));
+ BOOST_TEST(printer.x == 4);
+
+// Bound member functions
+
+ bind(&printer,&print_::foo0)()();
+
+ bind(printer,&print_::foo1)(111)();
+ bound_print_foo1(111)();
+ bound_print_foo1(111)();
+ bound_print_foo2(111, 222)();
+ bound_print_foo2(111, arg1)(i100);
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/test/functors_tests.cpp b/src/boost/libs/spirit/classic/phoenix/test/functors_tests.cpp
new file mode 100644
index 00000000..e0b84672
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/test/functors_tests.cpp
@@ -0,0 +1,95 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <iostream>
+#include <cmath>
+#include <boost/detail/lightweight_test.hpp>
+
+#define PHOENIX_LIMIT 15
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_composite.hpp>
+#include <boost/spirit/include/phoenix1_functions.hpp>
+#include <boost/spirit/include/phoenix1_operators.hpp>
+
+using namespace phoenix;
+using namespace std;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ struct test_ {
+
+ typedef void result_type;
+ void operator()() const { cout << "TEST LAZY FUNCTION\n"; }
+ };
+
+ function<test_> test;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ struct sqr_ {
+
+ template <typename ArgT>
+ struct result { typedef ArgT type; };
+
+ template <typename ArgT>
+ ArgT operator()(ArgT n) const { return n * n; }
+ };
+
+ function<sqr_> sqr;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ struct fact_ {
+
+ template <typename ArgT>
+ struct result { typedef ArgT type; };
+
+ template <typename ArgT>
+ ArgT operator()(ArgT n) const
+ { return (n <= 0) ? 1 : n * this->operator()(n-1); }
+ };
+
+ function<fact_> fact;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ struct pow_ {
+
+ template <typename Arg1T, typename Arg2T>
+ struct result { typedef Arg1T type; };
+
+ template <typename Arg1T, typename Arg2T>
+ Arg1T operator()(Arg1T a, Arg2T b) const { return pow(a, b); }
+ };
+
+ function<pow_> power;
+
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ int i5 = 5;
+ double d5 = 5, d3 = 3;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Lazy functors
+//
+///////////////////////////////////////////////////////////////////////////////
+
+ test()();
+ BOOST_TEST(sqr(arg1)(i5) == (i5*i5));
+ BOOST_TEST(fact(4)() == 24);
+ BOOST_TEST(fact(arg1)(i5) == 120);
+ BOOST_TEST((int)power(arg1, arg2)(d5, d3) == (int)pow(d5, d3));
+ BOOST_TEST((sqr(arg1) + 5)(i5) == ((i5*i5)+5));
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// End asserts
+//
+///////////////////////////////////////////////////////////////////////////////
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/test/iostream_tests.cpp b/src/boost/libs/spirit/classic/phoenix/test/iostream_tests.cpp
new file mode 100644
index 00000000..1677938b
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/test/iostream_tests.cpp
@@ -0,0 +1,86 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <string>
+#include <boost/detail/lightweight_test.hpp>
+
+#include <boost/config.hpp>
+#ifdef BOOST_NO_STRINGSTREAM
+#include <strstream>
+#define SSTREAM strstream
+std::string GETSTRING(std::strstream& ss)
+{
+ ss << ends;
+ std::string rval = ss.str();
+ ss.freeze(false);
+ return rval;
+}
+#else
+#include <sstream>
+#define GETSTRING(ss) ss.str()
+#define SSTREAM stringstream
+#endif
+
+//#define PHOENIX_LIMIT 15
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_composite.hpp>
+#include <boost/spirit/include/phoenix1_operators.hpp>
+#include <boost/spirit/include/phoenix1_special_ops.hpp>
+
+using namespace phoenix;
+using namespace std;
+
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ int i100 = 100;
+ string hello = "hello";
+ const char* world = " world";
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// IO streams
+//
+///////////////////////////////////////////////////////////////////////////////
+ vector<int> v;
+ v.push_back(1);
+ v.push_back(2);
+ v.push_back(3);
+ v.push_back(4);
+ v.push_back(5);
+
+ char const* msg = "cout assert\n";
+ (cout << arg1)(msg);
+ (cout << val(hello) << world << ", you da man!\n")();
+ for_each(v.begin(), v.end(), cout << arg1 << ',');
+ cout << endl;
+
+#ifdef __BORLANDC__ // *** See special_ops.hpp why ***
+ (cout << arg1 << "this is it, shukz:" << hex_ << arg2 << endl_ << endl_)(msg, i100);
+#else
+ (cout << arg1 << "this is it, shukz:" << hex << arg2 << endl << endl)(msg, i100);
+#endif
+ int in;
+ int out = 12345;
+ SSTREAM sstr;
+ (sstr << arg1)(out);
+ (sstr >> arg1)(in);
+ BOOST_TEST(in == out);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// End asserts
+//
+///////////////////////////////////////////////////////////////////////////////
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/test/mixed_binary_tests.cpp b/src/boost/libs/spirit/classic/phoenix/test/mixed_binary_tests.cpp
new file mode 100644
index 00000000..9f60a368
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/test/mixed_binary_tests.cpp
@@ -0,0 +1,50 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <iostream>
+#include <string>
+#include <boost/detail/lightweight_test.hpp>
+
+#define PHOENIX_LIMIT 15
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_operators.hpp>
+
+using namespace phoenix;
+using namespace std;
+
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ int i1 = 1, i2 = 2, i50 = 50, i100 = 100;
+ double d2_5 = 2.5;
+ string hello = "hello";
+ const char* world = " world";
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Mixed type operators
+//
+///////////////////////////////////////////////////////////////////////////////
+ BOOST_TEST((arg1 + arg2)(i100, i50) == (i100 + i50));
+ BOOST_TEST((arg1 + 3)(i100) == (3 + i100));
+ BOOST_TEST((arg1 + arg2)(hello, world) == "hello world");
+ BOOST_TEST((arg1 + arg2)(i1, d2_5) == (i1 + d2_5));
+
+ BOOST_TEST((*(arg1 + arg2))(world, i2) == *(world + i2));
+ BOOST_TEST((*(arg1 + arg2))(i2, world) == *(i2 + world));
+ BOOST_TEST((*(val(world+i2) - arg1))(i2) == *world);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// End asserts
+//
+///////////////////////////////////////////////////////////////////////////////
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/test/more_expressions_tests.cpp b/src/boost/libs/spirit/classic/phoenix/test/more_expressions_tests.cpp
new file mode 100644
index 00000000..51837416
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/test/more_expressions_tests.cpp
@@ -0,0 +1,104 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+#define PHOENIX_LIMIT 15
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_composite.hpp>
+#include <boost/spirit/include/phoenix1_functions.hpp>
+#include <boost/spirit/include/phoenix1_operators.hpp>
+
+using namespace phoenix;
+using namespace std;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ struct sqr_ {
+
+ template <typename ArgT>
+ struct result { typedef ArgT type; };
+
+ template <typename ArgT>
+ ArgT operator()(ArgT n) const { return n * n; }
+ };
+
+ function<sqr_> sqr;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ struct adder_ {
+
+ template <typename Arg1T, typename Arg2T, typename ArgT3>
+ struct result { typedef Arg1T type; };
+
+ template <typename Arg1T, typename Arg2T, typename ArgT3>
+ Arg1T operator()(Arg1T a, Arg2T b, ArgT3 c) const { return a + b + c; }
+ };
+
+ function<adder_> adder;
+
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ int i2 = 2, i = 4, i50 = 50, i10 = 10, i20 = 20, i100 = 100;
+ double d5 = 5, d10 = 10;
+ string hello = "hello";
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// More complex expressions
+//
+///////////////////////////////////////////////////////////////////////////////
+ BOOST_TEST((10 - arg1)(i100) == (10 - i100));
+ BOOST_TEST((20 - arg1)(i100) == (20 - i100));
+ BOOST_TEST((arg1 - 10)(i100) == (i100 - 10));
+ BOOST_TEST((arg1 - 20)(i100) == (i100 - 20));
+ BOOST_TEST((arg1 - arg2)(i100, i50) == (i100 - i50));
+ BOOST_TEST((arg1 - var(i))(i10) == (i10 - i));
+ BOOST_TEST((arg1 + arg2 - arg3)(i100, i50, i20) == (i100 + i50 - i20));
+ BOOST_TEST((sqr(arg1) + arg2 - arg3)(i100, i50, i20) == ((i100*i100) + i50 - i20));
+
+ int ii = i;
+ BOOST_TEST((var(i) += arg1)(i2) == (ii += i2));
+ BOOST_TEST((sqr(sqr(arg1)))(i100) == (i100*i100*i100*i100));
+
+
+#if 0 /*** SHOULD NOT COMPILE ***/
+ (val(3) += arg1)(i100);
+ (val(3) = 3)();
+#endif
+
+ BOOST_TEST(((adder(arg1, arg2, arg3) + arg2 - arg3)(i100, i50, i20)) == (i100 + i50 + i20) + i50 - i20);
+ BOOST_TEST((adder(arg1, arg2, arg3)(i100, i50, i20)) == (i100 + i50 + i20));
+ BOOST_TEST((sqr(sqr(sqr(sqr(arg1)))))(d10) == 1e16);
+ BOOST_TEST((sqr(sqr(arg1)) / arg1 / arg1)(d5) == 25);
+
+ for (int j = 0; j < 20; ++j)
+ {
+ cout << (10 < arg1)(j);
+ BOOST_TEST((10 < arg1)(j) == (10 < j));
+ }
+ cout << endl;
+
+ for (int k = 0; k < 20; ++k)
+ {
+ bool r = ((arg1 % 2 == 0) && (arg1 < 15))(k);
+ cout << r;
+ BOOST_TEST(r == ((k % 2 == 0) && (k < 15)));
+ }
+ cout << endl;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// End asserts
+//
+///////////////////////////////////////////////////////////////////////////////
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/test/new_test.cpp b/src/boost/libs/spirit/classic/phoenix/test/new_test.cpp
new file mode 100644
index 00000000..22c3b181
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/test/new_test.cpp
@@ -0,0 +1,46 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+ Copyright (c) 2003 Vaclav Vesely
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+#define PHOENIX_LIMIT 15
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_new.hpp>
+
+using namespace phoenix;
+using namespace std;
+
+class X
+{
+public:
+ X(int i_ = 1)
+ : i(i_)
+ {}
+
+ int i;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ int i2 = 2;
+ X x3(3);
+
+ BOOST_TEST(new_<int>()() != NULL);
+ BOOST_TEST(*new_<int>(arg1)(i2) == 2);
+
+ BOOST_TEST(new_<X>()() != NULL);
+ BOOST_TEST(new_<X>()()->i == 1);
+ BOOST_TEST(new_<X>(arg1)(i2)->i == 2);
+ BOOST_TEST(new_<X>(arg1)(x3)->i == 3);
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/test/primitives_tests.cpp b/src/boost/libs/spirit/classic/phoenix/test/primitives_tests.cpp
new file mode 100644
index 00000000..ada53334
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/test/primitives_tests.cpp
@@ -0,0 +1,42 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+#define PHOENIX_LIMIT 15
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+
+using namespace phoenix;
+using namespace std;
+
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ char c1 = '1';
+ int i1 = 1, i2 = 2, i = 4;
+ const char* s2 = "2";
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Values, variables and arguments
+//
+///////////////////////////////////////////////////////////////////////////////
+ cout << val("Hello")() << val(' ')() << val("World")() << endl;
+
+ BOOST_TEST(arg1(c1) == c1);
+ BOOST_TEST(arg1(i1, i2) == i1);
+ BOOST_TEST(arg2(i1, s2) == s2);
+
+ BOOST_TEST(val(3)() == 3);
+ BOOST_TEST(var(i)() == 4);
+ BOOST_TEST(var(++i)() == 5);
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/test/runtest.sh b/src/boost/libs/spirit/classic/phoenix/test/runtest.sh
new file mode 100644
index 00000000..09b804ea
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/test/runtest.sh
@@ -0,0 +1,25 @@
+#==============================================================================
+# Copyright (c) 2002 Joel de Guzman
+# http://spirit.sourceforge.net/
+#
+# Use, modification and distribution is subject to 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)
+#==============================================================================
+#!/bin/sh
+#./test1 << EOS || exit 1
+#123321
+#EOS
+./binary_tests || exit 1
+./binders_tests || exit 1
+./functors_tests || exit 1
+./iostream_tests << EOS || exit 1
+123321
+EOS
+./mixed_binary_tests || exit 1
+./more_expressions_tests || exit 1
+./primitives_tests || exit 1
+./statements_tests || exit 1
+./stl_tests || exit 1
+./tuples_tests || exit 1
+./unary_tests || exit 1
diff --git a/src/boost/libs/spirit/classic/phoenix/test/statements_tests.cpp b/src/boost/libs/spirit/classic/phoenix/test/statements_tests.cpp
new file mode 100644
index 00000000..83db0acf
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/test/statements_tests.cpp
@@ -0,0 +1,165 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <iostream>
+#include <vector>
+#include <algorithm>
+#include <boost/detail/lightweight_test.hpp>
+
+#define PHOENIX_LIMIT 15
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_functions.hpp>
+#include <boost/spirit/include/phoenix1_operators.hpp>
+#include <boost/spirit/include/phoenix1_special_ops.hpp>
+#include <boost/spirit/include/phoenix1_statements.hpp>
+
+using namespace phoenix;
+using namespace std;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ struct poly_print_ {
+
+ template <typename ArgT>
+ struct result { typedef void type; };
+
+ template <typename ArgT>
+ void operator()(ArgT v) const
+ { cout << v; }
+ };
+
+ function<poly_print_> poly_print;
+
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ char c1 = '1';
+ int i1 = 1;
+ double d2_5 = 2.5;
+ string hello = "hello";
+ const char* world = " world";
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Block statements
+//
+///////////////////////////////////////////////////////////////////////////////
+ (
+ poly_print(arg1),
+ poly_print(arg2),
+ poly_print(arg3),
+ poly_print(arg4),
+ poly_print(arg5),
+ poly_print("\n\n")
+ )
+ (hello, c1, world, i1, d2_5);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// If-else, while, do-while, for tatements
+//
+///////////////////////////////////////////////////////////////////////////////
+
+ vector<int> v;
+ v.push_back(1);
+ v.push_back(2);
+ v.push_back(3);
+ v.push_back(4);
+ v.push_back(5);
+ v.push_back(6);
+ v.push_back(7);
+ v.push_back(8);
+ v.push_back(9);
+ v.push_back(10);
+
+ cout << dec;
+
+ //////////////////////////////////
+ for_each(v.begin(), v.end(),
+ if_(arg1 > 3 && arg1 <= 8)
+ [
+ cout << arg1 << ", "
+ ]
+ );
+
+ cout << endl;
+
+ //////////////////////////////////
+ for_each(v.begin(), v.end(),
+ if_(arg1 > 5)
+ [
+ cout << arg1 << " > 5\n"
+ ]
+ .else_
+ [
+ if_(arg1 == 5)
+ [
+ cout << arg1 << " == 5\n"
+ ]
+ .else_
+ [
+ cout << arg1 << " < 5\n"
+ ]
+ ]
+ );
+
+ cout << endl;
+
+ vector<int> t = v;
+ //////////////////////////////////
+ for_each(v.begin(), v.end(),
+ (
+ while_(arg1--)
+ [
+ cout << arg1 << ", "
+ ],
+ cout << val("\n")
+ )
+ );
+
+ v = t;
+ cout << endl;
+
+ //////////////////////////////////
+ for_each(v.begin(), v.end(),
+ (
+ do_
+ [
+ cout << arg1 << ", "
+ ]
+ .while_(arg1--),
+ cout << val("\n")
+ )
+ );
+
+ v = t;
+ cout << endl;
+
+ //////////////////////////////////
+ int iii;
+ for_each(v.begin(), v.end(),
+ (
+ for_(var(iii) = 0, var(iii) < arg1, ++var(iii))
+ [
+ cout << arg1 << ", "
+ ],
+ cout << val("\n")
+ )
+ );
+
+ v = t;
+ cout << endl;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// End asserts
+//
+///////////////////////////////////////////////////////////////////////////////
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/test/stl_tests.cpp b/src/boost/libs/spirit/classic/phoenix/test/stl_tests.cpp
new file mode 100644
index 00000000..2fe461f0
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/test/stl_tests.cpp
@@ -0,0 +1,95 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <iostream>
+#include <vector>
+#include <list>
+#include <algorithm>
+#include <boost/detail/lightweight_test.hpp>
+
+#define PHOENIX_LIMIT 15
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_composite.hpp>
+#include <boost/spirit/include/phoenix1_functions.hpp>
+#include <boost/spirit/include/phoenix1_operators.hpp>
+#include <boost/spirit/include/phoenix1_binders.hpp>
+#include <boost/spirit/include/phoenix1_special_ops.hpp>
+
+using namespace phoenix;
+using namespace std;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ struct print_ { // a typical STL style monomorphic functor
+
+ typedef void result_type;
+ void operator()(int n0) { cout << "got 1 arg " << n0 << " \n"; }
+ };
+
+ functor<print_> print = print_();
+
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// STL algorithms
+//
+///////////////////////////////////////////////////////////////////////////////
+ vector<int> v;
+ v.push_back(1);
+ v.push_back(2);
+ v.push_back(3);
+ v.push_back(4);
+ v.push_back(5);
+
+ for_each(v.begin(), v.end(), arg1 *= 2);
+ for (int m = 0; m < 5; ++m, (cout << ','))
+ {
+ cout << v[m];
+ BOOST_TEST(v[m] == (m+1)*2);
+ }
+ cout << endl;
+
+ for_each(v.begin(), v.end(), print(arg1));
+
+ vector<int>::iterator it = find_if(v.begin(), v.end(), arg1 > 5);
+ if (it != v.end())
+ cout << *it << endl;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// STL iterators and containers
+//
+///////////////////////////////////////////////////////////////////////////////
+
+ BOOST_TEST((arg1[0])(v) == v[0]);
+ BOOST_TEST((arg1[1])(v) == v[1]);
+
+ list<int> l;
+ l.push_back(1);
+ l.push_back(2);
+ l.push_back(3);
+ l.push_back(4);
+ l.push_back(5);
+
+ list<int>::iterator first = l.begin();
+ list<int>::iterator last = l.end();
+
+ BOOST_TEST((*(++arg1))(first) == 2);
+ BOOST_TEST((*(----arg1))(last) == 4);
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// End asserts
+//
+///////////////////////////////////////////////////////////////////////////////
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/phoenix/test/tuples_tests.cpp b/src/boost/libs/spirit/classic/phoenix/test/tuples_tests.cpp
new file mode 100644
index 00000000..43b53fdd
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/test/tuples_tests.cpp
@@ -0,0 +1,57 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <iostream>
+#include <string>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/include/phoenix1_tuples.hpp>
+
+using namespace phoenix;
+using namespace phoenix::tuple_index_names;
+using std::cout;
+using std::endl;
+using std::string;
+
+int
+main()
+{
+ {
+ typedef tuple<int, char> tuple_t;
+ tuple_t ttt(3, 'c');
+
+ tuple_element<0, tuple_t>::type& e0 = ttt[_1];
+ tuple_element<1, tuple_t>::type& e1 = ttt[_2];
+
+ BOOST_TEST(e0 == 3);
+ BOOST_TEST(e1 == 'c');
+
+ cout << e0 << endl;
+ cout << e1 << endl;
+ }
+
+ {
+ typedef tuple<int, char, char const*> tuple_t;
+ tuple_t ttt(3, 'c', "hello world");
+ cout << ttt.length << endl;
+
+ tuple_element<0, tuple_t>::type& e0 = ttt[_1];
+ tuple_element<1, tuple_t>::type& e1 = ttt[_2];
+ tuple_element<2, tuple_t>::type& e2 = ttt[_3];
+
+ BOOST_TEST(e0 == 3);
+ BOOST_TEST(e1 == 'c');
+ BOOST_TEST(string(e2) == "hello world");
+
+ cout << e0 << endl;
+ cout << e1 << endl;
+ cout << e2 << endl;
+ }
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/phoenix/test/unary_tests.cpp b/src/boost/libs/spirit/classic/phoenix/test/unary_tests.cpp
new file mode 100644
index 00000000..6ac72cb6
--- /dev/null
+++ b/src/boost/libs/spirit/classic/phoenix/test/unary_tests.cpp
@@ -0,0 +1,47 @@
+/*=============================================================================
+ Phoenix V1.2.1
+ Copyright (c) 2001-2003 Joel de Guzman
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+#define PHOENIX_LIMIT 15
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_operators.hpp>
+
+using namespace phoenix;
+using namespace std;
+
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ int i1 = 1, i = 5;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Unary operators
+//
+///////////////////////////////////////////////////////////////////////////////
+ BOOST_TEST((!val(true))() == false);
+ BOOST_TEST((-val(1))() == -1);
+ BOOST_TEST((+val(1))() == +1);
+ BOOST_TEST((~val(1))() == ~1);
+ BOOST_TEST(*(&arg1)(i1) == *(&i1));
+ BOOST_TEST((&arg1)(i1) == &i1);
+
+ BOOST_TEST((*val(&i1))() == *(&i1));
+ BOOST_TEST((*&arg1)(i1) == *(&i1));
+ BOOST_TEST((++var(i))() == 6);
+ BOOST_TEST((--var(i))() == 5);
+ BOOST_TEST((var(i)++)() == 5);
+ BOOST_TEST(i == 6);
+ BOOST_TEST((var(i)--)() == 6);
+ BOOST_TEST(i == 5);
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/Jamfile b/src/boost/libs/spirit/classic/test/Jamfile
new file mode 100644
index 00000000..3ec2edcb
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/Jamfile
@@ -0,0 +1,204 @@
+#==============================================================================
+# Copyright (c) 2002 Joel de Guzman
+# Copyright (c) 2003-2004 Martin Wille
+# Copyright (c) 2019 Nikita Kniazev
+# http://spirit.sourceforge.net/
+#
+# Use, modification and distribution is subject to 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)
+#==============================================================================
+#
+# Spirit regression test boost-jam file
+# Joel de Guzman [Sept 27, 2002]
+#
+
+project spirit-classic
+ : requirements
+ <include>.
+ ;
+
+###############################################################################
+
+cpp-pch pch : pch.hpp : : : <include>. <toolset>msvc:<cxxflags>"/FIpch.hpp" ;
+cpp-pch pch-dbg : pch.hpp : <define>BOOST_SPIRIT_DEBUG :
+ : <include>. <toolset>msvc:<cxxflags>"/FIpch.hpp" ;
+
+explicit pch pch-dbg ;
+
+###############################################################################
+
+rule spirit-run ( sources + : args * : input-files * : requirements * : name ? : default-build * )
+{
+ name ?= $(sources[1]:D=:S=) ;
+ return
+ [ run $(sources) : $(args) : $(input-files) : $(requirements)
+ <pch>on-spirit:<source>pch : $(name)
+ : $(default-build) ]
+ [ run $(sources) : $(args) : $(input-files) : $(requirements)
+ <pch>on-spirit:<source>pch-dbg <define>BOOST_SPIRIT_DEBUG : $(name)_debug
+ : $(default-build) ]
+ ;
+}
+
+############################################################
+
+local opt = <toolset>vc-7.0:<optimization>speed
+ <toolset>vc-7.0:<inlining>on
+ <toolset>cw:<optimization>speed ;
+
+local opt-metrowerks = <toolset>cw:<optimization>speed ;
+
+
+# VP, 2005/04/14: MT is not available with Como, but this is
+# not handled yet.
+local multi-threading = <library>/boost/thread//boost_thread
+ <threading>multi <define>BOOST_ALL_NO_LIB ;
+
+ test-suite "spirit.classic.core.kernel"
+ : [ spirit-run match_tests.cpp ]
+ [ spirit-run post_skips.cpp ]
+ ;
+
+ test-suite "spirit.classic.core.scanner"
+ : [ spirit-run scanner_tests.cpp ]
+ [ spirit-run scanner_value_type_tests.cpp : : : <pch>off ]
+ ;
+
+ test-suite "spirit.classic.core.primitive"
+ : [ spirit-run primitives_tests.cpp ]
+ [ spirit-run char_strings_test.cpp ]
+ [ compile-fail char_strings_test_fail.cpp ]
+ [ spirit-run numerics_tests.cpp : : : $(opt) ]
+ [ spirit-run custom_real_parser.cpp ]
+ ;
+
+ test-suite "spirit.classic.core.composite"
+ : [ spirit-run epsilon_tests.cpp ]
+ [ spirit-run negated_eps_p_test.cpp ]
+ [ spirit-run operators_tests.cpp ]
+ [ spirit-run directives_tests.cpp ]
+ [ spirit-run shortest_alternative_tests.cpp ]
+ ;
+
+ test-suite "spirit.classic.core.non_terminal"
+ : [ spirit-run rule_tests.cpp : : : <pch>off ]
+ [ spirit-run owi_st_tests.cpp : : : <undef>BOOST_SPIRIT_THREADSAFE ]
+ [ spirit-run grammar_tests.cpp : : : <pch>off $(opt-metrowerks) ]
+ [ spirit-run grammar_multi_instance_tst.cpp : : : $(opt-metrowerks) ]
+ [ spirit-run subrule_tests.cpp ]
+ [ run owi_mt_tests.cpp : : : $(multi-threading) ]
+ [ run grammar_mt_tests.cpp : : : $(multi-threading) ]
+ [ spirit-run parser_context_test.cpp ]
+ ;
+
+ # traverse_tests defines SPIRIT_DEBUG, don't run the tests twice
+ test-suite "spirit.classic.meta"
+ : [ spirit-run fundamental_tests.cpp ]
+ [ spirit-run parser_traits_tests.cpp ]
+ [ spirit-run traverse_tests.cpp : : : <pch>off <toolset>intel:<debug-symbols>off ]
+ ;
+
+ test-suite "spirit.classic.attribute"
+ : [ spirit-run closure_tests.cpp : : : $(opt-metrowerks) ]
+ [ run bug_000008.cpp : : : $(multi-threading) ]
+ [ spirit-run parametric_tests.cpp ]
+ ;
+
+ test-suite "spirit.classic.error_handling"
+ : [ spirit-run exception_tests.cpp ]
+ ;
+
+ test-suite "spirit.classic.tree"
+ : [ spirit-run ast_calc_tests.cpp ]
+ [ spirit-run group_match_bug.cpp ]
+ [ spirit-run repeat_ast_tests.cpp ]
+ [ spirit-run tree_to_xml.cpp ]
+ [ compile mix_and_match_trees.cpp ]
+ ;
+
+# temporarily removed from the test suite. tree_tests are not finished, yet.
+# [ spirit-run tree_tests.cpp ]
+
+ test-suite "spirit.classic.dynamic"
+ : [ compile if_p_as_parser_tests.cpp ]
+ [ compile while_p_as_parser_tests.cpp ]
+ [ compile for_p_as_parser_tests.cpp ]
+ [ spirit-run if_tests.cpp ]
+ [ spirit-run if_p_int_as_condition_test.cpp ]
+ [ spirit-run for_tests.cpp ]
+ [ spirit-run while_tests.cpp ]
+ [ spirit-run lazy_tests.cpp ]
+ [ spirit-run switch_tests_eps_default.cpp : : : <pch>off ]
+ [ spirit-run switch_tests_general_def.cpp : : : <pch>off ]
+ [ spirit-run switch_tests_wo_default.cpp : : : <pch>off ]
+ [ spirit-run switch_tests_single.cpp : : : <pch>off ]
+ [ spirit-run switch_problem.cpp ]
+ [ spirit-run select_p_with_rule.cpp : : : <pch>off ]
+ ;
+
+ test-suite "spirit.classic.utility.parsers"
+ : [ spirit-run chset_tests.cpp ]
+ [ spirit-run confix_tests.cpp ]
+ [ spirit-run loops_tests.cpp ]
+ [ spirit-run symbols_tests.cpp ]
+ [ spirit-run symbols_add_null.cpp : : : <pch>off ]
+ [ spirit-run symbols_find_null.cpp ]
+ [ spirit-run escape_char_parser_tests.cpp : : : $(opt) ]
+ [ spirit-run distinct_tests.cpp ]
+ [ spirit-run grammar_def_test.cpp ]
+ ;
+
+ test-suite "spirit.classic.utility.support"
+ # This test doesn't actually use multiple threads
+ : [ spirit-run scoped_lock_tests.cpp : : : $(multi-threading) ]
+ [ compile threads_disabled_compile.cpp ]
+ ;
+
+ test-suite "spirit.classic.iterator"
+ : [ spirit-run fixed_size_queue_tests.cpp ]
+ [ compile-fail fixed_size_queue_fail_tests.cpp ]
+ [ run file_iterator_tests.cpp : : : <toolset>msvc:<define>_CRT_SECURE_NO_WARNINGS ]
+ [ spirit-run multi_pass_tests.cpp : : : $(opt-metrowerks) ]
+ [ spirit-run sf_bug_720917.cpp : : : <pch>off $(opt-metrowerks) ]
+ [ spirit-run position_iterator_tests.cpp : : : $(opt-metrowerks) ]
+ [ compile multi_pass_compile_tests.cpp ]
+ ;
+
+ test-suite "spirit.classic.small_bug_fixes"
+ : [ spirit-run bug_fixes.cpp ]
+ ;
+
+ actor_test_sources =
+ action_tests
+ assign_test
+ assign_key_test
+ clear_test
+ decrement_test
+ erase_at_test
+ increment_test
+ insert_key_test
+ insert_at_test
+ push_back_test
+ push_front_test
+ swap_test
+ ;
+
+ test-suite "spirit.classic.utility.actors"
+ : [ spirit-run actor/$(actor_test_sources).cpp ]
+ ;
+
+ test-suite "spirit.classic.typeof-support"
+ : [ compile typeof_support/typeof_actor.cpp ]
+ [ compile typeof_support/typeof_attribute.cpp ]
+ [ compile typeof_support/typeof_core.cpp ]
+ [ compile typeof_support/typeof_debug.cpp ]
+ [ compile typeof_support/typeof_dynamic.cpp ]
+ [ compile typeof_support/typeof_error_handling.cpp ]
+ [ compile typeof_support/typeof_iterator.cpp ]
+ [ compile typeof_support/typeof_symbols.cpp ]
+ [ compile typeof_support/typeof_tree.cpp ]
+ [ compile typeof_support/typeof_utility.cpp ]
+ ;
+
+
diff --git a/src/boost/libs/spirit/classic/test/actor/action_tests.cpp b/src/boost/libs/spirit/classic/test/actor/action_tests.cpp
new file mode 100644
index 00000000..792ba8c0
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/actor/action_tests.cpp
@@ -0,0 +1,26 @@
+/*=============================================================================
+ Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include "action_tests.hpp"
+
+int
+main()
+{
+ assign_action_test();
+ assign_key_action_test();
+ clear_action_test();
+ decrement_action_test();
+ erase_action_test();
+ increment_action_test();
+ insert_key_action_test();
+ push_front_action_test();
+ push_back_action_test();
+ swap_action_test();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/actor/action_tests.hpp b/src/boost/libs/spirit/classic/test/actor/action_tests.hpp
new file mode 100644
index 00000000..a17499e1
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/actor/action_tests.hpp
@@ -0,0 +1,33 @@
+/*=============================================================================
+ Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#ifndef BOOST_SPIRIT_ACTOR_TEST_HPP
+#define BOOST_SPIRIT_ACTOR_TEST_HPP
+#include <boost/detail/lightweight_test.hpp>
+#include "../impl/string_length.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+// Test suite for actors
+///////////////////////////////////////////////////////////////////////////////
+void assign_action_test();
+void assign_key_action_test();
+void clear_action_test();
+void decrement_action_test();
+void erase_action_test();
+void increment_action_test();
+void insert_key_action_test();
+void insert_at_action_test();
+void push_back_action_test();
+void push_front_action_test();
+void swap_action_test();
+
+#define BOOST_CHECK(t) BOOST_TEST((t));
+#define BOOST_CHECK_EQUAL(a, b) BOOST_TEST((a == b));
+#define BOOST_MESSAGE(m) std::cout << m << std::endl
+
+#endif
diff --git a/src/boost/libs/spirit/classic/test/actor/assign_key_test.cpp b/src/boost/libs/spirit/classic/test/actor/assign_key_test.cpp
new file mode 100644
index 00000000..f599b5e2
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/actor/assign_key_test.cpp
@@ -0,0 +1,116 @@
+/*=============================================================================
+ Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+///////////////////////////////////////////////////////////////////////////////
+// Test suite for assign_key_actor
+///////////////////////////////////////////////////////////////////////////////
+
+#include "action_tests.hpp"
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_confix.hpp>
+#include <boost/spirit/include/classic_lists.hpp>
+#include <map>
+#include <cstring>
+#include <iostream>
+#include <boost/spirit/include/classic_assign_key_actor.hpp>
+#include <boost/spirit/include/classic_assign_actor.hpp>
+
+void assign_key_single_argument_test()
+{
+ using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+ const char* cp = "(one,0),(two,1),(three,2)";
+ const char* cp_first = cp;
+ const char* cp_last = cp + test_impl::string_length(cp);
+ const char* cp_i[] = {"one","two","three"};
+ int i;
+ typedef std::map<int,std::string> map_string_type;
+ map_string_type c;
+ map_string_type::const_iterator it_find;
+ std::string str;
+
+ scanner<char const*> scan( cp_first, cp_last );
+ match<> hit;
+
+ hit = list_p(
+ confix_p(
+ '(',
+ (*alpha_p)[ assign(str)]
+ >>ch_p(',')
+ >> int_p[ assign_key_a(c,str)]
+ ,
+ ')'
+ )
+ ,
+ ch_p(',')
+ ).parse(scan);
+ BOOST_CHECK(hit);
+ BOOST_CHECK_EQUAL(scan.first, scan.last);
+ BOOST_CHECK_EQUAL( c.size(), static_cast<map_string_type::size_type>(3));
+ for (i=0;i<3;++i)
+ {
+ it_find = c.find(i);
+ BOOST_CHECK( it_find != c.end() );
+ BOOST_CHECK_EQUAL( i,it_find->first);
+ BOOST_CHECK_EQUAL( cp_i[i],it_find->second);
+ }
+
+}
+
+void assign_key_two_arguments_test()
+{
+ using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+ const char* cp = "(0,one),(1,two),(2,three)";
+ const char* cp_first = cp;
+ const char* cp_last = cp + test_impl::string_length(cp);
+ const char* cp_i[] = {"one","two","three"};
+ int i;
+ typedef std::map<std::string, int> map_string_type;
+ map_string_type c;
+ map_string_type::const_iterator it_find;
+ std::string str;
+
+ scanner<char const*> scan( cp_first, cp_last );
+ match<> hit;
+
+ hit = list_p(
+ confix_p(
+ '(',
+ int_p[ assign_a(i)]
+ >>ch_p(',')
+ >> (*alpha_p)[ assign_key_a(c,i)]
+ ,
+ ')'
+ )
+ ,
+ ch_p(',')
+ ).parse(scan);
+
+ BOOST_CHECK(hit);
+ BOOST_CHECK_EQUAL(scan.first, scan.last);
+ BOOST_CHECK_EQUAL( c.size(), static_cast<map_string_type::size_type>(3));
+
+ for (i=0;i<3;++i)
+ {
+ it_find = c.find(cp_i[i]);
+ BOOST_CHECK( it_find != c.end() );
+ BOOST_CHECK_EQUAL( i,it_find->second);
+ BOOST_CHECK_EQUAL( cp_i[i],it_find->first);
+ }
+ scan.first = cp;
+
+}
+
+void assign_key_action_test()
+{
+ assign_key_single_argument_test();
+ assign_key_two_arguments_test();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/actor/assign_test.cpp b/src/boost/libs/spirit/classic/test/actor/assign_test.cpp
new file mode 100644
index 00000000..e59fcc2c
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/actor/assign_test.cpp
@@ -0,0 +1,65 @@
+/*=============================================================================
+ Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+///////////////////////////////////////////////////////////////////////////////
+// Test suite for assign_actor
+///////////////////////////////////////////////////////////////////////////////
+
+#include "action_tests.hpp"
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_assign_actor.hpp>
+
+void assign_test()
+{
+ using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+ const char* cp = "63";
+ const char* cp_first = cp;
+ const char* cp_last = cp + test_impl::string_length(cp);
+ int h=127;
+ int hm=h;
+
+ scanner<char const*> scan( cp_first, cp_last );
+ match<> hit;
+
+ hit = int_p[ assign_a(hm)].parse(scan);
+ BOOST_CHECK(hit);
+ BOOST_CHECK_EQUAL(scan.first, scan.last);
+
+ h=63;
+ BOOST_CHECK_EQUAL( hm,h);
+}
+
+void assign_test_ref()
+{
+ using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+
+ const char* cp = "63";
+ const char* cp_first = cp;
+ const char* cp_last = cp + test_impl::string_length(cp);
+ int h=127;
+ int hm=63;
+
+ scanner<char const*> scan( cp_first, cp_last );
+ match<> hit;
+
+ hit = int_p[ assign_a(h,hm)].parse(scan);
+ BOOST_CHECK(hit);
+ BOOST_CHECK_EQUAL(scan.first, scan.last);
+
+ BOOST_CHECK_EQUAL( hm,h);
+}
+
+void assign_action_test()
+{
+ assign_test();
+ assign_test_ref();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/actor/clear_test.cpp b/src/boost/libs/spirit/classic/test/actor/clear_test.cpp
new file mode 100644
index 00000000..b39d9114
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/actor/clear_test.cpp
@@ -0,0 +1,47 @@
+/*=============================================================================
+ Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+///////////////////////////////////////////////////////////////////////////////
+// Test suite for clear_actor
+///////////////////////////////////////////////////////////////////////////////
+
+#include "action_tests.hpp"
+#include <boost/spirit/include/classic_core.hpp>
+#include <vector>
+#include <boost/spirit/include/classic_clear_actor.hpp>
+
+void clear_action_test()
+{
+ using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+ BOOST_MESSAGE("clear_test");
+
+ const char* cp = "63";
+ const char* cp_first = cp;
+ const char* cp_last = cp + test_impl::string_length(cp);
+ std::vector<int> c;
+ c.push_back(1);
+
+ scanner<char const*> scan( cp_first, cp_last );
+ match<> hit;
+
+ hit = int_p[ clear_a(c)].parse(scan);
+ BOOST_CHECK(hit);
+ BOOST_CHECK_EQUAL(scan.first, scan.last);
+ BOOST_CHECK( c.empty() );
+ scan.first = cp;
+ c.push_back(1);
+
+ hit = str_p("63")[ clear_a(c)].parse(scan);
+ BOOST_CHECK(hit);
+ BOOST_CHECK_EQUAL(scan.first, scan.last);
+ BOOST_CHECK( c.empty() );
+}
+
+
diff --git a/src/boost/libs/spirit/classic/test/actor/decrement_test.cpp b/src/boost/libs/spirit/classic/test/actor/decrement_test.cpp
new file mode 100644
index 00000000..728c838c
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/actor/decrement_test.cpp
@@ -0,0 +1,40 @@
+/*=============================================================================
+ Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+///////////////////////////////////////////////////////////////////////////////
+// Test suite for increment_actor
+///////////////////////////////////////////////////////////////////////////////
+
+#include "action_tests.hpp"
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_decrement_actor.hpp>
+
+void decrement_action_test()
+{
+ using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+ BOOST_MESSAGE("decrement_test");
+
+ const char* cp = "63";
+ const char* cp_first = cp;
+ const char* cp_last = cp + test_impl::string_length(cp);
+ int h=127;
+ int hm=h;
+
+ scanner<char const*> scan( cp_first, cp_last );
+ match<> hit;
+
+ hit = int_p[ decrement_a(hm)].parse(scan);
+ BOOST_CHECK(hit);
+ BOOST_CHECK_EQUAL(scan.first, scan.last);
+
+ --h;
+ BOOST_CHECK_EQUAL( hm,h);
+}
+
diff --git a/src/boost/libs/spirit/classic/test/actor/erase_at_test.cpp b/src/boost/libs/spirit/classic/test/actor/erase_at_test.cpp
new file mode 100644
index 00000000..9254b177
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/actor/erase_at_test.cpp
@@ -0,0 +1,54 @@
+/*=============================================================================
+ Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+///////////////////////////////////////////////////////////////////////////////
+// Test suite for push_front_actor, pop_front_actor
+///////////////////////////////////////////////////////////////////////////////
+
+#include "action_tests.hpp"
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_erase_actor.hpp>
+#include <map>
+
+void erase_action_test()
+{
+ using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+ const char* cp = "one,two,three";
+ const char* cp_first = cp;
+ const char* cp_last = cp + test_impl::string_length(cp);
+ const char* cp_i[] = {"one","two","three"};
+ typedef std::map<std::string, int> map_string_type;
+ map_string_type c;
+ map_string_type::const_iterator it_find;
+
+ scanner<char const*> scan(cp_first, cp_last);
+ match<> hit;
+
+ c["one"]=1;
+ c["two"]=2;
+ c["three"]=3;
+ c["four"]=4;
+
+ hit = (*((+alpha_p)[ erase_a(c) ] >> !ch_p(','))).parse(scan);
+
+ BOOST_CHECK(hit);
+ BOOST_CHECK_EQUAL(scan.first, scan.last);
+ BOOST_CHECK_EQUAL( c.size(), static_cast<map_string_type::size_type>(1));
+ for (int i=0;i<3;++i)
+ {
+ it_find = c.find(cp_i[i]);
+ BOOST_CHECK( it_find == c.end() );
+ }
+ scan.first = cp;
+
+}
+
+
+
diff --git a/src/boost/libs/spirit/classic/test/actor/increment_test.cpp b/src/boost/libs/spirit/classic/test/actor/increment_test.cpp
new file mode 100644
index 00000000..57f59970
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/actor/increment_test.cpp
@@ -0,0 +1,42 @@
+/*=============================================================================
+ Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+///////////////////////////////////////////////////////////////////////////////
+// Test suite for increment_actor
+///////////////////////////////////////////////////////////////////////////////
+
+#include "action_tests.hpp"
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_increment_actor.hpp>
+
+void increment_action_test()
+{
+ using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+ BOOST_MESSAGE("increment_test");
+
+ const char* cp = "63";
+ const char* cp_first = cp;
+ const char* cp_last = cp + test_impl::string_length(cp);
+ int h=127;
+ int hm=h;
+
+ scanner<char const*> scan( cp_first, cp_last );
+ match<> hit;
+
+ hit = int_p[ increment_a(hm)].parse(scan);
+ BOOST_CHECK(hit);
+ BOOST_CHECK_EQUAL(scan.first, scan.last);
+
+ ++h;
+ BOOST_CHECK_EQUAL( hm,h);
+}
+
+
+
diff --git a/src/boost/libs/spirit/classic/test/actor/insert_at_test.cpp b/src/boost/libs/spirit/classic/test/actor/insert_at_test.cpp
new file mode 100644
index 00000000..5ef6a102
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/actor/insert_at_test.cpp
@@ -0,0 +1,109 @@
+/*=============================================================================
+ Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+// Test suite for insert_at_actor
+///////////////////////////////////////////////////////////////////////////////
+
+#include "action_tests.hpp"
+#include <map>
+#include <cstring>
+#include <iostream>
+#include <boost/spirit/include/classic_spirit.hpp>
+#include <boost/spirit/include/classic_insert_at_actor.hpp>
+
+void insert_at_single_argument_test()
+{
+ using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+ const char* cp = "(one,0),(two,1),(three,2)";
+ const char* cp_first = cp;
+ const char* cp_last = cp + std::strlen(cp);
+ const char* cp_i[] = {"one","two","three"};
+ int i;
+ typedef std::map<std::string,int> map_string_type;
+ map_string_type c;
+ map_string_type::const_iterator it_find;
+ std::string str;
+
+ scanner<char const*> scan( cp_first, cp_last );
+ match<> hit;
+
+ hit = list_p(
+ confix_p(
+ '(',
+ (*alpha_p)[ assign(str)]
+ >>ch_p(',')
+ >> int_p[ insert_at_a(c,str)]
+ ,
+ ')'
+ )
+ ,
+ ch_p(',')
+ ).parse(scan);
+
+ BOOST_CHECK(hit);
+ BOOST_CHECK_EQUAL(scan.first, scan.last);
+ BOOST_CHECK_EQUAL( c.size(), static_cast<map_string_type::size_type>(3));
+ for (i=0;i<3;++i)
+ {
+ it_find = c.find(cp_i[i]);
+ BOOST_CHECK( it_find != c.end() );
+ BOOST_CHECK_EQUAL( i,it_find->second);
+ BOOST_CHECK_EQUAL( cp_i[i],it_find->first);
+ }
+}
+
+void insert_at_two_arguments_test()
+{
+ using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+ const char* cp = "(0,one),(1,two),(2,three)";
+ const char* cp_first = cp;
+ const char* cp_last = cp + std::strlen(cp);
+ const char* cp_i[] = {"one","two","three"};
+ int i;
+ typedef std::map<int,std::string> map_string_type;
+ map_string_type c;
+ map_string_type::const_iterator it_find;
+ std::string str;
+
+ scanner<char const*> scan( cp_first, cp_last );
+ match<> hit;
+
+ hit = list_p(
+ confix_p(
+ '(',
+ int_p[ assign(i)]
+ >>ch_p(',')
+ >> (*alpha_p)[ insert_at_a(c,i)]
+ ,
+ ')'
+ )
+ ,
+ ch_p(',')
+ ).parse(scan);
+
+ BOOST_CHECK(hit);
+ BOOST_CHECK_EQUAL(scan.first, scan.last);
+ BOOST_CHECK_EQUAL( c.size(), static_cast<map_string_type::size_type>(3));
+ for (i=0;i<3;++i)
+ {
+ it_find = c.find(i);
+ BOOST_CHECK( it_find != c.end() );
+ BOOST_CHECK_EQUAL( i,it_find->first);
+ BOOST_CHECK_EQUAL( cp_i[i],it_find->second);
+ }
+}
+
+void insert_at_action_test()
+{
+ insert_at_single_argument_test();
+ insert_at_two_arguments_test();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/actor/insert_key_test.cpp b/src/boost/libs/spirit/classic/test/actor/insert_key_test.cpp
new file mode 100644
index 00000000..4f6eb0b5
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/actor/insert_key_test.cpp
@@ -0,0 +1,116 @@
+/*=============================================================================
+ Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+///////////////////////////////////////////////////////////////////////////////
+// Test suite for insert_key_actor
+///////////////////////////////////////////////////////////////////////////////
+
+#include "action_tests.hpp"
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_confix.hpp>
+#include <boost/spirit/include/classic_lists.hpp>
+#include <map>
+#include <cstring>
+#include <iostream>
+#include <boost/spirit/include/classic_insert_key_actor.hpp>
+#include <boost/spirit/include/classic_assign_actor.hpp>
+
+void insert_key_single_argument_test()
+{
+ using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+ const char* cp = "(one,0),(two,1),(three,2)";
+ const char* cp_first = cp;
+ const char* cp_last = cp + test_impl::string_length(cp);
+ const char* cp_i[] = {"one","two","three"};
+ int i;
+ typedef std::map<int,std::string> map_string_type;
+ map_string_type c;
+ map_string_type::const_iterator it_find;
+ std::string str;
+
+ scanner<char const*> scan( cp_first, cp_last );
+ match<> hit;
+
+ hit = list_p(
+ confix_p(
+ '(',
+ (*alpha_p)[ assign_a(str)]
+ >>ch_p(',')
+ >> int_p[ insert_key_a(c,str)]
+ ,
+ ')'
+ )
+ ,
+ ch_p(',')
+ ).parse(scan);
+ BOOST_CHECK(hit);
+ BOOST_CHECK_EQUAL(scan.first, scan.last);
+ BOOST_CHECK_EQUAL( c.size(), static_cast<map_string_type::size_type>(3));
+ for (i=0;i<3;++i)
+ {
+ it_find = c.find(i);
+ BOOST_CHECK( it_find != c.end() );
+ BOOST_CHECK_EQUAL( i,it_find->first);
+ BOOST_CHECK_EQUAL( cp_i[i],it_find->second);
+ }
+
+}
+
+void insert_key_two_arguments_test()
+{
+ using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+ const char* cp = "(0,one),(1,two),(2,three)";
+ const char* cp_first = cp;
+ const char* cp_last = cp + test_impl::string_length(cp);
+ const char* cp_i[] = {"one","two","three"};
+ int i;
+ typedef std::map<std::string, int> map_string_type;
+ map_string_type c;
+ map_string_type::const_iterator it_find;
+ std::string str;
+
+ scanner<char const*> scan( cp_first, cp_last );
+ match<> hit;
+
+ hit = list_p(
+ confix_p(
+ '(',
+ int_p[ assign_a(i)]
+ >>ch_p(',')
+ >> (*alpha_p)[ insert_key_a(c,i)]
+ ,
+ ')'
+ )
+ ,
+ ch_p(',')
+ ).parse(scan);
+
+ BOOST_CHECK(hit);
+ BOOST_CHECK_EQUAL(scan.first, scan.last);
+ BOOST_CHECK_EQUAL( c.size(), static_cast<map_string_type::size_type>(3));
+
+ for (i=0;i<3;++i)
+ {
+ it_find = c.find(cp_i[i]);
+ BOOST_CHECK( it_find != c.end() );
+ BOOST_CHECK_EQUAL( i,it_find->second);
+ BOOST_CHECK_EQUAL( cp_i[i],it_find->first);
+ }
+ scan.first = cp;
+
+}
+
+void insert_key_action_test()
+{
+ insert_key_single_argument_test();
+ insert_key_two_arguments_test();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/actor/push_back_test.cpp b/src/boost/libs/spirit/classic/test/actor/push_back_test.cpp
new file mode 100644
index 00000000..ee83c19a
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/actor/push_back_test.cpp
@@ -0,0 +1,56 @@
+/*=============================================================================
+ Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+///////////////////////////////////////////////////////////////////////////////
+// Test suite for push_back_actor
+///////////////////////////////////////////////////////////////////////////////
+
+#include "action_tests.hpp"
+#include <string>
+#include <vector>
+#include <deque>
+#include <cstring>
+#include <iostream>
+#include <boost/spirit/include/classic_core.hpp>
+#include <algorithm>
+#include <boost/bind.hpp>
+#include <boost/spirit/include/classic_push_back_actor.hpp>
+#include <boost/spirit/include/classic_lists.hpp>
+
+template<typename ContainerT>
+void push_back_test()
+{
+ using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+ const char* cp = "one,two,three";
+ const char* cp_first = cp;
+ const char* cp_last = cp + test_impl::string_length(cp);
+ const char* cp_i[] = {"one","two","three"};
+ int i;
+ ContainerT c;
+ typename ContainerT::const_iterator it;
+
+ scanner<char const*> scan( cp_first, cp_last );
+ match<> hit;
+
+ hit = list_p( (*alpha_p)[ push_back_a(c)] , ch_p(',') ).parse(scan);
+ BOOST_CHECK(hit);
+ BOOST_CHECK_EQUAL(scan.first, scan.last);
+ BOOST_CHECK_EQUAL( c.size(), static_cast<typename ContainerT::size_type>(3));
+ for (i=0, it = c.begin();i<3 && it != c.end();++i, ++it)
+ BOOST_CHECK_EQUAL( cp_i[i], *it);
+ scan.first = cp;
+}
+
+void push_back_action_test()
+{
+ push_back_test< std::deque<std::string> >();
+ push_back_test< std::vector<std::string> >();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/actor/push_front_test.cpp b/src/boost/libs/spirit/classic/test/actor/push_front_test.cpp
new file mode 100644
index 00000000..ac42708e
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/actor/push_front_test.cpp
@@ -0,0 +1,53 @@
+/*=============================================================================
+ Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+///////////////////////////////////////////////////////////////////////////////
+// Test suite for push_front_actor
+///////////////////////////////////////////////////////////////////////////////
+
+#include "action_tests.hpp"
+#include <string>
+#include <vector>
+#include <deque>
+#include <cstring>
+#include <iostream>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_push_front_actor.hpp>
+#include <boost/spirit/include/classic_lists.hpp>
+
+template<typename ContainerT>
+void push_front_test()
+{
+ using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+ const char* cp = "one,two,three";
+ const char* cp_first = cp;
+ const char* cp_last = cp + test_impl::string_length(cp);
+ const char* cp_i[] = {"one","two","three"};;
+ int i;
+ ContainerT c;
+ typename ContainerT::const_iterator it;
+
+ scanner<char const*> scan( cp_first, cp_last );
+ match<> hit;
+
+ hit = list_p( (*alpha_p)[ push_front_a(c)] , ch_p(',') ).parse(scan);
+ BOOST_CHECK(hit);
+ BOOST_CHECK_EQUAL(scan.first, scan.last);
+ BOOST_CHECK_EQUAL( c.size(), static_cast<typename ContainerT::size_type>(3));
+ for (i=2, it = c.begin();i>=0 && it != c.end();--i, ++it)
+ BOOST_CHECK_EQUAL( cp_i[i], *it);
+ scan.first = cp;
+}
+
+void push_front_action_test()
+{
+ push_front_test< std::deque<std::string> >();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/actor/swap_test.cpp b/src/boost/libs/spirit/classic/test/actor/swap_test.cpp
new file mode 100644
index 00000000..0ba203de
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/actor/swap_test.cpp
@@ -0,0 +1,47 @@
+/*=============================================================================
+ Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+///////////////////////////////////////////////////////////////////////////////
+// Test suite for and_assign_actor
+///////////////////////////////////////////////////////////////////////////////
+
+#include "action_tests.hpp"
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_swap_actor.hpp>
+
+void swap_action_test()
+{
+ using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+ const char* cp = "63";
+ const char* cp_first = cp;
+ const char* cp_last = cp + test_impl::string_length(cp);
+ std::vector<int> v1,v2;
+
+ v1.push_back(0);
+ v1.push_back(1);
+
+ v2.push_back(2);
+ v2.push_back(3);
+
+ scanner<char const*> scan( cp_first, cp_last );
+ match<> hit;
+
+ hit = int_p[ swap_a(v1,v2)].parse(scan);
+ BOOST_CHECK(hit);
+ BOOST_CHECK_EQUAL(scan.first, scan.last);
+ BOOST_CHECK(v1.size()==2);
+ BOOST_CHECK(v2.size()==2);
+ BOOST_CHECK_EQUAL(v2[0],0);
+ BOOST_CHECK_EQUAL(v2[1],1);
+ BOOST_CHECK_EQUAL(v1[0],2);
+ BOOST_CHECK_EQUAL(v1[1],3);
+}
+
+
diff --git a/src/boost/libs/spirit/classic/test/actor/unit_test.cpp b/src/boost/libs/spirit/classic/test/actor/unit_test.cpp
new file mode 100644
index 00000000..f908155c
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/actor/unit_test.cpp
@@ -0,0 +1,10 @@
+/*=============================================================================
+ Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+
diff --git a/src/boost/libs/spirit/classic/test/ast_calc_tests.cpp b/src/boost/libs/spirit/classic/test/ast_calc_tests.cpp
new file mode 100644
index 00000000..a8b8be72
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/ast_calc_tests.cpp
@@ -0,0 +1,279 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Daniel Nuffer
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+// JDG 4-16-03 Modified from ast_calc.cpp as a test
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_ast.hpp>
+#include <boost/spirit/include/classic_tree_to_xml.hpp>
+#include <boost/detail/workaround.hpp>
+
+#include <iostream>
+#include <stack>
+#include <functional>
+#include <string>
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Our calculator grammar
+//
+////////////////////////////////////////////////////////////////////////////
+struct calculator : public grammar<calculator>
+{
+ static const int integerID = 1;
+ static const int factorID = 2;
+ static const int termID = 3;
+ static const int expressionID = 4;
+
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(calculator const& /*self*/)
+ {
+ // Start grammar definition
+ integer = leaf_node_d[real_p]; // we're not really using a real
+ // but just for compile checking
+ // the AST tree match code...
+ factor = integer
+ | inner_node_d[ch_p('(') >> expression >> ch_p(')')]
+ | (root_node_d[ch_p('-')] >> factor);
+
+ term = factor >>
+ *( (root_node_d[ch_p('*')] >> factor)
+ | (root_node_d[ch_p('/')] >> factor)
+ );
+
+ expression = term >>
+ *( (root_node_d[ch_p('+')] >> term)
+ | (root_node_d[ch_p('-')] >> term)
+ );
+ // End grammar definition
+ }
+
+ rule<ScannerT, parser_context<>, parser_tag<expressionID> > expression;
+ rule<ScannerT, parser_context<>, parser_tag<termID> > term;
+ rule<ScannerT, parser_context<>, parser_tag<factorID> > factor;
+ rule<ScannerT, parser_context<>, parser_tag<integerID> > integer;
+
+ rule<ScannerT, parser_context<>, parser_tag<expressionID> > const&
+ start() const { return expression; }
+ };
+};
+
+////////////////////////////////////////////////////////////////////////////
+//
+// Our calculator grammar, but with dynamically assigned rule ID's
+//
+////////////////////////////////////////////////////////////////////////////
+struct dyn_calculator : public grammar<dyn_calculator>
+{
+ static const int integerID = 1;
+ static const int factorID = 2;
+ static const int termID = 3;
+ static const int expressionID = 4;
+
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(dyn_calculator const& /*self*/)
+ {
+ expression.set_id(expressionID);
+ term.set_id(termID);
+ factor.set_id(factorID);
+ integer.set_id(integerID);
+
+ // Start grammar definition
+ integer = leaf_node_d[real_p]; // we're not really using a real
+ // but just for compile checking
+ // the AST tree match code...
+ factor = integer
+ | inner_node_d[ch_p('(') >> expression >> ch_p(')')]
+ | (root_node_d[ch_p('-')] >> factor);
+
+ term = factor >>
+ *( (root_node_d[ch_p('*')] >> factor)
+ | (root_node_d[ch_p('/')] >> factor)
+ );
+
+ expression = term >>
+ *( (root_node_d[ch_p('+')] >> term)
+ | (root_node_d[ch_p('-')] >> term)
+ );
+ // End grammar definition
+ }
+
+ rule<ScannerT, parser_context<>, dynamic_parser_tag> expression;
+ rule<ScannerT, parser_context<>, dynamic_parser_tag> term;
+ rule<ScannerT, parser_context<>, dynamic_parser_tag> factor;
+ rule<ScannerT, parser_context<>, dynamic_parser_tag> integer;
+
+ rule<ScannerT, parser_context<>, dynamic_parser_tag> const&
+ start() const { return expression; }
+ };
+};
+
+////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+typedef char const* parser_iterator_t;
+typedef tree_match<parser_iterator_t> parse_tree_match_t;
+typedef parse_tree_match_t::tree_iterator iter_t;
+
+////////////////////////////////////////////////////////////////////////////
+long evaluate(parse_tree_match_t hit);
+long eval_expression(iter_t const& i);
+
+long evaluate(tree_parse_info<> info)
+{
+ return eval_expression(info.trees.begin());
+}
+
+long eval_expression(iter_t const& i)
+{
+ switch (i->value.id().to_long())
+ {
+ case calculator::integerID:
+ {
+ BOOST_TEST(i->children.size() == 0);
+ // extract integer (not always delimited by '\0')
+#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
+ // std::string(iter,iter) constructor has a bug in MWCW 8.3:
+ // in some situations, the null terminator won't be added
+ // and c_str() will return bogus data. Conservatively, I
+ // activate this workaround up to version 8.3.
+ std::vector<char> value(i->value.begin(), i->value.end());
+ value.push_back('\0');
+ return strtol(&value[0], 0, 10);
+#else
+ string integer(i->value.begin(), i->value.end());
+ return strtol(integer.c_str(), 0, 10);
+#endif
+ }
+
+ case calculator::factorID:
+ {
+ // factor can only be unary minus
+ BOOST_TEST(*i->value.begin() == '-');
+ return - eval_expression(i->children.begin());
+ }
+
+ case calculator::termID:
+ {
+ if (*i->value.begin() == '*')
+ {
+ BOOST_TEST(i->children.size() == 2);
+ return eval_expression(i->children.begin()) *
+ eval_expression(i->children.begin()+1);
+ }
+ else if (*i->value.begin() == '/')
+ {
+ BOOST_TEST(i->children.size() == 2);
+ return eval_expression(i->children.begin()) /
+ eval_expression(i->children.begin()+1);
+ }
+ else
+ std::abort();
+ }
+
+ case calculator::expressionID:
+ {
+ if (*i->value.begin() == '+')
+ {
+ BOOST_TEST(i->children.size() == 2);
+ return eval_expression(i->children.begin()) +
+ eval_expression(i->children.begin()+1);
+ }
+ else if (*i->value.begin() == '-')
+ {
+ BOOST_TEST(i->children.size() == 2);
+ return eval_expression(i->children.begin()) -
+ eval_expression(i->children.begin()+1);
+ }
+ else
+ std::abort();
+ }
+
+ default:
+ std::abort(); // error
+ }
+
+#if defined(_MSC_VER) && (_MSC_VER < 1700)
+ return 0;
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////////
+int
+parse(char const* str)
+{
+ calculator calc;
+ tree_parse_info<> info = ast_parse(str, calc, space_p);
+
+ if (info.full)
+ return evaluate(info);
+ else
+ return -1;
+}
+
+int
+parse_dyn(char const* str)
+{
+ dyn_calculator calc;
+ tree_parse_info<> info = ast_parse(str, calc, space_p);
+
+ if (info.full)
+ return evaluate(info);
+ else
+ return -1;
+}
+
+int
+main()
+{
+// test the calculator with statically assigned rule ID's
+ BOOST_TEST(parse("12345") == 12345);
+ BOOST_TEST(parse("-12345") == -12345);
+ BOOST_TEST(parse("1 + 2") == 1 + 2);
+ BOOST_TEST(parse("1 * 2") == 1 * 2);
+ BOOST_TEST(parse("1/2 + 3/4") == 1/2 + 3/4);
+ BOOST_TEST(parse("1 + 2 + 3 + 4") == 1 + 2 + 3 + 4);
+ BOOST_TEST(parse("1 * 2 * 3 * 4") == 1 * 2 * 3 * 4);
+ BOOST_TEST(parse("(1 + 2) * (3 + 4)") == (1 + 2) * (3 + 4));
+ BOOST_TEST(parse("(-1 + 2) * (3 + -4)") == (-1 + 2) * (3 + -4));
+ BOOST_TEST(parse("1 + ((6 * 200) - 20) / 6") == 1 + ((6 * 200) - 20) / 6);
+ BOOST_TEST(parse("(1 + (2 + (3 + (4 + 5))))") == (1 + (2 + (3 + (4 + 5)))));
+ BOOST_TEST(parse("1 + 2 + 3 + 4 + 5") == 1 + 2 + 3 + 4 + 5);
+ BOOST_TEST(parse("(12 * 22) + (36 + -4 + 5)") == (12 * 22) + (36 + -4 + 5));
+ BOOST_TEST(parse("(12 * 22) / (5 - 10 + 15)") == (12 * 22) / (5 - 10 + 15));
+ BOOST_TEST(parse("12 * 6 * 15 + 5 - 25") == 12 * 6 * 15 + 5 - 25);
+
+// test the calculator with dynamically assigned rule ID's
+ BOOST_TEST(parse_dyn("12345") == 12345);
+ BOOST_TEST(parse_dyn("-12345") == -12345);
+ BOOST_TEST(parse_dyn("1 + 2") == 1 + 2);
+ BOOST_TEST(parse_dyn("1 * 2") == 1 * 2);
+ BOOST_TEST(parse_dyn("1/2 + 3/4") == 1/2 + 3/4);
+ BOOST_TEST(parse_dyn("1 + 2 + 3 + 4") == 1 + 2 + 3 + 4);
+ BOOST_TEST(parse_dyn("1 * 2 * 3 * 4") == 1 * 2 * 3 * 4);
+ BOOST_TEST(parse_dyn("(1 + 2) * (3 + 4)") == (1 + 2) * (3 + 4));
+ BOOST_TEST(parse_dyn("(-1 + 2) * (3 + -4)") == (-1 + 2) * (3 + -4));
+ BOOST_TEST(parse_dyn("1 + ((6 * 200) - 20) / 6") == 1 + ((6 * 200) - 20) / 6);
+ BOOST_TEST(parse_dyn("(1 + (2 + (3 + (4 + 5))))") == (1 + (2 + (3 + (4 + 5)))));
+ BOOST_TEST(parse_dyn("1 + 2 + 3 + 4 + 5") == 1 + 2 + 3 + 4 + 5);
+ BOOST_TEST(parse_dyn("(12 * 22) + (36 + -4 + 5)") == (12 * 22) + (36 + -4 + 5));
+ BOOST_TEST(parse_dyn("(12 * 22) / (5 - 10 + 15)") == (12 * 22) / (5 - 10 + 15));
+ BOOST_TEST(parse_dyn("12 * 6 * 15 + 5 - 25") == 12 * 6 * 15 + 5 - 25);
+
+ return boost::report_errors();
+}
+
+
diff --git a/src/boost/libs/spirit/classic/test/bug_000008.cpp b/src/boost/libs/spirit/classic/test/bug_000008.cpp
new file mode 100644
index 00000000..0d52cb34
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/bug_000008.cpp
@@ -0,0 +1,115 @@
+/*=============================================================================
+ Copyright (c) 2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+ // see http://article.gmane.org/gmane.comp.parsers.spirit.general/4575
+ // or https://sf.net/mailarchive/forum.php?thread_id=2692308&forum_id=1595
+ // for a description of the bug being tested for by this program
+ //
+ // the problem should be solved with version 1.3 of phoenix/closures.hpp>
+
+#if defined(BOOST_SPIRIT_DEBUG) && defined(__GNUC__) && defined(__WIN32__)
+// It seems that MinGW has some problems with threads and iostream ?
+// This code crashes MinGW when BOOST_SPIRIT_DEBUG is defined. The reason
+// is beyond me. Disable BOOST_SPIRIT_DEBUG for now.
+#undef BOOST_SPIRIT_DEBUG
+#endif
+
+#include <iostream>
+#include <boost/config.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined(DONT_HAVE_BOOST) || !defined(BOOST_HAS_THREADS) || defined(BOOST_DISABLE_THREADS)
+// we end here if we can't do multithreading
+static void skipped()
+{
+ std::cout << "skipped\n";
+}
+
+int
+main()
+{
+ skipped();
+ return boost::report_errors();
+}
+
+#else
+// the real MT stuff
+
+#undef BOOST_SPIRIT_THREADSAFE
+#define BOOST_SPIRIT_THREADSAFE
+#undef PHOENIX_THREADSAFE
+#define PHOENIX_THREADSAFE
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_closure.hpp>
+#include <boost/thread.hpp>
+
+static const int number_of_calls_to_parse_per_thread=20000;
+
+struct test_closure
+ : BOOST_SPIRIT_CLASSIC_NS::closure<test_closure, char const*>
+{
+ member1 b;
+};
+
+struct test_grammar
+ : BOOST_SPIRIT_CLASSIC_NS::grammar<test_grammar, test_closure::context_t>
+{
+ test_grammar() {}
+
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(test_grammar const &self)
+ {
+ using namespace phoenix;
+ rule = BOOST_SPIRIT_CLASSIC_NS::epsilon_p[self.b = arg1];
+ }
+
+ BOOST_SPIRIT_CLASSIC_NS::rule<ScannerT> const &start() const { return rule; }
+
+ BOOST_SPIRIT_CLASSIC_NS::rule<ScannerT> rule;
+ };
+};
+
+test_grammar const g;
+
+void
+in_thread(void)
+{
+ char const text[]="foo";
+ for(int i=0; i<number_of_calls_to_parse_per_thread; ++i)
+ {
+ BOOST_SPIRIT_CLASSIC_NS::parse(&text[0], text+sizeof(text), g);
+ }
+}
+
+void
+bug_000008()
+{
+ boost::thread t1(in_thread);
+ boost::thread t2(in_thread);
+ boost::thread t3(in_thread);
+ boost::thread t4(in_thread);
+
+ t1.join();
+ t2.join();
+ t3.join();
+ t4.join();
+}
+
+int
+main()
+{
+ bug_000008();
+ return boost::report_errors();
+}
+
+#endif
+
diff --git a/src/boost/libs/spirit/classic/test/bug_fixes.cpp b/src/boost/libs/spirit/classic/test/bug_fixes.cpp
new file mode 100644
index 00000000..69490b8b
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/bug_fixes.cpp
@@ -0,0 +1,365 @@
+/*=============================================================================
+ Copyright (c) 2003 Giovanni Bajo
+ Copyright (c) 2003 Joel de Guzman
+ Copyright (c) 2003 Vaclav Vesely
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_assign_actor.hpp>
+
+using namespace boost;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// bug_001
+//
+// access_node_d[] and access_match_d[] iterator bug
+// http://sf.net/mailarchive/forum.php?thread_id=1963157&forum_id=1595
+// http://sf.net/mailarchive/forum.php?thread_id=1966224&forum_id=1595
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_ast.hpp>
+
+struct my_action
+{
+ template <typename TreeT, typename IterT>
+ void operator()(TreeT& /*t*/, IterT begin, IterT end) const
+ {
+ BOOST_TEST(*begin == '1');
+ BOOST_TEST(*end == '2');
+ }
+};
+
+void bug_001()
+{
+ const char* text = "123";
+
+ ast_parse(text, text+3, access_node_d[chlit<>('1')][my_action()]);
+ ast_parse(text, text+3, access_match_d[chlit<>('1')][my_action()]);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// bug_001
+//
+// mismatch closure return type bug
+// http://article.gmane.org/gmane.comp.parsers.spirit.general/3678
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_attribute.hpp>
+#include <string>
+
+typedef std::string member_type;
+
+struct my_closure: closure<my_closure, member_type>
+{
+ member1 val;
+};
+
+void bug_002()
+{
+ rule<scanner<char const*>, my_closure::context_t> my_rule = real_p;
+ BOOST_TEST(parse("1", my_rule).full);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// bug_003
+//
+// impl::detach_clear bug
+// http://sourceforge.net/mailarchive/forum.php?thread_id=2008510&forum_id=25901
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_chset.hpp>
+
+void bug_003()
+{
+ chset<> set;
+ set = 'a';
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// bug_004
+//
+// chset<>::operator~(range<>) bug
+// operator&(chset<>, range<>) bug
+// operator&(range<>, chset<>) bug
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/limits.hpp>
+#include <boost/spirit/include/classic_chset.hpp>
+
+void bug_004()
+{
+ const char min = (std::numeric_limits<char>::min)();
+ const char max = (std::numeric_limits<char>::max)();
+
+ {
+ chset<> set(~range<>(min, max));
+ BOOST_TEST(set.test(min) == false);
+ BOOST_TEST(set.test(min) == false);
+ }
+
+ {
+ chset<> set(chset<>(anychar_p) & range<>(min, max));
+ BOOST_TEST(set.test(min) == true);
+ BOOST_TEST(set.test(min) == true);
+ }
+
+ {
+ chset<> set(range<>(min, max) & chset<>(anychar_p));
+ BOOST_TEST(set.test(min) == true);
+ BOOST_TEST(set.test(min) == true);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// bug_005
+//
+// Most trailing space bug
+// http://article.gmane.org/gmane.comp.parsers.spirit.general/4029
+// JDG: Oct 18, 2005. We shall revert to the previous behavior where
+// Post skips are not allowed. The reason is that
+// there is a valid use case where input is obtained
+// from cin and multi_pass which results in an infinite
+// loop while the post skipper waits for a whitespace.
+// For examples like below, the grammar must explicitly
+// include the post whitespace. One possible way is to
+// place an end_p at the end of the grammar. The end_p
+// will trigger the post-skip.
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_core.hpp>
+
+using namespace boost;
+using namespace spirit;
+
+void bug_005()
+{
+ BOOST_TEST(
+ parse(" aaaaaaaaa ", *ch_p('a') >> end_p, space_p).full
+ );
+
+ BOOST_TEST(
+ parse(" aaaaaaaaa ", lexeme_d[*ch_p('a')] >> end_p, space_p).full
+ );
+
+#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
+ // not sure why Code Warrior 9.5 does not recognize ch_p(' ') as the
+ // same as space_p (see above) when the inputs are spaces. The
+ // tests below are redundant anyway.
+#else
+
+ BOOST_TEST(
+ parse(" aaaaaaaaa ", *ch_p('a') >> end_p, ch_p(' ')).full
+ );
+
+ BOOST_TEST(
+ parse(" aaaaaaaaa ", lexeme_d[*ch_p('a')] >> end_p, ch_p(' ')).full
+ );
+
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// bug_006
+//
+// confix bug
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/limits.hpp>
+#include <boost/spirit/include/classic_confix.hpp>
+
+void bug_006()
+{
+ BOOST_TEST(parse("#some comment", comment_p('#')).full);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// bug_007
+//
+// handling of trailing whitespace bug (ast_parse/pt_parse related)
+// JDG: Oct 18, 2005. We shall revert to the previous behavior where
+// Post skips are not allowed. The reason is that
+// there is a valid use case where input is obtained
+// from cin and multi_pass which results in an infinite
+// loop while the post skipper waits for a whitespace.
+// For examples like below, the grammar must explicitly
+// include the post whitespace. One possible way is to
+// place an end_p at the end of the grammar. The end_p
+// will trigger the post-skip.
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_ast.hpp>
+#include <boost/spirit/include/classic_parse_tree.hpp>
+
+void bug_007()
+{
+ BOOST_TEST(parse("test ", str_p("test") >> end_p, space_p).full);
+ BOOST_TEST(pt_parse("test ", str_p("test") >> end_p, space_p).full);
+ BOOST_TEST(ast_parse("test ", str_p("test") >> end_p, space_p).full);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// sf_bug_718903
+//
+// see https://sourceforge.net/tracker/index.php
+// ?func=detail&aid=718903&group_id=28447&atid=393386
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/cstdlib.hpp>
+#include <boost/spirit/include/classic_chset.hpp>
+
+void sf_bug_718903()
+{
+ empty_match_parser<chset<char> >
+ e(epsilon_p(chset_p("abc")));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// sf_bug_719322
+// range_run bug
+//
+// see http://sourceforge.net/tracker/index.php
+// ?func=detail&aid=719322&group_id=28447&atid=393386
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_basic_chset.hpp>
+
+void sf_bug_719322()
+{
+ basic_chset<int> s;
+ s.set(3, 3);
+ s.set(1, 5);
+ BOOST_TEST(s.test(5));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// sf_bug_742038
+//
+// see http://sf.net/tracker/
+// ?func=detail&atid=393386&aid=742038&group_id=28447
+//
+///////////////////////////////////////////////////////////////////////////////
+#include <boost/spirit/include/classic_position_iterator.hpp>
+#include <boost/spirit/include/classic_file_iterator.hpp>
+#include <string>
+#include <fstream>
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+#include <stdio.h>
+
+template <typename IterT>
+void test_assign(IterT b, IterT e)
+{
+ typedef scanner<IterT> scanner_t;
+
+#if (defined(__GNUC__) && defined(__MINGW32__)) \
+ || (defined(__GNUC__) && (__GNUC_MINOR__ < 20))
+
+// There's a bug in g++3.x on MinGW that makes basic_string assert
+// when assigning from IterT [f, l) where IterT is a position_iterator.
+// This issue is discussed here:
+//
+// http://gcc.gnu.org/ml/libstdc++/2002-03/msg00196.html
+//
+// Aparently, this bug is only present on MinGW. I'm clueless as
+// to why this is so. Regressions on linux seem to be OK! :(
+//
+// With, g++3.1, assigning to basic_string from IterT [f, l) is a
+// compile error (a g++3.1 bug).
+//
+// In both cases above, we use a vector instead of a string.
+
+ typedef std::vector<char> store;
+#else
+ typedef std::string store;
+#endif
+
+ store dst;
+ rule<scanner_t> r = (*alpha_p)[assign_a(dst)];
+
+ parse(b, e, r);
+
+ store::iterator d = dst.begin();
+
+ while (b != e)
+ {
+ if (*d != *b)
+ BOOST_TEST(*d == *b);
+ ++b;
+ ++d;
+ }
+}
+
+void sf_bug_742038()
+{
+ std::string src = "abcdef";
+ const char* tmpfilename = "sf_bug_742038.tmp";
+
+ test_assign(src.begin(), src.end());
+
+ position_iterator<std::string::iterator> b(src.begin(), src.end(), "");
+ position_iterator<std::string::iterator> e;
+ test_assign(b, e);
+
+ {
+ std::fstream f(tmpfilename, std::ios::out);
+ f << src;
+ f.close();
+
+ file_iterator<> b1(tmpfilename);
+ file_iterator<> e1(b1.make_end());
+ test_assign(b1, e1);
+ }
+
+ std::remove(tmpfilename);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// bug_009
+//
+// limit_d bug
+// http://article.gmane.org/gmane.comp.parsers.spirit.devel/1891/
+//
+///////////////////////////////////////////////////////////////////////////////
+void
+bug_009()
+{
+ parse(
+ "test"
+ , limit_d(1U, 10U)[uint_p] | str_p("test"));
+}
+
+int
+main()
+{
+ bug_001();
+ bug_002();
+ bug_003();
+ bug_004();
+ bug_005();
+ bug_006();
+ bug_007();
+ bug_009();
+
+ sf_bug_718903();
+ sf_bug_719322();
+ sf_bug_742038();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/char_strings_test.cpp b/src/boost/libs/spirit/classic/test/char_strings_test.cpp
new file mode 100644
index 00000000..f2507a5f
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/char_strings_test.cpp
@@ -0,0 +1,32 @@
+/*=============================================================================
+ Copyright (c) 2004 Joao Abecasis
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include <boost/spirit/include/classic_primitives.hpp>
+#include <boost/spirit/include/classic_rule.hpp>
+
+#include <string>
+
+int main()
+{
+ using BOOST_SPIRIT_CLASSIC_NS::rule;
+ using BOOST_SPIRIT_CLASSIC_NS::str_p;
+ using BOOST_SPIRIT_CLASSIC_NS::ch_p;
+
+ using std::string;
+
+ string str = "abcd";
+
+ rule<> strings = str_p("abcd");
+ strings = str_p('a');
+ strings = str_p(str.begin(), str.end());
+
+ rule<> chars = ch_p('a');
+ chars = ch_p("b");
+}
+
diff --git a/src/boost/libs/spirit/classic/test/char_strings_test_fail.cpp b/src/boost/libs/spirit/classic/test/char_strings_test_fail.cpp
new file mode 100644
index 00000000..3bba0b56
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/char_strings_test_fail.cpp
@@ -0,0 +1,19 @@
+/*=============================================================================
+ Copyright (c) 2004 Joao Abecasis
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include <boost/spirit/include/classic_primitives.hpp>
+#include <boost/spirit/include/classic_rule.hpp>
+
+int main()
+{
+ using BOOST_SPIRIT_CLASSIC_NS::rule;
+ using BOOST_SPIRIT_CLASSIC_NS::ch_p;
+
+ rule<> chars = ch_p("string");
+}
diff --git a/src/boost/libs/spirit/classic/test/chset_tests.cpp b/src/boost/libs/spirit/classic/test/chset_tests.cpp
new file mode 100644
index 00000000..8955b152
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/chset_tests.cpp
@@ -0,0 +1,331 @@
+/*=============================================================================
+ Copyright (c) 1998-2003 Joel de Guzman
+ Copyright (c) 2001-2003 Daniel Nuffer
+ Copyright (c) 2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "impl/sstream.hpp"
+
+#include <boost/spirit/include/classic_chset.hpp>
+
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+namespace
+{
+ ///////////////////////////////////////////////////////////////////////////
+ //
+ // chset tests
+ //
+ ///////////////////////////////////////////////////////////////////////////
+ void
+ DrawRuler(sstream_t& out, char const* str)
+ {
+ out << std::endl << std::endl;
+ out << "\t_____________________________________________________________\n";
+ out << "\t" << str << std::endl;
+ out << "\t";
+ for (char i = '!'; i < '^'; i++)
+ out << i;
+ out << "\n";
+ out << "\t_____________________________________________________________\n\n";
+ }
+
+ //////////////////////////////////
+ template <typename CharT>
+ void
+ Draw(sstream_t& out, chset<CharT> a, char const* str)
+ {
+ out << "\t";
+
+ for (int i = '!'; i < '^'; i++)
+ if (a.test(CharT(i)))
+ out << '*';
+ else
+ out << " ";
+
+ out << "\t" << str << std::endl;
+ }
+
+ //////////////////////////////////
+ template <typename CharT>
+ void
+ chset_tests(sstream_t& out, CharT const* a_, CharT b1_, CharT b2_, CharT e1_)
+ {
+ chset<CharT> a(a_);
+ range<CharT> b_(b1_, b2_);
+ chset<CharT> b(b_);
+ chset<CharT> c(~a); // ~char_parser code must not interfere
+ // with chset
+ negated_char_parser<range<CharT> > d_(~b_);
+ chset<CharT> d(d_);
+ chlit<CharT> e_(e1_);
+ chset<CharT> e(e_);
+ negated_char_parser<chlit<CharT> > f_(e1_);
+ chset<CharT> f(f_);
+
+ DrawRuler(out, "Initial");
+ Draw(out, a, "a");
+ Draw(out, b, "b");
+ Draw(out, d, "d");
+ Draw(out, e, "e");
+ Draw(out, f, "f");
+
+ DrawRuler(out, "Inverse");
+ Draw(out, ~a, "~a");
+ Draw(out, c, "chset<>(~a)");
+ Draw(out, ~~a, "~~a");
+ Draw(out, ~b, "~b");
+
+ DrawRuler(out, "Union");
+ Draw(out, a, "a");
+ Draw(out, b, "b");
+ Draw(out, d, "d");
+ Draw(out, e, "e");
+ Draw(out, f, "f");
+ Draw(out, a | b, "a | b");
+ Draw(out, a | b_, "a | b_");
+ Draw(out, b_ | a, "b_ | a");
+ Draw(out, a | anychar_p, "a | anychar_p");
+ Draw(out, b | anychar_p, "b | anychar_p");
+ Draw(out, a | d, "a | d");
+ Draw(out, a | d_, "a | d_");
+ Draw(out, d_ | a, "d_ | a");
+ Draw(out, a | e_, "a | e_");
+ Draw(out, e_ | b, "e_ | b");
+ Draw(out, a | f_, "a | f_");
+ Draw(out, f_ | b, "f_ | b");
+
+ DrawRuler(out, "Intersection");
+ Draw(out, a, "a");
+ Draw(out, b, "b");
+ Draw(out, d, "d");
+ Draw(out, e, "e");
+ Draw(out, f, "f");
+ Draw(out, a & b, "a & b");
+ Draw(out, a & b_, "a & b_");
+ Draw(out, b_ & a, "b_ & a");
+ Draw(out, a & d, "a & d");
+ Draw(out, a & d_, "a & d_");
+ Draw(out, d_ & a, "d_ & a");
+ Draw(out, a & e_, "a & e_");
+ Draw(out, e_ & b, "e_ & b");
+ Draw(out, a & f_, "a & f_");
+ Draw(out, f_ & b, "f_ & b");
+ Draw(out, a & anychar_p, "a & anychar_p");
+ Draw(out, b & anychar_p, "b & anychar_p");
+
+ DrawRuler(out, "Difference");
+ Draw(out, a, "a");
+ Draw(out, b, "b");
+ Draw(out, d, "d");
+ Draw(out, e, "e");
+ Draw(out, f, "f");
+ Draw(out, a - b, "a - b");
+ Draw(out, b - a, "b - a");
+ Draw(out, a - b_, "a - b_");
+ Draw(out, b_ - a, "b_ - a");
+ Draw(out, a - d, "a - d");
+ Draw(out, d - a, "d - a");
+ Draw(out, a - d_, "a - d_");
+ Draw(out, d_ - a, "d_ - a");
+ Draw(out, a - e_, "a - e_");
+ Draw(out, e_ - b, "e_ - b");
+ Draw(out, a - f_, "a - f_");
+ Draw(out, f_ - b, "f_ - b");
+ Draw(out, a - anychar_p, "a - anychar_p");
+ Draw(out, anychar_p - a, "anychar_p - a");
+ Draw(out, b - anychar_p, "b - anychar_p");
+ Draw(out, anychar_p - b, "anychar_p - b");
+
+ DrawRuler(out, "Xor");
+ Draw(out, a, "a");
+ Draw(out, b, "b");
+ Draw(out, d, "d");
+ Draw(out, e, "e");
+ Draw(out, f, "f");
+ Draw(out, a ^ b, "a ^ b");
+ Draw(out, a ^ b_, "a ^ b_");
+ Draw(out, b_ ^ a, "b_ ^ a");
+ Draw(out, a ^ d, "a ^ d");
+ Draw(out, a ^ d_, "a ^ d_");
+ Draw(out, d_ ^ a, "d_ ^ a");
+ Draw(out, a ^ e_, "a ^ e_");
+ Draw(out, e_ ^ b, "e_ ^ b");
+ Draw(out, a ^ f_, "a ^ f_");
+ Draw(out, f_ ^ b, "f_ ^ b");
+ Draw(out, a ^ nothing_p, "a ^ nothing_p");
+ Draw(out, a ^ anychar_p, "a ^ anychar_p");
+ Draw(out, b ^ nothing_p, "b ^ nothing_p");
+ Draw(out, b ^ anychar_p, "b ^ anychar_p");
+ }
+
+ char const* expected_output =
+ "\n\n"
+ "\t_____________________________________________________________\n"
+ "\tInitial\n"
+ "\t!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]\n"
+ "\t_____________________________________________________________\n"
+ "\n"
+ "\t ********** ************************** \ta\n"
+ "\t ********************** \tb\n"
+ "\t******************** *******************\td\n"
+ "\t * \te\n"
+ "\t***************** *******************************************\tf\n"
+ "\n"
+ "\n"
+ "\t_____________________________________________________________\n"
+ "\tInverse\n"
+ "\t!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]\n"
+ "\t_____________________________________________________________\n"
+ "\n"
+ "\t*************** ******* ***\t~a\n"
+ "\t*************** ******* ***\tchset<>(~a)\n"
+ "\t ********** ************************** \t~~a\n"
+ "\t******************** *******************\t~b\n"
+ "\n"
+ "\n"
+ "\t_____________________________________________________________\n"
+ "\tUnion\n"
+ "\t!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]\n"
+ "\t_____________________________________________________________\n"
+ "\n"
+ "\t ********** ************************** \ta\n"
+ "\t ********************** \tb\n"
+ "\t******************** *******************\td\n"
+ "\t * \te\n"
+ "\t***************** *******************************************\tf\n"
+ "\t ******************************************* \ta | b\n"
+ "\t ******************************************* \ta | b_\n"
+ "\t ******************************************* \tb_ | a\n"
+ "\t*************************************************************\ta | anychar_p\n"
+ "\t*************************************************************\tb | anychar_p\n"
+ "\t************************* *****************************\ta | d\n"
+ "\t************************* *****************************\ta | d_\n"
+ "\t************************* *****************************\td_ | a\n"
+ "\t ********** ************************** \ta | e_\n"
+ "\t * ********************** \te_ | b\n"
+ "\t*************************************************************\ta | f_\n"
+ "\t***************** *******************************************\tf_ | b\n"
+ "\n"
+ "\n"
+ "\t_____________________________________________________________\n"
+ "\tIntersection\n"
+ "\t!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]\n"
+ "\t_____________________________________________________________\n"
+ "\n"
+ "\t ********** ************************** \ta\n"
+ "\t ********************** \tb\n"
+ "\t******************** *******************\td\n"
+ "\t * \te\n"
+ "\t***************** *******************************************\tf\n"
+ "\t ***** ********** \ta & b\n"
+ "\t ***** ********** \ta & b_\n"
+ "\t ***** ********** \tb_ & a\n"
+ "\t ***** **************** \ta & d\n"
+ "\t ***** **************** \ta & d_\n"
+ "\t ***** **************** \td_ & a\n"
+ "\t * \ta & e_\n"
+ "\t \te_ & b\n"
+ "\t ** ******* ************************** \ta & f_\n"
+ "\t ********************** \tf_ & b\n"
+ "\t ********** ************************** \ta & anychar_p\n"
+ "\t ********************** \tb & anychar_p\n"
+ "\n"
+ "\n"
+ "\t_____________________________________________________________\n"
+ "\tDifference\n"
+ "\t!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]\n"
+ "\t_____________________________________________________________\n"
+ "\n"
+ "\t ********** ************************** \ta\n"
+ "\t ********************** \tb\n"
+ "\t******************** *******************\td\n"
+ "\t * \te\n"
+ "\t***************** *******************************************\tf\n"
+ "\t ***** **************** \ta - b\n"
+ "\t ******* \tb - a\n"
+ "\t ***** **************** \ta - b_\n"
+ "\t ******* \tb_ - a\n"
+ "\t ***** ********** \ta - d\n"
+ "\t*************** ***\td - a\n"
+ "\t ***** ********** \ta - d_\n"
+ "\t*************** ***\td_ - a\n"
+ "\t ** ******* ************************** \ta - e_\n"
+ "\t * \te_ - b\n"
+ "\t * \ta - f_\n"
+ "\t***************** ** *******************\tf_ - b\n"
+ "\t \ta - anychar_p\n"
+ "\t*************** ******* ***\tanychar_p - a\n"
+ "\t \tb - anychar_p\n"
+ "\t******************** *******************\tanychar_p - b\n"
+ "\n"
+ "\n"
+ "\t_____________________________________________________________\n"
+ "\tXor\n"
+ "\t!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]\n"
+ "\t_____________________________________________________________\n"
+ "\n"
+ "\t ********** ************************** \ta\n"
+ "\t ********************** \tb\n"
+ "\t******************** *******************\td\n"
+ "\t * \te\n"
+ "\t***************** *******************************************\tf\n"
+ "\t ***** ******* **************** \ta ^ b\n"
+ "\t ***** ******* **************** \ta ^ b_\n"
+ "\t ***** ******* **************** \tb_ ^ a\n"
+ "\t*************** ***** ********** ***\ta ^ d\n"
+ "\t*************** ***** ********** ***\ta ^ d_\n"
+ "\t*************** ***** ********** ***\td_ ^ a\n"
+ "\t ** ******* ************************** \ta ^ e_\n"
+ "\t * ********************** \te_ ^ b\n"
+ "\t*************** * ******* ***\ta ^ f_\n"
+ "\t***************** ** *******************\tf_ ^ b\n"
+ "\t ********** ************************** \ta ^ nothing_p\n"
+ "\t*************** ******* ***\ta ^ anychar_p\n"
+ "\t ********************** \tb ^ nothing_p\n"
+ "\t******************** *******************\tb ^ anychar_p\n"
+ ;
+
+ void chset_tests()
+ {
+ sstream_t tout, aout, bout;
+
+ tout << expected_output;
+
+ chset_tests(aout, "0-9A-Z", '5', 'J', '2');
+ chset_tests(bout, L"0-9A-Z", L'5', L'J', L'2');
+
+#define narrow_chset_works (getstring(aout) == getstring(tout))
+#define wide_chset_works (getstring(bout) == getstring(tout))
+
+ if (!narrow_chset_works || !wide_chset_works)
+ {
+ std::cout << "EXPECTED:\n" <<
+ getstring(tout);
+ std::cout << "GOT:\n" <<
+ getstring(aout);
+ std::cout << "AND:\n" <<
+ getstring(bout);
+ }
+
+ BOOST_TEST(narrow_chset_works);
+ BOOST_TEST(wide_chset_works);
+ }
+
+} // namespace
+
+int
+main()
+{
+ chset_tests();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/closure_tests.cpp b/src/boost/libs/spirit/classic/test/closure_tests.cpp
new file mode 100644
index 00000000..f05d7210
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/closure_tests.cpp
@@ -0,0 +1,157 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_closure.hpp>
+#include <boost/spirit/include/classic_parametric.hpp>
+#include <boost/spirit/include/phoenix1_binders.hpp>
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace phoenix;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Closure tests
+//
+///////////////////////////////////////////////////////////////////////////////
+struct my_closure1 : BOOST_SPIRIT_CLASSIC_NS::closure<my_closure1, double>
+{
+ member1 val;
+};
+
+struct my_closure2 : BOOST_SPIRIT_CLASSIC_NS::closure<my_closure2, char>
+{
+ member1 ch;
+};
+
+struct my_closure3 : BOOST_SPIRIT_CLASSIC_NS::closure<my_closure3, char>
+{
+ member1 ch;
+};
+
+struct X { int a; int b; };
+
+#if defined(BOOST_SPIRIT_DEBUG)
+// If debugging is switched on, all closure members should have a
+// corresponding output streaming operator
+std::ostream &
+operator<< (std::ostream& o, X const &x)
+{
+ o << "X(" << x.a << ", " << x.b << ")";
+ return o;
+}
+#endif // defined(BOOST_SPIRIT_DEBUG)
+
+struct my_closure4 : BOOST_SPIRIT_CLASSIC_NS::closure<my_closure4, X>
+{
+ member1 x;
+};
+
+// MWCW8.3 needs the default constructor here or it won't compile.
+// It should not be needed.
+struct Y { Y() {} Y(int) {} };
+
+#if defined(BOOST_SPIRIT_DEBUG)
+// If debugging is switched on, all closure members should have a
+// corresponding output streaming operator
+std::ostream &
+operator<< (std::ostream& o, Y const &/*x*/)
+{
+ o << "Y";
+ return o;
+}
+#endif // defined(BOOST_SPIRIT_DEBUG)
+
+struct my_closure5 : BOOST_SPIRIT_CLASSIC_NS::closure<my_closure5, int, Y>
+{
+ member1 y;
+};
+
+struct my_closure6 : BOOST_SPIRIT_CLASSIC_NS::closure<my_closure6, int, int, int>
+{
+ member1 x;
+ member2 y;
+ member3 z;
+};
+
+void
+closure_tests()
+{
+ rule<phrase_scanner_t, my_closure1::context_t> num_list;
+ double n;
+
+ num_list =
+ (
+ real_p[num_list.val = arg1] >> *(',' >> real_p[num_list.val += arg1])
+ )
+ [var(n) = num_list.val];
+
+ parse_info<char const*> pi;
+ pi = parse("123, 456, 789", num_list, space_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(n == 123 + 456 + 789);
+
+ rule<scanner<>, my_closure2::context_t> rev;
+ rev = anychar_p[rev.ch = arg1] >> !rev >> f_ch_p(rev.ch);
+
+ pi = parse("xyzzyx", rev);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse("xyzczyx", rev);
+ BOOST_TEST(!pi.hit);
+
+ subrule<0, my_closure3::context_t> rev2;
+ pi = parse("atoyyota",
+ rev2 = anychar_p[rev2.ch = arg1] >> !rev2 >> f_ch_p(rev2.ch)
+ );
+
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse("whatdahell",
+ rev2 = anychar_p[rev2.ch = arg1] >> !rev2 >> f_ch_p(rev2.ch)
+ );
+ BOOST_TEST(!pi.hit);
+
+ rule<phrase_scanner_t, my_closure4::context_t> complex_p;
+ complex_p =
+ int_p[bind(&X::a)(complex_p.x) = arg1]
+ >> ','
+ >> int_p[bind(&X::b)(complex_p.x) = arg1]
+ ;
+
+ X x;
+ pi = parse("123, 456", complex_p[var(x) = arg1], space_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(x.a == 123);
+ BOOST_TEST(x.b == 456);
+
+ rule<scanner<>, my_closure5::context_t> init1; // compile check only
+ rule<> r1 = init1(3, 3); // member2 is constructed from int
+
+ rule<scanner<>, my_closure6::context_t> init2; // compile check only
+ rule<> r2 = init2(3); // member2 and member3 are default constructed
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ closure_tests();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/confix_tests.cpp b/src/boost/libs/spirit/classic/test/confix_tests.cpp
new file mode 100644
index 00000000..f1466a82
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/confix_tests.cpp
@@ -0,0 +1,60 @@
+/*=============================================================================
+ Copyright (c) 2003 2003 Vaclav Vesely
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_confix.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace boost;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+typedef
+ scanner<char const*, scanner_policies<skipper_iteration_policy<> > >
+ scanner_t;
+
+typedef
+ rule<scanner_t>
+ rule_t;
+
+void comment_nest_p_test()
+{
+ rule_t r = comment_nest_p('{', '}');
+
+ {
+ parse_info<> info = parse("{a{b}c{d}e}", r, space_p);
+ BOOST_TEST(info.full);
+ }
+
+ {
+ parse_info<> info = parse("{a{b}c{d}e}x", r, space_p);
+ BOOST_TEST(info.hit);
+ BOOST_TEST(info.length == 11);
+ }
+
+ {
+ char const* str = "x{a{b}c{d}e}";
+ parse_info<> info = parse(str, r, space_p);
+ BOOST_TEST(!info.hit);
+ BOOST_TEST(info.stop == str);
+ }
+
+ {
+ char const* str = "{a{b}c{d}e";
+ parse_info<> info = parse(str, r, space_p);
+ BOOST_TEST(!info.hit);
+ BOOST_TEST(info.stop == (str + 10));
+ }
+}
+
+int
+main()
+{
+ comment_nest_p_test();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/custom_real_parser.cpp b/src/boost/libs/spirit/classic/test/custom_real_parser.cpp
new file mode 100644
index 00000000..9971a69c
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/custom_real_parser.cpp
@@ -0,0 +1,33 @@
+/*=============================================================================
+ Copyright (c) 2007 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_actor.hpp>
+#include <boost/math/concepts/real_concept.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using boost::math::concepts::real_concept;
+
+int main()
+{
+ real_parser<real_concept> const rr_p;
+ bool started = false;
+ real_concept a, b;
+
+ parse_info<> pi = parse("range 0 1",
+ str_p("range")[assign_a(started, false)]
+ && rr_p[assign_a(a)]
+ && rr_p[assign_a(b)],
+ space_p);
+
+ BOOST_TEST(pi.full && a == 0.0 && b == 1.0);
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/directives_tests.cpp b/src/boost/libs/spirit/classic/test/directives_tests.cpp
new file mode 100644
index 00000000..e45b9d7f
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/directives_tests.cpp
@@ -0,0 +1,189 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+#include <string>
+
+
+#include "impl/string_length.hpp"
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_assign_actor.hpp>
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Directives tests
+//
+///////////////////////////////////////////////////////////////////////////////
+void
+directives_test1()
+{
+ char const* cpx = "H e l l o";
+ char const* cpx_first = cpx;
+ char const* cpx_last = cpx + test_impl::string_length(cpx);
+
+ match<> hit;
+ typedef skipper_iteration_policy<iteration_policy> iter_policy;
+ scanner<char const*, scanner_policies<iter_policy> >
+ scanx(cpx_first, cpx_last);
+
+ hit = str_p("Hello").parse(scanx);
+ BOOST_TEST(!hit);
+ scanx.first = cpx;
+
+ hit = chseq_p("Hello").parse(scanx);
+ BOOST_TEST(!!hit);
+ scanx.first = cpx;
+
+ char const* cp = "Hello \n\tWorld";
+ char const* cp_first = cp;
+ char const* cp_last = cp + test_impl::string_length(cp);
+
+ scanner<char const*, scanner_policies<iter_policy> >
+ scan(cp_first, cp_last);
+
+ hit = (+(alpha_p | punct_p)).parse(scan);
+ BOOST_TEST(!!hit);
+ BOOST_TEST(scan.first == scan.last);
+ scan.first = cp;
+
+ hit = (+(lexeme_d[+(alpha_p | '\'')])).parse(scan);
+ BOOST_TEST(!!hit);
+ BOOST_TEST(scan.first == scan.last);
+ scan.first = cp;
+
+ hit = (+(lexeme_d[lexeme_d[+anychar_p]])).parse(scan);
+ BOOST_TEST(!!hit);
+ BOOST_TEST(scan.first == scan.last);
+ scan.first = cp;
+
+ hit = (str_p("Hello") >> "World").parse(scan);
+ BOOST_TEST(!!hit);
+ BOOST_TEST(scan.first == scan.last);
+ scan.first = cp;
+
+ hit = as_lower_d[str_p("hello") >> "world"].parse(scan);
+ BOOST_TEST(!!hit);
+ BOOST_TEST(scan.first == scan.last);
+ scan.first = cp;
+
+ hit = (+(as_lower_d[as_lower_d[+lower_p | '\'']])).parse(scan);
+ BOOST_TEST(!!hit);
+ BOOST_TEST(scan.first == scan.last);
+ scan.first = cp;
+
+ char const* cpy = "123.456";
+ char const* cpy_first = cpy;
+ char const* cpy_last = cpy + test_impl::string_length(cpy);
+
+ scanner<> scany(cpy_first, cpy_last);
+ hit = longest_d[(+digit_p >> '.' >> +digit_p) | (+digit_p)].parse(scany);
+ BOOST_TEST(!!hit);
+ BOOST_TEST(scany.first == scany.last);
+ scany.first = cpy;
+
+ hit = shortest_d[(+digit_p >> '.' >> +digit_p) | (+digit_p)].parse(scany);
+ BOOST_TEST(!!hit);
+ BOOST_TEST(scany.first != scany.last);
+ scany.first = cpy;
+
+ char const* cpz = "razamanaz";
+ char const* cpz_first = cpz;
+ char const* cpz_last = cpz + test_impl::string_length(cpz);
+
+ scanner<> scanz(cpz_first, cpz_last);
+ hit = longest_d[str_p("raza") | "razaman" | "razamanaz"].parse(scanz);
+ BOOST_TEST(!!hit);
+ BOOST_TEST(scanz.first == scanz.last);
+ scanz.first = cpz;
+
+ hit = shortest_d[str_p("raza") | "razaman" | "razamanaz"].parse(scanz);
+ BOOST_TEST(!!hit);
+ BOOST_TEST(scanz.first == cpz+4);
+ scanz.first = cpz;
+
+// bounds_d
+
+ parse_info<> pr = parse("123", limit_d(0, 60)[int_p]);
+ BOOST_TEST(!pr.hit);
+
+ pr = parse("-2", limit_d(0, 60)[int_p]);
+ BOOST_TEST(!pr.hit);
+
+ pr = parse("60", limit_d(0, 60)[int_p]);
+ BOOST_TEST(pr.hit);
+
+ pr = parse("0", limit_d(0, 60)[int_p]);
+ BOOST_TEST(pr.hit);
+
+ pr = parse("-2", min_limit_d(0)[int_p]);
+ BOOST_TEST(!pr.hit);
+
+ pr = parse("-2", min_limit_d(-5)[int_p]);
+ BOOST_TEST(pr.hit);
+
+ pr = parse("101", max_limit_d(100)[int_p]);
+ BOOST_TEST(!pr.hit);
+
+ pr = parse("100", max_limit_d(100)[int_p]);
+ BOOST_TEST(pr.hit);
+}
+
+struct identifier : public grammar<identifier>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(identifier const& /*self*/)
+ {
+ rr = +(alpha_p | '_');
+ r = lexeme_d[rr];
+ }
+
+ rule<typename lexeme_scanner<ScannerT>::type> rr;
+ rule<ScannerT> r;
+
+ rule<ScannerT> const&
+ start() const { return r; }
+ };
+};
+
+void
+directives_test2()
+{
+ // Test that lexeme_d does not skip trailing spaces
+
+ std::string str1, str2;
+ identifier ident;
+
+ parse("rock_n_roll never_dies ",
+
+ ident[assign_a(str1)] >> ident[assign_a(str2)], space_p
+ );
+
+ std::cout << '*' << str1 << ',' << str2 << '*' << std::endl;
+
+
+ BOOST_TEST(str1 == "rock_n_roll");
+ BOOST_TEST(str2 == "never_dies");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ directives_test1();
+ directives_test2();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/distinct_tests.cpp b/src/boost/libs/spirit/classic/test/distinct_tests.cpp
new file mode 100644
index 00000000..0ef66b0a
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/distinct_tests.cpp
@@ -0,0 +1,248 @@
+/*=============================================================================
+ Copyright (c) 2003 Vaclav Vesely
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_distinct.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace boost;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+typedef
+ scanner<char const*, scanner_policies<skipper_iteration_policy<> > >
+ scanner_t;
+
+typedef
+ rule<scanner_t>
+ rule_t;
+
+void distinct_parser_test()
+{
+ // distinct_parser()
+ {
+ distinct_parser<> distinct_p;
+
+ // operator()(CharT const* str) const
+ rule_t r = distinct_p("keyword") >> !ch_p('-') >> int_p;
+ BOOST_TEST(parse("keyword123", r, space_p).full);
+ }
+
+ // distinct_parser(CharT const* letters)
+ {
+ distinct_parser<> distinct_p("0-9a-zA-Z_");
+
+ // operator()(CharT const* str) const
+ rule_t r = distinct_p("keyword") >> !ch_p('-') >> int_p;
+ BOOST_TEST(parse("keyword 123", r, space_p).full);
+ BOOST_TEST(parse("keyword-123", r, space_p).full);
+ BOOST_TEST(!parse("keyword123", r, space_p).hit);
+ }
+
+ // distinct_parser(parser<TailT> const & tail_)
+ {
+ distinct_parser<
+ char,
+ alternative<
+ alnum_parser,
+ sequence<
+ chlit<>,
+ negated_char_parser<chlit<> >
+ >
+ >
+ >
+ distinct_p(alnum_p | ('-' >> ~ch_p('-')));
+
+ // operator()(CharT const* str) const
+ rule_t r = distinct_p("keyword") >> !str_p("--") >> int_p;
+ BOOST_TEST(parse("keyword 123", r, space_p).full);
+ BOOST_TEST(parse("keyword--123", r, space_p).full);
+ BOOST_TEST(!parse("keyword-123", r, space_p).hit);
+ }
+}
+
+void distinct_directive_test()
+{
+ // distinct_directive()
+ {
+ distinct_directive<> distinct_d;
+
+ // operator[](CharT const* str) const
+ {
+ rule_t r = distinct_d["keyword"] >> !ch_p('-') >> int_p;
+ BOOST_TEST(parse("keyword123", r, space_p).full);
+ }
+
+ // operator[](parser<ParserT> const &subject) const
+ {
+ rule_t r = distinct_d[str_p("keyword")] >> !ch_p('-') >> int_p;
+ BOOST_TEST(parse("keyword123", r, space_p).full);
+ }
+ }
+
+ // distinct_directive(CharT const* letters)
+ {
+ distinct_directive<> distinct_d("0-9a-zA-Z_");
+
+ // operator[](CharT const* str) const
+ {
+ rule_t r = distinct_d["keyword"] >> !ch_p('-') >> int_p;
+ BOOST_TEST(parse("keyword 123", r, space_p).full);
+ BOOST_TEST(parse("keyword-123", r, space_p).full);
+ BOOST_TEST(!parse("keyword123", r, space_p).hit);
+ }
+
+ // operator[](parser<ParserT> const &subject) const
+ {
+ rule_t r = distinct_d[str_p("keyword")] >> !ch_p('-') >> int_p;
+ BOOST_TEST(parse("keyword 123", r, space_p).full);
+ BOOST_TEST(parse("keyword-123", r, space_p).full);
+ BOOST_TEST(!parse("keyword123", r, space_p).hit);
+ }
+ }
+
+ // distinct_directive(parser<TailT> const & tail_)
+ {
+ distinct_directive<
+ char,
+ alternative<
+ alnum_parser,
+ sequence<
+ chlit<>,
+ negated_char_parser<chlit<> >
+ >
+ >
+ >
+ distinct_d(alnum_p | ('-' >> ~ch_p('-')));
+
+ // operator[](CharT const* str) const
+ {
+ rule_t r = distinct_d["keyword"] >> !str_p("--") >> int_p;
+ BOOST_TEST(parse("keyword 123", r, space_p).full);
+ BOOST_TEST(parse("keyword--123", r, space_p).full);
+ BOOST_TEST(!parse("keyword-123", r, space_p).hit);
+ }
+
+ // operator[](parser<ParserT> const &subject) const
+ {
+ rule_t r = distinct_d[str_p("keyword")] >> !str_p("--") >> int_p;
+ BOOST_TEST(parse("keyword 123", r, space_p).full);
+ BOOST_TEST(parse("keyword--123", r, space_p).full);
+ BOOST_TEST(!parse("keyword-123", r, space_p).hit);
+ }
+ }
+}
+
+void dynamic_distinct_parser_test()
+{
+ // dynamic_distinct_parser()
+ {
+ dynamic_distinct_parser<scanner_t> distinct_p;
+
+ // operator()(CharT const* str) const
+ rule_t r = distinct_p("keyword") >> !ch_p('-') >> int_p;
+ BOOST_TEST(parse("keyword123", r, space_p).full);
+ }
+
+ // dynamic_distinct_parser(CharT const* letters)
+ {
+ dynamic_distinct_parser<scanner_t> distinct_p("0-9a-zA-Z_");
+
+ // operator()(CharT const* str) const
+ rule_t r = distinct_p("keyword") >> !ch_p('-') >> int_p;
+ BOOST_TEST(parse("keyword 123", r, space_p).full);
+ BOOST_TEST(parse("keyword-123", r, space_p).full);
+ BOOST_TEST(!parse("keyword123", r, space_p).hit);
+ }
+
+ // dynamic_distinct_parser(parser<TailT> const & tail_)
+ {
+ dynamic_distinct_parser<scanner_t>
+ distinct_p(alnum_p | ('-' >> ~ch_p('-')));
+
+ // operator()(CharT const* str) const
+ rule_t r = distinct_p("keyword") >> !str_p("--") >> int_p;
+ BOOST_TEST(parse("keyword 123", r, space_p).full);
+ BOOST_TEST(parse("keyword--123", r, space_p).full);
+ BOOST_TEST(!parse("keyword-123", r, space_p).hit);
+ }
+}
+
+void dynamic_distinct_directive_test()
+{
+ // dynamic_distinct_directive()
+ {
+ dynamic_distinct_directive<scanner_t> distinct_d;
+
+ // operator[](CharT const* str) const
+ {
+ rule_t r = distinct_d["keyword"] >> !ch_p('-') >> int_p;
+ BOOST_TEST(parse("keyword123", r, space_p).full);
+ }
+
+ // operator[](parser<ParserT> const &subject) const
+ {
+ rule_t r = distinct_d[str_p("keyword")] >> !ch_p('-') >> int_p;
+ BOOST_TEST(parse("keyword123", r, space_p).full);
+ }
+ }
+
+ // dynamic_distinct_directive(CharT const* letters)
+ {
+ dynamic_distinct_directive<scanner_t> distinct_d("0-9a-zA-Z_");
+
+ // operator[](CharT const* str) const
+ {
+ rule_t r = distinct_d["keyword"] >> !ch_p('-') >> int_p;
+ BOOST_TEST(parse("keyword 123", r, space_p).full);
+ BOOST_TEST(parse("keyword-123", r, space_p).full);
+ BOOST_TEST(!parse("keyword123", r, space_p).hit);
+ }
+
+ // operator[](parser<ParserT> const &subject) const
+ {
+ rule_t r = distinct_d[str_p("keyword")] >> !ch_p('-') >> int_p;
+ BOOST_TEST(parse("keyword 123", r, space_p).full);
+ BOOST_TEST(parse("keyword-123", r, space_p).full);
+ BOOST_TEST(!parse("keyword123", r, space_p).hit);
+ }
+ }
+
+ // dynamic_distinct_directive(parser<TailT> const & tail_)
+ {
+ dynamic_distinct_directive<scanner_t>
+ distinct_d(alnum_p | ('-' >> ~ch_p('-')));
+
+ // operator[](CharT const* str) const
+ {
+ rule_t r = distinct_d["keyword"] >> !str_p("--") >> int_p;
+ BOOST_TEST(parse("keyword 123", r, space_p).full);
+ BOOST_TEST(parse("keyword--123", r, space_p).full);
+ BOOST_TEST(!parse("keyword-123", r, space_p).hit);
+ }
+
+ // operator[](parser<ParserT> const &subject) const
+ {
+ rule_t r = distinct_d[str_p("keyword")] >> !str_p("--") >> int_p;
+ BOOST_TEST(parse("keyword 123", r, space_p).full);
+ BOOST_TEST(parse("keyword--123", r, space_p).full);
+ BOOST_TEST(!parse("keyword-123", r, space_p).hit);
+ }
+ }
+}
+
+int
+main()
+{
+ distinct_parser_test();
+ distinct_directive_test();
+ dynamic_distinct_parser_test();
+ dynamic_distinct_directive_test();
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/epsilon_tests.cpp b/src/boost/libs/spirit/classic/test/epsilon_tests.cpp
new file mode 100644
index 00000000..15aa632b
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/epsilon_tests.cpp
@@ -0,0 +1,136 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <cstring>
+#include <boost/detail/lightweight_test.hpp>
+
+// This test program only includes the epsilon.hpp header from Spirit
+#include <boost/spirit/include/classic_epsilon.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "impl/var.hpp"
+#include "impl/string_length.hpp"
+
+using namespace test;
+static BOOST_SPIRIT_CLASSIC_NS::parse_info<char const *> pi;
+
+////////////////////////////////////////////////
+// These macros are used with BOOST_TEST
+#define matches (pi.hit)
+#define full_match (pi.hit && pi.full)
+#define partial_match (pi.hit && !pi.full)
+#define no_match (!pi.hit && !pi.full)
+#define zero_length_match (pi.length == 0)
+#define stop_equals_start (pi.stop == s)
+
+template<typename ParserT>
+static void
+parse(char const *s, ParserT const &p, bool match)
+{
+
+ pi = BOOST_SPIRIT_CLASSIC_NS::parse(s, s + test_impl::string_length(s), p);
+ if (match)
+ {
+ BOOST_TEST(matches);
+ BOOST_TEST(zero_length_match);
+ BOOST_TEST(stop_equals_start);
+ }
+ else
+ {
+ BOOST_TEST(no_match);
+ }
+}
+
+static char const empty[] = "";
+static char const not_empty[] = "asdfgh";
+
+////////////////////////////////////////////////
+// Test wether epsilon_p/eps_p work as
+// primitive parsers
+static void
+epsilon_as_primitive()
+{
+ // This test case also is a compile time check wether
+ // both eps_p and epsilon_p are present.
+
+ parse(empty, BOOST_SPIRIT_CLASSIC_NS::epsilon_p, true);
+ BOOST_TEST(full_match);
+ parse(not_empty, BOOST_SPIRIT_CLASSIC_NS::epsilon_p, true);
+ BOOST_TEST(partial_match);
+
+ parse(empty, BOOST_SPIRIT_CLASSIC_NS::eps_p, true);
+ BOOST_TEST(full_match);
+ parse(not_empty, BOOST_SPIRIT_CLASSIC_NS::eps_p, true);
+ BOOST_TEST(partial_match);
+}
+
+////////////////////////////////////////////////
+// Test wether epsilon_p/eps_p work correctly as
+// a parser generator for creating parsers from
+// functors
+static void
+epsilon_as_parser_generator_for_functors()
+{
+ bool flag = false;
+ parse(empty, BOOST_SPIRIT_CLASSIC_NS::epsilon_p(var(flag)), flag);
+ BOOST_TEST(no_match);
+
+ flag = true;
+ parse(empty, BOOST_SPIRIT_CLASSIC_NS::epsilon_p(var(flag)), flag);
+ BOOST_TEST(full_match);
+}
+
+////////////////////////////////////////////////
+// Test wether epsilon_p/eps_p work correctly as
+// a parser generator for creating parsers from
+// other parsers
+static void
+epsilon_as_parser_generator_for_parsers()
+{
+ // This test case uses a parser created by epsilon_p
+ // as body-parser for another invokation of epsilon_p
+
+ bool flag = false;
+ parse(empty, BOOST_SPIRIT_CLASSIC_NS::epsilon_p(
+ BOOST_SPIRIT_CLASSIC_NS::epsilon_p(var(flag))), flag);
+ BOOST_TEST(no_match);
+
+ flag = true;
+ parse(empty, BOOST_SPIRIT_CLASSIC_NS::epsilon_p(
+ BOOST_SPIRIT_CLASSIC_NS::epsilon_p(var(flag))), flag);
+ BOOST_TEST(full_match);
+}
+
+////////////////////////////////////////////////
+// Test wether epsilon_p/eps_p support negation
+static void
+negation_operator_for_epsilon()
+{
+ bool flag = false;
+ parse(empty, ~BOOST_SPIRIT_CLASSIC_NS::epsilon_p(var(flag)), !flag);
+ BOOST_TEST(full_match);
+ parse(empty, ~~BOOST_SPIRIT_CLASSIC_NS::epsilon_p(var(flag)), flag);
+ BOOST_TEST(no_match);
+
+ flag = true;
+ parse(empty, ~BOOST_SPIRIT_CLASSIC_NS::epsilon_p(var(flag)), !flag);
+ BOOST_TEST(no_match);
+ parse(empty, ~~BOOST_SPIRIT_CLASSIC_NS::epsilon_p(var(flag)), flag);
+ BOOST_TEST(full_match);
+}
+
+int
+main()
+{
+ epsilon_as_primitive();
+ epsilon_as_parser_generator_for_functors();
+ epsilon_as_parser_generator_for_parsers();
+ negation_operator_for_epsilon();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/escape_char_parser_tests.cpp b/src/boost/libs/spirit/classic/test/escape_char_parser_tests.cpp
new file mode 100644
index 00000000..e719d6be
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/escape_char_parser_tests.cpp
@@ -0,0 +1,194 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Daniel Nuffer
+ Copyright (c) 2001-2003 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_assign_actor.hpp>
+#include <boost/spirit/include/classic_escape_char.hpp>
+
+#include <iostream>
+#include <boost/core/ignore_unused.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <cstdio> // for sprintf
+
+#if !defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_SWPRINTF)
+# include <cwchar> // for swprintf
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ char c;
+
+ // testing good C escapes
+ BOOST_TEST(parse("a", c_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == 'a');
+ BOOST_TEST(parse("\\b", c_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\b');
+ BOOST_TEST(parse("\\t", c_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\t');
+ BOOST_TEST(parse("\\n", c_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\n');
+ BOOST_TEST(parse("\\f", c_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\f');
+ BOOST_TEST(parse("\\r", c_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\r');
+ BOOST_TEST(parse("\\\"", c_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\"');
+ BOOST_TEST(parse("\\'", c_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\'');
+ BOOST_TEST(parse("\\\\", c_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\\');
+ BOOST_TEST(parse("\\120", c_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\120');
+ BOOST_TEST(parse("\\x2e", c_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\x2e');
+
+ // test bad C escapes
+ BOOST_TEST(!parse("\\z", c_escape_ch_p[assign_a(c)]).hit);
+
+ // testing good lex escapes
+ BOOST_TEST(parse("a", lex_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == 'a');
+ BOOST_TEST(parse("\\b", lex_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\b');
+ BOOST_TEST(parse("\\t", lex_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\t');
+ BOOST_TEST(parse("\\n", lex_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\n');
+ BOOST_TEST(parse("\\f", lex_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\f');
+ BOOST_TEST(parse("\\r", lex_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\r');
+ BOOST_TEST(parse("\\\"", lex_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\"');
+ BOOST_TEST(parse("\\'", lex_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\'');
+ BOOST_TEST(parse("\\\\", lex_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\\');
+ BOOST_TEST(parse("\\120", lex_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\120');
+ BOOST_TEST(parse("\\x2e", lex_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\x2e');
+ BOOST_TEST(parse("\\z", lex_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == 'z');
+ BOOST_TEST(parse("\\a", lex_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == 'a');
+
+ // test bad lex escapes
+ BOOST_TEST(!parse("\\xz", lex_escape_ch_p[assign_a(c)]).hit);
+
+ // test out of range octal escape
+ BOOST_TEST(!parse("\\777", lex_escape_ch_p[assign_a(c)]).hit);
+
+#if CHAR_MAX == 127
+ BOOST_TEST(!parse("\\200", lex_escape_ch_p[assign_a(c)]).hit);
+
+ BOOST_TEST(parse("\\177", lex_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\177');
+#elif CHAR_MAX == 255
+ BOOST_TEST(!parse("\\400", lex_escape_ch_p[assign_a(c)]).hit);
+
+ BOOST_TEST(parse("\\377", lex_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\377');
+#endif
+
+ // test out of range hex escape
+ BOOST_TEST(!parse("\\xFFF", lex_escape_ch_p[assign_a(c)]).hit);
+
+#if CHAR_MAX == 127
+ BOOST_TEST(!parse("\\X80", lex_escape_ch_p[assign_a(c)]).hit);
+
+ BOOST_TEST(parse("\\X7F", lex_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\x7f');
+#elif CHAR_MAX == 255
+ BOOST_TEST(!parse("\\X100", lex_escape_ch_p[assign_a(c)]).hit);
+
+ BOOST_TEST(parse("\\XFf", lex_escape_ch_p[assign_a(c)]).full);
+ BOOST_TEST(c == '\xff');
+#endif
+
+#ifndef BOOST_NO_CWCHAR
+
+ // test wide chars
+ typedef escape_char_parser<lex_escapes, wchar_t> wlep_t;
+ wlep_t wlep = wlep_t();
+
+ typedef escape_char_parser<c_escapes, wchar_t> wcep_t;
+ wcep_t wcep = wcep_t();
+
+ //wchar_t const* wstr = L"a\\b\\t\\n\\f\\r\\\"\\'\\\\\\120\\x2e";
+ //wchar_t const* wend(wstr + wcslen(wstr));
+
+ wchar_t wc;
+ BOOST_TEST(parse(L"a", wcep[assign_a(wc)]).hit);
+ BOOST_TEST(wc == L'a');
+ BOOST_TEST(parse(L"\\b", wcep[assign_a(wc)]).full);
+ BOOST_TEST(wc == L'\b');
+ BOOST_TEST(parse(L"\\t", wcep[assign_a(wc)]).full);
+ BOOST_TEST(wc == L'\t');
+ BOOST_TEST(parse(L"\\n", wcep[assign_a(wc)]).full);
+ BOOST_TEST(wc == L'\n');
+ BOOST_TEST(parse(L"\\f", wcep[assign_a(wc)]).full);
+ BOOST_TEST(wc == L'\f');
+ BOOST_TEST(parse(L"\\r", wcep[assign_a(wc)]).full);
+ BOOST_TEST(wc == L'\r');
+ BOOST_TEST(parse(L"\\\"", wcep[assign_a(wc)]).full);
+ BOOST_TEST(wc == L'\"');
+ BOOST_TEST(parse(L"\\'", wcep[assign_a(wc)]).full);
+ BOOST_TEST(wc == L'\'');
+ BOOST_TEST(parse(L"\\\\", wcep[assign_a(wc)]).full);
+ BOOST_TEST(wc == L'\\');
+ BOOST_TEST(parse(L"\\120", wcep[assign_a(wc)]).full);
+ BOOST_TEST(wc == L'\120');
+ BOOST_TEST(parse(L"\\x2e", wcep[assign_a(wc)]).full);
+ BOOST_TEST(wc == L'\x2e');
+
+ // test bad wc escapes
+ BOOST_TEST(!parse(L"\\z", wcep[assign_a(wc)]).hit);
+
+#if !defined(BOOST_NO_SWPRINTF)
+ // test out of range octal escape
+ size_t const octmax_size = 16;
+ wchar_t octmax[octmax_size];
+
+ swprintf(octmax, octmax_size,
+ L"\\%lo", (unsigned long)(std::numeric_limits<wchar_t>::max)());
+ BOOST_TEST(parse(octmax, wlep[assign_a(wc)]).full);
+ //BOOST_TEST(lex_escape_ch_p[assign_a(wc)].parse(str, end));
+ BOOST_TEST(wc == (std::numeric_limits<wchar_t>::max)());
+
+ swprintf(octmax, octmax_size,
+ L"\\%lo", (unsigned long)(std::numeric_limits<wchar_t>::max)() + 1);
+ BOOST_TEST(!parse(octmax, wlep[assign_a(wc)]).hit);
+
+ // test out of range hex escape
+ size_t const hexmax_size = 16;
+ wchar_t hexmax[hexmax_size];
+
+ swprintf(hexmax, hexmax_size,
+ L"\\x%lx", (unsigned long)(std::numeric_limits<wchar_t>::max)());
+ BOOST_TEST(parse(hexmax, wlep[assign_a(wc)]).full);
+ BOOST_TEST(wc == (std::numeric_limits<wchar_t>::max)());
+
+ swprintf(hexmax, hexmax_size,
+ L"\\x%lx", (unsigned long)(std::numeric_limits<wchar_t>::max)() + 1);
+ BOOST_TEST(!parse(hexmax, wlep[assign_a(wc)]).hit);
+#else
+ boost::ignore_unused(wlep);
+#endif // !defined(BOOST_NO_SWPRINTF)
+
+#endif
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/exception_tests.cpp b/src/boost/libs/spirit/classic/test/exception_tests.cpp
new file mode 100644
index 00000000..092f8fee
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/exception_tests.cpp
@@ -0,0 +1,49 @@
+/*=============================================================================
+ Copyright (c) 1998-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_exceptions.hpp>
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+struct handler
+{
+ template <typename ScannerT, typename ErrorT>
+ error_status<>
+ operator()(ScannerT const& /*scan*/, ErrorT const& /*error*/) const
+ {
+ cout << "exception caught...Test concluded successfully" << endl;
+ return error_status<>(error_status<>::fail);
+ }
+};
+
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tExceptions Test...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+
+ assertion<int> expect(0);
+ guard<int> my_guard;
+
+ bool r =
+ parse("abcx",
+ my_guard(ch_p('a') >> 'b' >> 'c' >> expect( ch_p('d') ))
+ [
+ handler()
+ ]
+ ).full;
+
+ BOOST_TEST(!r);
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/file_iterator_tests.cpp b/src/boost/libs/spirit/classic/test/file_iterator_tests.cpp
new file mode 100644
index 00000000..ec5d3678
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/file_iterator_tests.cpp
@@ -0,0 +1,186 @@
+/*=============================================================================
+ Copyright (c) 2003 Giovanni Bajo
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <cstdio>
+#include <iostream>
+#include <boost/concept_check.hpp>
+#include <boost/spirit/include/classic_file_iterator.hpp>
+
+// This checks for a namespace related problem in VC8
+// The problem can be avoided by not using "using namespace std;" in the
+// Spirit headers
+namespace vc8_bug_1 { struct plus {}; }
+namespace vc8_bug_2 { using namespace vc8_bug_1; struct test : plus {}; }
+
+
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+namespace {
+
+static const char* TMP_FILE = "file_iter.tmp";
+
+bool CreateTempFile(void)
+{
+ FILE* f = fopen(TMP_FILE, "wb");
+
+ if (!f)
+ return false;
+
+ for (int i=0;i<256;i++)
+ {
+ unsigned char ci = (unsigned char)i;
+
+ if (fwrite(&ci,1,1,f) == 0)
+ {
+ fclose(f);
+ return false;
+ }
+ }
+
+ fclose(f);
+ return true;
+}
+
+template <typename ITER>
+void RunTest(void)
+{
+ // Check constructor opening a file
+ ITER a(TMP_FILE);
+ BOOST_TEST(!!a);
+
+ // Assert dereference (twice: derefence
+ // must not move the iterator)
+ BOOST_TEST(*a == 0);
+ BOOST_TEST(*a == 0);
+
+ // Check random access
+ BOOST_TEST(a[123] == 123);
+
+ // Check copy constructor and operator==
+ ITER c(a);
+ BOOST_TEST(c == a);
+ BOOST_TEST(!(c != a));
+
+ // Check assignment operator
+ ITER d; d = a;
+ BOOST_TEST(d == a);
+ BOOST_TEST(!(d != a));
+
+ // Check make_end()
+ ITER b(a.make_end());
+ BOOST_TEST(!!b);
+ BOOST_TEST(a != b);
+ BOOST_TEST(a+256 == b);
+ BOOST_TEST(a == b-256);
+
+ // Check copy constructor on non-trivial position
+ BOOST_TEST(*ITER(a+67) == 67);
+
+ // Check increment
+ ++a; ++a; a++; a++;
+ BOOST_TEST(*a == 4);
+ BOOST_TEST(a == c+4);
+
+ // Check decrement
+ --a; --a; a--; a--;
+ BOOST_TEST(*a == 0);
+ BOOST_TEST(a == c);
+
+ // Check end iterator increment/decrement
+ --b; b--;
+ BOOST_TEST(*b == 254);
+ BOOST_TEST(a+254 == b);
+ ++b; b++;
+ BOOST_TEST(a+256 == b);
+
+ // Check order
+ a += 128;
+ BOOST_TEST(c < a);
+ BOOST_TEST(a < b);
+ BOOST_TEST(a > c);
+ BOOST_TEST(b > a);
+
+ // Check assignment
+ a = b;
+ BOOST_TEST(a == b);
+ a = c;
+ BOOST_TEST(a == c);
+
+ // Check weak order
+ BOOST_TEST(a <= c);
+ BOOST_TEST(a >= c);
+ BOOST_TEST(a <= b);
+ BOOST_TEST(!(a >= b));
+
+ // Check increment through end
+ a += 255;
+ BOOST_TEST(a != b);
+ ++a;
+ BOOST_TEST(a == b);
+ ++a;
+ BOOST_TEST(a != b);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+}
+
+typedef unsigned char character_t;
+typedef file_iterator<character_t,
+ fileiter_impl::std_file_iterator<character_t> > iter;
+BOOST_CLASS_REQUIRE(iter, boost, RandomAccessIteratorConcept);
+
+#ifdef BOOST_SPIRIT_FILEITERATOR_WINDOWS
+ typedef file_iterator<character_t,
+ fileiter_impl::mmap_file_iterator<character_t> > iterwin;
+ BOOST_CLASS_REQUIRE(iterwin, boost, RandomAccessIteratorConcept);
+#endif
+#ifdef BOOST_SPIRIT_FILEITERATOR_POSIX
+ typedef file_iterator<character_t,
+ fileiter_impl::mmap_file_iterator<character_t> > iterposix;
+ BOOST_CLASS_REQUIRE(iterposix, boost, RandomAccessIteratorConcept);
+#endif
+
+int main(void)
+{
+ if (!CreateTempFile())
+ {
+ cerr << "ERROR: Cannot create temporary file file_iter.tmp" << endl;
+ return 2;
+ }
+
+ cerr << "Testing standard iterator" << endl;
+ RunTest<iter>();
+
+#ifdef BOOST_SPIRIT_FILEITERATOR_WINDOWS
+ cerr << "Testing Windows iterator" << endl;
+ RunTest<iterwin>();
+#endif
+
+#ifdef BOOST_SPIRIT_FILEITERATOR_POSIX
+ cerr << "Testing POSIX iterator" << endl;
+ RunTest<iterposix>();
+#endif
+
+ // Check if the file handles were closed correctly
+ BOOST_TEST(remove(TMP_FILE) == 0);
+
+ return boost::report_errors();
+}
+
+#ifdef BOOST_NO_EXCEPTIONS
+
+namespace boost {
+ void throw_exception(std::exception const& e)
+ {
+ BOOST_EROR("throw_exception");
+ }
+}
+
+#endif
diff --git a/src/boost/libs/spirit/classic/test/fixed_size_queue_fail_tests.cpp b/src/boost/libs/spirit/classic/test/fixed_size_queue_fail_tests.cpp
new file mode 100644
index 00000000..aab7d61a
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/fixed_size_queue_fail_tests.cpp
@@ -0,0 +1,64 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Daniel Nuffer
+ Copyright (c) 2003 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_fixed_size_queue.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+
+typedef BOOST_SPIRIT_CLASSIC_NS::fixed_size_queue<int, 5> queue_t;
+typedef queue_t::iterator iter_t;
+typedef queue_t::const_iterator const_iter_t;
+BOOST_CLASS_REQUIRE(const_iter_t, boost, RandomAccessIteratorConcept);
+
+// Right now, the iterator is not a full compliant MutableRandomAccessIterator
+// because operator[] does not return a reference. This seems a problem in
+// boost::iterator_adaptors. Anyway, this feature is not used in multi_pass
+// iterator, and this class is not really meant for public use yet.
+BOOST_CLASS_REQUIRE(iter_t, boost, RandomAccessIteratorConcept);
+
+int main(int, char**)
+{
+ // Iterators are random access.
+ BOOST_MPL_ASSERT(( boost::is_same<
+ iter_t::iterator_category,
+ std::random_access_iterator_tag > ));
+ BOOST_MPL_ASSERT(( boost::is_same<
+ const_iter_t::iterator_category,
+ std::random_access_iterator_tag > ));
+
+ queue_t q;
+ const queue_t& cq = q;
+
+ iter_t b = q.begin();
+ const_iter_t c = cq.begin();
+
+// MSVC7.1 and EDG aren't able to compile this code for the new iterator
+// adaptors
+
+// The problem here is, that the old fixed_size_queue code wasn't a complete
+// and 'clean' iterator implementation, some of the required iterator concepts
+// were missing. It was never meant to be exposed outside the multi_pass. So I
+// haven't added any features while porting. The #ifdef'ed tests expose the
+// code weaknesses ((un-)fortunately only on conformant compilers, with a quite
+// good STL implementation). The simplest way to solve this issue was to switch
+// of the tests for these compilers then.
+
+// Check comparisons and interoperations (we are comparing
+// const and non-const iterators)
+
+ (void) c == b;
+ (void) c+4 > b;
+ (void) c < b+4;
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/fixed_size_queue_tests.cpp b/src/boost/libs/spirit/classic/test/fixed_size_queue_tests.cpp
new file mode 100644
index 00000000..e9077a73
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/fixed_size_queue_tests.cpp
@@ -0,0 +1,137 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Daniel Nuffer
+ Copyright (c) 2003 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_fixed_size_queue.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+
+typedef BOOST_SPIRIT_CLASSIC_NS::fixed_size_queue<int, 5> queue_t;
+typedef queue_t::iterator iter_t;
+typedef queue_t::const_iterator const_iter_t;
+BOOST_CLASS_REQUIRE(const_iter_t, boost, RandomAccessIteratorConcept);
+
+// Right now, the iterator is not a full compliant MutableRandomAccessIterator
+// because operator[] does not return a reference. This seems a problem in
+// boost::iterator_adaptors. Anyway, this feature is not used in multi_pass
+// iterator, and this class is not really meant for public use yet.
+BOOST_CLASS_REQUIRE(iter_t, boost, RandomAccessIteratorConcept);
+
+int main(int, char**)
+{
+ queue_t q;
+ const queue_t& cq = q;
+
+ q.push_back(1);
+ q.push_back(2);
+ q.push_back(3);
+ q.push_back(4);
+ BOOST_TEST(q.front() == 1);
+ q.pop_front();
+ BOOST_TEST(q.front() == 2);
+ q.pop_front();
+ BOOST_TEST(q.front() == 3);
+ q.pop_front();
+ BOOST_TEST(q.front() == 4);
+ q.pop_front();
+ q.push_back(5);
+ q.push_back(6);
+ q.push_back(7);
+ q.push_back(8);
+ BOOST_TEST(q.front() == 5);
+ q.pop_front();
+ BOOST_TEST(q.front() == 6);
+ q.pop_front();
+ BOOST_TEST(q.front() == 7);
+ q.pop_front();
+ BOOST_TEST(q.front() == 8);
+ q.pop_front();
+
+ q.push_front(5);
+ q.push_front(4);
+ q.push_front(3);
+ q.push_front(2);
+ q.push_front(1);
+
+ // NOTE: Iterator tests are not exhaustive and they are not meant to be so.
+
+ // Check iterator
+ iter_t b = q.begin();
+ BOOST_TEST(*b++ == 1);
+ BOOST_TEST(*b++ == 2);
+ BOOST_TEST(*b++ == 3);
+ BOOST_TEST(*b++ == 4);
+ BOOST_TEST(*b++ == 5);
+ BOOST_TEST(b == q.end());
+ BOOST_TEST(*--b == 5);
+ BOOST_TEST(*--b == 4);
+ BOOST_TEST(*--b == 3);
+ BOOST_TEST(*--b == 2);
+ BOOST_TEST(*--b == 1);
+ BOOST_TEST(b == q.begin());
+
+ // Check const_iterator
+ const_iter_t c = cq.begin();
+ BOOST_TEST(*c++ == 1);
+ BOOST_TEST(*c++ == 2);
+ BOOST_TEST(*c++ == 3);
+ BOOST_TEST(*c++ == 4);
+ BOOST_TEST(*c++ == 5);
+ BOOST_TEST(c == cq.end());
+ BOOST_TEST(*--c == 5);
+ BOOST_TEST(*--c == 4);
+ BOOST_TEST(*--c == 3);
+ BOOST_TEST(*--c == 2);
+ BOOST_TEST(*--c == 1);
+ BOOST_TEST(c == cq.begin());
+
+#if 0
+
+// Conforming compilers aren't able to compile this code for the new iterator
+// adaptors.
+
+// The problem here is, that the old fixed_size_queue code wasn't a complete
+// and 'clean' iterator implementation, some of the required iterator concepts
+// were missing. It was never meant to be exposed outside the multi_pass. So I
+// haven't added any features while porting. The #ifdef'ed tests expose the
+// code weaknesses ((un-)fortunately only on conformant compilers, with a quite
+// good STL implementation). The simplest way to solve this issue was to switch
+// of the tests for these compilers then.
+
+// $$$ This is isolated in fixed_size_queue_fail_tests.cpp [JDG 11-5-2003] $$$
+
+ // Iterators are random access.
+ BOOST_MPL_ASSERT(( boost::is_same<
+ iter_t::iterator_category,
+ std::random_access_iterator_tag > ));
+ BOOST_MPL_ASSERT(( boost::is_same<
+ const_iter_t::iterator_category,
+ std::random_access_iterator_tag > ));
+
+ // Check comparisons and interoperations (we are comparing
+ // const and non-const iterators)
+ BOOST_TEST(c == b);
+ BOOST_TEST(c+4 > b);
+ BOOST_TEST(c < b+4);
+
+#endif
+
+ // Check that you can actually modify the queue with an iterator
+ *b = 123;
+ BOOST_TEST(*c == 123);
+
+ // Check random access
+ BOOST_TEST(*((c+4)-4) == 123);
+ BOOST_TEST(*((c-4)+4) == 123);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/for_p_as_parser_tests.cpp b/src/boost/libs/spirit/classic/test/for_p_as_parser_tests.cpp
new file mode 100644
index 00000000..5d87f8de
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/for_p_as_parser_tests.cpp
@@ -0,0 +1,52 @@
+/*=============================================================================
+ Copyright (c) 2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_for.hpp>
+
+extern bool fun();
+
+struct ftor
+{
+ bool operator ()() const;
+};
+
+extern void init_fun();
+
+struct init_ftor
+{
+ void operator()() const;
+};
+
+extern void step_fun();
+
+struct step_ftor
+{
+ void operator()() const;
+};
+
+extern bool cmp_fun();
+
+struct cmp_ftor
+{
+ bool operator()() const;
+};
+
+int
+main()
+{
+ //////////////////////////////////
+ // compile time check wether as_parser<> works for for_p
+
+ ::BOOST_SPIRIT_CLASSIC_NS::rule<> r;
+
+ r = BOOST_SPIRIT_CLASSIC_NS::for_p(&init_fun, &cmp_fun, &step_fun)['-'];
+ r = BOOST_SPIRIT_CLASSIC_NS::for_p(init_ftor(), cmp_ftor(), step_ftor())["-"];
+
+ r = BOOST_SPIRIT_CLASSIC_NS::for_p(init_ftor(), r, step_ftor())[r];
+}
diff --git a/src/boost/libs/spirit/classic/test/for_tests.cpp b/src/boost/libs/spirit/classic/test/for_tests.cpp
new file mode 100644
index 00000000..5c20fe46
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/for_tests.cpp
@@ -0,0 +1,192 @@
+/*=============================================================================
+ Copyright (c) 2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+// vi:ts=4:sw=4:et
+// Tests for spirit::for_p
+// [13-Jan-2003]
+////////////////////////////////////////////////////////////////////////////////
+#include <iostream>
+#include <cstring>
+#include <string>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_assign_actor.hpp>
+#include <boost/spirit/include/classic_for.hpp>
+#include <boost/ref.hpp>
+#include "impl/string_length.hpp"
+
+namespace local
+{
+ template <typename T>
+ struct var_wrapper
+ : public ::boost::reference_wrapper<T>
+ {
+ typedef ::boost::reference_wrapper<T> parent;
+
+ explicit inline var_wrapper(T& t) : parent(t) {}
+
+ inline T& operator()() const { return parent::get(); }
+ };
+
+ template <typename T>
+ inline var_wrapper<T>
+ var(T& t)
+ {
+ return var_wrapper<T>(t);
+ }
+}
+
+namespace
+{
+ template <typename T>
+ class add_actor
+ {
+ public:
+ explicit add_actor(T &ref_) : ref(ref_) {}
+
+ template <typename T2>
+ void operator()(T2 const &val) const
+ { ref += val; }
+
+ private:
+ T& ref;
+ };
+
+ template <typename T>
+ inline add_actor<T> const
+ add(T& ref)
+ {
+ return add_actor<T>(ref);
+ }
+}
+
+typedef ::BOOST_SPIRIT_CLASSIC_NS::rule<> rule_t;
+
+unsigned int test_count = 0;
+unsigned int error_count = 0;
+
+unsigned int iterations_performed;
+unsigned int iterations_desired;
+std::string input_matched;
+
+//static const unsigned int kError = 999;
+static const bool good = true;
+static const bool bad = false;
+
+rule_t for_rule;
+rule_t for_rule2;
+
+void
+test_for
+(
+ char const *s,
+ bool succeed,
+ rule_t const &r,
+ unsigned int iterations_expected
+)
+{
+ using namespace std;
+
+ ++test_count;
+
+ iterations_performed = 0;
+
+ ::BOOST_SPIRIT_CLASSIC_NS::parse_info<> m = ::BOOST_SPIRIT_CLASSIC_NS::parse(s, s + test_impl::string_length(s), r);
+
+ bool result = (succeed==m.full)?good:bad;
+
+ if (m.full && (m.length != test_impl::string_length(s)))
+ result = bad;
+
+ result &= iterations_expected == iterations_performed;
+
+ if (result==good)
+ cout << "PASSED";
+ else
+ {
+ ++error_count;
+ cout << "FAILED";
+ }
+
+ cout << ": \"" << s << "\" ==> ";
+ if (!m.full)
+ cout << "<error>";
+ else
+ cout << '"' << input_matched << '"';
+
+ cout << " " << iterations_performed << " of "
+ << iterations_desired << " iterations\n";
+}
+
+namespace
+{
+ void zero() { iterations_performed = 0; }
+
+ struct inc
+ {
+ inline void operator()() const { ++iterations_performed; }
+ };
+ struct cmp
+ {
+ inline bool operator()() const
+ {
+ return iterations_performed<iterations_desired;
+ }
+ };
+}
+
+int
+main()
+{
+ using namespace std;
+
+ using BOOST_SPIRIT_CLASSIC_NS::uint_p;
+ using BOOST_SPIRIT_CLASSIC_NS::for_p;
+ using BOOST_SPIRIT_CLASSIC_NS::assign_a;
+
+#if qDebug
+ SPIRIT_DEBUG_RULE(for_rule);
+ SPIRIT_DEBUG_RULE(for_rule2);
+#endif
+
+ for_rule
+ = uint_p[assign_a(iterations_desired)] >> ':'
+ >> for_p(&zero, cmp(), inc())["xy"]
+ [assign_a(input_matched)]
+ ;
+
+ for_rule2
+ = for_p(&zero, '.', inc())["xy"]
+ [assign_a(input_matched)]
+ ;
+
+ cout << "/////////////////////////////////////////////////////////\n";
+ cout << "\n";
+ cout << " for_p test\n";
+ cout << "\n";
+ cout << "/////////////////////////////////////////////////////////\n";
+ cout << "\n";
+
+ test_for("3:xyxyxy", true, for_rule, 3);
+ test_for("3:", false, for_rule, 0);
+ test_for("3:xyxy", false, for_rule, 2);
+ test_for("3:xyxyxyxy", false, for_rule, 3);
+
+ test_for(".xy.xy.xy", true, for_rule2, 3);
+ test_for(".xy.xy.xy.", false, for_rule2, 3);
+
+ std::cout << "\n ";
+ if (error_count==0)
+ cout << "All " << test_count << " for_p-tests passed.\n"
+ << "Test concluded successfully\n";
+ else
+ cout << error_count << " of " << test_count << " for_p-tests failed\n"
+ << "Test failed\n";
+
+ return error_count!=0;
+}
+
diff --git a/src/boost/libs/spirit/classic/test/fundamental_tests.cpp b/src/boost/libs/spirit/classic/test/fundamental_tests.cpp
new file mode 100644
index 00000000..978d243a
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/fundamental_tests.cpp
@@ -0,0 +1,94 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// Fundamental meta sublayer tests
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include <boost/static_assert.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_meta.hpp>
+#include <boost/spirit/include/classic_assign_actor.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+typedef ref_value_actor<char, assign_action> assign_actor;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// node_count_tests
+//
+///////////////////////////////////////////////////////////////////////////////
+void
+node_count_tests()
+{
+// simple types
+ typedef chlit<char> plain_t;
+ typedef optional<chlit<char> > optional_t;
+ typedef action<chlit<char>, assign_actor> action_t;
+ typedef sequence<chlit<char>, anychar_parser> sequence_t;
+
+ BOOST_STATIC_ASSERT(1 == node_count<plain_t>::value);
+ BOOST_STATIC_ASSERT(2 == node_count<optional_t>::value);
+ BOOST_STATIC_ASSERT(2 == node_count<action_t>::value);
+ BOOST_STATIC_ASSERT(3 == node_count<sequence_t>::value);
+
+// more elaborate types
+ typedef sequence<sequence<plain_t, action_t>, plain_t> sequence2_t;
+ typedef sequence<plain_t, sequence<action_t, plain_t> > sequence3_t;
+
+ BOOST_STATIC_ASSERT(6 == node_count<sequence2_t>::value);
+ BOOST_STATIC_ASSERT(6 == node_count<sequence3_t>::value);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// leaf_count_tests
+//
+///////////////////////////////////////////////////////////////////////////////
+void
+leaf_count_tests()
+{
+// simple types
+ typedef chlit<char> plain_t;
+ typedef optional<chlit<char> > optional_t;
+ typedef action<chlit<char>, assign_actor> action_t;
+ typedef sequence<chlit<char>, anychar_parser> sequence_t;
+
+ BOOST_STATIC_ASSERT(1 == leaf_count<plain_t>::value);
+ BOOST_STATIC_ASSERT(1 == leaf_count<optional_t>::value);
+ BOOST_STATIC_ASSERT(1 == leaf_count<action_t>::value);
+ BOOST_STATIC_ASSERT(2 == leaf_count<sequence_t>::value);
+
+// more elaborate types
+ typedef sequence<sequence<plain_t, action_t>, plain_t> sequence2_t;
+ typedef sequence<plain_t, sequence<action_t, plain_t> > sequence3_t;
+
+ BOOST_STATIC_ASSERT(3 == leaf_count<sequence2_t>::value);
+ BOOST_STATIC_ASSERT(3 == leaf_count<sequence3_t>::value);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ node_count_tests();
+ leaf_count_tests();
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/grammar_def_test.cpp b/src/boost/libs/spirit/classic/test/grammar_def_test.cpp
new file mode 100644
index 00000000..20022f53
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/grammar_def_test.cpp
@@ -0,0 +1,85 @@
+//
+// Copyright (c) 2005 Joao Abecasis
+//
+// 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)
+//
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_attribute.hpp>
+#include <boost/spirit/include/classic_grammar_def.hpp>
+
+struct my_grammar1
+ : BOOST_SPIRIT_CLASSIC_NS::grammar<my_grammar1>
+{
+ template <typename Scanner>
+ struct definition
+ : BOOST_SPIRIT_CLASSIC_NS::grammar_def<
+ BOOST_SPIRIT_CLASSIC_NS::rule<Scanner>,
+ BOOST_SPIRIT_CLASSIC_NS::same
+ >
+ {
+ definition(my_grammar1 const &)
+ {
+ BOOST_SPIRIT_DEBUG_NODE(start_rule1);
+ BOOST_SPIRIT_DEBUG_NODE(start_rule2);
+
+ start_rule1 = BOOST_SPIRIT_CLASSIC_NS::str_p("int");
+ start_rule2 = BOOST_SPIRIT_CLASSIC_NS::int_p;
+
+ this->start_parsers(start_rule1, start_rule2);
+ }
+
+ BOOST_SPIRIT_CLASSIC_NS::rule<Scanner>
+ start_rule1,
+ start_rule2;
+ };
+};
+
+struct my_closure : BOOST_SPIRIT_CLASSIC_NS::closure<my_closure, int>
+{
+ member1 value;
+};
+
+struct my_grammar2
+ : BOOST_SPIRIT_CLASSIC_NS::grammar<my_grammar2, my_closure::context_t>
+{
+ template <typename Scanner>
+ struct definition
+ : BOOST_SPIRIT_CLASSIC_NS::grammar_def<
+ BOOST_SPIRIT_CLASSIC_NS::rule<Scanner>,
+ BOOST_SPIRIT_CLASSIC_NS::same
+ >
+ {
+ definition(my_grammar2 const &)
+ {
+ BOOST_SPIRIT_DEBUG_NODE(start_rule1);
+ BOOST_SPIRIT_DEBUG_NODE(start_rule2);
+
+ start_rule1 = BOOST_SPIRIT_CLASSIC_NS::str_p("int");
+ start_rule2 = BOOST_SPIRIT_CLASSIC_NS::int_p;
+
+ this->start_parsers(start_rule1, start_rule2);
+ }
+
+ BOOST_SPIRIT_CLASSIC_NS::rule<Scanner>
+ start_rule1,
+ start_rule2;
+ };
+};
+
+int main()
+{
+ my_grammar1 g1;
+ my_grammar2 g2;
+
+ BOOST_SPIRIT_DEBUG_NODE(g1);
+ BOOST_SPIRIT_DEBUG_NODE(g2);
+
+ parse(
+ "int 5",
+ g1.use_parser<0>() >> g2.use_parser<1>(),
+ BOOST_SPIRIT_CLASSIC_NS::space_p
+ );
+}
diff --git a/src/boost/libs/spirit/classic/test/grammar_mt_tests.cpp b/src/boost/libs/spirit/classic/test/grammar_mt_tests.cpp
new file mode 100644
index 00000000..59ea69e9
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/grammar_mt_tests.cpp
@@ -0,0 +1,318 @@
+/*=============================================================================
+ Copyright (c) 2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <boost/config.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined(DONT_HAVE_BOOST) || !defined(BOOST_HAS_THREADS) || defined(BOOST_DISABLE_THREADS)
+// we end here if we can't do multithreading
+static void skipped()
+{
+ std::cout << "skipped\n";
+}
+
+int
+main()
+{
+ skipped();
+ return 0;
+}
+
+#else
+// the real MT stuff
+
+#undef BOOST_SPIRIT_THREADSAFE
+#define BOOST_SPIRIT_THREADSAFE
+
+#include <boost/thread/thread.hpp>
+#include <boost/spirit/include/classic_grammar.hpp>
+#include <boost/spirit/include/classic_rule.hpp>
+#include <boost/spirit/include/classic_epsilon.hpp>
+#include <boost/thread/xtime.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/lock_types.hpp>
+#include <boost/ref.hpp>
+
+static boost::mutex simple_mutex;
+static int simple_definition_count = 0;
+
+struct simple : public BOOST_SPIRIT_CLASSIC_NS::grammar<simple>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(simple const& /*self*/)
+ {
+ top = BOOST_SPIRIT_CLASSIC_NS::epsilon_p;
+ boost::unique_lock<boost::mutex> lock(simple_mutex);
+ simple_definition_count++;
+ }
+
+ BOOST_SPIRIT_CLASSIC_NS::rule<ScannerT> top;
+ BOOST_SPIRIT_CLASSIC_NS::rule<ScannerT> const &start() const { return top; }
+ };
+};
+
+struct count_guard
+{
+ count_guard(int &c) : counter(c) {}
+ ~count_guard() { counter = 0; }
+private:
+ int &counter;
+};
+
+static void
+milli_sleep(unsigned long milliseconds)
+{
+ static long const nanoseconds_per_second = 1000L*1000L*1000L;
+ boost::xtime xt;
+ boost::xtime_get(&xt, boost::TIME_UTC_);
+ xt.nsec+=1000*1000*milliseconds;
+ while (xt.nsec > nanoseconds_per_second)
+ {
+ xt.nsec -= nanoseconds_per_second;
+ xt.sec++;
+ }
+
+ boost::thread::sleep(xt);
+}
+
+static void
+nap()
+{
+ // this function is called by various threads to ensure
+ // that thread lifetime actually overlap
+ milli_sleep(300);
+}
+
+template <typename GrammarT>
+static void
+make_definition(GrammarT &g)
+{
+ char const *text="blah";
+ BOOST_SPIRIT_CLASSIC_NS::scanner<> s(text, text+4);
+
+ g.parse(s);
+}
+
+template <typename GrammarT>
+static void
+make_definition3(GrammarT &g)
+{
+ char const *text="blah";
+ BOOST_SPIRIT_CLASSIC_NS::scanner<> s(text, text+4);
+
+ g.parse(s);
+ nap();
+ g.parse(s);
+ g.parse(s);
+}
+////////////////////////////////////////////////////////////////////////////////
+#define exactly_one_instance_created simple_definition_count == 1
+#define exactly_two_instances_created simple_definition_count == 2
+#define exactly_four_instances_created simple_definition_count == 4
+#define exactly_eight_instances_created simple_definition_count == 8
+
+////////////////////////////////////////////////////////////////////////////////
+static void
+multiple_attempts_to_instantiate_a_definition_from_a_single_thread()
+{
+ // checks wether exactly one definition per grammar
+ // object is created
+
+ count_guard guard(simple_definition_count);
+
+ simple simple1_p;
+ simple simple2_p;
+
+ make_definition(simple1_p);
+ make_definition(simple1_p);
+ make_definition(simple1_p);
+
+ BOOST_TEST(exactly_one_instance_created);
+
+ make_definition(simple2_p);
+ make_definition(simple2_p);
+ make_definition(simple2_p);
+
+ BOOST_TEST(exactly_two_instances_created);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+struct single_grammar_object_task
+{
+ void operator()() const
+ {
+ make_definition3(simple1_p);
+ };
+
+ simple simple1_p;
+};
+////////////////////////////////////////////////////////////////////////////////
+template <typename T>
+class callable_reference_wrapper
+ : public boost::reference_wrapper<T>
+{
+public:
+ explicit callable_reference_wrapper(T& t)
+ : boost::reference_wrapper<T>(t)
+ {}
+ inline void operator()() { this->get().operator()(); }
+};
+
+template <typename T>
+callable_reference_wrapper<T>
+callable_ref(T &t)
+{
+ return callable_reference_wrapper<T>(t);
+}
+////////////////////////////////////////////////////////////////////////////////
+static void
+single_local_grammar_object_multiple_threads()
+{
+ // check wether independent definition objects are
+ // created
+ count_guard guard(simple_definition_count);
+ single_grammar_object_task task1, task2, task3, task4;
+
+ boost::thread t1(callable_ref(task1));
+ boost::thread t2(callable_ref(task2));
+ boost::thread t3(callable_ref(task3));
+ boost::thread t4(callable_ref(task4));
+
+ t1.join();
+ t2.join();
+ t3.join();
+ t4.join();
+
+ BOOST_TEST(exactly_four_instances_created);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+struct two_grammar_objects_task
+{
+ void operator()() const
+ {
+ make_definition3(simple1_p);
+ make_definition3(simple2_p);
+ };
+
+ simple simple1_p;
+ simple simple2_p;
+};
+
+static void
+multiple_local_grammar_objects_multiple_threads()
+{
+ // check wether exactly one definition per thread
+ // and per grammar object is created
+ count_guard guard(simple_definition_count);
+ two_grammar_objects_task task1, task2, task3, task4;
+
+ boost::thread t1(callable_ref(task1));
+ boost::thread t2(callable_ref(task2));
+ boost::thread t3(callable_ref(task3));
+ boost::thread t4(callable_ref(task4));
+
+ t1.join();
+ t2.join();
+ t3.join();
+ t4.join();
+
+ BOOST_TEST(exactly_eight_instances_created);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+static simple global_simple1_p;
+
+struct single_global_grammar_object_task
+{
+ void operator()() const
+ {
+ make_definition3(global_simple1_p);
+ };
+};
+
+static void
+single_global_grammar_object_multiple_threads()
+{
+ // check wether exactly one definition per thread is
+ // created
+ count_guard guard(simple_definition_count);
+ single_global_grammar_object_task task1, task2, task3, task4;
+
+ boost::thread t1(callable_ref(task1));
+ boost::thread t2(callable_ref(task2));
+ boost::thread t3(callable_ref(task3));
+ boost::thread t4(callable_ref(task4));
+
+ t1.join();
+ t2.join();
+ t3.join();
+ t4.join();
+
+ BOOST_TEST(exactly_four_instances_created);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+static simple global_simple2_p;
+static simple global_simple3_p;
+
+struct multiple_global_grammar_objects_task
+{
+ void operator()() const
+ {
+ make_definition3(global_simple2_p);
+ make_definition3(global_simple3_p);
+ };
+};
+
+static void
+multiple_global_grammar_objects_multiple_threads()
+{
+ // check wether exactly one definition per thread
+ // and per grammar object is created
+ count_guard guard(simple_definition_count);
+ multiple_global_grammar_objects_task task1, task2, task3, task4;
+
+ boost::thread t1(callable_ref(task1));
+ boost::thread t2(callable_ref(task2));
+ boost::thread t3(callable_ref(task3));
+ boost::thread t4(callable_ref(task4));
+
+ t1.join();
+ t2.join();
+ t3.join();
+ t4.join();
+
+ BOOST_TEST(exactly_eight_instances_created);
+}
+////////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ multiple_attempts_to_instantiate_a_definition_from_a_single_thread();
+ single_local_grammar_object_multiple_threads();
+ multiple_local_grammar_objects_multiple_threads();
+ single_global_grammar_object_multiple_threads();
+ multiple_global_grammar_objects_multiple_threads();
+
+ return boost::report_errors();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+static BOOST_SPIRIT_CLASSIC_NS::parse_info<char const *> pi;
+
+////////////////////////////////////////////////
+// These macros are used with BOOST_TEST
+
+
+
+#endif // MT mode
diff --git a/src/boost/libs/spirit/classic/test/grammar_multi_instance_tst.cpp b/src/boost/libs/spirit/classic/test/grammar_multi_instance_tst.cpp
new file mode 100644
index 00000000..9ce05342
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/grammar_multi_instance_tst.cpp
@@ -0,0 +1,50 @@
+/*=============================================================================
+ Copyright (c) 2004 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace std;
+
+int g_count = 0;
+
+struct g : public grammar<g>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(g const& /*self*/)
+ {
+ g_count++;
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+};
+
+void
+grammar_tests()
+{
+ g my_g;
+ parse("", my_g);
+}
+
+int
+main()
+{
+ grammar_tests();
+ grammar_tests();
+ grammar_tests();
+ BOOST_TEST(g_count == 3);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/grammar_tests.cpp b/src/boost/libs/spirit/classic/test/grammar_tests.cpp
new file mode 100644
index 00000000..fb78ba33
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/grammar_tests.cpp
@@ -0,0 +1,157 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Joel de Guzman
+ Copyright (c) 2003 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+
+//#define BOOST_SPIRIT_DEBUG
+#define BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_grammar_def.hpp>
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+// This feature is disabled on non compliant compilers (e.g. Borland 5.5.1
+// VC6 and VC7)
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && \
+ !BOOST_WORKAROUND(__BORLANDC__, <= 0x551) && \
+ !BOOST_WORKAROUND(__GNUC__, < 3)
+# define BOOST_SPIRIT_USE_GRAMMARDEF
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// Grammar tests
+//
+///////////////////////////////////////////////////////////////////////////////
+struct num_list : public grammar<num_list>
+{
+ enum {
+ default_rule = 0,
+ num_rule = 1
+ };
+
+ template <typename ScannerT>
+ struct definition
+#if defined(BOOST_SPIRIT_USE_GRAMMARDEF)
+ : public grammar_def<rule<ScannerT>, same>
+#endif
+ {
+ definition(num_list const& /*self*/)
+ {
+ num = int_p;
+ r = num >> *(',' >> num);
+
+#if defined(BOOST_SPIRIT_USE_GRAMMARDEF)
+ this->start_parsers(r, num);
+#endif
+ BOOST_SPIRIT_DEBUG_RULE(num);
+ BOOST_SPIRIT_DEBUG_RULE(r);
+ }
+
+ rule<ScannerT> r, num;
+
+#if !defined(BOOST_SPIRIT_USE_GRAMMARDEF)
+ rule<ScannerT> const& start() const { return r; }
+#endif
+ };
+};
+
+struct num_list_ex : public grammar<num_list_ex>
+{
+ enum {
+ default_rule = 0,
+ num_rule = 1,
+ integer_rule = 2
+ };
+
+ template <typename ScannerT>
+ struct definition
+#if defined(BOOST_SPIRIT_USE_GRAMMARDEF)
+ : public grammar_def<rule<ScannerT>, same, int_parser<int, 10, 1, -1> >
+#endif
+ {
+ definition(num_list_ex const& /*self*/)
+ {
+ num = integer;
+ r = num >> *(',' >> num);
+
+#if defined(BOOST_SPIRIT_USE_GRAMMARDEF)
+ this->start_parsers(r, num, integer);
+#endif
+ BOOST_SPIRIT_DEBUG_RULE(num);
+ BOOST_SPIRIT_DEBUG_RULE(r);
+ }
+
+ rule<ScannerT> r, num;
+ int_parser<int, 10, 1, -1> integer;
+
+#if !defined(BOOST_SPIRIT_USE_GRAMMARDEF)
+ rule<ScannerT> const& start() const { return r; }
+#endif
+ };
+};
+
+void
+grammar_tests()
+{
+ num_list nlist;
+ BOOST_SPIRIT_DEBUG_GRAMMAR(nlist);
+
+ parse_info<char const*> pi;
+ pi = parse("123, 456, 789", nlist, space_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+#if defined(BOOST_SPIRIT_USE_GRAMMARDEF)
+ num_list_ex nlistex;
+ BOOST_SPIRIT_DEBUG_GRAMMAR(nlistex);
+
+ pi = parse("123, 456, 789", nlist.use_parser<num_list::default_rule>(),
+ space_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse("123", nlist.use_parser<num_list::num_rule>(), space_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse("123, 456, 789", nlistex, space_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse("123, 456, 789",
+ nlistex.use_parser<num_list_ex::default_rule>(), space_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse("123", nlistex.use_parser<num_list_ex::num_rule>(), space_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse("123", nlistex.use_parser<num_list_ex::integer_rule>(),
+ space_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+#endif // defined(BOOST_SPIRIT_USE_GRAMMARDEF)
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ grammar_tests();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/group_match_bug.cpp b/src/boost/libs/spirit/classic/test/group_match_bug.cpp
new file mode 100644
index 00000000..acc13a98
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/group_match_bug.cpp
@@ -0,0 +1,49 @@
+/*=============================================================================
+ Copyright (c) 2004 Joao Abecasis
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include <boost/spirit/include/classic_core.hpp>
+
+#include <boost/spirit/include/classic_closure.hpp>
+
+#include <boost/spirit/include/classic_ast.hpp>
+#include <boost/spirit/include/classic_parse_tree.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+struct test_closure : public closure<test_closure, int>
+{
+ member1 value;
+};
+
+struct test_grammar : public grammar<test_grammar>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(const test_grammar&)
+ {
+ }
+
+ rule<ScannerT, test_closure::context_t> const & start() const
+ {
+ return first;
+ }
+
+ rule<ScannerT, test_closure::context_t> first;
+ };
+};
+
+int main()
+{
+ parse("abcd", test_grammar());
+ pt_parse("abcd", test_grammar());
+ ast_parse("abcd", test_grammar());
+}
+
+
diff --git a/src/boost/libs/spirit/classic/test/if_p_as_parser_tests.cpp b/src/boost/libs/spirit/classic/test/if_p_as_parser_tests.cpp
new file mode 100644
index 00000000..5b20aa2e
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/if_p_as_parser_tests.cpp
@@ -0,0 +1,39 @@
+/*=============================================================================
+ Copyright (c) 2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_if.hpp>
+
+extern bool fun();
+
+struct ftor
+{
+ bool operator()() const;
+};
+
+int
+main()
+{
+ //////////////////////////////////
+ // compile time check wether as_parser<> works for if_p
+
+ ::BOOST_SPIRIT_CLASSIC_NS::rule<> r;
+
+ r = ::BOOST_SPIRIT_CLASSIC_NS::if_p('-')['-'];
+ r = ::BOOST_SPIRIT_CLASSIC_NS::if_p("-")["-"];
+ r = ::BOOST_SPIRIT_CLASSIC_NS::if_p('-')['-'].else_p['-'];
+ r = ::BOOST_SPIRIT_CLASSIC_NS::if_p("-")["-"].else_p["-"];
+
+ r = ::BOOST_SPIRIT_CLASSIC_NS::if_p(&fun)["foo"];
+ r = ::BOOST_SPIRIT_CLASSIC_NS::if_p(ftor())["foo"];
+ r = ::BOOST_SPIRIT_CLASSIC_NS::if_p(&fun)["foo"].else_p["bar"];
+ r = ::BOOST_SPIRIT_CLASSIC_NS::if_p(ftor())["foo"].else_p["bar"];
+
+ r = ::BOOST_SPIRIT_CLASSIC_NS::if_p(r)[r];
+ r = ::BOOST_SPIRIT_CLASSIC_NS::if_p(r)[r].else_p[r];
+}
diff --git a/src/boost/libs/spirit/classic/test/if_p_int_as_condition_test.cpp b/src/boost/libs/spirit/classic/test/if_p_int_as_condition_test.cpp
new file mode 100644
index 00000000..c14058d7
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/if_p_int_as_condition_test.cpp
@@ -0,0 +1,87 @@
+/*=============================================================================
+ Copyright (c) 2004 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_dynamic.hpp>
+#include <boost/spirit/include/classic_ast.hpp>
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+int the_var_to_be_tested = 0;
+
+namespace local
+{
+ template <typename T>
+ struct var_wrapper : public ::boost::reference_wrapper<T>
+ {
+ typedef ::boost::reference_wrapper<T> parent;
+
+ explicit inline var_wrapper(T& t) : parent(t) {}
+
+ inline T& operator()() const { return parent::get(); }
+ };
+
+ template <typename T>
+ inline var_wrapper<T>
+ var(T& t)
+ {
+ return var_wrapper<T>(t);
+ }
+}
+
+struct test_grammar : public grammar <test_grammar>
+{
+ template <typename ScannerT>
+
+ struct definition
+ {
+ rule <ScannerT, parser_tag <0> > test;
+
+ definition(const test_grammar& /*self*/)
+ {
+ test
+ = if_p(local::var(the_var_to_be_tested))
+ [
+ real_p
+ ];
+
+ }
+ const rule <ScannerT, parser_tag<0> >& start() const {return test;}
+ };
+};
+
+int main()
+{
+ test_grammar gram;
+ tree_parse_info <const char*> result;
+
+ //predictably fails
+ the_var_to_be_tested = 0;
+ result = ast_parse("1.50", gram, space_p);
+ std::cout << "Testing if_p against: " << the_var_to_be_tested << std::endl;
+ std::cout << "success: " << result.full << std::endl;
+ BOOST_TEST(!result.full);
+
+ //predicatably succeeds
+ the_var_to_be_tested = 1;
+ result = ast_parse("1.50", gram, space_p);
+ std::cout << "Testing if_p against: " << the_var_to_be_tested << std::endl;
+ std::cout << "success: " << result.full << std::endl;
+ BOOST_TEST(result.full);
+
+ //should succeed
+ the_var_to_be_tested = 2;
+ result = ast_parse("1.50", gram, space_p);
+ std::cout << "Testing if_p against: " << the_var_to_be_tested << std::endl;
+ std::cout << "success: " << result.full << std::endl;
+ BOOST_TEST(result.full);
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/if_tests.cpp b/src/boost/libs/spirit/classic/test/if_tests.cpp
new file mode 100644
index 00000000..bfbc9d5f
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/if_tests.cpp
@@ -0,0 +1,250 @@
+/*=============================================================================
+ Copyright (c) 2004 Stefan Slapeta
+ Copyright (c) 2002-2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+// vi:ts=4:sw=4:et
+// Tests for BOOST_SPIRIT_CLASSIC_NS::if_p
+// [28-Dec-2002]
+////////////////////////////////////////////////////////////////////////////////
+#include <iostream>
+#include <cstring>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_if.hpp>
+#include <boost/spirit/include/classic_assign_actor.hpp>
+#include <boost/ref.hpp>
+#include "impl/string_length.hpp"
+
+namespace local
+{
+ template <typename T>
+ struct var_wrapper
+ : public ::boost::reference_wrapper<T>
+ {
+ typedef ::boost::reference_wrapper<T> parent;
+
+ explicit inline var_wrapper(T& t) : parent(t) {}
+
+ inline T& operator()() const { return parent::get(); }
+ };
+
+ template <typename T>
+ inline var_wrapper<T>
+ var(T& t)
+ {
+ return var_wrapper<T>(t);
+ }
+}
+
+typedef ::BOOST_SPIRIT_CLASSIC_NS::rule<> rule_t;
+typedef ::BOOST_SPIRIT_CLASSIC_NS::rule<BOOST_SPIRIT_CLASSIC_NS::no_actions_scanner<>::type >
+ no_actions_rule_t;
+
+unsigned int test_count = 0;
+unsigned int error_count = 0;
+
+unsigned int number_result;
+static const unsigned int kError = 999;
+static const bool good = true;
+static const bool bad = false;
+
+rule_t hex_prefix;
+no_actions_rule_t oct_prefix;
+rule_t hex_rule, oct_rule, dec_rule;
+
+rule_t auto_number_rule;
+rule_t hex_or_dec_number_rule;
+
+void
+test_number(char const *s, unsigned int wanted, rule_t const &r)
+{
+ using namespace std;
+
+ ++test_count;
+
+ number_result = wanted-1;
+ ::BOOST_SPIRIT_CLASSIC_NS::parse_info<> m = ::BOOST_SPIRIT_CLASSIC_NS::parse(s, s + test_impl::string_length(s), r);
+
+ bool result = wanted == kError?(m.full?bad:good): (number_result==wanted);
+
+ if (m.full && (m.length != test_impl::string_length(s)))
+ result = bad;
+
+
+ if (result==good)
+ cout << "PASSED";
+ else
+ {
+ ++error_count;
+ cout << "FAILED";
+ }
+
+ cout << ": \"" << s << "\" ==> ";
+ if (number_result==wanted-1)
+ cout << "<error>";
+ else
+ cout << number_result;
+
+ cout << "\n";
+}
+
+void
+test_enclosed_fail()
+{
+ using namespace std;
+
+ using ::BOOST_SPIRIT_CLASSIC_NS::if_p;
+ using ::BOOST_SPIRIT_CLASSIC_NS::str_p;
+ using ::BOOST_SPIRIT_CLASSIC_NS::nothing_p;
+
+ cout << "\nfail enclosed parser:\n";
+
+ const char *p = "abc";
+
+ ::BOOST_SPIRIT_CLASSIC_NS::strlit<const char*> success_p = str_p(p);
+ ::BOOST_SPIRIT_CLASSIC_NS::strlit<const char*> fail_p = str_p("xxx");
+
+ ::BOOST_SPIRIT_CLASSIC_NS::rule<> r = if_p(success_p)[nothing_p];
+
+ ::BOOST_SPIRIT_CLASSIC_NS::parse_info<> m = ::BOOST_SPIRIT_CLASSIC_NS::parse(p, r);
+
+ if (m.full) {
+ cout << "FAILED: if --> match" << endl;
+ ++error_count;
+ } else {
+ cout << "PASSED: if --> no_match" << endl;
+ }
+
+ r = if_p(fail_p)[success_p].else_p[nothing_p];
+
+ m = ::BOOST_SPIRIT_CLASSIC_NS::parse(p, r);
+
+ if (m.full) {
+ cout << "FAILED: else --> match" << endl;
+ ++error_count;
+ } else {
+ cout << "PASSED: else --> no_match" << endl;
+ }
+}
+
+int
+main()
+{
+ using namespace std;
+ using ::BOOST_SPIRIT_CLASSIC_NS::if_p;
+ using ::BOOST_SPIRIT_CLASSIC_NS::uint_p;
+ using ::BOOST_SPIRIT_CLASSIC_NS::oct_p;
+ using ::BOOST_SPIRIT_CLASSIC_NS::hex_p;
+ using ::BOOST_SPIRIT_CLASSIC_NS::str_p;
+ using ::BOOST_SPIRIT_CLASSIC_NS::ch_p;
+ using ::BOOST_SPIRIT_CLASSIC_NS::assign_a;
+
+ cout << "/////////////////////////////////////////////////////////\n";
+ cout << "\n";
+ cout << " if_p test\n";
+ cout << "\n";
+ cout << "/////////////////////////////////////////////////////////\n";
+ cout << "\n";
+
+ bool as_hex;
+
+#if qDebug
+ BOOST_SPIRIT_DEBUG_RULE(hex_prefix);
+ BOOST_SPIRIT_DEBUG_RULE(hex_rule);
+ BOOST_SPIRIT_DEBUG_RULE(oct_prefix);
+ BOOST_SPIRIT_DEBUG_RULE(oct_rule);
+ BOOST_SPIRIT_DEBUG_RULE(dec_rule);
+ BOOST_SPIRIT_DEBUG_RULE(auto_number_rule);
+ BOOST_SPIRIT_DEBUG_RULE(hex_or_dec_number_rule);
+#endif
+
+ hex_prefix = str_p("0x");
+ oct_prefix = ch_p('0');
+
+ hex_rule = hex_p[assign_a(number_result)];
+ oct_rule = oct_p[assign_a(number_result)];
+ dec_rule = uint_p[assign_a(number_result)];
+
+ auto_number_rule =
+ if_p(hex_prefix)
+ [hex_rule]
+ .else_p
+ [
+ if_p(::BOOST_SPIRIT_CLASSIC_NS::eps_p(oct_prefix))
+ [oct_rule]
+ .else_p
+ [dec_rule]
+ ];
+
+ hex_or_dec_number_rule =
+ if_p(local::var(as_hex))[hex_prefix>>hex_rule].else_p[dec_rule];
+
+ cout << "auto:\n";
+ test_number("", kError, auto_number_rule);
+ test_number("0", 0, auto_number_rule);
+ test_number("1", 1, auto_number_rule);
+ test_number("00", 0, auto_number_rule);
+ test_number("0x", kError, auto_number_rule);
+ test_number("0x0", 0, auto_number_rule);
+ test_number("0755", 493, auto_number_rule);
+ test_number("0x100", 256, auto_number_rule);
+
+ cout << "\ndecimal:\n";
+ as_hex = false;
+ test_number("", kError, hex_or_dec_number_rule);
+ test_number("100", 100, hex_or_dec_number_rule);
+ test_number("0x100", kError, hex_or_dec_number_rule);
+ test_number("0xff", kError, hex_or_dec_number_rule);
+
+ cout << "\nhexadecimal:\n";
+ as_hex = true;
+ test_number("", kError, hex_or_dec_number_rule);
+ test_number("0x100", 256, hex_or_dec_number_rule);
+ test_number("0xff", 255, hex_or_dec_number_rule);
+
+ //////////////////////////////////
+ // tests for if_p without else-parser
+ cout << "\nno-else:\n";
+ rule_t r = if_p(::BOOST_SPIRIT_CLASSIC_NS::eps_p('0'))[oct_rule];
+
+ test_number("0", 0, r);
+
+ ++test_count;
+ ::BOOST_SPIRIT_CLASSIC_NS::parse_info<> m = ::BOOST_SPIRIT_CLASSIC_NS::parse("", r);
+ if (!m.hit || !m.full || m.length!=0)
+ {
+ std::cout << "FAILED: \"\" ==> <error>\n";
+ ++error_count;
+ }
+ else
+ std::cout << "PASSED: \"\" ==> <empty match>\n";
+
+ ++test_count;
+ m = ::BOOST_SPIRIT_CLASSIC_NS::parse("junk", r);
+ if (!m.hit || m.full || m.length!=0)
+ {
+ std::cout << "FAILED: \"junk\" ==> <error>\n";
+ ++error_count;
+ }
+ else
+ std::cout << "PASSED: \"junk\" ==> <empty match>\n";
+
+ test_enclosed_fail();
+
+
+ //////////////////////////////////
+ // report results
+ std::cout << "\n ";
+ if (error_count==0)
+ cout << "All " << test_count << " if_p-tests passed.\n"
+ << "Test concluded successfully\n";
+ else
+ cout << error_count << " of " << test_count << " if_p-tests failed\n"
+ << "Test failed\n";
+
+ return error_count!=0;
+}
diff --git a/src/boost/libs/spirit/classic/test/impl/sstream.hpp b/src/boost/libs/spirit/classic/test/impl/sstream.hpp
new file mode 100644
index 00000000..bb94cb9c
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/impl/sstream.hpp
@@ -0,0 +1,46 @@
+/*=============================================================================
+ Copyright (c) 2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/config.hpp>
+
+///////////////////////////////////////////////////////////////////////////
+// workaround for prestandard support of stringstreams
+//
+// * defines sstream_t for the string stream type
+// * defines std::string getstring(sstream_t &);
+//
+
+#ifdef BOOST_NO_STRINGSTREAM
+# include <strstream>
+ typedef strstream sstream_t;
+ std::string
+ getstring(std::strstream& ss)
+ {
+ ss << ends;
+ std::string rval = ss.str();
+ ss.freeze(false);
+ return rval;
+ }
+#else
+# include <sstream>
+ typedef std::stringstream sstream_t;
+ std::string
+ getstring(std::stringstream &ss)
+ {
+ return ss.str();
+ }
+#endif
+
+void use_getstring_to_avoid_compiler_warnings_about_unused_functions()
+{
+ sstream_t ss;
+ getstring(ss);
+ if(!ss) { // to be not recursive on all control paths
+ use_getstring_to_avoid_compiler_warnings_about_unused_functions();
+ }
+}
diff --git a/src/boost/libs/spirit/classic/test/impl/string_length.hpp b/src/boost/libs/spirit/classic/test/impl/string_length.hpp
new file mode 100644
index 00000000..f55c4bbf
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/impl/string_length.hpp
@@ -0,0 +1,30 @@
+/*=============================================================================
+ Copyright (c) 2004 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#if !defined(SPIRIT_TEST_IMPL_STRING_LEN_HPP)
+#define SPIRIT_TEST_IMPL_STRING_LEN_HPP
+
+// We use our own string_len function instead of std::strlen
+// to avoid the namespace confusion on different compilers. Some
+// have it in namespace std. Some have it in global namespace.
+// Some have it in both.
+namespace test_impl
+{
+ template <typename Char>
+ inline unsigned int
+ string_length(Char const* str)
+ {
+ unsigned int len = 0;
+ while (*str++)
+ ++len;
+ return len;
+ }
+}
+
+#endif
+
diff --git a/src/boost/libs/spirit/classic/test/impl/var.hpp b/src/boost/libs/spirit/classic/test/impl/var.hpp
new file mode 100644
index 00000000..d2019452
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/impl/var.hpp
@@ -0,0 +1,34 @@
+/*=============================================================================
+ Copyright (c) 2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#ifndef BOOST_SPIRIT_TEST_IMPL_VAR_HPP
+#define BOOST_SPIRIT_TEST_IMPL_VAR_HPP
+
+#include <boost/ref.hpp>
+
+namespace test
+{
+ template <typename T>
+ struct var_wrapper
+ : public ::boost::reference_wrapper<T>
+ {
+ typedef ::boost::reference_wrapper<T> parent;
+
+ explicit inline var_wrapper(T& t) : parent(t) {}
+
+ inline T& operator()() const { return parent::get(); }
+ };
+
+ template <typename T>
+ inline var_wrapper<T>
+ var(T& t)
+ {
+ return var_wrapper<T>(t);
+ }
+}
+#endif // BOOST_SPIRIT_TEST_IMPL_VAR_HPP
diff --git a/src/boost/libs/spirit/classic/test/lazy_tests.cpp b/src/boost/libs/spirit/classic/test/lazy_tests.cpp
new file mode 100644
index 00000000..47485c2f
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/lazy_tests.cpp
@@ -0,0 +1,27 @@
+/*=============================================================================
+ Copyright (c) 2003 Vaclav Vesely
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_assign_actor.hpp>
+#include <boost/spirit/include/classic_lazy.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_operators.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace boost;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace phoenix;
+
+int main()
+{
+ int result;
+ BOOST_TEST(parse("123", lazy_p(val(int_p))[assign_a(result)]).full);
+ BOOST_TEST((result == 123));
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/loops_tests.cpp b/src/boost/libs/spirit/classic/test/loops_tests.cpp
new file mode 100644
index 00000000..2a97f311
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/loops_tests.cpp
@@ -0,0 +1,118 @@
+/*=============================================================================
+ Copyright (c) 1998-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_loops.hpp>
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Loops tests
+//
+///////////////////////////////////////////////////////////////////////////////
+void
+loops_tests()
+{
+ parse_info<char const*> pi;
+
+ pi = parse("\"Hello World\"", "\"" >> *(anychar_p - "\"") >> "\"");
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 13);
+ BOOST_TEST(*pi.stop == 0);
+
+ pi = parse("\"Hello World\"", "\"" >> repeat_p(0, more)[anychar_p - "\""] >> "\"");
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 13);
+ BOOST_TEST(*pi.stop == 0);
+
+ pi = parse("xx", +ch_p('x'));
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 2);
+ BOOST_TEST(*pi.stop == 0);
+
+ pi = parse("xx", repeat_p(1, more)[ch_p('x')]);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 2);
+ BOOST_TEST(*pi.stop == 0);
+
+ pi = parse("", +ch_p('x'));
+ BOOST_TEST(!pi.hit);
+
+ pi = parse("", repeat_p(1, more)[ch_p('x')]);
+ BOOST_TEST(!pi.hit);
+
+ pi = parse("", *ch_p('x'));
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 0);
+ BOOST_TEST(*pi.stop == 0);
+
+ pi = parse("", repeat_p(0, more)[ch_p('x')]);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 0);
+ BOOST_TEST(*pi.stop == 0);
+
+ // repeat exact 8
+ rule<> rep8 = repeat_p(8)[alpha_p] >> 'X';
+ BOOST_TEST(!parse("abcdefgX", rep8).hit);
+ BOOST_TEST(parse("abcdefghX", rep8).full);
+ BOOST_TEST(!parse("abcdefghiX", rep8).hit);
+ BOOST_TEST(!parse("abcdefgX", rep8).hit);
+ BOOST_TEST(!parse("aX", rep8).hit);
+
+ // repeat 2 to 8
+ rule<> rep28 = repeat_p(2, 8)[alpha_p] >> '*';
+ BOOST_TEST(parse("abcdefg*", rep28).full);
+ BOOST_TEST(parse("abcdefgh*", rep28).full);
+ BOOST_TEST(!parse("abcdefghi*", rep28).hit);
+ BOOST_TEST(!parse("a*", rep28).hit);
+
+ // repeat 2 or more
+ rule<> rep2_ = repeat_p(2, more)[alpha_p] >> '+';
+ BOOST_TEST(parse("abcdefg+", rep2_).full);
+ BOOST_TEST(parse("abcdefgh+", rep2_).full);
+ BOOST_TEST(parse("abcdefghi+", rep2_).full);
+ BOOST_TEST(parse("abcdefg+", rep2_).full);
+ BOOST_TEST(!parse("a+", rep2_).hit);
+
+ // repeat 0
+ rule<> rep0 = repeat_p(0)[alpha_p] >> '/';
+ BOOST_TEST(parse("/", rep0).full);
+ BOOST_TEST(!parse("a/", rep0).hit);
+
+ // repeat 0 or 1
+ rule<> rep01 = repeat_p(0, 1)[alpha_p >> digit_p] >> '?';
+ BOOST_TEST(!parse("abcdefg?", rep01).hit);
+ BOOST_TEST(!parse("a?", rep01).hit);
+ BOOST_TEST(!parse("1?", rep01).hit);
+ BOOST_TEST(!parse("11?", rep01).hit);
+ BOOST_TEST(!parse("aa?", rep01).hit);
+ BOOST_TEST(parse("?", rep01).full);
+ BOOST_TEST(parse("a1?", rep01).full);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ loops_tests();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/match_tests.cpp b/src/boost/libs/spirit/classic/test/match_tests.cpp
new file mode 100644
index 00000000..bc919bbe
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/match_tests.cpp
@@ -0,0 +1,175 @@
+/*=============================================================================
+ Copyright (c) 1998-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+#include <string>
+
+using namespace std;
+
+#include <boost/spirit/include/classic_core.hpp>
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Match tests
+//
+///////////////////////////////////////////////////////////////////////////////
+struct X {};
+struct Y { Y(int) {} }; // not default constructible
+struct Z { Z(double n):n(n){} double n; }; // implicitly convertible from double
+
+void
+match_tests()
+{
+ match<> m0;
+ BOOST_TEST(!m0.has_valid_attribute());
+
+ match<int> m1(m0);
+ m1.value(123);
+ BOOST_TEST(m1.has_valid_attribute());
+ BOOST_TEST(m1.value() == 123);
+
+ match<double> m2(m1);
+ BOOST_TEST(m2.has_valid_attribute());
+ BOOST_TEST(m1.value() == int(m2.value()));
+ m2.value(456);
+
+ *&m0 = m0; // match<nil> = match<nil>
+ m0 = m1; // match<nil> = match<int>
+ m0 = m2; // match<nil> = match<double>
+ m1 = m0; // match<int> = match<nil>
+ BOOST_TEST(!m1);
+ BOOST_TEST(!m1.has_valid_attribute());
+
+ *&m1 = m1; // match<int> = match<int>
+ m1.value(int(m2.value()));
+ BOOST_TEST(m1.has_valid_attribute());
+ BOOST_TEST(m1.value() == int(m2.value()));
+
+ m2.value(123.456);
+ match<Z> mz(m2); // copy from match<double>
+ mz = m2; // assign from match<double>
+ BOOST_TEST(mz.value().n == 123.456);
+
+ m1.value(123);
+ m2 = m0;
+ BOOST_TEST(!m2);
+ BOOST_TEST(!m2.has_valid_attribute());
+
+ m2 = m1; // match<double> = match<int>
+ BOOST_TEST(m2.has_valid_attribute());
+ BOOST_TEST(m1.value() == int(m2.value()));
+ *&m2 = m2; // match<double> = match<double>
+
+ cout << "sizeof(int) == " << sizeof(int) << '\n';
+ cout << "sizeof(match<>) == " << sizeof(m0) << '\n';
+ cout << "sizeof(match<int>) == " << sizeof(m1) << '\n';
+ cout << "sizeof(match<double>) == " << sizeof(m2) << '\n';
+
+ match<int&> mr;
+ BOOST_TEST(!mr.has_valid_attribute());
+
+ match<int&> mrr(4);
+ BOOST_TEST(!mrr.has_valid_attribute());
+
+ int ri = 3;
+ match<int&> mr2(4, ri);
+ BOOST_TEST(mr2.has_valid_attribute());
+ mr = mr2;
+ BOOST_TEST(mr.has_valid_attribute());
+
+ match<int&> mr3(mrr);
+ BOOST_TEST(!mr3.has_valid_attribute());
+ mr2 = mr3;
+ BOOST_TEST(!mr2.has_valid_attribute());
+
+ match<X> mx;
+ m1 = mx;
+ m0 = mx;
+ BOOST_TEST(!mx.has_valid_attribute());
+ BOOST_TEST(!m0.has_valid_attribute());
+ BOOST_TEST(!m1.has_valid_attribute());
+
+ match<Y> my;
+ BOOST_TEST(!my.has_valid_attribute());
+
+ match<std::string> ms;
+ BOOST_TEST(!ms.has_valid_attribute());
+ ms.value("Kimpo Ponchwayla");
+ BOOST_TEST(ms.has_valid_attribute());
+ BOOST_TEST(ms.value() == "Kimpo Ponchwayla");
+ ms = match<>();
+ BOOST_TEST(!ms.has_valid_attribute());
+
+ // let's try a match with a reference:
+ int i;
+ match<int&> mr4(4, i);
+ BOOST_TEST(mr4.has_valid_attribute());
+ mr4.value(3);
+ BOOST_TEST(mr4.value() == 3);
+ BOOST_TEST(i == 3);
+ (void)i;
+
+ int x = 456;
+ match<int&> mref(1, x);
+ BOOST_TEST(mref.value() == 456);
+ mref.value(123);
+ BOOST_TEST(mref.value() == 123);
+ x = mref.value();
+ BOOST_TEST(x == 123);
+ mref.value() = 986;
+ BOOST_TEST(x == 986);
+
+ std::string s("hello");
+ match<int> mint(1, x);
+ BOOST_TEST(mint.value() == x);
+ match<std::string> mstr(1, s);
+ BOOST_TEST(mstr.value() == "hello");
+ mstr = mint;
+ mint = mstr;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Match Policy tests
+//
+///////////////////////////////////////////////////////////////////////////////
+void
+match_policy_tests()
+{
+ match<> m0;
+ match<int> m1;
+ match<double> m2;
+ match_policy mp;
+
+ m0 = mp.no_match(); BOOST_TEST(!m0);
+ m1 = mp.no_match(); BOOST_TEST(!m1);
+ m0 = mp.empty_match(); BOOST_TEST(!!m0);
+ m2 = mp.empty_match(); BOOST_TEST(!!m2);
+
+ m1 = mp.create_match(5, 100, 0, 0);
+ m2 = mp.create_match(5, 10.5, 0, 0);
+
+ mp.concat_match(m1, m2);
+ BOOST_TEST(m1.length() == 10);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ match_tests();
+ match_policy_tests();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/mix_and_match_trees.cpp b/src/boost/libs/spirit/classic/test/mix_and_match_trees.cpp
new file mode 100644
index 00000000..f489e181
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/mix_and_match_trees.cpp
@@ -0,0 +1,82 @@
+//
+// Copyright (c) 2006 Joao Abecasis
+//
+// 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)
+//
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// As reported by Jascha Wetzel, in
+// http://article.gmane.org/gmane.comp.parsers.spirit.general/9013, the
+// directives gen_ast_node_d and gen_pt_node_d were not working for lack of
+// appropriate conversion constructors in the underlying tree match policies.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_ast.hpp>
+#include <boost/spirit/include/classic_parse_tree.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+struct my_grammar : grammar<my_grammar>
+{
+ template <class Scanner>
+ struct definition
+ {
+ typedef
+ scanner<
+ typename Scanner::iterator_t,
+ scanner_policies<
+ typename Scanner::iteration_policy_t,
+ ast_match_policy<
+ typename Scanner::match_policy_t::iterator_t,
+ typename Scanner::match_policy_t::factory_t
+ >,
+ typename Scanner::action_policy_t
+ >
+ > ast_scanner;
+
+ typedef
+ scanner<
+ typename Scanner::iterator_t,
+ scanner_policies<
+ typename Scanner::iteration_policy_t,
+ pt_match_policy<
+ typename Scanner::match_policy_t::iterator_t,
+ typename Scanner::match_policy_t::factory_t
+ >,
+ typename Scanner::action_policy_t
+ >
+ > pt_scanner;
+
+ typedef rule<ast_scanner> ast_rule;
+ typedef rule<pt_scanner> pt_rule;
+ typedef rule<Scanner> rule_;
+
+ definition(my_grammar const & /* self */)
+ {
+ start_ = gen_ast_node_d[ ast_rule_ ];
+ start_ = gen_pt_node_d[ pt_rule_ ];
+ }
+
+ rule_ const & start() const
+ {
+ return start_;
+ }
+
+ rule_ start_;
+ ast_rule ast_rule_;
+ pt_rule pt_rule_;
+ };
+};
+
+int main()
+{
+ const char * begin = NULL, * end = NULL;
+
+ pt_parse(begin, end, my_grammar());
+ ast_parse(begin, end, my_grammar());
+}
diff --git a/src/boost/libs/spirit/classic/test/multi_pass_compile_tests.cpp b/src/boost/libs/spirit/classic/test/multi_pass_compile_tests.cpp
new file mode 100644
index 00000000..eebab917
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/multi_pass_compile_tests.cpp
@@ -0,0 +1,61 @@
+/*=============================================================================
+ Copyright (c) 2004 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+// This is a compile only test for verifying, whether the multi_pass<>
+// iterator works ok with an input iterator, which returns a value_type and not
+// a reference from its dereferencing operator.
+
+#include <cstdio>
+#include <fstream>
+#include <iterator>
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_multi_pass.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace std;
+
+int main ()
+{
+ // create a sample file
+ {
+ ofstream out("./input_file.txt");
+ out << 1.0 << "," << 2.0;
+ }
+
+ int result = 0;
+
+ // read in the values from the sample file
+ {
+ ifstream in("./input_file.txt"); // we get our input from this file
+
+ typedef char char_t;
+ typedef multi_pass<istreambuf_iterator<char_t> > iterator_t;
+
+ typedef skip_parser_iteration_policy<space_parser> it_policy_t;
+ typedef scanner_policies<it_policy_t> scan_policies_t;
+ typedef scanner<iterator_t, scan_policies_t> scanner_t;
+
+ typedef rule<scanner_t> rule_t;
+
+ it_policy_t iter_policy(space_p);
+ scan_policies_t policies(iter_policy);
+ iterator_t first(make_multi_pass(std::istreambuf_iterator<char_t>(in)));
+ scanner_t scan(first, make_multi_pass(std::istreambuf_iterator<char_t>()),
+ policies);
+
+ rule_t n_list = real_p >> *(',' >> real_p);
+ match<> m = n_list.parse(scan);
+
+ result = !m ? 1 : 0;
+ }
+
+ std::remove("./input_file.txt");
+ return result;
+}
diff --git a/src/boost/libs/spirit/classic/test/multi_pass_tests.cpp b/src/boost/libs/spirit/classic/test/multi_pass_tests.cpp
new file mode 100644
index 00000000..2dcf2e56
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/multi_pass_tests.cpp
@@ -0,0 +1,765 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Daniel Nuffer
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_multi_pass.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <iterator>
+#include <string>
+#include <boost/detail/lightweight_test.hpp>
+#include "impl/sstream.hpp"
+
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+sstream_t res;
+
+typedef multi_pass<istream_iterator<char> > default_multi_pass_t;
+
+typedef look_ahead<istream_iterator<char>, 6> fixed_multi_pass_t;
+
+typedef multi_pass<
+ istream_iterator<char>,
+ multi_pass_policies::input_iterator,
+ multi_pass_policies::first_owner,
+ multi_pass_policies::buf_id_check,
+ multi_pass_policies::std_deque
+> first_owner_multi_pass_t;
+
+
+// a functor to test out the functor_multi_pass
+class my_functor
+{
+ public:
+ typedef char result_type;
+ my_functor()
+ : c('A')
+ {}
+
+ char operator()()
+ {
+ if (c == 'M')
+ return eof;
+ else
+ return c++;
+ }
+
+ static result_type eof;
+ private:
+ char c;
+};
+
+my_functor::result_type my_functor::eof = '\0';
+
+typedef multi_pass<
+ my_functor,
+ multi_pass_policies::functor_input,
+ multi_pass_policies::first_owner,
+ multi_pass_policies::no_check,
+ multi_pass_policies::std_deque
+> functor_multi_pass_t;
+
+void test_default_multi_pass()
+{
+ res << "-*= test_default_multi_pass =*-\n";
+ istream_iterator<char> end;
+ boost::scoped_ptr<default_multi_pass_t> mpend(new default_multi_pass_t(end));
+
+ {
+ sstream_t ss;
+ ss << "test string";
+
+ istream_iterator<char> a(ss);
+ boost::scoped_ptr<default_multi_pass_t> mp1(new default_multi_pass_t(a));
+
+ while (*mp1 != *mpend)
+ {
+ res << *((*mp1)++);
+ }
+
+ res << endl;
+ }
+
+ {
+ sstream_t ss;
+ ss << "test string";
+ istream_iterator<char> b(ss);
+ boost::scoped_ptr<default_multi_pass_t> mp2(new default_multi_pass_t(b));
+ boost::scoped_ptr<default_multi_pass_t> mp3(new default_multi_pass_t(b));
+ *mp3 = *mp2;
+
+ for (int i = 0; i < 4; ++i)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ mp3.reset();
+
+ while (*mp2 != *mpend)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ res << endl;
+ }
+
+ {
+ sstream_t ss;
+ ss << "test string";
+ istream_iterator<char> a(ss);
+ boost::scoped_ptr<default_multi_pass_t> mp1(new default_multi_pass_t(a));
+ boost::scoped_ptr<default_multi_pass_t> mp2(new default_multi_pass_t(*mp1));
+
+ for (int i = 0; i < 4; ++i)
+ {
+ res << **mp1;
+ ++*mp1;
+ }
+
+ while (*mp2 != *mpend)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ while (*mp1 != *mpend)
+ {
+ res << **mp1;
+ ++*mp1;
+ }
+
+ res << endl;
+ }
+
+ {
+ sstream_t ss;
+ ss << "test string";
+ istream_iterator<char> b(ss);
+ boost::scoped_ptr<default_multi_pass_t> mp2(new default_multi_pass_t(b));
+ boost::scoped_ptr<default_multi_pass_t> mp3(new default_multi_pass_t(b));
+ *mp3 = *mp2;
+
+ for (int i = 0; i < 4; ++i)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ mp3.reset();
+ ++*mp2;
+
+ while (*mp2 != *mpend)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ res << endl;
+ }
+
+ {
+ sstream_t ss;
+ ss << "test string";
+ istream_iterator<char> a(ss);
+ boost::scoped_ptr<default_multi_pass_t> mp1(new default_multi_pass_t(a));
+ boost::scoped_ptr<default_multi_pass_t> mp2(new default_multi_pass_t(*mp1));
+
+ BOOST_TEST(*mp1 == *mp2);
+ BOOST_TEST(*mp1 >= *mp2);
+ BOOST_TEST(*mp1 <= *mp2);
+ for (int i = 0; i < 4; ++i)
+ {
+ res << **mp1;
+ ++*mp1;
+ }
+
+ BOOST_TEST(*mp1 != *mp2);
+ BOOST_TEST(*mp1 > *mp2);
+ BOOST_TEST(*mp1 >= *mp2);
+ BOOST_TEST(*mp2 < *mp1);
+ BOOST_TEST(*mp2 <= *mp1);
+ while (*mp2 != *mp1)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ BOOST_TEST(*mp1 == *mp2);
+ BOOST_TEST(*mp1 >= *mp2);
+ BOOST_TEST(*mp1 <= *mp2);
+ while (*mp1 != *mpend)
+ {
+ res << **mp1;
+ ++*mp1;
+ }
+
+ BOOST_TEST(*mp1 != *mp2);
+ BOOST_TEST(*mp1 > *mp2);
+ BOOST_TEST(*mp1 >= *mp2);
+ BOOST_TEST(*mp2 < *mp1);
+ BOOST_TEST(*mp2 <= *mp1);
+ while (*mp2 != *mpend)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ BOOST_TEST(*mp1 == *mp2);
+ BOOST_TEST(*mp1 >= *mp2);
+ BOOST_TEST(*mp1 <= *mp2);
+ res << endl;
+ }
+
+ {
+ sstream_t ss;
+ ss << "test string";
+ istream_iterator<char> a(ss);
+ boost::scoped_ptr<default_multi_pass_t> mp1(new default_multi_pass_t(a));
+ boost::scoped_ptr<default_multi_pass_t> mp2(new default_multi_pass_t(a));
+ BOOST_TEST(*mp1 != *mp2);
+ ++*mp1;
+ BOOST_TEST(*mp1 != *mp2);
+
+ }
+
+ {
+ sstream_t ss;
+ ss << "test string";
+ istream_iterator<char> b(ss);
+ boost::scoped_ptr<default_multi_pass_t> mp2(new default_multi_pass_t(b));
+ boost::scoped_ptr<default_multi_pass_t> mp3(new default_multi_pass_t(b));
+ *mp3 = *mp2;
+
+ for (int i = 0; i < 4; ++i)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ mp2->clear_queue();
+
+ while (*mp2 != *mpend)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ try
+ {
+ res << **mp3; // this should throw illegal_backtracking
+ BOOST_TEST(0);
+ }
+ catch (const BOOST_SPIRIT_CLASSIC_NS::multi_pass_policies::illegal_backtracking& /*e*/)
+ {
+ }
+ res << endl;
+ }
+
+
+}
+
+void test_fixed_multi_pass()
+{
+ res << "-*= test_fixed_multi_pass =*-\n";
+ istream_iterator<char> end;
+ boost::scoped_ptr<fixed_multi_pass_t> mpend(new fixed_multi_pass_t(end));
+
+ {
+ sstream_t ss;
+ ss << "test string";
+
+ istream_iterator<char> a(ss);
+ boost::scoped_ptr<fixed_multi_pass_t> mp1(new fixed_multi_pass_t(a));
+
+ while (*mp1 != *mpend)
+ {
+ res << *((*mp1)++);
+ }
+
+ res << endl;
+ }
+
+ {
+ sstream_t ss;
+ ss << "test string";
+ istream_iterator<char> b(ss);
+ boost::scoped_ptr<fixed_multi_pass_t> mp2(new fixed_multi_pass_t(b));
+ boost::scoped_ptr<fixed_multi_pass_t> mp3(new fixed_multi_pass_t(*mp2));
+
+ for (int i = 0; i < 4; ++i)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ mp3.reset();
+
+ while (*mp2 != *mpend)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ res << endl;
+ }
+
+ {
+ sstream_t ss;
+ ss << "test string";
+ istream_iterator<char> a(ss);
+ boost::scoped_ptr<fixed_multi_pass_t> mp1(new fixed_multi_pass_t(a));
+ boost::scoped_ptr<fixed_multi_pass_t> mp2(new fixed_multi_pass_t(*mp1));
+
+ for (int i = 0; i < 4; ++i)
+ {
+ res << **mp1;
+ ++*mp1;
+ }
+
+ while (*mp2 != *mpend)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ while (*mp1 != *mpend)
+ {
+ res << **mp1;
+ ++*mp1;
+ }
+
+ res << endl;
+ }
+
+ {
+ sstream_t ss;
+ ss << "test string";
+ istream_iterator<char> b(ss);
+ boost::scoped_ptr<fixed_multi_pass_t> mp2(new fixed_multi_pass_t(b));
+ boost::scoped_ptr<fixed_multi_pass_t> mp3(new fixed_multi_pass_t(*mp2));
+
+ for (int i = 0; i < 4; ++i)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ mp3.reset();
+ ++*mp2;
+
+ while (*mp2 != *mpend)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ res << endl;
+ }
+
+ {
+ sstream_t ss;
+ ss << "test string";
+ istream_iterator<char> a(ss);
+ boost::scoped_ptr<fixed_multi_pass_t> mp1(new fixed_multi_pass_t(a));
+ boost::scoped_ptr<fixed_multi_pass_t> mp2(new fixed_multi_pass_t(*mp1));
+
+ BOOST_TEST(*mp1 == *mp2);
+ BOOST_TEST(*mp1 >= *mp2);
+ BOOST_TEST(*mp1 <= *mp2);
+ for (int i = 0; i < 4; ++i)
+ {
+ res << **mp1;
+ ++*mp1;
+ }
+
+ BOOST_TEST(*mp1 != *mp2);
+ BOOST_TEST(*mp1 > *mp2);
+ BOOST_TEST(*mp1 >= *mp2);
+ BOOST_TEST(*mp2 < *mp1);
+ BOOST_TEST(*mp2 <= *mp1);
+ while (*mp2 != *mp1)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ BOOST_TEST(*mp1 == *mp2);
+ BOOST_TEST(*mp1 >= *mp2);
+ BOOST_TEST(*mp1 <= *mp2);
+ while (*mp1 != *mpend)
+ {
+ res << **mp1;
+ ++*mp1;
+ }
+
+ BOOST_TEST(*mp1 != *mp2);
+ BOOST_TEST(*mp1 > *mp2);
+ BOOST_TEST(*mp1 >= *mp2);
+ BOOST_TEST(*mp2 < *mp1);
+ BOOST_TEST(*mp2 <= *mp1);
+ while (*mp2 != *mpend)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ BOOST_TEST(*mp1 == *mp2);
+ BOOST_TEST(*mp1 >= *mp2);
+ BOOST_TEST(*mp1 <= *mp2);
+ res << endl;
+ }
+
+ {
+ sstream_t ss;
+ ss << "test string";
+ istream_iterator<char> a(ss);
+ boost::scoped_ptr<fixed_multi_pass_t> mp1(new fixed_multi_pass_t(a));
+ boost::scoped_ptr<fixed_multi_pass_t> mp2(new fixed_multi_pass_t(a));
+ BOOST_TEST(*mp1 != *mp2);
+ ++*mp1;
+ BOOST_TEST(*mp1 != *mp2);
+
+ }
+
+}
+
+void test_first_owner_multi_pass()
+{
+ res << "-*= test_first_owner_multi_pass =*-\n";
+ istream_iterator<char> end;
+ boost::scoped_ptr<first_owner_multi_pass_t> mpend(new first_owner_multi_pass_t(end));
+
+ {
+ sstream_t ss;
+ ss << "test string";
+
+ istream_iterator<char> a(ss);
+ boost::scoped_ptr<first_owner_multi_pass_t> mp1(new first_owner_multi_pass_t(a));
+
+ while (*mp1 != *mpend)
+ {
+ res << *((*mp1)++);
+ }
+
+ res << endl;
+ }
+
+ {
+ sstream_t ss;
+ ss << "test string";
+ istream_iterator<char> b(ss);
+ boost::scoped_ptr<first_owner_multi_pass_t> mp2(new first_owner_multi_pass_t(b));
+ boost::scoped_ptr<first_owner_multi_pass_t> mp3(new first_owner_multi_pass_t(*mp2));
+
+ for (int i = 0; i < 4; ++i)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ mp3.reset();
+
+ while (*mp2 != *mpend)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ res << endl;
+ }
+
+ {
+ sstream_t ss;
+ ss << "test string";
+ istream_iterator<char> a(ss);
+ boost::scoped_ptr<first_owner_multi_pass_t> mp1(new first_owner_multi_pass_t(a));
+ boost::scoped_ptr<first_owner_multi_pass_t> mp2(new first_owner_multi_pass_t(*mp1));
+
+ for (int i = 0; i < 4; ++i)
+ {
+ res << **mp1;
+ ++*mp1;
+ }
+
+ while (*mp2 != *mpend)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ while (*mp1 != *mpend)
+ {
+ res << **mp1;
+ ++*mp1;
+ }
+
+ res << endl;
+ }
+
+ {
+ sstream_t ss;
+ ss << "test string";
+ istream_iterator<char> b(ss);
+ boost::scoped_ptr<first_owner_multi_pass_t> mp2(new first_owner_multi_pass_t(b));
+ boost::scoped_ptr<first_owner_multi_pass_t> mp3(new first_owner_multi_pass_t(*mp2));
+
+ for (int i = 0; i < 4; ++i)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ mp3.reset();
+ ++*mp2;
+
+ while (*mp2 != *mpend)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ res << endl;
+ }
+
+ {
+ sstream_t ss;
+ ss << "test string";
+ istream_iterator<char> a(ss);
+ boost::scoped_ptr<first_owner_multi_pass_t> mp1(new first_owner_multi_pass_t(a));
+ boost::scoped_ptr<first_owner_multi_pass_t> mp2(new first_owner_multi_pass_t(*mp1));
+
+ BOOST_TEST(*mp1 == *mp2);
+ BOOST_TEST(*mp1 >= *mp2);
+ BOOST_TEST(*mp1 <= *mp2);
+ for (int i = 0; i < 4; ++i)
+ {
+ res << **mp1;
+ ++*mp1;
+ }
+
+ BOOST_TEST(*mp1 != *mp2);
+ BOOST_TEST(*mp1 > *mp2);
+ BOOST_TEST(*mp1 >= *mp2);
+ BOOST_TEST(*mp2 < *mp1);
+ BOOST_TEST(*mp2 <= *mp1);
+ while (*mp2 != *mp1)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ BOOST_TEST(*mp1 == *mp2);
+ BOOST_TEST(*mp1 >= *mp2);
+ BOOST_TEST(*mp1 <= *mp2);
+ while (*mp1 != *mpend)
+ {
+ res << **mp1;
+ ++*mp1;
+ }
+
+ BOOST_TEST(*mp1 != *mp2);
+ BOOST_TEST(*mp1 > *mp2);
+ BOOST_TEST(*mp1 >= *mp2);
+ BOOST_TEST(*mp2 < *mp1);
+ BOOST_TEST(*mp2 <= *mp1);
+ while (*mp2 != *mpend)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ BOOST_TEST(*mp1 == *mp2);
+ BOOST_TEST(*mp1 >= *mp2);
+ BOOST_TEST(*mp1 <= *mp2);
+ res << endl;
+ }
+
+ {
+ sstream_t ss;
+ ss << "test string";
+ istream_iterator<char> a(ss);
+ boost::scoped_ptr<first_owner_multi_pass_t> mp1(new first_owner_multi_pass_t(a));
+ boost::scoped_ptr<first_owner_multi_pass_t> mp2(new first_owner_multi_pass_t(a));
+ BOOST_TEST(*mp1 != *mp2);
+ ++*mp1;
+ BOOST_TEST(*mp1 != *mp2);
+
+ }
+
+ {
+ sstream_t ss;
+ ss << "test string";
+ istream_iterator<char> b(ss);
+ boost::scoped_ptr<first_owner_multi_pass_t> mp2(new first_owner_multi_pass_t(b));
+ boost::scoped_ptr<first_owner_multi_pass_t> mp3(new first_owner_multi_pass_t(*mp2));
+
+ for (int i = 0; i < 4; ++i)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ mp2->clear_queue();
+
+ while (*mp2 != *mpend)
+ {
+ res << **mp2;
+ ++*mp2;
+ }
+
+ try
+ {
+ res << **mp3; // this should throw illegal_backtracking
+ BOOST_TEST(0);
+ }
+ catch (const BOOST_SPIRIT_CLASSIC_NS::multi_pass_policies::illegal_backtracking& /*e*/)
+ {
+ }
+ res << endl;
+ }
+
+}
+
+
+void test_functor_multi_pass()
+{
+ res << "-*= test_functor_multi_pass =*-\n";
+ functor_multi_pass_t mpend;
+
+ {
+ functor_multi_pass_t mp1 = functor_multi_pass_t(my_functor());
+
+ while (mp1 != mpend)
+ {
+ res << *(mp1++);
+ }
+
+ res << endl;
+ }
+
+ {
+ functor_multi_pass_t mp1 = functor_multi_pass_t(my_functor());
+ functor_multi_pass_t mp2 = functor_multi_pass_t(mp1);
+
+ for (int i = 0; i < 4; ++i)
+ {
+ res << *mp1;
+ ++mp1;
+ }
+
+ while (mp2 != mpend)
+ {
+ res << *mp2;
+ ++mp2;
+ }
+
+ while (mp1 != mpend)
+ {
+ res << *mp1;
+ ++mp1;
+ }
+
+ res << endl;
+ }
+
+ {
+ functor_multi_pass_t mp1 = functor_multi_pass_t(my_functor());
+ functor_multi_pass_t mp2 = functor_multi_pass_t(mp1);
+
+ BOOST_TEST(mp1 == mp2);
+ BOOST_TEST(mp1 >= mp2);
+ BOOST_TEST(mp1 <= mp2);
+ for (int i = 0; i < 4; ++i)
+ {
+ res << *mp1;
+ ++mp1;
+ }
+
+ BOOST_TEST(mp1 != mp2);
+ BOOST_TEST(mp1 > mp2);
+ BOOST_TEST(mp1 >= mp2);
+ BOOST_TEST(mp2 < mp1);
+ BOOST_TEST(mp2 <= mp1);
+ while (mp2 != mp1)
+ {
+ res << *mp2;
+ ++mp2;
+ }
+
+ BOOST_TEST(mp1 == mp2);
+ BOOST_TEST(mp1 >= mp2);
+ BOOST_TEST(mp1 <= mp2);
+ while (mp1 != mpend)
+ {
+ res << *mp1;
+ ++mp1;
+ }
+
+ BOOST_TEST(mp1 != mp2);
+ BOOST_TEST(mp1 > mp2);
+ BOOST_TEST(mp1 >= mp2);
+ BOOST_TEST(mp2 < mp1);
+ BOOST_TEST(mp2 <= mp1);
+ while (mp2 != mpend)
+ {
+ res << *mp2;
+ ++mp2;
+ }
+
+ BOOST_TEST(mp1 == mp2);
+ BOOST_TEST(mp1 >= mp2);
+ BOOST_TEST(mp1 <= mp2);
+ res << endl;
+ }
+
+ {
+ functor_multi_pass_t mp1 = functor_multi_pass_t(my_functor());
+ functor_multi_pass_t mp2 = functor_multi_pass_t(my_functor());
+ BOOST_TEST(mp1 != mp2);
+ ++mp1;
+ BOOST_TEST(mp1 != mp2);
+
+ }
+}
+
+int main(int, char**)
+{
+
+ test_default_multi_pass();
+ test_fixed_multi_pass();
+ test_first_owner_multi_pass();
+ test_functor_multi_pass();
+
+ BOOST_TEST(getstring(res) == "-*= test_default_multi_pass =*-\n"
+ "teststring\n"
+ "teststring\n"
+ "testteststringstring\n"
+ "testtring\n"
+ "testteststringstring\n"
+ "teststring\n"
+ "-*= test_fixed_multi_pass =*-\n"
+ "teststring\n"
+ "teststring\n"
+ "testteststringstring\n"
+ "testtring\n"
+ "testteststringstring\n"
+ "-*= test_first_owner_multi_pass =*-\n"
+ "teststring\n"
+ "teststring\n"
+ "testteststringstring\n"
+ "testtring\n"
+ "testteststringstring\n"
+ "teststring\n"
+ "-*= test_functor_multi_pass =*-\n"
+ "ABCDEFGHIJKL\n"
+ "ABCDABCDEFGHIJKLEFGHIJKL\n"
+ "ABCDABCDEFGHIJKLEFGHIJKL\n");
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/negated_eps_p_test.cpp b/src/boost/libs/spirit/classic/test/negated_eps_p_test.cpp
new file mode 100644
index 00000000..5dcf1e61
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/negated_eps_p_test.cpp
@@ -0,0 +1,39 @@
+/*=============================================================================
+ Copyright (c) 2004 Joao Abecasis
+ Copyright (c) 2004 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_dynamic.hpp>
+#include <boost/spirit/include/phoenix1.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include <string>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace phoenix;
+
+int main()
+{
+ using std::cout;
+ using std::endl;
+ using std::string;
+
+ bool f = false;
+
+ rule<> start =
+ while_p(~eps_p(anychar_p[var(f) = true]))
+ [
+ anychar_p
+ ];
+
+ parse("This goes to prove my point.", start);
+ BOOST_TEST(f == false);
+ return boost::report_errors();
+}
+
+
diff --git a/src/boost/libs/spirit/classic/test/numerics_tests.cpp b/src/boost/libs/spirit/classic/test/numerics_tests.cpp
new file mode 100644
index 00000000..69819eaa
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/numerics_tests.cpp
@@ -0,0 +1,313 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Joel de Guzman
+ Copyright (c) 2001-2003 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_assign_actor.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include <climits>
+
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+template <typename T>
+struct ts_real_parser_policies : public ureal_parser_policies<T>
+{
+ // These policies can be used to parse thousand separated
+ // numbers with at most 2 decimal digits after the decimal
+ // point. e.g. 123,456,789.01
+
+ typedef uint_parser<int, 10, 1, 2> uint2_t;
+ typedef uint_parser<T, 10, 1, -1> uint_parser_t;
+ typedef int_parser<int, 10, 1, -1> int_parser_t;
+
+ ////////////////////////////////// 2 decimal places Max
+ template <typename ScannerT>
+ static typename parser_result<uint2_t, ScannerT>::type
+ parse_frac_n(ScannerT& scan)
+ { return uint2_t().parse(scan); }
+
+ ////////////////////////////////// No exponent
+ template <typename ScannerT>
+ static typename parser_result<chlit<>, ScannerT>::type
+ parse_exp(ScannerT& scan)
+ { return scan.no_match(); }
+
+ ////////////////////////////////// No exponent
+ template <typename ScannerT>
+ static typename parser_result<int_parser_t, ScannerT>::type
+ parse_exp_n(ScannerT& scan)
+ { return scan.no_match(); }
+
+ ////////////////////////////////// Thousands separated numbers
+ template <typename ScannerT>
+ static typename parser_result<uint_parser_t, ScannerT>::type
+ parse_n(ScannerT& scan)
+ {
+ typedef typename parser_result<uint_parser_t, ScannerT>::type RT;
+ static uint_parser<unsigned, 10, 1, 3> uint3_p;
+ static uint_parser<unsigned, 10, 3, 3> uint3_3_p;
+
+ if (RT hit = uint3_p.parse(scan))
+ {
+ T n;
+ typedef typename ScannerT::iterator_t iterator_t;
+ iterator_t save = scan.first;
+ while (match<> next = (',' >> uint3_3_p[assign_a(n)]).parse(scan))
+ {
+ hit.value((hit.value() * 1000) + n);
+ scan.concat_match(hit, next);
+ save = scan.first;
+ }
+ scan.first = save;
+ return hit;
+ }
+ return scan.no_match();
+ }
+};
+
+real_parser<double, ts_real_parser_policies<double> > const
+ ts_real_p = real_parser<double, ts_real_parser_policies<double> >();
+
+template <typename T>
+struct no_trailing_dot : public real_parser_policies<T>
+{
+ static const bool allow_trailing_dot = false;
+};
+
+real_parser<double, no_trailing_dot<double> > const
+ notrdot_real_p = real_parser<double, no_trailing_dot<double> >();
+
+template <typename T>
+struct no_leading_dot : public real_parser_policies<T>
+{
+ static const bool allow_leading_dot = false;
+};
+
+real_parser<double, no_leading_dot<double> > const
+ nolddot_real_p = real_parser<double, no_leading_dot<double> >();
+
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ cout << "/////////////////////////////////////////////////////////\n\n";
+ cout << "\t\tNumeric tests...\n\n";
+ cout << "/////////////////////////////////////////////////////////\n\n";
+
+ // *** The following assumes 32 bit integers. Modify these constant
+ // *** strings when appropriate. BEWARE PLATFORM DEPENDENT!
+
+ char const* max_unsigned = "4294967295";
+ char const* unsigned_overflow = "4294967296";
+ char const* max_int = "2147483647";
+ char const* int_overflow = "2147483648";
+ char const* min_int = "-2147483648";
+ char const* int_underflow = "-2147483649";
+ char const* max_binary = "11111111111111111111111111111111";
+ char const* binary_overflow = "100000000000000000000000000000000";
+ char const* max_octal = "37777777777";
+ char const* octal_overflow = "100000000000";
+ char const* max_hex = "FFFFFFFF";
+ char const* hex_overflow = "100000000";
+
+#ifdef BOOST_HAS_LONG_LONG
+
+ char const* max_long_long = "9223372036854775807";
+ char const* long_long_overflow = "9223372036854775808";
+ char const* min_long_long = "-9223372036854775808";
+ char const* long_long_underflow = "-9223372036854775809";
+
+#endif
+
+// BEGIN TESTS...
+
+ unsigned u;
+
+// unsigned integer
+
+ parse("123456", uint_p[assign_a(u)]);
+ BOOST_TEST(u == 123456);
+
+ parse(max_unsigned, uint_p[assign_a(u)]);
+ BOOST_TEST(u == UINT_MAX);
+
+ BOOST_TEST(!parse(unsigned_overflow, uint_p).full);
+
+// signed integer
+
+ int i;
+
+ parse("123456", int_p[assign_a(i)]);
+ BOOST_TEST(i == 123456);
+
+ parse("-123456", int_p[assign_a(i)]);
+ BOOST_TEST(i == -123456);
+
+ parse(max_int, int_p[assign_a(i)]);
+ BOOST_TEST(i == INT_MAX);
+
+ parse(min_int, int_p[assign_a(i)]);
+ BOOST_TEST(i == INT_MIN);
+
+ BOOST_TEST(!parse(int_overflow, int_p).full);
+ BOOST_TEST(!parse(int_underflow, int_p).full);
+
+ BOOST_TEST(!parse("-", int_p).hit);
+
+// binary
+
+ parse("11111110", bin_p[assign_a(u)]);
+ BOOST_TEST(u == 0xFE);
+
+ parse(max_binary, bin_p[assign_a(u)]);
+ BOOST_TEST(u == UINT_MAX);
+
+ BOOST_TEST(!parse(binary_overflow, bin_p).full);
+
+// octal
+
+ parse("12545674515", oct_p[assign_a(u)]);
+ BOOST_TEST(u == 012545674515);
+
+ parse(max_octal, oct_p[assign_a(u)]);
+ BOOST_TEST(u == UINT_MAX);
+
+ BOOST_TEST(!parse(octal_overflow, oct_p).full);
+
+// hex
+
+ parse("95BC8DF", hex_p[assign_a(u)]);
+ BOOST_TEST(u == 0x95BC8DF);
+
+ parse("abcdef12", hex_p[assign_a(u)]);
+ BOOST_TEST(u == 0xabcdef12);
+
+ parse(max_hex, hex_p[assign_a(u)]);
+ BOOST_TEST(u == UINT_MAX);
+
+ BOOST_TEST(!parse(hex_overflow, hex_p).full);
+
+// limited fieldwidth
+
+ uint_parser<unsigned, 10, 1, 3> uint3_p;
+ parse("123456", uint3_p[assign_a(u)]);
+ BOOST_TEST(u == 123);
+
+ uint_parser<unsigned, 10, 1, 4> uint4_p;
+ parse("123456", uint4_p[assign_a(u)]);
+ BOOST_TEST(u == 1234);
+
+ uint_parser<unsigned, 10, 3, 3> uint3_3_p;
+
+// thousand separated numbers
+
+#define r (uint3_p >> *(',' >> uint3_3_p))
+
+ BOOST_TEST(parse("1,234,567,890", r).full); // OK
+ BOOST_TEST(parse("12,345,678,900", r).full); // OK
+ BOOST_TEST(parse("123,456,789,000", r).full); // OK
+ BOOST_TEST(!parse("1000,234,567,890", r).full); // Bad
+ BOOST_TEST(!parse("1,234,56,890", r).full); // Bad
+ BOOST_TEST(!parse("1,66", r).full); // Bad
+
+// long long
+
+#ifdef BOOST_HAS_LONG_LONG
+
+// Some compilers have long long, but don't define the
+// LONG_LONG_MIN and LONG_LONG_MAX macros in limits.h. This
+// assumes that long long is 64 bits.
+#if !defined(LONG_LONG_MIN) && !defined(LONG_LONG_MAX) \
+ && !defined(ULONG_LONG_MAX)
+#define ULONG_LONG_MAX 0xffffffffffffffffLLU
+#define LONG_LONG_MAX 0x7fffffffffffffffLL
+#define LONG_LONG_MIN (-LONG_LONG_MAX - 1)
+#endif
+
+ ::boost::long_long_type ll;
+ int_parser< ::boost::long_long_type> long_long_p;
+
+ parse("1234567890123456789", long_long_p[assign_a(ll)]);
+ BOOST_TEST(ll == 1234567890123456789LL);
+
+ parse("-1234567890123456789", long_long_p[assign_a(ll)]);
+ BOOST_TEST(ll == -1234567890123456789LL);
+
+ parse(max_long_long, long_long_p[assign_a(ll)]);
+ BOOST_TEST(ll == LONG_LONG_MAX);
+
+ parse(min_long_long, long_long_p[assign_a(ll)]);
+ BOOST_TEST(ll == LONG_LONG_MIN);
+
+#if defined(__GNUG__) && (__GNUG__ == 3) && (__GNUC_MINOR__ < 3) \
+ && !defined(__EDG__)
+ // gcc 3.2.3 crashes on parse(long_long_overflow, long_long_p)
+ // wrapping long_long_p into a rule avoids the crash
+ rule<> gcc_3_2_3_long_long_r = long_long_p;
+ BOOST_TEST(!parse(long_long_overflow, gcc_3_2_3_long_long_r).full);
+ BOOST_TEST(!parse(long_long_underflow, gcc_3_2_3_long_long_r).full);
+#else
+ BOOST_TEST(!parse(long_long_overflow, long_long_p).full);
+ BOOST_TEST(!parse(long_long_underflow, long_long_p).full);
+#endif
+
+#endif
+
+// real numbers
+
+ double d;
+
+ BOOST_TEST(parse("1234", ureal_p[assign_a(d)]).full && d == 1234); // Good.
+ BOOST_TEST(parse("1.2e3", ureal_p[assign_a(d)]).full && d == 1.2e3); // Good.
+ BOOST_TEST(parse("1.2e-3", ureal_p[assign_a(d)]).full && d == 1.2e-3); // Good.
+ BOOST_TEST(parse("1.e2", ureal_p[assign_a(d)]).full && d == 1.e2); // Good.
+ BOOST_TEST(parse(".2e3", ureal_p[assign_a(d)]).full && d == .2e3); // Good.
+ BOOST_TEST(parse("2e3", ureal_p[assign_a(d)]).full && d == 2e3); // Good. No fraction
+ BOOST_TEST(!parse("e3", ureal_p).full); // Bad! No number
+ BOOST_TEST(!parse("-1.2e3", ureal_p).full); // Bad! Negative number
+ BOOST_TEST(!parse("+1.2e3", ureal_p).full); // Bad! Positive sign
+ BOOST_TEST(!parse("1.2e", ureal_p).full); // Bad! No exponent
+ BOOST_TEST(!parse("-.3", ureal_p).full); // Bad! Negative
+
+ BOOST_TEST(parse("-1234", real_p[assign_a(d)]).full && d == -1234); // Good.
+ BOOST_TEST(parse("-1.2e3", real_p[assign_a(d)]).full && d == -1.2e3); // Good.
+ BOOST_TEST(parse("+1.2e3", real_p[assign_a(d)]).full && d == 1.2e3); // Good.
+ BOOST_TEST(parse("-0.1", real_p[assign_a(d)]).full && d == -0.1); // Good.
+ BOOST_TEST(parse("-1.2e-3", real_p[assign_a(d)]).full && d == -1.2e-3); // Good.
+ BOOST_TEST(parse("-1.e2", real_p[assign_a(d)]).full && d == -1.e2); // Good.
+ BOOST_TEST(parse("-.2e3", real_p[assign_a(d)]).full && d == -.2e3); // Good.
+ BOOST_TEST(parse("-2e3", real_p[assign_a(d)]).full && d == -2e3); // Good. No fraction
+ BOOST_TEST(!parse("-e3", real_p).full); // Bad! No number
+ BOOST_TEST(!parse("-1.2e", real_p).full); // Bad! No exponent
+
+ BOOST_TEST(!parse("1234", strict_ureal_p[assign_a(d)]).full); // Bad. Strict real
+ BOOST_TEST(parse("1.2", strict_ureal_p[assign_a(d)]).full && d == 1.2); // Good.
+ BOOST_TEST(!parse("-1234", strict_real_p[assign_a(d)]).full); // Bad. Strict real
+ BOOST_TEST(parse("123.", strict_real_p[assign_a(d)]).full && d == 123); // Good.
+ BOOST_TEST(parse("3.E6", strict_real_p[assign_a(d)]).full && d == 3e6); // Good.
+
+ BOOST_TEST(!parse("1234.", notrdot_real_p[assign_a(d)]).full); // Bad trailing dot
+ BOOST_TEST(!parse(".1234", nolddot_real_p[assign_a(d)]).full); // Bad leading dot
+
+// Special thousands separated numbers
+
+ BOOST_TEST(parse("123,456,789.01", ts_real_p[assign_a(d)]).full && d == 123456789.01); // Good.
+ BOOST_TEST(parse("12,345,678.90", ts_real_p[assign_a(d)]).full && d == 12345678.90); // Good.
+ BOOST_TEST(parse("1,234,567.89", ts_real_p[assign_a(d)]).full && d == 1234567.89); // Good.
+ BOOST_TEST(!parse("1234,567,890", ts_real_p).full); // Bad.
+ BOOST_TEST(!parse("1,234,5678,9", ts_real_p).full); // Bad.
+ BOOST_TEST(!parse("1,234,567.89e6", ts_real_p).full); // Bad.
+ BOOST_TEST(!parse("1,66", ts_real_p).full); // Bad.
+
+// END TESTS.
+
+/////////////////////////////////////////////////////////////////
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/operators_tests.cpp b/src/boost/libs/spirit/classic/test/operators_tests.cpp
new file mode 100644
index 00000000..fd89e216
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/operators_tests.cpp
@@ -0,0 +1,164 @@
+/*=============================================================================
+ Copyright (c) 1998-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace std;
+
+#include <boost/spirit/include/classic_core.hpp>
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Operators tests
+//
+///////////////////////////////////////////////////////////////////////////////
+void
+operators_tests()
+{
+ parse_info<char const*> pi;
+
+ pi = parse("Hello World", str_p("Hello ") >> "World");
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 11);
+ BOOST_TEST(*pi.stop == 0);
+
+ pi = parse("Banana", str_p("Banana") | "Pineapple");
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 6);
+ BOOST_TEST(*pi.stop == 0);
+
+ pi = parse("Pineapple", str_p("Banana") | "Pineapple");
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 9);
+ BOOST_TEST(*pi.stop == 0);
+
+ pi = parse("a.2 ", alpha_p || ('.' >> digit_p));
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.length == 3);
+
+ pi = parse("a ", alpha_p || ('.' >> digit_p));
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.length == 1);
+
+ pi = parse(".1 ", alpha_p || ('.' >> digit_p));
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.length == 2);
+
+ pi = parse("1.a ", alpha_p || ('.' >> digit_p));
+ BOOST_TEST(!pi.hit);
+
+ pi = parse("abcdefghij", +xdigit_p & +alpha_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.length == 6);
+
+ pi = parse("abcdefghij", +alpha_p & +xdigit_p);
+ BOOST_TEST(!pi.hit);
+
+ pi = parse("abcdefghij", +digit_p & +alpha_p);
+ BOOST_TEST(!pi.hit);
+
+ pi = parse("abcdefghij", +alpha_p & +digit_p);
+ BOOST_TEST(!pi.hit);
+
+ // Test for bug reported by Yusaku Sugai here:
+ // http://article.gmane.org/gmane.comp.parsers.spirit.general/8544
+ pi = parse( "foo", (anychar_p & anychar_p), ch_p(' ') );
+ BOOST_TEST(pi.hit);
+
+ pi = parse("F", xdigit_p - range_p('5','8'));
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.length == 1);
+
+ pi = parse("0", xdigit_p - range_p('5','8'));
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.length == 1);
+
+ pi = parse("4", xdigit_p - range_p('5','8'));
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.length == 1);
+
+ pi = parse("9", xdigit_p - range_p('5','8'));
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.length == 1);
+
+ pi = parse("5", xdigit_p - range_p('5','8'));
+ BOOST_TEST(!pi.hit);
+
+ pi = parse("7", xdigit_p - range_p('5','8'));
+ BOOST_TEST(!pi.hit);
+
+ pi = parse("x*/", anychar_p - "*/");
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.length == 1);
+
+ pi = parse("*/", anychar_p - "*/");
+ BOOST_TEST(!pi.hit);
+
+ pi = parse("switcher ", str_p("switcher") - "switch");
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.length == 8);
+
+ pi = parse("Z", alpha_p ^ xdigit_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.length == 1);
+
+ pi = parse("1", alpha_p ^ xdigit_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.length == 1);
+
+ pi = parse("B", alpha_p ^ xdigit_p);
+ BOOST_TEST(!pi.hit);
+
+ pi = parse("B", !alpha_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.length == 1);
+
+ pi = parse("1", !alpha_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.length == 0);
+ BOOST_TEST(*pi.stop == '1');
+
+ pi = parse("1234 5678 1234 5678", *(+digit_p >> *space_p));
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 19);
+ BOOST_TEST(*pi.stop == 0);
+
+ pi = parse("abcdefghijklmnopqrstuvwxyz123", *alpha_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.length == 26);
+
+ pi = parse("1234+5678*1234/5678", +digit_p % (ch_p('+') | '*' | '/'));
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 19);
+ BOOST_TEST(*pi.stop == 0);
+
+ pi = parse("1234+", +digit_p % '+');
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(!pi.full);
+ BOOST_TEST(pi.length == 4);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ operators_tests();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/owi_mt_tests.cpp b/src/boost/libs/spirit/classic/test/owi_mt_tests.cpp
new file mode 100644
index 00000000..9490d092
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/owi_mt_tests.cpp
@@ -0,0 +1,242 @@
+/*=============================================================================
+ Copyright (c) 2002-2004 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+// std::lower_bound seems to perform awfully slow with _GLIBCXX_DEBUG enabled
+#undef _GLIBCXX_DEBUG
+
+#include <iostream>
+#include <boost/config.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if !defined(BOOST_HAS_THREADS) || defined(DONT_HAVE_BOOST) || defined(BOOST_DISABLE_THREADS)
+static void skipped()
+{
+ std::cout << "skipped\n";
+}
+
+int
+main()
+{
+ skipped();
+ return 0;
+}
+#else
+
+////////////////////////////////////////////////////////////////////////////////
+
+static const unsigned long initial_test_size = 5000UL;
+#if defined(_DEBUG) && (BOOST_MSVC >= 1400)
+static const unsigned long maximum_test_size = 10000UL;
+#else
+static const unsigned long maximum_test_size = 1000000UL;
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+
+#undef BOOST_SPIRIT_THREADSAFE
+#define BOOST_SPIRIT_THREADSAFE
+
+#include <boost/thread/thread.hpp>
+#include <boost/spirit/home/classic/core/non_terminal/impl/object_with_id.ipp>
+#include <boost/ref.hpp>
+#include <boost/thread/xtime.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/lock_types.hpp>
+#include <vector>
+#include <algorithm>
+#include <boost/detail/lightweight_test.hpp>
+
+using BOOST_SPIRIT_CLASSIC_NS::impl::object_with_id;
+
+struct tag1 {};
+typedef object_with_id<tag1> class1;
+
+unsigned long test_size = initial_test_size;
+boost::xtime start_time;
+
+template <typename ClassT>
+struct test_task
+{
+ test_task() : v(), m(), progress(0) {}
+
+ void operator ()()
+ { // create lots of objects
+ unsigned long i = 0;
+
+ v.reserve(maximum_test_size);
+ do
+ {
+ for (; i<test_size; ++i)
+ v.push_back(new ClassT);
+ }
+ while ( i < increase_test_size(i) );
+ }
+
+ static unsigned long
+ increase_test_size(unsigned long size)
+ {
+ static boost::mutex m;
+ boost::unique_lock<boost::mutex> l(m);
+
+ if (size<test_size || test_size == maximum_test_size)
+ return test_size;
+
+ boost::xtime now;
+ boost::xtime_get(&now, boost::TIME_UTC_);
+ boost::xtime::xtime_sec_t seconds = now.sec - start_time.sec;
+ if (seconds < 4)
+ {
+ test_size *= 2;
+ if (test_size > maximum_test_size)
+ test_size = maximum_test_size;
+ }
+
+ return test_size;
+ }
+
+ std::vector<ClassT*> const &data() const
+ {
+ return v;
+ }
+
+private:
+ std::vector<ClassT*> v;
+ boost::mutex m;
+ unsigned int progress;
+};
+
+template <typename T>
+class callable_reference_wrapper
+ : public boost::reference_wrapper<T>
+{
+public:
+ explicit callable_reference_wrapper(T& t)
+ : boost::reference_wrapper<T>(t)
+ {}
+ inline void operator()() { this->get().operator()(); }
+};
+
+template <typename T>
+callable_reference_wrapper<T>
+callable_ref(T &t)
+{
+ return callable_reference_wrapper<T>(t);
+}
+
+test_task<class1> test1;
+test_task<class1> test2;
+test_task<class1> test3;
+
+
+template <typename ClassT>
+void
+check_ascending(test_task<ClassT> const &t)
+{
+ typedef typename std::vector<ClassT*>::const_iterator iter;
+ iter p(t.data().begin());
+ iter const e(t.data().end());
+ iter n(p);
+
+ while (++n!=e)
+ {
+ if ((**n).get_object_id()<=(**p).get_object_id())
+ {
+ using namespace std;
+ throw std::runtime_error("object ids out of order");
+ }
+ p = n;
+ }
+}
+
+struct less1
+{
+ bool operator()(class1 const *p, class1 const *q) const
+ {
+ return p->get_object_id() < q->get_object_id();
+ }
+};
+
+template <typename ClassT>
+void
+check_not_contained_in(
+ test_task<ClassT> const &candidate,
+ test_task<ClassT> const &in
+)
+{
+ typedef typename std::vector<ClassT*>::const_iterator iter;
+ iter p(candidate.data().begin());
+ iter const e(candidate.data().end());
+
+ while (p!=e)
+ {
+ iter found = std::lower_bound(in.data().begin(),in.data().end(),*p,less1());
+ if (found!=in.data().end() &&
+ (**found).get_object_id() == (**p).get_object_id())
+ {
+ using namespace std;
+ throw std::runtime_error("object ids not unqiue");
+ }
+ ++p;
+ }
+}
+
+void concurrent_creation_of_objects()
+{
+ {
+ boost::xtime_get(&start_time, boost::TIME_UTC_);
+ boost::thread thread1(callable_ref(test1));
+ boost::thread thread2(callable_ref(test2));
+ boost::thread thread3(callable_ref(test3));
+
+ thread1.join();
+ thread2.join();
+ thread3.join();
+ }
+}
+
+void local_uniqueness()
+{
+
+
+ BOOST_TEST(test1.data().size()==test_size);
+ BOOST_TEST(test2.data().size()==test_size);
+ BOOST_TEST(test3.data().size()==test_size);
+}
+
+void local_ordering_and_uniqueness()
+{
+ // now all objects should have unique ids,
+ // the ids must be ascending within each vector
+ // check for ascending ids
+ check_ascending(test1);
+ check_ascending(test2);
+ check_ascending(test3);
+}
+
+void global_uniqueness()
+{
+ check_not_contained_in(test1,test3);
+ check_not_contained_in(test1,test2);
+ check_not_contained_in(test2,test1);
+ check_not_contained_in(test2,test3);
+ check_not_contained_in(test3,test2);
+ check_not_contained_in(test3,test1);
+}
+
+int
+main()
+{
+ concurrent_creation_of_objects();
+ local_ordering_and_uniqueness();
+ global_uniqueness();
+ return boost::report_errors();
+}
+
+#endif // BOOST_HAS_THREADS
+
diff --git a/src/boost/libs/spirit/classic/test/owi_st_tests.cpp b/src/boost/libs/spirit/classic/test/owi_st_tests.cpp
new file mode 100644
index 00000000..20c1ca09
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/owi_st_tests.cpp
@@ -0,0 +1,88 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+// vim:ts=4:sw=4:et
+
+#if defined(BOOST_BUILD_PCH_ENABLED) && defined(BOOST_SPIRIT_THREADSAFE)
+# error BOOST_SPIRIT_THREADSAFE has to be undefined for this test
+#endif
+#undef BOOST_SPIRIT_THREADSAFE
+#include <boost/spirit/home/classic/core/non_terminal/impl/object_with_id.ipp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+
+using BOOST_SPIRIT_CLASSIC_NS::impl::object_with_id;
+
+struct tag1 {};
+struct tag2 {};
+
+typedef object_with_id<tag1> class1;
+typedef object_with_id<tag2> class2;
+
+int
+main()
+{
+ std::cout << "/////////////////////////////////////////////////////////\n";
+ std::cout << "\n";
+ std::cout << " object_with_id test (ST)\n";
+ std::cout << "\n";
+ std::cout << "/////////////////////////////////////////////////////////\n";
+ std::cout << "\n";
+
+ class1 *c1o1 = new class1;
+ class1 *c1o2 = new class1;
+ class1 *c1o3 = new class1;
+
+ // test wether the objects have consecutive numbers
+ BOOST_TEST(c1o1->get_object_id()==1);
+ BOOST_TEST(c1o2->get_object_id()==2);
+ BOOST_TEST(c1o3->get_object_id()==3);
+
+ // test wether number recycling works
+ delete c1o3;
+ c1o3 = new class1;
+ BOOST_TEST(c1o3->get_object_id()==3);
+
+ delete c1o2;
+ c1o2 = new class1;
+ BOOST_TEST(c1o2->get_object_id()==2);
+
+ delete c1o2;
+ delete c1o3;
+ c1o2 = new class1;
+ c1o3 = new class1;
+ BOOST_TEST(c1o3->get_object_id()==3);
+ BOOST_TEST(c1o2->get_object_id()==2);
+
+ // test whether objects of different classes are numbered independently
+ class2 *c2o1 = new class2;
+ class2 *c2o2 = new class2;
+ class2 *c2o3 = new class2;
+ BOOST_TEST(c2o1->get_object_id()==1);
+ BOOST_TEST(c2o2->get_object_id()==2);
+ BOOST_TEST(c2o3->get_object_id()==3);
+
+ //
+ delete c1o1;
+ delete c2o2;
+ c2o2 = new class2;
+ c1o1 = new class1;
+ BOOST_TEST(c1o1->get_object_id()==1);
+ BOOST_TEST(c2o2->get_object_id()==2);
+
+ // test wether the copy ctor doesn't copy the id
+ delete c1o1;
+ c1o1 = new class1(*c1o2);
+ BOOST_TEST(c1o1->get_object_id()==1);
+
+ // test wether the assignment operator doesn't assign the id
+ *c1o1 = *c1o2;
+ BOOST_TEST(c1o1->get_object_id()==1);
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/parametric_tests.cpp b/src/boost/libs/spirit/classic/test/parametric_tests.cpp
new file mode 100644
index 00000000..9fc7b2c9
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/parametric_tests.cpp
@@ -0,0 +1,185 @@
+/*=============================================================================
+ Copyright (c) 2001-2003 Joel de Guzman
+ Copyright (c) 2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+#include <string>
+
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_parametric.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_operators.hpp>
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace phoenix;
+
+#include <boost/detail/lightweight_test.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Parametric tests
+//
+///////////////////////////////////////////////////////////////////////////////
+
+template <typename T>
+static unsigned
+length(T const *p)
+{
+ unsigned result = 0;
+ while (*p++)
+ ++result;
+ return result;
+}
+
+template <typename T>
+bool
+is_equal(T const* a, T const* b)
+{
+ while (*a && *b)
+ if (*a++ != *b++)
+ return false;
+ return true;
+}
+
+typedef rule< scanner<wchar_t const *> > wrule_t;
+
+void
+narrow_f_ch_p()
+{
+ char ch;
+ rule<> r = anychar_p[var(ch) = arg1] >> *f_ch_p(const_(ch));
+ parse_info<char const*> pi;
+
+ pi = parse("aaaaaaaaa", r);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse("aaaaabaaa", r);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(!pi.full);
+ BOOST_TEST(is_equal(pi.stop, "baaa"));
+}
+
+void
+wide_f_ch_p()
+{
+ wchar_t ch;
+ wrule_t r = anychar_p[var(ch) = arg1] >> *f_ch_p(const_(ch));
+ parse_info<wchar_t const*> pi;
+
+ pi = parse(L"aaaaaaaaa", r);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse(L"aaaaabaaa", r);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(!pi.full);
+ BOOST_TEST(is_equal(pi.stop, L"baaa"));
+}
+
+void
+narrow_f_range_p()
+{
+ char from = 'a';
+ char to = 'z';
+
+ parse_info<char const*> pi;
+
+ rule<> r2 = *f_range_p(const_(from), const_(to));
+ pi = parse("abcdefghijklmnopqrstuvwxyz", r2);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse("abcdefghijklmnopqrstuvwxyz123", r2);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(!pi.full);
+ BOOST_TEST(is_equal(pi.stop, "123"));
+}
+
+void
+wide_f_range_p()
+{
+ wchar_t from = L'a';
+ wchar_t to = L'z';
+
+ parse_info<wchar_t const*> pi;
+
+ wrule_t r2 = *f_range_p(const_(from), const_(to));
+ pi = parse(L"abcdefghijklmnopqrstuvwxyz", r2);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse(L"abcdefghijklmnopqrstuvwxyz123", r2);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(!pi.full);
+ BOOST_TEST(is_equal(pi.stop, L"123"));
+}
+
+void
+narrow_f_str_p()
+{
+ parse_info<char const*> pi;
+
+ char const* start = "kim";
+ char const* end = start + length(start);
+ rule<> r3 = +f_str_p(const_(start), const_(end));
+
+ pi = parse("kimkimkimkimkimkimkimkimkim", r3);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse("kimkimkimkimkimkimkimkimkimmama", r3);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(!pi.full);
+ BOOST_TEST(is_equal(pi.stop, "mama"));
+
+ pi = parse("joel", r3);
+ BOOST_TEST(!pi.hit);
+}
+
+void
+wide_f_str_p()
+{
+ parse_info<wchar_t const*> pi;
+
+ wchar_t const* start = L"kim";
+ wchar_t const* end = start + length(start);
+ wrule_t r3 = +f_str_p(const_(start), const_(end));
+
+ pi = parse(L"kimkimkimkimkimkimkimkimkim", r3);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse(L"kimkimkimkimkimkimkimkimkimmama", r3);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(!pi.full);
+ BOOST_TEST(is_equal(pi.stop, L"mama"));
+
+ pi = parse(L"joel", r3);
+ BOOST_TEST(!pi.hit);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// test suite
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ narrow_f_ch_p();
+ wide_f_ch_p();
+ narrow_f_range_p();
+ wide_f_range_p();
+ narrow_f_str_p();
+ wide_f_str_p();
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/parser_context_test.cpp b/src/boost/libs/spirit/classic/test/parser_context_test.cpp
new file mode 100644
index 00000000..7883bab4
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/parser_context_test.cpp
@@ -0,0 +1,24 @@
+/*=============================================================================
+ Copyright (c) 2003 Vaclav Vesely
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_assign_actor.hpp>
+
+using namespace boost;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+int main()
+{
+ rule<parser_context<int> > int_rule = int_p;
+ int result(0);
+ parse("123", int_rule[assign_a(result)]);
+ BOOST_TEST(result == 123);
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/parser_traits_tests.cpp b/src/boost/libs/spirit/classic/test/parser_traits_tests.cpp
new file mode 100644
index 00000000..901cf787
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/parser_traits_tests.cpp
@@ -0,0 +1,285 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// Parser traits tests
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_assign_actor.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+typedef ref_value_actor<char, assign_action> assign_actor;
+
+// Test parser_traits templates
+void
+parser_traits_tests()
+{
+// is_parser_category_tests
+ typedef chlit<char> plain_t;
+ typedef optional<chlit<char> > unary_t;
+ typedef action<chlit<char>, assign_actor> action_t;
+ typedef sequence<chlit<char>, anychar_parser> binary_t;
+
+// is_parser
+ BOOST_STATIC_ASSERT(is_parser<plain_t>::value);
+ BOOST_STATIC_ASSERT(is_parser<unary_t>::value);
+ BOOST_STATIC_ASSERT(is_parser<action_t>::value);
+ BOOST_STATIC_ASSERT(is_parser<binary_t>::value);
+
+// is_action_parser
+ BOOST_STATIC_ASSERT(!is_action_parser<plain_t>::value);
+ BOOST_STATIC_ASSERT(!is_action_parser<unary_t>::value);
+ BOOST_STATIC_ASSERT(is_action_parser<action_t>::value);
+ BOOST_STATIC_ASSERT(!is_action_parser<binary_t>::value);
+
+// is_unary_composite
+ BOOST_STATIC_ASSERT(!is_unary_composite<plain_t>::value);
+ BOOST_STATIC_ASSERT(is_unary_composite<unary_t>::value);
+ BOOST_STATIC_ASSERT(is_unary_composite<action_t>::value); // action_t _is_ an unary_t!
+ BOOST_STATIC_ASSERT(!is_unary_composite<binary_t>::value);
+
+// is_binary_composite
+ BOOST_STATIC_ASSERT(!is_binary_composite<plain_t>::value);
+ BOOST_STATIC_ASSERT(!is_binary_composite<unary_t>::value);
+ BOOST_STATIC_ASSERT(!is_binary_composite<action_t>::value);
+ BOOST_STATIC_ASSERT(is_binary_composite<binary_t>::value);
+
+// is_composite_parser
+ BOOST_STATIC_ASSERT(!is_composite_parser<plain_t>::value);
+ BOOST_STATIC_ASSERT(is_composite_parser<unary_t>::value);
+ BOOST_STATIC_ASSERT(is_composite_parser<action_t>::value); // action_t _is_ an unary_t!
+ BOOST_STATIC_ASSERT(is_composite_parser<binary_t>::value);
+
+// is_composite_type_tests
+ typedef alternative<chlit<char>, anychar_parser> alternative_t;
+ typedef sequence<chlit<char>, anychar_parser> sequence_t;
+ typedef sequential_or<chlit<char>, anychar_parser> sequential_or_t;
+ typedef intersection<chlit<char>, anychar_parser> intersection_t;
+ typedef difference<chlit<char>, anychar_parser> difference_t;
+ typedef exclusive_or<chlit<char>, anychar_parser> exclusive_or_t;
+
+ typedef optional<chlit<char> > optional_t;
+ typedef kleene_star<chlit<char> > kleene_star_t;
+ typedef positive<chlit<char> > positive_t;
+
+// is_parser
+ BOOST_STATIC_ASSERT(is_parser<alternative_t>::value);
+ BOOST_STATIC_ASSERT(is_parser<sequence_t>::value);
+ BOOST_STATIC_ASSERT(is_parser<sequential_or_t>::value);
+ BOOST_STATIC_ASSERT(is_parser<intersection_t>::value);
+ BOOST_STATIC_ASSERT(is_parser<difference_t>::value);
+ BOOST_STATIC_ASSERT(is_parser<exclusive_or_t>::value);
+ BOOST_STATIC_ASSERT(is_parser<optional_t>::value);
+ BOOST_STATIC_ASSERT(is_parser<positive_t>::value);
+
+// is_alternative
+ BOOST_STATIC_ASSERT(!is_alternative<plain_t>::value);
+ BOOST_STATIC_ASSERT(!is_alternative<action_t>::value);
+
+ BOOST_STATIC_ASSERT(is_alternative<alternative_t>::value);
+ BOOST_STATIC_ASSERT(!is_alternative<sequence_t>::value);
+ BOOST_STATIC_ASSERT(!is_alternative<sequential_or_t>::value);
+ BOOST_STATIC_ASSERT(!is_alternative<intersection_t>::value);
+ BOOST_STATIC_ASSERT(!is_alternative<difference_t>::value);
+ BOOST_STATIC_ASSERT(!is_alternative<exclusive_or_t>::value);
+
+ BOOST_STATIC_ASSERT(!is_alternative<optional_t>::value);
+ BOOST_STATIC_ASSERT(!is_alternative<kleene_star_t>::value);
+ BOOST_STATIC_ASSERT(!is_alternative<positive_t>::value);
+
+// is_sequence
+ BOOST_STATIC_ASSERT(!is_sequence<plain_t>::value);
+ BOOST_STATIC_ASSERT(!is_sequence<action_t>::value);
+
+ BOOST_STATIC_ASSERT(!is_sequence<alternative_t>::value);
+ BOOST_STATIC_ASSERT(is_sequence<sequence_t>::value);
+ BOOST_STATIC_ASSERT(!is_sequence<sequential_or_t>::value);
+ BOOST_STATIC_ASSERT(!is_sequence<intersection_t>::value);
+ BOOST_STATIC_ASSERT(!is_sequence<difference_t>::value);
+ BOOST_STATIC_ASSERT(!is_sequence<exclusive_or_t>::value);
+
+ BOOST_STATIC_ASSERT(!is_sequence<optional_t>::value);
+ BOOST_STATIC_ASSERT(!is_sequence<kleene_star_t>::value);
+ BOOST_STATIC_ASSERT(!is_sequence<positive_t>::value);
+
+// is_sequential_or
+ BOOST_STATIC_ASSERT(!is_sequential_or<plain_t>::value);
+ BOOST_STATIC_ASSERT(!is_sequential_or<action_t>::value);
+
+ BOOST_STATIC_ASSERT(!is_sequential_or<alternative_t>::value);
+ BOOST_STATIC_ASSERT(!is_sequential_or<sequence_t>::value);
+ BOOST_STATIC_ASSERT(is_sequential_or<sequential_or_t>::value);
+ BOOST_STATIC_ASSERT(!is_sequential_or<intersection_t>::value);
+ BOOST_STATIC_ASSERT(!is_sequential_or<difference_t>::value);
+ BOOST_STATIC_ASSERT(!is_sequential_or<exclusive_or_t>::value);
+
+ BOOST_STATIC_ASSERT(!is_sequential_or<optional_t>::value);
+ BOOST_STATIC_ASSERT(!is_sequential_or<kleene_star_t>::value);
+ BOOST_STATIC_ASSERT(!is_sequential_or<positive_t>::value);
+
+// is_intersection
+ BOOST_STATIC_ASSERT(!is_intersection<plain_t>::value);
+ BOOST_STATIC_ASSERT(!is_intersection<action_t>::value);
+
+ BOOST_STATIC_ASSERT(!is_intersection<alternative_t>::value);
+ BOOST_STATIC_ASSERT(!is_intersection<sequence_t>::value);
+ BOOST_STATIC_ASSERT(!is_intersection<sequential_or_t>::value);
+ BOOST_STATIC_ASSERT(is_intersection<intersection_t>::value);
+ BOOST_STATIC_ASSERT(!is_intersection<difference_t>::value);
+ BOOST_STATIC_ASSERT(!is_intersection<exclusive_or_t>::value);
+
+ BOOST_STATIC_ASSERT(!is_intersection<optional_t>::value);
+ BOOST_STATIC_ASSERT(!is_intersection<kleene_star_t>::value);
+ BOOST_STATIC_ASSERT(!is_intersection<positive_t>::value);
+
+// is_difference
+ BOOST_STATIC_ASSERT(!is_difference<plain_t>::value);
+ BOOST_STATIC_ASSERT(!is_difference<action_t>::value);
+
+ BOOST_STATIC_ASSERT(!is_difference<alternative_t>::value);
+ BOOST_STATIC_ASSERT(!is_difference<sequence_t>::value);
+ BOOST_STATIC_ASSERT(!is_difference<sequential_or_t>::value);
+ BOOST_STATIC_ASSERT(!is_difference<intersection_t>::value);
+ BOOST_STATIC_ASSERT(is_difference<difference_t>::value);
+ BOOST_STATIC_ASSERT(!is_difference<exclusive_or_t>::value);
+
+ BOOST_STATIC_ASSERT(!is_difference<optional_t>::value);
+ BOOST_STATIC_ASSERT(!is_difference<kleene_star_t>::value);
+ BOOST_STATIC_ASSERT(!is_difference<positive_t>::value);
+
+// is_exclusive_or
+ BOOST_STATIC_ASSERT(!is_exclusive_or<plain_t>::value);
+ BOOST_STATIC_ASSERT(!is_exclusive_or<action_t>::value);
+
+ BOOST_STATIC_ASSERT(!is_exclusive_or<alternative_t>::value);
+ BOOST_STATIC_ASSERT(!is_exclusive_or<sequence_t>::value);
+ BOOST_STATIC_ASSERT(!is_exclusive_or<sequential_or_t>::value);
+ BOOST_STATIC_ASSERT(!is_exclusive_or<intersection_t>::value);
+ BOOST_STATIC_ASSERT(!is_exclusive_or<difference_t>::value);
+ BOOST_STATIC_ASSERT(is_exclusive_or<exclusive_or_t>::value);
+
+ BOOST_STATIC_ASSERT(!is_exclusive_or<optional_t>::value);
+ BOOST_STATIC_ASSERT(!is_exclusive_or<kleene_star_t>::value);
+ BOOST_STATIC_ASSERT(!is_exclusive_or<positive_t>::value);
+
+// is_optional
+ BOOST_STATIC_ASSERT(!is_optional<plain_t>::value);
+ BOOST_STATIC_ASSERT(!is_optional<action_t>::value);
+
+ BOOST_STATIC_ASSERT(!is_optional<alternative_t>::value);
+ BOOST_STATIC_ASSERT(!is_optional<sequence_t>::value);
+ BOOST_STATIC_ASSERT(!is_optional<sequential_or_t>::value);
+ BOOST_STATIC_ASSERT(!is_optional<intersection_t>::value);
+ BOOST_STATIC_ASSERT(!is_optional<difference_t>::value);
+ BOOST_STATIC_ASSERT(!is_optional<exclusive_or_t>::value);
+
+ BOOST_STATIC_ASSERT(is_optional<optional_t>::value);
+ BOOST_STATIC_ASSERT(!is_optional<kleene_star_t>::value);
+ BOOST_STATIC_ASSERT(!is_optional<positive_t>::value);
+
+// is_kleene_star
+ BOOST_STATIC_ASSERT(!is_kleene_star<plain_t>::value);
+ BOOST_STATIC_ASSERT(!is_kleene_star<action_t>::value);
+
+ BOOST_STATIC_ASSERT(!is_kleene_star<alternative_t>::value);
+ BOOST_STATIC_ASSERT(!is_kleene_star<sequence_t>::value);
+ BOOST_STATIC_ASSERT(!is_kleene_star<sequential_or_t>::value);
+ BOOST_STATIC_ASSERT(!is_kleene_star<intersection_t>::value);
+ BOOST_STATIC_ASSERT(!is_kleene_star<difference_t>::value);
+ BOOST_STATIC_ASSERT(!is_kleene_star<exclusive_or_t>::value);
+
+ BOOST_STATIC_ASSERT(!is_kleene_star<optional_t>::value);
+ BOOST_STATIC_ASSERT(is_kleene_star<kleene_star_t>::value);
+ BOOST_STATIC_ASSERT(!is_kleene_star<positive_t>::value);
+
+// is_positive
+ BOOST_STATIC_ASSERT(!is_positive<plain_t>::value);
+ BOOST_STATIC_ASSERT(!is_positive<action_t>::value);
+
+ BOOST_STATIC_ASSERT(!is_positive<alternative_t>::value);
+ BOOST_STATIC_ASSERT(!is_positive<sequence_t>::value);
+ BOOST_STATIC_ASSERT(!is_positive<sequential_or_t>::value);
+ BOOST_STATIC_ASSERT(!is_positive<intersection_t>::value);
+ BOOST_STATIC_ASSERT(!is_positive<difference_t>::value);
+ BOOST_STATIC_ASSERT(!is_positive<exclusive_or_t>::value);
+
+ BOOST_STATIC_ASSERT(!is_positive<optional_t>::value);
+ BOOST_STATIC_ASSERT(!is_positive<kleene_star_t>::value);
+ BOOST_STATIC_ASSERT(is_positive<positive_t>::value);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Test parser extraction templates
+void
+parser_extraction_tests()
+{
+ typedef chlit<char> plain_t;
+ typedef optional<plain_t> unary_t;
+ typedef action<plain_t, assign_actor> action_t;
+ typedef sequence<plain_t, anychar_parser> binary_t;
+
+// parser type extraction templates
+ BOOST_STATIC_ASSERT((
+ ::boost::is_same<
+ chlit<char>, unary_subject<unary_t>::type
+ >::value));
+ BOOST_STATIC_ASSERT((
+ ::boost::is_same<
+ chlit<char>, action_subject<action_t>::type
+ >::value));
+ BOOST_STATIC_ASSERT((
+ ::boost::is_same<
+ assign_actor, semantic_action<action_t>::type
+ >::value));
+ BOOST_STATIC_ASSERT((
+ ::boost::is_same<
+ chlit<char>, binary_left_subject<binary_t>::type
+ >::value));
+ BOOST_STATIC_ASSERT((
+ ::boost::is_same<
+ anychar_parser, binary_right_subject<binary_t>::type
+ >::value));
+
+// parser object extraction functions
+ BOOST_TEST(1 == parse("aaaa", get_unary_subject(*ch_p('a'))).length);
+
+char c = 'b';
+
+ BOOST_TEST(1 == parse("aaaa", get_action_subject(ch_p('a')[assign(c)])).length);
+ BOOST_TEST(c == 'b');
+
+ BOOST_TEST(1 == parse("aaaa",
+ ch_p('a')[ get_semantic_action(ch_p('b')[assign(c)]) ]).length);
+ BOOST_TEST(c == 'a');
+
+ BOOST_TEST(1 == parse("abab",
+ get_binary_left_subject(ch_p('a') >> ch_p('b'))).length);
+ BOOST_TEST(1 == parse("baba",
+ get_binary_right_subject(ch_p('a') >> ch_p('b'))).length);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ parser_traits_tests();
+ parser_extraction_tests();
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/pch.hpp b/src/boost/libs/spirit/classic/test/pch.hpp
new file mode 100644
index 00000000..94dde346
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/pch.hpp
@@ -0,0 +1,15 @@
+/*=============================================================================
+ Copyright (c) 2019 Nikita Kniazev
+
+ 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)
+=============================================================================*/
+#ifdef BOOST_BUILD_PCH_ENABLED
+
+#include <boost/spirit/include/classic.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <vector>
+#include <string>
+#include <iostream>
+
+#endif
diff --git a/src/boost/libs/spirit/classic/test/position_iterator_tests.cpp b/src/boost/libs/spirit/classic/test/position_iterator_tests.cpp
new file mode 100644
index 00000000..a1fd6ea3
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/position_iterator_tests.cpp
@@ -0,0 +1,583 @@
+/*=============================================================================
+ Copyright (c) 2003 Giovanni Bajo
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include <vector>
+#include <string>
+#include <list>
+#include <algorithm>
+#include <iterator>
+#include <cstddef>
+#include <boost/config.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/list.hpp>
+#include <boost/mpl/for_each.hpp>
+
+// Our baby
+#include <boost/spirit/include/classic_position_iterator.hpp>
+
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+namespace mpl = boost::mpl;
+
+///////////////////////////////////////////////////////////////////////////////
+namespace test_impl {
+
+template <typename IterT>
+void InstanciateTestOne(void)
+{
+ IterT();
+
+ // Check that the iterator is a full non-mutable forward iterator
+ typedef boost::ForwardIteratorConcept<IterT> concept_t;
+ boost::function_requires<concept_t>();
+}
+
+struct InstanciateTest
+{
+ template <typename BaseIterT>
+ void operator()(BaseIterT )
+ {
+ InstanciateTestOne<position_iterator<BaseIterT> >();
+ InstanciateTestOne<position_iterator2<BaseIterT> >();
+ InstanciateTestOne<position_iterator<BaseIterT, file_position_without_column> >();
+ InstanciateTestOne<position_iterator2<BaseIterT, file_position_without_column> >();
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+} /* namespace test_impl */
+
+// These tests are defined after main() to be absolutely sure that the
+// instantiation test will happen before any other (since it's mainly
+// a compile-time test).
+void CheckInstantiation(void);
+void CheckConstructors(void);
+void CheckBasicFunctionality(void);
+void CheckColumnCounting(void);
+void CheckLineExtraction(void);
+void CheckDistance(void);
+void CheckSingular();
+
+void CheckInstantiation(void)
+{
+ typedef mpl::list
+ <
+ char*
+ ,const char*
+ ,string::iterator
+ ,string::const_iterator
+ > iter_list_t;
+
+ mpl::for_each<iter_list_t>(test_impl::InstanciateTest());
+}
+
+int main(void)
+{
+ CheckInstantiation();
+ CheckConstructors();
+ CheckBasicFunctionality();
+ CheckColumnCounting();
+ CheckLineExtraction();
+ CheckDistance();
+ CheckSingular();
+
+ return boost::report_errors();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace test_impl {
+
+template <typename IterT>
+void CheckIncrement(IterT iter)
+{
+ IterT end;
+
+ // Check also that copy construction and assignment do not
+ // interfere with increment
+ IterT iter2(iter);
+ IterT iter3 = iter;
+
+ BOOST_TEST(iter != end);
+ BOOST_TEST(iter2 != end);
+ BOOST_TEST(iter3 != end);
+ BOOST_TEST(*iter == '0');
+
+ ++iter;
+ ++iter2;
+ ++iter3;
+ BOOST_TEST(iter == iter2);
+ BOOST_TEST(iter == iter3);
+ BOOST_TEST(*iter == *iter2);
+ BOOST_TEST(*iter == *iter3);
+ BOOST_TEST(iter.get_position() == iter2.get_position());
+ BOOST_TEST(iter.get_position() == iter3.get_position());
+ BOOST_TEST(*iter == '1');
+
+ BOOST_TEST(*iter++ == '1');
+ BOOST_TEST(*iter2++ == '1');
+ BOOST_TEST(*iter3++ == '1');
+ BOOST_TEST(*iter == *iter2);
+ BOOST_TEST(*iter == *iter3);
+ BOOST_TEST(iter.get_position() == iter2.get_position());
+ BOOST_TEST(iter.get_position() == iter3.get_position());
+ BOOST_TEST(*iter == '2');
+
+ ++iter; ++iter; ++iter; ++iter; ++iter; ++iter; ++iter;
+ BOOST_TEST(*iter == '9');
+ ++iter;
+ BOOST_TEST(iter == end);
+
+ // Check that one after end is no more end
+ ++iter;
+ BOOST_TEST(iter != end);
+}
+
+template <typename IterT>
+void CheckLineCounting(IterT iter)
+{
+ IterT end;
+
+ BOOST_TEST(*iter == '\n');
+ BOOST_TEST(iter.get_position().line == 1);
+ ++iter; // 0
+ BOOST_TEST(iter.get_position().line == 2);
+ ++iter; // 1
+ ++iter; // 2
+ ++iter; // 3
+ ++iter; // \r
+ BOOST_TEST(*iter == '\r');
+ BOOST_TEST(iter.get_position().line == 2);
+ ++iter; // \n
+ BOOST_TEST(*iter == '\n');
+ BOOST_TEST(iter.get_position().line == 2);
+ ++iter; // 4
+ BOOST_TEST(iter.get_position().line == 3);
+ ++iter; // 5
+ ++iter; // 6
+ ++iter; // 7
+ ++iter; // \n
+ BOOST_TEST(*iter == '\n');
+ BOOST_TEST(iter.get_position().line == 3);
+ ++iter; // 8
+ BOOST_TEST(iter.get_position().line == 4);
+ ++iter; // 9
+ ++iter; // \n
+ BOOST_TEST(iter.get_position().line == 4);
+ BOOST_TEST(*iter == '\n');
+ ++iter; // \r
+ BOOST_TEST(iter.get_position().line == 5);
+ BOOST_TEST(*iter == '\r');
+ ++iter; // end
+ BOOST_TEST(iter.get_position().line == 6);
+ BOOST_TEST(iter == end);
+}
+
+template <typename IterT>
+void CheckColumnCounting_Tab4(IterT iter)
+{
+ IterT end;
+
+ // Don't call set_tabchars() here because
+ // default must be 3.
+ BOOST_TEST(*iter == '\t');
+ BOOST_TEST(iter.get_position().column == 1);
+ ++iter; // 0
+ BOOST_TEST(iter.get_position().column == 5);
+ ++iter; // 1
+ BOOST_TEST(iter.get_position().column == 6);
+ ++iter; // 2
+ BOOST_TEST(iter.get_position().column == 7);
+ ++iter; // 3
+ BOOST_TEST(iter.get_position().column == 8);
+ ++iter; // tab
+ BOOST_TEST(*iter == '\t');
+ BOOST_TEST(iter.get_position().column == 9);
+ ++iter; // 4
+ BOOST_TEST(iter.get_position().column == 13);
+ ++iter; // tab
+ BOOST_TEST(*iter == '\t');
+ BOOST_TEST(iter.get_position().column == 14);
+ ++iter; // 5
+ BOOST_TEST(iter.get_position().column == 17);
+ ++iter; // tab
+ BOOST_TEST(*iter == '\t');
+ BOOST_TEST(iter.get_position().column == 18);
+ ++iter; // end
+ BOOST_TEST(iter == end);
+}
+
+template <typename IterT>
+void CheckColumnCounting_Tab3(IterT iter)
+{
+ IterT end;
+
+ iter.set_tabchars(3);
+
+ // Check also that tab settings propagates through
+ // assignment and copy construction
+ IterT iter2(iter);
+ IterT iter3; iter3 = iter2;
+
+ BOOST_TEST(*iter == '\t');
+ BOOST_TEST(iter.get_position().column == 1);
+ ++iter; // 0
+ ++iter2; ++iter3;
+ BOOST_TEST(iter.get_position().column == 4);
+ BOOST_TEST(iter2.get_position().column == 4);
+ BOOST_TEST(iter3.get_position().column == 4);
+ ++iter; // 1
+ BOOST_TEST(iter.get_position().column == 5);
+ ++iter; // 2
+ BOOST_TEST(iter.get_position().column == 6);
+ ++iter; // 3
+ BOOST_TEST(iter.get_position().column == 7);
+ ++iter; // tab
+ BOOST_TEST(*iter == '\t');
+ BOOST_TEST(iter.get_position().column == 8);
+ ++iter; // 4
+ BOOST_TEST(iter.get_position().column == 10);
+ ++iter; // tab
+ BOOST_TEST(*iter == '\t');
+ BOOST_TEST(iter.get_position().column == 11);
+ ++iter; // 5
+ BOOST_TEST(iter.get_position().column == 13);
+ ++iter; // tab
+ BOOST_TEST(*iter == '\t');
+ BOOST_TEST(iter.get_position().column == 14);
+ ++iter; // end
+ BOOST_TEST(iter == end);
+}
+
+const string line1 = "abcd";
+const string line2 = "efgh";
+const string linebuf = "\n" + line1 + "\n" + line2 + "\n";
+
+template <typename IterT>
+void AssertIterString(IterT begin, IterT end, string s)
+{
+ BOOST_TEST(string(begin, end) == s);
+}
+
+template <typename IterT>
+void CheckLineExtractionOne(IterT iter)
+{
+ IterT end;
+
+ // At the start, we are on a newline, which is an empty
+ // string
+ BOOST_TEST(iter.get_currentline() == string());
+ BOOST_TEST(
+ string(iter.get_currentline_begin(), iter.get_currentline_end())
+ == string());
+
+ ++iter; // a
+ ++iter; // b
+ ++iter; // c
+ BOOST_TEST(iter.get_currentline() == line1);
+ AssertIterString(
+ iter.get_currentline_begin(),
+ iter.get_currentline_end(),
+ line1);
+
+ ++iter; // d
+ ++iter; // newline
+ ++iter; // e
+
+ // check that copy construction and assignment do
+ // not interfere with get_currentline
+ IterT iter2(iter);
+ IterT iter3; iter3 = iter;
+ BOOST_TEST(iter2.get_currentline() == line2);
+ BOOST_TEST(iter3.get_currentline() == line2);
+ AssertIterString(
+ iter2.get_currentline_begin(),
+ iter2.get_currentline_end(),
+ line2);
+ AssertIterString(
+ iter3.get_currentline_begin(),
+ iter3.get_currentline_end(),
+ line2);
+
+ ++iter; // f
+ ++iter; // g
+ ++iter; // h
+ ++iter; // newline
+
+ // Check when the iterator is on a newline
+ BOOST_TEST(iter.get_currentline() == line2);
+ AssertIterString(
+ iter.get_currentline_begin(),
+ iter.get_currentline_end(),
+ line2);
+
+ ++iter;
+ BOOST_TEST(iter == end);
+}
+
+
+void CheckLineExtraction(void)
+{
+ typedef string::const_iterator iter_t;
+
+ CheckLineExtractionOne(
+ position_iterator2<iter_t, file_position>
+ (linebuf.begin(), linebuf.end(), ""));
+
+ CheckLineExtractionOne(
+ position_iterator2<iter_t, file_position_without_column>
+ (linebuf.begin(), linebuf.end(), ""));
+}
+
+template <typename IterT>
+void CheckEmptySequence(void)
+{
+ typedef IterT iter_t;
+ char a[10];
+
+ // Check construction with empty sequence, and
+ // correct propagation of the information
+ iter_t iter(a,a, "");
+ iter_t iter2(iter);
+ iter_t iter3; iter3 = iter;
+
+ BOOST_TEST(iter == iter_t());
+ BOOST_TEST(iter2 == iter_t());
+ BOOST_TEST(iter3 == iter_t());
+}
+
+template <typename IterC, typename Iter>
+void CheckConstructors(void)
+{
+ char a[20];
+ std::string name = "abc";
+
+ file_position_without_column pos(name,1);
+ file_position posc(name,1,1);
+ typedef IterC iterc_t;
+ typedef Iter iter_t;
+
+ BOOST_TEST(iterc_t(a,a+20,name).get_position() == posc);
+ BOOST_TEST(iterc_t(a,a+20,name,1).get_position() == posc);
+ BOOST_TEST(iterc_t(a,a+20,name,1,1).get_position() == posc);
+ BOOST_TEST(iterc_t(a,a+20,posc).get_position() == posc);
+ BOOST_TEST(iter_t(a,a+20,name).get_position() == pos);
+ BOOST_TEST(iter_t(a,a+20,name,1).get_position() == pos);
+ BOOST_TEST(iter_t(a,a+20,pos).get_position() == pos);
+
+ // Check copy constructor and assignment. Notice that we want
+ // an implicit copy constructor.
+ iterc_t ic1(a,a+20,name);
+ iterc_t ic2 = ic1;
+ iterc_t ic3; ic3 = ic1;
+ BOOST_TEST(ic1 == ic2);
+ BOOST_TEST(ic1 == ic3);
+ BOOST_TEST(ic1.get_position() == ic2.get_position());
+ BOOST_TEST(ic1.get_position() == ic3.get_position());
+
+ iter_t i1(a,a+20,name);
+ iter_t i2 = i1;
+ iter_t i3; i3 = i1;
+ BOOST_TEST(i1 == i2);
+ BOOST_TEST(i1 == i3);
+ BOOST_TEST(i1.get_position() == i2.get_position());
+ BOOST_TEST(i1.get_position() == i3.get_position());
+
+ // Check construction with an empty sequence
+ CheckEmptySequence<iter_t>();
+ CheckEmptySequence<iterc_t>();
+}
+
+template <typename IterT>
+void CheckDistance(IterT begin)
+{
+ IterT end;
+
+ std::size_t std_distance = std::distance(begin, end);
+
+ std::size_t manual_count = 0;
+ for(IterT it = begin; it != end; ++it)
+ ++manual_count;
+
+ BOOST_TEST(std_distance == manual_count);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+} /* namespace test_impl */
+
+
+void CheckConstructors(void)
+{
+ test_impl::CheckConstructors
+ <
+ position_iterator<char*, file_position>,
+ position_iterator<char*, file_position_without_column>
+ >();
+
+ test_impl::CheckConstructors
+ <
+ position_iterator2<char*, file_position>,
+ position_iterator2<char*, file_position_without_column>
+ >();
+}
+
+void CheckBasicFunctionality(void)
+{
+ const char* a = "0123456789";
+ typedef const char* iter_t;
+
+ test_impl::CheckIncrement(position_iterator<iter_t>(a, a+10, ""));
+ test_impl::CheckIncrement(position_iterator2<iter_t>(a, a+10, ""));
+ test_impl::CheckIncrement(position_iterator<iter_t, file_position_without_column>(a, a+10, ""));
+ test_impl::CheckIncrement(position_iterator2<iter_t, file_position_without_column>(a, a+10, ""));
+
+ const char* b = "\n0123\r\n4567\n89\n\r";
+
+ test_impl::CheckLineCounting(position_iterator<iter_t>(b, b+16, ""));
+ test_impl::CheckLineCounting(position_iterator2<iter_t>(b, b+16, ""));
+ test_impl::CheckLineCounting(position_iterator<iter_t, file_position_without_column>(b, b+16, ""));
+ test_impl::CheckLineCounting(position_iterator2<iter_t, file_position_without_column>(b, b+16, ""));
+}
+
+
+void CheckColumnCounting(void)
+{
+ const char* a = "\t0123\t4\t5\t";
+ typedef const char* iter_t;
+
+ test_impl::CheckColumnCounting_Tab4(position_iterator<iter_t>(a, a+10, ""));
+ test_impl::CheckColumnCounting_Tab4(position_iterator2<iter_t>(a, a+10, ""));
+ test_impl::CheckColumnCounting_Tab3(position_iterator<iter_t>(a, a+10, ""));
+ test_impl::CheckColumnCounting_Tab3(position_iterator2<iter_t>(a, a+10, ""));
+}
+
+void CheckLineExtraction(void)
+{
+ test_impl::CheckLineExtraction();
+}
+
+void CheckDistance(void)
+{
+ const char* b = "\n0123\r\n4567\n89\n\r";
+ typedef const char* iter_t;
+
+ test_impl::CheckDistance(position_iterator<iter_t>(b, b+15, ""));
+ test_impl::CheckDistance(position_iterator2<iter_t>(b, b+15, ""));
+ test_impl::CheckDistance(position_iterator<iter_t, file_position_without_column>(b, b+15, ""));
+ test_impl::CheckDistance(position_iterator2<iter_t, file_position_without_column>(b, b+15, ""));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace test_impl {
+
+ template <bool AsValue = false>
+ class check_singular_iterator
+ {
+ bool singular_;
+ int count_;
+
+ public:
+ typedef std::forward_iterator_tag iterator_category;
+ typedef int value_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef int const* pointer;
+ typedef typename boost::mpl::if_c<AsValue, int, int const&>::type reference;
+
+ check_singular_iterator() : singular_(true), count_(0) {}
+ explicit check_singular_iterator(int x) : singular_(false), count_(x) {}
+
+ reference operator*() const {
+ BOOST_TEST(!singular_);
+ return count_;
+ }
+
+ pointer operator->() const {
+ BOOST_TEST(!singular_);
+ return &count_;
+ }
+
+ check_singular_iterator& operator++() {
+ BOOST_TEST(count_ > 0);
+ --count_;
+ return *this;
+ }
+
+ check_singular_iterator operator++(int) {
+ check_singular_iterator tmp(*this);
+ ++(*this);
+ return tmp;
+ }
+
+ bool operator==(check_singular_iterator const& other) const {
+ BOOST_TEST(!singular_ && !other.singular_);
+ return count_ == other.count_;
+ }
+
+ bool operator!=(check_singular_iterator const& other) const {
+ return !(*this == other);
+ }
+ };
+
+ template <typename CountIterator, typename Iterator>
+ void CheckSingularImpl()
+ {
+ CountIterator begin(Iterator(5), Iterator(0));
+ CountIterator end1(Iterator(0), Iterator(0));
+ CountIterator end2;
+
+ BOOST_TEST(begin == begin);
+ BOOST_TEST(begin != end1);
+ BOOST_TEST(begin != end2);
+
+ BOOST_TEST(end1 != begin);
+ BOOST_TEST(end1 == end1);
+ BOOST_TEST(end1 == end2);
+
+ BOOST_TEST(end2 != begin);
+ BOOST_TEST(end2 == end1);
+ BOOST_TEST(end2 == end2);
+
+ BOOST_TEST(std::distance(begin, begin) == 0);
+ BOOST_TEST(std::distance(begin, end1) == 5);
+ BOOST_TEST(std::distance(begin, end2) == 5);
+
+ BOOST_TEST(std::distance(end1, end1) == 0);
+ BOOST_TEST(std::distance(end1, end2) == 0);
+
+ BOOST_TEST(std::distance(end2, end1) == 0);
+ BOOST_TEST(std::distance(end2, end2) == 0);
+
+ BOOST_TEST(*begin == 5);
+ }
+
+ template <typename PositionT>
+ void CheckSingular()
+ {
+ {
+ typedef check_singular_iterator<false> interator_type;
+ CheckSingularImpl<position_iterator<interator_type, PositionT>, interator_type>();
+ CheckSingularImpl<position_iterator2<interator_type, PositionT>, interator_type>();
+ }
+ {
+ typedef check_singular_iterator<true> interator_type;
+ CheckSingularImpl<position_iterator<interator_type, PositionT>, interator_type>();
+ CheckSingularImpl<position_iterator2<interator_type, PositionT>, interator_type>();
+ }
+ }
+}
+
+void CheckSingular()
+{
+ test_impl::CheckSingular<file_position>();
+ test_impl::CheckSingular<file_position_without_column>();
+}
diff --git a/src/boost/libs/spirit/classic/test/post_skips.cpp b/src/boost/libs/spirit/classic/test/post_skips.cpp
new file mode 100644
index 00000000..97b8aba1
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/post_skips.cpp
@@ -0,0 +1,113 @@
+/*=============================================================================
+ Copyright (c) 2004 Joao Abecasis
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include <boost/spirit/include/classic_parser.hpp>
+#include <boost/spirit/include/classic_skipper.hpp>
+#include <boost/spirit/include/classic_primitives.hpp>
+#include <boost/spirit/include/classic_optional.hpp>
+#include <boost/spirit/include/classic_sequence.hpp>
+#include <boost/spirit/include/classic_ast.hpp>
+#include <boost/spirit/include/classic_parse_tree.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+char const * test1 = " 12345 ";
+char const * test2 = " 12345 x";
+
+void parse_tests()
+{
+ parse_info<> info;
+
+ // Warming up...
+ info = parse(test1, str_p("12345"));
+ BOOST_TEST(!info.hit);
+
+ // No post-skips!
+ info = parse(test1, str_p("12345"), blank_p);
+ BOOST_TEST(info.hit);
+ BOOST_TEST(!info.full);
+
+ // Require a full match
+ info = parse(test1, str_p("12345") >> end_p, blank_p);
+ BOOST_TEST(info.full);
+ info = parse(test2, str_p("12345") >> end_p, blank_p);
+ BOOST_TEST(!info.hit);
+
+ // Check for a full match but don't make it a requirement
+ info = parse(test1, str_p("12345") >> !end_p, blank_p);
+ BOOST_TEST(info.full);
+ info = parse(test2, str_p("12345") >> !end_p, blank_p);
+ BOOST_TEST(info.hit);
+ BOOST_TEST(!info.full);
+}
+
+void ast_parse_tests()
+{
+ tree_parse_info<> info;
+
+ // Warming up...
+ info = ast_parse(test1, str_p("12345"));
+ BOOST_TEST(!info.match);
+
+ // No post-skips!
+ info = ast_parse(test1, str_p("12345"), blank_p);
+ BOOST_TEST(info.match);
+ BOOST_TEST(!info.full);
+
+ // Require a full match
+ info = ast_parse(test1, str_p("12345") >> end_p, blank_p);
+ BOOST_TEST(info.full);
+ info = ast_parse(test2, str_p("12345") >> end_p, blank_p);
+ BOOST_TEST(!info.match);
+
+ // Check for a full match but don't make it a requirement
+ info = ast_parse(test1, str_p("12345") >> !end_p, blank_p);
+ BOOST_TEST(info.full);
+ info = ast_parse(test2, str_p("12345") >> !end_p, blank_p);
+ BOOST_TEST(info.match);
+ BOOST_TEST(!info.full);
+}
+
+void pt_parse_tests()
+{
+ tree_parse_info<> info;
+
+ // Warming up...
+ info = pt_parse(test1, str_p("12345"));
+ BOOST_TEST(!info.match);
+
+ // No post-skips!
+ info = pt_parse(test1, str_p("12345"), blank_p);
+ BOOST_TEST(info.match);
+ BOOST_TEST(!info.full);
+
+ // Require a full match
+ info = pt_parse(test1, str_p("12345") >> end_p, blank_p);
+ BOOST_TEST(info.full);
+ info = pt_parse(test2, str_p("12345") >> end_p, blank_p);
+ BOOST_TEST(!info.match);
+
+ // Check for a full match but don't make it a requirement
+ info = pt_parse(test1, str_p("12345") >> !end_p, blank_p);
+ BOOST_TEST(info.full);
+ info = pt_parse(test2, str_p("12345") >> !end_p, blank_p);
+ BOOST_TEST(info.match);
+ BOOST_TEST(!info.full);
+}
+
+int main()
+{
+ parse_tests();
+ ast_parse_tests();
+ pt_parse_tests();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/primitives_tests.cpp b/src/boost/libs/spirit/classic/test/primitives_tests.cpp
new file mode 100644
index 00000000..c5772e02
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/primitives_tests.cpp
@@ -0,0 +1,135 @@
+/*=============================================================================
+ Copyright (c) 1998-2003 Joel de Guzman
+ Copyright (c) 2002-2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include "impl/string_length.hpp"
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Primitives tests
+//
+///////////////////////////////////////////////////////////////////////////////
+void
+primitives_tests()
+{
+ char const* cp = "xyz.Jambalaya";
+ char const* cp_first = cp;
+ char const* cp_last = cp + test_impl::string_length(cp);
+
+ chlit<> cpx('x');
+ parse_info<char const*> pi = parse(cp_first, cp_last, cpx);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(!pi.full);
+ BOOST_TEST(pi.length == 1);
+ BOOST_TEST(pi.stop == &cp[1]);
+
+ pi = parse(pi.stop, ch_p('y'));
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(!pi.full);
+ BOOST_TEST(pi.length == 1);
+ BOOST_TEST(pi.stop == &cp[2]);
+
+ scanner<char const*> scan(pi.stop, cp_last);
+ match<char> hit = ch_p('z').parse(scan);
+ BOOST_TEST(hit);
+ BOOST_TEST(hit.value() == 'z');
+ BOOST_TEST(pi.stop == &cp[3]);
+
+ pi = parse(pi.stop, eps_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(!pi.full);
+ BOOST_TEST(pi.length == 0);
+ BOOST_TEST(pi.stop == &cp[3]);
+
+ pi = parse(pi.stop, nothing_p);
+ BOOST_TEST(!pi.hit);
+ BOOST_TEST(!pi.full);
+ BOOST_TEST(pi.stop == &cp[3]);
+
+ pi = parse(pi.stop, anychar_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(!pi.full);
+ BOOST_TEST(pi.length == 1);
+ BOOST_TEST(pi.stop == &cp[4]);
+
+ scan.first = pi.stop;
+ hit = range_p('A','Z').parse(scan);
+ BOOST_TEST(hit);
+ BOOST_TEST(hit.value() == 'J');
+ BOOST_TEST(pi.stop == &cp[5]);
+
+ strlit<char const*> sp("ambalaya");
+ strlit<wchar_t const*> wsp(L"ambalaya");
+
+ char const* save = pi.stop;
+ pi = parse(save, sp);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 8);
+ BOOST_TEST(pi.stop == cp_last);
+
+ pi = parse(save, wsp);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 8);
+ BOOST_TEST(pi.stop == cp_last);
+
+ pi = parse("\n", eol_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse("\r", eol_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse("\r\n", eol_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse("\n\r", eol_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(!pi.full);
+
+ pi = parse("", end_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse("1", ~alpha_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse("a", ~alpha_p);
+ BOOST_TEST(!pi.hit);
+
+ pi = parse("a", ~~alpha_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse("1", ~~alpha_p);
+ BOOST_TEST(!pi.hit);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ primitives_tests();
+ if (boost::report_errors() == 0)
+ std::cout << "Tests concluded successfully\n";
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/repeat_ast_tests.cpp b/src/boost/libs/spirit/classic/test/repeat_ast_tests.cpp
new file mode 100644
index 00000000..5091f76e
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/repeat_ast_tests.cpp
@@ -0,0 +1,95 @@
+/*=============================================================================
+ Copyright (c) 2004 Chris Hoeppler
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+// This test verifies, that reapeat_p et.al. work correctly while using AST's
+
+# include <map>
+# include <boost/detail/lightweight_test.hpp>
+# include <iostream>
+# include <string>
+
+# include <boost/spirit/include/classic_core.hpp>
+# include <boost/spirit/include/classic_loops.hpp>
+# include <boost/spirit/include/classic_ast.hpp>
+# include <boost/spirit/include/classic_tree_to_xml.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+static const int numID = 1;
+static const int funcID = 2;
+static const int expressionID = 3;
+
+struct grammar_fail : public grammar<grammar_fail>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(grammar_fail const& /*self */)
+ {
+ num = leaf_node_d[real_p];
+ func = root_node_d[ch_p('+') | '-']
+ >> repeat_p(2)[expression];
+ expression = func | num;
+ }
+ rule<ScannerT, parser_context<>, parser_tag<numID> > num;
+ rule<ScannerT, parser_context<>, parser_tag<funcID> > func;
+ typedef rule<ScannerT, parser_context<>, parser_tag<expressionID> > expr_t;
+ expr_t expression;
+ expr_t const& start() const { return expression; }
+ };
+};
+struct grammar_success : public grammar<grammar_success>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(grammar_success const& /*self */)
+ {
+ num = leaf_node_d[real_p];
+ func = root_node_d[ch_p('+') | '-']
+ >> expression >> expression; // line differing from grammar_fail
+ expression = func | num;
+ }
+ rule<ScannerT, parser_context<>, parser_tag<numID> > num;
+ rule<ScannerT, parser_context<>, parser_tag<funcID> > func;
+ typedef rule<ScannerT, parser_context<>, parser_tag<expressionID> > expr_t;
+ expr_t expression;
+ expr_t const& start() const { return expression; }
+ };
+};
+
+int main() {
+
+ std::map<parser_id, std::string> rule_names;
+ rule_names[expressionID] = "expression";
+ rule_names[funcID] = "func";
+ rule_names[numID] = "num";
+
+ std::string test("+ 1 - 2 3");
+
+// case 1
+ grammar_fail g_fail;
+ tree_parse_info<> info1 = ast_parse(test.c_str(), g_fail, space_p);
+ BOOST_TEST(info1.full);
+
+ //std::cout << "...Case 1: Using repeat_p\n";
+ //tree_to_xml(std::cerr, info1.trees, test, rule_names);
+
+// case 2
+ grammar_success g_success;
+ tree_parse_info<> info2 = ast_parse(test.c_str(), g_success, space_p);
+ BOOST_TEST(info2.full);
+
+ //std::cout << "...Case 2: No repeat_p\n";
+ //tree_to_xml(std::cerr, info2.trees, test, rule_names);
+ // could be used for test case instead of printing the xml stuff:
+ BOOST_TEST(info2.trees.begin()->children.size() == 2);
+ BOOST_TEST(info1.trees.begin()->children.size() == 2);
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/rule_tests.cpp b/src/boost/libs/spirit/classic/test/rule_tests.cpp
new file mode 100644
index 00000000..65210a03
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/rule_tests.cpp
@@ -0,0 +1,264 @@
+/*=============================================================================
+ Copyright (c) 1998-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+
+//#define BOOST_SPIRIT_DEBUG
+#define BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT 3
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_stored_rule.hpp>
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Rule tests
+//
+///////////////////////////////////////////////////////////////////////////////
+void
+aliasing_tests()
+{
+ rule<> a = ch_p('a');
+ rule<> b = ch_p('b');
+ rule<> c = ch_p('c');
+
+ std::cout << "sizeof(rule<>): " << sizeof(rule<>) << std::endl;
+
+ BOOST_SPIRIT_DEBUG_RULE(a);
+ BOOST_SPIRIT_DEBUG_RULE(b);
+ BOOST_SPIRIT_DEBUG_RULE(c);
+
+ rule<> start;
+ BOOST_SPIRIT_DEBUG_RULE(start);
+
+ rule<> d;
+ d = start; // aliasing
+
+ parse_info<char const*> pi;
+
+ start = *(a | b | c);
+ pi = parse("abcabcacb", d);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 9);
+ BOOST_TEST(*pi.stop == 0);
+
+ start = (a | b) >> (start | b);
+ pi = parse("aaaabababaaabbb", d);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 15);
+ BOOST_TEST(*pi.stop == 0);
+}
+
+void
+rule_template_param_tests()
+{
+ // test that rules can be issued its template params in any order:
+
+ rule<> rx1;
+ rule<scanner<> > rx2;
+ rule<scanner<>, parser_context<> > rx3;
+ rule<scanner<>, parser_context<>, parser_address_tag> rx4;
+
+ rule<parser_context<> > rx5;
+ rule<parser_context<>, parser_address_tag> rx6;
+ rule<parser_context<>, parser_address_tag, scanner<> > rx7;
+
+ rule<parser_address_tag> rx8;
+ rule<parser_address_tag, scanner<> > rx9;
+ rule<parser_address_tag, scanner<>, parser_context<> > rx10;
+
+ rule<parser_address_tag, parser_context<> > rx11;
+ rule<parser_address_tag, parser_context<>, scanner<> > rx12;
+
+ rule<parser_context<>, scanner<> > rx13;
+ rule<parser_context<>, scanner<>, parser_address_tag> rx14;
+}
+
+struct my_grammar : public grammar<my_grammar>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(my_grammar const& /*self*/)
+ {
+ r = lower_p;
+ rr = +(lexeme_d[r] >> as_lower_d[r] >> r);
+ }
+
+ typedef scanner_list<
+ ScannerT
+ , typename lexeme_scanner<ScannerT>::type
+ , typename as_lower_scanner<ScannerT>::type
+ > scanners;
+
+ rule<scanners> r;
+ rule<ScannerT> rr;
+ rule<ScannerT> const& start() const { return rr; }
+ };
+};
+
+void
+rule_2_or_more_scanners_tests()
+{
+ { // 2 scanners
+ typedef scanner_list<scanner<>, phrase_scanner_t> scanners;
+
+ rule<scanners> r = +anychar_p;
+ BOOST_TEST(parse("abcdefghijk", r).full);
+ BOOST_TEST(parse("a b c d e f g h i j k", r, space_p).full);
+ }
+
+ { // 3 scanners
+ my_grammar g;
+ BOOST_TEST(parse("abcdef aBc d e f aBc d E f", g, space_p).full);
+ }
+}
+
+void
+rule_basic_tests()
+{
+ rule<> a = ch_p('a');
+ rule<> b = ch_p('b');
+ rule<> c = ch_p('c');
+
+ BOOST_SPIRIT_DEBUG_RULE(a);
+ BOOST_SPIRIT_DEBUG_RULE(b);
+ BOOST_SPIRIT_DEBUG_RULE(c);
+
+ parse_info<char const*> pi;
+
+ rule<> start = *(a | b | c);
+
+ BOOST_SPIRIT_DEBUG_RULE(start);
+
+ pi = parse("abcabcacb", start);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 9);
+ BOOST_TEST(*pi.stop == 0);
+
+ start = (a | b) >> (start | b);
+ pi = parse("aaaabababaaabbb", start);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 15);
+ BOOST_TEST(*pi.stop == 0);
+
+ pi = parse("aaaabababaaabba", start);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(!pi.full);
+ BOOST_TEST(pi.length == 14);
+
+ rule<> r = anychar_p;
+ r.copy(); // copy test (compile only)
+}
+
+void
+stored_rule_basic_tests()
+{
+ stored_rule<> a = ch_p('a');
+ stored_rule<> b = ch_p('b');
+ stored_rule<> c = ch_p('c');
+
+ BOOST_SPIRIT_DEBUG_RULE(a);
+ BOOST_SPIRIT_DEBUG_RULE(b);
+ BOOST_SPIRIT_DEBUG_RULE(c);
+
+ parse_info<char const*> pi;
+
+ stored_rule<> start = *(a | b | c);
+
+ BOOST_SPIRIT_DEBUG_RULE(start);
+
+ pi = parse("abcabcacb", start);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 9);
+ BOOST_TEST(*pi.stop == 0);
+
+ start = (a | b) >> (start | b);
+ pi = parse("aaaabababaaabbb", start);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 15);
+ BOOST_TEST(*pi.stop == 0);
+
+ pi = parse("aaaabababaaabba", start);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(!pi.full);
+ BOOST_TEST(pi.length == 14);
+}
+
+void
+stored_rule_dynamic_tests()
+{
+ rule<> a = ch_p('a');
+ rule<> b = ch_p('b');
+ rule<> c = ch_p('c');
+
+ BOOST_SPIRIT_DEBUG_RULE(a);
+ BOOST_SPIRIT_DEBUG_RULE(b);
+ BOOST_SPIRIT_DEBUG_RULE(c);
+
+ parse_info<char const*> pi;
+
+ // The FF is the dynamic equivalent of start = *(a | b | c);
+ stored_rule<> start = a;
+ start = start.copy() | b;
+ start = start.copy() | c;
+ start = *(start.copy());
+
+ std::cout << "sizeof(stored_rule<>): " << sizeof(stored_rule<>) << std::endl;
+
+ BOOST_SPIRIT_DEBUG_RULE(start);
+
+ pi = parse("abcabcacb", start);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 9);
+ BOOST_TEST(*pi.stop == 0);
+
+ // The FF is the dynamic equivalent of start = (a | b) >> (start | b);
+ start = b;
+ start = a | start.copy();
+ start = start.copy() >> (start | b);
+
+ pi = parse("aaaabababaaabbb", start);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 15);
+ BOOST_TEST(*pi.stop == 0);
+
+ pi = parse("aaaabababaaabba", start);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(!pi.full);
+ BOOST_TEST(pi.length == 14);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ rule_basic_tests();
+ aliasing_tests();
+ rule_template_param_tests();
+ rule_2_or_more_scanners_tests();
+ stored_rule_basic_tests();
+ stored_rule_dynamic_tests();
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/scanner_tests.cpp b/src/boost/libs/spirit/classic/test/scanner_tests.cpp
new file mode 100644
index 00000000..69f69509
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/scanner_tests.cpp
@@ -0,0 +1,140 @@
+/*=============================================================================
+ Copyright (c) 1998-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+#include <list>
+
+
+#include <boost/spirit/include/classic_core.hpp>
+#include "impl/string_length.hpp"
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Scanner tests
+//
+///////////////////////////////////////////////////////////////////////////////
+struct to_upper_iter_policy : public iteration_policy {
+
+ char filter(char ch) const
+ { using namespace std; return char(toupper(ch)); }
+};
+
+inline bool test_isspace(char c)
+{
+ using namespace std; return isspace(c) != 0;
+}
+
+inline bool test_islower(char c)
+{
+ using namespace std; return islower(c) != 0;
+}
+
+struct skip_white_iter_policy : public iteration_policy {
+
+ template <typename ScannerT>
+ void
+ advance(ScannerT const& scan) const
+ {
+ do
+ ++scan.first;
+ while (!at_end(scan) && test_isspace(get(scan)));
+ }
+};
+
+void
+scanner_tests()
+{
+ char const* cp = "The Big Brown Fox Jumped \n\tOver The Lazy Dog's Back";
+ char const* cp_first = cp;
+ char const* cp_last = cp + test_impl::string_length(cp);
+
+ scanner<char const*>
+ pp1(cp_first, cp_last);
+
+ // compile check only...
+ scanner<> spp1(pp1); (void)spp1;
+ scanner<> spp2(pp1); (void)spp2;
+ // spp1 = spp2;
+ // compile check only...
+
+ while (!pp1.at_end())
+ {
+ std::cout << *pp1;
+ ++pp1;
+ }
+ std::cout << '\n';
+ cp_first = cp;
+
+ std::list<char> li(cp_first, cp_last);
+ std::list<char>::iterator li_first = li.begin();
+ std::list<char>::iterator li_last = li.end();
+
+ scanner<std::list<char>::iterator>
+ pp2(li_first, li_last);
+
+ while (!pp2.at_end())
+ {
+ std::cout << *pp2;
+ ++pp2;
+ }
+ std::cout << '\n';
+ li_first = li.begin();
+
+ scanner<char const*, scanner_policies<to_upper_iter_policy> >
+ pp3(cp_first, cp_last);
+
+ while (!pp3.at_end())
+ {
+ std::cout << *pp3;
+ BOOST_TEST(!test_islower(*pp3));
+ ++pp3;
+ }
+ std::cout << '\n';
+ cp_first = cp;
+
+ scanner<char const*, scanner_policies<skip_white_iter_policy> >
+ pp4(cp_first, cp_last);
+
+ // compile check only...
+ pp1.change_policies(scanner_policies<skip_white_iter_policy>());
+ // compile check only...
+
+ while (!pp4.at_end())
+ {
+ std::cout << *pp4;
+ BOOST_TEST(!test_isspace(*pp4));
+ ++pp4;
+ }
+ std::cout << '\n';
+ cp_first = cp;
+
+ std::cout << "sizeof(scanner<>) == " << sizeof(scanner<>) << '\n';
+
+ parse_info<> pi = parse("12abcdefg12345ABCDEFG789", +digit_p, alpha_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ pi = parse("abcdefg12345ABCDEFG789", +digit_p, alpha_p);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ scanner_tests();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/scanner_value_type_tests.cpp b/src/boost/libs/spirit/classic/test/scanner_value_type_tests.cpp
new file mode 100644
index 00000000..ac7f4ff6
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/scanner_value_type_tests.cpp
@@ -0,0 +1,139 @@
+/*=============================================================================
+ Copyright (c) 2005 Jordan DeLong
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+// Some tests of parsing on value_t's that aren't char or wchar_t.
+//
+// Part of what this is testing is that BOOST_SPIRIT_DEBUG doesn't
+// break when the scanner::value_t is some sort of non-char.
+#define SPIRIT_DEBUG_NODE
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <deque>
+#include <iostream>
+
+namespace sp = BOOST_SPIRIT_CLASSIC_NS;
+
+namespace {
+
+ struct grammar : sp::grammar<grammar> {
+ template<class Scanner>
+ struct definition {
+ definition(grammar const&)
+ {
+ foo
+ = sp::alpha_p
+ | sp::alnum_p
+ | sp::cntrl_p
+ | sp::print_p
+ | sp::blank_p
+ | sp::digit_p
+ | sp::graph_p
+ | sp::lower_p
+ | sp::upper_p
+ | sp::xdigit_p
+ | sp::punct_p
+ ;
+ }
+
+ sp::rule<Scanner> foo;
+ sp::rule<Scanner> const&
+ start() const
+ {
+ return foo;
+ }
+ };
+ };
+
+ struct non_pod {
+ non_pod() : value('1') {}
+ char value;
+ bool operator==(non_pod const& o) const { return value == o.value; }
+ };
+
+ BOOST_ATTRIBUTE_UNUSED
+ std::ostream&
+ operator<<(std::ostream& out, non_pod const& x)
+ {
+ out << x.value;
+ return out;
+ }
+
+ template<class T>
+ struct convertable_non_pod : non_pod {
+ operator T() { return value; }
+ };
+
+ struct nonpod_gram : sp::grammar<nonpod_gram> {
+ template<class Scanner>
+ struct definition {
+ definition(nonpod_gram const&)
+ {
+ foo = sp::ch_p(typename Scanner::value_t());
+ }
+
+ sp::rule<Scanner> foo;
+ sp::rule<Scanner> const&
+ start() const
+ {
+ return foo;
+ }
+ };
+ };
+
+ template<class Grammar, class ValueType>
+ void
+ test_type()
+ {
+ typedef std::deque<ValueType> container;
+ typedef typename container::iterator iterator;
+ typedef sp::scanner<iterator> scanner;
+
+ container blah;
+ blah.push_back(typename container::value_type());
+ blah.push_back(typename container::value_type());
+
+ iterator first = blah.begin();
+ iterator last = blah.end();
+
+ scanner scan(first, last);
+
+ // Make sure this actually tries what we think it tries.
+ BOOST_STATIC_ASSERT((
+ boost::is_same<typename scanner::value_t, ValueType>::value
+ ));
+
+ Grammar().parse(scan);
+ }
+
+}
+
+int
+main()
+{
+ // Make sure isfoo() style functions work for integral types.
+ test_type<grammar, char>();
+ test_type<grammar, unsigned char>();
+ test_type<grammar, wchar_t>();
+ test_type<grammar, int>();
+ test_type<grammar, long>();
+ test_type<grammar, short>();
+ test_type<grammar, bool>();
+
+ // Non-POD's should work with things like alpha_p as long as we
+ // can turn them into a type that can do isalpha().
+ test_type<grammar, convertable_non_pod<char> >();
+ test_type<grammar, convertable_non_pod<wchar_t> >();
+ test_type<grammar, convertable_non_pod<int> >();
+
+ // BOOST_SPIRIT_DEBUG should work with grammars that parse
+ // non-POD's even if they can't do things like isalpha().
+ test_type<nonpod_gram, non_pod>();
+}
diff --git a/src/boost/libs/spirit/classic/test/scoped_lock_tests.cpp b/src/boost/libs/spirit/classic/test/scoped_lock_tests.cpp
new file mode 100644
index 00000000..4c4fde0c
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/scoped_lock_tests.cpp
@@ -0,0 +1,61 @@
+/*=============================================================================
+ Copyright (C) 2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+// Nota bene: the actual locking is _not_ tested here!
+
+#include <iostream>
+#include <boost/config.hpp>
+
+void banner()
+{
+ std::cout << "/////////////////////////////////////////////////////////\n";
+ std::cout << "\n";
+ std::cout << " scoped_lock test\n";
+ std::cout << "\n";
+ std::cout << "/////////////////////////////////////////////////////////\n";
+ std::cout << "\n";
+}
+
+#if defined(DONT_HAVE_BOOST) || !defined(BOOST_HAS_THREADS) || defined(BOOST_DISABLE_THREADS)
+// if boost libraries are not available we have to skip the tests
+int
+main()
+{
+ banner();
+ std::cout << "Test skipped (Boost libaries not available)\n";
+ return 0;
+}
+#else
+
+#include <boost/thread/mutex.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_scoped_lock.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int
+main()
+{
+ banner();
+
+ using BOOST_SPIRIT_CLASSIC_NS::rule;
+ using BOOST_SPIRIT_CLASSIC_NS::scoped_lock_d;
+ using BOOST_SPIRIT_CLASSIC_NS::parse_info;
+ using BOOST_SPIRIT_CLASSIC_NS::parse;
+ using boost::mutex;
+
+ mutex m;
+ rule<> r = scoped_lock_d(m)['x'];
+ parse_info<> pi = parse("x", r);
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+
+ return boost::report_errors();
+}
+
+#endif // defined(DONT_HAVE_BOOST)
diff --git a/src/boost/libs/spirit/classic/test/select_p_with_rule.cpp b/src/boost/libs/spirit/classic/test/select_p_with_rule.cpp
new file mode 100644
index 00000000..54142afe
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/select_p_with_rule.cpp
@@ -0,0 +1,89 @@
+/*=============================================================================
+ Copyright (c) 2004 Vyacheslav E. Andrejev
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+
+#define PHOENIX_LIMIT 2
+#define BOOST_SPIRIT_SELECT_LIMIT 2
+#define BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT 2
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_lists.hpp>
+#include <boost/spirit/include/classic_select.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace std;
+
+struct format_grammar : public grammar<format_grammar>
+{
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(format_grammar const& /*self*/)
+ {
+ descriptor_list =
+ list_p(format_descriptor, ch_p(','))
+ ;
+
+ format_descriptor =
+ select_p(E_descriptor, EN_descriptor)
+ ;
+
+ E_descriptor = // E[w[.d][Ee]]
+ lexeme_d
+ [
+ (ch_p('E') - (str_p("EN")))
+ >> !(
+ min_limit_d(1u)[uint_p]
+ >> !(ch_p('.') >> uint_p)
+ >> !(ch_p('E') >> min_limit_d(1u)[uint_p])
+ )
+ ]
+ ;
+
+ EN_descriptor = // EN[w[.d][Ee]]
+ lexeme_d
+ [
+ str_p("EN")
+ >> !(
+ min_limit_d(1u)[uint_p]
+ >> !(ch_p('.') >> uint_p)
+ >> !(ch_p('E') >> min_limit_d(1u)[uint_p])
+ )
+ ]
+ ;
+ }
+
+ rule<ScannerT> descriptor_list;
+ rule<ScannerT> format_descriptor;
+ rule<ScannerT> E_descriptor;
+ rule<ScannerT> EN_descriptor;
+
+ rule<ScannerT> const& start() const
+ {
+ return descriptor_list;
+ }
+ };
+};
+
+int main()
+{
+ format_grammar grammar;
+ const char* format = "E2, EN15.7, E20.10E3, E, EN";
+
+ parse_info<> pi = parse(format, grammar, blank_p);
+
+ if (pi.full) {
+ cout << "Test concluded successful" << endl;
+ return 0;
+ }
+ else {
+ BOOST_SPIRIT_ASSERT(false); // Test fails
+ return -1;
+ }
+}
diff --git a/src/boost/libs/spirit/classic/test/sf_bug_720917.cpp b/src/boost/libs/spirit/classic/test/sf_bug_720917.cpp
new file mode 100644
index 00000000..4e2724d5
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/sf_bug_720917.cpp
@@ -0,0 +1,115 @@
+/*=============================================================================
+ Copyright (c) 2003 Giovanni Bajo
+ Copyrigh (c) 2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_multi_pass.hpp>
+#include <iterator>
+#include "impl/sstream.hpp"
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+// Test for bug #720917
+// http://sf.net/tracker/index.php?func=detail&aid=720917&group_id=28447&atid=393386
+//
+// Check that it's possible to use multi_pass
+// together with standard library as a normal iterator
+//
+
+// a functor to test out the functor_multi_pass
+class my_functor
+{
+ public:
+ typedef char result_type;
+ my_functor()
+ : c('A')
+ {}
+
+ char operator()()
+ {
+ if (c == 'M')
+ return eof;
+ else
+ return c++;
+ }
+
+ static result_type eof;
+ private:
+ char c;
+};
+
+my_functor::result_type my_functor::eof = '\0';
+
+////////////////////////////////////////////////
+// four types of multi_pass iterators
+typedef multi_pass<
+ my_functor,
+ multi_pass_policies::functor_input,
+ multi_pass_policies::first_owner,
+ multi_pass_policies::no_check,
+ multi_pass_policies::std_deque
+> functor_multi_pass_t;
+
+typedef multi_pass<istream_iterator<char> > default_multi_pass_t;
+typedef look_ahead<istream_iterator<char>, 6> fixed_multi_pass_t;
+
+typedef multi_pass<
+ istream_iterator<char>,
+ multi_pass_policies::input_iterator,
+ multi_pass_policies::first_owner,
+ multi_pass_policies::buf_id_check,
+ multi_pass_policies::std_deque
+> first_owner_multi_pass_t;
+
+
+////////////////////////////////////////////////
+// the test cases
+template <typename IterT>
+void construct_string_from(void)
+{
+ sstream_t ss;
+ ss << "test string";
+
+ IterT mpend;
+ istream_iterator<char> a(ss);
+ IterT mp1(a);
+
+ std::string dummy;
+#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
+ dummy.assign(mp1, mpend);
+#else
+ copy(mp1, mpend, inserter(dummy, dummy.end()));
+#endif
+}
+
+template <>
+void construct_string_from<functor_multi_pass_t>(void)
+{
+ functor_multi_pass_t mpend;
+ functor_multi_pass_t mp1 = functor_multi_pass_t(my_functor());
+
+ std::string dummy;
+#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
+ dummy.assign(mp1, mpend);
+#else
+ copy(mp1, mpend, inserter(dummy, dummy.end()));
+#endif
+}
+
+////////////////////////////////////////////////
+// Definition of the test suite
+int
+main()
+{
+ construct_string_from<default_multi_pass_t>();
+ construct_string_from<fixed_multi_pass_t>();
+ construct_string_from<first_owner_multi_pass_t>();
+ construct_string_from<functor_multi_pass_t>();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/shortest_alternative_tests.cpp b/src/boost/libs/spirit/classic/test/shortest_alternative_tests.cpp
new file mode 100644
index 00000000..1169fbc6
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/shortest_alternative_tests.cpp
@@ -0,0 +1,58 @@
+//
+// Copyright (c) 2004 Joao Abecasis
+//
+// Use, modification and distribution is subject to 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)
+//
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+void shortest_alternative_parser_test()
+{
+ typedef
+ shortest_alternative<
+ shortest_alternative<
+ shortest_alternative<
+ strlit<>,
+ strlit<> >,
+ strlit<> >,
+ strlit<> >
+ parser_t;
+
+ parser_t short_rule =
+ shortest_d[
+ str_p("a")
+ | str_p("aa")
+ | str_p("aaa")
+ | str_p("aaaa")
+ ];
+
+ BOOST_TEST(parse("a", short_rule).full);
+ BOOST_TEST(parse("aa", short_rule).length == 1);
+ BOOST_TEST(parse("aaa", short_rule).length == 1);
+ BOOST_TEST(parse("aaaa", short_rule).length == 1);
+
+ short_rule =
+ shortest_d[
+ str_p("d")
+ | str_p("cd")
+ | str_p("bcd")
+ | str_p("abcd")
+ ];
+
+ BOOST_TEST(parse("d", short_rule).full);
+ BOOST_TEST(parse("cd", short_rule).full);
+ BOOST_TEST(parse("bcd", short_rule).full);
+ BOOST_TEST(parse("abcd", short_rule).full);
+}
+
+int
+main()
+{
+ shortest_alternative_parser_test();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/subrule_tests.cpp b/src/boost/libs/spirit/classic/test/subrule_tests.cpp
new file mode 100644
index 00000000..fd0a66cc
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/subrule_tests.cpp
@@ -0,0 +1,92 @@
+/*=============================================================================
+ Copyright (c) 1998-2003 Joel de Guzman
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+
+#include <boost/spirit/include/classic_core.hpp>
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Sub Rules tests
+//
+///////////////////////////////////////////////////////////////////////////////
+void
+subrules_tests()
+{
+ subrule<0> start;
+ subrule<1> a;
+ subrule<2> b;
+ subrule<3> c;
+
+ parse_info<char const*> pi;
+ pi = parse("abcabcacb",
+ (
+ start = *(a | b | c),
+ a = ch_p('a'),
+ b = ch_p('b'),
+ c = ch_p('c')
+ )
+ );
+
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 9);
+ BOOST_TEST(*pi.stop == 0);
+
+ pi = parse("aaaabababaaabbb",
+ (
+ start = (a | b) >> (start | b),
+ a = ch_p('a'),
+ b = ch_p('b')
+ )
+ );
+
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 15);
+ BOOST_TEST(*pi.stop == 0);
+
+ pi = parse("aaaabababaaabba",
+ (
+ start = (a | b) >> (start | b),
+ a = ch_p('a'),
+ b = ch_p('b')
+ )
+ );
+
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(!pi.full);
+ BOOST_TEST(pi.length == 14);
+
+ pi = parse("aaaabababaaabbb",
+
+ // single subrule test
+ start = (ch_p('a') | 'b') >> (start | 'b')
+ );
+
+ BOOST_TEST(pi.hit);
+ BOOST_TEST(pi.full);
+ BOOST_TEST(pi.length == 15);
+ BOOST_TEST(*pi.stop == 0);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ subrules_tests();
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/switch_problem.cpp b/src/boost/libs/spirit/classic/test/switch_problem.cpp
new file mode 100644
index 00000000..b2a7131a
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/switch_problem.cpp
@@ -0,0 +1,107 @@
+/*=============================================================================
+ Copyright (c) 2004 Angus Leeming
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// The switch_p parser was broken sometime during the boost 1.32 development
+// cycle. This little program tests it, the for_p parser and the limit_d
+// directive.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_for.hpp>
+#include <boost/spirit/include/classic_switch.hpp>
+#include <boost/spirit/include/classic_position_iterator.hpp>
+#include <boost/spirit/include/classic_confix.hpp>
+
+#include <boost/spirit/include/phoenix1.hpp>
+
+#include <iostream>
+#include <string>
+
+namespace spirit = BOOST_SPIRIT_CLASSIC_NS;
+
+typedef unsigned int uint;
+
+struct switch_grammar : public spirit::grammar<switch_grammar> {
+ template <typename ScannerT>
+ struct definition {
+ definition(switch_grammar const & self);
+
+ typedef spirit::rule<ScannerT> rule_t;
+ rule_t const & start() const { return expression; }
+
+ private:
+ rule_t expression;
+ uint index;
+ uint nnodes;
+ };
+};
+
+
+template <typename ScannerT>
+switch_grammar::definition<ScannerT>::definition(switch_grammar const & /*self*/)
+{
+ using boost::cref;
+
+ using phoenix::arg1;
+ using phoenix::var;
+
+ using spirit::case_p;
+ using spirit::for_p;
+ using spirit::limit_d;
+ using spirit::str_p;
+ using spirit::switch_p;
+ using spirit::uint_p;
+
+ expression =
+ str_p("NNODES") >>
+ uint_p[var(nnodes) = arg1] >>
+
+ for_p(var(index) = 1,
+ var(index) <= var(nnodes),
+ var(index)++)
+ [
+ limit_d(cref(index), cref(index))[uint_p] >>
+
+ switch_p[
+ case_p<'s'>(uint_p),
+ case_p<'d'>(uint_p),
+ case_p<'n'>(uint_p)
+ ]
+ ];
+}
+
+
+int main()
+{
+ std::string const data("NNODES 3\n"
+ "1 s 1\n"
+ "2 d 2\n"
+ "3 n 3"); // JDG 10-18-2005 removed trailing \n to
+ // avoid post skip problems
+
+ typedef spirit::position_iterator<std::string::const_iterator>
+ iterator_t;
+
+ spirit::parse_info<iterator_t> const info =
+ parse(iterator_t(data.begin(), data.end(), "switch test"),
+ iterator_t(),
+ switch_grammar(),
+ spirit::space_p);
+
+ if (!info.full) {
+ spirit::file_position const fp = info.stop.get_position();
+ std::cerr << "Parsing failed at line " << fp.line
+ << ", column " << fp.column << ".\n";
+ }
+
+ return info.full ? 0 : 1;
+}
diff --git a/src/boost/libs/spirit/classic/test/switch_tests_eps_default.cpp b/src/boost/libs/spirit/classic/test/switch_tests_eps_default.cpp
new file mode 100644
index 00000000..747164d8
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/switch_tests_eps_default.cpp
@@ -0,0 +1,327 @@
+/*=============================================================================
+ Copyright (c) 2003 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+
+#define BOOST_SPIRIT_SWITCH_CASE_LIMIT 6
+#define BOOST_SPIRIT_SELECT_LIMIT 6
+#define PHOENIX_LIMIT 6
+
+//#define BOOST_SPIRIT_DEBUG
+#include <boost/mpl/list.hpp>
+#include <boost/mpl/for_each.hpp>
+
+#include <boost/spirit/include/classic_primitives.hpp>
+#include <boost/spirit/include/classic_numerics.hpp>
+#include <boost/spirit/include/classic_actions.hpp>
+#include <boost/spirit/include/classic_operators.hpp>
+#include <boost/spirit/include/classic_rule.hpp>
+#include <boost/spirit/include/classic_grammar.hpp>
+#include <boost/spirit/include/classic_switch.hpp>
+#include <boost/spirit/include/classic_select.hpp>
+#include <boost/spirit/include/classic_closure.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+namespace test_grammars {
+
+///////////////////////////////////////////////////////////////////////////////
+// Test the direct switch_p usage (with default_p)
+ struct switch_grammar_direct_default4
+ : public grammar<switch_grammar_direct_default4>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_direct_default4 const& /*self*/)
+ {
+ r = switch_p [
+ case_p<'a'>(int_p),
+ case_p<'b'>(ch_p(',')),
+ case_p<'c'>(str_p("bcd")),
+ default_p
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+ struct switch_grammar_direct_default5
+ : public grammar<switch_grammar_direct_default5>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_direct_default5 const& /*self*/)
+ {
+ r = switch_p [
+ case_p<'a'>(int_p),
+ case_p<'b'>(ch_p(',')),
+ default_p,
+ case_p<'c'>(str_p("bcd"))
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+ struct switch_grammar_direct_default6
+ : public grammar<switch_grammar_direct_default6>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_direct_default6 const& /*self*/)
+ {
+ r = switch_p [
+ default_p,
+ case_p<'a'>(int_p),
+ case_p<'b'>(ch_p(',')),
+ case_p<'c'>(str_p("bcd"))
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+///////////////////////////////////////////////////////////////////////////////
+// Test the switch_p usage given a parser as the switch condition
+ struct switch_grammar_parser_default4
+ : public grammar<switch_grammar_parser_default4>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_parser_default4 const& /*self*/)
+ {
+ r = switch_p(anychar_p) [
+ case_p<'a'>(int_p),
+ case_p<'b'>(ch_p(',')),
+ case_p<'c'>(str_p("bcd")),
+ default_p
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+ struct switch_grammar_parser_default5
+ : public grammar<switch_grammar_parser_default5>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_parser_default5 const& /*self*/)
+ {
+ r = switch_p(anychar_p) [
+ case_p<'a'>(int_p),
+ case_p<'b'>(ch_p(',')),
+ default_p,
+ case_p<'c'>(str_p("bcd"))
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+ struct switch_grammar_parser_default6
+ : public grammar<switch_grammar_parser_default6>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_parser_default6 const& /*self*/)
+ {
+ r = switch_p(anychar_p) [
+ default_p,
+ case_p<'a'>(int_p),
+ case_p<'b'>(ch_p(',')),
+ case_p<'c'>(str_p("bcd"))
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+///////////////////////////////////////////////////////////////////////////////
+// Test the switch_p usage given an actor as the switch condition
+ struct select_result : public BOOST_SPIRIT_CLASSIC_NS::closure<select_result, int>
+ {
+ member1 val;
+ };
+
+ struct switch_grammar_actor_default4
+ : public grammar<switch_grammar_actor_default4>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_actor_default4 const& /*self*/)
+ {
+ using phoenix::arg1;
+ r = select_p('a', 'b', 'c', 'd')[r.val = arg1] >>
+ switch_p(r.val) [
+ case_p<0>(int_p),
+ case_p<1>(ch_p(',')),
+ case_p<2>(str_p("bcd")),
+ default_p
+ ];
+ }
+
+ rule<ScannerT, select_result::context_t> r;
+ rule<ScannerT, select_result::context_t> const&
+ start() const { return r; }
+ };
+ };
+
+ struct switch_grammar_actor_default5
+ : public grammar<switch_grammar_actor_default5>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_actor_default5 const& /*self*/)
+ {
+ using phoenix::arg1;
+ r = select_p('a', 'b', 'c', 'd')[r.val = arg1] >>
+ switch_p(r.val) [
+ case_p<0>(int_p),
+ case_p<1>(ch_p(',')),
+ default_p,
+ case_p<2>(str_p("bcd"))
+ ];
+ }
+
+ rule<ScannerT, select_result::context_t> r;
+ rule<ScannerT, select_result::context_t> const&
+ start() const { return r; }
+ };
+ };
+
+ struct switch_grammar_actor_default6
+ : public grammar<switch_grammar_actor_default6>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_actor_default6 const& /*self*/)
+ {
+ using phoenix::arg1;
+ r = select_p('a', 'b', 'c', 'd')[r.val = arg1] >>
+ switch_p(r.val) [
+ default_p,
+ case_p<0>(int_p),
+ case_p<1>(ch_p(',')),
+ case_p<2>(str_p("bcd"))
+ ];
+ }
+
+ rule<ScannerT, select_result::context_t> r;
+ rule<ScannerT, select_result::context_t> const&
+ start() const { return r; }
+ };
+ };
+
+} // namespace test_grammars
+
+///////////////////////////////////////////////////////////////////////////////
+namespace tests {
+
+ // Tests for known (to the grammars) sequences
+ struct check_grammar_known {
+
+ template <typename GrammarT>
+ void operator()(GrammarT)
+ {
+ GrammarT g;
+
+ BOOST_TEST(parse("a1", g).full);
+ BOOST_TEST(!parse("a,", g).hit);
+ BOOST_TEST(!parse("abcd", g).hit);
+
+ BOOST_TEST(parse("a 1", g, space_p).full);
+ BOOST_TEST(!parse("a ,", g, space_p).hit);
+ BOOST_TEST(!parse("a bcd", g, space_p).hit);
+
+ BOOST_TEST(!parse("b1", g).hit);
+ BOOST_TEST(parse("b,", g).full);
+ BOOST_TEST(!parse("bbcd", g).hit);
+
+ BOOST_TEST(!parse("b 1", g, space_p).hit);
+ BOOST_TEST(parse("b ,", g, space_p).full);
+ BOOST_TEST(!parse("b bcd", g, space_p).hit);
+
+ BOOST_TEST(!parse("c1", g).hit);
+ BOOST_TEST(!parse("c,", g).hit);
+ BOOST_TEST(parse("cbcd", g).full);
+
+ BOOST_TEST(!parse("c 1", g, space_p).hit);
+ BOOST_TEST(!parse("c ,", g, space_p).hit);
+ BOOST_TEST(parse("c bcd", g, space_p).full);
+ }
+ };
+
+ // Tests for known (to the grammars) sequences
+ // Tests for the default branches (without parsers) of the grammars
+ struct check_grammar_default_plain {
+
+ template <typename GrammarT>
+ void operator()(GrammarT)
+ {
+ GrammarT g;
+
+ BOOST_TEST(parse("d", g).full);
+ BOOST_TEST(parse(" d", g, space_p).full); // JDG 10-18-2005 removed trailing ' ' to
+ // avoid post skip problems
+ }
+ };
+
+} // namespace tests
+
+int
+main()
+{
+ // Test switch_p parsers containing special (epsilon) default_p case
+ // branches
+ typedef boost::mpl::list<
+ // switch_p syntax
+ test_grammars::switch_grammar_direct_default4,
+ test_grammars::switch_grammar_direct_default5,
+ test_grammars::switch_grammar_direct_default6,
+
+ // switch_p(parser) syntax
+ test_grammars::switch_grammar_parser_default4,
+ test_grammars::switch_grammar_parser_default5,
+ test_grammars::switch_grammar_parser_default6,
+
+ // switch_p(actor) syntax
+ test_grammars::switch_grammar_actor_default4,
+ test_grammars::switch_grammar_actor_default5,
+ test_grammars::switch_grammar_actor_default6
+ > default_epsilon_list_t;
+
+ boost::mpl::for_each<default_epsilon_list_t>(tests::check_grammar_known());
+ boost::mpl::for_each<default_epsilon_list_t>(
+ tests::check_grammar_default_plain());
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/switch_tests_general_def.cpp b/src/boost/libs/spirit/classic/test/switch_tests_general_def.cpp
new file mode 100644
index 00000000..7abfeb58
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/switch_tests_general_def.cpp
@@ -0,0 +1,343 @@
+/*=============================================================================
+ Copyright (c) 2003 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+
+#define BOOST_SPIRIT_SWITCH_CASE_LIMIT 6
+#define BOOST_SPIRIT_SELECT_LIMIT 6
+#define PHOENIX_LIMIT 6
+
+//#define BOOST_SPIRIT_DEBUG
+#include <boost/mpl/list.hpp>
+#include <boost/mpl/for_each.hpp>
+
+#include <boost/spirit/include/classic_primitives.hpp>
+#include <boost/spirit/include/classic_numerics.hpp>
+#include <boost/spirit/include/classic_actions.hpp>
+#include <boost/spirit/include/classic_operators.hpp>
+#include <boost/spirit/include/classic_rule.hpp>
+#include <boost/spirit/include/classic_grammar.hpp>
+#include <boost/spirit/include/classic_switch.hpp>
+#include <boost/spirit/include/classic_select.hpp>
+#include <boost/spirit/include/classic_closure.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+namespace test_grammars {
+
+///////////////////////////////////////////////////////////////////////////////
+// Test the direct switch_p usage (with default_p)
+ struct switch_grammar_direct_default1
+ : public grammar<switch_grammar_direct_default1>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_direct_default1 const& /*self*/)
+ {
+ r = switch_p [
+ case_p<'a'>(int_p),
+ case_p<'b'>(ch_p(',')),
+ case_p<'c'>(str_p("bcd")),
+ default_p(str_p("default"))
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+ struct switch_grammar_direct_default2
+ : public grammar<switch_grammar_direct_default2>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_direct_default2 const& /*self*/)
+ {
+ r = switch_p [
+ case_p<'a'>(int_p),
+ case_p<'b'>(ch_p(',')),
+ default_p(str_p("default")),
+ case_p<'c'>(str_p("bcd"))
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+ struct switch_grammar_direct_default3
+ : public grammar<switch_grammar_direct_default3>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_direct_default3 const& /*self*/)
+ {
+ r = switch_p [
+ default_p(str_p("default")),
+ case_p<'a'>(int_p),
+ case_p<'b'>(ch_p(',')),
+ case_p<'c'>(str_p("bcd"))
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+///////////////////////////////////////////////////////////////////////////////
+// Test the switch_p usage given a parser as the switch condition
+ struct switch_grammar_parser_default1
+ : public grammar<switch_grammar_parser_default1>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_parser_default1 const& /*self*/)
+ {
+ r = switch_p(anychar_p) [
+ case_p<'a'>(int_p),
+ case_p<'b'>(ch_p(',')),
+ case_p<'c'>(str_p("bcd")),
+ default_p(str_p("default"))
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+ struct switch_grammar_parser_default2
+ : public grammar<switch_grammar_parser_default2>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_parser_default2 const& /*self*/)
+ {
+ r = switch_p(anychar_p) [
+ case_p<'a'>(int_p),
+ case_p<'b'>(ch_p(',')),
+ default_p(str_p("default")),
+ case_p<'c'>(str_p("bcd"))
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+ struct switch_grammar_parser_default3
+ : public grammar<switch_grammar_parser_default3>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_parser_default3 const& /*self*/)
+ {
+ r = switch_p(anychar_p) [
+ default_p(str_p("default")),
+ case_p<'a'>(int_p),
+ case_p<'b'>(ch_p(',')),
+ case_p<'c'>(str_p("bcd"))
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+///////////////////////////////////////////////////////////////////////////////
+// Test the switch_p usage given an actor as the switch condition
+ struct select_result : public BOOST_SPIRIT_CLASSIC_NS::closure<select_result, int>
+ {
+ member1 val;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ struct switch_grammar_actor_default1
+ : public grammar<switch_grammar_actor_default1>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_actor_default1 const& /*self*/)
+ {
+ using phoenix::arg1;
+ r = select_p('a', 'b', 'c', 'd')[r.val = arg1] >>
+ switch_p(r.val) [
+ case_p<0>(int_p),
+ case_p<1>(ch_p(',')),
+ case_p<2>(str_p("bcd")),
+ default_p(str_p("default"))
+ ];
+ }
+
+ rule<ScannerT, select_result::context_t> r;
+ rule<ScannerT, select_result::context_t> const&
+ start() const { return r; }
+ };
+ };
+
+ struct switch_grammar_actor_default2
+ : public grammar<switch_grammar_actor_default2>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_actor_default2 const& /*self*/)
+ {
+ using phoenix::arg1;
+ r = select_p('a', 'b', 'c', 'd')[r.val = arg1] >>
+ switch_p(r.val) [
+ case_p<0>(int_p),
+ case_p<1>(ch_p(',')),
+ default_p(str_p("default")),
+ case_p<2>(str_p("bcd"))
+ ];
+ }
+
+ rule<ScannerT, select_result::context_t> r;
+ rule<ScannerT, select_result::context_t> const&
+ start() const { return r; }
+ };
+ };
+
+ struct switch_grammar_actor_default3
+ : public grammar<switch_grammar_actor_default3>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_actor_default3 const& /*self*/)
+ {
+ using phoenix::arg1;
+ r = select_p('a', 'b', 'c', 'd')[r.val = arg1] >>
+ switch_p(r.val) [
+ default_p(str_p("default")),
+ case_p<0>(int_p),
+ case_p<1>(ch_p(',')),
+ case_p<2>(str_p("bcd"))
+ ];
+ }
+
+ rule<ScannerT, select_result::context_t> r;
+ rule<ScannerT, select_result::context_t> const&
+ start() const { return r; }
+ };
+ };
+
+} // namespace test_grammars
+
+///////////////////////////////////////////////////////////////////////////////
+namespace tests {
+
+ // Tests for known (to the grammars) sequences
+ struct check_grammar_known {
+
+ template <typename GrammarT>
+ void operator()(GrammarT)
+ {
+ GrammarT g;
+
+ BOOST_TEST(parse("a1", g).full);
+ BOOST_TEST(!parse("a,", g).hit);
+ BOOST_TEST(!parse("abcd", g).hit);
+
+ BOOST_TEST(parse("a 1", g, space_p).full);
+ BOOST_TEST(!parse("a ,", g, space_p).hit);
+ BOOST_TEST(!parse("a bcd", g, space_p).hit);
+
+ BOOST_TEST(!parse("b1", g).hit);
+ BOOST_TEST(parse("b,", g).full);
+ BOOST_TEST(!parse("bbcd", g).hit);
+
+ BOOST_TEST(!parse("b 1", g, space_p).hit);
+ BOOST_TEST(parse("b ,", g, space_p).full);
+ BOOST_TEST(!parse("b bcd", g, space_p).hit);
+
+ BOOST_TEST(!parse("c1", g).hit);
+ BOOST_TEST(!parse("c,", g).hit);
+ BOOST_TEST(parse("cbcd", g).full);
+
+ BOOST_TEST(!parse("c 1", g, space_p).hit);
+ BOOST_TEST(!parse("c ,", g, space_p).hit);
+ BOOST_TEST(parse("c bcd", g, space_p).full);
+ }
+ };
+
+ // Tests for unknown (to the grammar) sequences
+ struct check_grammar_unknown_default {
+
+ template <typename GrammarT>
+ void operator()(GrammarT)
+ {
+ GrammarT g;
+
+ BOOST_TEST(!parse("d1", g).hit);
+ BOOST_TEST(!parse("d,", g).hit);
+ BOOST_TEST(!parse("dbcd", g).hit);
+
+ BOOST_TEST(!parse("d 1", g, space_p).hit);
+ BOOST_TEST(!parse("d ,", g, space_p).hit);
+ BOOST_TEST(!parse("d bcd", g, space_p).hit);
+ }
+ };
+
+ // Tests for the default branches (with parsers) of the grammars
+ struct check_grammar_default {
+
+ template <typename GrammarT>
+ void operator()(GrammarT)
+ {
+ GrammarT g;
+
+ BOOST_TEST(parse("ddefault", g).full);
+ BOOST_TEST(parse("d default", g, space_p).full);
+ }
+ };
+
+} // namespace tests
+
+int
+main()
+{
+ // Test switch_p parsers containing general default_p(...) case branches
+ typedef boost::mpl::list<
+ // switch_p syntax
+ test_grammars::switch_grammar_direct_default1,
+ test_grammars::switch_grammar_direct_default2,
+ test_grammars::switch_grammar_direct_default3,
+
+ // switch_p(parser) syntax
+ test_grammars::switch_grammar_parser_default1,
+ test_grammars::switch_grammar_parser_default2,
+ test_grammars::switch_grammar_parser_default3,
+
+ // switch_p(actor) syntax
+ test_grammars::switch_grammar_actor_default1,
+ test_grammars::switch_grammar_actor_default2,
+ test_grammars::switch_grammar_actor_default3
+ > default_list_t;
+
+ boost::mpl::for_each<default_list_t>(tests::check_grammar_known());
+ boost::mpl::for_each<default_list_t>(tests::check_grammar_unknown_default());
+ boost::mpl::for_each<default_list_t>(tests::check_grammar_default());
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/switch_tests_single.cpp b/src/boost/libs/spirit/classic/test/switch_tests_single.cpp
new file mode 100644
index 00000000..780f4195
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/switch_tests_single.cpp
@@ -0,0 +1,350 @@
+/*=============================================================================
+ Copyright (c) 2003 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+
+#define BOOST_SPIRIT_SWITCH_CASE_LIMIT 6
+#define BOOST_SPIRIT_SELECT_LIMIT 6
+#define PHOENIX_LIMIT 6
+
+//#define BOOST_SPIRIT_DEBUG
+#include <boost/mpl/list.hpp>
+#include <boost/mpl/for_each.hpp>
+
+#include <boost/spirit/include/classic_primitives.hpp>
+#include <boost/spirit/include/classic_numerics.hpp>
+#include <boost/spirit/include/classic_actions.hpp>
+#include <boost/spirit/include/classic_operators.hpp>
+#include <boost/spirit/include/classic_rule.hpp>
+#include <boost/spirit/include/classic_grammar.hpp>
+#include <boost/spirit/include/classic_switch.hpp>
+#include <boost/spirit/include/classic_select.hpp>
+#include <boost/spirit/include/classic_closure.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+namespace test_grammars {
+
+///////////////////////////////////////////////////////////////////////////////
+// Test the direct switch_p usage
+ struct switch_grammar_direct_single
+ : public grammar<switch_grammar_direct_single>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_direct_single const& /*self*/)
+ {
+ r = switch_p [
+ case_p<'a'>(int_p)
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+ struct switch_grammar_direct_default_single1
+ : public grammar<switch_grammar_direct_default_single1>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_direct_default_single1 const& /*self*/)
+ {
+ r = switch_p [
+ default_p(str_p("default"))
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+ struct switch_grammar_direct_default_single2
+ : public grammar<switch_grammar_direct_default_single2>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_direct_default_single2 const& /*self*/)
+ {
+ r = switch_p [
+ default_p
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+///////////////////////////////////////////////////////////////////////////////
+// Test the switch_p usage given a parser as the switch condition
+ struct switch_grammar_parser_single
+ : public grammar<switch_grammar_parser_single>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_parser_single const& /*self*/)
+ {
+ r = switch_p(anychar_p) [
+ case_p<'a'>(int_p)
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+ struct switch_grammar_parser_default_single1
+ : public grammar<switch_grammar_parser_default_single1>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_parser_default_single1 const& /*self*/)
+ {
+ r = switch_p(anychar_p) [
+ default_p(str_p("default"))
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+ struct switch_grammar_parser_default_single2
+ : public grammar<switch_grammar_parser_default_single2>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_parser_default_single2 const& /*self*/)
+ {
+ r = switch_p(anychar_p) [
+ default_p
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+///////////////////////////////////////////////////////////////////////////////
+// Test the switch_p usage given an actor as the switch condition
+ struct select_result : public BOOST_SPIRIT_CLASSIC_NS::closure<select_result, int>
+ {
+ member1 val;
+ };
+
+ struct switch_grammar_actor_single
+ : public grammar<switch_grammar_actor_single>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_actor_single const& /*self*/)
+ {
+ using phoenix::arg1;
+ r = select_p('a')[r.val = arg1] >>
+ switch_p(r.val) [
+ case_p<0>(int_p)
+ ];
+ }
+
+ rule<ScannerT, select_result::context_t> r;
+ rule<ScannerT, select_result::context_t> const&
+ start() const { return r; }
+ };
+ };
+
+ struct switch_grammar_actor_default_single1
+ : public grammar<switch_grammar_actor_default_single1>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_actor_default_single1 const& /*self*/)
+ {
+ using phoenix::arg1;
+ r = select_p('d')[r.val = arg1] >>
+ switch_p(r.val) [
+ default_p(str_p("default"))
+ ];
+ }
+
+ rule<ScannerT, select_result::context_t> r;
+ rule<ScannerT, select_result::context_t> const&
+ start() const { return r; }
+ };
+ };
+
+ struct switch_grammar_actor_default_single2
+ : public grammar<switch_grammar_actor_default_single2>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_actor_default_single2 const& /*self*/)
+ {
+ using phoenix::arg1;
+ r = select_p('d')[r.val = arg1] >>
+ switch_p(r.val) [
+ default_p
+ ];
+ }
+
+ rule<ScannerT, select_result::context_t> r;
+ rule<ScannerT, select_result::context_t> const&
+ start() const { return r; }
+ };
+ };
+
+} // namespace test_grammars
+
+///////////////////////////////////////////////////////////////////////////////
+namespace tests {
+
+ // Tests for known (to the grammars) sequences
+ struct check_grammar_unknown {
+
+ template <typename GrammarT>
+ void operator()(GrammarT)
+ {
+ GrammarT g;
+
+ BOOST_TEST(!parse("a1", g).hit);
+ BOOST_TEST(!parse("a,", g).hit);
+ BOOST_TEST(!parse("abcd", g).hit);
+
+ BOOST_TEST(!parse("a 1", g, space_p).hit);
+ BOOST_TEST(!parse("a ,", g, space_p).hit);
+ BOOST_TEST(!parse("a bcd", g, space_p).hit);
+
+ BOOST_TEST(!parse("b1", g).hit);
+ BOOST_TEST(!parse("b,", g).hit);
+ BOOST_TEST(!parse("bbcd", g).hit);
+
+ BOOST_TEST(!parse("b 1", g, space_p).hit);
+ BOOST_TEST(!parse("b ,", g, space_p).hit);
+ BOOST_TEST(!parse("b bcd", g, space_p).hit);
+
+ BOOST_TEST(!parse("c1", g).hit);
+ BOOST_TEST(!parse("c,", g).hit);
+ BOOST_TEST(!parse("cbcd", g).hit);
+
+ BOOST_TEST(!parse("c 1", g, space_p).hit);
+ BOOST_TEST(!parse("c ,", g, space_p).hit);
+ BOOST_TEST(!parse("c bcd", g, space_p).hit);
+ }
+ };
+
+ // Tests for the default branches (with parsers) of the grammars
+ struct check_grammar_default {
+
+ template <typename GrammarT>
+ void operator()(GrammarT)
+ {
+ GrammarT g;
+
+ BOOST_TEST(parse("ddefault", g).full);
+ BOOST_TEST(parse("d default", g, space_p).full);
+ }
+ };
+
+ // Tests for the default branches (without parsers) of the grammars
+ struct check_grammar_default_plain {
+
+ template <typename GrammarT>
+ void operator()(GrammarT)
+ {
+ GrammarT g;
+
+ BOOST_TEST(parse("d", g).full);
+ BOOST_TEST(parse(" d", g, space_p).full); // JDG 10-18-2005 removed trailing ' ' to
+ // avoid post skip problems
+ }
+ };
+
+ // Tests grammars with a single case_p branch
+ struct check_grammar_single {
+
+ template <typename GrammarT>
+ void operator()(GrammarT)
+ {
+ GrammarT g;
+
+ BOOST_TEST(parse("a1", g).full);
+ BOOST_TEST(!parse("a,", g).hit);
+ BOOST_TEST(!parse("abcd", g).hit);
+
+ BOOST_TEST(parse("a 1", g, space_p).full);
+ BOOST_TEST(!parse("a ,", g, space_p).hit);
+ BOOST_TEST(!parse("a bcd", g, space_p).hit);
+
+ BOOST_TEST(!parse("b1", g).hit);
+ BOOST_TEST(!parse("b,", g).hit);
+ BOOST_TEST(!parse("bbcd", g).hit);
+
+ BOOST_TEST(!parse("b 1", g, space_p).hit);
+ BOOST_TEST(!parse("b ,", g, space_p).hit);
+ BOOST_TEST(!parse("b bcd", g, space_p).hit);
+
+ BOOST_TEST(!parse("c1", g).hit);
+ BOOST_TEST(!parse("c,", g).hit);
+ BOOST_TEST(!parse("cbcd", g).hit);
+
+ BOOST_TEST(!parse("c 1", g, space_p).hit);
+ BOOST_TEST(!parse("c ,", g, space_p).hit);
+ BOOST_TEST(!parse("c bcd", g, space_p).hit);
+ }
+ };
+
+} // namespace tests
+
+int
+main()
+{
+ // Test switch_p with a single case_p branch
+ typedef boost::mpl::list<
+ test_grammars::switch_grammar_direct_single,
+ test_grammars::switch_grammar_parser_single,
+ test_grammars::switch_grammar_actor_single
+ > single_list_t;
+
+ boost::mpl::for_each<single_list_t>(tests::check_grammar_single());
+
+ typedef boost::mpl::list<
+ test_grammars::switch_grammar_direct_default_single1,
+ test_grammars::switch_grammar_parser_default_single1,
+ test_grammars::switch_grammar_actor_default_single1
+ > default_single_t;
+
+ boost::mpl::for_each<default_single_t>(tests::check_grammar_default());
+ boost::mpl::for_each<default_single_t>(tests::check_grammar_unknown());
+
+ typedef boost::mpl::list<
+ test_grammars::switch_grammar_direct_default_single2,
+ test_grammars::switch_grammar_parser_default_single2,
+ test_grammars::switch_grammar_actor_default_single2
+ > default_plain_single_t;
+
+ boost::mpl::for_each<default_plain_single_t>(
+ tests::check_grammar_default_plain());
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/switch_tests_wo_default.cpp b/src/boost/libs/spirit/classic/test/switch_tests_wo_default.cpp
new file mode 100644
index 00000000..2671a09f
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/switch_tests_wo_default.cpp
@@ -0,0 +1,202 @@
+/*=============================================================================
+ Copyright (c) 2003 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <boost/detail/lightweight_test.hpp>
+
+
+#define BOOST_SPIRIT_SWITCH_CASE_LIMIT 6
+#define BOOST_SPIRIT_SELECT_LIMIT 6
+#define PHOENIX_LIMIT 6
+
+//#define BOOST_SPIRIT_DEBUG
+#include <boost/mpl/list.hpp>
+#include <boost/mpl/for_each.hpp>
+
+#include <boost/spirit/include/classic_primitives.hpp>
+#include <boost/spirit/include/classic_numerics.hpp>
+#include <boost/spirit/include/classic_actions.hpp>
+#include <boost/spirit/include/classic_operators.hpp>
+#include <boost/spirit/include/classic_rule.hpp>
+#include <boost/spirit/include/classic_grammar.hpp>
+#include <boost/spirit/include/classic_switch.hpp>
+#include <boost/spirit/include/classic_select.hpp>
+#include <boost/spirit/include/classic_closure.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+namespace test_grammars {
+
+///////////////////////////////////////////////////////////////////////////////
+// Test the direct switch_p usage
+ struct switch_grammar_direct : public grammar<switch_grammar_direct>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_direct const& /*self*/)
+ {
+ r = switch_p [
+ case_p<'a'>(int_p),
+ case_p<'b'>(ch_p(',')),
+ case_p<'c'>(str_p("bcd")),
+ case_p<'d'>(eps_p)
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+///////////////////////////////////////////////////////////////////////////////
+// Test the switch_p usage given a parser as the switch condition
+ struct switch_grammar_parser : public grammar<switch_grammar_parser>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_parser const& /*self*/)
+ {
+ r = switch_p(anychar_p) [
+ case_p<'a'>(int_p),
+ case_p<'b'>(ch_p(',')),
+ case_p<'c'>(str_p("bcd")),
+ case_p<'d'>(eps_p)
+ ];
+ }
+
+ rule<ScannerT> r;
+ rule<ScannerT> const& start() const { return r; }
+ };
+ };
+
+///////////////////////////////////////////////////////////////////////////////
+// Test the switch_p usage given an actor as the switch condition
+ struct select_result : public BOOST_SPIRIT_CLASSIC_NS::closure<select_result, int>
+ {
+ member1 val;
+ };
+
+ struct switch_grammar_actor : public grammar<switch_grammar_actor>
+ {
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(switch_grammar_actor const& /*self*/)
+ {
+ using phoenix::arg1;
+ r = select_p('a', 'b', 'c', 'd')[r.val = arg1] >>
+ switch_p(r.val) [
+ case_p<0>(int_p),
+ case_p<1>(ch_p(',')),
+ case_p<2>(str_p("bcd")),
+ case_p<3>(eps_p)
+ ];
+ }
+
+ rule<ScannerT, select_result::context_t> r;
+ rule<ScannerT, select_result::context_t> const&
+ start() const { return r; }
+ };
+ };
+
+} // namespace test_grammars
+
+///////////////////////////////////////////////////////////////////////////////
+namespace tests {
+
+ // Tests for known (to the grammars) sequences
+ struct check_grammar_known {
+
+ template <typename GrammarT>
+ void operator()(GrammarT)
+ {
+ GrammarT g;
+
+ BOOST_TEST(parse("a1", g).full);
+ BOOST_TEST(!parse("a,", g).hit);
+ BOOST_TEST(!parse("abcd", g).hit);
+ BOOST_TEST(!parse("a", g).hit);
+
+ BOOST_TEST(parse("a 1", g, space_p).full);
+ BOOST_TEST(!parse("a ,", g, space_p).hit);
+ BOOST_TEST(!parse("a bcd", g, space_p).hit);
+ BOOST_TEST(!parse("a ", g, space_p).hit);
+
+ BOOST_TEST(!parse("b1", g).hit);
+ BOOST_TEST(parse("b,", g).full);
+ BOOST_TEST(!parse("bbcd", g).hit);
+ BOOST_TEST(!parse("b", g).hit);
+
+ BOOST_TEST(!parse("b 1", g, space_p).hit);
+ BOOST_TEST(parse("b ,", g, space_p).full);
+ BOOST_TEST(!parse("b bcd", g, space_p).hit);
+ BOOST_TEST(!parse("b ", g, space_p).hit);
+
+ BOOST_TEST(!parse("c1", g).hit);
+ BOOST_TEST(!parse("c,", g).hit);
+ BOOST_TEST(parse("cbcd", g).full);
+ BOOST_TEST(!parse("c", g).hit);
+
+ BOOST_TEST(!parse("c 1", g, space_p).hit);
+ BOOST_TEST(!parse("c ,", g, space_p).hit);
+ BOOST_TEST(parse("c bcd", g, space_p).full);
+ BOOST_TEST(!parse("c ", g, space_p).hit);
+
+ BOOST_TEST(parse("d1", g).hit);
+ BOOST_TEST(parse("d,", g).hit);
+ BOOST_TEST(parse("dbcd", g).hit);
+ BOOST_TEST(parse("d", g).full);
+
+ BOOST_TEST(parse("d 1", g, space_p).hit);
+ BOOST_TEST(parse("d ,", g, space_p).hit);
+ BOOST_TEST(parse("d bcd", g, space_p).hit);
+ BOOST_TEST(parse(" d", g, space_p).full); // JDG 10-18-2005 removed trailing ' ' to
+ // avoid post skip problems
+
+ BOOST_TEST(parse(" a 1 b , c bcd d", *g, space_p).full);
+ // JDG 10-18-2005 removed trailing ' ' to avoid post skip problems
+ }
+ };
+
+ // Tests for unknown (to the grammar) sequences
+ struct check_grammar_unknown_default {
+
+ template <typename GrammarT>
+ void operator()(GrammarT)
+ {
+ GrammarT g;
+
+ BOOST_TEST(!parse("x1", g).hit);
+ BOOST_TEST(!parse("x,", g).hit);
+ BOOST_TEST(!parse("xbcd", g).hit);
+
+ BOOST_TEST(!parse("x 1", g, space_p).hit);
+ BOOST_TEST(!parse("x ,", g, space_p).hit);
+ BOOST_TEST(!parse("x bcd", g, space_p).hit);
+ }
+ };
+
+} // namespace tests
+
+int
+main()
+{
+ // Test switch_p without any default_p case branches
+ typedef boost::mpl::list<
+ test_grammars::switch_grammar_direct,
+ test_grammars::switch_grammar_parser,
+ test_grammars::switch_grammar_actor
+ > grammar_list_t;
+
+ boost::mpl::for_each<grammar_list_t>(tests::check_grammar_known());
+ boost::mpl::for_each<grammar_list_t>(tests::check_grammar_unknown_default());
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/symbols_add_null.cpp b/src/boost/libs/spirit/classic/test/symbols_add_null.cpp
new file mode 100644
index 00000000..12597770
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/symbols_add_null.cpp
@@ -0,0 +1,79 @@
+/*=============================================================================
+ Copyright (c) 2004 Joao Abecasis
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+// This test requires NDEBUG to be undefined, because it depends on
+// BOOST_SPIRIT_ASSERT throwing an exception.
+#ifdef NDEBUG
+# undef NDEBUG
+#endif
+
+#include <boost/config.hpp>
+#include <stdexcept>
+
+#define BOOST_SPIRIT_ASSERT_EXCEPTION ::spirit_exception
+
+struct spirit_exception : std::exception
+{
+ spirit_exception(char const * msg)
+ : message(msg)
+ {
+ }
+ ~spirit_exception() BOOST_NOEXCEPT_OR_NOTHROW {}
+
+ char const* what() const BOOST_NOEXCEPT_OR_NOTHROW { return message; }
+
+ char const * message;
+};
+
+#include <boost/spirit/include/classic_scanner.hpp>
+#include <boost/spirit/home/classic/symbols/impl/tst.ipp>
+#include <boost/utility/addressof.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+typedef char char_type;
+typedef char const * iterator;
+
+char_type data_[] = "whatever";
+
+iterator begin = data_;
+iterator end = data_
+ + sizeof(data_)/sizeof(char_type); // Yes, this is an intentional bug ;)
+
+char_type data2_[] = "\0something";
+iterator begin2 = data2_;
+iterator end2 = data2_ + sizeof(data2_)/sizeof(char_type) - 1;
+
+int main()
+{
+ typedef BOOST_SPIRIT_CLASSIC_NS::impl::tst<void *, char_type> symbols;
+
+ symbols symbols_;
+
+ try
+ {
+ // It is not ok to add strings containing the null character.
+ symbols_.add(begin, end, (void*) boost::addressof(symbols_));
+ BOOST_TEST(0);
+ }
+ catch (spirit_exception &/*e*/)
+ {
+ }
+
+ try
+ {
+ // It is not ok to add strings containing the null character.
+ symbols_.add(begin2, end2, (void*) boost::addressof(symbols_));
+ BOOST_TEST(0);
+ }
+ catch (spirit_exception &/*e*/)
+ {
+ }
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/symbols_find_null.cpp b/src/boost/libs/spirit/classic/test/symbols_find_null.cpp
new file mode 100644
index 00000000..bf5a657b
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/symbols_find_null.cpp
@@ -0,0 +1,35 @@
+/*=============================================================================
+ Copyright (c) 2004 Joao Abecasis
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include <boost/spirit/include/classic_scanner.hpp>
+#include <boost/spirit/home/classic/symbols/impl/tst.ipp>
+#include <boost/utility/addressof.hpp>
+
+typedef char char_type;
+typedef char const * iterator;
+
+char_type data_[] = "whatever";
+
+iterator begin = data_;
+iterator end = data_
+ + sizeof(data_)/sizeof(char_type); // Yes, this is an intencional bug ;)
+
+int main()
+{
+ typedef BOOST_SPIRIT_CLASSIC_NS::scanner<> scanner;
+ typedef BOOST_SPIRIT_CLASSIC_NS::impl::tst<void *, char_type> symbols;
+
+ symbols symbols_;
+
+ symbols_.add(begin, end - 1, (void*) boost::addressof(symbols_));
+
+ // The symbol table parser should not choke on input containing the null
+ // character.
+ symbols_.find(scanner(begin, end));
+}
diff --git a/src/boost/libs/spirit/classic/test/symbols_tests.cpp b/src/boost/libs/spirit/classic/test/symbols_tests.cpp
new file mode 100644
index 00000000..a0bcc265
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/symbols_tests.cpp
@@ -0,0 +1,318 @@
+/*=============================================================================
+ Copyright (c) 1998-2003 Joel de Guzman
+ Copyright (c) 2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <iostream>
+#include <string>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_symbols.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+using namespace std;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+
+template <typename IteratorT>
+bool
+equal(IteratorT p, IteratorT q)
+{
+ while (*p && *p == *q)
+ {
+ ++p;
+ ++q;
+ }
+ return *p == *q;
+}
+
+template <class SymbolsT, typename CharT>
+void
+docheck
+(
+ SymbolsT const &sym,
+ CharT const *candidate,
+ bool hit,
+ CharT const *result,
+ int length
+)
+{
+ parse_info<CharT const*> info = parse(candidate, sym);
+
+#define correctly_matched hit == info.hit
+#define correct_match_length unsigned(length) == info.length
+#define correct_tail equal(candidate + (hit?1:0)*length, result)
+
+ BOOST_TEST(correctly_matched);
+
+ if (hit)
+ {
+ BOOST_TEST(correct_match_length);
+ BOOST_TEST(correct_tail);
+ }
+ else
+ {
+ BOOST_TEST(correct_tail);
+ }
+}
+
+template <typename T>
+struct store_action
+{
+ store_action(T const &v) : value(v) {}
+ void operator()(T &v) const { v = value; }
+private:
+ T const value;
+};
+
+template <typename T>
+store_action<T>
+store(T const &v)
+{
+ return v;
+}
+
+template <typename T>
+struct check_action
+{
+ check_action(T const &v) : value(v) {}
+
+#define correct_value_stored (v==value)
+ void operator()(T const &v) const { BOOST_TEST(correct_value_stored); }
+private:
+ T const value;
+};
+
+template <typename T>
+check_action<T>
+docheck(T const &v)
+{
+ return v;
+}
+
+
+static void
+default_constructible()
+{ // this actually a compile time test
+ symbols<> ns1;
+ symbols<int, wchar_t> ws1;
+ symbols<std::string, char> ns2;
+ symbols<std::string, wchar_t> ws2;
+
+ (void)ns1; (void)ws1; (void)ns2; (void)ws2;
+}
+
+static void
+narrow_match_tests()
+{
+ symbols<> sym;
+ sym = "pineapple", "orange", "banana", "applepie", "apple";
+
+ docheck(sym, "pineapple", true, "", 9);
+ docheck(sym, "orange", true, "", 6);
+ docheck(sym, "banana", true, "", 6);
+ docheck(sym, "apple", true, "", 5);
+ docheck(sym, "pizza", false, "pizza", -1);
+ docheck(sym, "steak", false, "steak", -1);
+ docheck(sym, "applepie", true, "", 8);
+ docheck(sym, "bananarama", true, "rama", 6);
+ docheck(sym, "applet", true, "t", 5);
+ docheck(sym, "applepi", true, "pi", 5);
+ docheck(sym, "appl", false, "appl", -1);
+
+ docheck(sym, "pineapplez", true, "z", 9);
+ docheck(sym, "orangez", true, "z", 6);
+ docheck(sym, "bananaz", true, "z", 6);
+ docheck(sym, "applez", true, "z", 5);
+ docheck(sym, "pizzaz", false, "pizzaz", -1);
+ docheck(sym, "steakz", false, "steakz", -1);
+ docheck(sym, "applepiez", true, "z", 8);
+ docheck(sym, "bananaramaz", true, "ramaz", 6);
+ docheck(sym, "appletz", true, "tz", 5);
+ docheck(sym, "applepix", true, "pix", 5);
+}
+
+static void
+narrow_copy_ctor_tests()
+{
+ symbols<> sym;
+ sym = "pineapple", "orange", "banana", "applepie", "apple";
+
+ symbols<> sym2(sym);
+ docheck(sym2, "pineapple", true, "", 9);
+ docheck(sym2, "pizza", false, "pizza", -1);
+ docheck(sym2, "bananarama", true, "rama", 6);
+}
+
+static void
+narrow_assigment_operator_tests()
+{
+ symbols<> sym;
+ sym = "pineapple", "orange", "banana", "applepie", "apple";
+
+ symbols<> sym2;
+ sym2 = sym;
+
+ docheck(sym2, "pineapple", true, "", 9);
+ docheck(sym2, "pizza", false, "pizza", -1);
+ docheck(sym2, "bananarama", true, "rama", 6);
+}
+
+static void
+narrow_value_tests()
+{ // also tests the add member functions
+ symbols<> sym;
+
+ sym = "orange", "banana";
+ sym.add("pineapple",1234);
+ sym.add("lemon");
+
+ parse("orange", sym[store(12345)]);
+ parse("orange", sym[docheck(12345)]);
+ parse("pineapple", sym[docheck(1234)]);
+ parse("banana", sym[docheck(int())]);
+ parse("lemon", sym[docheck(int())]);
+}
+
+static void
+narrow_free_functions_tests()
+{
+ symbols<> sym;
+
+#define add_returned_non_null_value (res!=0)
+#define add_returned_null (res==0)
+#define find_returned_non_null_value (res!=0)
+#define find_returned_null (res==0)
+
+ int *res = add(sym,"pineapple");
+ BOOST_TEST(add_returned_non_null_value);
+ res = add(sym,"pineapple");
+ BOOST_TEST(add_returned_null);
+
+ res = find(sym, "pineapple");
+ BOOST_TEST(find_returned_non_null_value);
+ res = find(sym, "banana");
+ BOOST_TEST(find_returned_null);
+}
+
+static void
+wide_match_tests()
+{
+ symbols<int, wchar_t> sym;
+ sym = L"pineapple", L"orange", L"banana", L"applepie", L"apple";
+
+ docheck(sym, L"pineapple", true, L"", 9);
+ docheck(sym, L"orange", true, L"", 6);
+ docheck(sym, L"banana", true, L"", 6);
+ docheck(sym, L"apple", true, L"", 5);
+ docheck(sym, L"pizza", false, L"pizza", -1);
+ docheck(sym, L"steak", false, L"steak", -1);
+ docheck(sym, L"applepie", true, L"", 8);
+ docheck(sym, L"bananarama", true, L"rama", 6);
+ docheck(sym, L"applet", true, L"t", 5);
+ docheck(sym, L"applepi", true, L"pi", 5);
+ docheck(sym, L"appl", false, L"appl", -1);
+
+ docheck(sym, L"pineapplez", true, L"z", 9);
+ docheck(sym, L"orangez", true, L"z", 6);
+ docheck(sym, L"bananaz", true, L"z", 6);
+ docheck(sym, L"applez", true, L"z", 5);
+ docheck(sym, L"pizzaz", false, L"pizzaz", -1);
+ docheck(sym, L"steakz", false, L"steakz", -1);
+ docheck(sym, L"applepiez", true, L"z", 8);
+ docheck(sym, L"bananaramaz", true, L"ramaz", 6);
+ docheck(sym, L"appletz", true, L"tz", 5);
+ docheck(sym, L"applepix", true, L"pix", 5);
+}
+
+static void
+wide_copy_ctor_tests()
+{
+ symbols<int, wchar_t> sym;
+ sym = L"pineapple", L"orange", L"banana", L"applepie", L"apple";
+
+ symbols<int, wchar_t> sym2(sym);
+ docheck(sym2, L"pineapple", true, L"", 9);
+ docheck(sym2, L"pizza", false, L"pizza", -1);
+ docheck(sym2, L"bananarama", true, L"rama", 6);
+}
+
+static void
+wide_assigment_operator_tests()
+{
+ symbols<int, wchar_t> sym;
+ sym = L"pineapple", L"orange", L"banana", L"applepie", L"apple";
+
+ symbols<int, wchar_t> sym2;
+ sym2 = sym;
+
+ docheck(sym2, L"pineapple", true, L"", 9);
+ docheck(sym2, L"pizza", false, L"pizza", -1);
+ docheck(sym2, L"bananarama", true, L"rama", 6);
+}
+
+static void
+wide_value_tests()
+{ // also tests the add member functions
+ symbols<int, wchar_t> sym;
+
+ sym = L"orange", L"banana";
+ sym.add(L"pineapple",1234);
+ sym.add(L"lemon");
+
+ parse(L"orange", sym[store(12345)]);
+ parse(L"orange", sym[docheck(12345)]);
+ parse(L"pineapple", sym[docheck(1234)]);
+ parse(L"banana", sym[docheck(int())]);
+ parse(L"lemon", sym[docheck(int())]);
+}
+
+static void
+wide_free_functions_tests()
+{
+ symbols<int, wchar_t> sym;
+
+ int *res = add(sym,L"pineapple");
+ BOOST_TEST(add_returned_non_null_value);
+ res = add(sym,L"pineapple");
+ BOOST_TEST(add_returned_null);
+
+ res = find(sym, L"pineapple");
+ BOOST_TEST(find_returned_non_null_value);
+ res = find(sym, L"banana");
+ BOOST_TEST(find_returned_null);
+}
+
+static
+void free_add_find_functions_tests()
+{
+ symbols<> sym;
+ BOOST_TEST(*add(sym, "a", 0) == 0);
+ BOOST_TEST(*add(sym, "a2", 1) == 1);
+ BOOST_TEST(find(sym, "a2"));
+ BOOST_TEST(find(sym, "a"));
+}
+
+int
+main()
+{
+ default_constructible();
+ narrow_match_tests();
+ narrow_copy_ctor_tests();
+ narrow_assigment_operator_tests();
+ narrow_value_tests();
+ narrow_free_functions_tests();
+ wide_match_tests();
+ wide_copy_ctor_tests();
+ wide_assigment_operator_tests();
+ wide_value_tests();
+ wide_free_functions_tests();
+ free_add_find_functions_tests();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/threads_disabled_compile.cpp b/src/boost/libs/spirit/classic/test/threads_disabled_compile.cpp
new file mode 100644
index 00000000..208cd112
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/threads_disabled_compile.cpp
@@ -0,0 +1,19 @@
+/*=============================================================================
+ Copyright (c) 2017 Nikita Kniazev
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+// Spirit should not include any Boost.Thread header until user explicitly
+// requested threadsafe support with BOOST_SPIRIT_THREADSAFE defined.
+
+#undef BOOST_SPIRIT_THREADSAFE
+#ifndef BOOST_DISABLE_THREADS
+# define BOOST_DISABLE_THREADS
+#endif
+#include <boost/spirit/include/classic.hpp>
+
+int main() { return 0; }
diff --git a/src/boost/libs/spirit/classic/test/traverse_tests.cpp b/src/boost/libs/spirit/classic/test/traverse_tests.cpp
new file mode 100644
index 00000000..17512667
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/traverse_tests.cpp
@@ -0,0 +1,517 @@
+/*=============================================================================
+ Copyright (c) 2002-2003 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+///////////////////////////////////////////////////////////////////////////////
+//
+// Traversal tests
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include <boost/config.hpp>
+#include <boost/static_assert.hpp>
+
+#ifdef BOOST_NO_STRINGSTREAM
+#include <strstream>
+#define OSSTREAM std::ostrstream
+std::string GETSTRING(std::ostrstream& ss)
+{
+ ss << ends;
+ std::string rval = ss.str();
+ ss.freeze(false);
+ return rval;
+}
+#else
+#include <sstream>
+#define GETSTRING(ss) ss.str()
+#define OSSTREAM std::ostringstream
+#endif
+
+#ifndef BOOST_SPIRIT_DEBUG
+#define BOOST_SPIRIT_DEBUG // needed for parser_name functions
+#endif
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_assign_actor.hpp>
+#include <boost/spirit/include/classic_meta.hpp>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+typedef ref_value_actor<char, assign_action> assign_actor;
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Test identity transformation
+//
+///////////////////////////////////////////////////////////////////////////////
+void
+traverse_identity_tests()
+{
+ // test type equality
+ typedef sequence<chlit<char>, chlit<char> > test_sequence1_t;
+ BOOST_STATIC_ASSERT((
+ ::boost::is_same<
+ test_sequence1_t,
+ post_order::result<identity_transform, test_sequence1_t>::type
+ >::value
+ ));
+
+ // test (rough) runtime equality
+ BOOST_TEST(
+ parse(
+ "ab",
+ post_order::traverse(identity_transform(), ch_p('a') >> 'b')
+ ).full
+ );
+ BOOST_TEST(
+ !parse(
+ "ba",
+ post_order::traverse(identity_transform(), ch_p('a') >> 'b')
+ ).hit
+ );
+
+ ///////////////////////////////////////////////////////////////////////////
+ BOOST_TEST(
+ !parse(
+ "cba",
+ post_order::traverse(
+ identity_transform(),
+ ch_p('a') >> 'b' >> 'c'
+ )
+ ).hit
+ );
+
+///////////////////////////////////////////////////////////////////////////////
+// Test more complex sequences
+char c;
+
+///////////////////////////////////////////////////////////////////////////////
+// test: ((a >> b) >> c) >> d
+ typedef
+ sequence<
+ sequence<
+ sequence<
+ kleene_star<chlit<> >,
+ action<chlit<>, assign_actor>
+ >,
+ chlit<>
+ >,
+ optional<chlit<> >
+ > test_sequence2_t;
+
+ BOOST_STATIC_ASSERT((
+ ::boost::is_same<
+ test_sequence2_t,
+ post_order::result<identity_transform, test_sequence2_t>::type
+ >::value
+ ));
+
+ c = 0;
+ BOOST_TEST(
+ parse(
+ "aabcd",
+ post_order::traverse(
+ identity_transform(),
+ ((*ch_p('a') >> ch_p('b')[assign_a(c)]) >> 'c') >> !ch_p('d')
+ )
+ ).full
+ );
+ BOOST_TEST(c == 'b');
+
+///////////////////////////////////////////////////////////////////////////////
+// test: (a >> (b >> c)) >> d
+ typedef
+ sequence<
+ sequence<
+ kleene_star<chlit<> >,
+ sequence<
+ action<chlit<>, assign_actor>,
+ chlit<>
+ >
+ >,
+ optional<chlit<char> >
+ > test_sequence3_t;
+
+ BOOST_STATIC_ASSERT((
+ ::boost::is_same<
+ test_sequence3_t,
+ post_order::result<identity_transform, test_sequence3_t>::type
+ >::value
+ ));
+
+ c = 0;
+ BOOST_TEST(
+ parse(
+ "aabcd",
+ post_order::traverse(
+ identity_transform(),
+ (*ch_p('a') >> (ch_p('b')[assign_a(c)] >> 'c')) >> !ch_p('d')
+ )
+ ).full
+ );
+ BOOST_TEST(c == 'b');
+
+///////////////////////////////////////////////////////////////////////////////
+// test: a >> (b >> (c >> d))
+ typedef
+ sequence<
+ kleene_star<chlit<> >,
+ sequence<
+ action<chlit<>, assign_actor>,
+ sequence<
+ chlit<>,
+ optional<chlit<> >
+ >
+ >
+ > test_sequence4_t;
+
+ BOOST_STATIC_ASSERT((
+ ::boost::is_same<
+ test_sequence4_t,
+ post_order::result<identity_transform, test_sequence4_t>::type
+ >::value
+ ));
+
+ c = 0;
+ BOOST_TEST(
+ parse(
+ "aabcd",
+ post_order::traverse(
+ identity_transform(),
+ *ch_p('a') >> (ch_p('b')[assign_a(c)] >> ('c' >> !ch_p('d')))
+ )
+ ).full
+ );
+ BOOST_TEST(c == 'b');
+
+///////////////////////////////////////////////////////////////////////////////
+// test: a >> ((b >> c) >> d)
+ typedef
+ sequence<
+ kleene_star<chlit<> >,
+ sequence<
+ sequence<
+ action<chlit<>, assign_actor>,
+ chlit<>
+ >,
+ optional<chlit<> >
+ >
+ > test_sequence5_t;
+
+ BOOST_STATIC_ASSERT((
+ ::boost::is_same<
+ test_sequence5_t,
+ post_order::result<identity_transform, test_sequence5_t>::type
+ >::value
+ ));
+
+ c = 0;
+ BOOST_TEST(
+ parse(
+ "aabcd",
+ post_order::traverse(
+ identity_transform(),
+ *ch_p('a') >> ((ch_p('b')[assign_a(c)] >> 'c') >> !ch_p('d'))
+ )
+ ).full
+ );
+ BOOST_TEST(c == 'b');
+
+///////////////////////////////////////////////////////////////////////////////
+// test: (a >> b) >> (c >> d)
+ typedef
+ sequence<
+ sequence<
+ kleene_star<chlit<> >,
+ action<chlit<>, assign_actor>
+ >,
+ sequence<
+ chlit<>,
+ optional<chlit<> >
+ >
+ > test_sequence6_t;
+
+ BOOST_STATIC_ASSERT((
+ ::boost::is_same<
+ test_sequence6_t,
+ post_order::result<identity_transform, test_sequence6_t>::type
+ >::value
+ ));
+
+ c = 0;
+ BOOST_TEST(
+ parse(
+ "aabcd",
+ post_order::traverse(
+ identity_transform(),
+ (*ch_p('a') >> ch_p('b')[assign_a(c)]) >> ('c' >> !ch_p('d'))
+ )
+ ).full
+ );
+ BOOST_TEST(c == 'b');
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// The following is a tracing identity_transform traverse metafunction
+//
+///////////////////////////////////////////////////////////////////////////////
+
+class trace_identity_transform
+: public transform_policies<trace_identity_transform> {
+
+public:
+ typedef trace_identity_transform self_t;
+ typedef transform_policies<trace_identity_transform> base_t;
+
+ template <typename ParserT, typename EnvT>
+ typename parser_traversal_plain_result<self_t, ParserT, EnvT>::type
+ generate_plain(ParserT const &parser_, EnvT const &env) const
+ {
+ OSSTREAM strout;
+ strout
+ << EnvT::node
+ << ": plain ("
+ << EnvT::level << ", "
+ << EnvT::index
+ << "): "
+ << parser_name(parser_);
+ traces.push_back(GETSTRING(strout));
+
+ return this->base_t::generate_plain(parser_, env);
+ }
+
+ template <typename UnaryT, typename SubjectT, typename EnvT>
+ typename parser_traversal_unary_result<self_t, UnaryT, SubjectT, EnvT>::type
+ generate_unary(UnaryT const &unary_, SubjectT const &subject_,
+ EnvT const &env) const
+ {
+ OSSTREAM strout;
+ strout
+ << EnvT::node << ": unary ("
+ << EnvT::level
+ << "): "
+ << parser_name(unary_);
+ traces.push_back(GETSTRING(strout));
+
+ return this->base_t::generate_unary(unary_, subject_, env);
+ }
+
+ template <typename ActionT, typename SubjectT, typename EnvT>
+ typename parser_traversal_action_result<self_t, ActionT, SubjectT, EnvT>::type
+ generate_action(ActionT const &action_, SubjectT const &subject_,
+ EnvT const &env) const
+ {
+ OSSTREAM strout;
+ strout
+ << EnvT::node << ": action("
+ << EnvT::level
+ << "): "
+ << parser_name(action_);
+ traces.push_back(GETSTRING(strout));
+
+ return this->base_t::generate_action(action_, subject_, env);
+ }
+
+ template <typename BinaryT, typename LeftT, typename RightT, typename EnvT>
+ typename parser_traversal_binary_result<self_t, BinaryT, LeftT, RightT, EnvT>::type
+ generate_binary(BinaryT const &binary_, LeftT const& left_,
+ RightT const& right_, EnvT const &env) const
+ {
+ OSSTREAM strout;
+ strout
+ << EnvT::node << ": binary("
+ << EnvT::level
+ << "): "
+ << parser_name(binary_);
+ traces.push_back(GETSTRING(strout));
+
+ return this->base_t::generate_binary(binary_, left_, right_, env);
+ }
+
+ std::vector<std::string> const &get_output() const { return traces; }
+
+private:
+ mutable std::vector<std::string> traces;
+};
+
+template <typename ParserT>
+void
+post_order_trace_test(ParserT const &parser_, char const *first[], size_t cnt)
+{
+// traverse
+trace_identity_transform trace_vector;
+
+ post_order::traverse(trace_vector, parser_);
+
+// The following two re-find loops ensure, that both string arrays contain the
+// same entries, only their order may differ. The differences in the trace
+// string order is based on the different parameter evaluation order as it is
+// implemented by different compilers.
+
+// re-find all trace strings in the array of expected strings
+std::vector<std::string>::const_iterator it = trace_vector.get_output().begin();
+std::vector<std::string>::const_iterator end = trace_vector.get_output().end();
+
+ BOOST_TEST(cnt == trace_vector.get_output().size());
+ for (/**/; it != end; ++it)
+ {
+ if (std::find(first, first + cnt, *it) == first + cnt)
+ std::cerr << "node in question: " << *it << std::endl;
+
+ BOOST_TEST(std::find(first, first + cnt, *it) != first + cnt);
+ }
+
+// re-find all expected strings in the vector of trace strings
+std::vector<std::string>::const_iterator begin = trace_vector.get_output().begin();
+char const *expected = first[0];
+
+ for (size_t i = 0; i < cnt - 1; expected = first[++i])
+ {
+ if (std::find(begin, end, std::string(expected)) == end)
+ std::cerr << "node in question: " << expected << std::endl;
+
+ BOOST_TEST(std::find(begin, end, std::string(expected)) != end);
+ }
+}
+
+#if defined(_countof)
+#undef _countof
+#endif
+#define _countof(x) (sizeof(x)/sizeof(x[0]))
+
+void
+traverse_trace_tests()
+{
+const char *test_result1[] = {
+ "0: plain (1, 0): chlit('a')",
+ "1: plain (1, 1): chlit('b')",
+ "2: binary(0): sequence[chlit('a'), chlit('b')]",
+ };
+
+ post_order_trace_test(
+ ch_p('a') >> 'b',
+ test_result1, _countof(test_result1)
+ );
+
+char c = 0;
+
+// test: ((a >> b) >> c) >> d
+const char *test_result2[] = {
+ "0: plain (4, 0): chlit('a')",
+ "1: unary (3): kleene_star[chlit('a')]",
+ "2: plain (4, 1): chlit('b')",
+ "3: action(3): action[chlit('b')]",
+ "4: binary(2): sequence[kleene_star[chlit('a')], action[chlit('b')]]",
+ "5: plain (2, 2): chlit('c')",
+ "6: binary(1): sequence[sequence[kleene_star[chlit('a')], action[chlit('b')]], chlit('c')]",
+ "7: plain (2, 3): chlit('d')",
+ "8: unary (1): optional[chlit('d')]",
+ "9: binary(0): sequence[sequence[sequence[kleene_star[chlit('a')], action[chlit('b')]], chlit('c')], optional[chlit('d')]]",
+ };
+
+ post_order_trace_test(
+ ((*ch_p('a') >> ch_p('b')[assign_a(c)]) >> 'c') >> !ch_p('d'),
+ test_result2, _countof(test_result2)
+ );
+
+// test: (a >> (b >> c)) >> d
+const char *test_result3[] = {
+ "0: plain (3, 0): chlit('a')",
+ "1: unary (2): kleene_star[chlit('a')]",
+ "2: plain (4, 1): chlit('b')",
+ "3: action(3): action[chlit('b')]",
+ "4: plain (3, 2): chlit('c')",
+ "5: binary(2): sequence[action[chlit('b')], chlit('c')]",
+ "6: binary(1): sequence[kleene_star[chlit('a')], sequence[action[chlit('b')], chlit('c')]]",
+ "7: plain (2, 3): chlit('d')",
+ "8: unary (1): optional[chlit('d')]",
+ "9: binary(0): sequence[sequence[kleene_star[chlit('a')], sequence[action[chlit('b')], chlit('c')]], optional[chlit('d')]]",
+ };
+
+ post_order_trace_test(
+ (*ch_p('a') >> (ch_p('b')[assign_a(c)] >> 'c')) >> !ch_p('d'),
+ test_result3, _countof(test_result3)
+ );
+
+// test: a >> (b >> (c >> d))
+const char *test_result4[] = {
+ "0: plain (2, 0): chlit('a')",
+ "1: unary (1): kleene_star[chlit('a')]",
+ "2: plain (3, 1): chlit('b')",
+ "3: action(2): action[chlit('b')]",
+ "4: plain (3, 2): chlit('c')",
+ "5: plain (4, 3): chlit('d')",
+ "6: unary (3): optional[chlit('d')]",
+ "7: binary(2): sequence[chlit('c'), optional[chlit('d')]]",
+ "8: binary(1): sequence[action[chlit('b')], sequence[chlit('c'), optional[chlit('d')]]]",
+ "9: binary(0): sequence[kleene_star[chlit('a')], sequence[action[chlit('b')], sequence[chlit('c'), optional[chlit('d')]]]]",
+ };
+
+ post_order_trace_test(
+ *ch_p('a') >> (ch_p('b')[assign_a(c)] >> ('c' >> !ch_p('d'))),
+ test_result4, _countof(test_result4)
+ );
+
+// test: a >> ((b >> c) >> d)
+const char *test_result5[] = {
+ "0: plain (2, 0): chlit('a')",
+ "1: unary (1): kleene_star[chlit('a')]",
+ "2: plain (4, 1): chlit('b')",
+ "3: action(3): action[chlit('b')]",
+ "4: plain (3, 2): chlit('c')",
+ "5: binary(2): sequence[action[chlit('b')], chlit('c')]",
+ "6: plain (3, 3): chlit('d')",
+ "7: unary (2): optional[chlit('d')]",
+ "8: binary(1): sequence[sequence[action[chlit('b')], chlit('c')], optional[chlit('d')]]",
+ "9: binary(0): sequence[kleene_star[chlit('a')], sequence[sequence[action[chlit('b')], chlit('c')], optional[chlit('d')]]]",
+ };
+
+ post_order_trace_test(
+ *ch_p('a') >> ((ch_p('b')[assign_a(c)] >> 'c') >> !ch_p('d')),
+ test_result5, _countof(test_result5)
+ );
+
+// test: (a >> b) >> (c >> d)
+const char *test_result6[] = {
+ "0: plain (3, 0): chlit('a')",
+ "1: unary (2): kleene_star[chlit('a')]",
+ "2: plain (3, 1): chlit('b')",
+ "3: action(2): action[chlit('b')]",
+ "4: binary(1): sequence[kleene_star[chlit('a')], action[chlit('b')]]",
+ "5: plain (2, 2): chlit('c')",
+ "6: plain (3, 3): chlit('d')",
+ "7: unary (2): optional[chlit('d')]",
+ "8: binary(1): sequence[chlit('c'), optional[chlit('d')]]",
+ "9: binary(0): sequence[sequence[kleene_star[chlit('a')], action[chlit('b')]], sequence[chlit('c'), optional[chlit('d')]]]",
+ };
+
+ post_order_trace_test(
+ (*ch_p('a') >> ch_p('b')[assign_a(c)]) >> ('c' >> !ch_p('d')),
+ test_result6, _countof(test_result6)
+ );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Main
+//
+///////////////////////////////////////////////////////////////////////////////
+int
+main()
+{
+ traverse_identity_tests();
+ traverse_trace_tests();
+
+ return boost::report_errors();
+}
+
diff --git a/src/boost/libs/spirit/classic/test/tree_tests.cpp b/src/boost/libs/spirit/classic/test/tree_tests.cpp
new file mode 100644
index 00000000..be9b5ee5
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/tree_tests.cpp
@@ -0,0 +1,383 @@
+/*=============================================================================
+ Copyright (c) 2003 Giovanni Bajo
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_ast.hpp>
+#include <boost/spirit/include/classic_tree_to_xml.hpp>
+#include <boost/preprocessor/arithmetic/inc.hpp>
+#include <boost/preprocessor/punctuation/comma_if.hpp>
+#include <boost/preprocessor/repetition.hpp>
+#include <boost/preprocessor/arithmetic/sub.hpp>
+#include <boost/mpl/list.hpp>
+#include <boost/mpl/apply.hpp>
+#include <boost/mpl/remove.hpp>
+#include <boost/mpl/size.hpp>
+#include <boost/mpl/for_each.hpp>
+
+#include <map>
+#include <string>
+
+#include <fstream>
+#include <boost/detail/lightweight_test.hpp>
+#include "impl/string_length.hpp"
+
+#define DEBUG_DUMP_TREES (1)
+
+//////////////////////////////////////////////////////////////////////////////
+// rule_id helper
+// http://sf.net/tracker/index.php?func=detail&aid=715483&group_id=28447&atid=393389)
+
+namespace boost { namespace spirit {
+
+ template <
+ typename ScannerT,
+ unsigned long ID = 0,
+ typename ContextT = parser_context<> >
+ class rule_id
+ : public rule<ScannerT, ContextT, parser_tag<ID> >
+ {
+ typedef rule<ScannerT, ContextT, parser_tag<ID> > base_t;
+
+ public:
+ // Forward ctors and operator=.
+ rule_id()
+ {}
+
+ template <typename T>
+ rule_id(const T& a)
+ : base_t(a) {}
+
+ template <typename T>
+ rule_id& operator=(const T& a)
+ { base_t::operator=(a); return *this; }
+ };
+}}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Framework setup
+
+namespace mpl = boost::mpl;
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+using namespace std;
+
+
+enum RULE_ID
+{
+ ID_A = 1,
+ ID_B,
+ ID_C,
+ ID_ROOT
+};
+
+map<parser_id, string> rule_names;
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Generic tree manipulation tools
+
+template <typename TreeT>
+RULE_ID id(TreeT& t)
+{ return (RULE_ID)t.value.id().to_long(); }
+
+
+template <typename TreeT>
+TreeT& child(TreeT& t, unsigned n)
+{
+ return t.children[n];
+}
+
+template <typename TreeT>
+size_t num_children(const TreeT& t)
+{ return t.children.size(); }
+
+template <typename TreeT>
+typename TreeT::parse_node_t::iterator_t ValueBeginIterator(TreeT& t)
+{ return t.value.begin(); }
+
+template <typename TreeT>
+typename TreeT::parse_node_t::iterator_t ValueEndIterator(TreeT& t)
+{ return t.value.end(); }
+
+template <typename TreeT>
+bool equal(TreeT& a, TreeT& b)
+{
+ if (id(a) != id(b))
+ return false;
+
+ if (num_children(a) != num_children(b))
+ return false;
+
+ unsigned n = num_children(a);
+ for (unsigned i=0;i<n;i++)
+ if (!equal(child(a, i), child(b, i)))
+ return false;
+
+ return true;
+}
+
+template <typename TreeT>
+void dump(ostream& o, TreeT& t, int level = 0)
+{
+ string name;
+ string value;
+ map<parser_id, string>::iterator iter =
+ rule_names.find(id(t));
+
+ if (iter == rule_names.end())
+ name = "noname";
+ else
+ name = iter->second;
+
+ value.assign(ValueBeginIterator(t), ValueEndIterator(t));
+
+ for (int i=0;i<level;i++)
+ o << " ";
+
+
+ o << name << ": " << value << endl;
+
+ unsigned n = num_children(t);
+ for (unsigned c=0;c<n;c++)
+ dump(o, child(t, c), level+1);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Tree folding
+
+namespace test_impl {
+
+ template <typename ParmT>
+ struct fold_node
+ {
+ // assign a subtree
+ void operator()(ParmT& t, ParmT ch) const
+ { t = ch; }
+
+ // wrong specialization
+ template <typename TreeT>
+ void operator()(TreeT& t, ParmT p) const
+ { typedef typename TreeT::this_should_never_be_compiled type; }
+ };
+
+ template <>
+ struct fold_node<nil_t>
+ {
+ template <typename TreeT>
+ void operator()(TreeT& t, nil_t) const
+ { typedef typename TreeT::this_should_never_be_compiled type; }
+ };
+
+ template <>
+ struct fold_node<RULE_ID>
+ {
+ template <typename TreeT>
+ void operator()(TreeT& t, RULE_ID id) const
+ { t.value.id(id); }
+ };
+
+ template <typename ParmT>
+ struct fold_child
+ {
+ template <typename TreeT>
+ void operator()(TreeT& t, ParmT p, unsigned n) const
+ { fold_node<ParmT>()(t.children[n], p); }
+ };
+
+ template <>
+ struct fold_child<nil_t>
+ {
+ template <typename TreeT>
+ void operator()(TreeT& t, nil_t, unsigned n) const
+ {}
+ };
+}
+
+template <typename TreeT,
+ typename T, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6, typename T7, typename T8>
+TreeT fold(T p, T1 p1, T2 p2, T3 p3, T4 p4, T5 p5, T6 p6, T7 p7, T8 p8)
+{
+ // Prepare a list with all the template types
+ typedef mpl::list<T1,T2,T3,T4,T5,T6,T7,T8> full_list_t;
+
+ // Remove the ones equal to nil_t: they are the default parameters
+ // unspecified from the user
+ typedef typename mpl::remove<full_list_t, nil_t>::type parm_list_t;
+
+ // Get the size of the list = number of parameters specified by the user
+ typedef typename mpl::size<parm_list_t>::type parm_list_size_t;
+ enum { NUM_CHILDREN = parm_list_size_t::value };
+
+ TreeT t;
+
+ // Generate the root of the tree (specialized for the first parameter)
+ test_impl::fold_node<T>()(t, p);
+
+ // Make room for the children
+ if (NUM_CHILDREN > 0)
+ t.children.resize(NUM_CHILDREN);
+
+ // For each children, call the GenerateChild function, which is specialized
+ // on the different types
+ test_impl::fold_child<T1>()(t, p1, 0);
+ test_impl::fold_child<T2>()(t, p2, 1);
+ test_impl::fold_child<T3>()(t, p3, 2);
+ test_impl::fold_child<T4>()(t, p4, 3);
+ test_impl::fold_child<T5>()(t, p5, 4);
+ test_impl::fold_child<T6>()(t, p6, 5);
+ test_impl::fold_child<T7>()(t, p7, 6);
+ test_impl::fold_child<T8>()(t, p8, 7);
+
+ return t;
+}
+
+
+// Define fold() wrapper for 1->7 parameters: they just call the 8 parameter
+// version passing nil_t for the other arguments
+#define PUT_EMPTY(Z, N, _) nil_t()
+
+#define DEFINE_FOLD(Z, N, _) \
+ template <typename TreeT, typename T BOOST_PP_COMMA_IF(N) \
+ BOOST_PP_ENUM_PARAMS(N, typename T) > \
+ TreeT fold(T p BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_BINARY_PARAMS(N, T, p)) \
+ { \
+ return fold<TreeT>(p \
+ BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N, p) \
+ BOOST_PP_COMMA_IF(BOOST_PP_SUB(8,N)) \
+ BOOST_PP_ENUM(BOOST_PP_SUB(8,N), PUT_EMPTY, _)); \
+ }
+
+BOOST_PP_REPEAT(7, DEFINE_FOLD, _)
+
+#undef PUT_EMPTY
+#undef DEFINE_FOLD
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// test_banal: simple tree construction
+
+struct test_banal : public grammar<test_banal>
+{
+ template <class T>
+ struct definition
+ {
+ rule_id<T, ID_ROOT> root;
+ rule_id<T, ID_A> a;
+ rule_id<T, ID_B> b;
+ rule_id<T, ID_C> c;
+
+ definition(const test_banal&)
+ {
+ root = a >> c;
+ a = b;
+ b = chlit<>('b');
+ c = chlit<>('c');
+ }
+
+ const rule_id<T, ID_ROOT>& start()
+ { return root; }
+ };
+
+ const char* pattern(void)
+ {
+ return "bc";
+ }
+
+ template <typename TreeT>
+ TreeT expected_tree(void)
+ {
+ return fold<TreeT>(
+ ID_ROOT, fold<TreeT>(
+ ID_A,
+ ID_B),
+ ID_C);
+ }
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+// All the tests
+
+typedef mpl::list
+<
+ test_banal
+
+> tests_t;
+
+
+//////////////////////////////////////////////////////////////////////////////
+// run_test - code to run a test
+
+struct run_test
+{
+ template <typename TestT>
+ void operator()(TestT gram)
+ {
+ typedef const char* iterator_t;
+ typedef node_val_data_factory<nil_t> factory_t;
+ typedef typename
+ factory_t
+ ::BOOST_NESTED_TEMPLATE factory<iterator_t>
+ ::node_t node_t;
+ typedef tree_node<node_t> tree_t;
+
+ iterator_t text_begin = gram.pattern();
+ iterator_t text_end = text_begin + test_impl::string_length(text_begin);
+
+ tree_parse_info<iterator_t, factory_t> info =
+ ast_parse(text_begin, text_end, gram);
+
+ BOOST_TEST(info.full);
+
+ tree_t expected = gram.template expected_tree<tree_t>();
+
+#if DEBUG_DUMP_TREES
+ dump(cout, info.trees[0]);
+ dump(cout, expected);
+#endif
+
+ BOOST_TEST(equal(info.trees[0], expected));
+ }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+// main() stuff
+
+#ifdef BOOST_NO_EXCEPTIONS
+namespace boost
+{
+ void throw_exception(std::exception const & )
+ {
+ std::cerr << "Exception caught" << std::endl;
+ BOOST_TEST(0);
+ }
+}
+
+#endif
+
+
+void init(void)
+{
+ rule_names[ID_ROOT] = "ID_ROOT";
+ rule_names[ID_A] = "ID_A";
+ rule_names[ID_B] = "ID_B";
+ rule_names[ID_C] = "ID_C";
+}
+
+
+int main()
+{
+ init();
+
+ mpl::for_each<tests_t, mpl::_> (run_test());
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/tree_to_xml.cpp b/src/boost/libs/spirit/classic/test/tree_to_xml.cpp
new file mode 100644
index 00000000..d6a4724b
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/tree_to_xml.cpp
@@ -0,0 +1,186 @@
+/*=============================================================================
+ Copyright (c) 2001-2007 Hartmut Kaiser
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_ast.hpp>
+#include <boost/spirit/include/classic_tree_to_xml.hpp>
+
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable: 4702) // unreachable code
+#endif
+#include <boost/iostreams/stream.hpp>
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
+///////////////////////////////////////////////////////////////////////////////
+struct calculator : public grammar<calculator>
+{
+ static const int integerID = 1;
+ static const int factorID = 2;
+ static const int termID = 3;
+ static const int expressionID = 4;
+
+ template <typename ScannerT>
+ struct definition
+ {
+ definition(calculator const& /*self*/)
+ {
+ // Start grammar definition
+ integer = leaf_node_d[ lexeme_d[
+ (!ch_p('-') >> +digit_p)
+ ] ];
+
+ factor = integer
+ | inner_node_d[ch_p('(') >> expression >> ch_p(')')]
+ | (root_node_d[ch_p('-')] >> factor);
+
+ term = factor >>
+ *( (root_node_d[ch_p('*')] >> factor)
+ | (root_node_d[ch_p('/')] >> factor)
+ );
+
+ expression = term >>
+ *( (root_node_d[ch_p('+')] >> term)
+ | (root_node_d[ch_p('-')] >> term)
+ );
+ // End grammar definition
+
+ // turn on the debugging info.
+ BOOST_SPIRIT_DEBUG_RULE(integer);
+ BOOST_SPIRIT_DEBUG_RULE(factor);
+ BOOST_SPIRIT_DEBUG_RULE(term);
+ BOOST_SPIRIT_DEBUG_RULE(expression);
+ }
+
+ rule<ScannerT, parser_context<>, parser_tag<expressionID> > expression;
+ rule<ScannerT, parser_context<>, parser_tag<termID> > term;
+ rule<ScannerT, parser_context<>, parser_tag<factorID> > factor;
+ rule<ScannerT, parser_context<>, parser_tag<integerID> > integer;
+
+ rule<ScannerT, parser_context<>, parser_tag<expressionID> > const&
+ start() const { return expression; }
+ };
+};
+
+///////////////////////////////////////////////////////////////////////////////
+/// this is a Boost.IoStreams source device usable to create a istream on
+/// top of a random access container (i.e. vector<>)
+template<typename Container>
+class container_device
+{
+public:
+ typedef typename Container::value_type char_type;
+ typedef boost::iostreams::sink_tag category;
+
+ container_device(Container& container)
+ : container_(container), pos_(0)
+ {}
+
+ /// Write up to n characters to the underlying data sink into the
+ /// buffer s, returning the number of characters written
+ std::streamsize write(const char_type* s, std::streamsize n)
+ {
+ std::streamsize result = 0;
+ if (pos_ != container_.size()) {
+ std::streamsize amt =
+ static_cast<std::streamsize>(container_.size() - pos_);
+ result = (std::min)(n, amt);
+ std::copy(s, s + result, container_.begin() + pos_);
+ pos_ += static_cast<size_type>(result);
+ }
+ if (result < n) {
+ container_.insert(container_.end(), s, s + n);
+ pos_ = container_.size();
+ }
+ return n;
+ }
+
+ Container& container() { return container_; }
+
+private:
+ typedef typename Container::size_type size_type;
+ Container& container_;
+ size_type pos_;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+#define EXPECTED_XML_OUTPUT "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n\
+<!DOCTYPE parsetree SYSTEM \"parsetree.dtd\">\n\
+<!-- 1+2 -->\n\
+<parsetree version=\"1.0\">\n\
+ <parsenode>\n\
+ <value>+</value>\n\
+ <parsenode>\n\
+ <value>1</value>\n\
+ </parsenode>\n\
+ <parsenode>\n\
+ <value>2</value>\n\
+ </parsenode>\n\
+ </parsenode>\n\
+</parsetree>\n"
+
+#define EXPECTED_XML_OUTPUT_WIDE BOOST_PP_CAT(L, EXPECTED_XML_OUTPUT)
+
+bool test(wchar_t const *text)
+{
+ typedef std::basic_string<wchar_t>::iterator iterator_t;
+
+ std::basic_string<wchar_t> input(text);
+ calculator calc;
+ tree_parse_info<iterator_t> ast_info =
+ ast_parse(iterator_t(input.begin()), iterator_t(input.end()),
+ calc >> end_p, space_p);
+
+ std::basic_string<wchar_t> out;
+ {
+ typedef container_device<std::basic_string<wchar_t> > device_type;
+ boost::iostreams::stream<device_type> outsink(out);
+ basic_tree_to_xml<wchar_t>(outsink, ast_info.trees, input);
+ }
+ return out == EXPECTED_XML_OUTPUT_WIDE;
+}
+
+bool test(char const *text)
+{
+ typedef std::string::iterator iterator_t;
+
+ std::string input(text);
+ calculator calc;
+ tree_parse_info<iterator_t> ast_info =
+ ast_parse(iterator_t(input.begin()), iterator_t(input.end()),
+ calc >> end_p, space_p);
+
+ std::string out;
+ {
+ typedef container_device<std::string> device_type;
+ boost::iostreams::stream<device_type> outsink(out);
+ basic_tree_to_xml<char>(outsink, ast_info.trees, input);
+ }
+ return out == EXPECTED_XML_OUTPUT;
+}
+
+int main()
+{
+ BOOST_TEST(test("1+2"));
+ if (std::has_facet<std::ctype<wchar_t> >(std::locale()))
+ {
+ BOOST_TEST(test(L"1+2"));
+ }
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/spirit/classic/test/typeof_support/typeof_actor.cpp b/src/boost/libs/spirit/classic/test/typeof_support/typeof_actor.cpp
new file mode 100644
index 00000000..447d06d8
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/typeof_support/typeof_actor.cpp
@@ -0,0 +1,13 @@
+/*=============================================================================
+ Copyright (c) 2006 Tobias Schwinger
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#define BOOST_TYPEOF_EMULATION
+#include <boost/spirit/include/classic_typeof.hpp>
+#include <boost/spirit/include/classic_actor.hpp>
+
diff --git a/src/boost/libs/spirit/classic/test/typeof_support/typeof_attribute.cpp b/src/boost/libs/spirit/classic/test/typeof_support/typeof_attribute.cpp
new file mode 100644
index 00000000..bb1e8ffb
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/typeof_support/typeof_attribute.cpp
@@ -0,0 +1,13 @@
+/*=============================================================================
+ Copyright (c) 2006 Tobias Schwinger
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#define BOOST_TYPEOF_EMULATION
+#include <boost/spirit/include/classic_typeof.hpp>
+#include <boost/spirit/include/classic_attribute.hpp>
+
diff --git a/src/boost/libs/spirit/classic/test/typeof_support/typeof_core.cpp b/src/boost/libs/spirit/classic/test/typeof_support/typeof_core.cpp
new file mode 100644
index 00000000..5b08f964
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/typeof_support/typeof_core.cpp
@@ -0,0 +1,13 @@
+/*=============================================================================
+ Copyright (c) 2006 Tobias Schwinger
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#define BOOST_TYPEOF_EMULATION
+#include <boost/spirit/include/classic_typeof.hpp>
+#include <boost/spirit/include/classic_core.hpp>
+
diff --git a/src/boost/libs/spirit/classic/test/typeof_support/typeof_debug.cpp b/src/boost/libs/spirit/classic/test/typeof_support/typeof_debug.cpp
new file mode 100644
index 00000000..2cdc5637
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/typeof_support/typeof_debug.cpp
@@ -0,0 +1,15 @@
+/*=============================================================================
+ Copyright (c) 2006 Tobias Schwinger
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#define BOOST_TYPEOF_EMULATION
+#define BOOST_SPIRIT_DEBUG
+
+#include <boost/spirit/include/classic_typeof.hpp>
+#include <boost/spirit/include/classic_debug.hpp>
+
diff --git a/src/boost/libs/spirit/classic/test/typeof_support/typeof_dynamic.cpp b/src/boost/libs/spirit/classic/test/typeof_support/typeof_dynamic.cpp
new file mode 100644
index 00000000..9ebb546a
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/typeof_support/typeof_dynamic.cpp
@@ -0,0 +1,17 @@
+/*=============================================================================
+ Copyright (c) 2006 Tobias Schwinger
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#define BOOST_TYPEOF_EMULATION
+#include <boost/spirit/include/classic_typeof.hpp>
+#include <boost/spirit/include/classic_dynamic.hpp>
+
+// currently not in the master header
+#include <boost/spirit/include/classic_switch.hpp>
+#include <boost/spirit/include/classic_select.hpp>
+
diff --git a/src/boost/libs/spirit/classic/test/typeof_support/typeof_error_handling.cpp b/src/boost/libs/spirit/classic/test/typeof_support/typeof_error_handling.cpp
new file mode 100644
index 00000000..1d1d7f37
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/typeof_support/typeof_error_handling.cpp
@@ -0,0 +1,13 @@
+/*=============================================================================
+ Copyright (c) 2006 Tobias Schwinger
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#define BOOST_TYPEOF_EMULATION
+#include <boost/spirit/include/classic_typeof.hpp>
+#include <boost/spirit/include/classic_error_handling.hpp>
+
diff --git a/src/boost/libs/spirit/classic/test/typeof_support/typeof_iterator.cpp b/src/boost/libs/spirit/classic/test/typeof_support/typeof_iterator.cpp
new file mode 100644
index 00000000..a3517616
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/typeof_support/typeof_iterator.cpp
@@ -0,0 +1,13 @@
+/*=============================================================================
+ Copyright (c) 2006 Tobias Schwinger
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#define BOOST_TYPEOF_EMULATION
+#include <boost/spirit/include/classic_typeof.hpp>
+#include <boost/spirit/include/classic_iterator.hpp>
+
diff --git a/src/boost/libs/spirit/classic/test/typeof_support/typeof_symbols.cpp b/src/boost/libs/spirit/classic/test/typeof_support/typeof_symbols.cpp
new file mode 100644
index 00000000..c88c9410
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/typeof_support/typeof_symbols.cpp
@@ -0,0 +1,13 @@
+/*=============================================================================
+ Copyright (c) 2006 Tobias Schwinger
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#define BOOST_TYPEOF_EMULATION
+#include <boost/spirit/include/classic_typeof.hpp>
+#include <boost/spirit/include/classic_symbols.hpp>
+
diff --git a/src/boost/libs/spirit/classic/test/typeof_support/typeof_tree.cpp b/src/boost/libs/spirit/classic/test/typeof_support/typeof_tree.cpp
new file mode 100644
index 00000000..b18ea487
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/typeof_support/typeof_tree.cpp
@@ -0,0 +1,15 @@
+/*=============================================================================
+ Copyright (c) 2006 Tobias Schwinger
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#define BOOST_TYPEOF_EMULATION
+#include <boost/spirit/include/classic_typeof.hpp>
+
+#include <boost/spirit/include/classic_ast.hpp>
+#include <boost/spirit/include/classic_parse_tree.hpp>
+
diff --git a/src/boost/libs/spirit/classic/test/typeof_support/typeof_utility.cpp b/src/boost/libs/spirit/classic/test/typeof_support/typeof_utility.cpp
new file mode 100644
index 00000000..eb947818
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/typeof_support/typeof_utility.cpp
@@ -0,0 +1,18 @@
+/*=============================================================================
+ Copyright (c) 2006 Tobias Schwinger
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+#define BOOST_TYPEOF_EMULATION
+#include <boost/spirit/include/classic_typeof.hpp>
+
+#include <boost/spirit/include/classic_utility.hpp>
+
+// currently not in the master header
+#include <boost/spirit/include/classic_regex.hpp>
+#include <boost/spirit/include/classic_grammar_def.hpp>
+
diff --git a/src/boost/libs/spirit/classic/test/while_p_as_parser_tests.cpp b/src/boost/libs/spirit/classic/test/while_p_as_parser_tests.cpp
new file mode 100644
index 00000000..e1aee4f9
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/while_p_as_parser_tests.cpp
@@ -0,0 +1,42 @@
+/*=============================================================================
+ Copyright (c) 2003 Martin Wille
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_while.hpp>
+
+extern bool fun();
+
+struct ftor
+{
+ bool operator()() const;
+};
+
+int
+main()
+{
+ //////////////////////////////////
+ // compile time check wether as_parser<> works for while_p
+
+ ::BOOST_SPIRIT_CLASSIC_NS::rule<> r;
+
+ r = ::BOOST_SPIRIT_CLASSIC_NS::while_p('-')['-'];
+ r = ::BOOST_SPIRIT_CLASSIC_NS::while_p("-")["-"];
+
+ r = ::BOOST_SPIRIT_CLASSIC_NS::while_p(&fun)["foo"];
+ r = ::BOOST_SPIRIT_CLASSIC_NS::while_p(ftor())["foo"];
+
+ r = ::BOOST_SPIRIT_CLASSIC_NS::while_p(r)[r];
+
+ r = ::BOOST_SPIRIT_CLASSIC_NS::do_p['-'].while_p('-');
+ r = ::BOOST_SPIRIT_CLASSIC_NS::do_p["-"].while_p("-");
+
+ r = ::BOOST_SPIRIT_CLASSIC_NS::do_p["foo"].while_p(&fun);
+ r = ::BOOST_SPIRIT_CLASSIC_NS::do_p["foo"].while_p(ftor());
+
+ r = ::BOOST_SPIRIT_CLASSIC_NS::do_p[r].while_p(r);
+}
diff --git a/src/boost/libs/spirit/classic/test/while_tests.cpp b/src/boost/libs/spirit/classic/test/while_tests.cpp
new file mode 100644
index 00000000..33219e5a
--- /dev/null
+++ b/src/boost/libs/spirit/classic/test/while_tests.cpp
@@ -0,0 +1,202 @@
+/*=============================================================================
+ Phoenix V1.0
+ Copyright (c) 2002-2003 Martin Wille
+
+ Use, modification and distribution is subject to 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)
+==============================================================================*/
+// vi:ts=4:sw=4:et
+// Tests for BOOST_SPIRIT_CLASSIC_NS::while_p
+// [28-Dec-2002]
+////////////////////////////////////////////////////////////////////////////////
+#include <iostream>
+#include <cstring>
+
+#include "impl/string_length.hpp"
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_assign_actor.hpp>
+#include <boost/spirit/include/classic_while.hpp>
+#include <boost/ref.hpp>
+
+namespace local
+{
+ template <typename T>
+ struct var_wrapper
+ : public ::boost::reference_wrapper<T>
+ {
+ typedef boost::reference_wrapper<T> parent;
+
+ explicit inline var_wrapper(T& t) : parent(t) {}
+
+ inline T& operator()() const { return parent::get(); }
+ };
+
+ template <typename T>
+ inline var_wrapper<T>
+ var(T& t)
+ {
+ return var_wrapper<T>(t);
+ }
+}
+
+namespace
+{
+ template <typename T>
+ class add_actor
+ {
+ public:
+ explicit add_actor(T &ref_) : ref(ref_) {}
+
+ template <typename T2>
+ void operator()(T2 const &val) const
+ { ref += val; }
+
+ private:
+ T& ref;
+ };
+
+ template <typename T>
+ inline add_actor<T> const
+ add(T& ref)
+ {
+ return add_actor<T>(ref);
+ }
+}
+
+typedef BOOST_SPIRIT_CLASSIC_NS::rule<> rule_t;
+
+unsigned int test_count = 0;
+unsigned int error_count = 0;
+unsigned int iterations_performed;
+
+unsigned int number_result;
+static const unsigned int kError = 999;
+static const bool good = true;
+static const bool bad = false;
+
+rule_t while_rule;
+rule_t do_while_rule;
+
+void
+test_while(
+ char const *s,
+ unsigned int wanted,
+ rule_t const &r,
+ unsigned int iterations_wanted)
+{
+ using namespace std;
+
+ ++test_count;
+
+ number_result = 0;
+ iterations_performed = 0;
+
+ BOOST_SPIRIT_CLASSIC_NS::parse_info<> m = BOOST_SPIRIT_CLASSIC_NS::parse(s, s+ test_impl::string_length(s), r);
+
+ bool result = wanted == kError?(m.full?bad:good): (number_result==wanted);
+
+ result &= iterations_performed == iterations_wanted;
+
+ if (m.full && (m.length != test_impl::string_length(s)))
+ result = bad;
+
+ if (result==good)
+ cout << "PASSED";
+ else
+ {
+ ++error_count;
+ cout << "FAILED";
+ }
+
+ cout << ": \"" << s << "\" ==> ";
+ if (!m.full)
+ cout << "<error>";
+ else
+ cout << number_result;
+ cout << " " << iterations_performed << " of "
+ << iterations_wanted << " iterations\n";
+}
+
+template<typename T>
+struct inc_actor
+{
+ explicit inc_actor(T &t) : var(t) {}
+ template<typename IteratorT>
+ void operator()(IteratorT const &, IteratorT const &) const
+ {
+ ++var;
+ }
+ template<typename U>
+ void operator()(U) const
+ {
+ ++var;
+ }
+ T &var;
+};
+
+template<typename T>
+inc_actor<T>
+inc(T &t)
+{
+ return inc_actor<T>(t);
+}
+
+int
+main()
+{
+ using namespace std;
+ using ::BOOST_SPIRIT_CLASSIC_NS::uint_p;
+ using ::BOOST_SPIRIT_CLASSIC_NS::while_p;
+ using ::BOOST_SPIRIT_CLASSIC_NS::do_p;
+ using ::BOOST_SPIRIT_CLASSIC_NS::assign_a;
+
+#if qDebug
+ BOOST_SPIRIT_DEBUG_RULE(while_rule);
+ BOOST_SPIRIT_DEBUG_RULE(do_while_rule);
+#endif
+
+ while_rule
+ = uint_p[assign_a(number_result)]
+ >> while_p('+')
+ [
+ uint_p[add(number_result)][inc(iterations_performed)]
+ ];
+
+ do_while_rule
+ = do_p
+ [
+ uint_p[add(number_result)][inc(iterations_performed)]
+ ].while_p('+');
+
+ cout << "/////////////////////////////////////////////////////////\n";
+ cout << "\n";
+ cout << " while_p test\n";
+ cout << "\n";
+ cout << "/////////////////////////////////////////////////////////\n";
+ cout << "\n";
+
+ cout << "while_p()[]\n";
+ test_while("", kError, while_rule, 0);
+ test_while("1", 1, while_rule, 0);
+ test_while("1+1", 2, while_rule, 1);
+ test_while("1+1+12", 14, while_rule, 2);
+ test_while("1+1+x", kError, while_rule, 1);
+
+ cout << "do_p[].while_p()\n";
+ test_while("", kError, do_while_rule, 0);
+ test_while("1", 1, do_while_rule, 1);
+ test_while("1+1", 2, do_while_rule, 2);
+ test_while("1+1+12", 14, do_while_rule, 3);
+ test_while("1+1+x", kError, do_while_rule, 2);
+
+ std::cout << "\n ";
+ if (error_count==0)
+ cout << "All " << test_count << " while_p-tests passed.\n"
+ << "Test concluded successfully\n";
+ else
+ cout << error_count << " of " << test_count << " while_p-tests failed\n"
+ << "Test failed\n";
+
+ return error_count!=0;
+}