• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2001-2015 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/home/x3.hpp>
10 
11 #include <string>
12 #include <cstring>
13 #include <iostream>
14 #include "test.hpp"
15 
16 int
main()17 main()
18 {
19     using spirit_test::test_attr;
20     using spirit_test::test;
21 
22     using namespace boost::spirit::x3::ascii;
23     using boost::spirit::x3::rule;
24     using boost::spirit::x3::lit;
25     using boost::spirit::x3::int_;
26     using boost::spirit::x3::unused_type;
27     using boost::spirit::x3::phrase_parse;
28     using boost::spirit::x3::skip_flag;
29     using boost::spirit::x3::traits::has_attribute;
30 
31 #ifdef BOOST_SPIRIT_X3_NO_RTTI
32     BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(rule<class r>{});
33 #endif
34     BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(rule<class r>{"r"});
35     BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(rule<class r>{"r"} = 'x');
36 
37     // check attribute advertising
38     static_assert( has_attribute<rule<class r, int>, /*Context=*/unused_type>::value, "");
39     static_assert(!has_attribute<rule<class r     >, /*Context=*/unused_type>::value, "");
40     static_assert( has_attribute<decltype(rule<class r, int>{} = int_), /*Context=*/unused_type>::value, "");
41     static_assert(!has_attribute<decltype(rule<class r     >{} = int_), /*Context=*/unused_type>::value, "");
42 
43 
44     { // basic tests
45 
46         auto a = lit('a');
47         auto b = lit('b');
48         auto c = lit('c');
49         rule<class r> r;
50 
51         {
52             auto start =
53                 r = *(a | b | c);
54 
55             BOOST_TEST(test("abcabcacb", start));
56         }
57 
58         {
59             auto start =
60                 r = (a | b) >> (r | b);
61 
62             BOOST_TEST(test("aaaabababaaabbb", start));
63             BOOST_TEST(test("aaaabababaaabba", start, false));
64 
65             // ignore the skipper!
66             BOOST_TEST(test("aaaabababaaabba", start, space, false));
67         }
68     }
69 
70     { // basic tests w/ skipper
71 
72         auto a = lit('a');
73         auto b = lit('b');
74         auto c = lit('c');
75         rule<class r> r;
76 
77         {
78             auto start =
79                 r = *(a | b | c);
80 
81             BOOST_TEST(test(" a b c a b c a c b ", start, space));
82         }
83 
84         {
85             auto start =
86                 r = (a | b) >> (r | b);
87 
88             BOOST_TEST(test(" a a a a b a b a b a a a b b b ", start, space));
89             BOOST_TEST(test(" a a a a b a b a b a a a b b a ", start, space, false));
90         }
91     }
92 
93     { // basic tests w/ skipper but no final post-skip
94 
95         auto a = rule<class a>()
96             = lit('a');
97 
98         auto b = rule<class b>()
99             = lit('b');
100 
101         auto c = rule<class c>()
102             = lit('c');
103 
104         {
105             auto start = rule<class start>() = *(a | b) >> c;
106 
107             char const *s1 = " a b a a b b a c ... "
108               , *const e1 = s1 + std::strlen(s1);
109             BOOST_TEST(phrase_parse(s1, e1, start, space, skip_flag::dont_post_skip)
110               && s1 == e1 - 5);
111 
112         }
113 
114         {
115             rule<class start> start;
116 
117             auto p =
118                 start = (a | b) >> (start | c);
119             {
120                 char const *s1 = " a a a a b a b a b a a a b b b c "
121                   , *const e1 = s1 + std::strlen(s1);
122                 BOOST_TEST(phrase_parse(s1, e1, p, space, skip_flag::post_skip)
123                   && s1 == e1);
124             }
125             {
126                 char const *s1 = " a a a a b a b a b a a a b b b c "
127                   , *const e1 = s1 + std::strlen(s1);
128                 BOOST_TEST(phrase_parse(s1, e1, p, space, skip_flag::dont_post_skip)
129                   && s1 == e1 - 1);
130             }
131         }
132     }
133 
134     return boost::report_errors();
135 }
136