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 using namespace std;
14 
15 //#define BOOST_SPIRIT_DEBUG
16 #define BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
17 #include <boost/spirit/include/classic_core.hpp>
18 #include <boost/spirit/include/classic_grammar_def.hpp>
19 using namespace BOOST_SPIRIT_CLASSIC_NS;
20 
21 ///////////////////////////////////////////////////////////////////////////////
22 //  This feature is disabled on non compliant compilers (e.g. Borland 5.5.1
23 //  VC6 and VC7)
24 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && \
25     !BOOST_WORKAROUND(__BORLANDC__, <= 0x551) && \
26     !BOOST_WORKAROUND(__GNUC__, < 3)
27 # define BOOST_SPIRIT_USE_GRAMMARDEF
28 #endif
29 
30 //////////////////////////////////////////////////////////////////////////////
31 //
32 //  Grammar tests
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35 struct num_list : public grammar<num_list>
36 {
37     enum {
38         default_rule = 0,
39         num_rule = 1,
40     };
41 
42     template <typename ScannerT>
43     struct definition
44 #if defined(BOOST_SPIRIT_USE_GRAMMARDEF)
45     :   public grammar_def<rule<ScannerT>, same>
46 #endif
47     {
definitionnum_list::definition48         definition(num_list const& /*self*/)
49         {
50             num = int_p;
51             r = num >> *(',' >> num);
52 
53 #if defined(BOOST_SPIRIT_USE_GRAMMARDEF)
54             this->start_parsers(r, num);
55 #endif
56             BOOST_SPIRIT_DEBUG_RULE(num);
57             BOOST_SPIRIT_DEBUG_RULE(r);
58         }
59 
60         rule<ScannerT> r, num;
61 
62 #if !defined(BOOST_SPIRIT_USE_GRAMMARDEF)
startnum_list::definition63         rule<ScannerT> const& start() const { return r; }
64 #endif
65     };
66 };
67 
68 struct num_list_ex : public grammar<num_list_ex>
69 {
70     enum {
71         default_rule = 0,
72         num_rule = 1,
73         integer_rule = 2
74     };
75 
76     template <typename ScannerT>
77     struct definition
78 #if defined(BOOST_SPIRIT_USE_GRAMMARDEF)
79     :   public grammar_def<rule<ScannerT>, same, int_parser<int, 10, 1, -1> >
80 #endif
81     {
definitionnum_list_ex::definition82         definition(num_list_ex const& /*self*/)
83         {
84             num = integer;
85             r = num >> *(',' >> num);
86 
87 #if defined(BOOST_SPIRIT_USE_GRAMMARDEF)
88             this->start_parsers(r, num, integer);
89 #endif
90             BOOST_SPIRIT_DEBUG_RULE(num);
91             BOOST_SPIRIT_DEBUG_RULE(r);
92         }
93 
94         rule<ScannerT> r, num;
95         int_parser<int, 10, 1, -1> integer;
96 
97 #if !defined(BOOST_SPIRIT_USE_GRAMMARDEF)
startnum_list_ex::definition98         rule<ScannerT> const& start() const { return r; }
99 #endif
100     };
101 };
102 
103 void
grammar_tests()104 grammar_tests()
105 {
106     num_list nlist;
107     BOOST_SPIRIT_DEBUG_GRAMMAR(nlist);
108 
109     parse_info<char const*> pi;
110     pi = parse("123, 456, 789", nlist, space_p);
111     BOOST_TEST(pi.hit);
112     BOOST_TEST(pi.full);
113 
114 #if defined(BOOST_SPIRIT_USE_GRAMMARDEF)
115     num_list_ex nlistex;
116     BOOST_SPIRIT_DEBUG_GRAMMAR(nlistex);
117 
118     pi = parse("123, 456, 789", nlist.use_parser<num_list::default_rule>(),
119         space_p);
120     BOOST_TEST(pi.hit);
121     BOOST_TEST(pi.full);
122 
123     pi = parse("123", nlist.use_parser<num_list::num_rule>(), space_p);
124     BOOST_TEST(pi.hit);
125     BOOST_TEST(pi.full);
126 
127     pi = parse("123, 456, 789", nlistex, space_p);
128     BOOST_TEST(pi.hit);
129     BOOST_TEST(pi.full);
130 
131     pi = parse("123, 456, 789",
132         nlistex.use_parser<num_list_ex::default_rule>(), space_p);
133     BOOST_TEST(pi.hit);
134     BOOST_TEST(pi.full);
135 
136     pi = parse("123", nlistex.use_parser<num_list_ex::num_rule>(), space_p);
137     BOOST_TEST(pi.hit);
138     BOOST_TEST(pi.full);
139 
140     pi = parse("123", nlistex.use_parser<num_list_ex::integer_rule>(),
141         space_p);
142     BOOST_TEST(pi.hit);
143     BOOST_TEST(pi.full);
144 #endif // defined(BOOST_SPIRIT_USE_GRAMMARDEF)
145 }
146 
147 ///////////////////////////////////////////////////////////////////////////////
148 //
149 //  Main
150 //
151 ///////////////////////////////////////////////////////////////////////////////
152 int
main()153 main()
154 {
155     grammar_tests();
156     return boost::report_errors();
157 }
158 
159