Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/spirit/example/intermediate/lazy_parser.cpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 3.6 KB
Line 
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 <cassert>
34#include <boost/cstdlib.hpp>
35#include <boost/spirit/phoenix.hpp>
36#include <boost/spirit/core.hpp>
37#include <boost/spirit/symbols.hpp>
38#include <boost/spirit/attribute.hpp>
39#include <boost/spirit/dynamic.hpp>
40
41using namespace boost;
42using namespace spirit;
43using namespace phoenix;
44
45//-----------------------------------------------------------------------------
46//  my grammar
47
48struct 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 spirit::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
113int 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    assert(info.full);
121    assert(result == 9);
122
123    return exit_success;
124}
125
126//-----------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.