]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/classic/example/intermediate/lazy_parser.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / classic / example / intermediate / lazy_parser.cpp
1 /*=============================================================================
2 Copyright (c) 2003 Vaclav Vesely
3 http://spirit.sourceforge.net/
4
5 Use, modification and distribution is subject to the Boost Software
6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 http://www.boost.org/LICENSE_1_0.txt)
8 =============================================================================*/
9 //
10 // This example demonstrates the lazy_p parser. You should read
11 // "The Lazy Parser" in the documentation.
12 //
13 // We want to parse nested blocks of numbers like this:
14 //
15 // dec {
16 // 1 2 3
17 // bin {
18 // 1 10 11
19 // }
20 // 4 5 6
21 // }
22 //
23 // where the numbers in the "dec" block are wrote in the decimal system and
24 // the numbers in the "bin" block are wrote in the binary system. We want
25 // parser to return the overall sum.
26 //
27 // To achive this when base ("bin" or "dec") is parsed, in semantic action
28 // we store a pointer to the appropriate numeric parser in the closure
29 // variable block.int_rule. Than, when we need to parse a number we use lazy_p
30 // parser to invoke the parser stored in the block.int_rule pointer.
31 //
32 //-----------------------------------------------------------------------------
33 #include <boost/assert.hpp>
34 #include <boost/cstdlib.hpp>
35 #include <boost/spirit/include/phoenix1.hpp>
36 #include <boost/spirit/include/classic_core.hpp>
37 #include <boost/spirit/include/classic_symbols.hpp>
38 #include <boost/spirit/include/classic_attribute.hpp>
39 #include <boost/spirit/include/classic_dynamic.hpp>
40
41 using namespace boost;
42 using namespace BOOST_SPIRIT_CLASSIC_NS;
43 using namespace phoenix;
44
45 //-----------------------------------------------------------------------------
46 // my grammar
47
48 struct my_grammar
49 : public grammar<my_grammar, parser_context<int> >
50 {
51 // grammar definition
52 template<typename ScannerT>
53 struct definition
54 {
55 typedef rule<ScannerT> rule_t;
56 typedef stored_rule<ScannerT, parser_context<int> > number_rule_t;
57
58 struct block_closure;
59 typedef boost::spirit::classic::closure<
60 block_closure,
61 int,
62 typename number_rule_t::alias_t>
63 closure_base_t;
64
65 struct block_closure : closure_base_t
66 {
67 typename closure_base_t::member1 sum;
68 typename closure_base_t::member2 int_rule;
69 };
70
71 // block rule type
72 typedef rule<ScannerT, typename block_closure::context_t> block_rule_t;
73
74 block_rule_t block;
75 rule_t block_item;
76 symbols<number_rule_t> base;
77
78 definition(my_grammar const& self)
79 {
80 block =
81 base[
82 block.sum = 0,
83 // store a number rule in a closure member
84 block.int_rule = arg1
85 ]
86 >> "{"
87 >> *block_item
88 >> "}"
89 ;
90
91 block_item =
92 // use the stored rule
93 lazy_p(block.int_rule)[block.sum += arg1]
94 | block[block.sum += arg1]
95 ;
96
97 // bind base keywords and number parsers
98 base.add
99 ("bin", bin_p)
100 ("dec", uint_p)
101 ;
102 }
103
104 block_rule_t const& start() const
105 {
106 return block;
107 }
108 };
109 };
110
111 //-----------------------------------------------------------------------------
112
113 int main()
114 {
115 my_grammar gram;
116 parse_info<> info;
117
118 int result;
119 info = parse("bin{1 dec{1 2 3} 10}", gram[var(result) = arg1], space_p);
120 BOOST_ASSERT(info.full);
121 BOOST_ASSERT(result == 9);
122
123 return exit_success;
124 }
125
126 //-----------------------------------------------------------------------------