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