• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2004 Angus Leeming
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 ///////////////////////////////////////////////////////////////////////////////
11 //
12 // The switch_p parser was broken sometime during the boost 1.32 development
13 // cycle. This little program tests it, the for_p parser and the limit_d
14 // directive.
15 //
16 ///////////////////////////////////////////////////////////////////////////////
17 
18 #include <boost/spirit/include/classic_core.hpp>
19 #include <boost/spirit/include/classic_for.hpp>
20 #include <boost/spirit/include/classic_switch.hpp>
21 #include <boost/spirit/include/classic_position_iterator.hpp>
22 #include <boost/spirit/include/classic_confix.hpp>
23 
24 #include <boost/spirit/include/phoenix1.hpp>
25 
26 #include <iostream>
27 #include <string>
28 
29 namespace spirit = BOOST_SPIRIT_CLASSIC_NS;
30 
31 typedef unsigned int uint;
32 
33 struct switch_grammar : public spirit::grammar<switch_grammar> {
34     template <typename ScannerT>
35     struct definition {
36         definition(switch_grammar const & self);
37 
38         typedef spirit::rule<ScannerT> rule_t;
startswitch_grammar::definition39         rule_t const & start() const { return expression; }
40 
41     private:
42         rule_t expression;
43         uint index;
44         uint nnodes;
45     };
46 };
47 
48 
49 template <typename ScannerT>
definition(switch_grammar const &)50 switch_grammar::definition<ScannerT>::definition(switch_grammar const & /*self*/)
51 {
52     using boost::cref;
53 
54     using phoenix::arg1;
55     using phoenix::var;
56 
57     using spirit::case_p;
58     using spirit::for_p;
59     using spirit::limit_d;
60     using spirit::str_p;
61     using spirit::switch_p;
62     using spirit::uint_p;
63 
64     expression =
65         str_p("NNODES") >>
66         uint_p[var(nnodes) = arg1] >>
67 
68         for_p(var(index) = 1,
69               var(index) <= var(nnodes),
70               var(index)++)
71         [
72             limit_d(cref(index), cref(index))[uint_p] >>
73 
74             switch_p[(
75                 case_p<'s'>(uint_p),
76                 case_p<'d'>(uint_p),
77                 case_p<'n'>(uint_p)
78             )]
79         ];
80 }
81 
82 
main()83 int main()
84 {
85     std::string const data("NNODES 3\n"
86                    "1 s 1\n"
87                    "2 d 2\n"
88                    "3 n 3"); // JDG 10-18-2005 removed trailing \n to
89                              // avoid post skip problems
90 
91     typedef spirit::position_iterator<std::string::const_iterator>
92         iterator_t;
93 
94     spirit::parse_info<iterator_t> const info =
95         parse(iterator_t(data.begin(), data.end(), "switch test"),
96               iterator_t(),
97               switch_grammar(),
98               spirit::space_p);
99 
100     if (!info.full) {
101         spirit::file_position const fp = info.stop.get_position();
102         std::cerr << "Parsing failed at line " << fp.line
103               << ", column " << fp.column << ".\n";
104     }
105 
106     return info.full ? 0 : 1;
107 }
108