• 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     { // 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