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