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