1 /*=============================================================================
2 Copyright (c) 2001-2010 Joel de Guzman
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 =============================================================================*/
7 #include <boost/spirit/include/qi_string.hpp>
8 #include <boost/spirit/include/qi_char.hpp>
9 #include <boost/spirit/include/qi_action.hpp>
10 #include <boost/spirit/include/qi_auxiliary.hpp>
11 #include <boost/spirit/include/qi_directive.hpp>
12 #include <boost/spirit/include/qi_operator.hpp>
13 #include <boost/spirit/include/qi_nonterminal.hpp>
14 #include <boost/spirit/include/support_argument.hpp>
15 #include <boost/spirit/include/phoenix_core.hpp>
16 #include <boost/spirit/include/phoenix_operator.hpp>
17
18 #include <boost/core/lightweight_test.hpp>
19 #include <boost/core/lightweight_test_trait.hpp>
20
21 #include <iostream>
22 #include "test.hpp"
23
24 // Custom string type with a C-style string conversion.
25 struct custom_string_c
26 {
custom_string_ccustom_string_c27 custom_string_c(char c) { str[0] = c; str[1] = '\0'; }
28
operator char*custom_string_c29 operator char*() { return str; }
operator char const*custom_string_c30 operator char const*() const { return str; }
31
32 private:
33 char str[2];
34 };
35
36 int
main()37 main()
38 {
39 using spirit_test::test;
40 using spirit_test::test_attr;
41 using boost::spirit::qi::symbols;
42 using boost::spirit::qi::rule;
43 using boost::spirit::qi::lazy;
44 using boost::spirit::qi::_r1;
45
46 { // basics
47 symbols<char, int> sym;
48
49 sym.add
50 ("Joel")
51 ("Ruby")
52 ("Tenji")
53 ("Tutit")
54 ("Kim")
55 ("Joey")
56 ("Joeyboy")
57 ;
58
59 BOOST_TEST_TRAIT_TRUE((boost::spirit::traits::is_parser<symbols<char, int> >));
60
61 BOOST_TEST((test("Joel", sym)));
62 BOOST_TEST((test("Ruby", sym)));
63 BOOST_TEST((test("Tenji", sym)));
64 BOOST_TEST((test("Tutit", sym)));
65 BOOST_TEST((test("Kim", sym)));
66 BOOST_TEST((test("Joey", sym)));
67 BOOST_TEST((test("Joeyboy", sym)));
68 BOOST_TEST((!test("XXX", sym)));
69
70 // test copy
71 symbols<char, int> sym2;
72 sym2 = sym;
73 BOOST_TEST((test("Joel", sym2)));
74 BOOST_TEST((test("Ruby", sym2)));
75 BOOST_TEST((test("Tenji", sym2)));
76 BOOST_TEST((test("Tutit", sym2)));
77 BOOST_TEST((test("Kim", sym2)));
78 BOOST_TEST((test("Joey", sym2)));
79 BOOST_TEST((!test("XXX", sym2)));
80
81 // make sure it plays well with other parsers
82 BOOST_TEST((test("Joelyo", sym >> "yo")));
83
84 sym.remove
85 ("Joel")
86 ("Ruby")
87 ;
88
89 BOOST_TEST((!test("Joel", sym)));
90 BOOST_TEST((!test("Ruby", sym)));
91 }
92
93 { // comma syntax
94 symbols<char, int> sym;
95 sym += "Joel", "Ruby", "Tenji", "Tutit", "Kim", "Joey";
96
97 BOOST_TEST((test("Joel", sym)));
98 BOOST_TEST((test("Ruby", sym)));
99 BOOST_TEST((test("Tenji", sym)));
100 BOOST_TEST((test("Tutit", sym)));
101 BOOST_TEST((test("Kim", sym)));
102 BOOST_TEST((test("Joey", sym)));
103 BOOST_TEST((!test("XXX", sym)));
104
105 sym -= "Joel", "Ruby";
106
107 BOOST_TEST((!test("Joel", sym)));
108 BOOST_TEST((!test("Ruby", sym)));
109 }
110
111 { // no-case handling
112 using namespace boost::spirit::ascii;
113
114 symbols<char, int> sym;
115 // NOTE: make sure all entries are in lower-case!!!
116 sym = "joel", "ruby", "tenji", "tutit", "kim", "joey";
117
118 BOOST_TEST((test("joel", no_case[sym])));
119 BOOST_TEST((test("ruby", no_case[sym])));
120 BOOST_TEST((test("tenji", no_case[sym])));
121 BOOST_TEST((test("tutit", no_case[sym])));
122 BOOST_TEST((test("kim", no_case[sym])));
123 BOOST_TEST((test("joey", no_case[sym])));
124
125 BOOST_TEST((test("JOEL", no_case[sym])));
126 BOOST_TEST((test("RUBY", no_case[sym])));
127 BOOST_TEST((test("TENJI", no_case[sym])));
128 BOOST_TEST((test("TUTIT", no_case[sym])));
129 BOOST_TEST((test("KIM", no_case[sym])));
130 BOOST_TEST((test("JOEY", no_case[sym])));
131
132 // make sure it plays well with other parsers
133 BOOST_TEST((test("Joelyo", no_case[sym] >> "yo")));
134 }
135
136 { // attributes
137 symbols<char, int> sym;
138
139 sym.add
140 ("Joel", 1)
141 ("Ruby", 2)
142 ("Tenji", 3)
143 ("Tutit", 4)
144 ("Kim", 5)
145 ("Joey", 6)
146 ("Joeyboy", 7)
147 ;
148
149 int i;
150 BOOST_TEST((test_attr("Joel", sym, i)));
151 BOOST_TEST(i == 1);
152 BOOST_TEST((test_attr("Ruby", sym, i)));
153 BOOST_TEST(i == 2);
154 BOOST_TEST((test_attr("Tenji", sym, i)));
155 BOOST_TEST(i == 3);
156 BOOST_TEST((test_attr("Tutit", sym, i)));
157 BOOST_TEST(i == 4);
158 BOOST_TEST((test_attr("Kim", sym, i)));
159 BOOST_TEST(i == 5);
160 BOOST_TEST((test_attr("Joey", sym, i)));
161 BOOST_TEST(i == 6);
162 BOOST_TEST((test_attr("Joeyboy", sym, i)));
163 BOOST_TEST(i == 7);
164 BOOST_TEST((!test_attr("XXX", sym, i)));
165
166 // double add:
167
168 sym.add("Joel", 265);
169 BOOST_TEST((test_attr("Joel", sym, i)));
170 BOOST_TEST(i == 1);
171 }
172
173 { // actions
174 namespace phx = boost::phoenix;
175 using boost::spirit::_1;
176
177 symbols<char, int> sym;
178 sym.add
179 ("Joel", 1)
180 ("Ruby", 2)
181 ("Tenji", 3)
182 ("Tutit", 4)
183 ("Kim", 5)
184 ("Joey", 6)
185 ;
186
187 int i;
188 BOOST_TEST((test("Joel", sym[phx::ref(i) = _1])));
189 BOOST_TEST(i == 1);
190 BOOST_TEST((test("Ruby", sym[phx::ref(i) = _1])));
191 BOOST_TEST(i == 2);
192 BOOST_TEST((test("Tenji", sym[phx::ref(i) = _1])));
193 BOOST_TEST(i == 3);
194 BOOST_TEST((test("Tutit", sym[phx::ref(i) = _1])));
195 BOOST_TEST(i == 4);
196 BOOST_TEST((test("Kim", sym[phx::ref(i) = _1])));
197 BOOST_TEST(i == 5);
198 BOOST_TEST((test("Joey", sym[phx::ref(i) = _1])));
199 BOOST_TEST(i == 6);
200 BOOST_TEST((!test("XXX", sym[phx::ref(i) = _1])));
201 }
202
203 return boost::report_errors();
204 }
205