• 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 
8 #include <boost/detail/lightweight_test.hpp>
9 #include <boost/spirit/include/qi_operator.hpp>
10 #include <boost/spirit/include/qi_char.hpp>
11 #include <boost/spirit/include/qi_string.hpp>
12 #include <boost/spirit/include/qi_numeric.hpp>
13 #include <boost/spirit/include/qi_auxiliary.hpp>
14 #include <boost/spirit/include/qi_directive.hpp>
15 #include <boost/spirit/include/qi_nonterminal.hpp>
16 #include <boost/spirit/include/qi_action.hpp>
17 #include <boost/spirit/include/phoenix_core.hpp>
18 #include <boost/spirit/include/phoenix_operator.hpp>
19 #include <boost/fusion/include/std_pair.hpp>
20 
21 #include <string>
22 #include <cstring>
23 #include <iostream>
24 #include "test.hpp"
25 
26 int
main()27 main()
28 {
29     using spirit_test::test_attr;
30     using spirit_test::test;
31 
32     using namespace boost::spirit::ascii;
33     using namespace boost::spirit::qi::labels;
34     using boost::spirit::qi::locals;
35     using boost::spirit::qi::rule;
36     using boost::spirit::qi::int_;
37     using boost::spirit::qi::uint_;
38     using boost::spirit::qi::fail;
39     using boost::spirit::qi::on_error;
40     using boost::spirit::qi::debug;
41     using boost::spirit::qi::lit;
42 
43     namespace phx = boost::phoenix;
44 
45     { // test unassigned rule
46 
47         rule<char const*> a;
48         BOOST_TEST(!test("x", a));
49     }
50 
51     { // alias tests
52 
53         rule<char const*> a, b, c, d, start;
54 
55         a = 'a';
56         b = 'b';
57         c = 'c';
58         d = start.alias(); // d will always track start
59 
60         start = *(a | b | c);
61         BOOST_TEST(test("abcabcacb", d));
62 
63         start = (a | b) >> (start | b);
64         BOOST_TEST(test("aaaabababaaabbb", d));
65     }
66 
67     { // copy tests
68 
69         rule<char const*> a, b, c, start;
70 
71         a = 'a';
72         b = 'b';
73         c = 'c';
74 
75         // The FF is the dynamic equivalent of start = *(a | b | c);
76         start = a;
77         start = start.copy() | b;
78         start = start.copy() | c;
79         start = *(start.copy());
80 
81         BOOST_TEST(test("abcabcacb", start));
82 
83         // The FF is the dynamic equivalent of start = (a | b) >> (start | b);
84         start = b;
85         start = a | start.copy();
86         start = start.copy() >> (start | b);
87 
88         BOOST_TEST(test("aaaabababaaabbb", start));
89         BOOST_TEST(test("aaaabababaaabba", start, false));
90     }
91 
92     { // context tests
93 
94         char ch;
95         rule<char const*, char()> a;
96         a = alpha[_val = _1];
97 
98         BOOST_TEST(test("x", a[phx::ref(ch) = _1]));
99         BOOST_TEST(ch == 'x');
100 
101         BOOST_TEST(test_attr("z", a, ch)); // attribute is given.
102         BOOST_TEST(ch == 'z');
103     }
104 
105     { // auto rules tests
106 
107         char ch = '\0';
108         rule<char const*, char()> a;
109         a %= alpha;
110 
111         BOOST_TEST(test("x", a[phx::ref(ch) = _1]));
112         BOOST_TEST(ch == 'x');
113         ch = '\0';
114         BOOST_TEST(test_attr("z", a, ch)); // attribute is given.
115         BOOST_TEST(ch == 'z');
116 
117         a = alpha;    // test deduced auto rule behavior
118         ch = '\0';
119         BOOST_TEST(test("x", a[phx::ref(ch) = _1]));
120         BOOST_TEST(ch == 'x');
121         ch = '\0';
122         BOOST_TEST(test_attr("z", a, ch)); // attribute is given.
123         BOOST_TEST(ch == 'z');
124     }
125 
126     { // auto rules tests: allow stl containers as attributes to
127       // sequences (in cases where attributes of the elements
128       // are convertible to the value_type of the container or if
129       // the element itself is an stl container with value_type
130       // that is convertible to the value_type of the attribute).
131 
132         std::string s;
133         rule<char const*, std::string()> r;
134         r %= char_ >> *(',' >> char_);
135 
136         BOOST_TEST(test("a,b,c,d,e,f", r[phx::ref(s) = _1]));
137         BOOST_TEST(s == "abcdef");
138 
139         r = char_ >> *(',' >> char_);    // test deduced auto rule behavior
140         s.clear();
141         BOOST_TEST(test("a,b,c,d,e,f", r[phx::ref(s) = _1]));
142         BOOST_TEST(s == "abcdef");
143 
144         r %= char_ >> char_ >> char_ >> char_ >> char_ >> char_;
145         s.clear();
146         BOOST_TEST(test("abcdef", r[phx::ref(s) = _1]));
147         BOOST_TEST(s == "abcdef");
148 
149         r = char_ >> char_ >> char_ >> char_ >> char_ >> char_;
150         s.clear();
151         BOOST_TEST(test("abcdef", r[phx::ref(s) = _1]));
152         BOOST_TEST(s == "abcdef");
153     }
154 
155     return boost::report_errors();
156 }
157 
158