• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2001-2011 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/detail/lightweight_test.hpp>
8 #include <boost/spirit/include/qi_string.hpp>
9 #include <boost/spirit/include/qi_char.hpp>
10 #include <boost/spirit/include/qi_action.hpp>
11 #include <boost/spirit/include/qi_auxiliary.hpp>
12 #include <boost/spirit/include/qi_directive.hpp>
13 #include <boost/spirit/include/qi_operator.hpp>
14 #include <boost/spirit/include/qi_nonterminal.hpp>
15 #include <boost/spirit/include/support_argument.hpp>
16 #include <boost/spirit/include/phoenix_core.hpp>
17 #include <boost/spirit/include/phoenix_operator.hpp>
18 
19 #include <iostream>
20 #include "test.hpp"
21 
22 // Custom string type with a C-style string conversion.
23 struct custom_string_c
24 {
custom_string_ccustom_string_c25     custom_string_c(char c) { str[0] = c; str[1] = '\0'; }
26 
operator char*custom_string_c27     operator char*() { return str; }
operator char const*custom_string_c28     operator char const*() const { return str; }
29 
30 private:
31     char str[2];
32 };
33 
get_str(char const * str)34 std::string get_str(char const* str)
35 {
36     return std::string(str);
37 }
38 
39 int
main()40 main()
41 {
42     using spirit_test::test;
43     using spirit_test::test_attr;
44     using boost::spirit::qi::symbols;
45     using boost::spirit::qi::rule;
46     using boost::spirit::qi::lazy;
47     using boost::spirit::qi::_r1;
48 
49     { // construction from symbol array
50         char const* syms[] = {"Joel","Ruby","Tenji","Tutit","Kim","Joey"};
51         symbols<char, int> sym(syms);
52 
53         BOOST_TEST((test("Joel", sym)));
54         BOOST_TEST((test("Ruby", sym)));
55         BOOST_TEST((test("Tenji", sym)));
56         BOOST_TEST((test("Tutit", sym)));
57         BOOST_TEST((test("Kim", sym)));
58         BOOST_TEST((test("Joey", sym)));
59         BOOST_TEST((!test("XXX", sym)));
60     }
61 
62     { // construction from 2 arrays
63 
64         char const* syms[] = {"Joel","Ruby","Tenji","Tutit","Kim","Joey"};
65         int data[] = {1,2,3,4,5,6};
66         symbols<char, int> sym(syms, data);
67 
68         int i;
69         BOOST_TEST((test_attr("Joel", sym, i)));
70         BOOST_TEST(i == 1);
71         BOOST_TEST((test_attr("Ruby", sym, i)));
72         BOOST_TEST(i == 2);
73         BOOST_TEST((test_attr("Tenji", sym, i)));
74         BOOST_TEST(i == 3);
75         BOOST_TEST((test_attr("Tutit", sym, i)));
76         BOOST_TEST(i == 4);
77         BOOST_TEST((test_attr("Kim", sym, i)));
78         BOOST_TEST(i == 5);
79         BOOST_TEST((test_attr("Joey", sym, i)));
80         BOOST_TEST(i == 6);
81         BOOST_TEST((!test_attr("XXX", sym, i)));
82     }
83 
84     { // allow std::string and other string types
85         symbols<> sym;
86 
87         // const and non-const std::string
88         std::string a("abc");
89         std::string const b("def");
90         sym += a;
91         sym += b;
92         BOOST_TEST((test("abc", sym)));
93         BOOST_TEST((test("def", sym)));
94         sym = a;
95         BOOST_TEST((test("abc", sym)));
96         BOOST_TEST((!test("def", sym)));
97 
98         // non-const C-style string
99         char arr[2]; arr[0] = 'a'; arr[1] = '\0';
100         sym = arr;
101         BOOST_TEST((test("a", sym)));
102         BOOST_TEST((!test("b", sym)));
103 
104         // const and non-const custom string type
105         custom_string_c c('x');
106         custom_string_c const cc('y');
107         sym = c, cc;
108         BOOST_TEST((test("x", sym)));
109         BOOST_TEST((test("y", sym)));
110         BOOST_TEST((!test("z", sym)));
111     }
112 
113     {
114         namespace phx = boost::phoenix;
115 
116         symbols<char, int> sym;
117         sym.add
118             ("a", 1)
119             ("b", 2)
120         ;
121 
122         rule<char const*, int(symbols<char, int>&)> r;
123         r %= lazy(_r1);
124 
125         int i = 0;
126         BOOST_TEST(test_attr("a", r(phx::ref(sym)), i));
127         BOOST_TEST(i == 1);
128         BOOST_TEST(test_attr("b", r(phx::ref(sym)), i));
129         BOOST_TEST(i == 2);
130         BOOST_TEST(!test("c", r(phx::ref(sym))));
131     }
132 
133     { // find
134 
135         symbols<char, int> sym;
136         sym.add("a", 1)("b", 2);
137 
138         BOOST_TEST(!sym.find("c"));
139 
140         BOOST_TEST(sym.find("a") && *sym.find("a") == 1);
141         BOOST_TEST(sym.find("b") && *sym.find("b") == 2);
142 
143         BOOST_TEST(sym.at("a") == 1);
144         BOOST_TEST(sym.at("b") == 2);
145         BOOST_TEST(sym.at("c") == 0);
146 
147         BOOST_TEST(sym.find("a") && *sym.find("a") == 1);
148         BOOST_TEST(sym.find("b") && *sym.find("b") == 2);
149         BOOST_TEST(sym.find("c") && *sym.find("c") == 0);
150 
151         symbols<char, int> const_sym(sym);
152 
153         BOOST_TEST(const_sym.find("a") && *const_sym.find("a") == 1);
154         BOOST_TEST(const_sym.find("b") && *const_sym.find("b") == 2);
155         BOOST_TEST(const_sym.find("c") && *const_sym.find("c") == 0);
156         BOOST_TEST(!const_sym.find("d"));
157 
158         char const *str1 = "all";
159         char const *first = str1, *last = str1 + 3;
160         BOOST_TEST(*sym.prefix_find(first, last) == 1 && first == str1 + 1);
161 
162         char const *str2 = "dart";
163         first = str2; last = str2 + 4;
164         BOOST_TEST(!sym.prefix_find(first, last) && first == str2);
165     }
166 
167     { // name
168         symbols <char, int> sym,sym2;
169         sym.name("test");
170         BOOST_TEST(sym.name()=="test");
171         sym2 = sym;
172         BOOST_TEST(sym2.name()=="test");
173 
174         symbols <char,int> sym3(sym);
175         BOOST_TEST(sym3.name()=="test");
176     }
177 
178     { // Substrings
179 
180         symbols<char, int> sym;
181         BOOST_TEST(sym.at("foo") == 0);
182         sym.at("foo") = 1;
183         BOOST_TEST(sym.at("foo") == 1);
184         BOOST_TEST(sym.at("fool") == 0);
185         sym.at("fool") = 2;
186         BOOST_TEST(sym.find("foo") && *sym.find("foo") == 1);
187         BOOST_TEST(sym.find("fool") && *sym.find("fool") == 2);
188         BOOST_TEST(!sym.find("foolish"));
189         BOOST_TEST(!sym.find("foot"));
190         BOOST_TEST(!sym.find("afoot"));
191 
192         char const *str, *first, *last;
193         str = "foolish"; first = str; last = str + 7;
194         BOOST_TEST(*sym.prefix_find(first, last) == 2 && first == str + 4);
195 
196         first = str; last = str + 4;
197         BOOST_TEST(*sym.prefix_find(first, last) == 2 && first == str + 4);
198 
199         str = "food"; first = str; last = str + 4;
200         BOOST_TEST(*sym.prefix_find(first, last) == 1 && first == str + 3);
201 
202         first = str; last = str + 3;
203         BOOST_TEST(*sym.prefix_find(first, last) == 1 && first == str + 3);
204 
205         first = str; last = str + 2;
206         BOOST_TEST(!sym.prefix_find(first, last) && first == str);
207     }
208 
209     {
210         // remove bug
211 
212         std::string s;
213         symbols<char, double> vars;
214 
215         vars.add("l1", 12.0);
216         vars.add("l2", 0.0);
217         vars.remove("l2");
218         vars.find("l1");
219         double* d = vars.find("l1");
220         BOOST_TEST(d != 0);
221     }
222 
223     { // test for proto problem with rvalue references (10-11-2011)
224         symbols<char, int> sym;
225         sym += get_str("Joel");
226         sym += get_str("Ruby");
227 
228         BOOST_TEST((test("Joel", sym)));
229         BOOST_TEST((test("Ruby", sym)));
230     }
231 
232     return boost::report_errors();
233 }
234