Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/boost/spirit/home/x3/directive/matches.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ namespace boost { namespace spirit { namespace x3
bool parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
Iterator save = first;
bool const result = this->subject.parse(
first, last, context, rcontext, unused);
if (!result) first = save;
traits::move_to(result, attr);
return true;
}
Expand Down
8 changes: 4 additions & 4 deletions include/boost/spirit/home/x3/directive/repeat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,22 @@ namespace boost { namespace spirit { namespace x3
Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
Iterator local_iterator = first;
typename RepeatCountLimit::type i{};
for (/**/; !repeat_limit.got_min(i); ++i)
{
if (!detail::parse_into_container(
this->subject, local_iterator, last, context, rcontext, attr))
this->subject, first, last, context, rcontext, attr))
return false;
}

first = local_iterator;
Iterator iter = first;
// parse some more up to the maximum specified
for (/**/; !repeat_limit.got_max(i); ++i)
{
if (!detail::parse_into_container(
this->subject, first, last, context, rcontext, attr))
this->subject, iter, last, context, rcontext, attr))
break;
first = iter;
}
return true;
}
Expand Down
3 changes: 2 additions & 1 deletion include/boost/spirit/home/x3/numeric/bool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ namespace boost { namespace spirit { namespace x3
, Context const& context, unused_type, T& attr) const
{
x3::skip_over(first, last, context);
Iterator save = first;
return policies.parse_true(first, last, attr, get_case_compare<encoding>(context))
|| policies.parse_false(first, last, attr, get_case_compare<encoding>(context));
|| policies.parse_false(first = save, last, attr, get_case_compare<encoding>(context));
}

template <typename Iterator, typename Context, typename Attribute>
Expand Down
6 changes: 4 additions & 2 deletions include/boost/spirit/home/x3/operator/alternative.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ namespace boost { namespace spirit { namespace x3
Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, unused_type) const
{
Iterator save = first;
return this->left.parse(first, last, context, rcontext, unused)
|| this->right.parse(first, last, context, rcontext, unused);
|| this->right.parse(first = save, last, context, rcontext, unused);
}

template <typename Iterator, typename Context
Expand All @@ -38,8 +39,9 @@ namespace boost { namespace spirit { namespace x3
Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
Iterator save = first;
return detail::parse_alternative(this->left, first, last, context, rcontext, attr)
|| detail::parse_alternative(this->right, first, last, context, rcontext, attr);
|| detail::parse_alternative(this->right, first = save, last, context, rcontext, attr);
}
};

Expand Down
6 changes: 4 additions & 2 deletions include/boost/spirit/home/x3/operator/detail/alternative.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,9 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attribute, mpl::false_)
{
Iterator save = first;
return detail::parse_into_container(parser.left, first, last, context, rcontext, attribute)
|| detail::parse_into_container(parser.right, first, last, context, rcontext, attribute);
|| detail::parse_into_container(parser.right, first = save, last, context, rcontext, attribute);
}

template <typename Iterator, typename Attribute>
Expand All @@ -231,8 +232,9 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
, Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attribute, mpl::true_)
{
Iterator save = first;
return detail::parse_into_container(alternative_helper<Left>{parser.left}, first, last, context, rcontext, attribute)
|| detail::parse_into_container(alternative_helper<Right>{parser.right}, first, last, context, rcontext, attribute);
|| detail::parse_into_container(alternative_helper<Right>{parser.right}, first = save, last, context, rcontext, attribute);
}

template <typename Iterator, typename Attribute>
Expand Down
6 changes: 0 additions & 6 deletions include/boost/spirit/home/x3/operator/detail/sequence.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,9 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
typename l_pass::type l_attr = l_pass::call(l_part);
typename r_pass::type r_attr = r_pass::call(r_part);

Iterator save = first;
if (parser.left.parse(first, last, context, rcontext, l_attr)
&& parser.right.parse(first, last, context, rcontext, r_attr))
return true;
first = save;
return false;
}

Expand Down Expand Up @@ -289,11 +287,9 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
, Context const& context, RContext& rcontext, Attribute& attr
, traits::container_attribute)
{
Iterator save = first;
if (parse_sequence_container(parser.left, first, last, context, rcontext, attr)
&& parse_sequence_container(parser.right, first, last, context, rcontext, attr))
return true;
first = save;
return false;
}

Expand All @@ -312,11 +308,9 @@ namespace boost { namespace spirit { namespace x3 { namespace detail
Parser const& parser , Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr, mpl::true_ /*should_split*/)
{
Iterator save = first;
if (parser.left.parse( first, last, context, rcontext, attr)
&& parser.right.parse(first, last, context, rcontext, attr))
return true;
first = save;
return false;
}

Expand Down
5 changes: 3 additions & 2 deletions include/boost/spirit/home/x3/operator/kleene.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ namespace boost { namespace spirit { namespace x3
bool parse(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr) const
{
Iterator iter = first;
while (detail::parse_into_container(
this->subject, first, last, context, rcontext, attr))
;
this->subject, iter, last, context, rcontext, attr))
first = iter;
return true;
}
};
Expand Down
23 changes: 20 additions & 3 deletions include/boost/spirit/home/x3/operator/optional.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ namespace boost { namespace spirit { namespace x3
, Context const& context, RContext& rcontext, Attribute& attr
, traits::container_attribute) const
{
detail::parse_into_container(
this->subject, first, last, context, rcontext, attr);
Iterator iter = first;
if (detail::parse_into_container(
this->subject, iter, last, context, rcontext, attr))
first = iter;
return true;
}

Expand All @@ -55,13 +57,28 @@ namespace boost { namespace spirit { namespace x3
// create a local value
value_type val{};

if (this->subject.parse(first, last, context, rcontext, val))
Iterator iter = first;
if (this->subject.parse(iter, last, context, rcontext, val))
{
first = iter;
// assign the parsed value into our attribute
x3::traits::move_to(val, attr);
}
return true;
}

// Attribute is of other type
template <typename Iterator, typename Context
, typename RContext, typename Attribute, typename Category>
bool parse_subject(Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, Attribute& attr
, Category) const
{
Iterator iter = first;
if (this->subject.parse(iter, last, context, rcontext, attr))
first = iter;
return true;
}
};

template <typename Subject>
Expand Down
5 changes: 3 additions & 2 deletions include/boost/spirit/home/x3/operator/plus.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ namespace boost { namespace spirit { namespace x3
this->subject, first, last, context, rcontext, attr))
return false;

Iterator iter = first;
while (detail::parse_into_container(
this->subject, first, last, context, rcontext, attr))
;
this->subject, iter, last, context, rcontext, attr))
first = iter;
return true;
}
};
Expand Down
2 changes: 0 additions & 2 deletions include/boost/spirit/home/x3/operator/sequence.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,9 @@ namespace boost { namespace spirit { namespace x3
Iterator& first, Iterator const& last
, Context const& context, RContext& rcontext, unused_type) const
{
Iterator save = first;
if (this->left.parse(first, last, context, rcontext, unused)
&& this->right.parse(first, last, context, rcontext, unused))
return true;
first = save;
return false;
}

Expand Down
3 changes: 3 additions & 0 deletions test/x3/alternative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <iostream>
#include <vector>
#include "test.hpp"
#include "utils.hpp"

struct di_ignore
{
Expand Down Expand Up @@ -72,6 +73,8 @@ main()
BOOST_TEST((test("roll", lit("rock") | lit("roll"))));
BOOST_TEST((test("rock", lit("rock") | int_)));
BOOST_TEST((test("12345", lit("rock") | int_)));

BOOST_TEST(test("F", sf | lit('F')));
}

{
Expand Down
23 changes: 23 additions & 0 deletions test/x3/bool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,26 @@
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#include "bool.hpp"
#include "utils.hpp"

struct sf_bool_policies : boost::spirit::x3::bool_policies<>
{
template <typename Iterator, typename Attribute, typename CaseCompare>
static bool parse_true(Iterator& first, Iterator const& last, Attribute& attr_, CaseCompare const&)
{
bool r = parse(first, last, sf);
if (r) boost::spirit::x3::traits::move_to(true, attr_);
return r;
}

template <typename Iterator, typename Attribute, typename CaseCompare>
static bool parse_false(Iterator& first, Iterator const& last, Attribute& attr_, CaseCompare const&)
{
bool r = parse(first, last, boost::spirit::x3::lit('F'));
if (r) boost::spirit::x3::traits::move_to(false, attr_);
return r;
}
};

int main()
{
Expand All @@ -19,6 +39,9 @@ int main()
BOOST_TEST(test("true", bool_));
BOOST_TEST(test("false", bool_));
BOOST_TEST(!test("fasle", bool_));

constexpr boost::spirit::x3::bool_parser<bool, boost::spirit::char_encoding::standard, sf_bool_policies> sf_bool{};
BOOST_TEST(test("F", sf_bool));
}

{
Expand Down
2 changes: 1 addition & 1 deletion test/x3/error_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct test_rule_class : x3::annotate_on_success, error_handler_base {};

x3::rule<test_inner_rule_class> const test_inner_rule = "\"bar\"";
x3::rule<test_rule_class> const test_rule;
auto const test_inner_rule_def = x3::lit("bar");
auto const test_inner_rule_def = x3::lit("bar") > x3::eps;
auto const test_rule_def = x3::lit("foo") > test_inner_rule > x3::lit("git");

BOOST_SPIRIT_DEFINE(test_inner_rule, test_rule)
Expand Down
6 changes: 6 additions & 0 deletions test/x3/kleene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ main()
{
using spirit_test::test;
using spirit_test::test_attr;
using spirit_test::test_failure;
using spirit_test::test_partial;
using boost::spirit::x3::char_;
using boost::spirit::x3::alpha;
using boost::spirit::x3::upper;
Expand All @@ -58,6 +60,10 @@ main()
BOOST_TEST(test("", *char_));
BOOST_TEST(test("aaaaaaaa", *alpha));
BOOST_TEST(!test("aaaaaaaa", *upper));

BOOST_TEST(test_partial("F", *sf, 0));
BOOST_TEST(test_partial("sF", +sf, 1));
BOOST_TEST(test_partial("ssF", +sf, 2));
}

{
Expand Down
5 changes: 5 additions & 0 deletions test/x3/list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ main()

BOOST_SPIRIT_ASSERT_CONSTEXPR_CTORS(char_ % ',');

{
BOOST_TEST(test_partial("s,F", sf % ',', 1));
BOOST_TEST(test_partial("s,s,F", sf % ',', 3));
}

{
BOOST_TEST(test("a,b,c,d,e,f,g,h", char_ % ','));
BOOST_TEST(test("a,b,c,d,e,f,g,h,", char_ % ',', false));
Expand Down
5 changes: 5 additions & 0 deletions test/x3/matches.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include "test.hpp"
#include "utils.hpp"

int
main()
{
using spirit_test::test;
using spirit_test::test_attr;
using spirit_test::test_failure;
using spirit_test::test_partial;
using boost::spirit::x3::matches;
using boost::spirit::x3::char_;

Expand All @@ -23,6 +26,8 @@ main()
BOOST_TEST(test("x", matches[char_]));
bool result = false;
BOOST_TEST(test_attr("x", matches[char_], result) && result);

BOOST_TEST(test_partial("F", matches[sf], 0));
}

{
Expand Down
4 changes: 4 additions & 0 deletions test/x3/optional.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ main()

using spirit_test::test;
using spirit_test::test_attr;
using spirit_test::test_failure;
using spirit_test::test_partial;

using boost::spirit::x3::int_;
using boost::spirit::x3::omit;
Expand All @@ -56,6 +58,8 @@ main()
BOOST_TEST((test("1234", -int_)));
BOOST_TEST((test("abcd", -int_, false)));

BOOST_TEST(test_partial("F", -sf, 0));

boost::optional<int> n;
BOOST_TEST(test_attr("", -int_, n))
&& BOOST_TEST(!n);
Expand Down
5 changes: 5 additions & 0 deletions test/x3/plus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ main()
{
using spirit_test::test;
using spirit_test::test_attr;
using spirit_test::test_failure;
using spirit_test::test_partial;
using boost::spirit::x3::char_;
using boost::spirit::x3::alpha;
using boost::spirit::x3::upper;
Expand All @@ -63,6 +65,9 @@ main()
BOOST_TEST(!test("", +char_));
BOOST_TEST(test("aaaaaaaa", +alpha));
BOOST_TEST(!test("aaaaaaaa", +upper));

BOOST_TEST(test_partial("sF", +sf, 1));
BOOST_TEST(test_partial("ssF", +sf, 2));
}

{
Expand Down
11 changes: 11 additions & 0 deletions test/x3/repeat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ main()
{
using spirit_test::test_attr;
using spirit_test::test;
using spirit_test::test_failure;
using spirit_test::test_partial;

using namespace boost::spirit::x3::ascii;
using boost::spirit::x3::repeat;
Expand Down Expand Up @@ -51,6 +53,15 @@ main()
BOOST_TEST(test("aaaaa", repeat(3, inf)[char_]));
BOOST_TEST(test("aaaaaa", repeat(3, inf)[char_]));
BOOST_TEST(!test("aa", repeat(3, inf)[char_]));

BOOST_TEST(test_partial("sF", repeat(1)[sf], 1));
BOOST_TEST(test_partial("sF", repeat(1, inf)[sf], 1));
BOOST_TEST(test_partial("ssF", repeat(2)[sf], 2));
BOOST_TEST(test_partial("ssF", repeat(1, inf)[sf], 2));
BOOST_TEST(test_partial("ssF", repeat(2, inf)[sf], 2));
BOOST_TEST(test_partial("sssF", repeat(3)[sf], 3));
BOOST_TEST(test_partial("sssF", repeat(1, inf)[sf], 3));
BOOST_TEST(test_partial("sssF", repeat(2, inf)[sf], 3));
}
{
std::string s;
Expand Down
Loading