1 /*=============================================================================
2     Copyright (c) 2001-2003 Joel de Guzman
3     Copyright (c) 2003 Hartmut Kaiser
4     http://spirit.sourceforge.net/
5 
6     Use, modification and distribution is subject to the Boost Software
7     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8     http://www.boost.org/LICENSE_1_0.txt)
9 =============================================================================*/
10 #include <iostream>
11 #include <boost/detail/lightweight_test.hpp>
12 
13 
14 //#define BOOST_SPIRIT_DEBUG
15 #define BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
16 #include <boost/spirit/include/classic_core.hpp>
17 #include <boost/spirit/include/classic_grammar_def.hpp>
18 using namespace BOOST_SPIRIT_CLASSIC_NS;
19 
20 ///////////////////////////////////////////////////////////////////////////////
21 //  This feature is disabled on non compliant compilers (e.g. Borland 5.5.1
22 //  VC6 and VC7)
23 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && \
24     !BOOST_WORKAROUND(__BORLANDC__, <= 0x551) && \
25     !BOOST_WORKAROUND(__GNUC__, < 3)
26 # define BOOST_SPIRIT_USE_GRAMMARDEF
27 #endif
28 
29 //////////////////////////////////////////////////////////////////////////////
30 //
31 //  Grammar tests
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 struct num_list : public grammar<num_list>
35 {
36     enum {
37         default_rule = 0,
38         num_rule = 1
39     };
40 
41     template <typename ScannerT>
42     struct definition
43 #if defined(BOOST_SPIRIT_USE_GRAMMARDEF)
44     :   public grammar_def<rule<ScannerT>, same>
45 #endif
46     {
definitionnum_list::definition47         definition(num_list const& /*self*/)
48         {
49             num = int_p;
50             r = num >> *(',' >> num);
51 
52 #if defined(BOOST_SPIRIT_USE_GRAMMARDEF)
53             this->start_parsers(r, num);
54 #endif
55             BOOST_SPIRIT_DEBUG_RULE(num);
56             BOOST_SPIRIT_DEBUG_RULE(r);
57         }
58 
59         rule<ScannerT> r, num;
60 
61 #if !defined(BOOST_SPIRIT_USE_GRAMMARDEF)
startnum_list::definition62         rule<ScannerT> const& start() const { return r; }
63 #endif
64     };
65 };
66 
67 struct num_list_ex : public grammar<num_list_ex>
68 {
69     enum {
70         default_rule = 0,
71         num_rule = 1,
72         integer_rule = 2
73     };
74 
75     template <typename ScannerT>
76     struct definition
77 #if defined(BOOST_SPIRIT_USE_GRAMMARDEF)
78     :   public grammar_def<rule<ScannerT>, same, int_parser<int, 10, 1, -1> >
79 #endif
80     {
definitionnum_list_ex::definition81         definition(num_list_ex const& /*self*/)
82         {
83             num = integer;
84             r = num >> *(',' >> num);
85 
86 #if defined(BOOST_SPIRIT_USE_GRAMMARDEF)
87             this->start_parsers(r, num, integer);
88 #endif
89             BOOST_SPIRIT_DEBUG_RULE(num);
90             BOOST_SPIRIT_DEBUG_RULE(r);
91         }
92 
93         rule<ScannerT> r, num;
94         int_parser<int, 10, 1, -1> integer;
95 
96 #if !defined(BOOST_SPIRIT_USE_GRAMMARDEF)
startnum_list_ex::definition97         rule<ScannerT> const& start() const { return r; }
98 #endif
99     };
100 };
101 
102 void
grammar_tests()103 grammar_tests()
104 {
105     num_list nlist;
106     BOOST_SPIRIT_DEBUG_GRAMMAR(nlist);
107 
108     parse_info<char const*> pi;
109     pi = parse("123, 456, 789", nlist, space_p);
110     BOOST_TEST(pi.hit);
111     BOOST_TEST(pi.full);
112 
113 #if defined(BOOST_SPIRIT_USE_GRAMMARDEF)
114     num_list_ex nlistex;
115     BOOST_SPIRIT_DEBUG_GRAMMAR(nlistex);
116 
117     pi = parse("123, 456, 789", nlist.use_parser<num_list::default_rule>(),
118         space_p);
119     BOOST_TEST(pi.hit);
120     BOOST_TEST(pi.full);
121 
122     pi = parse("123", nlist.use_parser<num_list::num_rule>(), space_p);
123     BOOST_TEST(pi.hit);
124     BOOST_TEST(pi.full);
125 
126     pi = parse("123, 456, 789", nlistex, space_p);
127     BOOST_TEST(pi.hit);
128     BOOST_TEST(pi.full);
129 
130     pi = parse("123, 456, 789",
131         nlistex.use_parser<num_list_ex::default_rule>(), space_p);
132     BOOST_TEST(pi.hit);
133     BOOST_TEST(pi.full);
134 
135     pi = parse("123", nlistex.use_parser<num_list_ex::num_rule>(), space_p);
136     BOOST_TEST(pi.hit);
137     BOOST_TEST(pi.full);
138 
139     pi = parse("123", nlistex.use_parser<num_list_ex::integer_rule>(),
140         space_p);
141     BOOST_TEST(pi.hit);
142     BOOST_TEST(pi.full);
143 #endif // defined(BOOST_SPIRIT_USE_GRAMMARDEF)
144 }
145 
146 ///////////////////////////////////////////////////////////////////////////////
147 //
148 //  Main
149 //
150 ///////////////////////////////////////////////////////////////////////////////
151 int
main()152 main()
153 {
154     grammar_tests();
155     return boost::report_errors();
156 }
157 
158