Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/spirit/example/intermediate/parameters.cpp @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 6.4 KB
Line 
1/*=============================================================================
2    Copyright (c) 2001-2003 Hartmut Kaiser
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 sample show the usage of parser parameters.
11//
12// Parser parameters are used to pass some values from the outer parsing scope
13// to the next inner scope. They can be imagined as the opposite to the return
14// value paradigm, which returns some value from the inner to the next outer
15// scope. See the "Closures" chapter in the User's Guide.
16
17#include <string>
18#include <iostream>
19#include <cassert>
20
21#if defined(_MSC_VER) /*&& !defined(__COMO__)*/
22#pragma warning(disable: 4244)
23#pragma warning(disable: 4355)
24#endif // defined(_MSC_VER) && !defined(__COMO__)
25
26#include <boost/spirit/core.hpp>
27#include <boost/spirit/symbols/symbols.hpp>
28
29#include <boost/spirit/phoenix/tuples.hpp>
30#include <boost/spirit/phoenix/tuple_helpers.hpp>
31#include <boost/spirit/phoenix/primitives.hpp>
32#include <boost/spirit/attribute/closure.hpp>
33
34///////////////////////////////////////////////////////////////////////////////
35// used namespaces
36using namespace boost::spirit;
37using namespace phoenix;
38using namespace std;
39
40///////////////////////////////////////////////////////////////////////////////
41// Helper class for encapsulation of the type for the parsed variable names
42class declaration_type
43{
44public:
45    enum vartype {
46        vartype_unknown = 0,        // unknown variable type
47        vartype_int = 1,            // 'int'
48        vartype_real = 2            // 'real'
49    };
50
51    declaration_type() : type(vartype_unknown)
52    {
53    }
54    template <typename ItT>
55    declaration_type(ItT const &first, ItT const &last)
56    {
57        init(string(first, last-first-1));
58    }
59    declaration_type(declaration_type const &type_) : type(type_.type)
60    {
61    }
62    declaration_type(string const &type_) : type(vartype_unknown)
63    {
64        init(type_);
65    }
66
67// access to the variable type
68    operator vartype const &() const { return type; }
69    operator string ()
70    {
71        switch(type) {
72        default:
73        case vartype_unknown:   break;
74        case vartype_int:       return string("int");
75        case vartype_real:      return string("real");
76        }
77        return string ("unknown");
78    }
79
80    void swap(declaration_type &s) { std::swap(type, s.type); }
81
82protected:
83    void init (string const &type_)
84    {
85        if (type_ == "int")
86            type = vartype_int;
87        else if (type_ == "real")
88            type = vartype_real;
89        else
90            type = vartype_unknown;
91    }
92
93private:
94    vartype type;
95};
96
97///////////////////////////////////////////////////////////////////////////////
98//
99//  used closure type
100//
101///////////////////////////////////////////////////////////////////////////////
102struct var_decl_closure : boost::spirit::closure<var_decl_closure, declaration_type>
103{
104    member1 val;
105};
106
107///////////////////////////////////////////////////////////////////////////////
108//
109//  symbols_with_data
110//
111//      Helper class for inserting an item with data into a symbol table
112//
113///////////////////////////////////////////////////////////////////////////////
114template <typename T, typename InitT>
115class symbols_with_data
116{
117public:
118    typedef
119        symbol_inserter<T, boost::spirit::impl::tst<T, char> >
120        symbol_inserter_t;
121
122    symbols_with_data(symbol_inserter_t const &add_, InitT const &data_) :
123        add(add_), data(as_actor<InitT>::convert(data_))
124    {
125    }
126
127    template <typename IteratorT>
128    symbol_inserter_t const &
129    operator()(IteratorT const &first_, IteratorT const &last) const
130    {
131        IteratorT first = first_;
132        return add(first, last, data());
133    }
134
135private:
136    symbol_inserter_t const &add;
137    typename as_actor<InitT>::type data;
138};
139
140template <typename T, typename CharT, typename InitT>
141inline
142symbols_with_data<T, InitT>
143symbols_gen(symbol_inserter<T, boost::spirit::impl::tst<T, CharT> > const &add_,
144    InitT const &data_)
145{
146    return symbols_with_data<T, InitT>(add_, data_);
147}
148
149///////////////////////////////////////////////////////////////////////////////
150// The var_decl_list grammar parses variable declaration list
151
152struct var_decl_list :
153    public grammar<var_decl_list, var_decl_closure::context_t>
154{
155    template <typename ScannerT>
156    struct definition
157    {
158        definition(var_decl_list const &self)
159        {
160        // pass variable type returned from 'type' to list closure member 0
161            decl = type[self.val = arg1] >> +space_p >> list(self.val);
162
163        // m0 to access arg 0 of list --> passing variable type down to ident
164            list = ident(list.val) >> *(',' >> ident(list.val));
165
166        // store identifier and type into the symbol table
167            ident = (*alnum_p)[symbols_gen(symtab.add, ident.val)];
168
169        // the type of the decl is returned in type's closure member 0
170            type =
171                    str_p("int")[type.val = construct_<string>(arg1, arg2)]
172                |   str_p("real")[type.val = construct_<string>(arg1, arg2)]
173                ;
174
175            BOOST_SPIRIT_DEBUG_RULE(decl);
176            BOOST_SPIRIT_DEBUG_RULE(list);
177            BOOST_SPIRIT_DEBUG_RULE(ident);
178            BOOST_SPIRIT_DEBUG_RULE(type);
179        }
180
181        rule<ScannerT> const&
182        start() const { return decl; }
183
184    private:
185        typedef rule<ScannerT, var_decl_closure::context_t> rule_t;
186        rule_t type;
187        rule_t list;
188        rule_t ident;
189        symbols<declaration_type> symtab;
190
191        rule<ScannerT> decl;        // start rule
192    };
193};
194
195///////////////////////////////////////////////////////////////////////////////
196// main entry point
197int main()
198{
199var_decl_list decl;
200declaration_type type;
201char const *pbegin = "int  var1";
202
203    if (parse (pbegin, decl[assign(type)]).full) {
204        cout << endl
205             << "Parsed variable declarations successfully!" << endl
206             << "Detected type: " << declaration_type::vartype(type)
207             << " (" << string(type) << ")"
208             << endl;
209    } else {
210        cout << endl
211             << "Parsing the input stream failed!"
212             << endl;
213    }
214    return 0;
215}
216
Note: See TracBrowser for help on using the repository browser.