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 { // synth attribute value-init
46
47 std::string s;
48 rule<char const*, char()> r;
49 r = alpha[_val += _1];
50 BOOST_TEST(test_attr("abcdef", +r, s));
51 BOOST_TEST(s == "abcdef");
52 }
53
54 { // auto rules aliasing tests
55
56 char ch = '\0';
57 rule<char const*, char()> a, b;
58 a %= b;
59 b %= alpha;
60
61 BOOST_TEST(test("x", a[phx::ref(ch) = _1]));
62 BOOST_TEST(ch == 'x');
63 ch = '\0';
64 BOOST_TEST(test_attr("z", a, ch)); // attribute is given.
65 BOOST_TEST(ch == 'z');
66
67 a = b; // test deduced auto rule behavior
68 b = alpha;
69
70 ch = '\0';
71 BOOST_TEST(test("x", a[phx::ref(ch) = _1]));
72 BOOST_TEST(ch == 'x');
73 ch = '\0';
74 BOOST_TEST(test_attr("z", a, ch)); // attribute is given.
75 BOOST_TEST(ch == 'z');
76 }
77
78 { // context (w/arg) tests
79
80 char ch;
81 rule<char const*, char(int)> a; // 1 arg
82 a = alpha[_val = _1 + _r1];
83
84 BOOST_TEST(test("x", a(phx::val(1))[phx::ref(ch) = _1]));
85 BOOST_TEST(ch == 'x' + 1);
86
87 BOOST_TEST(test_attr("a", a(1), ch)); // allow scalars as rule args too.
88 BOOST_TEST(ch == 'a' + 1);
89
90 rule<char const*, char(int, int)> b; // 2 args
91 b = alpha[_val = _1 + _r1 + _r2];
92 BOOST_TEST(test_attr("a", b(1, 2), ch));
93 BOOST_TEST(ch == 'a' + 1 + 2);
94 }
95
96 { // context (w/ reference arg) tests
97
98 char ch;
99 rule<char const*, void(char&)> a; // 1 arg (reference)
100 a = alpha[_r1 = _1];
101
102 BOOST_TEST(test("x", a(phx::ref(ch))));
103 BOOST_TEST(ch == 'x');
104 }
105
106 { // context (w/locals) tests
107
108 rule<char const*, locals<char> > a; // 1 local
109 a = alpha[_a = _1] >> char_(_a);
110 BOOST_TEST(test("aa", a));
111 BOOST_TEST(!test("ax", a));
112 }
113
114 { // context (w/args and locals) tests
115
116 rule<char const*, void(int), locals<char> > a; // 1 arg + 1 local
117 a = alpha[_a = _1 + _r1] >> char_(_a);
118 BOOST_TEST(test("ab", a(phx::val(1))));
119 BOOST_TEST(test("xy", a(phx::val(1))));
120 BOOST_TEST(!test("ax", a(phx::val(1))));
121 }
122
123 { // void() has unused type (void == unused_type)
124
125 std::pair<int, char> attr;
126 rule<char const*, void()> r;
127 r = char_;
128 BOOST_TEST(test_attr("123ax", int_ >> char_ >> r, attr));
129 BOOST_TEST(attr.first == 123);
130 BOOST_TEST(attr.second == 'a');
131 }
132
133 { // bug: test that injected attributes are ok
134
135 rule<char const*, char(int) > r;
136
137 // problem code:
138 r = char_(_r1)[_val = _1];
139 }
140
141 return boost::report_errors();
142 }
143
144