2
0
mirror of https://github.com/boostorg/spirit.git synced 2026-01-19 04:42:11 +00:00

Merging Spirit x3 into devel

This commit is contained in:
Joel de Guzman
2014-03-18 11:06:19 +08:00
135 changed files with 16689 additions and 0 deletions

Binary file not shown.

281
example/x3/calc4.cpp Normal file
View File

@@ -0,0 +1,281 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
///////////////////////////////////////////////////////////////////////////////
//
// A Calculator example demonstrating generation of AST. The AST,
// once created, is traversed, 1) To print its contents and
// 2) To evaluate the result.
//
// [ JDG April 28, 2008 ] For BoostCon 2008
// [ JDG February 18, 2011 ] Pure attributes. No semantic actions.
// [ JDG January 9, 2013 ] Spirit X3
//
///////////////////////////////////////////////////////////////////////////////
#if defined(_MSC_VER)
# pragma warning(disable: 4345)
#endif
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <iostream>
#include <string>
#include <list>
#include <numeric>
namespace client { namespace ast
{
///////////////////////////////////////////////////////////////////////////
// The AST
///////////////////////////////////////////////////////////////////////////
struct nil {};
struct signed_;
struct program;
typedef boost::variant<
nil
, unsigned int
, boost::recursive_wrapper<signed_>
, boost::recursive_wrapper<program>
>
operand;
struct signed_
{
char sign;
operand operand_;
};
struct operation
{
char operator_;
operand operand_;
};
struct program
{
operand first;
std::list<operation> rest;
};
}}
BOOST_FUSION_ADAPT_STRUCT(
client::ast::signed_,
(char, sign)
(client::ast::operand, operand_)
)
BOOST_FUSION_ADAPT_STRUCT(
client::ast::operation,
(char, operator_)
(client::ast::operand, operand_)
)
BOOST_FUSION_ADAPT_STRUCT(
client::ast::program,
(client::ast::operand, first)
(std::list<client::ast::operation>, rest)
)
namespace client { namespace ast
{
///////////////////////////////////////////////////////////////////////////
// The AST Printer
///////////////////////////////////////////////////////////////////////////
struct printer
{
typedef void result_type;
void operator()(nil) const {}
void operator()(unsigned int n) const { std::cout << n; }
void operator()(operation const& x) const
{
boost::apply_visitor(*this, x.operand_);
switch (x.operator_)
{
case '+': std::cout << " add"; break;
case '-': std::cout << " subt"; break;
case '*': std::cout << " mult"; break;
case '/': std::cout << " div"; break;
}
}
void operator()(signed_ const& x) const
{
boost::apply_visitor(*this, x.operand_);
switch (x.sign)
{
case '-': std::cout << " neg"; break;
case '+': std::cout << " pos"; break;
}
}
void operator()(program const& x) const
{
boost::apply_visitor(*this, x.first);
for (operation const& oper: x.rest)
{
std::cout << ' ';
(*this)(oper);
}
}
};
///////////////////////////////////////////////////////////////////////////
// The AST evaluator
///////////////////////////////////////////////////////////////////////////
struct eval
{
typedef int result_type;
int operator()(nil) const { BOOST_ASSERT(0); return 0; }
int operator()(unsigned int n) const { return n; }
int operator()(int lhs, operation const& x) const
{
int rhs = boost::apply_visitor(*this, x.operand_);
switch (x.operator_)
{
case '+': return lhs + rhs;
case '-': return lhs - rhs;
case '*': return lhs * rhs;
case '/': return lhs / rhs;
}
BOOST_ASSERT(0);
return 0;
}
int operator()(signed_ const& x) const
{
int rhs = boost::apply_visitor(*this, x.operand_);
switch (x.sign)
{
case '-': return -rhs;
case '+': return +rhs;
}
BOOST_ASSERT(0);
return 0;
}
int operator()(program const& x) const
{
return std::accumulate( x.rest.begin(), x.rest.end()
, boost::apply_visitor(*this, x.first)
, *this);
}
};
}}
namespace client
{
namespace x3 = boost::spirit::x3;
///////////////////////////////////////////////////////////////////////////////
// The calculator grammar
///////////////////////////////////////////////////////////////////////////////
namespace calculator_grammar
{
using x3::uint_;
using x3::char_;
x3::rule<class expression, ast::program> const expression("expression");
x3::rule<class term, ast::program> const term("term");
x3::rule<class factor, ast::operand> const factor("factor");
auto const expression_def =
term
>> *( (char_('+') >> term)
| (char_('-') >> term)
)
;
auto const term_def =
factor
>> *( (char_('*') >> factor)
| (char_('/') >> factor)
)
;
auto const factor_def =
uint_
| '(' >> expression >> ')'
| (char_('-') >> factor)
| (char_('+') >> factor)
;
auto const calculator = x3::grammar(
"calculator"
, expression = expression_def
, term = term_def
, factor = factor_def
);
}
using calculator_grammar::calculator;
}
///////////////////////////////////////////////////////////////////////////////
// Main program
///////////////////////////////////////////////////////////////////////////////
int
main()
{
std::cout << "/////////////////////////////////////////////////////////\n\n";
std::cout << "Expression parser...\n\n";
std::cout << "/////////////////////////////////////////////////////////\n\n";
std::cout << "Type an expression...or [q or Q] to quit\n\n";
typedef std::string::const_iterator iterator_type;
typedef client::ast::program ast_program;
typedef client::ast::printer ast_print;
typedef client::ast::eval ast_eval;
std::string str;
while (std::getline(std::cin, str))
{
if (str.empty() || str[0] == 'q' || str[0] == 'Q')
break;
auto& calc = client::calculator; // Our grammar
ast_program program; // Our program (AST)
ast_print print; // Prints the program
ast_eval eval; // Evaluates the program
iterator_type iter = str.begin();
iterator_type end = str.end();
boost::spirit::x3::ascii::space_type space;
bool r = phrase_parse(iter, end, calc, space, program);
if (r && iter == end)
{
std::cout << "-------------------------\n";
std::cout << "Parsing succeeded\n";
print(program);
std::cout << "\nResult: " << eval(program) << std::endl;
std::cout << "-------------------------\n";
}
else
{
std::string rest(iter, end);
std::cout << "-------------------------\n";
std::cout << "Parsing failed\n";
std::cout << "stopped at: \"" << rest << "\"\n";
std::cout << "-------------------------\n";
}
}
std::cout << "Bye... :-) \n\n";
return 0;
}

275
example/x3/calc4b.cpp Normal file
View File

@@ -0,0 +1,275 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
///////////////////////////////////////////////////////////////////////////////
//
// A Calculator example demonstrating generation of AST. The AST,
// once created, is traversed, 1) To print its contents and
// 2) To evaluate the result.
//
// [ JDG April 28, 2008 ] For BoostCon 2008
// [ JDG February 18, 2011 ] Pure attributes. No semantic actions.
// [ JDG January 9, 2013 ] Spirit X3
//
///////////////////////////////////////////////////////////////////////////////
#if defined(_MSC_VER)
# pragma warning(disable: 4345)
#endif
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <iostream>
#include <string>
#include <list>
#include <numeric>
namespace client { namespace ast
{
///////////////////////////////////////////////////////////////////////////
// The AST
///////////////////////////////////////////////////////////////////////////
struct nil {};
struct signed_;
struct program;
typedef boost::variant<
nil
, unsigned int
, boost::recursive_wrapper<signed_>
, boost::recursive_wrapper<program>
>
operand;
struct signed_
{
char sign;
operand operand_;
};
struct operation
{
char operator_;
operand operand_;
};
struct program
{
operand first;
std::list<operation> rest;
};
}}
BOOST_FUSION_ADAPT_STRUCT(
client::ast::signed_,
(char, sign)
(client::ast::operand, operand_)
)
BOOST_FUSION_ADAPT_STRUCT(
client::ast::operation,
(char, operator_)
(client::ast::operand, operand_)
)
BOOST_FUSION_ADAPT_STRUCT(
client::ast::program,
(client::ast::operand, first)
(std::list<client::ast::operation>, rest)
)
namespace client { namespace ast
{
///////////////////////////////////////////////////////////////////////////
// The AST Printer
///////////////////////////////////////////////////////////////////////////
struct printer
{
typedef void result_type;
void operator()(nil) const {}
void operator()(unsigned int n) const { std::cout << n; }
void operator()(operation const& x) const
{
boost::apply_visitor(*this, x.operand_);
switch (x.operator_)
{
case '+': std::cout << " add"; break;
case '-': std::cout << " subt"; break;
case '*': std::cout << " mult"; break;
case '/': std::cout << " div"; break;
}
}
void operator()(signed_ const& x) const
{
boost::apply_visitor(*this, x.operand_);
switch (x.sign)
{
case '-': std::cout << " neg"; break;
case '+': std::cout << " pos"; break;
}
}
void operator()(program const& x) const
{
boost::apply_visitor(*this, x.first);
for (operation const& oper: x.rest)
{
std::cout << ' ';
(*this)(oper);
}
}
};
///////////////////////////////////////////////////////////////////////////
// The AST evaluator
///////////////////////////////////////////////////////////////////////////
struct eval
{
typedef int result_type;
int operator()(nil) const { BOOST_ASSERT(0); return 0; }
int operator()(unsigned int n) const { return n; }
int operator()(int lhs, operation const& x) const
{
int rhs = boost::apply_visitor(*this, x.operand_);
switch (x.operator_)
{
case '+': return lhs + rhs;
case '-': return lhs - rhs;
case '*': return lhs * rhs;
case '/': return lhs / rhs;
}
BOOST_ASSERT(0);
return 0;
}
int operator()(signed_ const& x) const
{
int rhs = boost::apply_visitor(*this, x.operand_);
switch (x.sign)
{
case '-': return -rhs;
case '+': return +rhs;
}
BOOST_ASSERT(0);
return 0;
}
int operator()(program const& x) const
{
return std::accumulate( x.rest.begin(), x.rest.end()
, boost::apply_visitor(*this, x.first)
, *this);
}
};
}}
namespace client
{
namespace x3 = boost::spirit::x3;
///////////////////////////////////////////////////////////////////////////////
// The calculator grammar
///////////////////////////////////////////////////////////////////////////////
namespace calculator_grammar
{
using x3::uint_;
using x3::char_;
x3::rule<class expression, ast::program> const expression("expression");
x3::rule<class term, ast::program> const term("term");
x3::rule<class factor, ast::operand> const factor("factor");
auto const calculator = x3::grammar("calculator",
expression =
term
>> *( (char_('+') >> term)
| (char_('-') >> term)
)
,
term =
factor
>> *( (char_('*') >> factor)
| (char_('/') >> factor)
)
,
factor =
uint_
| '(' >> expression >> ')'
| (char_('-') >> factor)
| (char_('+') >> factor)
);
}
using calculator_grammar::calculator;
}
///////////////////////////////////////////////////////////////////////////////
// Main program
///////////////////////////////////////////////////////////////////////////////
int
main()
{
std::cout << "/////////////////////////////////////////////////////////\n\n";
std::cout << "Expression parser...\n\n";
std::cout << "/////////////////////////////////////////////////////////\n\n";
std::cout << "Type an expression...or [q or Q] to quit\n\n";
typedef std::string::const_iterator iterator_type;
typedef client::ast::program ast_program;
typedef client::ast::printer ast_print;
typedef client::ast::eval ast_eval;
std::string str;
while (std::getline(std::cin, str))
{
if (str.empty() || str[0] == 'q' || str[0] == 'Q')
break;
auto& calc = client::calculator; // Our grammar
ast_program program; // Our program (AST)
ast_print print; // Prints the program
ast_eval eval; // Evaluates the program
iterator_type iter = str.begin();
iterator_type end = str.end();
boost::spirit::x3::ascii::space_type space;
bool r = phrase_parse(iter, end, calc, space, program);
if (r && iter == end)
{
std::cout << "-------------------------\n";
std::cout << "Parsing succeeded\n";
print(program);
std::cout << "\nResult: " << eval(program) << std::endl;
std::cout << "-------------------------\n";
}
else
{
std::string rest(iter, end);
std::cout << "-------------------------\n";
std::cout << "Parsing failed\n";
std::cout << "stopped at: \"" << rest << "\"\n";
std::cout << "-------------------------\n";
}
}
std::cout << "Bye... :-) \n\n";
return 0;
}

View File

@@ -0,0 +1,27 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_MARCH_04_2007_0852PM)
#define BOOST_SPIRIT_X3_MARCH_04_2007_0852PM
#if defined(_MSC_VER)
#pragma once
#endif
//~ #include <boost/spirit/home/x3/action.hpp>
//~ #include <boost/spirit/home/x3/auto.hpp>
#include <boost/spirit/home/x3/auxiliary.hpp>
#include <boost/spirit/home/x3/char.hpp>
//~ #include <boost/spirit/home/x3/binary.hpp>
#include <boost/spirit/home/x3/directive.hpp>
#include <boost/spirit/home/x3/nonterminal.hpp>
#include <boost/spirit/home/x3/numeric.hpp>
#include <boost/spirit/home/x3/operator.hpp>
#include <boost/spirit/home/x3/core.hpp>
#include <boost/spirit/home/x3/string.hpp>
//~ #include <boost/spirit/home/x3/stream.hpp>
#endif

View File

@@ -0,0 +1,24 @@
/*=============================================================================
Copyright (c) 2001-2012 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_AUXILIARY_FEBRUARY_03_2007_0355PM)
#define BOOST_SPIRIT_X3_AUXILIARY_FEBRUARY_03_2007_0355PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/auxiliary/eps.hpp>
#include <boost/spirit/home/x3/auxiliary/guard.hpp>
#include <boost/spirit/home/x3/auxiliary/action.hpp>
//~ #include <boost/spirit/home/x3/auxiliary/lazy.hpp>
#include <boost/spirit/home/x3/auxiliary/eol.hpp>
#include <boost/spirit/home/x3/auxiliary/eoi.hpp>
#include <boost/spirit/home/x3/auxiliary/attr.hpp>
//~ #include <boost/spirit/home/x3/auxiliary/attr_cast.hpp>
#endif

View File

@@ -0,0 +1,74 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_ACTION_JANUARY_07_2007_1128AM)
#define SPIRIT_ACTION_JANUARY_07_2007_1128AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/make_attribute.hpp>
#include <boost/spirit/home/x3/nonterminal/detail/transform_attribute.hpp>
namespace boost { namespace spirit { namespace x3
{
struct rule_context_tag;
template <typename Subject, typename Action>
struct action : unary_parser<Subject, action<Subject, Action>>
{
typedef unary_parser<Subject, action<Subject, Action>> base_type;
static bool const is_pass_through_unary = true;
static bool const has_action = true;
action(Subject const& subject, Action f)
: base_type(subject), f(f) {}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
Iterator save = first;
if (this->subject.parse(first, last, context, attr))
{
// call the function, passing the enclosing rule's context
// and the subject's attribute.
f(context, attr);
return true;
// reset iterators if semantic action failed the match
// retrospectively
first = save;
}
return false;
}
template <typename Iterator, typename Context>
bool parse(Iterator& first, Iterator const& last
, Context const& context, unused_type) const
{
typedef typename
traits::attribute_of<action<Subject, Action>, Context>::type
attribute_type;
typedef traits::make_attribute<attribute_type, unused_type> make_attribute;
typedef traits::transform_attribute<
typename make_attribute::type, attribute_type, parser_id>
transform;
// synthesize the attribute since one is not supplied
typename make_attribute::type made_attr = make_attribute::call(unused_type());
typename transform::type attr = transform::pre(made_attr);
return parse(first, last, context, attr);
}
Action f;
};
}}}
#endif

View File

@@ -0,0 +1,133 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2013 Agustin Berge
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#ifndef BOOST_SPIRIT_X3_ATTR_JUL_23_2008_0956AM
#define BOOST_SPIRIT_X3_ATTR_JUL_23_2008_0956AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <algorithm>
#include <cstddef>
#include <string>
#include <utility>
namespace boost { namespace spirit { namespace x3
{
template <typename Value>
struct attr_parser : parser<attr_parser<Value>>
{
typedef Value attribute_type;
static bool const has_attribute =
!is_same<unused_type, attribute_type>::value;
static bool const handles_container =
traits::is_container<attribute_type>::value;
attr_parser(Value const& value)
: value_(value) {}
attr_parser(Value&& value)
: value_(std::move(value)) {}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Attribute& attr_) const
{
// $$$ Change to copy_to once we have it $$$
traits::move_to(value_, attr_);
return true;
}
Value value_;
private:
// silence MSVC warning C4512: assignment operator could not be generated
attr_parser& operator= (attr_parser const&);
};
template <typename Value, std::size_t N>
struct attr_parser<Value[N]> : parser<attr_parser<Value[N]>>
{
typedef Value attribute_type[N];
static bool const has_attribute =
!is_same<unused_type, attribute_type>::value;
static bool const handles_container = true;
attr_parser(Value const (&value)[N])
{
std::copy(value + 0, value + N, value_ + 0);
}
attr_parser(Value (&&value)[N])
{
std::move(value + 0, value + N, value_ + 0);
}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Attribute& attr_) const
{
// $$$ Change to copy_to once we have it $$$
traits::move_to(value_ + 0, value_ + N, attr_);
return true;
}
Value value_[N];
private:
// silence MSVC warning C4512: assignment operator could not be generated
attr_parser& operator= (attr_parser const&);
};
template <typename Value>
struct get_info<attr_parser<Value>>
{
typedef std::string result_type;
std::string operator()(attr_parser<Value> const& /*p*/) const
{
return "attr";
}
};
struct attr_gen
{
template <typename Value>
attr_parser<typename remove_cv<
typename remove_reference<Value>::type>::type>
operator()(Value&& value) const
{
return {std::forward<Value>(value)};
}
template <typename Value, std::size_t N>
attr_parser<typename remove_cv<Value>::type[N]>
operator()(Value (&value)[N]) const
{
return {value};
}
template <typename Value, std::size_t N>
attr_parser<typename remove_cv<Value>::type[N]>
operator()(Value (&&value)[N]) const
{
return {value};
}
};
attr_gen const attr = attr_gen();
}}}
#endif

View File

@@ -0,0 +1,45 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_EOI_MARCH_23_2007_0454PM)
#define BOOST_SPIRIT_X3_EOI_MARCH_23_2007_0454PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
namespace boost { namespace spirit { namespace x3
{
struct eoi_parser : parser<eoi_parser>
{
typedef unused_type attribute_type;
static bool const has_attribute = false;
template <typename Iterator, typename Context, typename Attribute>
bool parse( Iterator& first, Iterator const& last
, Context const& context, Attribute& /*attr*/) const
{
x3::skip_over(first, last, context);
return first == last;
}
};
template<>
struct get_info<eoi_parser>
{
typedef std::string result_type;
result_type operator()(eoi_parser const &) const { return "eoi"; }
};
eoi_parser const eoi = eoi_parser();
}}}
#endif

View File

@@ -0,0 +1,59 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_EOL_MARCH_23_2007_0454PM)
#define BOOST_SPIRIT_X3_EOL_MARCH_23_2007_0454PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
namespace boost { namespace spirit { namespace x3
{
struct eol_parser : parser<eol_parser>
{
typedef unused_type attribute_type;
static bool const has_attribute = false;
template <typename Iterator, typename Context, typename Attribute>
bool parse( Iterator& first, Iterator const& last
, Context const& context, Attribute& /*attr*/) const
{
x3::skip_over(first, last, context);
Iterator iter = first;
bool matched = false;
if (iter != last && *iter == '\r') // CR
{
matched = true;
++iter;
}
if (iter != last && *iter == '\n') // LF
{
matched = true;
++iter;
}
if (matched) first = iter;
return matched;
}
};
template<>
struct get_info<eol_parser>
{
typedef std::string result_type;
result_type operator()(eol_parser const &) const { return "eol"; }
};
eol_parser const eol = eol_parser();
}}}
#endif

View File

@@ -0,0 +1,91 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_EPS_MARCH_23_2007_0454PM)
#define BOOST_SPIRIT_X3_EPS_MARCH_23_2007_0454PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
namespace boost { namespace spirit { namespace x3
{
struct rule_context_tag;
struct semantic_predicate : parser<semantic_predicate>
{
typedef unused_type attribute_type;
static bool const has_attribute = false;
semantic_predicate(bool predicate)
: predicate(predicate) {}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& /*attr*/) const
{
x3::skip_over(first, last, context);
return predicate;
}
bool predicate;
};
template <typename F>
struct lazy_semantic_predicate : parser<lazy_semantic_predicate<F>>
{
typedef unused_type attribute_type;
static bool const has_attribute = false;
lazy_semantic_predicate(F f)
: f(f) {}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
x3::skip_over(first, last, context);
return f(x3::get<rule_context_tag>(context));
}
F f;
};
struct eps_parser : parser<eps_parser>
{
typedef unused_type attribute_type;
static bool const has_attribute = false;
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& /*attr*/) const
{
x3::skip_over(first, last, context);
return true;
}
semantic_predicate
operator()(bool predicate) const
{
return semantic_predicate(predicate);
}
template <typename F>
lazy_semantic_predicate<F>
operator()(F f) const
{
return lazy_semantic_predicate<F>(f);
}
};
eps_parser const eps = eps_parser();
}}}
#endif

View File

@@ -0,0 +1,72 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_GUARD_FERBRUARY_02_2013_0649PM)
#define BOOST_SPIRIT_X3_GUARD_FERBRUARY_02_2013_0649PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/directive/expect.hpp>
namespace boost { namespace spirit { namespace x3
{
enum error_handler_result
{
fail
, retry
, accept
, rethrow
};
template <typename Subject, typename Handler>
struct guard : unary_parser<Subject, guard<Subject, Handler>>
{
typedef unary_parser<Subject, guard<Subject, Handler>> base_type;
static bool const is_pass_through_unary = true;
guard(Subject const& subject, Handler handler)
: base_type(subject), handler(handler) {}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
for (;;)
{
try
{
Iterator i = first;
bool r = this->subject.parse(i, last, context, attr);
if (r)
first = i;
return r;
}
catch (expectation_failure<Iterator> const& x)
{
switch (handler(first, x, context))
{
case fail:
return false;
case retry:
continue;
case accept:
return true;
case rethrow:
throw;
}
}
}
return false;
}
Handler handler;
};
}}}
#endif

View File

@@ -0,0 +1,23 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_CHAR_FEBRUARY_02_2007_0921AM)
#define BOOST_SPIRIT_X3_CHAR_FEBRUARY_02_2007_0921AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/char/char_parser.hpp>
#include <boost/spirit/home/x3/char/negated_char_parser.hpp>
#include <boost/spirit/home/x3/char/char.hpp>
#include <boost/spirit/home/x3/char/char_class.hpp>
#if defined(BOOST_SPIRIT_X3_UNICODE)
#include <boost/spirit/home/x3/char/unicode.hpp>
#endif
#endif

View File

@@ -0,0 +1,41 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_ANY_CHAR_APRIL_16_2006_1051AM)
#define BOOST_SPIRIT_X3_ANY_CHAR_APRIL_16_2006_1051AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/char/literal_char.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Encoding>
struct any_char : char_parser<any_char<Encoding>>
{
typedef typename Encoding::char_type char_type;
typedef Encoding encoding;
typedef char_type attribute_type;
static bool const has_attribute = true;
template <typename Char, typename Context>
bool test(Char ch_, Context const&) const
{
return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch_));
}
template <typename Char>
literal_char<Encoding>
operator()(Char ch) const
{
return literal_char<Encoding>(ch);
}
};
}}}
#endif

View File

@@ -0,0 +1,88 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_CHAR_APRIL_16_2006_1051AM)
#define BOOST_SPIRIT_X3_CHAR_APRIL_16_2006_1051AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/char/any_char.hpp>
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
#include <boost/spirit/home/support/char_encoding/standard.hpp>
#include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
namespace boost { namespace spirit { namespace x3
{
namespace standard
{
typedef any_char<char_encoding::standard> char_type;
char_type const char_ = char_type();
}
using standard::char_type;
using standard::char_;
namespace standard_wide
{
typedef any_char<char_encoding::standard_wide> char_type;
char_type const char_ = char_type();
}
namespace ascii
{
typedef any_char<char_encoding::ascii> char_type;
char_type const char_ = char_type();
}
namespace extension
{
template <>
struct as_parser<char>
{
typedef literal_char<
char_encoding::standard, unused_type>
type;
typedef type value_type;
static type call(char ch)
{
return type(ch);
}
};
template <>
struct as_parser<wchar_t>
{
typedef literal_char<
char_encoding::standard_wide, unused_type>
type;
typedef type value_type;
static type call(wchar_t ch)
{
return type(ch);
}
};
}
inline literal_char<char_encoding::standard, unused_type>
lit(char ch)
{
return literal_char<char_encoding::standard, unused_type>(ch);
}
inline literal_char<char_encoding::standard_wide, unused_type>
lit(wchar_t ch)
{
return literal_char<char_encoding::standard_wide, unused_type>(ch);
}
}}}
#endif

View File

@@ -0,0 +1,148 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_CHAR_CLASS_APRIL_16_2006_1051AM)
#define BOOST_SPIRIT_X3_CHAR_CLASS_APRIL_16_2006_1051AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/char/char_parser.hpp>
#include <boost/spirit/home/x3/char/detail/cast_char.hpp>
#include <boost/spirit/home/support/char_encoding/standard.hpp>
#include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
#include <boost/spirit/home/support/char_encoding/iso8859_1.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
struct char_tag {};
struct alnum_tag {};
struct alpha_tag {};
struct blank_tag {};
struct cntrl_tag {};
struct digit_tag {};
struct graph_tag {};
struct print_tag {};
struct punct_tag {};
struct space_tag {};
struct xdigit_tag {};
struct lower_tag {};
struct upper_tag {};
///////////////////////////////////////////////////////////////////////////
template <typename Encoding>
struct char_class_base
{
typedef typename Encoding::char_type char_type;
#define BOOST_SPIRIT_X3_CLASSIFY(name) \
template <typename Char> \
static bool \
is(name##_tag, Char ch) \
{ \
return Encoding::is##name \
BOOST_PREVENT_MACRO_SUBSTITUTION \
(detail::cast_char<char_type>(ch)); \
} \
/***/
BOOST_SPIRIT_X3_CLASSIFY(char)
BOOST_SPIRIT_X3_CLASSIFY(alnum)
BOOST_SPIRIT_X3_CLASSIFY(alpha)
BOOST_SPIRIT_X3_CLASSIFY(digit)
BOOST_SPIRIT_X3_CLASSIFY(xdigit)
BOOST_SPIRIT_X3_CLASSIFY(cntrl)
BOOST_SPIRIT_X3_CLASSIFY(graph)
BOOST_SPIRIT_X3_CLASSIFY(lower)
BOOST_SPIRIT_X3_CLASSIFY(print)
BOOST_SPIRIT_X3_CLASSIFY(punct)
BOOST_SPIRIT_X3_CLASSIFY(space)
BOOST_SPIRIT_X3_CLASSIFY(blank)
BOOST_SPIRIT_X3_CLASSIFY(upper)
#undef BOOST_SPIRIT_X3_CLASSIFY
};
template <typename Encoding, typename Tag>
struct char_class
: char_parser<char_class<Encoding, Tag>>
{
typedef Encoding encoding;
typedef Tag tag;
typedef typename Encoding::char_type char_type;
typedef char_type attribute_type;
static bool const has_attribute = true;
template <typename Char, typename Context>
bool test(Char ch, Context const&) const
{
return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch))
&& char_class_base<Encoding>::is(tag(), ch);
}
};
#define BOOST_SPIRIT_X3_CHAR_CLASS(encoding, name) \
typedef char_class<char_encoding::encoding, name##_tag> name##_type; \
name##_type const name = name##_type(); \
/***/
#define BOOST_SPIRIT_X3_CHAR_CLASSES(encoding) \
namespace encoding \
{ \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, alnum) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, alpha) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, digit) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, xdigit) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, cntrl) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, graph) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, lower) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, print) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, punct) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, space) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, blank) \
BOOST_SPIRIT_X3_CHAR_CLASS(encoding, upper) \
} \
/***/
BOOST_SPIRIT_X3_CHAR_CLASSES(standard)
BOOST_SPIRIT_X3_CHAR_CLASSES(standard_wide)
BOOST_SPIRIT_X3_CHAR_CLASSES(ascii)
BOOST_SPIRIT_X3_CHAR_CLASSES(iso8859_1)
#undef BOOST_SPIRIT_X3_CHAR_CLASS
#undef BOOST_SPIRIT_X3_CHAR_CLASSES
using standard::alnum_type;
using standard::alpha_type;
using standard::digit_type;
using standard::xdigit_type;
using standard::cntrl_type;
using standard::graph_type;
using standard::lower_type;
using standard::print_type;
using standard::punct_type;
using standard::space_type;
using standard::blank_type;
using standard::upper_type;
using standard::alnum;
using standard::alpha;
using standard::digit;
using standard::xdigit;
using standard::cntrl;
using standard::graph;
using standard::lower;
using standard::print;
using standard::punct;
using standard::space;
using standard::blank;
using standard::upper;
}}}
#endif

View File

@@ -0,0 +1,44 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_CHAR_PARSER_APR_16_2006_0906AM)
#define BOOST_SPIRIT_X3_CHAR_PARSER_APR_16_2006_0906AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// The base char_parser
///////////////////////////////////////////////////////////////////////////
template <typename Derived>
struct char_parser : parser<Derived>
{
template <typename Iterator, typename Context, typename Attribute>
bool parse(
Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
x3::skip_over(first, last, context);
if (first != last && this->derived().test(*first, context))
{
x3::traits::move_to(*first, attr);
++first;
return true;
}
return false;
}
};
}}}
#endif

View File

@@ -0,0 +1,58 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_CAST_CHAR_NOVEMBER_10_2006_0907AM)
#define BOOST_SPIRIT_X3_CAST_CHAR_NOVEMBER_10_2006_0907AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/type_traits/is_signed.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/make_signed.hpp>
namespace boost { namespace spirit { namespace x3 { namespace detail
{
// Here's the thing... typical encodings (except ASCII) deal with unsigned
// integers > 127 (ASCII uses only 127). Yet, most char and wchar_t are signed.
// Thus, a char with value > 127 is negative (e.g. char 233 is -23). When you
// cast this to an unsigned int with 32 bits, you get 4294967273!
//
// The trick is to cast to an unsigned version of the source char first
// before casting to the target. {P.S. Don't worry about the code, the
// optimizer will optimize the if-else branches}
template <typename TargetChar, typename SourceChar>
TargetChar cast_char(SourceChar ch)
{
if (is_signed<TargetChar>::value != is_signed<SourceChar>::value)
{
if (is_signed<SourceChar>::value)
{
// source is signed, target is unsigned
typedef typename make_unsigned<SourceChar>::type USourceChar;
return TargetChar(USourceChar(ch));
}
else
{
// source is unsigned, target is signed
typedef typename make_signed<SourceChar>::type SSourceChar;
return TargetChar(SSourceChar(ch));
}
}
else
{
// source and target has same signedness
return TargetChar(ch); // just cast
}
}
}}}}
#endif

View File

@@ -0,0 +1,54 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_LITERAL_CHAR_APRIL_16_2006_1051AM)
#define BOOST_SPIRIT_X3_LITERAL_CHAR_APRIL_16_2006_1051AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/char/char_parser.hpp>
#include <boost/spirit/home/x3/support/utility/utf8.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Encoding, typename Attribute = typename Encoding::char_type>
struct literal_char : char_parser<literal_char<Encoding, Attribute>>
{
typedef typename Encoding::char_type char_type;
typedef Encoding encoding;
typedef Attribute attribute_type;
static bool const has_attribute =
!is_same<unused_type, attribute_type>::value;
template <typename Char>
literal_char(Char ch)
: ch(static_cast<char_type>(ch)) {}
template <typename Char, typename Context>
bool test(Char ch_, Context const&) const
{
return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch_))
&& ch == char_type(ch_);
}
char_type ch;
};
template <typename Encoding, typename Attribute>
struct get_info<literal_char<Encoding, Attribute>>
{
typedef std::string result_type;
std::string operator()(literal_char<Encoding, Attribute> const& p) const
{
return '\'' + to_utf8(Encoding::toucs4(p.ch)) + '\'';
}
};
}}}
#endif

View File

@@ -0,0 +1,65 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_NEGATED_CHAR_PARSER_APR_16_2006_0906AM)
#define BOOST_SPIRIT_X3_NEGATED_CHAR_PARSER_APR_16_2006_0906AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
#include <boost/spirit/home/x3/char/char_parser.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// negated_char_parser handles ~cp expressions (cp is a char_parser)
///////////////////////////////////////////////////////////////////////////
template <typename Positive>
struct negated_char_parser :
char_parser<negated_char_parser<Positive>>
{
negated_char_parser(Positive const& positive)
: positive(positive) {}
template <typename CharParam, typename Context>
bool test(CharParam ch, Context const& context) const
{
return !positive.test(ch, context);
}
Positive positive;
};
template <typename Positive>
inline negated_char_parser<Positive>
operator~(char_parser<Positive> const& cp)
{
return negated_char_parser<Positive>(cp.derived());
}
template <typename Positive>
inline Positive const&
operator~(negated_char_parser<Positive> const& cp)
{
return cp.positive;
}
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Positive, typename Context>
struct attribute_of<x3::negated_char_parser<Positive>, Context>
: attribute_of<Positive, Context> {};
template <typename Positive, typename Context>
struct has_attribute<x3::negated_char_parser<Positive>, Context>
: has_attribute<Positive, Context> {};
}}}}
#endif

View File

@@ -0,0 +1,617 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_UNICODE_JAN_20_2012_1218AM)
#define BOOST_SPIRIT_X3_UNICODE_JAN_20_2012_1218AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/char/char_parser.hpp>
#include <boost/spirit/home/x3/char/char.hpp>
#include <boost/spirit/home/x3/char/detail/cast_char.hpp>
#include <boost/spirit/home/support/char_encoding/unicode.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
struct char_tag;
struct alnum_tag;
struct alpha_tag;
struct blank_tag;
struct cntrl_tag;
struct digit_tag;
struct graph_tag;
struct print_tag;
struct punct_tag;
struct space_tag;
struct xdigit_tag;
struct lower_tag;
struct upper_tag;
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
struct letter_tag {};
struct mark_tag {};
struct number_tag {};
struct separator_tag {};
struct other_tag {};
struct punctuation_tag {};
struct symbol_tag {};
///////////////////////////////////////////////////////////////////////////
// Unicode General Categories
///////////////////////////////////////////////////////////////////////////
struct uppercase_letter_tag {};
struct lowercase_letter_tag {};
struct titlecase_letter_tag {};
struct modifier_letter_tag {};
struct other_letter_tag {};
struct nonspacing_mark_tag {};
struct enclosing_mark_tag {};
struct spacing_mark_tag {};
struct decimal_number_tag {};
struct letter_number_tag {};
struct other_number_tag {};
struct space_separator_tag {};
struct line_separator_tag {};
struct paragraph_separator_tag {};
struct control_tag {};
struct format_tag {};
struct private_use_tag {};
struct surrogate_tag {};
struct unassigned_tag {};
struct dash_punctuation_tag {};
struct open_punctuation_tag {};
struct close_punctuation_tag {};
struct connector_punctuation_tag {};
struct other_punctuation_tag {};
struct initial_punctuation_tag {};
struct final_punctuation_tag {};
struct math_symbol_tag {};
struct currency_symbol_tag {};
struct modifier_symbol_tag {};
struct other_symbol_tag {};
///////////////////////////////////////////////////////////////////////////
// Unicode Derived Categories
///////////////////////////////////////////////////////////////////////////
struct alphabetic_tag {};
struct uppercase_tag {};
struct lowercase_tag {};
struct white_space_tag {};
struct hex_digit_tag {};
struct noncharacter_code_point_tag {};
struct default_ignorable_code_point_tag {};
///////////////////////////////////////////////////////////////////////////
// Unicode Scripts
///////////////////////////////////////////////////////////////////////////
struct arabic_tag {};
struct imperial_aramaic_tag {};
struct armenian_tag {};
struct avestan_tag {};
struct balinese_tag {};
struct bamum_tag {};
struct bengali_tag {};
struct bopomofo_tag {};
struct braille_tag {};
struct buginese_tag {};
struct buhid_tag {};
struct canadian_aboriginal_tag {};
struct carian_tag {};
struct cham_tag {};
struct cherokee_tag {};
struct coptic_tag {};
struct cypriot_tag {};
struct cyrillic_tag {};
struct devanagari_tag {};
struct deseret_tag {};
struct egyptian_hieroglyphs_tag {};
struct ethiopic_tag {};
struct georgian_tag {};
struct glagolitic_tag {};
struct gothic_tag {};
struct greek_tag {};
struct gujarati_tag {};
struct gurmukhi_tag {};
struct hangul_tag {};
struct han_tag {};
struct hanunoo_tag {};
struct hebrew_tag {};
struct hiragana_tag {};
struct katakana_or_hiragana_tag {};
struct old_italic_tag {};
struct javanese_tag {};
struct kayah_li_tag {};
struct katakana_tag {};
struct kharoshthi_tag {};
struct khmer_tag {};
struct kannada_tag {};
struct kaithi_tag {};
struct tai_tham_tag {};
struct lao_tag {};
struct latin_tag {};
struct lepcha_tag {};
struct limbu_tag {};
struct linear_b_tag {};
struct lisu_tag {};
struct lycian_tag {};
struct lydian_tag {};
struct malayalam_tag {};
struct mongolian_tag {};
struct meetei_mayek_tag {};
struct myanmar_tag {};
struct nko_tag {};
struct ogham_tag {};
struct ol_chiki_tag {};
struct old_turkic_tag {};
struct oriya_tag {};
struct osmanya_tag {};
struct phags_pa_tag {};
struct inscriptional_pahlavi_tag {};
struct phoenician_tag {};
struct inscriptional_parthian_tag {};
struct rejang_tag {};
struct runic_tag {};
struct samaritan_tag {};
struct old_south_arabian_tag {};
struct saurashtra_tag {};
struct shavian_tag {};
struct sinhala_tag {};
struct sundanese_tag {};
struct syloti_nagri_tag {};
struct syriac_tag {};
struct tagbanwa_tag {};
struct tai_le_tag {};
struct new_tai_lue_tag {};
struct tamil_tag {};
struct tai_viet_tag {};
struct telugu_tag {};
struct tifinagh_tag {};
struct tagalog_tag {};
struct thaana_tag {};
struct thai_tag {};
struct tibetan_tag {};
struct ugaritic_tag {};
struct vai_tag {};
struct old_persian_tag {};
struct cuneiform_tag {};
struct yi_tag {};
struct inherited_tag {};
struct common_tag {};
struct unknown_tag {};
///////////////////////////////////////////////////////////////////////////
struct unicode_char_class_base
{
typedef char_encoding::unicode encoding;
typedef char_encoding::unicode::char_type char_type;
#define BOOST_SPIRIT_X3_BASIC_CLASSIFY(name) \
template <typename Char> \
static bool \
is(name##_tag, Char ch) \
{ \
return encoding::is ##name \
BOOST_PREVENT_MACRO_SUBSTITUTION \
(detail::cast_char<char_type>(ch)); \
} \
/***/
#define BOOST_SPIRIT_X3_CLASSIFY(name) \
template <typename Char> \
static bool \
is(name##_tag, Char ch) \
{ \
return encoding::is_##name \
BOOST_PREVENT_MACRO_SUBSTITUTION \
(detail::cast_char<char_type>(ch)); \
} \
/***/
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_BASIC_CLASSIFY(char)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(alnum)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(alpha)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(digit)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(xdigit)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(cntrl)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(graph)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(lower)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(print)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(punct)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(space)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(blank)
BOOST_SPIRIT_X3_BASIC_CLASSIFY(upper)
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CLASSIFY(letter)
BOOST_SPIRIT_X3_CLASSIFY(mark)
BOOST_SPIRIT_X3_CLASSIFY(number)
BOOST_SPIRIT_X3_CLASSIFY(separator)
BOOST_SPIRIT_X3_CLASSIFY(other)
BOOST_SPIRIT_X3_CLASSIFY(punctuation)
BOOST_SPIRIT_X3_CLASSIFY(symbol)
///////////////////////////////////////////////////////////////////////////
// Unicode General Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CLASSIFY(uppercase_letter)
BOOST_SPIRIT_X3_CLASSIFY(lowercase_letter)
BOOST_SPIRIT_X3_CLASSIFY(titlecase_letter)
BOOST_SPIRIT_X3_CLASSIFY(modifier_letter)
BOOST_SPIRIT_X3_CLASSIFY(other_letter)
BOOST_SPIRIT_X3_CLASSIFY(nonspacing_mark)
BOOST_SPIRIT_X3_CLASSIFY(enclosing_mark)
BOOST_SPIRIT_X3_CLASSIFY(spacing_mark)
BOOST_SPIRIT_X3_CLASSIFY(decimal_number)
BOOST_SPIRIT_X3_CLASSIFY(letter_number)
BOOST_SPIRIT_X3_CLASSIFY(other_number)
BOOST_SPIRIT_X3_CLASSIFY(space_separator)
BOOST_SPIRIT_X3_CLASSIFY(line_separator)
BOOST_SPIRIT_X3_CLASSIFY(paragraph_separator)
BOOST_SPIRIT_X3_CLASSIFY(control)
BOOST_SPIRIT_X3_CLASSIFY(format)
BOOST_SPIRIT_X3_CLASSIFY(private_use)
BOOST_SPIRIT_X3_CLASSIFY(surrogate)
BOOST_SPIRIT_X3_CLASSIFY(unassigned)
BOOST_SPIRIT_X3_CLASSIFY(dash_punctuation)
BOOST_SPIRIT_X3_CLASSIFY(open_punctuation)
BOOST_SPIRIT_X3_CLASSIFY(close_punctuation)
BOOST_SPIRIT_X3_CLASSIFY(connector_punctuation)
BOOST_SPIRIT_X3_CLASSIFY(other_punctuation)
BOOST_SPIRIT_X3_CLASSIFY(initial_punctuation)
BOOST_SPIRIT_X3_CLASSIFY(final_punctuation)
BOOST_SPIRIT_X3_CLASSIFY(math_symbol)
BOOST_SPIRIT_X3_CLASSIFY(currency_symbol)
BOOST_SPIRIT_X3_CLASSIFY(modifier_symbol)
BOOST_SPIRIT_X3_CLASSIFY(other_symbol)
///////////////////////////////////////////////////////////////////////////
// Unicode Derived Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CLASSIFY(alphabetic)
BOOST_SPIRIT_X3_CLASSIFY(uppercase)
BOOST_SPIRIT_X3_CLASSIFY(lowercase)
BOOST_SPIRIT_X3_CLASSIFY(white_space)
BOOST_SPIRIT_X3_CLASSIFY(hex_digit)
BOOST_SPIRIT_X3_CLASSIFY(noncharacter_code_point)
BOOST_SPIRIT_X3_CLASSIFY(default_ignorable_code_point)
///////////////////////////////////////////////////////////////////////////
// Unicode Scripts
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CLASSIFY(arabic)
BOOST_SPIRIT_X3_CLASSIFY(imperial_aramaic)
BOOST_SPIRIT_X3_CLASSIFY(armenian)
BOOST_SPIRIT_X3_CLASSIFY(avestan)
BOOST_SPIRIT_X3_CLASSIFY(balinese)
BOOST_SPIRIT_X3_CLASSIFY(bamum)
BOOST_SPIRIT_X3_CLASSIFY(bengali)
BOOST_SPIRIT_X3_CLASSIFY(bopomofo)
BOOST_SPIRIT_X3_CLASSIFY(braille)
BOOST_SPIRIT_X3_CLASSIFY(buginese)
BOOST_SPIRIT_X3_CLASSIFY(buhid)
BOOST_SPIRIT_X3_CLASSIFY(canadian_aboriginal)
BOOST_SPIRIT_X3_CLASSIFY(carian)
BOOST_SPIRIT_X3_CLASSIFY(cham)
BOOST_SPIRIT_X3_CLASSIFY(cherokee)
BOOST_SPIRIT_X3_CLASSIFY(coptic)
BOOST_SPIRIT_X3_CLASSIFY(cypriot)
BOOST_SPIRIT_X3_CLASSIFY(cyrillic)
BOOST_SPIRIT_X3_CLASSIFY(devanagari)
BOOST_SPIRIT_X3_CLASSIFY(deseret)
BOOST_SPIRIT_X3_CLASSIFY(egyptian_hieroglyphs)
BOOST_SPIRIT_X3_CLASSIFY(ethiopic)
BOOST_SPIRIT_X3_CLASSIFY(georgian)
BOOST_SPIRIT_X3_CLASSIFY(glagolitic)
BOOST_SPIRIT_X3_CLASSIFY(gothic)
BOOST_SPIRIT_X3_CLASSIFY(greek)
BOOST_SPIRIT_X3_CLASSIFY(gujarati)
BOOST_SPIRIT_X3_CLASSIFY(gurmukhi)
BOOST_SPIRIT_X3_CLASSIFY(hangul)
BOOST_SPIRIT_X3_CLASSIFY(han)
BOOST_SPIRIT_X3_CLASSIFY(hanunoo)
BOOST_SPIRIT_X3_CLASSIFY(hebrew)
BOOST_SPIRIT_X3_CLASSIFY(hiragana)
BOOST_SPIRIT_X3_CLASSIFY(katakana_or_hiragana)
BOOST_SPIRIT_X3_CLASSIFY(old_italic)
BOOST_SPIRIT_X3_CLASSIFY(javanese)
BOOST_SPIRIT_X3_CLASSIFY(kayah_li)
BOOST_SPIRIT_X3_CLASSIFY(katakana)
BOOST_SPIRIT_X3_CLASSIFY(kharoshthi)
BOOST_SPIRIT_X3_CLASSIFY(khmer)
BOOST_SPIRIT_X3_CLASSIFY(kannada)
BOOST_SPIRIT_X3_CLASSIFY(kaithi)
BOOST_SPIRIT_X3_CLASSIFY(tai_tham)
BOOST_SPIRIT_X3_CLASSIFY(lao)
BOOST_SPIRIT_X3_CLASSIFY(latin)
BOOST_SPIRIT_X3_CLASSIFY(lepcha)
BOOST_SPIRIT_X3_CLASSIFY(limbu)
BOOST_SPIRIT_X3_CLASSIFY(linear_b)
BOOST_SPIRIT_X3_CLASSIFY(lisu)
BOOST_SPIRIT_X3_CLASSIFY(lycian)
BOOST_SPIRIT_X3_CLASSIFY(lydian)
BOOST_SPIRIT_X3_CLASSIFY(malayalam)
BOOST_SPIRIT_X3_CLASSIFY(mongolian)
BOOST_SPIRIT_X3_CLASSIFY(meetei_mayek)
BOOST_SPIRIT_X3_CLASSIFY(myanmar)
BOOST_SPIRIT_X3_CLASSIFY(nko)
BOOST_SPIRIT_X3_CLASSIFY(ogham)
BOOST_SPIRIT_X3_CLASSIFY(ol_chiki)
BOOST_SPIRIT_X3_CLASSIFY(old_turkic)
BOOST_SPIRIT_X3_CLASSIFY(oriya)
BOOST_SPIRIT_X3_CLASSIFY(osmanya)
BOOST_SPIRIT_X3_CLASSIFY(phags_pa)
BOOST_SPIRIT_X3_CLASSIFY(inscriptional_pahlavi)
BOOST_SPIRIT_X3_CLASSIFY(phoenician)
BOOST_SPIRIT_X3_CLASSIFY(inscriptional_parthian)
BOOST_SPIRIT_X3_CLASSIFY(rejang)
BOOST_SPIRIT_X3_CLASSIFY(runic)
BOOST_SPIRIT_X3_CLASSIFY(samaritan)
BOOST_SPIRIT_X3_CLASSIFY(old_south_arabian)
BOOST_SPIRIT_X3_CLASSIFY(saurashtra)
BOOST_SPIRIT_X3_CLASSIFY(shavian)
BOOST_SPIRIT_X3_CLASSIFY(sinhala)
BOOST_SPIRIT_X3_CLASSIFY(sundanese)
BOOST_SPIRIT_X3_CLASSIFY(syloti_nagri)
BOOST_SPIRIT_X3_CLASSIFY(syriac)
BOOST_SPIRIT_X3_CLASSIFY(tagbanwa)
BOOST_SPIRIT_X3_CLASSIFY(tai_le)
BOOST_SPIRIT_X3_CLASSIFY(new_tai_lue)
BOOST_SPIRIT_X3_CLASSIFY(tamil)
BOOST_SPIRIT_X3_CLASSIFY(tai_viet)
BOOST_SPIRIT_X3_CLASSIFY(telugu)
BOOST_SPIRIT_X3_CLASSIFY(tifinagh)
BOOST_SPIRIT_X3_CLASSIFY(tagalog)
BOOST_SPIRIT_X3_CLASSIFY(thaana)
BOOST_SPIRIT_X3_CLASSIFY(thai)
BOOST_SPIRIT_X3_CLASSIFY(tibetan)
BOOST_SPIRIT_X3_CLASSIFY(ugaritic)
BOOST_SPIRIT_X3_CLASSIFY(vai)
BOOST_SPIRIT_X3_CLASSIFY(old_persian)
BOOST_SPIRIT_X3_CLASSIFY(cuneiform)
BOOST_SPIRIT_X3_CLASSIFY(yi)
BOOST_SPIRIT_X3_CLASSIFY(inherited)
BOOST_SPIRIT_X3_CLASSIFY(common)
BOOST_SPIRIT_X3_CLASSIFY(unknown)
#undef BOOST_SPIRIT_X3_BASIC_CLASSIFY
#undef BOOST_SPIRIT_X3_CLASSIFY
};
template <typename Tag>
struct unicode_char_class
: char_parser<unicode_char_class<Tag>>
{
typedef char_encoding::unicode encoding;
typedef Tag tag;
typedef typename encoding::char_type char_type;
typedef char_type attribute_type;
static bool const has_attribute = true;
template <typename Char, typename Context>
bool test(Char ch, Context const&) const
{
return ((sizeof(Char) <= sizeof(char_type)) || encoding::ischar(ch))
&& unicode_char_class_base::is(tag(), ch);
}
};
#define BOOST_SPIRIT_X3_CHAR_CLASS(name) \
typedef unicode_char_class<name##_tag> name##_type; \
name##_type const name = name##_type(); \
/***/
namespace unicode
{
typedef any_char<char_encoding::unicode> char_type;
char_type const char_ = char_type();
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CHAR_CLASS(alnum)
BOOST_SPIRIT_X3_CHAR_CLASS(alpha)
BOOST_SPIRIT_X3_CHAR_CLASS(digit)
BOOST_SPIRIT_X3_CHAR_CLASS(xdigit)
BOOST_SPIRIT_X3_CHAR_CLASS(cntrl)
BOOST_SPIRIT_X3_CHAR_CLASS(graph)
BOOST_SPIRIT_X3_CHAR_CLASS(lower)
BOOST_SPIRIT_X3_CHAR_CLASS(print)
BOOST_SPIRIT_X3_CHAR_CLASS(punct)
BOOST_SPIRIT_X3_CHAR_CLASS(space)
BOOST_SPIRIT_X3_CHAR_CLASS(blank)
BOOST_SPIRIT_X3_CHAR_CLASS(upper)
///////////////////////////////////////////////////////////////////////////
// Unicode Major Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CHAR_CLASS(letter)
BOOST_SPIRIT_X3_CHAR_CLASS(mark)
BOOST_SPIRIT_X3_CHAR_CLASS(number)
BOOST_SPIRIT_X3_CHAR_CLASS(separator)
BOOST_SPIRIT_X3_CHAR_CLASS(other)
BOOST_SPIRIT_X3_CHAR_CLASS(punctuation)
BOOST_SPIRIT_X3_CHAR_CLASS(symbol)
///////////////////////////////////////////////////////////////////////////
// Unicode General Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CHAR_CLASS(uppercase_letter)
BOOST_SPIRIT_X3_CHAR_CLASS(lowercase_letter)
BOOST_SPIRIT_X3_CHAR_CLASS(titlecase_letter)
BOOST_SPIRIT_X3_CHAR_CLASS(modifier_letter)
BOOST_SPIRIT_X3_CHAR_CLASS(other_letter)
BOOST_SPIRIT_X3_CHAR_CLASS(nonspacing_mark)
BOOST_SPIRIT_X3_CHAR_CLASS(enclosing_mark)
BOOST_SPIRIT_X3_CHAR_CLASS(spacing_mark)
BOOST_SPIRIT_X3_CHAR_CLASS(decimal_number)
BOOST_SPIRIT_X3_CHAR_CLASS(letter_number)
BOOST_SPIRIT_X3_CHAR_CLASS(other_number)
BOOST_SPIRIT_X3_CHAR_CLASS(space_separator)
BOOST_SPIRIT_X3_CHAR_CLASS(line_separator)
BOOST_SPIRIT_X3_CHAR_CLASS(paragraph_separator)
BOOST_SPIRIT_X3_CHAR_CLASS(control)
BOOST_SPIRIT_X3_CHAR_CLASS(format)
BOOST_SPIRIT_X3_CHAR_CLASS(private_use)
BOOST_SPIRIT_X3_CHAR_CLASS(surrogate)
BOOST_SPIRIT_X3_CHAR_CLASS(unassigned)
BOOST_SPIRIT_X3_CHAR_CLASS(dash_punctuation)
BOOST_SPIRIT_X3_CHAR_CLASS(open_punctuation)
BOOST_SPIRIT_X3_CHAR_CLASS(close_punctuation)
BOOST_SPIRIT_X3_CHAR_CLASS(connector_punctuation)
BOOST_SPIRIT_X3_CHAR_CLASS(other_punctuation)
BOOST_SPIRIT_X3_CHAR_CLASS(initial_punctuation)
BOOST_SPIRIT_X3_CHAR_CLASS(final_punctuation)
BOOST_SPIRIT_X3_CHAR_CLASS(math_symbol)
BOOST_SPIRIT_X3_CHAR_CLASS(currency_symbol)
BOOST_SPIRIT_X3_CHAR_CLASS(modifier_symbol)
BOOST_SPIRIT_X3_CHAR_CLASS(other_symbol)
///////////////////////////////////////////////////////////////////////////
// Unicode Derived Categories
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CHAR_CLASS(alphabetic)
BOOST_SPIRIT_X3_CHAR_CLASS(uppercase)
BOOST_SPIRIT_X3_CHAR_CLASS(lowercase)
BOOST_SPIRIT_X3_CHAR_CLASS(white_space)
BOOST_SPIRIT_X3_CHAR_CLASS(hex_digit)
BOOST_SPIRIT_X3_CHAR_CLASS(noncharacter_code_point)
BOOST_SPIRIT_X3_CHAR_CLASS(default_ignorable_code_point)
///////////////////////////////////////////////////////////////////////////
// Unicode Scripts
///////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_X3_CHAR_CLASS(arabic)
BOOST_SPIRIT_X3_CHAR_CLASS(imperial_aramaic)
BOOST_SPIRIT_X3_CHAR_CLASS(armenian)
BOOST_SPIRIT_X3_CHAR_CLASS(avestan)
BOOST_SPIRIT_X3_CHAR_CLASS(balinese)
BOOST_SPIRIT_X3_CHAR_CLASS(bamum)
BOOST_SPIRIT_X3_CHAR_CLASS(bengali)
BOOST_SPIRIT_X3_CHAR_CLASS(bopomofo)
BOOST_SPIRIT_X3_CHAR_CLASS(braille)
BOOST_SPIRIT_X3_CHAR_CLASS(buginese)
BOOST_SPIRIT_X3_CHAR_CLASS(buhid)
BOOST_SPIRIT_X3_CHAR_CLASS(canadian_aboriginal)
BOOST_SPIRIT_X3_CHAR_CLASS(carian)
BOOST_SPIRIT_X3_CHAR_CLASS(cham)
BOOST_SPIRIT_X3_CHAR_CLASS(cherokee)
BOOST_SPIRIT_X3_CHAR_CLASS(coptic)
BOOST_SPIRIT_X3_CHAR_CLASS(cypriot)
BOOST_SPIRIT_X3_CHAR_CLASS(cyrillic)
BOOST_SPIRIT_X3_CHAR_CLASS(devanagari)
BOOST_SPIRIT_X3_CHAR_CLASS(deseret)
BOOST_SPIRIT_X3_CHAR_CLASS(egyptian_hieroglyphs)
BOOST_SPIRIT_X3_CHAR_CLASS(ethiopic)
BOOST_SPIRIT_X3_CHAR_CLASS(georgian)
BOOST_SPIRIT_X3_CHAR_CLASS(glagolitic)
BOOST_SPIRIT_X3_CHAR_CLASS(gothic)
BOOST_SPIRIT_X3_CHAR_CLASS(greek)
BOOST_SPIRIT_X3_CHAR_CLASS(gujarati)
BOOST_SPIRIT_X3_CHAR_CLASS(gurmukhi)
BOOST_SPIRIT_X3_CHAR_CLASS(hangul)
BOOST_SPIRIT_X3_CHAR_CLASS(han)
BOOST_SPIRIT_X3_CHAR_CLASS(hanunoo)
BOOST_SPIRIT_X3_CHAR_CLASS(hebrew)
BOOST_SPIRIT_X3_CHAR_CLASS(hiragana)
BOOST_SPIRIT_X3_CHAR_CLASS(katakana_or_hiragana)
BOOST_SPIRIT_X3_CHAR_CLASS(old_italic)
BOOST_SPIRIT_X3_CHAR_CLASS(javanese)
BOOST_SPIRIT_X3_CHAR_CLASS(kayah_li)
BOOST_SPIRIT_X3_CHAR_CLASS(katakana)
BOOST_SPIRIT_X3_CHAR_CLASS(kharoshthi)
BOOST_SPIRIT_X3_CHAR_CLASS(khmer)
BOOST_SPIRIT_X3_CHAR_CLASS(kannada)
BOOST_SPIRIT_X3_CHAR_CLASS(kaithi)
BOOST_SPIRIT_X3_CHAR_CLASS(tai_tham)
BOOST_SPIRIT_X3_CHAR_CLASS(lao)
BOOST_SPIRIT_X3_CHAR_CLASS(latin)
BOOST_SPIRIT_X3_CHAR_CLASS(lepcha)
BOOST_SPIRIT_X3_CHAR_CLASS(limbu)
BOOST_SPIRIT_X3_CHAR_CLASS(linear_b)
BOOST_SPIRIT_X3_CHAR_CLASS(lisu)
BOOST_SPIRIT_X3_CHAR_CLASS(lycian)
BOOST_SPIRIT_X3_CHAR_CLASS(lydian)
BOOST_SPIRIT_X3_CHAR_CLASS(malayalam)
BOOST_SPIRIT_X3_CHAR_CLASS(mongolian)
BOOST_SPIRIT_X3_CHAR_CLASS(meetei_mayek)
BOOST_SPIRIT_X3_CHAR_CLASS(myanmar)
BOOST_SPIRIT_X3_CHAR_CLASS(nko)
BOOST_SPIRIT_X3_CHAR_CLASS(ogham)
BOOST_SPIRIT_X3_CHAR_CLASS(ol_chiki)
BOOST_SPIRIT_X3_CHAR_CLASS(old_turkic)
BOOST_SPIRIT_X3_CHAR_CLASS(oriya)
BOOST_SPIRIT_X3_CHAR_CLASS(osmanya)
BOOST_SPIRIT_X3_CHAR_CLASS(phags_pa)
BOOST_SPIRIT_X3_CHAR_CLASS(inscriptional_pahlavi)
BOOST_SPIRIT_X3_CHAR_CLASS(phoenician)
BOOST_SPIRIT_X3_CHAR_CLASS(inscriptional_parthian)
BOOST_SPIRIT_X3_CHAR_CLASS(rejang)
BOOST_SPIRIT_X3_CHAR_CLASS(runic)
BOOST_SPIRIT_X3_CHAR_CLASS(samaritan)
BOOST_SPIRIT_X3_CHAR_CLASS(old_south_arabian)
BOOST_SPIRIT_X3_CHAR_CLASS(saurashtra)
BOOST_SPIRIT_X3_CHAR_CLASS(shavian)
BOOST_SPIRIT_X3_CHAR_CLASS(sinhala)
BOOST_SPIRIT_X3_CHAR_CLASS(sundanese)
BOOST_SPIRIT_X3_CHAR_CLASS(syloti_nagri)
BOOST_SPIRIT_X3_CHAR_CLASS(syriac)
BOOST_SPIRIT_X3_CHAR_CLASS(tagbanwa)
BOOST_SPIRIT_X3_CHAR_CLASS(tai_le)
BOOST_SPIRIT_X3_CHAR_CLASS(new_tai_lue)
BOOST_SPIRIT_X3_CHAR_CLASS(tamil)
BOOST_SPIRIT_X3_CHAR_CLASS(tai_viet)
BOOST_SPIRIT_X3_CHAR_CLASS(telugu)
BOOST_SPIRIT_X3_CHAR_CLASS(tifinagh)
BOOST_SPIRIT_X3_CHAR_CLASS(tagalog)
BOOST_SPIRIT_X3_CHAR_CLASS(thaana)
BOOST_SPIRIT_X3_CHAR_CLASS(thai)
BOOST_SPIRIT_X3_CHAR_CLASS(tibetan)
BOOST_SPIRIT_X3_CHAR_CLASS(ugaritic)
BOOST_SPIRIT_X3_CHAR_CLASS(vai)
BOOST_SPIRIT_X3_CHAR_CLASS(old_persian)
BOOST_SPIRIT_X3_CHAR_CLASS(cuneiform)
BOOST_SPIRIT_X3_CHAR_CLASS(yi)
BOOST_SPIRIT_X3_CHAR_CLASS(inherited)
BOOST_SPIRIT_X3_CHAR_CLASS(common)
BOOST_SPIRIT_X3_CHAR_CLASS(unknown)
}
#undef BOOST_SPIRIT_X3_CHAR_CLASS
}}}
#endif

View File

@@ -0,0 +1,19 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_CORE_APRIL_04_2012_0318PM)
#define BOOST_SPIRIT_X3_QI_MARCH_04_2007_0852PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/core/parse.hpp>
//~ #include <boost/spirit/home/x3/core/parse_attr.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#endif

View File

@@ -0,0 +1,152 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_PARSE_INTO_CONTAINER_JAN_15_2013_0957PM)
#define SPIRIT_PARSE_INTO_CONTAINER_JAN_15_2013_0957PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/spirit/home/x3/support/traits/value_traits.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/handles_container.hpp>
#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
#include <boost/spirit/home/x3/support/traits/is_substitute.hpp>
#include <boost/mpl/and.hpp>
#include <boost/fusion/include/front.hpp>
namespace boost { namespace spirit { namespace x3 { namespace detail
{
template <typename Parser>
struct parse_into_container_base_impl
{
// Parser has attribute (synthesize; Attribute is a container)
template <typename Iterator, typename Context, typename Attribute>
static bool call_synthesize(
Parser const& parser
, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr, mpl::false_)
{
// synthesized attribute needs to be value initialized
typedef typename
traits::container_value<Attribute>::type
value_type;
value_type val = traits::value_initialize<value_type>::call();
if (!parser.parse(first, last, context, val))
return false;
// push the parsed value into our attribute
traits::push_back(attr, val);
return true;
}
// Parser has attribute (synthesize; Attribute is a single element fusion sequence)
template <typename Iterator, typename Context, typename Attribute>
static bool call_synthesize(
Parser const& parser
, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr, mpl::true_)
{
static_assert(traits::has_size<Attribute, 1>::value,
"Expecting a single element fusion sequence");
return call_synthesize(parser, first, last, context,
fusion::front(attr), mpl::false_());
}
// Parser has attribute (synthesize)
template <typename Iterator, typename Context, typename Attribute>
static bool call(
Parser const& parser
, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr, mpl::true_)
{
return call_synthesize(parser, first, last, context, attr
, fusion::traits::is_sequence<Attribute>());
}
// Parser has no attribute (pass unused)
template <typename Iterator, typename Context, typename Attribute>
static bool call(
Parser const& parser
, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr, mpl::false_)
{
return parser.parse(first, last, context, unused);
}
template <typename Iterator, typename Context, typename Attribute>
static bool call(
Parser const& parser
, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr)
{
return call(parser, first, last, context, attr
, mpl::bool_<traits::has_attribute<Parser, Context>::value>());
}
};
template <typename Parser, typename Context, typename Enable = void>
struct parse_into_container_impl : parse_into_container_base_impl<Parser> {};
template <typename Parser, typename Container, typename Context>
struct parser_attr_is_substitute_for_container_value
: traits::is_substitute<
typename traits::attribute_of<Parser, Context>::type
, typename traits::container_value<Container>::type
>
{};
template <typename Parser, typename Context>
struct parse_into_container_impl<Parser, Context,
typename enable_if<traits::handles_container<Parser, Context>>::type>
{
template <typename Iterator, typename Attribute>
static bool call(
Parser const& parser
, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr, mpl::true_)
{
return parse_into_container_base_impl<Parser>::call(
parser, first, last, context, attr);
}
template <typename Iterator, typename Attribute>
static bool call(
Parser const& parser
, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr, mpl::false_)
{
return parser.parse(first, last, context, attr);
}
template <typename Iterator, typename Attribute>
static bool call(
Parser const& parser
, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr)
{
return call(parser, first, last, context, attr,
parser_attr_is_substitute_for_container_value<Parser, Attribute, Context>());
}
};
template <typename Parser, typename Iterator
, typename Context, typename Attribute>
bool parse_into_container(
Parser const& parser
, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr)
{
return parse_into_container_impl<Parser, Context>::call(
parser, first, last, context, attr);
}
}}}}
#endif

View File

@@ -0,0 +1,102 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_PARSE_APRIL_16_2006_0442PM)
#define BOOST_SPIRIT_X3_PARSE_APRIL_16_2006_0442PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/concept_check.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Parser, typename Attribute>
inline bool
parse(
Iterator& first
, Iterator last
, Parser const& p
, Attribute& attr)
{
// Make sure the iterator is at least a forward_iterator. If you got a
// compilation error here, then you are using an input_iterator while
// calling this function. You need to supply at least a forward_iterator
// instead.
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
// If you get an error no matching function for call to 'as_parser'
// here, then p is not a parser or there is no suitable conversion
// from p to a parser.
return as_parser(p).parse(first, last, unused, attr);
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Parser>
inline bool
parse(
Iterator& first
, Iterator last
, Parser const& p)
{
return parse(first, last, p, unused);
}
///////////////////////////////////////////////////////////////////////////
enum class skip_flag
{
post_skip, // force post-skipping in phrase_parse()
dont_post_skip // inhibit post-skipping in phrase_parse()
};
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Parser, typename Skipper, typename Attribute>
inline bool
phrase_parse(
Iterator& first
, Iterator last
, Parser const& p
, Skipper const& s
, Attribute& attr
, skip_flag post_skip = skip_flag::post_skip)
{
// Make sure the iterator is at least a forward_iterator. If you got a
// compilation error here, then you are using an input_iterator while
// calling this function. You need to supply at least a forward_iterator
// instead.
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
// If you get an error no matching function for call to 'as_parser'
// here, for either p or s, then p or s is not a parser or there is
// no suitable conversion from p to a parser.
context<skipper_tag, Skipper const> skipper(as_parser(s));
bool r = as_parser(p).parse(first, last, skipper, attr);
if (post_skip == skip_flag::post_skip)
x3::skip_over(first, last, skipper);
return r;
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Parser, typename Skipper>
inline bool
phrase_parse(
Iterator& first
, Iterator last
, Parser const& p
, Skipper const& s
, skip_flag post_skip = skip_flag::post_skip)
{
return phrase_parse(first, last, p, s, unused, post_skip);
}
}}}
#endif

View File

@@ -0,0 +1,250 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2013 Agustin Berge
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_PARSER_OCTOBER_16_2008_0254PM)
#define BOOST_SPIRIT_X3_PARSER_OCTOBER_16_2008_0254PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/mpl/bool.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/declval.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
#include <string>
#if !defined(BOOST_SPIRIT_X3_NO_RTTI)
#include <typeinfo>
#endif
namespace boost { namespace spirit { namespace x3
{
using x3::unused_type;
using x3::unused;
using x3::get;
template <typename Subject, typename Action>
struct action;
template <typename Subject, typename Handler>
struct guard;
struct parser_base {};
struct parser_id;
template <typename Derived>
struct parser : parser_base
{
typedef Derived derived_type;
static bool const handles_container = false;
static bool const is_pass_through_unary = false;
static bool const has_action = false;
Derived const& derived() const
{
return *static_cast<Derived const*>(this);
}
template <typename Action>
action<Derived, Action>
operator[](Action f) const
{
return action<Derived, Action>(this->derived(), f);
}
template <typename Handler>
guard<Derived, Handler>
on_error(Handler f) const
{
return guard<Derived, Handler>(this->derived(), f);
}
};
struct unary_category;
struct binary_category;
template <typename Subject, typename Derived>
struct unary_parser : parser<Derived>
{
typedef unary_category category;
typedef Subject subject_type;
static bool const has_action = Subject::has_action;
unary_parser(Subject subject)
: subject(subject) {}
unary_parser const& get_unary() const { return *this; }
Subject subject;
};
template <typename Left, typename Right, typename Derived>
struct binary_parser : parser<Derived>
{
typedef binary_category category;
typedef Left left_type;
typedef Right right_type;
static bool const has_action =
left_type::has_action || right_type::has_action;
binary_parser(Left left, Right right)
: left(left), right(right) {}
binary_parser const& get_binary() const { return *this; }
Left left;
Right right;
};
///////////////////////////////////////////////////////////////////////////
// as_parser: convert a type, T, into a parser.
///////////////////////////////////////////////////////////////////////////
namespace extension
{
namespace detail
{
namespace as_parser_guard
{
void as_spirit_parser(...);
template<typename T, typename R =
decltype(as_spirit_parser(boost::declval<T const&>()))>
struct deduce_as_parser {
typedef R type;
typedef typename boost::remove_cv<
typename boost::remove_reference<R>::type
>::type value_type;
static type call(T const& v)
{
return as_spirit_parser(v);
}
};
template<typename T>
struct deduce_as_parser<T, void>
{};
}
using as_parser_guard::deduce_as_parser;
}
template <typename T, typename Enable = void>
struct as_parser : detail::deduce_as_parser<T> {};
template <>
struct as_parser<unused_type>
{
typedef unused_type type;
typedef unused_type value_type;
static type call(unused_type)
{
return unused;
}
};
template <typename Derived>
struct as_parser<Derived
, typename enable_if<is_base_of<parser_base, Derived>>::type>
{
typedef Derived const& type;
typedef Derived value_type;
static type call(Derived const& p)
{
return p;
}
};
template <typename Derived>
struct as_parser<parser<Derived>>
{
typedef Derived const& type;
typedef Derived value_type;
static type call(parser<Derived> const& p)
{
return p.derived();
}
};
}
template <typename T>
inline typename extension::as_parser<T>::type
as_parser(T const& x)
{
return extension::as_parser<T>::call(x);
}
template <typename Derived>
inline Derived const&
as_parser(parser<Derived> const& p)
{
return p.derived();
}
///////////////////////////////////////////////////////////////////////////
// is_parser<T>: metafunction that evaluates to mpl::true_ if a type T
// can be used as a parser, mpl::false_ otherwise
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Enable = void>
struct is_parser
: mpl::false_
{};
template <typename T>
struct is_parser<T, typename disable_if_substitution_failure<
typename extension::as_parser<T>::type>::type>
: mpl::true_
{};
///////////////////////////////////////////////////////////////////////////
// The main what function
//
// Note: unlike Spirit2, spirit parsers are no longer required to have a
// "what" member function. In X3, we specialize the get_info struct
// below where needed. If a specialization is not provided, the default
// below will be used. The default "what" result will be the typeid
// name of the parser if BOOST_SPIRIT_X3_NO_RTTI is not defined, otherwise
// "undefined"
///////////////////////////////////////////////////////////////////////////
template <typename Parser, typename Enable = void>
struct get_info
{
typedef std::string result_type;
std::string operator()(Parser const&) const
{
#if !defined(BOOST_SPIRIT_X3_NO_RTTI)
return typeid(Parser).name();
#else
return "undefined";
#endif
}
};
template <typename Parser>
std::string what(Parser const& p)
{
return get_info<Parser>()(p);
}
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Subject, typename Derived, typename Context>
struct has_attribute<x3::unary_parser<Subject, Derived>, Context>
: has_attribute<Subject, Context> {};
template <typename Left, typename Right, typename Derived, typename Context>
struct has_attribute<x3::binary_parser<Left, Right, Derived>, Context>
: mpl::bool_<has_attribute<Left, Context>::value ||
has_attribute<Right, Context>::value> {};
}}}}
#endif

View File

@@ -0,0 +1,52 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_PROXY_FEBRUARY_1_2013_0211PM)
#define BOOST_SPIRIT_X3_PROXY_FEBRUARY_1_2013_0211PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Subject, typename Derived>
struct proxy : unary_parser<Subject, Derived>
{
static bool const is_pass_through_unary = true;
proxy(Subject const& subject)
: unary_parser<Subject, Derived>(subject) {}
// Overload this when appropriate. The proxy parser will pick up
// the most derived overload.
template <
typename Iterator, typename Context, typename Attribute
, typename Category>
bool parse_subject(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr, Category) const
{
this->subject.parse(first, last, context, attr);
return true;
}
// Main entry point.
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
return this->derived().parse_subject(first, last, context, attr
, typename traits::attribute_category<Attribute>::type());
}
};
}}}
#endif

View File

@@ -0,0 +1,104 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_SKIP_APRIL_16_2006_0625PM)
#define BOOST_SPIRIT_X3_SKIP_APRIL_16_2006_0625PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/not.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/declval.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// Move the /first/ iterator to the first non-matching position
// given a skip-parser. The function is a no-op if unused_type or
// unused_skipper is passed as the skip-parser.
///////////////////////////////////////////////////////////////////////////
template <typename Skipper>
struct unused_skipper : unused_type
{
unused_skipper(Skipper const& skipper)
: skipper(skipper) {}
Skipper const& skipper;
};
namespace detail
{
template <typename Skipper>
struct is_unused_skipper
: mpl::false_ {};
template <typename Skipper>
struct is_unused_skipper<unused_skipper<Skipper>>
: mpl::true_ {};
template <>
struct is_unused_skipper<unused_type>
: mpl::true_ {};
template <typename Skipper>
inline Skipper const&
get_unused_skipper(Skipper const& skipper)
{
return skipper;
}
template <typename Skipper>
inline Skipper const&
get_unused_skipper(unused_skipper<Skipper> const& unused_skipper)
{
return unused_skipper.skipper;
}
template <typename Iterator, typename Skipper>
inline void skip_over(
Iterator& first, Iterator const& last, Skipper const& skipper)
{
while (first != last && skipper.parse(first, last, unused, unused))
/***/;
}
template <typename Iterator>
inline void skip_over(Iterator&, Iterator const&, unused_type)
{
}
template <typename Iterator, typename Skipper>
inline void skip_over(
Iterator&, Iterator const&, unused_skipper<Skipper> const&)
{
}
}
// this tag is used to find the skipper from the context
struct skipper_tag;
template <typename Context>
struct has_skipper
: mpl::not_<detail::is_unused_skipper<
typename remove_cv<typename remove_reference<
decltype(x3::get<skipper_tag>(boost::declval<Context>()))
>::type>::type
>> {};
template <typename Iterator, typename Context>
inline void skip_over(
Iterator& first, Iterator const& last, Context const& context)
{
detail::skip_over(first, last, x3::get<skipper_tag>(context));
}
}}}
#endif

View File

@@ -0,0 +1,27 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_DIRECTIVE_FEBRUARY_05_2007_0313PM)
#define BOOST_SPIRIT_X3_DIRECTIVE_FEBRUARY_05_2007_0313PM
#if defined(_MSC_VER)
#pragma once
#endif
//~ #include <boost/spirit/home/x3/directive/as.hpp>
//~ #include <boost/spirit/home/x3/directive/encoding.hpp>
//~ #include <boost/spirit/home/x3/directive/hold.hpp>
#include <boost/spirit/home/x3/directive/expect.hpp>
#include <boost/spirit/home/x3/directive/lexeme.hpp>
#include <boost/spirit/home/x3/directive/no_skip.hpp>
//~ #include <boost/spirit/home/x3/directive/matches.hpp>
//~ #include <boost/spirit/home/x3/directive/no_case.hpp>
#include <boost/spirit/home/x3/directive/omit.hpp>
//~ #include <boost/spirit/home/x3/directive/raw.hpp>
//~ #include <boost/spirit/home/x3/directive/repeat.hpp>
#include <boost/spirit/home/x3/directive/skip.hpp>
#endif

View File

@@ -0,0 +1,73 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_EXPECT_MARCH_16_2012_1024PM)
#define SPIRIT_EXPECT_MARCH_16_2012_1024PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/throw_exception.hpp>
#include <stdexcept>
namespace boost { namespace spirit { namespace x3
{
template <typename Iterator>
struct expectation_failure : std::runtime_error
{
expectation_failure(Iterator first, Iterator last, std::string const& what)
: std::runtime_error("boost::spirit::x3::expectation_failure")
, first(first), last(last), what_(what)
{}
~expectation_failure() throw() {}
Iterator first;
Iterator last;
std::string what_;
};
template <typename Subject>
struct expect_directive : unary_parser<Subject, expect_directive<Subject>>
{
typedef unary_parser<Subject, expect_directive<Subject> > base_type;
static bool const is_pass_through_unary = true;
expect_directive(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
bool r = this->subject.parse(first, last, context, attr);
if (!r)
{
boost::throw_exception(
expectation_failure<Iterator>(
first, last, what(this->subject)));
}
return r;
}
};
struct expect_gen
{
template <typename Subject>
expect_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return {as_parser(subject)};
}
};
expect_gen const expect = expect_gen();
}}}
#endif

View File

@@ -0,0 +1,80 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_LEXEME_MARCH_24_2007_0802AM)
#define SPIRIT_LEXEME_MARCH_24_2007_0802AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Subject>
struct lexeme_directive : unary_parser<Subject, lexeme_directive<Subject>>
{
typedef unary_parser<Subject, lexeme_directive<Subject> > base_type;
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
lexeme_directive(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context, typename Attribute>
typename enable_if<has_skipper<Context>, bool>::type
parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
x3::skip_over(first, last, context);
auto const& skipper = get<skipper_tag>(context);
typedef unused_skipper<
typename remove_reference<decltype(skipper)>::type>
unused_skipper_type;
unused_skipper_type unused_skipper(skipper);
return this->subject.parse(
first, last
, make_context<skipper_tag>(unused_skipper, context)
, attr);
}
template <typename Iterator, typename Context, typename Attribute>
typename disable_if<has_skipper<Context>, bool>::type
parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
// no need to pre-skip if skipper is unused
//- x3::skip_over(first, last, context);
return this->subject.parse(
first, last
, context
, attr);
}
};
struct lexeme_gen
{
template <typename Subject>
lexeme_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return {as_parser(subject)};
}
};
lexeme_gen const lexeme = lexeme_gen();
}}}
#endif

View File

@@ -0,0 +1,78 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2013 Agustin Berge
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_NO_SKIP_JAN_16_2010_0802PM)
#define SPIRIT_NO_SKIP_JAN_16_2010_0802PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit { namespace x3
{
// same as lexeme[], but does not pre-skip
template <typename Subject>
struct no_skip_directive : unary_parser<Subject, no_skip_directive<Subject>>
{
typedef unary_parser<Subject, no_skip_directive<Subject> > base_type;
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
no_skip_directive(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context, typename Attribute>
typename enable_if<has_skipper<Context>, bool>::type
parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
auto const& skipper = get<skipper_tag>(context);
typedef unused_skipper<
typename remove_reference<decltype(skipper)>::type>
unused_skipper_type;
unused_skipper_type unused_skipper(skipper);
return this->subject.parse(
first, last
, make_context<skipper_tag>(unused_skipper, context)
, attr);
}
template <typename Iterator, typename Context, typename Attribute>
typename disable_if<has_skipper<Context>, bool>::type
parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
return this->subject.parse(
first, last
, context
, attr);
}
};
struct no_skip_gen
{
template <typename Subject>
no_skip_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return {as_parser(subject)};
}
};
no_skip_gen const no_skip = no_skip_gen();
}}}
#endif

View File

@@ -0,0 +1,55 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_OMIT_MARCH_24_2007_0802AM)
#define SPIRIT_OMIT_MARCH_24_2007_0802AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// omit_directive forces the attribute of subject parser
// to be unused_type
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct omit_directive : unary_parser<Subject, omit_directive<Subject>>
{
typedef unary_parser<Subject, omit_directive<Subject> > base_type;
typedef unused_type attribute_type;
static bool const has_attribute = false;
typedef Subject subject_type;
omit_directive(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
return this->subject.parse(first, last, context, attr);
}
};
struct omit_gen
{
template <typename Subject>
omit_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return {as_parser(subject)};
}
};
omit_gen const omit = omit_gen();
}}}
#endif

View File

@@ -0,0 +1,118 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2013 Agustin Berge
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_SKIP_JANUARY_26_2008_0422PM)
#define SPIRIT_SKIP_JANUARY_26_2008_0422PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/context.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Subject>
struct reskip_directive : unary_parser<Subject, reskip_directive<Subject>>
{
typedef unary_parser<Subject, reskip_directive<Subject>> base_type;
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
reskip_directive(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context, typename Attribute>
typename disable_if<has_skipper<Context>, bool>::type
parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
auto const& skipper =
detail::get_unused_skipper(get<skipper_tag>(context));
return this->subject.parse(
first, last
, make_context<skipper_tag>(skipper, context)
, attr);
}
template <typename Iterator, typename Context, typename Attribute>
typename enable_if<has_skipper<Context>, bool>::type
parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
return this->subject.parse(
first, last
, context
, attr);
}
};
template <typename Subject, typename Skipper>
struct skip_directive : unary_parser<Subject, skip_directive<Subject, Skipper>>
{
typedef unary_parser<Subject, skip_directive<Subject, Skipper>> base_type;
static bool const is_pass_through_unary = true;
static bool const handles_container = Subject::handles_container;
skip_directive(Subject const& subject, Skipper const& skipper)
: base_type(subject)
, skipper(skipper)
{}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
return this->subject.parse(
first, last
, make_context<skipper_tag>(skipper, context)
, attr);
}
Skipper const skipper;
};
struct reskip_gen
{
template <typename Skipper>
struct skip_gen
{
explicit skip_gen(Skipper const& skipper)
: skipper_(skipper) {}
template <typename Subject>
skip_directive<typename extension::as_parser<Subject>::value_type, Skipper>
operator[](Subject const& subject) const
{
return {as_parser(subject), skipper_};
}
Skipper skipper_;
};
template <typename Skipper>
skip_gen<Skipper> const operator()(Skipper const& skipper) const
{
return skip_gen<Skipper>(skipper);
}
template <typename Subject>
reskip_directive<typename extension::as_parser<Subject>::value_type>
operator[](Subject const& subject) const
{
return {as_parser(subject)};
}
};
reskip_gen const skip = reskip_gen();
}}}
#endif

View File

@@ -0,0 +1,20 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_NONTERMINAL_FEBRUARY_12_2007_1018AM)
#define BOOST_SPIRIT_X3_NONTERMINAL_FEBRUARY_12_2007_1018AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/nonterminal/rule.hpp>
#include <boost/spirit/home/x3/nonterminal/grammar.hpp>
//~ #include <boost/spirit/home/x3/nonterminal/error_handler.hpp>
//~ #include <boost/spirit/home/x3/nonterminal/debug_handler.hpp>
//~ #include <boost/spirit/home/x3/nonterminal/success_handler.hpp>
#endif

View File

@@ -0,0 +1,24 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_DEBUG_HANDLER_STATE_APR_21_2010_0733PM)
#define BOOST_SPIRIT_X3_DEBUG_HANDLER_STATE_APR_21_2010_0733PM
#if defined(_MSC_VER)
#pragma once
#endif
namespace boost { namespace spirit { namespace x3
{
enum debug_handler_state
{
pre_parse
, successful_parse
, failed_parse
};
}}}
#endif

View File

@@ -0,0 +1,189 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_DETAIL_RULE_JAN_08_2012_0326PM)
#define BOOST_SPIRIT_X3_DETAIL_RULE_JAN_08_2012_0326PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/traits/make_attribute.hpp>
#include <boost/spirit/home/x3/nonterminal/detail/transform_attribute.hpp>
#include <boost/utility/addressof.hpp>
#if defined(BOOST_SPIRIT_X3_DEBUG)
#include <boost/spirit/home/x3/nonterminal/simple_trace.hpp>
#endif
namespace boost { namespace spirit { namespace x3
{
template <typename ID>
struct rule_context_with_id_tag;
}}}
namespace boost { namespace spirit { namespace x3 { namespace detail
{
#if defined(BOOST_SPIRIT_X3_DEBUG)
template <typename Iterator, typename Attribute>
struct context_debug
{
context_debug(
char const* rule_name
, Iterator const& first, Iterator const& last
, Attribute const& attr)
: fail(true), rule_name(rule_name)
, first(first), last(last)
, attr(attr)
, f(detail::get_simple_trace())
{
f(first, last, attr, pre_parse, rule_name);
}
~context_debug()
{
auto status = fail ? failed_parse : successful_parse;
f(first, last, attr, status, rule_name);
}
bool fail;
char const* rule_name;
Iterator const& first;
Iterator const& last;
Attribute const& attr;
detail::simple_trace_type& f;
};
#endif
template <typename Attribute>
struct attr_pointer_scope
{
attr_pointer_scope(Attribute*& ptr, Attribute* set)
: save(ptr), ptr(ptr) { ptr = set; }
~attr_pointer_scope() { ptr = save; }
Attribute* save;
Attribute*& ptr;
};
template <>
struct attr_pointer_scope<unused_type>
{
attr_pointer_scope(unused_type, unused_type) {}
~attr_pointer_scope() {}
};
template <typename Attribute, typename ID>
struct parse_rule
{
template <typename RHS, typename Iterator, typename Context, typename ActualAttribute>
static bool parse_rhs(
RHS const& rhs
, Iterator& first, Iterator const& last
, Context const& context, ActualAttribute& attr
, mpl::false_)
{
return rhs.parse(first, last, context, attr);
}
template <typename RHS, typename Iterator, typename Context, typename ActualAttribute>
static bool parse_rhs(
RHS const& rhs
, Iterator& first, Iterator const& last
, Context const& context, ActualAttribute& attr
, mpl::true_)
{
return rhs.parse(first, last, context, unused);
}
template <typename RHS, typename Iterator, typename Context, typename ActualAttribute>
static bool parse_rhs(
RHS const& rhs
, Iterator& first, Iterator const& last
, Context const& context, ActualAttribute& attr)
{
return parse_rhs(rhs, first, last, context, attr
, mpl::bool_<(RHS::has_action)>());
}
template <typename RHS, typename Iterator, typename Context
, typename ActualAttribute, typename AttributePtr>
static bool call_rule_definition(
RHS const& rhs
, char const* rule_name
, Iterator& first, Iterator const& last
, Context const& context, ActualAttribute& attr, AttributePtr*& attr_ptr)
{
typedef traits::make_attribute<Attribute, ActualAttribute> make_attribute;
// do down-stream transformation, provides attribute for
// rhs parser
typedef traits::transform_attribute<
typename make_attribute::type, Attribute, parser_id>
transform;
typedef typename make_attribute::value_type value_type;
typedef typename transform::type transform_attr;
value_type made_attr = make_attribute::call(attr);
transform_attr attr_ = transform::pre(made_attr);
#if defined(BOOST_SPIRIT_X3_DEBUG)
context_debug<Iterator, typename make_attribute::value_type>
dbg(rule_name, first, last, made_attr);
#endif
attr_pointer_scope<typename remove_reference<transform_attr>::type>
attr_scope(attr_ptr, boost::addressof(attr_));
if (parse_rhs(rhs, first, last, context, attr_))
{
// do up-stream transformation, this integrates the results
// back into the original attribute value, if appropriate
traits::post_transform(attr, attr_);
#if defined(BOOST_SPIRIT_X3_DEBUG)
dbg.fail = false;
#endif
return true;
}
return false;
}
template <typename RuleDef, typename Iterator, typename Context
, typename ActualAttribute, typename AttributeContext>
static bool call_from_rule(
RuleDef const& rule_def
, char const* rule_name
, Iterator& first, Iterator const& last
, Context const& context, ActualAttribute& attr, AttributeContext& attr_ctx)
{
// This is called when a rule-body has already been established.
// The rule body is already established by the rule_definition class,
// we will not do it again. We'll simply call the RHS by calling
// call_rule_definition.
return call_rule_definition(
rule_def.rhs, rule_name, first, last
, context, attr, attr_ctx.attr_ptr);
}
template <typename RuleDef, typename Iterator, typename Context
, typename ActualAttribute>
static bool call_from_rule(
RuleDef const& rule_def
, char const* rule_name
, Iterator& first, Iterator const& last
, Context const& context, ActualAttribute& attr, unused_type)
{
// This is called when a rule-body has *not yet* been established.
// The rule body is established by the rule_definition class, so
// we call it to parse and establish the rule-body.
return rule_def.parse(first, last, context, attr);
}
};
}}}}
#endif

View File

@@ -0,0 +1,108 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_X3_DETAIL_ATTRIBUTES_APR_18_2010_0458PM)
#define SPIRIT_X3_DETAIL_ATTRIBUTES_APR_18_2010_0458PM
#include <boost/spirit/home/x3/support/traits/transform_attribute.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace x3
{
struct parser_id;
template <typename Exposed, typename Transformed>
struct default_transform_attribute
{
typedef Transformed type;
static Transformed pre(Exposed&) { return Transformed(); }
static void post(Exposed& val, Transformed& attr)
{
traits::move_to(attr, val);
}
};
// handle case where no transformation is required as the types are the same
template <typename Attribute>
struct default_transform_attribute<Attribute, Attribute>
{
typedef Attribute& type;
static Attribute& pre(Attribute& val) { return val; }
static void post(Attribute&, Attribute const&) {}
};
// main specialization for x3
template <typename Exposed, typename Transformed, typename Enable = void>
struct transform_attribute
: default_transform_attribute<Exposed, Transformed> {};
// reference types need special handling
template <typename Attribute>
struct transform_attribute<Attribute&, Attribute>
{
typedef Attribute& type;
static Attribute& pre(Attribute& val) { return val; }
static void post(Attribute&, Attribute const&) {}
};
// unused_type needs some special handling as well
template <>
struct transform_attribute<unused_type, unused_type>
{
typedef unused_type type;
static unused_type pre(unused_type) { return unused; }
static void post(unused_type, unused_type) {}
};
template <>
struct transform_attribute<unused_type const, unused_type>
: transform_attribute<unused_type, unused_type> {};
template <typename Attribute>
struct transform_attribute<unused_type, Attribute>
: transform_attribute<unused_type, unused_type> {};
template <typename Attribute>
struct transform_attribute<unused_type const, Attribute>
: transform_attribute<unused_type, unused_type> {};
template <typename Attribute>
struct transform_attribute<Attribute, unused_type>
: transform_attribute<unused_type, unused_type> {};
template <typename Attribute>
struct transform_attribute<Attribute const, unused_type>
: transform_attribute<unused_type, unused_type> {};
}}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Exposed, typename Transformed>
struct transform_attribute<Exposed, Transformed, x3::parser_id>
: x3::transform_attribute<Exposed, Transformed> {};
template <typename Exposed, typename Transformed>
struct transform_attribute<Exposed&, Transformed, x3::parser_id>
: transform_attribute<Exposed, Transformed, x3::parser_id> {};
template <typename Attribute>
struct transform_attribute<Attribute&, Attribute, x3::parser_id>
: x3::transform_attribute<Attribute&, Attribute> {};
///////////////////////////////////////////////////////////////////////////
template <typename Exposed, typename Transformed>
void post_transform(Exposed& dest, Transformed&& attr)
{
return transform_attribute<Exposed, Transformed, x3::parser_id>::post(dest, attr);
}
}}}}
#endif

View File

@@ -0,0 +1,161 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_GRAMMAR_JAN_19_2012_0454PM)
#define BOOST_SPIRIT_X3_GRAMMAR_JAN_19_2012_0454PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
#include <boost/spirit/home/x3/nonterminal/grammar.hpp>
#include <boost/fusion/container/map.hpp>
#include <boost/fusion/sequence/intrinsic/at_key.hpp>
#include <boost/fusion/sequence/intrinsic/has_key.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/config.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Elements, typename Next>
struct grammar_context
{
grammar_context(Elements const& elements, Next const& next)
: elements(elements), next(next) {}
template <typename ID>
struct get_result
{
typedef typename ID::type id_type;
typedef typename Next::template get_result<ID> next_get_result;
typedef typename mpl::eval_if<
fusion::result_of::has_key<Elements const, id_type>
, fusion::result_of::at_key<Elements const, id_type>
, next_get_result>::type
type;
};
template <typename ID>
typename get_result<ID>::type
get_impl(ID id, mpl::true_) const
{
typedef typename ID::type id_type;
return fusion::at_key<id_type>(elements);
}
template <typename ID>
typename get_result<ID>::type
get_impl(ID id, mpl::false_) const
{
return next.get(id);
}
template <typename ID>
typename get_result<ID>::type
get(ID id) const
{
typedef typename ID::type id_type;
typename fusion::result_of::has_key<Elements, id_type> has_key;
return get_impl(id, has_key);
}
Elements const& elements;
Next const& next;
};
template <typename Elements>
struct grammar_parser : parser<grammar_parser<Elements>>
{
typedef typename
remove_reference<
typename fusion::result_of::front<Elements>::type
>::type::second_type
start_rule;
grammar_parser(char const* name, Elements const& elements)
: name(name), elements(elements) {}
template <typename Iterator, typename Context, typename Attribute_>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute_& attr) const
{
grammar_context<Elements, Context> our_context(elements, context);
return fusion::front(elements).second.parse(first, last, our_context, attr);
}
char const* name;
Elements elements;
};
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <typename ...Elements>
grammar_parser<fusion::map<fusion::pair<typename Elements::id, Elements>...>>
grammar(char const* name, Elements const&... elements)
{
typedef fusion::map<fusion::pair<typename Elements::id, Elements>...> sequence;
return grammar_parser<sequence>(name,
sequence(fusion::make_pair<typename Elements::id>(elements)...));
}
#else
template <typename T1, typename T2, typename T3>
grammar_parser<
fusion::map<
fusion::pair<typename T1::id, T1>
, fusion::pair<typename T2::id, T2>
, fusion::pair<typename T3::id, T3>
>>
grammar(char const* name, T1 const& _1, T2 const& _2, T3 const& _3)
{
typedef fusion::map<
fusion::pair<typename T1::id, T1>
, fusion::pair<typename T2::id, T2>
, fusion::pair<typename T3::id, T3>>
sequence;
return grammar_parser<sequence>(name,
sequence(
fusion::make_pair<typename T1::id>(_1)
, fusion::make_pair<typename T2::id>(_2)
, fusion::make_pair<typename T3::id>(_3)
));
}
#endif
template <typename Elements>
struct get_info<grammar_parser<Elements>>
{
typedef std::string result_type;
std::string operator()(grammar_parser<Elements> const& p) const
{
return p.name;
}
};
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Elements, typename Context>
struct attribute_of<x3::grammar_parser<Elements>, Context>
: attribute_of<
typename x3::grammar_parser<Elements>::start_rule, Context> {};
template <typename Elements, typename Context>
struct has_attribute<x3::grammar_parser<Elements>, Context>
: has_attribute<
typename x3::grammar_parser<Elements>::start_rule, Context> {};
}}}}
#endif

View File

@@ -0,0 +1,142 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM)
#define BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/nonterminal/detail/rule.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/spirit/home/x3/support/context.hpp>
#if !defined(BOOST_SPIRIT_X3_NO_RTTI)
#include <typeinfo>
#endif
namespace boost { namespace spirit { namespace x3
{
struct rule_context_tag;
template <typename ID>
struct rule_context_with_id_tag;
template <typename Attribute>
struct rule_context
{
Attribute& val() const
{
BOOST_ASSERT(attr_ptr);
return *attr_ptr;
}
Attribute* attr_ptr;
};
template <typename Attribute>
struct rule_context_proxy
{
template <typename Context>
rule_context_proxy(Context& context)
: val(x3::get<rule_context_tag>(context).val()) {}
Attribute& val;
};
template <typename ID, typename RHS, typename Attribute>
struct rule_definition : parser<rule_definition<ID, RHS, Attribute>>
{
typedef rule_definition<ID, RHS, Attribute> this_type;
typedef ID id;
typedef RHS rhs_type;
typedef Attribute attribute_type;
static bool const has_attribute =
!is_same<Attribute, unused_type>::value;
static bool const handles_container =
traits::is_container<Attribute>::value;
rule_definition(RHS rhs, char const* name)
: rhs(rhs), name(name) {}
template <typename Iterator, typename Context, typename Attribute_>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute_& attr) const
{
rule_context<Attribute> r_context = { 0 };
auto rule_ctx1 = make_context<rule_context_with_id_tag<ID>>(r_context, context);
auto rule_ctx2 = make_context<rule_context_tag>(r_context, rule_ctx1);
auto this_context = make_context<ID>(*this, rule_ctx2);
return detail::parse_rule<attribute_type, ID>::call_rule_definition(
rhs, name, first, last, this_context, attr, r_context.attr_ptr);
}
RHS rhs;
char const* name;
};
template <typename ID, typename Attribute = unused_type>
struct rule : parser<rule<ID, Attribute>>
{
typedef ID id;
typedef Attribute attribute_type;
static bool const has_attribute =
!is_same<Attribute, unused_type>::value;
static bool const handles_container =
traits::is_container<Attribute>::value;
typedef rule_context_proxy<Attribute> context;
#if !defined(BOOST_SPIRIT_X3_NO_RTTI)
rule(char const* name = typeid(rule).name()) : name(name) {}
#else
rule(char const* name = "unnamed") : name(name) {}
#endif
template <typename RHS>
rule_definition<
ID, typename extension::as_parser<RHS>::value_type, Attribute>
operator=(RHS const& rhs) const
{
return {as_parser(rhs), name};
}
template <typename Iterator, typename Context, typename Attribute_>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute_& attr) const
{
return detail::parse_rule<attribute_type, ID>::call_from_rule(
x3::get<ID>(context), name
, first, last, context, attr
, x3::get<rule_context_with_id_tag<ID>>(context));
}
char const* name;
};
template <typename ID, typename Attribute>
struct get_info<rule<ID, Attribute>>
{
typedef std::string result_type;
std::string operator()(rule<ID, Attribute> const& p) const
{
return p.name;
}
};
template <typename ID, typename Attribute, typename RHS>
struct get_info<rule_definition<ID, RHS, Attribute>>
{
typedef std::string result_type;
std::string operator()(rule_definition<ID, RHS, Attribute> const& p) const
{
return p.name;
}
};
}}}
#endif

View File

@@ -0,0 +1,150 @@
/*=============================================================================
Copyright (c) 2001-2012 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_SIMPLE_TRACE_DECEMBER_06_2008_1102AM)
#define BOOST_SPIRIT_X3_SIMPLE_TRACE_DECEMBER_06_2008_1102AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/traits/print_token.hpp>
#include <boost/spirit/home/x3/support/traits/print_attribute.hpp>
#include <boost/spirit/home/x3/nonterminal/debug_handler_state.hpp>
#include <boost/fusion/include/out.hpp>
#include <boost/type_traits/is_same.hpp>
#include <ostream>
// The stream to use for debug output
#if !defined(BOOST_SPIRIT_X3_DEBUG_OUT)
#define BOOST_SPIRIT_X3_DEBUG_OUT std::cerr
#endif
// number of tokens to print while debugging
#if !defined(BOOST_SPIRIT_X3_DEBUG_PRINT_SOME)
#define BOOST_SPIRIT_X3_DEBUG_PRINT_SOME 20
#endif
// number of spaces to indent
#if !defined(BOOST_SPIRIT_X3_DEBUG_INDENT)
#define BOOST_SPIRIT_X3_DEBUG_INDENT 2
#endif
namespace boost { namespace spirit { namespace x3
{
namespace detail
{
template <typename Char>
inline void token_printer(std::ostream& o, Char c)
{
// allow customization of the token printer routine
x3::traits::print_token(o, c);
}
}
template <int IndentSpaces = 2, int CharsToPrint = 20>
struct simple_trace
{
simple_trace(std::ostream& out)
: out(out), indent(0) {}
void print_indent(int n) const
{
n *= IndentSpaces;
for (int i = 0; i != n; ++i)
out << ' ';
}
template <typename Iterator>
void print_some(
char const* tag
, Iterator first, Iterator const& last) const
{
print_indent(indent);
out << '<' << tag << '>';
int const n = CharsToPrint;
for (int i = 0; first != last && i != n && *first; ++i, ++first)
detail::token_printer(out, *first);
out << "</" << tag << '>' << std::endl;
// $$$ FIXME convert invalid xml characters (e.g. '<') to valid
// character entities. $$$
}
template <typename Iterator, typename Attribute, typename State>
void operator()(
Iterator const& first
, Iterator const& last
, Attribute const& attr
, State state
, std::string const& rule_name) const
{
switch (state)
{
case pre_parse:
print_indent(indent++);
out
<< '<' << rule_name << '>'
<< std::endl;
print_some("try", first, last);
break;
case successful_parse:
print_some("success", first, last);
if (!is_same<Attribute, unused_type>::value)
{
print_indent(indent);
out
<< "<attributes>";
traits::print_attribute(out, attr);
out
<< "</attributes>";
out << std::endl;
}
//~ if (!fusion::empty(context.locals))
//~ out
//~ << "<locals>"
//~ << context.locals
//~ << "</locals>";
print_indent(--indent);
out
<< "</" << rule_name << '>'
<< std::endl;
break;
case failed_parse:
print_indent(indent);
out << "<fail/>" << std::endl;
print_indent(--indent);
out
<< "</" << rule_name << '>'
<< std::endl;
break;
}
}
std::ostream& out;
mutable int indent;
};
namespace detail
{
typedef simple_trace<
BOOST_SPIRIT_X3_DEBUG_INDENT, BOOST_SPIRIT_X3_DEBUG_PRINT_SOME>
simple_trace_type;
inline simple_trace_type&
get_simple_trace()
{
static simple_trace_type tracer(BOOST_SPIRIT_X3_DEBUG_OUT);
return tracer;
}
}
}}}
#endif

View File

@@ -0,0 +1,19 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_NUMERIC_FEBRUARY_05_2007_1231PM)
#define BOOST_SPIRIT_X3_NUMERIC_FEBRUARY_05_2007_1231PM
#if defined(_MSC_VER)
#pragma once
#endif
//~ #include <boost/spirit/home/x3/numeric/bool.hpp>
#include <boost/spirit/home/x3/numeric/int.hpp>
#include <boost/spirit/home/x3/numeric/uint.hpp>
#include <boost/spirit/home/x3/numeric/real.hpp>
#endif

View File

@@ -0,0 +1,66 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_INT_APR_17_2006_0830AM)
#define BOOST_SPIRIT_X3_INT_APR_17_2006_0830AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/extract_int.hpp>
#include <cstdint>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
template <
typename T
, unsigned Radix = 10
, unsigned MinDigits = 1
, int MaxDigits = -1>
struct int_parser : parser<int_parser<T, Radix, MinDigits, MaxDigits>>
{
// check template parameter 'Radix' for validity
static_assert(
(Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16),
"Error Unsupported Radix");
typedef T attribute_type;
static bool const has_attribute = true;
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
typedef extract_int<T, Radix, MinDigits, MaxDigits> extract;
x3::skip_over(first, last, context);
return extract::call(first, last, attr);
}
};
#define BOOST_SPIRIT_X3_INT_PARSER(int_type, name) \
typedef int_parser<int_type> name##type; \
name##type const name = name##type(); \
/***/
BOOST_SPIRIT_X3_INT_PARSER(long, long_)
BOOST_SPIRIT_X3_INT_PARSER(short, short_)
BOOST_SPIRIT_X3_INT_PARSER(int, int_)
BOOST_SPIRIT_X3_INT_PARSER(long long, long_long)
BOOST_SPIRIT_X3_INT_PARSER(int8_t, int8)
BOOST_SPIRIT_X3_INT_PARSER(int16_t, int16)
BOOST_SPIRIT_X3_INT_PARSER(int32_t, int32)
BOOST_SPIRIT_X3_INT_PARSER(int64_t, int64)
#undef BOOST_SPIRIT_X3_INT_PARSER
}}}
#endif

View File

@@ -0,0 +1,66 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_REAL_APRIL_18_2006_0850AM)
#define BOOST_SPIRIT_X3_REAL_APRIL_18_2006_0850AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/numeric/real_policies.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/extract_real.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename T, typename RealPolicies = real_policies<T> >
struct real_parser : parser<real_parser<T, RealPolicies> >
{
typedef T attribute_type;
static bool const has_attribute = true;
real_parser()
: policies() {}
real_parser(RealPolicies const& policies)
: policies(policies) {}
template <typename Iterator, typename Context>
bool parse(Iterator& first, Iterator const& last
, Context& context, T& attr_) const
{
x3::skip_over(first, last, context);
return extract_real<T, RealPolicies>::parse(first, last, attr_, policies);
}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Attribute& attr_param) const
{
// this case is called when Attribute is not T
T attr_;
if (parse(first, last, context, attr_))
{
traits::move_to(attr_, attr_param);
return true;
}
return false;
}
RealPolicies policies;
};
typedef real_parser<float> float_type;
float_type const float_ = float_type();
typedef real_parser<double> double_type;
double_type const double_ = double_type();
}}}
#endif

View File

@@ -0,0 +1,186 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(SPIRIT_REAL_POLICIES_APRIL_17_2006_1158PM)
#define SPIRIT_REAL_POLICIES_APRIL_17_2006_1158PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/string/detail/string_parse.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/extract_int.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// Default (unsigned) real number policies
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct ureal_policies
{
// trailing dot policy suggested by Gustavo Guerra
static bool const allow_leading_dot = true;
static bool const allow_trailing_dot = true;
static bool const expect_dot = false;
template <typename Iterator>
static bool
parse_sign(Iterator& /*first*/, Iterator const& /*last*/)
{
return false;
}
template <typename Iterator, typename Attribute>
static bool
parse_n(Iterator& first, Iterator const& last, Attribute& attr_)
{
return extract_uint<T, 10, 1, -1>::call(first, last, attr_);
}
template <typename Iterator>
static bool
parse_dot(Iterator& first, Iterator const& last)
{
if (first == last || *first != '.')
return false;
++first;
return true;
}
template <typename Iterator, typename Attribute>
static bool
parse_frac_n(Iterator& first, Iterator const& last, Attribute& attr_)
{
return extract_uint<T, 10, 1, -1, true>::call(first, last, attr_);
}
template <typename Iterator>
static bool
parse_exp(Iterator& first, Iterator const& last)
{
if (first == last || (*first != 'e' && *first != 'E'))
return false;
++first;
return true;
}
template <typename Iterator>
static bool
parse_exp_n(Iterator& first, Iterator const& last, int& attr_)
{
return extract_int<int, 10, 1, -1>::call(first, last, attr_);
}
///////////////////////////////////////////////////////////////////////
// The parse_nan() and parse_inf() functions get called whenever:
//
// - a number to parse does not start with a digit (after having
// successfully parsed an optional sign)
//
// or
//
// - after a floating point number of the value 1 (having no
// exponential part and a fractional part value of 0) has been
// parsed.
//
// The first call allows to recognize representations of NaN or Inf
// starting with a non-digit character (such as NaN, Inf, QNaN etc.).
//
// The second call allows to recognize representation formats starting
// with a 1.0 (such as 1.0#NAN or 1.0#INF etc.).
//
// The functions should return true if a Nan or Inf has been found. In
// this case the attr should be set to the matched value (NaN or
// Inf). The optional sign will be automatically applied afterwards.
//
// The default implementation below recognizes representations of NaN
// and Inf as mandated by the C99 Standard and as proposed for
// inclusion into the C++0x Standard: nan, nan(...), inf and infinity
// (the matching is performed case-insensitively).
///////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Attribute>
static bool
parse_nan(Iterator& first, Iterator const& last, Attribute& attr_)
{
if (first == last)
return false; // end of input reached
if (*first != 'n' && *first != 'N')
return false; // not "nan"
// nan[(...)] ?
if (detail::string_parse("nan", "NAN", first, last, unused))
{
if (*first == '(')
{
// skip trailing (...) part
Iterator i = first;
while (++i != last && *i != ')')
;
if (i == last)
return false; // no trailing ')' found, give up
first = ++i;
}
attr_ = std::numeric_limits<T>::quiet_NaN();
return true;
}
return false;
}
template <typename Iterator, typename Attribute>
static bool
parse_inf(Iterator& first, Iterator const& last, Attribute& attr_)
{
if (first == last)
return false; // end of input reached
if (*first != 'i' && *first != 'I')
return false; // not "inf"
// inf or infinity ?
if (detail::string_parse("inf", "INF", first, last, unused))
{
// skip allowed 'inity' part of infinity
detail::string_parse("inity", "INITY", first, last, unused);
attr_ = std::numeric_limits<T>::infinity();
return true;
}
return false;
}
};
///////////////////////////////////////////////////////////////////////////
// Default (signed) real number policies
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct real_policies : ureal_policies<T>
{
template <typename Iterator>
static bool
parse_sign(Iterator& first, Iterator const& last)
{
return extract_sign(first, last);
}
};
template <typename T>
struct strict_ureal_policies : ureal_policies<T>
{
static bool const expect_dot = true;
};
template <typename T>
struct strict_real_policies : real_policies<T>
{
static bool const expect_dot = true;
};
}}}
#endif

View File

@@ -0,0 +1,79 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2011 Jan Frederick Eick
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_UINT_APR_17_2006_0901AM)
#define BOOST_SPIRIT_X3_UINT_APR_17_2006_0901AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/extract_int.hpp>
#include <cstdint>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
template <
typename T
, unsigned Radix = 10
, unsigned MinDigits = 1
, int MaxDigits = -1>
struct uint_parser : parser<uint_parser<T, Radix, MinDigits, MaxDigits>>
{
// check template parameter 'Radix' for validity
static_assert(
(Radix >= 2 && Radix <= 36),
"Error Unsupported Radix");
typedef T attribute_type;
static bool const has_attribute = true;
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
typedef extract_uint<T, Radix, MinDigits, MaxDigits> extract;
x3::skip_over(first, last, context);
return extract::call(first, last, attr);
}
};
#define BOOST_SPIRIT_X3_UINT_PARSER(uint_type, name) \
typedef uint_parser<uint_type> name##type; \
name##type const name = name##type(); \
/***/
BOOST_SPIRIT_X3_UINT_PARSER(unsigned long, ulong_)
BOOST_SPIRIT_X3_UINT_PARSER(unsigned short, ushort_)
BOOST_SPIRIT_X3_UINT_PARSER(unsigned int, uint_)
BOOST_SPIRIT_X3_UINT_PARSER(unsigned long long, ulong_long)
BOOST_SPIRIT_X3_UINT_PARSER(uint8_t, uint8)
BOOST_SPIRIT_X3_UINT_PARSER(uint16_t, uint16)
BOOST_SPIRIT_X3_UINT_PARSER(uint32_t, uint32)
BOOST_SPIRIT_X3_UINT_PARSER(uint64_t, uint64)
#undef BOOST_SPIRIT_X3_UINT_PARSER
#define BOOST_SPIRIT_X3_UINT_PARSER(uint_type, radix, name) \
typedef uint_parser<uint_type, radix> name##type; \
name##type const name = name##type(); \
/***/
BOOST_SPIRIT_X3_UINT_PARSER(unsigned, 2, bin)
BOOST_SPIRIT_X3_UINT_PARSER(unsigned, 8, oct)
BOOST_SPIRIT_X3_UINT_PARSER(unsigned, 16, hex)
#undef BOOST_SPIRIT_X3_UINT_PARSER
}}}
#endif

View File

@@ -0,0 +1,26 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_OPERATOR_FEBRUARY_02_2007_0558PM)
#define BOOST_SPIRIT_X3_OPERATOR_FEBRUARY_02_2007_0558PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/operator/sequence.hpp>
#include <boost/spirit/home/x3/operator/alternative.hpp>
//~ #include <boost/spirit/home/x3/operator/sequential_or.hpp>
//~ #include <boost/spirit/home/x3/operator/permutation.hpp>
#include <boost/spirit/home/x3/operator/difference.hpp>
#include <boost/spirit/home/x3/operator/list.hpp>
#include <boost/spirit/home/x3/operator/optional.hpp>
#include <boost/spirit/home/x3/operator/kleene.hpp>
#include <boost/spirit/home/x3/operator/plus.hpp>
#include <boost/spirit/home/x3/operator/and_predicate.hpp>
#include <boost/spirit/home/x3/operator/not_predicate.hpp>
#endif

View File

@@ -0,0 +1,67 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_ALTERNATIVE_JAN_07_2013_1131AM)
#define SPIRIT_ALTERNATIVE_JAN_07_2013_1131AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/operator/detail/alternative.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Left, typename Right>
struct alternative : binary_parser<Left, Right, alternative<Left, Right>>
{
typedef binary_parser<Left, Right, alternative<Left, Right>> base_type;
alternative(Left left, Right right)
: base_type(left, right) {}
template <typename Iterator, typename Context>
bool parse(
Iterator& first, Iterator const& last
, Context const& context, unused_type) const
{
return this->left.parse(first, last, context, unused)
|| this->right.parse(first, last, context, unused);
}
template <typename Iterator, typename Context, typename Attribute>
bool parse(
Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
if (detail::parse_alternative(this->left, first, last, context, attr))
return true;
if (detail::parse_alternative(this->right, first, last, context, attr))
return true;
return false;
}
};
template <typename Left, typename Right>
inline alternative<
typename extension::as_parser<Left>::value_type
, typename extension::as_parser<Right>::value_type>
operator|(Left const& left, Right const& right)
{
return {as_parser(left), as_parser(right)};
}
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Left, typename Right, typename Context>
struct attribute_of<x3::alternative<Left, Right>, Context>
: x3::detail::attribute_of_alternative<Left, Right, Context> {};
}}}}
#endif

View File

@@ -0,0 +1,46 @@
/*=============================================================================
Copyright (c) 2001-2012 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_AND_PREDICATE_MARCH_23_2007_0617PM)
#define SPIRIT_AND_PREDICATE_MARCH_23_2007_0617PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/core/parser.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Subject>
struct and_predicate : unary_parser<Subject, and_predicate<Subject>>
{
typedef unary_parser<Subject, and_predicate<Subject>> base_type;
typedef unused_type attribute_type;
static bool const has_attribute = false;
and_predicate(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& /*attr*/) const
{
Iterator i = first;
return this->subject.parse(i, last, context, unused);
}
};
template <typename Subject>
inline and_predicate<typename extension::as_parser<Subject>::value_type>
operator&(Subject const& subject)
{
return {as_parser(subject)};
}
}}}
#endif

View File

@@ -0,0 +1,366 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_ALTERNATIVE_DETAIL_JAN_07_2013_1245PM)
#define SPIRIT_ALTERNATIVE_DETAIL_JAN_07_2013_1245PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
#include <boost/spirit/home/x3/support/traits/is_substitute.hpp>
#include <boost/spirit/home/x3/support/traits/is_variant.hpp>
#include <boost/spirit/home/x3/support/traits/tuple_traits.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
#include <boost/variant/variant.hpp>
#include <boost/mpl/copy_if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/joint_view.hpp>
#include <boost/fusion/include/front.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Left, typename Right>
struct alternative;
}}}
namespace boost { namespace spirit { namespace x3 { namespace detail
{
template <typename Variant, typename Attribute>
struct has_substitute_impl
{
// Find the type from the variant that can be a substitute for Attribute.
// return true_ if one is found, else false_
typedef Variant variant_type;
typedef typename variant_type::types types;
typedef typename mpl::end<types>::type end;
typedef typename
mpl::find_if<types, is_same<mpl::_1, Attribute> >::type
iter_1;
typedef typename
mpl::eval_if<
is_same<iter_1, end>,
mpl::find_if<types, traits::is_substitute<mpl::_1, Attribute> >,
mpl::identity<iter_1>
>::type
iter;
typedef mpl::not_<is_same<iter, end>> type;
};
template <typename Variant, typename Attribute>
struct has_substitute : has_substitute_impl<Variant, Attribute>::type {};
template <typename Attribute>
struct has_substitute<unused_type, Attribute> : mpl::true_ {};
template <typename Attribute>
struct has_substitute<unused_type const, Attribute> : mpl::true_ {};
template <typename Variant, typename Attribute>
struct find_substitute
{
// Get the type from the variant that can be a substitute for Attribute.
// If none is found, just return Attribute
typedef Variant variant_type;
typedef typename variant_type::types types;
typedef typename mpl::end<types>::type end;
typedef typename
mpl::find_if<types, is_same<mpl::_1, Attribute> >::type
iter_1;
typedef typename
mpl::eval_if<
is_same<iter_1, end>,
mpl::find_if<types, traits::is_substitute<mpl::_1, Attribute> >,
mpl::identity<iter_1>
>::type
iter;
typedef typename
mpl::eval_if<
is_same<iter, end>,
mpl::identity<Attribute>,
mpl::deref<iter>
>::type
type;
};
struct pass_variant_unused
{
typedef unused_type type;
template <typename T>
static unused_type
call(T&)
{
return unused_type();
}
};
template <typename Attribute>
struct pass_variant_used
{
typedef Attribute& type;
static Attribute&
call(Attribute& v)
{
return v;
}
};
template <>
struct pass_variant_used<unused_type> : pass_variant_unused {};
template <typename Parser, typename Attribute, typename Context
, typename Enable = void>
struct pass_parser_attribute
{
typedef typename
traits::attribute_of<Parser, Context>::type
attribute_type;
typedef typename
find_substitute<Attribute, attribute_type>::type
substitute_type;
typedef typename
mpl::if_<
is_same<Attribute, substitute_type>
, Attribute&
, substitute_type
>::type
type;
template <typename Attribute_>
static Attribute_&
call(Attribute_& attr, mpl::true_)
{
return attr;
}
template <typename Attribute_>
static type
call(Attribute_&, mpl::false_)
{
return type();
}
template <typename Attribute_>
static type
call(Attribute_& attr)
{
return call(attr, is_same<Attribute_, type>());
}
};
// Pass non-variant attributes as-is
template <typename Parser, typename Attribute, typename Context
, typename Enable = void>
struct pass_non_variant_attribute
{
typedef Attribute& type;
static Attribute&
call(Attribute& attr)
{
return attr;
}
};
// Unwrap single element sequences
template <typename Parser, typename Attribute, typename Context>
struct pass_non_variant_attribute<Parser, Attribute, Context,
typename enable_if<traits::is_size_one_sequence<Attribute>>::type>
{
typedef typename remove_reference<
typename fusion::result_of::front<Attribute>::type>::type
attr_type;
typedef pass_parser_attribute<Parser, attr_type, Context> pass;
typedef typename pass::type type;
template <typename Attribute_>
static type
call(Attribute_& attr)
{
return pass::call(fusion::front(attr));
}
};
template <typename Parser, typename Attribute, typename Context>
struct pass_parser_attribute<Parser, Attribute, Context,
typename enable_if_c<(!traits::is_variant<Attribute>::value)>::type>
: pass_non_variant_attribute<Parser, Attribute, Context>
{};
template <typename Parser, typename Context>
struct pass_parser_attribute<Parser, unused_type, Context>
: pass_variant_unused {};
template <typename Parser, typename Attribute, typename Context>
struct pass_variant_attribute :
mpl::if_c<traits::has_attribute<Parser, Context>::value
, pass_parser_attribute<Parser, Attribute, Context>
, pass_variant_unused>::type
{
static bool const is_alternative = false;
};
template <typename L, typename R, typename Attribute, typename Context>
struct pass_variant_attribute<alternative<L, R>, Attribute, Context> :
mpl::if_c<traits::has_attribute<alternative<L, R>, Context>::value
, pass_variant_used<Attribute>
, pass_variant_unused>::type
{
static bool const is_alternative = true;
};
template <typename L, typename R, typename C>
struct get_alternative_types
{
typedef
mpl::vector<
typename traits::attribute_of<L, C>::type
, typename traits::attribute_of<R, C>::type
>
type;
};
template <typename LL, typename LR, typename R, typename C>
struct get_alternative_types<alternative<LL, LR>, R, C>
{
typedef typename
mpl::push_back<
typename get_alternative_types<LL, LR, C>::type
, typename traits::attribute_of<R, C>::type
>::type
type;
};
template <typename L, typename RL, typename RR, typename C>
struct get_alternative_types<L, alternative<RL, RR>, C>
{
typedef typename
mpl::push_front<
typename get_alternative_types<RL, RR, C>::type
, typename traits::attribute_of<L, C>::type
>::type
type;
};
template <typename LL, typename LR, typename RL, typename RR, typename C>
struct get_alternative_types<alternative<LL, LR>, alternative<RL, RR>, C>
{
typedef
mpl::joint_view<
typename get_alternative_types<LL, LR, C>::type
, typename get_alternative_types<RL, RR, C>::type
>
type;
};
template <typename L, typename R, typename C>
struct attribute_of_alternative
{
// Get all alternative attribute types
typedef typename get_alternative_types<L, R, C>::type all_types;
// Filter all unused_types
typedef typename
mpl::copy_if<
all_types
, mpl::not_<is_same<mpl::_1, unused_type>>
, mpl::back_inserter<mpl::vector<>>
>::type
filtered_types;
// Build a variant if filtered_types is not empty,
// else just return unused_type
typedef typename
mpl::eval_if<
mpl::empty<filtered_types>
, mpl::identity<unused_type>
, make_variant_over<filtered_types>
>::type
type;
};
template <typename Parser, typename Iterator, typename Context, typename Attribute>
bool parse_alternative(
Parser const& p, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr)
{
typedef detail::pass_variant_attribute<Parser, Attribute, Context> pass;
typename pass::type attr_ = pass::call(attr);
if (p.parse(first, last, context, attr_))
{
if (!pass::is_alternative)
traits::move_to(attr_, attr);
return true;
}
return false;
}
template <typename Left, typename Right, typename Context>
struct parse_into_container_impl<alternative<Left, Right>, Context>
{
typedef alternative<Left, Right> parser_type;
template <typename Iterator, typename Attribute>
static bool call(
parser_type const& parser
, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr, mpl::true_)
{
return parse_alternative(parser, first, last, context, attr);
}
template <typename Iterator, typename Attribute>
static bool call(
parser_type const& parser
, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr, mpl::false_)
{
return parse_into_container_base_impl<parser_type>::call(
parser, first, last, context, attr);
}
template <typename Iterator, typename Attribute>
static bool call(
parser_type const& parser
, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr)
{
typedef typename
traits::attribute_of<parser_type, Context>::type
attribute_type;
return call(parser, first, last, context, attr
, has_substitute<attribute_type, Attribute>());
}
};
}}}}
#endif

View File

@@ -0,0 +1,425 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_SEQUENCE_DETAIL_JAN_06_2013_1015AM)
#define SPIRIT_SEQUENCE_DETAIL_JAN_06_2013_1015AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
#include <boost/spirit/home/x3/support/traits/make_attribute.hpp>
#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
#include <boost/spirit/home/x3/support/traits/is_substitute.hpp>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
#include <boost/fusion/include/begin.hpp>
#include <boost/fusion/include/end.hpp>
#include <boost/fusion/include/advance.hpp>
#include <boost/fusion/include/empty.hpp>
#include <boost/fusion/include/front.hpp>
#include <boost/fusion/include/iterator_range.hpp>
#include <boost/fusion/include/as_deque.hpp>
#include <boost/fusion/include/mpl.hpp>
#include <boost/mpl/copy_if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Left, typename Right>
struct sequence;
}}}
namespace boost { namespace spirit { namespace x3 { namespace detail
{
template <typename Parser, typename Context, typename Enable = void>
struct sequence_size
{
static int const value = traits::has_attribute<Parser, Context>::value;
};
template <typename Parser, typename Context>
struct sequence_size_subject
: sequence_size<typename Parser::subject_type, Context> {};
template <typename Parser, typename Context>
struct sequence_size<Parser, Context
, typename enable_if_c<(Parser::is_pass_through_unary)>::type>
: sequence_size_subject<Parser, Context> {};
template <typename L, typename R, typename Context>
struct sequence_size<sequence<L, R>, Context>
{
static int const value =
sequence_size<L, Context>::value +
sequence_size<R, Context>::value;
};
struct pass_sequence_attribute_unused
{
typedef unused_type type;
template <typename T>
static unused_type
call(T&)
{
return unused_type();
}
};
template <typename Attribute>
struct pass_sequence_attribute_front
{
typedef typename fusion::result_of::front<Attribute>::type type;
static typename add_reference<type>::type
call(Attribute& attr)
{
return fusion::front(attr);
}
};
template <typename Attribute>
struct pass_through_sequence_attribute
{
typedef Attribute& type;
template <typename Attribute_>
static Attribute_&
call(Attribute_& attr)
{
return attr;
}
};
template <typename Parser, typename Attribute>
struct pass_sequence_attribute_used :
pass_sequence_attribute_front<Attribute> {};
template <typename Parser, typename Attribute, typename Enable = void>
struct pass_sequence_attribute :
mpl::if_<
fusion::result_of::empty<Attribute>
, pass_sequence_attribute_unused
, pass_sequence_attribute_used<Parser, Attribute>>::type {};
template <typename L, typename R, typename Attribute>
struct pass_sequence_attribute<sequence<L, R>, Attribute>
: pass_through_sequence_attribute<Attribute> {};
template <typename Parser, typename Attribute>
struct pass_sequence_attribute_subject :
pass_sequence_attribute<typename Parser::subject_type, Attribute> {};
template <typename Parser, typename Attribute>
struct pass_sequence_attribute<Parser, Attribute
, typename enable_if_c<(Parser::is_pass_through_unary)>::type>
: pass_sequence_attribute_subject<Parser, Attribute> {};
template <typename L, typename R, typename Attribute, typename Context
, typename Enable = void>
struct partition_attribute
{
static int const l_size = sequence_size<L, Context>::value;
static int const r_size = sequence_size<R, Context>::value;
// If you got an error here, then you are trying to pass
// a fusion sequence with the wrong number of elements
// as that expected by the (sequence) parser.
static_assert(
fusion::result_of::size<Attribute>::value == (l_size + r_size)
, "Attribute does not have the expected size."
);
typedef typename fusion::result_of::begin<Attribute>::type l_begin;
typedef typename fusion::result_of::advance_c<l_begin, l_size>::type l_end;
typedef typename fusion::result_of::end<Attribute>::type r_end;
typedef fusion::iterator_range<l_begin, l_end> l_part;
typedef fusion::iterator_range<l_end, r_end> r_part;
typedef pass_sequence_attribute<L, l_part> l_pass;
typedef pass_sequence_attribute<R, r_part> r_pass;
static l_part left(Attribute& s)
{
auto i = fusion::begin(s);
return l_part(i, fusion::advance_c<l_size>(i));
}
static r_part right(Attribute& s)
{
return r_part(
fusion::advance_c<l_size>(fusion::begin(s))
, fusion::end(s));
}
};
template <typename L, typename R, typename Attribute, typename Context>
struct partition_attribute<L, R, Attribute, Context,
typename enable_if_c<(!traits::has_attribute<L, Context>::value &&
traits::has_attribute<R, Context>::value)>::type>
{
typedef unused_type l_part;
typedef Attribute& r_part;
typedef pass_sequence_attribute_unused l_pass;
typedef pass_through_sequence_attribute<Attribute> r_pass;
static unused_type left(Attribute&)
{
return unused;
}
static Attribute& right(Attribute& s)
{
return s;
}
};
template <typename L, typename R, typename Attribute, typename Context>
struct partition_attribute<L, R, Attribute, Context,
typename enable_if_c<(traits::has_attribute<L, Context>::value &&
!traits::has_attribute<R, Context>::value)>::type>
{
typedef Attribute& l_part;
typedef unused_type r_part;
typedef pass_through_sequence_attribute<Attribute> l_pass;
typedef pass_sequence_attribute_unused r_pass;
static Attribute& left(Attribute& s)
{
return s;
}
static unused_type right(Attribute&)
{
return unused;
}
};
template <typename L, typename R, typename Attribute, typename Context>
struct partition_attribute<L, R, Attribute, Context,
typename enable_if_c<(!traits::has_attribute<L, Context>::value &&
!traits::has_attribute<R, Context>::value)>::type>
{
typedef unused_type l_part;
typedef unused_type r_part;
typedef pass_sequence_attribute_unused l_pass;
typedef pass_sequence_attribute_unused r_pass;
static unused_type left(Attribute&)
{
return unused;
}
static unused_type right(Attribute&)
{
return unused;
}
};
template <typename L, typename R, typename C>
struct get_sequence_types
{
typedef
mpl::vector<
typename traits::attribute_of<L, C>::type
, typename traits::attribute_of<R, C>::type
>
type;
};
template <typename LL, typename LR, typename R, typename C>
struct get_sequence_types<sequence<LL, LR>, R, C>
{
typedef typename
mpl::push_back<
typename get_sequence_types<LL, LR, C>::type
, typename traits::attribute_of<R, C>::type
>::type
type;
};
template <typename L, typename RL, typename RR, typename C>
struct get_sequence_types<L, sequence<RL, RR>, C>
{
typedef typename
mpl::push_front<
typename get_sequence_types<RL, RR, C>::type
, typename traits::attribute_of<L, C>::type
>::type
type;
};
template <typename LL, typename LR, typename RL, typename RR, typename C>
struct get_sequence_types<sequence<LL, LR>, sequence<RL, RR>, C>
{
typedef
mpl::joint_view<
typename get_sequence_types<LL, LR, C>::type
, typename get_sequence_types<RL, RR, C>::type
>
type;
};
template <typename L, typename R, typename C>
struct attribute_of_sequence
{
// Get all sequence attribute types
typedef typename get_sequence_types<L, R, C>::type all_types;
// Filter all unused_types
typedef typename
mpl::copy_if<
all_types
, mpl::not_<is_same<mpl::_1, unused_type>>
, mpl::back_inserter<mpl::vector<>>
>::type
filtered_types;
// Build a fusion::deque if filtered_types is not empty,
// else just return unused_type
typedef typename
mpl::eval_if<
mpl::empty<filtered_types>
, mpl::identity<unused_type>
, fusion::result_of::as_deque<filtered_types>
>::type
type;
};
template <typename Left, typename Right
, typename Iterator, typename Context, typename Attribute>
bool parse_sequence(
Left const& left, Right const& right
, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr, traits::tuple_attribute)
{
typedef partition_attribute<Left, Right, Attribute, Context> partition;
typedef typename partition::l_pass l_pass;
typedef typename partition::r_pass r_pass;
typename partition::l_part l_part = partition::left(attr);
typename partition::r_part r_part = partition::right(attr);
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 (left.parse(first, last, context, l_attr)
&& right.parse(first, last, context, r_attr))
return true;
first = save;
return false;
}
template <typename Left, typename Right
, typename Iterator, typename Context, typename Attribute>
bool parse_sequence(
Left const& left, Right const& right
, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr, traits::plain_attribute)
{
typedef typename traits::attribute_of<Left, Context>::type l_attr_type;
typedef typename traits::attribute_of<Right, Context>::type r_attr_type;
typedef traits::make_attribute<l_attr_type, Attribute> l_make_attribute;
typedef traits::make_attribute<r_attr_type, Attribute> r_make_attribute;
typename l_make_attribute::type l_attr = l_make_attribute::call(attr);
typename r_make_attribute::type r_attr = r_make_attribute::call(attr);
Iterator save = first;
if (left.parse(first, last, context, l_attr)
&& right.parse(first, last, context, r_attr))
return true;
first = save;
return false;
}
template <typename Left, typename Right
, typename Iterator, typename Context, typename Attribute>
bool parse_sequence(
Left const& left, Right const& right
, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr, traits::container_attribute);
template <typename Left, typename Right
, typename Iterator, typename Context, typename Attribute>
bool parse_sequence(
Left const& left, Right const& right
, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr, traits::container_attribute)
{
Iterator save = first;
if (parse_into_container(left, first, last, context, attr)
&& parse_into_container(right, first, last, context, attr))
return true;
first = save;
return false;
}
template <typename Left, typename Right, typename Context>
struct parse_into_container_impl<sequence<Left, Right>, Context>
{
typedef sequence<Left, Right> parser_type;
template <typename Iterator, typename Attribute>
static bool call(
parser_type const& parser
, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr, mpl::false_)
{
Attribute attr_;
if (!parse_sequence(parser.left, parser.right
, first, last, context, attr_, traits::container_attribute()))
{
return false;
}
traits::append(attr, attr_.begin(), attr_.end());
return true;
}
template <typename Iterator, typename Attribute>
static bool call(
parser_type const& parser
, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr, mpl::true_)
{
return parse_into_container_base_impl<parser_type>::call(
parser, first, last, context, attr);
}
template <typename Iterator, typename Attribute>
static bool call(
parser_type const& parser
, Iterator& first, Iterator const& last
, Context const& context, Attribute& attr)
{
typedef typename
traits::attribute_of<parser_type, Context>::type
attribute_type;
typedef typename
traits::container_value<Attribute>::type
value_type;
return call(parser, first, last, context, attr
, traits::is_substitute<attribute_type, value_type>());
}
};
}}}}
#endif

View File

@@ -0,0 +1,74 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_DIFFERENCE_FEBRUARY_11_2007_1250PM)
#define SPIRIT_DIFFERENCE_FEBRUARY_11_2007_1250PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Left, typename Right>
struct difference : binary_parser<Left, Right, difference<Left, Right>>
{
typedef binary_parser<Left, Right, difference<Left, Right>> base_type;
static bool const handles_container = Left::handles_container;
difference(Left const& left, Right const& right)
: base_type(left, right) {}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
// Try Right first
Iterator start = first;
if (this->right.parse(first, last, context, unused))
{
// Right succeeds, we fail.
first = start;
return false;
}
// Right fails, now try Left
return this->left.parse(first, last, context, attr);
}
template <typename Left_, typename Right_>
difference<Left_, Right_>
make(Left_ const& left, Right_ const& right) const
{
return difference<Left_, Right_>(left, right);
}
};
template <typename Left, typename Right>
inline difference<
typename extension::as_parser<Left>::value_type
, typename extension::as_parser<Right>::value_type>
operator-(Left const& left, Right const& right)
{
return {as_parser(left), as_parser(right)};
}
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Left, typename Right, typename Context>
struct attribute_of<x3::difference<Left, Right>, Context>
: attribute_of<Left, Context> {};
template <typename Left, typename Right, typename Context>
struct has_attribute<x3::difference<Left, Right>, Context>
: has_attribute<Left, Context> {};
}}}}
#endif

View File

@@ -0,0 +1,58 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_KLEENE_JANUARY_07_2007_0818AM)
#define SPIRIT_KLEENE_JANUARY_07_2007_0818AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Subject>
struct kleene : unary_parser<Subject, kleene<Subject>>
{
typedef unary_parser<Subject, kleene<Subject>> base_type;
static bool const handles_container = true;
kleene(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
while (detail::parse_into_container(
this->subject, first, last, context, attr))
;
return true;
}
};
template <typename Subject>
inline kleene<typename extension::as_parser<Subject>::value_type>
operator*(Subject const& subject)
{
return {as_parser(subject)};
}
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Subject, typename Context>
struct attribute_of<x3::kleene<Subject>, Context>
: build_container<
typename attribute_of<Subject, Context>::type> {};
}}}}
#endif

View File

@@ -0,0 +1,72 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_LIST_MARCH_24_2007_1031AM)
#define SPIRIT_LIST_MARCH_24_2007_1031AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Left, typename Right>
struct list : binary_parser<Left, Right, list<Left, Right>>
{
typedef binary_parser<Left, Right, list<Left, Right>> base_type;
static bool const handles_container = true;
static bool const has_attribute = true;
list(Left const& left, Right const& right)
: base_type(left, right) {}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
// in order to succeed we need to match at least one element
if (!detail::parse_into_container(
this->left, first, last, context, attr))
return false;
Iterator save = first;
while (this->right.parse(first, last, context, unused)
&& detail::parse_into_container(
this->left, first, last, context, attr))
{
save = first;
}
first = save;
return true;
}
};
template <typename Left, typename Right>
inline list<
typename extension::as_parser<Left>::value_type
, typename extension::as_parser<Right>::value_type>
operator%(Left const& left, Right const& right)
{
return {as_parser(left), as_parser(right)};
}
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Left, typename Right, typename Context>
struct attribute_of<x3::list<Left, Right>, Context>
: traits::build_container<
typename attribute_of<Left, Context>::type> {};
}}}}
#endif

View File

@@ -0,0 +1,46 @@
/*=============================================================================
Copyright (c) 2001-2012 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_NOT_PREDICATE_MARCH_23_2007_0618PM)
#define SPIRIT_NOT_PREDICATE_MARCH_23_2007_0618PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/core/parser.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Subject>
struct not_predicate : unary_parser<Subject, not_predicate<Subject>>
{
typedef unary_parser<Subject, not_predicate<Subject>> base_type;
typedef unused_type attribute_type;
static bool const has_attribute = false;
not_predicate(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& /*attr*/) const
{
Iterator i = first;
return !this->subject.parse(i, last, context, unused);
}
};
template <typename Subject>
inline not_predicate<typename extension::as_parser<Subject>::value_type>
operator!(Subject const& subject)
{
return {as_parser(subject)};
}
}}}
#endif

View File

@@ -0,0 +1,82 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_OPTIONAL_MARCH_23_2007_1117PM)
#define SPIRIT_OPTIONAL_MARCH_23_2007_1117PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/core/proxy.hpp>
#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/spirit/home/x3/support/traits/optional_traits.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Subject>
struct optional : proxy<Subject, optional<Subject>>
{
typedef proxy<Subject, optional<Subject>> base_type;
static bool const handles_container = true;
optional(Subject const& subject)
: base_type(subject) {}
using base_type::parse_subject;
// Attribute is a container
template <typename Iterator, typename Context, typename Attribute>
bool parse_subject(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr, traits::container_attribute) const
{
detail::parse_into_container(
this->subject, first, last, context, attr);
return true;
}
// Attribute is an optional
template <typename Iterator, typename Context, typename Attribute>
bool parse_subject(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr, traits::optional_attribute) const
{
typedef typename
x3::traits::optional_value<Attribute>::type
value_type;
// create a local value
value_type val = value_type();
if (this->subject.parse(first, last, context, val))
{
// assign the parsed value into our attribute
x3::traits::move_to(val, attr);
}
return true;
}
};
template <typename Subject>
inline optional<typename extension::as_parser<Subject>::value_type>
operator-(Subject const& subject)
{
return {as_parser(subject)};
}
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Subject, typename Context>
struct attribute_of<x3::optional<Subject>, Context>
: build_optional<
typename attribute_of<Subject, Context>::type> {};
}}}}
#endif

View File

@@ -0,0 +1,62 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_PLUS_MARCH_13_2007_0127PM)
#define SPIRIT_PLUS_MARCH_13_2007_0127PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/core/detail/parse_into_container.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Subject>
struct plus : unary_parser<Subject, plus<Subject>>
{
typedef unary_parser<Subject, plus<Subject>> base_type;
static bool const handles_container = true;
plus(Subject const& subject)
: base_type(subject) {}
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
if (!detail::parse_into_container(
this->subject, first, last, context, attr))
return false;
while (detail::parse_into_container(
this->subject, first, last, context, attr))
;
return true;
}
};
template <typename Subject>
inline plus<typename extension::as_parser<Subject>::value_type>
operator+(Subject const& subject)
{
return {as_parser(subject)};
}
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Subject, typename Context>
struct attribute_of<x3::plus<Subject>, Context>
: build_container<
typename attribute_of<Subject, Context>::type> {};
}}}}
#endif

View File

@@ -0,0 +1,79 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_SEQUENCE_JAN_06_2013_1015AM)
#define SPIRIT_SEQUENCE_JAN_06_2013_1015AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/operator/detail/sequence.hpp>
#include <boost/spirit/home/x3/directive/expect.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename Left, typename Right>
struct sequence : binary_parser<Left, Right, sequence<Left, Right>>
{
typedef binary_parser<Left, Right, sequence<Left, Right>> base_type;
sequence(Left left, Right right)
: base_type(left, right) {}
template <typename Iterator, typename Context>
bool parse(
Iterator& first, Iterator const& last
, Context const& context, unused_type) const
{
Iterator save = first;
if (this->left.parse(first, last, context, unused)
&& this->right.parse(first, last, context, unused))
return true;
first = save;
return false;
}
template <typename Iterator, typename Context, typename Attribute>
bool parse(
Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
return detail::parse_sequence(
this->left, this->right, first, last, context, attr
, typename traits::attribute_category<Attribute>::type());
}
};
template <typename Left, typename Right>
inline sequence<
typename extension::as_parser<Left>::value_type
, typename extension::as_parser<Right>::value_type>
operator>>(Left const& left, Right const& right)
{
return {as_parser(left), as_parser(right)};
}
template <typename Left, typename Right>
inline sequence<
typename extension::as_parser<Left>::value_type
, expect_directive<typename extension::as_parser<Right>::value_type>>
operator>(Left const& left, Right const& right)
{
return {as_parser(left), as_parser(right)};
}
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Left, typename Right, typename Context>
struct attribute_of<x3::sequence<Left, Right>, Context>
: x3::detail::attribute_of_sequence<Left, Right, Context> {};
}}}}
#endif

View File

@@ -0,0 +1,17 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_STRING_FEBRUARY_03_2007_0355PM)
#define BOOST_SPIRIT_X3_STRING_FEBRUARY_03_2007_0355PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/string/literal_string.hpp>
#include <boost/spirit/home/x3/string/symbols.hpp>
#endif

View File

@@ -0,0 +1,89 @@
/*=============================================================================
Copyright (c) 2001-2012 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_STRING_PARSE_APR_18_2006_1125PM)
#define BOOST_SPIRIT_X3_STRING_PARSE_APR_18_2006_1125PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
namespace boost { namespace spirit { namespace x3 { namespace detail
{
template <typename Char, typename Iterator, typename Attribute>
inline bool string_parse(
Char const* str
, Iterator& first, Iterator const& last, Attribute& attr)
{
Iterator i = first;
Char ch = *str;
for (; !!ch; ++i)
{
if (i == last || (ch != *i))
return false;
ch = *++str;
}
x3::traits::move_to(first, i, attr);
first = i;
return true;
}
template <typename String, typename Iterator, typename Attribute>
inline bool string_parse(
String const& str
, Iterator& first, Iterator const& last, Attribute& attr)
{
Iterator i = first;
typename String::const_iterator stri = str.begin();
typename String::const_iterator str_last = str.end();
for (; stri != str_last; ++stri, ++i)
if (i == last || (*stri != *i))
return false;
x3::traits::move_to(first, i, attr);
first = i;
return true;
}
template <typename Char, typename Iterator, typename Attribute>
inline bool string_parse(
Char const* uc_i, Char const* lc_i
, Iterator& first, Iterator const& last, Attribute& attr)
{
Iterator i = first;
for (; *uc_i && *lc_i; ++uc_i, ++lc_i, ++i)
if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
return false;
x3::traits::move_to(first, i, attr);
first = i;
return true;
}
template <typename String, typename Iterator, typename Attribute>
inline bool string_parse(
String const& ucstr, String const& lcstr
, Iterator& first, Iterator const& last, Attribute& attr)
{
typename String::const_iterator uc_i = ucstr.begin();
typename String::const_iterator uc_last = ucstr.end();
typename String::const_iterator lc_i = lcstr.begin();
Iterator i = first;
for (; uc_i != uc_last; ++uc_i, ++lc_i, ++i)
if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
return false;
x3::traits::move_to(first, i, attr);
first = i;
return true;
}
}}}}
#endif

View File

@@ -0,0 +1,213 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_TST_MARCH_09_2007_0905AM)
#define BOOST_SPIRIT_X3_TST_MARCH_09_2007_0905AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/call_traits.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/foreach.hpp>
#include <boost/assert.hpp>
namespace boost { namespace spirit { namespace x3 { namespace detail
{
// This file contains low level TST routines, not for
// public consumption.
template <typename Char, typename T>
struct tst_node
{
tst_node(Char id)
: id(id), data(0), lt(0), eq(0), gt(0)
{
}
template <typename Alloc>
static void
destruct_node(tst_node* p, Alloc* alloc)
{
if (p)
{
if (p->data)
alloc->delete_data(p->data);
destruct_node(p->lt, alloc);
destruct_node(p->eq, alloc);
destruct_node(p->gt, alloc);
alloc->delete_node(p);
}
}
template <typename Alloc>
static tst_node*
clone_node(tst_node* p, Alloc* alloc)
{
if (p)
{
tst_node* clone = alloc->new_node(p->id);
if (p->data)
clone->data = alloc->new_data(*p->data);
clone->lt = clone_node(p->lt, alloc);
clone->eq = clone_node(p->eq, alloc);
clone->gt = clone_node(p->gt, alloc);
return clone;
}
return 0;
}
template <typename Iterator, typename Filter>
static T*
find(tst_node* start, Iterator& first, Iterator last, Filter filter)
{
if (first == last)
return 0;
Iterator i = first;
Iterator latest = first;
tst_node* p = start;
T* found = 0;
while (p && i != last)
{
typename
boost::detail::iterator_traits<Iterator>::value_type
c = filter(*i); // filter only the input
if (c == p->id)
{
if (p->data)
{
found = p->data;
latest = i;
}
p = p->eq;
i++;
}
else if (c < p->id)
{
p = p->lt;
}
else
{
p = p->gt;
}
}
if (found)
first = ++latest; // one past the last matching char
return found;
}
template <typename Iterator, typename Alloc>
static T*
add(
tst_node*& start
, Iterator first
, Iterator last
, typename boost::call_traits<T>::param_type val
, Alloc* alloc)
{
if (first == last)
return 0;
tst_node** pp = &start;
for(;;)
{
typename
boost::detail::iterator_traits<Iterator>::value_type
c = *first;
if (*pp == 0)
*pp = alloc->new_node(c);
tst_node* p = *pp;
if (c == p->id)
{
if (++first == last)
{
if (p->data == 0)
p->data = alloc->new_data(val);
return p->data;
}
pp = &p->eq;
}
else if (c < p->id)
{
pp = &p->lt;
}
else
{
pp = &p->gt;
}
}
}
template <typename Iterator, typename Alloc>
static void
remove(tst_node*& p, Iterator first, Iterator last, Alloc* alloc)
{
if (p == 0 || first == last)
return;
typename
boost::detail::iterator_traits<Iterator>::value_type
c = *first;
if (c == p->id)
{
if (++first == last)
{
if (p->data)
{
alloc->delete_data(p->data);
p->data = 0;
}
}
remove(p->eq, first, last, alloc);
}
else if (c < p->id)
{
remove(p->lt, first, last, alloc);
}
else
{
remove(p->gt, first, last, alloc);
}
if (p->data == 0 && p->lt == 0 && p->eq == 0 && p->gt == 0)
{
alloc->delete_node(p);
p = 0;
}
}
template <typename F>
static void
for_each(tst_node* p, std::basic_string<Char> prefix, F f)
{
if (p)
{
for_each(p->lt, prefix, f);
std::basic_string<Char> s = prefix + p->id;
for_each(p->eq, s, f);
if (p->data)
f(s, *p->data);
for_each(p->gt, prefix, f);
}
}
Char id; // the node's identity character
T* data; // optional data
tst_node* lt; // left pointer
tst_node* eq; // middle pointer
tst_node* gt; // right pointer
};
}}}}
#endif

View File

@@ -0,0 +1,124 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_LITERAL_STRING_APR_18_2006_1125PM)
#define BOOST_SPIRIT_X3_LITERAL_STRING_APR_18_2006_1125PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/string/detail/string_parse.hpp>
#include <boost/spirit/home/x3/support/utility/utf8.hpp>
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
#include <boost/spirit/home/support/char_encoding/standard.hpp>
#include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <string>
namespace boost { namespace spirit { namespace x3
{
template <typename String, typename Encoding,
typename Attribute = std::basic_string<typename Encoding::char_type>>
struct literal_string : parser<literal_string<String, Encoding, Attribute>>
{
typedef typename Encoding::char_type char_type;
typedef Encoding encoding;
typedef Attribute attribute_type;
static bool const has_attribute =
!is_same<unused_type, attribute_type>::value;
static bool const handles_container = true;
literal_string(typename add_reference<String>::type str)
: str(str)
{}
template <typename Iterator, typename Context, typename Attribute_>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute_& attr) const
{
x3::skip_over(first, last, context);
return detail::string_parse(str, first, last, attr);
}
String str;
};
namespace standard
{
inline literal_string<char const*, char_encoding::standard>
string(char const* s)
{
return literal_string<char const*, char_encoding::standard>(s);
}
}
using standard::string;
namespace extension
{
template <int N>
struct as_parser<char[N]>
{
typedef
literal_string<
char const*, char_encoding::standard, unused_type>
type;
typedef type value_type;
static type call(char const* s)
{
return type(s);
}
};
template <int N>
struct as_parser<char const[N]> : as_parser<char[N]> {};
template <int N>
struct as_parser<wchar_t[N]>
{
typedef
literal_string<
wchar_t const*, char_encoding::standard_wide, unused_type>
type;
typedef type value_type;
static type call(wchar_t const* s)
{
return type(s);
}
};
template <int N>
struct as_parser<wchar_t const[N]> : as_parser<wchar_t[N]> {};
}
using standard::string;
inline literal_string<char const*, char_encoding::standard, unused_type>
lit(char const* s)
{
return literal_string<char const*, char_encoding::standard, unused_type>(s);
}
template <typename String, typename Encoding, typename Attribute>
struct get_info<literal_string<String, Encoding, Attribute>>
{
typedef std::string result_type;
std::string operator()(literal_string<String, Encoding, Attribute> const& p) const
{
return '"' + to_utf8(p.str) + '"';
}
};
}}}
#endif

View File

@@ -0,0 +1,358 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2013 Carl Barron
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_SYMBOLS_MARCH_11_2007_1055AM)
#define BOOST_SPIRIT_X3_SYMBOLS_MARCH_11_2007_1055AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/core/skip_over.hpp>
#include <boost/spirit/home/x3/core/parser.hpp>
#include <boost/spirit/home/x3/string/tst.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/traits/string_traits.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/range.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/shared_ptr.hpp>
#include <initializer_list>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
#endif
namespace boost { namespace spirit { namespace x3
{
template <
typename Char = char
, typename T = unused_type
, typename Lookup = tst<Char, T>
, typename Filter = tst_pass_through>
struct symbols : parser<symbols<Char, T, Lookup, Filter>>
{
typedef Char char_type; // the character type
typedef T value_type; // the value associated with each entry
typedef symbols<Char, T, Lookup, Filter> this_type;
typedef value_type attribute_type;
static bool const has_attribute =
!is_same<unused_type, attribute_type>::value;
static bool const handles_container =
traits::is_container<attribute_type>::value;
symbols(std::string const& name = "symbols")
: add(*this)
, remove(*this)
, lookup(new Lookup())
, name_(name)
{
}
symbols(symbols const& syms)
: add(*this)
, remove(*this)
, lookup(syms.lookup)
, name_(syms.name_)
{
}
template <typename Filter_>
symbols(symbols<Char, T, Lookup, Filter_> const& syms)
: add(*this)
, remove(*this)
, lookup(syms.lookup)
, name_(syms.name_)
{
}
template <typename Symbols>
symbols(Symbols const& syms, std::string const& name = "symbols")
: add(*this)
, remove(*this)
, lookup(new Lookup())
, name_(name)
{
typename range_const_iterator<Symbols>::type si = boost::begin(syms);
while (si != boost::end(syms))
add(*si++);
}
template <typename Symbols, typename Data>
symbols(Symbols const& syms, Data const& data
, std::string const& name = "symbols")
: add(*this)
, remove(*this)
, lookup(new Lookup())
, name_(name)
{
typename range_const_iterator<Symbols>::type si = boost::begin(syms);
typename range_const_iterator<Data>::type di = boost::begin(data);
while (si != boost::end(syms))
add(*si++, *di++);
}
symbols(std::initializer_list<std::pair<Char const*, T>> syms
, std::string const & name="symbols")
: add(*this)
, remove(*this)
, lookup(new Lookup())
, name_(name)
{
typedef std::initializer_list<std::pair<Char const*, T>> symbols_t;
typename range_const_iterator<symbols_t>::type si = boost::begin(syms);
for (;si != boost::end(syms); ++si)
add(si->first, si->second);
}
symbols(std::initializer_list<Char const*> syms
, std::string const &name="symbols")
: add(*this)
, remove(*this)
, lookup(new Lookup())
, name_(name)
{
typedef std::initializer_list<Char const*> symbols_t;
typename range_const_iterator<symbols_t>::type si = boost::begin(syms);
while (si != boost::end(syms))
add(*si++);
}
symbols&
operator=(symbols const& rhs)
{
name_ = rhs.name_;
lookup = rhs.lookup;
return *this;
}
template <typename Filter_>
symbols&
operator=(symbols<Char, T, Lookup, Filter_> const& rhs)
{
name_ = rhs.name_;
lookup = rhs.lookup;
return *this;
}
void clear()
{
lookup->clear();
}
struct adder;
struct remover;
template <typename Str>
adder const&
operator=(Str const& str)
{
lookup->clear();
return add(str);
}
template <typename Str>
friend adder const&
operator+=(symbols& sym, Str const& str)
{
return sym.add(str);
}
template <typename Str>
friend remover const&
operator-=(symbols& sym, Str const& str)
{
return sym.remove(str);
}
template <typename F>
void for_each(F f) const
{
lookup->for_each(f);
}
template <typename Str>
value_type& at(Str const& str)
{
return *lookup->add(traits::get_string_begin<Char>(str)
, traits::get_string_end<Char>(str), T());
}
template <typename Iterator>
value_type* prefix_find(Iterator& first, Iterator const& last)
{
return lookup->find(first, last, Filter());
}
template <typename Iterator>
value_type const* prefix_find(Iterator& first, Iterator const& last) const
{
return lookup->find(first, last, Filter());
}
template <typename Str>
value_type* find(Str const& str)
{
return find_impl(traits::get_string_begin<Char>(str)
, traits::get_string_end<Char>(str));
}
template <typename Str>
value_type const* find(Str const& str) const
{
return find_impl(traits::get_string_begin<Char>(str)
, traits::get_string_end<Char>(str));
}
private:
template <typename Iterator>
value_type* find_impl(Iterator begin, Iterator end)
{
value_type* r = lookup->find(begin, end, Filter());
return begin == end ? r : 0;
}
template <typename Iterator>
value_type const* find_impl(Iterator begin, Iterator end) const
{
value_type const* r = lookup->find(begin, end, Filter());
return begin == end ? r : 0;
}
public:
template <typename Iterator, typename Context, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context const& context, Attribute& attr) const
{
x3::skip_over(first, last, context);
if (value_type* val_ptr
= lookup->find(first, last, Filter()))
{
x3::traits::move_to(*val_ptr, attr);
return true;
}
return false;
}
void name(std::string const &str)
{
name_ = str;
}
std::string const &name() const
{
return name_;
}
struct adder
{
template <typename, typename = unused_type, typename = unused_type>
struct result { typedef adder const& type; };
adder(symbols& sym)
: sym(sym)
{
}
template <typename Iterator>
adder const&
operator()(Iterator first, Iterator last, T const& val) const
{
sym.lookup->add(first, last, val);
return *this;
}
template <typename Str>
adder const&
operator()(Str const& s, T const& val = T()) const
{
sym.lookup->add(traits::get_string_begin<Char>(s)
, traits::get_string_end<Char>(s), val);
return *this;
}
template <typename Str>
adder const&
operator,(Str const& s) const
{
sym.lookup->add(traits::get_string_begin<Char>(s)
, traits::get_string_end<Char>(s), T());
return *this;
}
symbols& sym;
};
struct remover
{
template <typename, typename = unused_type, typename = unused_type>
struct result { typedef remover const& type; };
remover(symbols& sym)
: sym(sym)
{
}
template <typename Iterator>
remover const&
operator()(Iterator const& first, Iterator const& last) const
{
sym.lookup->remove(first, last);
return *this;
}
template <typename Str>
remover const&
operator()(Str const& s) const
{
sym.lookup->remove(traits::get_string_begin<Char>(s)
, traits::get_string_end<Char>(s));
return *this;
}
template <typename Str>
remover const&
operator,(Str const& s) const
{
sym.lookup->remove(traits::get_string_begin<Char>(s)
, traits::get_string_end<Char>(s));
return *this;
}
symbols& sym;
};
adder add;
remover remove;
shared_ptr<Lookup> lookup;
std::string name_;
};
template <typename Char, typename T, typename Lookup, typename Filter>
struct get_info<symbols<Char, T, Lookup, Filter>>
{
typedef std::string result_type;
result_type operator()(symbols< Char, T
, Lookup, Filter
> const& symbols) const
{
return symbols.name();
}
};
}}}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#endif

View File

@@ -0,0 +1,137 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_TST_JUNE_03_2007_1031AM)
#define BOOST_SPIRIT_X3_TST_JUNE_03_2007_1031AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/string/detail/tst.hpp>
namespace boost { namespace spirit { namespace x3
{
struct tst_pass_through
{
template <typename Char>
Char operator()(Char ch) const
{
return ch;
}
};
template <typename Char, typename T>
struct tst
{
typedef Char char_type; // the character type
typedef T value_type; // the value associated with each entry
typedef detail::tst_node<Char, T> node;
tst()
: root(0)
{
}
~tst()
{
clear();
}
tst(tst const& rhs)
: root(0)
{
copy(rhs);
}
tst& operator=(tst const& rhs)
{
return assign(rhs);
}
template <typename Iterator, typename Filter>
T* find(Iterator& first, Iterator last, Filter filter) const
{
return node::find(root, first, last, filter);
}
template <typename Iterator>
T* find(Iterator& first, Iterator last) const
{
return find(first, last, tst_pass_through());
}
template <typename Iterator>
T* add(
Iterator first
, Iterator last
, typename boost::call_traits<T>::param_type val)
{
return node::add(root, first, last, val, this);
}
template <typename Iterator>
void remove(Iterator first, Iterator last)
{
node::remove(root, first, last, this);
}
void clear()
{
node::destruct_node(root, this);
root = 0;
}
template <typename F>
void for_each(F f) const
{
node::for_each(root, std::basic_string<Char>(), f);
}
private:
friend struct detail::tst_node<Char, T>;
void copy(tst const& rhs)
{
root = node::clone_node(rhs.root, this);
}
tst& assign(tst const& rhs)
{
if (this != &rhs)
{
clear();
copy(rhs);
}
return *this;
}
node* root;
node* new_node(Char id)
{
return new node(id);
}
T* new_data(typename boost::call_traits<T>::param_type val)
{
return new T(val);
}
void delete_node(node* p)
{
delete p;
}
void delete_data(T* p)
{
delete p;
}
};
}}}
#endif

View File

@@ -0,0 +1,216 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_TST_MAP_JUNE_03_2007_1143AM)
#define BOOST_SPIRIT_X3_TST_MAP_JUNE_03_2007_1143AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/string/detail/tst.hpp>
#include <unordered_map>
#include <boost/pool/object_pool.hpp>
namespace boost { namespace spirit { namespace x3
{
struct tst_pass_through; // declared in tst.hpp
template <typename Char, typename T>
struct tst_map
{
typedef Char char_type; // the character type
typedef T value_type; // the value associated with each entry
typedef detail::tst_node<Char, T> node;
tst_map()
{
}
~tst_map()
{
// Nothing to do here.
// The pools do the right thing for us
}
tst_map(tst_map const& rhs)
{
copy(rhs);
}
tst_map& operator=(tst_map const& rhs)
{
return assign(rhs);
}
template <typename Iterator, typename Filter>
T* find(Iterator& first, Iterator last, Filter filter) const
{
if (first != last)
{
Iterator save = first;
typename map_type::const_iterator
i = map.find(filter(*first++));
if (i == map.end())
{
first = save;
return 0;
}
if (T* p = node::find(i->second.root, first, last, filter))
{
return p;
}
return i->second.data;
}
return 0;
}
template <typename Iterator>
T* find(Iterator& first, Iterator last) const
{
return find(first, last, tst_pass_through());
}
template <typename Iterator>
bool add(
Iterator first
, Iterator last
, typename boost::call_traits<T>::param_type val)
{
if (first != last)
{
map_data x = {0, 0};
std::pair<typename map_type::iterator, bool>
r = map.insert(std::pair<Char, map_data>(*first++, x));
if (first != last)
{
return node::add(r.first->second.root
, first, last, val, this) ? true : false;
}
else
{
if (r.first->second.data)
return false;
r.first->second.data = this->new_data(val);
}
return true;
}
return false;
}
template <typename Iterator>
void remove(Iterator first, Iterator last)
{
if (first != last)
{
typename map_type::iterator i = map.find(*first++);
if (i != map.end())
{
if (first != last)
{
node::remove(i->second.root, first, last, this);
}
else if (i->second.data)
{
this->delete_data(i->second.data);
i->second.data = 0;
}
if (i->second.data == 0 && i->second.root == 0)
{
map.erase(i);
}
}
}
}
void clear()
{
BOOST_FOREACH(typename map_type::value_type& x, map)
{
node::destruct_node(x.second.root, this);
if (x.second.data)
this->delete_data(x.second.data);
}
map.clear();
}
template <typename F>
void for_each(F f) const
{
BOOST_FOREACH(typename map_type::value_type const& x, map)
{
std::basic_string<Char> s(1, x.first);
node::for_each(x.second.root, s, f);
if (x.second.data)
f(s, *x.second.data);
}
}
private:
friend struct detail::tst_node<Char, T>;
struct map_data
{
node* root;
T* data;
};
typedef std::unordered_map<Char, map_data> map_type;
void copy(tst_map const& rhs)
{
BOOST_FOREACH(typename map_type::value_type const& x, rhs.map)
{
map_data xx = {node::clone_node(x.second.root, this), 0};
if (x.second.data)
xx.data = data_pool.construct(*x.second.data);
map[x.first] = xx;
}
}
tst_map& assign(tst_map const& rhs)
{
if (this != &rhs)
{
BOOST_FOREACH(typename map_type::value_type& x, map)
{
node::destruct_node(x.second.root, this);
}
map.clear();
copy(rhs);
}
return *this;
}
node* new_node(Char id)
{
return node_pool.construct(id);
}
T* new_data(typename boost::call_traits<T>::param_type val)
{
return data_pool.construct(val);
}
void delete_node(node* p)
{
node_pool.destroy(p);
}
void delete_data(T* p)
{
data_pool.destroy(p);
}
map_type map;
object_pool<node> node_pool;
object_pool<T> data_pool;
};
}}}
#endif

View File

@@ -0,0 +1,110 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_CONTEXT_JAN_4_2012_1215PM)
#define BOOST_SPIRIT_X3_CONTEXT_JAN_4_2012_1215PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/mpl/identity.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename ID, typename T, typename Next = unused_type>
struct context
{
context(T& val, Next const& next)
: val(val), next(next) {}
template <typename ID_, typename Unused = void>
struct get_result
{
typedef typename Next::template get_result<ID_>::type type;
};
template <typename Unused>
struct get_result<mpl::identity<ID>, Unused>
{
typedef T& type;
};
T& get(mpl::identity<ID>) const
{
return val;
}
template <typename ID_>
typename Next::template get_result<ID_>::type
get(ID_ id) const
{
return next.get(id);
}
T& val;
Next const& next;
};
template <typename ID, typename T>
struct context<ID, T, unused_type>
{
context(T& val)
: val(val) {}
context(T& val, unused_type)
: val(val) {}
template <typename ID_, typename Unused = void>
struct get_result
{
typedef unused_type type;
};
template <typename Unused>
struct get_result<mpl::identity<ID>, Unused>
{
typedef T& type;
};
T& get(mpl::identity<ID>) const
{
return val;
}
template <typename ID_>
unused_type
get(ID_) const
{
return unused;
}
T& val;
};
template <typename Tag, typename Context>
inline auto
get(Context const& context) -> decltype(context.get(mpl::identity<Tag>()))
{
return context.get(mpl::identity<Tag>());
}
template <typename ID, typename T, typename Next>
inline context<ID, T, Next> make_context(T& val, Next const& next)
{
return context<ID, T, Next>(val, next);
}
template <typename ID, typename T>
inline context<ID, T> make_context(T& val)
{
return context<ID, T>(val);
}
}}}
#endif

View File

@@ -0,0 +1,512 @@
/*=============================================================================
Copyright (c) 2001-2012 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2011 Jan Frederick Eick
Copyright (c) 2011 Christopher Jefferson
Copyright (c) 2006 Stephen Nutt
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_DETAIL_EXTRACT_INT_APRIL_17_2006_0816AM)
#define BOOST_SPIRIT_X3_DETAIL_EXTRACT_INT_APRIL_17_2006_0816AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_type.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/spirit/home/x3/support/traits/numeric_traits.hpp>
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/comparison/less.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_signed.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/and.hpp>
#include <boost/limits.hpp>
#if !defined(SPIRIT_NUMERICS_LOOP_UNROLL)
# define SPIRIT_NUMERICS_LOOP_UNROLL 3
#endif
namespace boost { namespace spirit { namespace x3 { namespace detail
{
///////////////////////////////////////////////////////////////////////////
//
// The maximum radix digits that can be represented without
// overflow:
//
// template<typename T, unsigned Radix>
// struct digits_traits::value;
//
///////////////////////////////////////////////////////////////////////////
template <typename T, unsigned Radix>
struct digits_traits;
// lookup table for log2(x) : 2 <= x <= 36
#define BOOST_SPIRIT_X3_LOG2 (#error)(#error) \
(1000000)(1584960)(2000000)(2321920)(2584960)(2807350) \
(3000000)(3169920)(3321920)(3459430)(3584960)(3700430) \
(3807350)(3906890)(4000000)(4087460)(4169920)(4247920) \
(4321920)(4392310)(4459430)(4523560)(4584960)(4643850) \
(4700430)(4754880)(4807350)(4857980)(4906890)(4954190) \
(5000000)(5044390)(5087460)(5129280)(5169925) \
/***/
#define BOOST_PP_LOCAL_MACRO(Radix) \
template <typename T> struct digits_traits<T, Radix> \
{ \
typedef std::numeric_limits<T> numeric_limits_type; \
BOOST_STATIC_CONSTANT(int, value = static_cast<int>( \
(numeric_limits_type::digits * 1000000) / \
BOOST_PP_SEQ_ELEM(Radix, BOOST_SPIRIT_X3_LOG2))); \
}; \
/***/
#define BOOST_PP_LOCAL_LIMITS (2, 36)
#include BOOST_PP_LOCAL_ITERATE()
#undef BOOST_SPIRIT_X3_LOG2
///////////////////////////////////////////////////////////////////////////
//
// Traits class for radix specific number conversion
//
// Test the validity of a single character:
//
// template<typename Char> static bool is_valid(Char ch);
//
// Convert a digit from character representation to binary
// representation:
//
// template<typename Char> static int digit(Char ch);
//
///////////////////////////////////////////////////////////////////////////
template <unsigned Radix>
struct radix_traits
{
template <typename Char>
inline static bool is_valid(Char ch)
{
if (Radix <= 10)
return (ch >= '0' && ch <= static_cast<Char>('0' + Radix -1));
return (ch >= '0' && ch <= '9')
|| (ch >= 'a' && ch <= static_cast<Char>('a' + Radix -10 -1))
|| (ch >= 'A' && ch <= static_cast<Char>('A' + Radix -10 -1));
}
template <typename Char>
inline static unsigned digit(Char ch)
{
if (Radix <= 10 || (ch >= '0' && ch <= '9'))
return ch - '0';
return char_encoding::ascii::tolower(ch) - 'a' + 10;
}
};
///////////////////////////////////////////////////////////////////////////
// positive_accumulator/negative_accumulator: Accumulator policies for
// extracting integers. Use positive_accumulator if number is positive.
// Use negative_accumulator if number is negative.
///////////////////////////////////////////////////////////////////////////
template <unsigned Radix>
struct positive_accumulator
{
template <typename T, typename Char>
inline static void add(T& n, Char ch, mpl::false_) // unchecked add
{
const int digit = radix_traits<Radix>::digit(ch);
n = n * T(Radix) + T(digit);
}
template <typename T, typename Char>
inline static bool add(T& n, Char ch, mpl::true_) // checked add
{
// Ensure n *= Radix will not overflow
static T const max = (std::numeric_limits<T>::max)();
static T const val = max / Radix;
if (n > val)
return false;
n *= Radix;
// Ensure n += digit will not overflow
const int digit = radix_traits<Radix>::digit(ch);
if (n > max - digit)
return false;
n += static_cast<T>(digit);
return true;
}
};
template <unsigned Radix>
struct negative_accumulator
{
template <typename T, typename Char>
inline static void add(T& n, Char ch, mpl::false_) // unchecked subtract
{
const int digit = radix_traits<Radix>::digit(ch);
n = n * T(Radix) - T(digit);
}
template <typename T, typename Char>
inline static bool add(T& n, Char ch, mpl::true_) // checked subtract
{
// Ensure n *= Radix will not underflow
static T const min = (std::numeric_limits<T>::min)();
static T const val = (min + 1) / T(Radix);
if (n < val)
return false;
n *= Radix;
// Ensure n -= digit will not underflow
int const digit = radix_traits<Radix>::digit(ch);
if (n < min + digit)
return false;
n -= static_cast<T>(digit);
return true;
}
};
///////////////////////////////////////////////////////////////////////////
// Common code for extract_int::parse specializations
///////////////////////////////////////////////////////////////////////////
template <unsigned Radix, typename Accumulator, int MaxDigits>
struct int_extractor
{
template <typename Char, typename T>
inline static bool
call(Char ch, std::size_t count, T& n, mpl::true_)
{
static std::size_t const
overflow_free = digits_traits<T, Radix>::value - 1;
if (count < overflow_free)
{
Accumulator::add(n, ch, mpl::false_());
}
else
{
if (!Accumulator::add(n, ch, mpl::true_()))
return false; // over/underflow!
}
return true;
}
template <typename Char, typename T>
inline static bool
call(Char ch, std::size_t /*count*/, T& n, mpl::false_)
{
// no need to check for overflow
Accumulator::add(n, ch, mpl::false_());
return true;
}
template <typename Char>
inline static bool
call(Char /*ch*/, std::size_t /*count*/, unused_type, mpl::false_)
{
return true;
}
template <typename Char, typename T>
inline static bool
call(Char ch, std::size_t count, T& n)
{
return call(ch, count, n
, mpl::bool_<
( (MaxDigits < 0)
|| (MaxDigits > digits_traits<T, Radix>::value)
)
&& traits::check_overflow<T>::value
>()
);
}
};
///////////////////////////////////////////////////////////////////////////
// End of loop checking: check if the number of digits
// being parsed exceeds MaxDigits. Note: if MaxDigits == -1
// we don't do any checking.
///////////////////////////////////////////////////////////////////////////
template <int MaxDigits>
struct check_max_digits
{
inline static bool
call(std::size_t count)
{
return count < MaxDigits; // bounded
}
};
template <>
struct check_max_digits<-1>
{
inline static bool
call(std::size_t /*count*/)
{
return true; // unbounded
}
};
///////////////////////////////////////////////////////////////////////////
// extract_int: main code for extracting integers
///////////////////////////////////////////////////////////////////////////
#define SPIRIT_NUMERIC_INNER_LOOP(z, x, data) \
if (!check_max_digits<MaxDigits>::call(count + leading_zeros) \
|| it == last) \
break; \
ch = *it; \
if (!radix_check::is_valid(ch) || !extractor::call(ch, count, val)) \
break; \
++it; \
++count; \
/**/
template <
typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
, typename Accumulator = positive_accumulator<Radix>
, bool Accumulate = false
>
struct extract_int
{
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
#endif
template <typename Iterator, typename Attribute>
inline static bool
parse_main(
Iterator& first
, Iterator const& last
, Attribute& attr)
{
typedef radix_traits<Radix> radix_check;
typedef int_extractor<Radix, Accumulator, MaxDigits> extractor;
typedef typename
boost::detail::iterator_traits<Iterator>::value_type
char_type;
Iterator it = first;
std::size_t leading_zeros = 0;
if (!Accumulate)
{
// skip leading zeros
while (it != last && *it == '0' && leading_zeros < MaxDigits)
{
++it;
++leading_zeros;
}
}
typedef typename
traits::attribute_type<Attribute>::type
attribute_type;
attribute_type val = Accumulate ? attr : attribute_type(0);
std::size_t count = 0;
char_type ch;
while (true)
{
BOOST_PP_REPEAT(
SPIRIT_NUMERICS_LOOP_UNROLL
, SPIRIT_NUMERIC_INNER_LOOP, _)
}
if (count + leading_zeros >= MinDigits)
{
traits::move_to(val, attr);
first = it;
return true;
}
return false;
}
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(pop)
#endif
template <typename Iterator>
inline static bool
parse(
Iterator& first
, Iterator const& last
, unused_type)
{
T n = 0; // must calculate value to detect over/underflow
return parse_main(first, last, n);
}
template <typename Iterator, typename Attribute>
inline static bool
parse(
Iterator& first
, Iterator const& last
, Attribute& attr)
{
return parse_main(first, last, attr);
}
};
#undef SPIRIT_NUMERIC_INNER_LOOP
///////////////////////////////////////////////////////////////////////////
// extract_int: main code for extracting integers
// common case where MinDigits == 1 and MaxDigits = -1
///////////////////////////////////////////////////////////////////////////
#define SPIRIT_NUMERIC_INNER_LOOP(z, x, data) \
if (it == last) \
break; \
ch = *it; \
if (!radix_check::is_valid(ch)) \
break; \
if (!extractor::call(ch, count, val)) \
return false; \
++it; \
++count; \
/**/
template <typename T, unsigned Radix, typename Accumulator, bool Accumulate>
struct extract_int<T, Radix, 1, -1, Accumulator, Accumulate>
{
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
#endif
template <typename Iterator, typename Attribute>
inline static bool
parse_main(
Iterator& first
, Iterator const& last
, Attribute& attr)
{
typedef radix_traits<Radix> radix_check;
typedef int_extractor<Radix, Accumulator, -1> extractor;
typedef typename
boost::detail::iterator_traits<Iterator>::value_type
char_type;
Iterator it = first;
std::size_t count = 0;
if (!Accumulate)
{
// skip leading zeros
while (it != last && *it == '0')
{
++it;
++count;
}
if (it == last)
{
if (count == 0) // must have at least one digit
return false;
attr = 0;
first = it;
return true;
}
}
typedef typename
traits::attribute_type<Attribute>::type
attribute_type;
attribute_type val = Accumulate ? attr : attribute_type(0);
char_type ch = *it;
if (!radix_check::is_valid(ch) || !extractor::call(ch, 0, val))
{
if (count == 0) // must have at least one digit
return false;
traits::move_to(val, attr);
first = it;
return true;
}
count = 0;
++it;
while (true)
{
BOOST_PP_REPEAT(
SPIRIT_NUMERICS_LOOP_UNROLL
, SPIRIT_NUMERIC_INNER_LOOP, _)
}
traits::move_to(val, attr);
first = it;
return true;
}
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(pop)
#endif
template <typename Iterator>
inline static bool
parse(
Iterator& first
, Iterator const& last
, unused_type)
{
T n = 0; // must calculate value to detect over/underflow
return parse_main(first, last, n);
}
template <typename Iterator, typename Attribute>
inline static bool
parse(
Iterator& first
, Iterator const& last
, Attribute& attr)
{
return parse_main(first, last, attr);
}
};
#undef SPIRIT_NUMERIC_INNER_LOOP
///////////////////////////////////////////////////////////////////////////
// Cast an signed integer to an unsigned integer
///////////////////////////////////////////////////////////////////////////
template <typename T,
bool force_unsigned
= mpl::and_<is_integral<T>, is_signed<T> >::value>
struct cast_unsigned;
template <typename T>
struct cast_unsigned<T, true>
{
typedef typename make_unsigned<T>::type unsigned_type;
typedef typename make_unsigned<T>::type& unsigned_type_ref;
inline static unsigned_type_ref call(T& n)
{
return unsigned_type_ref(n);
}
};
template <typename T>
struct cast_unsigned<T, false>
{
inline static T& call(T& n)
{
return n;
}
};
}}}}
#endif

View File

@@ -0,0 +1,147 @@
/*=============================================================================
Copyright (c) 2001-2012 Joel de Guzman
Copyright (c) 2011 Jan Frederick Eick
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_EXTRACT_INT_APRIL_17_2006_0830AM)
#define BOOST_SPIRIT_X3_EXTRACT_INT_APRIL_17_2006_0830AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/detail/extract_int.hpp>
#include <boost/assert.hpp>
namespace boost { namespace spirit { namespace x3
{
///////////////////////////////////////////////////////////////////////////
// Extract the prefix sign (- or +), return true if a '-' was found
///////////////////////////////////////////////////////////////////////////
template <typename Iterator>
inline bool
extract_sign(Iterator& first, Iterator const& last)
{
(void)last; // silence unused warnings
BOOST_ASSERT(first != last); // precondition
// Extract the sign
bool neg = *first == '-';
if (neg || (*first == '+'))
{
++first;
return neg;
}
return false;
}
///////////////////////////////////////////////////////////////////////////
// Low level unsigned integer parser
///////////////////////////////////////////////////////////////////////////
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
, bool Accumulate = false>
struct extract_uint
{
// check template parameter 'Radix' for validity
static_assert(
(Radix >= 2 && Radix <= 36),
"Error Unsupported Radix");
template <typename Iterator>
inline static bool call(Iterator& first, Iterator const& last, T& attr)
{
if (first == last)
return false;
typedef detail::extract_int<
T
, Radix
, MinDigits
, MaxDigits
, detail::positive_accumulator<Radix>
, Accumulate>
extract_type;
Iterator save = first;
if (!extract_type::parse(first, last,
detail::cast_unsigned<T>::call(attr)))
{
first = save;
return false;
}
return true;
}
template <typename Iterator, typename Attribute>
inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
{
// this case is called when Attribute is not T
T attr;
if (call(first, last, attr))
{
traits::move_to(attr, attr_);
return true;
}
return false;
}
};
///////////////////////////////////////////////////////////////////////////
// Low level signed integer parser
///////////////////////////////////////////////////////////////////////////
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
struct extract_int
{
// check template parameter 'Radix' for validity
static_assert(
(Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16),
"Error Unsupported Radix");
template <typename Iterator>
inline static bool call(Iterator& first, Iterator const& last, T& attr)
{
if (first == last)
return false;
typedef detail::extract_int<
T, Radix, MinDigits, MaxDigits>
extract_pos_type;
typedef detail::extract_int<
T, Radix, MinDigits, MaxDigits, detail::negative_accumulator<Radix> >
extract_neg_type;
Iterator save = first;
bool hit = extract_sign(first, last);
if (hit)
hit = extract_neg_type::parse(first, last, attr);
else
hit = extract_pos_type::parse(first, last, attr);
if (!hit)
{
first = save;
return false;
}
return true;
}
template <typename Iterator, typename Attribute>
inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
{
// this case is called when Attribute is not T
T attr;
if (call(first, last, attr))
{
traits::move_to(attr, attr_);
return true;
}
return false;
}
};
}}}
#endif

View File

@@ -0,0 +1,271 @@
/*=============================================================================
Copyright (c) 2001-2012 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_EXTRACT_REAL_APRIL_18_2006_0901AM)
#define SPIRIT_EXTRACT_REAL_APRIL_18_2006_0901AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <cmath>
#include <boost/limits.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/pow10.hpp>
#include <boost/spirit/home/x3/support/numeric_utils/sign.hpp>
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
#include <boost/assert.hpp>
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(push)
# pragma warning(disable: 4100) // 'p': unreferenced formal parameter
# pragma warning(disable: 4127) // conditional expression is constant
#endif
namespace boost { namespace spirit { namespace x3 { namespace extension
{
using x3::traits::pow10;
template <typename T>
inline void
scale(int exp, T& n)
{
if (exp >= 0)
{
// $$$ Why is this failing for boost.math.concepts ? $$$
//~ int nn = std::numeric_limits<T>::max_exponent10;
//~ BOOST_ASSERT(exp <= std::numeric_limits<T>::max_exponent10);
n *= pow10<T>(exp);
}
else
{
if (exp < std::numeric_limits<T>::min_exponent10)
{
n /= pow10<T>(-std::numeric_limits<T>::min_exponent10);
n /= pow10<T>(-exp + std::numeric_limits<T>::min_exponent10);
}
else
{
n /= pow10<T>(-exp);
}
}
}
inline void
scale(int /*exp*/, unused_type /*n*/)
{
// no-op for unused_type
}
template <typename T>
inline void
scale(int exp, int frac, T& n)
{
scale(exp - frac, n);
}
inline void
scale(int /*exp*/, int /*frac*/, unused_type /*n*/)
{
// no-op for unused_type
}
inline float
negate(bool neg, float n)
{
return neg ? x3::changesign(n) : n;
}
inline double
negate(bool neg, double n)
{
return neg ? x3::changesign(n) : n;
}
inline long double
negate(bool neg, long double n)
{
return neg ? x3::changesign(n) : n;
}
template <typename T>
inline T
negate(bool neg, T const& n)
{
return neg ? -n : n;
}
inline unused_type
negate(bool /*neg*/, unused_type n)
{
// no-op for unused_type
return n;
}
template <typename T>
inline bool
is_equal_to_one(T const& value)
{
return value == 1.0;
}
inline bool
is_equal_to_one(unused_type)
{
// no-op for unused_type
return false;
}
}}}}
namespace boost { namespace spirit { namespace x3
{
template <typename T, typename RealPolicies>
struct extract_real
{
template <typename Iterator, typename Attribute>
static bool
parse(Iterator& first, Iterator const& last, Attribute& attr,
RealPolicies const& p)
{
if (first == last)
return false;
Iterator save = first;
// Start by parsing the sign. neg will be true if
// we got a "-" sign, false otherwise.
bool neg = p.parse_sign(first, last);
// Now attempt to parse an integer
T n = 0;
bool got_a_number = p.parse_n(first, last, n);
// If we did not get a number it might be a NaN, Inf or a leading
// dot.
if (!got_a_number)
{
// Check whether the number to parse is a NaN or Inf
if (p.parse_nan(first, last, n) ||
p.parse_inf(first, last, n))
{
// If we got a negative sign, negate the number
traits::move_to(extension::negate(neg, n), attr);
return true; // got a NaN or Inf, return early
}
// If we did not get a number and our policies do not
// allow a leading dot, fail and return early (no-match)
if (!p.allow_leading_dot)
{
first = save;
return false;
}
}
bool e_hit = false;
int frac_digits = 0;
// Try to parse the dot ('.' decimal point)
if (p.parse_dot(first, last))
{
// We got the decimal point. Now we will try to parse
// the fraction if it is there. If not, it defaults
// to zero (0) only if we already got a number.
Iterator savef = first;
if (p.parse_frac_n(first, last, n))
{
// Optimization note: don't compute frac_digits if T is
// an unused_type. This should be optimized away by the compiler.
if (!is_same<T, unused_type>::value)
frac_digits =
static_cast<int>(std::distance(savef, first));
}
else if (!got_a_number || !p.allow_trailing_dot)
{
// We did not get a fraction. If we still haven't got a
// number and our policies do not allow a trailing dot,
// return no-match.
first = save;
return false;
}
// Now, let's see if we can parse the exponent prefix
e_hit = p.parse_exp(first, last);
}
else
{
// No dot and no number! Return no-match.
if (!got_a_number)
{
first = save;
return false;
}
// If we must expect a dot and we didn't see an exponent
// prefix, return no-match.
e_hit = p.parse_exp(first, last);
if (p.expect_dot && !e_hit)
{
first = save;
return false;
}
}
if (e_hit)
{
// We got the exponent prefix. Now we will try to parse the
// actual exponent. It is an error if it is not there.
int exp = 0;
if (p.parse_exp_n(first, last, exp))
{
// Got the exponent value. Scale the number by
// exp-frac_digits.
extension::scale(exp, frac_digits, n);
}
else
{
// Oops, no exponent, return no-match.
first = save;
return false;
}
}
else if (frac_digits)
{
// No exponent found. Scale the number by -frac_digits.
extension::scale(-frac_digits, n);
}
else if (extension::is_equal_to_one(n))
{
// There is a chance of having to parse one of the 1.0#...
// styles some implementations use for representing NaN or Inf.
// Check whether the number to parse is a NaN or Inf
if (p.parse_nan(first, last, n) ||
p.parse_inf(first, last, n))
{
// If we got a negative sign, negate the number
traits::move_to(extension::negate(neg, n), attr);
return true; // got a NaN or Inf, return immediately
}
}
// If we got a negative sign, negate the number
traits::move_to(extension::negate(neg, n), attr);
// Success!!!
return true;
}
};
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(pop)
#endif
}}}
#endif

View File

@@ -0,0 +1,116 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_POW10_DECEMBER_26_2008_1118AM)
#define BOOST_SPIRIT_X3_POW10_DECEMBER_26_2008_1118AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config/no_tr1/cmath.hpp>
#include <boost/limits.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/spirit/home/x3/support/traits/numeric_traits.hpp>
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(push)
# pragma warning(disable: 4244) // conversion from 'double' to 'float', possible loss of data
#endif
namespace boost { namespace spirit { namespace x3 { namespace traits
{
namespace detail
{
template <typename T, typename Enable = void>
struct pow10_helper
{
static T call(unsigned dim)
{
using namespace std; // allow for ADL to find the correct overload
return pow(T(10), T(dim));
}
};
template <>
struct pow10_helper<unused_type>
{
static unused_type call(unused_type)
{
return unused;
}
};
#if (DBL_MAX_10_EXP == 308) // for IEEE-754
template <>
struct pow10_helper<double>
{
static double call(unsigned dim)
{
static double const exponents[] =
{
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49,
1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59,
1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69,
1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79,
1e80, 1e81, 1e82, 1e83, 1e84, 1e85, 1e86, 1e87, 1e88, 1e89,
1e90, 1e91, 1e92, 1e93, 1e94, 1e95, 1e96, 1e97, 1e98, 1e99,
1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,
1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,
1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,
1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,
1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,
1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,
1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,
1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,
1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,
1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,
1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,
1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,
1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,
1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308,
};
BOOST_ASSERT(dim < sizeof(exponents)/sizeof(double));
return exponents[dim];
}
};
template <>
struct pow10_helper<float>
{
static float call(unsigned dim)
{
return pow10_helper<double>::call(dim);
}
};
#endif // for IEEE-754
}
template <typename T>
inline T pow10(unsigned dim)
{
return detail::pow10_helper<T>::call(dim);
}
}}}}
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(pop)
#endif
#endif

View File

@@ -0,0 +1,48 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(SPIRIT_SIGN_MAR_11_2009_0734PM)
#define SPIRIT_SIGN_MAR_11_2009_0734PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config/no_tr1/cmath.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/math/special_functions/sign.hpp>
namespace boost { namespace spirit { namespace x3
{
template<typename T>
inline bool (signbit)(T x)
{
return (boost::math::signbit)(x) ? true : false;
}
// This routine has been taken and adapted from Johan Rade's fp_traits
// library
template<typename T>
inline T (changesign)(T x)
{
#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY)
return -x;
#else
typedef typename math::detail::fp_traits<T>::type traits_type;
typename traits_type::bits a;
traits_type::get_bits(x, a);
a ^= traits_type::sign;
traits_type::set_bits(x, a);
return x;
#endif
}
}}}
#endif

View File

@@ -0,0 +1,75 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2013 Agustín Bergé
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_SUBCONTEXT_APR_15_2013_0840AM)
#define BOOST_SPIRIT_X3_SUBCONTEXT_APR_15_2013_0840AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/fusion/support/pair.hpp>
#include <boost/spirit/home/x3/support/context.hpp>
namespace boost { namespace spirit { namespace x3
{
template <typename... T>
struct subcontext;
template <>
struct subcontext<>
{
template <typename Context>
subcontext(Context const& /*context*/)
{}
};
template <typename T>
struct subcontext<T>
: boost::spirit::context<
typename T::first_type, typename T::second_type
>
{
typedef boost::spirit::context<
typename T::first_type, typename T::second_type
> context_type;
template <typename Context>
subcontext(Context const& context)
: context_type(boost::spirit::get<typename T::first_type>(context))
{}
};
template <typename T, typename... Tail>
struct subcontext<T, Tail...>
: subcontext<Tail...>
, boost::spirit::context<
typename T::first_type, typename T::second_type
, subcontext<Tail...>
>
{
typedef subcontext<Tail...> base_type;
typedef boost::spirit::context<
typename T::first_type, typename T::second_type
, base_type
> context_type;
template <typename Context>
subcontext(Context const& context)
: base_type(context)
, context_type(
boost::spirit::get<typename T::first_type>(context)
, *static_cast< base_type* >( this ) )
{}
using context_type::get;
};
}}}
#endif

View File

@@ -0,0 +1,64 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_ATTRIBUTE_CATEGORY_JAN_4_2012_1150AM)
#define BOOST_SPIRIT_X3_ATTRIBUTE_CATEGORY_JAN_4_2012_1150AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/mpl/identity.hpp>
#include <boost/fusion/include/copy.hpp>
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/spirit/home/x3/support/traits/is_variant.hpp>
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
namespace boost { namespace spirit { namespace x3
{
struct unused_type;
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
struct unused_attribute {};
struct plain_attribute {};
struct container_attribute {};
struct tuple_attribute {};
struct variant_attribute {};
struct optional_attribute {};
template <typename T, typename Enable = void>
struct attribute_category
: mpl::identity<plain_attribute> {};
template <>
struct attribute_category<unused_type>
: mpl::identity<unused_attribute> {};
template <>
struct attribute_category<unused_type const>
: mpl::identity<unused_attribute> {};
template <typename T>
struct attribute_category<T,
typename enable_if<fusion::traits::is_sequence<T>>::type>
: mpl::identity<tuple_attribute> {};
template <typename T>
struct attribute_category<T,
typename enable_if<traits::is_variant<T>>::type>
: mpl::identity<variant_attribute> {};
template <typename T>
struct attribute_category<T,
typename enable_if<traits::is_container<T>>::type>
: mpl::identity<container_attribute> {};
}}}}
#endif

View File

@@ -0,0 +1,59 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2013 Agustin Berge
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_ATTRIBUTE_OF_JAN_7_2012_0914AM)
#define BOOST_SPIRIT_X3_ATTRIBUTE_OF_JAN_7_2012_0914AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// Get the attribute type of a component. By default, this gets the
// Component's attribute_type typedef or instantiates a nested attribute
// metafunction. Components may specialize this if such an attribute_type
// is not readily available (e.g. expensive to compute at compile time).
///////////////////////////////////////////////////////////////////////////
template <typename Component, typename Context, typename Enable = void>
struct attribute_of;
namespace detail
{
template <typename Component, typename Context, typename Enable = void>
struct default_attribute_of;
template <typename Component, typename Context>
struct default_attribute_of<Component, Context,
typename disable_if_substitution_failure<
typename Component::attribute_type>::type>
: mpl::identity<typename Component::attribute_type> {};
template <typename Component, typename Context>
struct default_attribute_of<Component, Context,
typename disable_if_substitution_failure<
typename Component::template attribute<Context>::type>::type>
: Component::template attribute<Context> {};
template <typename Component, typename Context>
struct default_attribute_of<Component, Context,
typename enable_if_c<Component::is_pass_through_unary>::type>
: attribute_of<typename Component::subject_type, Context>{};
}
template <typename Component, typename Context, typename Enable>
struct attribute_of : detail::default_attribute_of<Component, Context> {};
}}}}
#endif

View File

@@ -0,0 +1,30 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_ATTRIBUTE_TYPE_JAN_5_2012_0358PM)
#define BOOST_SPIRIT_X3_ATTRIBUTE_TYPE_JAN_5_2012_0358PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/mpl/identity.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// Retrieve the attribute type to use from the given type
//
// This is needed to extract the correct attribute type from proxy classes
// as utilized in FUSION_ADAPT_ADT et. al.
///////////////////////////////////////////////////////////////////////////
template <typename Attribute, typename Enable = void>
struct attribute_type : mpl::identity<Attribute> {};
}}}}
#endif

View File

@@ -0,0 +1,304 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_CONTAINER_FEBRUARY_06_2007_1001AM)
#define BOOST_SPIRIT_X3_CONTAINER_FEBRUARY_06_2007_1001AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/bool.hpp>
#include <vector>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// This file contains some container utils for stl containers.
///////////////////////////////////////////////////////////////////////////
namespace detail
{
BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type)
BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator)
BOOST_MPL_HAS_XXX_TRAIT_DEF(size_type)
BOOST_MPL_HAS_XXX_TRAIT_DEF(reference)
}
template <typename T, typename Enable = void>
struct is_container
: mpl::bool_<
detail::has_value_type<T>::value &&
detail::has_iterator<T>::value &&
detail::has_size_type<T>::value &&
detail::has_reference<T>::value>
{};
///////////////////////////////////////////////////////////////////////////
namespace detail
{
template <typename T>
struct remove_value_const : mpl::identity<T> {};
template <typename T>
struct remove_value_const<T const> : remove_value_const<T> {};
template <typename F, typename S>
struct remove_value_const<std::pair<F, S>>
{
typedef typename remove_value_const<F>::type first_type;
typedef typename remove_value_const<S>::type second_type;
typedef std::pair<first_type, second_type> type;
};
}
///////////////////////////////////////////////////////////////////////
template <typename Container, typename Enable = void>
struct container_value
: detail::remove_value_const<typename Container::value_type>
{};
template <typename Container>
struct container_value<Container const> : container_value<Container> {};
template <>
struct container_value<unused_type> : mpl::identity<unused_type> {};
///////////////////////////////////////////////////////////////////////////
template <typename Container, typename Enable = void>
struct container_iterator
: mpl::identity<typename Container::iterator> {};
template <typename Container>
struct container_iterator<Container const>
: mpl::identity<typename Container::const_iterator> {};
template <>
struct container_iterator<unused_type>
: mpl::identity<unused_type const*> {};
template <>
struct container_iterator<unused_type const>
: mpl::identity<unused_type const*> {};
///////////////////////////////////////////////////////////////////////////
template <typename Container, typename T>
bool push_back(Container& c, T&& val);
template <typename Container, typename Enable = void>
struct push_back_container
{
template <typename T>
static bool call(Container& c, T&& val)
{
c.insert(c.end(), std::move(val));
return true;
}
};
template <typename Container, typename T>
inline bool push_back(Container& c, T&& val)
{
return push_back_container<Container>::call(c, std::move(val));
}
template <typename Container>
inline bool push_back(Container&, unused_type)
{
return true;
}
template <typename T>
inline bool push_back(unused_type, T const&)
{
return true;
}
inline bool push_back(unused_type, unused_type)
{
return true;
}
///////////////////////////////////////////////////////////////////////////
template <typename Container, typename Iterator>
bool append(Container& c, Iterator first, Iterator last);
template <typename Container, typename Enable = void>
struct append_container
{
// Not all containers have "reserve"
template <typename Container_>
static void reserve(Container_& c, std::size_t size) {}
template <typename T>
static void reserve(std::vector<T>& c, std::size_t size)
{
c.reserve(size);
}
template <typename Iterator>
static bool call(Container& c, Iterator first, Iterator last)
{
reserve(c, c.size() + std::distance(first, last));
c.insert(c.end(), first, last);
return true;
}
};
template <typename Container, typename Iterator>
inline bool append(Container& c, Iterator first, Iterator last)
{
return append_container<Container>::call(c, first, last);
}
///////////////////////////////////////////////////////////////////////////
template <typename Container, typename Enable = void>
struct is_empty_container
{
static bool call(Container const& c)
{
return c.empty();
}
};
template <typename Container>
inline bool is_empty(Container const& c)
{
return is_empty_container<Container>::call(c);
}
inline bool is_empty(unused_type)
{
return true;
}
///////////////////////////////////////////////////////////////////////////
template <typename Container, typename Enable = void>
struct begin_container
{
static typename container_iterator<Container>::type call(Container& c)
{
return c.begin();
}
};
template <typename Container>
inline typename container_iterator<Container>::type
begin(Container& c)
{
return begin_container<Container>::call(c);
}
inline unused_type const*
begin(unused_type)
{
return &unused;
}
///////////////////////////////////////////////////////////////////////////
template <typename Container, typename Enable = void>
struct end_container
{
static typename container_iterator<Container>::type call(Container& c)
{
return c.end();
}
};
template <typename Container>
inline typename container_iterator<Container>::type
end(Container& c)
{
return end_container<Container>::call(c);
}
inline unused_type const*
end(unused_type)
{
return &unused;
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Enable = void>
struct deref_iterator
{
typedef typename boost::detail::iterator_traits<Iterator>::reference type;
static type call(Iterator& it)
{
return *it;
}
};
template <typename Iterator>
typename deref_iterator<Iterator>::type
deref(Iterator& it)
{
return deref_iterator<Iterator>::call(it);
}
inline unused_type
deref(unused_type const*)
{
return unused;
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Enable = void>
struct next_iterator
{
static void call(Iterator& it)
{
++it;
}
};
template <typename Iterator>
void next(Iterator& it)
{
next_iterator<Iterator>::call(it);
}
inline void next(unused_type const*)
{
// do nothing
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Enable = void>
struct compare_iterators
{
static bool call(Iterator const& it1, Iterator const& it2)
{
return it1 == it2;
}
};
template <typename Iterator>
bool compare(Iterator& it1, Iterator& it2)
{
return compare_iterators<Iterator>::call(it1, it2);
}
inline bool compare(unused_type const*, unused_type const*)
{
return false;
}
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct build_container : mpl::identity<std::vector<T>> {};
template <>
struct build_container<unused_type> : mpl::identity<unused_type> {};
}}}}
#endif

View File

@@ -0,0 +1,31 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2013 Agustin Berge
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_HANDLES_CONTAINER_DEC_18_2010_0920AM)
#define BOOST_SPIRIT_X3_HANDLES_CONTAINER_DEC_18_2010_0920AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/mpl/bool.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// Whether a component handles container attributes intrinsically
// (or whether container attributes need to be split up separately).
// By default, this gets the Component's handles_container nested value.
// Components may specialize this if such a handles_container is not
// readily available (e.g. expensive to compute at compile time).
///////////////////////////////////////////////////////////////////////////
template <typename Component, typename Context, typename Enable = void>
struct handles_container : mpl::bool_<Component::handles_container> {};
}}}}
#endif

View File

@@ -0,0 +1,63 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2013 Agustin Berge
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_HAS_ATTRIBUTE_JUN_6_2012_1714PM)
#define BOOST_SPIRIT_X3_HAS_ATTRIBUTE_JUN_6_2012_1714PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/traits/attribute_of.hpp>
#include <boost/spirit/home/x3/support/utility/sfinae.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/not.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit { namespace x3
{
struct unused_type;
}}}
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// Whether a component has an attribute. By default, this compares the
// component attribute against unused_type. If the component provides a
// nested constant expression has_attribute as a hint, that value is used
// instead. Components may specialize this.
///////////////////////////////////////////////////////////////////////////
template <typename Component, typename Context, typename Enable = void>
struct has_attribute;
namespace detail
{
template <typename Component, typename Context, typename Enable = void>
struct default_has_attribute
: mpl::not_<is_same<unused_type,
typename attribute_of<Component, Context>::type>> {};
template <typename Component, typename Context>
struct default_has_attribute<Component, Context,
typename disable_if_substitution_failure<
mpl::bool_<Component::has_attribute>>::type>
: mpl::bool_<Component::has_attribute> {};
template <typename Component, typename Context>
struct default_has_attribute<Component, Context,
typename enable_if_c<Component::is_pass_through_unary>::type>
: has_attribute<typename Component::subject_type, Context> {};
}
template <typename Component, typename Context, typename Enable>
struct has_attribute : detail::default_has_attribute<Component, Context> {};
}}}}
#endif

View File

@@ -0,0 +1,75 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_IS_SUBSTITUTE_JAN_9_2012_1049PM)
#define BOOST_SPIRIT_X3_IS_SUBSTITUTE_JAN_9_2012_1049PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/traits/container_traits.hpp>
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/optional/optional.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// Find out if T can be a (strong) substitute for Attribute
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Attribute, typename Enable = void>
struct is_substitute;
namespace detail
{
template <typename T, typename Attribute>
struct value_type_is_substitute
: is_substitute<
typename container_value<T>::type
, typename container_value<Attribute>::type>
{};
template <typename T, typename Attribute, typename Enable = void>
struct is_substitute_impl : is_same<T, Attribute> {};
template <typename T, typename Attribute>
struct is_substitute_impl<T, Attribute,
typename enable_if<
mpl::and_<
fusion::traits::is_sequence<T>,
fusion::traits::is_sequence<Attribute>,
mpl::equal<T, Attribute, is_substitute<mpl::_1, mpl::_2>>
>
>::type>
: mpl::true_ {};
template <typename T, typename Attribute>
struct is_substitute_impl<T, Attribute,
typename enable_if<
mpl::and_<
is_container<T>,
is_container<Attribute>,
value_type_is_substitute<T, Attribute>
>
>::type>
: mpl::true_ {};
}
template <typename T, typename Attribute, typename Enable /*= void*/>
struct is_substitute
: detail::is_substitute_impl<T, Attribute> {};
template <typename T, typename Attribute>
struct is_substitute<optional<T>, optional<Attribute>>
: is_substitute<T, Attribute> {};
}}}}
#endif

View File

@@ -0,0 +1,45 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_IS_VARIANT_JAN_10_2012_0823AM)
#define BOOST_SPIRIT_X3_IS_VARIANT_JAN_10_2012_0823AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/variant.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/bool.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
namespace detail
{
// By declaring a nested struct in your class/struct, you tell
// spirit that it is regarded as a variant type. The minimum
// required interface for such a variant is that it has constructors
// for various types supported by your variant and a typedef 'types'
// which is an mpl sequence of the contained types.
//
// This is an intrusive interface. For a non-intrusive interface,
// use the not_is_variant trait.
BOOST_MPL_HAS_XXX_TRAIT_DEF(adapted_variant_tag)
}
template <typename T, typename Enable = void>
struct is_variant
: detail::has_adapted_variant_tag<T>
{};
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
struct is_variant<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>>
: mpl::true_
{};
}}}}
#endif

View File

@@ -0,0 +1,75 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2012 Hartmut Kaiser
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_MAKE_ATTRIBUTE_JAN_8_2012_0721PM)
#define BOOST_SPIRIT_X3_MAKE_ATTRIBUTE_JAN_8_2012_0721PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/mpl/if.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/spirit/home/x3/support/unused.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Attribute>
struct make_attribute_base
{
static Attribute call(unused_type)
{
// synthesize the attribute/parameter
return Attribute();
}
template <typename T>
static T& call(T& value)
{
return value; // just pass the one provided
}
};
template <typename Attribute, typename ActualAttribute>
struct make_attribute : make_attribute_base<Attribute>
{
typedef ActualAttribute& type;
typedef ActualAttribute value_type;
};
template <typename Attribute>
struct make_attribute<Attribute, unused_type>
: make_attribute_base<Attribute>
{
typedef typename remove_const<Attribute>::type attribute_type;
typedef attribute_type type;
typedef attribute_type value_type;
};
template <typename Attribute, typename ActualAttribute>
struct make_attribute<Attribute&, ActualAttribute>
: make_attribute<Attribute, ActualAttribute> {};
template <typename Attribute, typename ActualAttribute>
struct make_attribute<Attribute const&, ActualAttribute>
: make_attribute<Attribute const, ActualAttribute> {};
template <typename ActualAttribute>
struct make_attribute<unused_type, ActualAttribute>
{
typedef unused_type type;
typedef unused_type value_type;
static unused_type call(unused_type)
{
return unused;
}
};
}}}}
#endif

View File

@@ -0,0 +1,154 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2013 Agustin Berge
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_MOVE_TO_JAN_17_2013_0859PM)
#define BOOST_SPIRIT_X3_MOVE_TO_JAN_17_2013_0859PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
#include <boost/spirit/home/x3/support/traits/tuple_traits.hpp>
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/fusion/include/front.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/fusion/include/move.hpp>
#include <utility>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Source, typename Dest>
void move_to(Source&& src, Dest& dest);
template <typename Dest>
inline void move_to(unused_type, Dest&) {}
template <typename Source>
inline void move_to(Source&, unused_type) {}
inline void move_to(unused_type, unused_type) {}
template <typename Iterator, typename Dest>
void
move_to(Iterator first, Iterator last, Dest& dest);
template <typename Iterator>
inline void
move_to(Iterator, Iterator, unused_type) {}
namespace detail
{
template <typename Source, typename Dest>
inline void
move_to(Source&&, Dest&, unused_attribute) {}
template <typename Source, typename Dest>
inline void
move_to(Source&& src, Dest& dest, plain_attribute)
{
dest = std::move(src);
}
template <typename Source, typename Dest>
inline typename enable_if<is_container<Source>>::type
move_to(Source&& src, Dest& dest, container_attribute)
{
traits::move_to(src.begin(), src.end(), dest);
}
template <typename Source, typename Dest>
inline typename enable_if<
is_same_size_sequence<Dest, Source>
>::type
move_to(Source&& src, Dest& dest, tuple_attribute)
{
fusion::move(std::move(src), dest);
}
template <typename Source, typename Dest>
inline typename enable_if<
is_size_one_sequence<Dest>
>::type
move_to(Source&& src, Dest& dest, tuple_attribute)
{
traits::move_to(src, fusion::front(dest));
}
template <typename Source, typename Dest>
inline void
move_to(Source&& src, Dest& dest, variant_attribute, mpl::false_)
{
dest = std::move(src);
}
template <typename Source, typename Dest>
inline void
move_to(Source&& src, Dest& dest, variant_attribute, mpl::true_)
{
dest = std::move(fusion::front(src));
}
template <typename Source, typename Dest>
inline void
move_to(Source&& src, Dest& dest, variant_attribute tag)
{
move_to(src, dest, tag, is_size_one_sequence<Source>());
}
template <typename Iterator>
inline void
move_to(Iterator, Iterator, unused_type, unused_attribute) {}
template <typename Iterator, typename Dest>
inline void
move_to(Iterator first, Iterator last, Dest& dest, container_attribute)
{
if (is_empty(dest))
dest = Dest(first, last);
else
append(dest, first, last);
}
}
template <typename Source, typename Dest>
inline void
move_to(Source&& src, Dest& dest)
{
detail::move_to(std::move(src), dest
, typename attribute_category<Dest>::type());
}
template <typename T>
inline void move_to(T& src, T& dest)
{
dest = std::move(src);
}
template <typename T>
inline void move_to(T const& src, T& dest)
{
dest = std::move(src);
}
template <typename T>
inline void move_to(T&& src, T& dest)
{
dest = std::move(src);
}
template <typename Iterator, typename Dest>
inline void
move_to(Iterator first, Iterator last, Dest& dest)
{
// $$$ Use std::move_iterator when iterator is not a const-iterator $$$
detail::move_to(first, last, dest, typename attribute_category<Dest>::type());
}
}}}}
#endif

View File

@@ -0,0 +1,128 @@
/*=============================================================================
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_NUMERIC_TRAITS_JAN_07_2011_0722AM)
#define BOOST_SPIRIT_X3_NUMERIC_TRAITS_JAN_07_2011_0722AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/config.hpp>
#include <boost/integer_traits.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// Determine if T is a boolean type
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct is_bool : mpl::false_ {};
template <typename T>
struct is_bool<T const> : is_bool<T> {};
template <>
struct is_bool<bool> : mpl::true_ {};
///////////////////////////////////////////////////////////////////////////
// Determine if T is a signed integer type
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct is_int : mpl::false_ {};
template <typename T>
struct is_int<T const> : is_int<T> {};
template <>
struct is_int<short> : mpl::true_ {};
template <>
struct is_int<int> : mpl::true_ {};
template <>
struct is_int<long> : mpl::true_ {};
#ifdef BOOST_HAS_LONG_LONG
template <>
struct is_int<boost::long_long_type> : mpl::true_ {};
#endif
///////////////////////////////////////////////////////////////////////////
// Determine if T is an unsigned integer type
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct is_uint : mpl::false_ {};
template <typename T>
struct is_uint<T const> : is_uint<T> {};
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
template <>
struct is_uint<unsigned short> : mpl::true_ {};
#endif
template <>
struct is_uint<unsigned int> : mpl::true_ {};
template <>
struct is_uint<unsigned long> : mpl::true_ {};
#ifdef BOOST_HAS_LONG_LONG
template <>
struct is_uint<boost::ulong_long_type> : mpl::true_ {};
#endif
///////////////////////////////////////////////////////////////////////////
// Determine if T is a floating point type
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct is_real : mpl::false_ {};
template <typename T>
struct is_real<T const> : is_uint<T> {};
template <>
struct is_real<float> : mpl::true_ {};
template <>
struct is_real<double> : mpl::true_ {};
template <>
struct is_real<long double> : mpl::true_ {};
///////////////////////////////////////////////////////////////////////////
// customization points for numeric operations
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Enable = void>
struct absolute_value;
template <typename T, typename Enable = void>
struct is_negative;
template <typename T, typename Enable = void>
struct is_zero;
template <typename T, typename Enable = void>
struct pow10_helper;
template <typename T, typename Enable = void>
struct is_nan;
template <typename T, typename Enable = void>
struct is_infinite;
template <typename T, typename Enable = void>
struct check_overflow : mpl::false_ {};
template <typename T>
struct check_overflow<T, typename enable_if_c<integer_traits<T>::is_integral>::type>
: mpl::true_ {};
}}}}
#endif

View File

@@ -0,0 +1,78 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_OPTIONAL_TRAITS_FEBRUARY_06_2007_1001AM)
#define BOOST_SPIRIT_X3_OPTIONAL_TRAITS_FEBRUARY_06_2007_1001AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/x3/support/unused.hpp>
#include <boost/optional/optional.hpp>
#include <boost/mpl/identity.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Enable = void>
struct is_optional
: mpl::false_
{};
template <typename T>
struct is_optional<boost::optional<T>>
: mpl::true_
{};
///////////////////////////////////////////////////////////////////////////
// build_optional
//
// Build a boost::optional from T. Return unused_type if T is unused_type.
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct build_optional
{
typedef boost::optional<T> type;
};
template <typename T>
struct build_optional<boost::optional<T> >
{
typedef boost::optional<T> type;
};
template <>
struct build_optional<unused_type>
{
typedef unused_type type;
};
///////////////////////////////////////////////////////////////////////////
// optional_value
//
// Get the optional's value_type. Handles unused_type as well.
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct optional_value : mpl::identity<T> {};
template <typename T>
struct optional_value<boost::optional<T> >
: mpl::identity<T> {};
template <>
struct optional_value<unused_type>
: mpl::identity<unused_type> {};
template <>
struct optional_value<unused_type const>
: mpl::identity<unused_type> {};
}}}}
#endif

View File

@@ -0,0 +1,150 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
================================================_==============================*/
#if !defined(BOOST_SPIRIT_X3_PRINT_ATTRIBUTE_JANUARY_20_2013_0814AM)
#define BOOST_SPIRIT_X3_PRINT_ATTRIBUTE_JANUARY_20_2013_0814AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/variant.hpp>
#include <boost/optional/optional.hpp>
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
#include <boost/spirit/home/x3/support/traits/is_variant.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename Out, typename T>
void print_attribute(Out& out, T const& val);
template <typename Out>
inline void print_attribute(Out&, unused_type) {}
///////////////////////////////////////////////////////////////////////////
namespace detail
{
template <typename Out>
struct print_fusion_sequence
{
print_fusion_sequence(Out& out)
: out(out), is_first(true) {}
typedef void result_type;
template <typename T>
void operator()(T const& val) const
{
if (is_first)
is_first = false;
else
out << ", ";
x3::traits::print_attribute(out, val);
}
Out& out;
mutable bool is_first;
};
// print elements in a variant
template <typename Out>
struct print_visitor : static_visitor<>
{
print_visitor(Out& out) : out(out) {}
template <typename T>
void operator()(T const& val) const
{
x3::traits::print_attribute(out, val);
}
Out& out;
};
}
template <typename Out, typename T, typename Enable = void>
struct print_attribute_debug
{
// for plain data types
template <typename T_>
static void call(Out& out, T_ const& val, unused_attribute)
{
out << "unused";
}
// for plain data types
template <typename T_>
static void call(Out& out, T_ const& val, plain_attribute)
{
out << val;
}
// for fusion data types
template <typename T_>
static void call(Out& out, T_ const& val, tuple_attribute)
{
out << '[';
fusion::for_each(val, detail::print_fusion_sequence<Out>(out));
out << ']';
}
// stl container
template <typename T_>
static void call(Out& out, T_ const& val, container_attribute)
{
out << '[';
if (!traits::is_empty(val))
{
bool first = true;
typename container_iterator<T_ const>::type iend = traits::end(val);
for (typename container_iterator<T_ const>::type i = traits::begin(val);
!traits::compare(i, iend); traits::next(i))
{
if (!first)
out << ", ";
first = false;
x3::traits::print_attribute(out, traits::deref(i));
}
}
out << ']';
}
// for variant types
template <typename T_>
static void call(Out& out, T_ const& val, variant_attribute)
{
apply_visitor(detail::print_visitor<Out>(out), val);
}
// for optional types
template <typename T_>
static void call(Out& out, T_ const& val, optional_attribute)
{
if (val)
x3::traits::print_attribute(out, *val);
else
out << "[empty]";
}
// main entry point
static void call(Out& out, T const& val)
{
call(out, val, typename attribute_category<T>::type());
}
};
///////////////////////////////////////////////////////////////////////////
template <typename Out, typename T>
inline void print_attribute(Out& out, T const& val)
{
print_attribute_debug<Out, T>::call(out, val);
}
}}}}
#endif

View File

@@ -0,0 +1,79 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
================================================_==============================*/
#if !defined(BOOST_SPIRIT_X3_PRINT_TOKEN_JANUARY_20_2013_0814AM)
#define BOOST_SPIRIT_X3_PRINT_TOKEN_JANUARY_20_2013_0814AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <cctype>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// generate debug output for lookahead token (character) stream
namespace detail
{
struct token_printer_debug_for_chars
{
template<typename Out, typename Char>
static void print(Out& o, Char c)
{
using namespace std; // allow for ADL to find the proper iscntrl
switch (c)
{
case '\a': o << "\\a"; break;
case '\b': o << "\\b"; break;
case '\f': o << "\\f"; break;
case '\n': o << "\\n"; break;
case '\r': o << "\\r"; break;
case '\t': o << "\\t"; break;
case '\v': o << "\\v"; break;
default:
if (c >= 0 && c < 127 && iscntrl(c))
o << "\\" << std::oct << int(c);
else
o << Char(c);
}
}
};
// for token types where the comparison with char constants wouldn't work
struct token_printer_debug
{
template<typename Out, typename T>
static void print(Out& o, T const& val)
{
o << val;
}
};
}
template <typename T, typename Enable = void>
struct token_printer_debug
: mpl::if_<
mpl::and_<
is_convertible<T, char>, is_convertible<char, T> >
, detail::token_printer_debug_for_chars
, detail::token_printer_debug>::type
{};
template <typename Out, typename T>
inline void print_token(Out& out, T const& val)
{
// allow to customize the token printer routine
token_printer_debug<T>::print(out, val);
}
}}}}
#endif

View File

@@ -0,0 +1,291 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Copyright (c) 2010 Bryce Lelbach
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
================================================_==============================*/
#if !defined(BOOST_SPIRIT_X3_STRING_TRAITS_OCTOBER_2008_1252PM)
#define BOOST_SPIRIT_X3_STRING_TRAITS_OCTOBER_2008_1252PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <string>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// Determine if T is a character type
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct is_char : mpl::false_ {};
template <typename T>
struct is_char<T const> : is_char<T> {};
template <>
struct is_char<char> : mpl::true_ {};
template <>
struct is_char<wchar_t> : mpl::true_ {};
///////////////////////////////////////////////////////////////////////////
// Determine if T is a string
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct is_string : mpl::false_ {};
template <typename T>
struct is_string<T const> : is_string<T> {};
template <>
struct is_string<char const*> : mpl::true_ {};
template <>
struct is_string<wchar_t const*> : mpl::true_ {};
template <>
struct is_string<char*> : mpl::true_ {};
template <>
struct is_string<wchar_t*> : mpl::true_ {};
template <std::size_t N>
struct is_string<char[N]> : mpl::true_ {};
template <std::size_t N>
struct is_string<wchar_t[N]> : mpl::true_ {};
template <std::size_t N>
struct is_string<char const[N]> : mpl::true_ {};
template <std::size_t N>
struct is_string<wchar_t const[N]> : mpl::true_ {};
template <std::size_t N>
struct is_string<char(&)[N]> : mpl::true_ {};
template <std::size_t N>
struct is_string<wchar_t(&)[N]> : mpl::true_ {};
template <std::size_t N>
struct is_string<char const(&)[N]> : mpl::true_ {};
template <std::size_t N>
struct is_string<wchar_t const(&)[N]> : mpl::true_ {};
template <typename T, typename Traits, typename Allocator>
struct is_string<std::basic_string<T, Traits, Allocator> > : mpl::true_ {};
///////////////////////////////////////////////////////////////////////////
// Get the underlying char type of a string
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct char_type_of;
template <typename T>
struct char_type_of<T const> : char_type_of<T> {};
template <>
struct char_type_of<char> : mpl::identity<char> {};
template <>
struct char_type_of<wchar_t> : mpl::identity<wchar_t> {};
template <>
struct char_type_of<char const*> : mpl::identity<char const> {};
template <>
struct char_type_of<wchar_t const*> : mpl::identity<wchar_t const> {};
template <>
struct char_type_of<char*> : mpl::identity<char> {};
template <>
struct char_type_of<wchar_t*> : mpl::identity<wchar_t> {};
template <std::size_t N>
struct char_type_of<char[N]> : mpl::identity<char> {};
template <std::size_t N>
struct char_type_of<wchar_t[N]> : mpl::identity<wchar_t> {};
template <std::size_t N>
struct char_type_of<char const[N]> : mpl::identity<char const> {};
template <std::size_t N>
struct char_type_of<wchar_t const[N]> : mpl::identity<wchar_t const> {};
template <std::size_t N>
struct char_type_of<char(&)[N]> : mpl::identity<char> {};
template <std::size_t N>
struct char_type_of<wchar_t(&)[N]> : mpl::identity<wchar_t> {};
template <std::size_t N>
struct char_type_of<char const(&)[N]> : mpl::identity<char const> {};
template <std::size_t N>
struct char_type_of<wchar_t const(&)[N]> : mpl::identity<wchar_t const> {};
template <typename T, typename Traits, typename Allocator>
struct char_type_of<std::basic_string<T, Traits, Allocator> >
: mpl::identity<T> {};
///////////////////////////////////////////////////////////////////////////
// Get the C string from a string
///////////////////////////////////////////////////////////////////////////
template <typename String>
struct extract_c_string;
template <typename String>
struct extract_c_string
{
typedef typename char_type_of<String>::type char_type;
template <typename T>
static T const* call (T* str)
{
return (T const*)str;
}
template <typename T>
static T const* call (T const* str)
{
return str;
}
};
// Forwarder that strips const
template <typename T>
struct extract_c_string<T const>
{
typedef typename extract_c_string<T>::char_type char_type;
static typename extract_c_string<T>::char_type const* call (T const str)
{
return extract_c_string<T>::call(str);
}
};
// Forwarder that strips references
template <typename T>
struct extract_c_string<T&>
{
typedef typename extract_c_string<T>::char_type char_type;
static typename extract_c_string<T>::char_type const* call (T& str)
{
return extract_c_string<T>::call(str);
}
};
// Forwarder that strips const references
template <typename T>
struct extract_c_string<T const&>
{
typedef typename extract_c_string<T>::char_type char_type;
static typename extract_c_string<T>::char_type const* call (T const& str)
{
return extract_c_string<T>::call(str);
}
};
template <typename T, typename Traits, typename Allocator>
struct extract_c_string<std::basic_string<T, Traits, Allocator> >
{
typedef T char_type;
typedef std::basic_string<T, Traits, Allocator> string;
static T const* call (string const& str)
{
return str.c_str();
}
};
template <typename T>
typename extract_c_string<T*>::char_type const*
get_c_string(T* str)
{
return extract_c_string<T*>::call(str);
}
template <typename T>
typename extract_c_string<T const*>::char_type const*
get_c_string(T const* str)
{
return extract_c_string<T const*>::call(str);
}
template <typename String>
typename extract_c_string<String>::char_type const*
get_c_string(String& str)
{
return extract_c_string<String>::call(str);
}
template <typename String>
typename extract_c_string<String>::char_type const*
get_c_string(String const& str)
{
return extract_c_string<String>::call(str);
}
///////////////////////////////////////////////////////////////////////////
// Get the begin/end iterators from a string
///////////////////////////////////////////////////////////////////////////
// Implementation for C-style strings.
template <typename T>
inline T const* get_string_begin(T const* str) { return str; }
template <typename T>
inline T* get_string_begin(T* str) { return str; }
template <typename T>
inline T const* get_string_end(T const* str)
{
T const* last = str;
while (*last)
last++;
return last;
}
template <typename T>
inline T* get_string_end(T* str)
{
T* last = str;
while (*last)
last++;
return last;
}
// Implementation for containers (includes basic_string).
template <typename T, typename Str>
inline typename Str::const_iterator get_string_begin(Str const& str)
{ return str.begin(); }
template <typename T, typename Str>
inline typename Str::iterator
get_string_begin(Str& str)
{ return str.begin(); }
template <typename T, typename Str>
inline typename Str::const_iterator get_string_end(Str const& str)
{ return str.end(); }
template <typename T, typename Str>
inline typename Str::iterator
get_string_end(Str& str)
{ return str.end(); }
}}}}
#endif

View File

@@ -0,0 +1,48 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2012 Hartmut Kaiser
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_ATTRIBUTE_TRANSFORM_JAN_8_2012_0721PM)
#define BOOST_SPIRIT_X3_ATTRIBUTE_TRANSFORM_JAN_8_2012_0721PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/mpl/identity.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// transform_attribute
//
// Sometimes the user needs to transform the attribute types for certain
// attributes. This template can be used as a customization point, where
// the user is able specify specific transformation rules for any attribute
// type.
///////////////////////////////////////////////////////////////////////////
template <typename Exposed, typename Transformed, typename Tag
, typename Enable = void>
struct transform_attribute;
///////////////////////////////////////////////////////////////////////////
template <typename Tag, typename Transformed, typename Exposed>
typename transform_attribute<Exposed, Transformed, Tag>::type
pre_transform(Exposed& attr)
{
return transform_attribute<Exposed, Transformed, Tag>::pre(attr);
}
template <typename Tag, typename Transformed, typename Exposed>
typename transform_attribute<Exposed, Transformed, Tag>::type
pre_transform(Exposed const& attr)
{
return transform_attribute<Exposed const, Transformed, Tag>::pre(attr);
}
}}}}
#endif

View File

@@ -0,0 +1,52 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
================================================_==============================*/
#if !defined(BOOST_SPIRIT_X3_TUPLE_TRAITS_JANUARY_2012_1132PM)
#define BOOST_SPIRIT_X3_TUPLE_TRAITS_JANUARY_2012_1132PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/and.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename A, typename B>
struct has_same_size
: mpl::bool_<(
fusion::result_of::size<A>::value ==
fusion::result_of::size<B>::value
)>
{};
template <typename T, std::size_t N>
struct has_size
: mpl::bool_<(fusion::result_of::size<T>::value == N)>
{};
template <typename A, typename B>
struct is_same_size_sequence
: mpl::and_<
fusion::traits::is_sequence<A>
, fusion::traits::is_sequence<B>
, has_same_size<A, B>
>
{};
template <typename Seq>
struct is_size_one_sequence
: mpl::and_<
fusion::traits::is_sequence<Seq>
, has_size<Seq, 1>
>
{};
}}}}
#endif

View File

@@ -0,0 +1,30 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_X3_VALUE_TRAITS_MAY_07_2013_0203PM)
#define BOOST_SPIRIT_X3_VALUE_TRAITS_MAY_07_2013_0203PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/utility/value_init.hpp>
namespace boost { namespace spirit { namespace x3 { namespace traits
{
template <typename T, typename Enable = void>
struct value_initialize
{
static T call()
{
return boost::value_initialized<T>();
}
};
}}}}
#endif

View File

@@ -0,0 +1,29 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2013 Agustin Berge
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_SFINAE_MAY_20_2013_0840AM)
#define BOOST_SPIRIT_X3_SFINAE_MAY_20_2013_0840AM
#if defined(_MSC_VER)
#pragma once
#endif
namespace boost { namespace spirit { namespace x3
{
template <typename Expr, typename T = void>
struct disable_if_substitution_failure
{
typedef T type;
};
template <typename Expr, typename T>
struct lazy_disable_if_substitution_failure
{
typedef typename T::type type;
};
}}}
#endif

View File

@@ -0,0 +1,72 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_X3_UC_TYPES_NOVEMBER_23_2008_0840PM)
#define BOOST_SPIRIT_X3_UC_TYPES_NOVEMBER_23_2008_0840PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/cstdint.hpp>
#include <boost/foreach.hpp>
#include <boost/regex/pending/unicode_iterator.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <string>
namespace boost { namespace spirit { namespace x3
{
typedef ::boost::uint32_t ucs4_char;
typedef char utf8_char;
typedef std::basic_string<ucs4_char> ucs4_string;
typedef std::basic_string<utf8_char> utf8_string;
template <typename Char>
inline utf8_string to_utf8(Char value)
{
// always store as UTF8
utf8_string result;
typedef std::back_insert_iterator<utf8_string> insert_iter;
insert_iter out_iter(result);
utf8_output_iterator<insert_iter> utf8_iter(out_iter);
typedef typename make_unsigned<Char>::type UChar;
*utf8_iter = (UChar)value;
return result;
}
template <typename Char>
inline utf8_string to_utf8(Char const* str)
{
// always store as UTF8
utf8_string result;
typedef std::back_insert_iterator<utf8_string> insert_iter;
insert_iter out_iter(result);
utf8_output_iterator<insert_iter> utf8_iter(out_iter);
typedef typename make_unsigned<Char>::type UChar;
while (*str)
*utf8_iter++ = (UChar)*str++;
return result;
}
template <typename Char, typename Traits, typename Allocator>
inline utf8_string
to_utf8(std::basic_string<Char, Traits, Allocator> const& str)
{
// always store as UTF8
utf8_string result;
typedef std::back_insert_iterator<utf8_string> insert_iter;
insert_iter out_iter(result);
utf8_output_iterator<insert_iter> utf8_iter(out_iter);
typedef typename make_unsigned<Char>::type UChar;
BOOST_FOREACH(Char ch, str)
{
*utf8_iter++ = (UChar)ch;
}
return result;
}
}}}
#endif

5
test/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
/bin/
/.DS_Store
/*.gitignore
/test_dfa.hpp
/test_switch.hpp

293
test/x3/alternative.cpp Normal file
View File

@@ -0,0 +1,293 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#include <boost/detail/lightweight_test.hpp>
//~ #include <boost/mpl/print.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/variant.hpp>
//~ #include <boost/assert.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/at.hpp>
#include <string>
#include <iostream>
#include <vector>
#include "test.hpp"
//~ struct test_action
//~ {
//~ test_action(char last)
//~ : last_(last) {}
//~ void operator()(std::vector<char> const& v
//~ , boost::spirit::x3::unused_type
//~ , boost::spirit::x3::unused_type) const
//~ {
//~ BOOST_TEST(v.size() == 4 &&
//~ v[0] == 'a' && v[1] == 'b' && v[2] == '1' && v[3] == last_);
//~ }
//~ char last_;
//~ };
//~ struct test_action_2
//~ {
//~ typedef std::vector<boost::optional<char> > result_type;
//~ void operator()(result_type const& v
//~ , boost::spirit::x3::unused_type
//~ , boost::spirit::x3::unused_type) const
//~ {
//~ BOOST_TEST(v.size() == 5 &&
//~ !v[0] && v[1] == 'a' && v[2] == 'b' && v[3] == '1' && v[4] == '2');
//~ }
//~ };
struct di_ignore
{
std::string text;
};
struct di_include
{
std::string FileName;
};
BOOST_FUSION_ADAPT_STRUCT(
di_ignore,
(std::string, text)
)
BOOST_FUSION_ADAPT_STRUCT(
di_include,
(std::string, FileName)
)
struct undefined {};
int
main()
{
using spirit_test::test;
using spirit_test::test_attr;
using boost::spirit::x3::char_;
using boost::spirit::x3::int_;
using boost::spirit::x3::lit;
using boost::spirit::x3::unused_type;
using boost::spirit::x3::unused;
using boost::spirit::x3::omit;
{
BOOST_TEST((test("a", char_ | char_)));
BOOST_TEST((test("x", lit('x') | lit('i'))));
BOOST_TEST((test("i", lit('x') | lit('i'))));
BOOST_TEST((!test("z", lit('x') | lit('o'))));
BOOST_TEST((test("rock", lit("rock") | lit("roll"))));
BOOST_TEST((test("roll", lit("rock") | lit("roll"))));
BOOST_TEST((test("rock", lit("rock") | int_)));
BOOST_TEST((test("12345", lit("rock") | int_)));
}
{
typedef boost::variant<undefined, int, char> attr_type;
attr_type v;
BOOST_TEST((test_attr("12345", int_ | char_, v)));
BOOST_TEST(boost::get<int>(v) == 12345);
BOOST_TEST((test_attr("12345", lit("rock") | int_ | char_, v)));
BOOST_TEST(boost::get<int>(v) == 12345);
v = attr_type();
BOOST_TEST((test_attr("rock", lit("rock") | int_ | char_, v)));
BOOST_TEST(v.which() == 0);
BOOST_TEST((test_attr("x", lit("rock") | int_ | char_, v)));
BOOST_TEST(boost::get<char>(v) == 'x');
}
{ // Make sure that we are using the actual supplied attribute types
// from the variant and not the expected type.
boost::variant<int, std::string> v;
BOOST_TEST((test_attr("12345", int_ | +char_, v)));
BOOST_TEST(boost::get<int>(v) == 12345);
BOOST_TEST((test_attr("abc", int_ | +char_, v)));
BOOST_TEST(boost::get<std::string>(v) == "abc");
BOOST_TEST((test_attr("12345", +char_ | int_, v)));
BOOST_TEST(boost::get<std::string>(v) == "12345");
}
//~ { // test action
//~ namespace phx = boost::phoenix;
//~ boost::optional<boost::variant<int, char> > v;
//~ BOOST_TEST((test("12345", (lit("rock") | int_ | char_)[phx::ref(v) = _1])));
//~ BOOST_TEST(boost::get<int>(boost::get(v)) == 12345);
//~ BOOST_TEST((test("rock", (lit("rock") | int_ | char_)[phx::ref(v) = _1])));
//~ BOOST_TEST(!v);
//~ }
{
unused_type x;
BOOST_TEST((test_attr("rock", lit("rock") | lit('x'), x)));
}
{
// test if alternatives with all components having unused
// attributes have an unused attribute
using boost::fusion::vector;
using boost::fusion::at_c;
vector<char, char> v;
BOOST_TEST((test_attr("abc",
char_ >> (omit[char_] | omit[char_]) >> char_, v)));
BOOST_TEST((at_c<0>(v) == 'a'));
BOOST_TEST((at_c<1>(v) == 'c'));
}
{
// Test that we can still pass a "compatible" attribute to
// an alternate even if its "expected" attribute is unused type.
std::string s;
BOOST_TEST((test_attr("...", *(char_('.') | char_(',')), s)));
BOOST_TEST(s == "...");
}
// $$$ Not yet implemented
//~ { // make sure collapsing eps works as expected
//~ // (compile check only)
//~ using boost::spirit::x3::rule;
//~ using boost::spirit::x3::eps;
//~ rule<class r1, wchar_t> r1;
//~ rule<class r2, wchar_t> r2;
//~ rule<class r3, wchar_t> r3;
//~ r3 = ((eps >> r1))[_val += _1];
//~ r3 = ((r1 ) | r2)[_val += _1];
//~ r3 = ((eps >> r1) | r2);
//~ }
//~ // make sure the attribute of an alternative gets properly collapsed
//~ {
//~ using boost::spirit::x3::lexeme;
//~ using boost::spirit::x3::ascii::alnum;
//~ using boost::spirit::x3::ascii::alpha;
//~ using boost::spirit::x3::ascii::digit;
//~ using boost::spirit::x3::ascii::string;
//~ namespace phx = boost::phoenix;
//~ BOOST_TEST( (test("ab1_", (*(alnum | char_('_')))[test_action('_')])) );
//~ BOOST_TEST( (test("ab12", (*(alpha | digit))[test_action('2')])) );
//~ BOOST_TEST( (test("abcab12", (*("abc" | alnum))[test_action_2()])) );
//~ std::vector<boost::optional<char> > v;
//~ BOOST_TEST( (test("x,y,z", (*(',' | char_))[phx::ref(v) = _1])) );
//~ BOOST_ASSERT(v[0] == 'x');
//~ BOOST_ASSERT(!v[1]);
//~ BOOST_ASSERT(v[2] == 'y');
//~ BOOST_ASSERT(!v[3]);
//~ BOOST_ASSERT(v[4] == 'z');
//~ }
{
std::string s;
using boost::spirit::x3::eps;
// test having a variant<container, ...>
BOOST_TEST( (test_attr("a,b", (char_ % ',') | eps, s )) );
BOOST_TEST(s == "ab");
}
{
using boost::spirit::x3::eps;
// testing a sequence taking a container as attribute
std::string s;
BOOST_TEST( (test_attr("abc,a,b,c",
char_ >> char_ >> (char_ % ','), s )) );
BOOST_TEST(s == "abcabc");
// test having an optional<container> inside a sequence
s.erase();
BOOST_TEST( (test_attr("ab",
char_ >> char_ >> -(char_ % ','), s )) );
BOOST_TEST(s == "ab");
// test having a variant<container, ...> inside a sequence
s.erase();
BOOST_TEST( (test_attr("ab",
char_ >> char_ >> ((char_ % ',') | eps), s )) );
BOOST_TEST(s == "ab");
s.erase();
BOOST_TEST( (test_attr("abc",
char_ >> char_ >> ((char_ % ',') | eps), s )) );
BOOST_TEST(s == "abc");
}
//~ {
//~ using boost::spirit::x3::int_;
//~ int i = 0;
//~ BOOST_TEST( (test_attr("10", int_(5) | int_(10), i)) );
//~ BOOST_TEST(i == 10);
//~ }
// $$$ No longer relevant? $$$
{
//compile test only (bug_march_10_2011_8_35_am)
typedef boost::variant<double, std::string> value_type;
using boost::spirit::x3::rule;
using boost::spirit::x3::eps;
rule<class r1, value_type> r1;
auto r1_ = r1 = r1 | eps; // left recursive!
unused = r1_; // silence unused local warning
}
{
using boost::spirit::x3::rule;
typedef boost::variant<di_ignore, di_include> d_line;
rule<class ignore, di_ignore> ignore;
rule<class include, di_include> include;
rule<class line, d_line> line;
auto start =
line = include | ignore;
unused = start; // silence unused local warning
}
// single-element fusion vector tests
{
boost::fusion::vector<boost::variant<int, std::string>> fv;
BOOST_TEST((test_attr("12345", int_ | +char_, fv)));
BOOST_TEST(boost::get<int>(boost::fusion::at_c<0>(fv)) == 12345);
boost::fusion::vector<boost::variant<int, std::string>> fvi;
BOOST_TEST((test_attr("12345", int_ | int_, fvi)));
BOOST_TEST(boost::get<int>(boost::fusion::at_c<0>(fvi)) == 12345);
}
return boost::report_errors();
}

25
test/x3/and_predicate.cpp Normal file
View File

@@ -0,0 +1,25 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#include <boost/detail/lightweight_test.hpp>
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include "test.hpp"
int
main()
{
using spirit_test::test;
using boost::spirit::x3::int_;
{
BOOST_TEST((test("1234", &int_, false)));
BOOST_TEST((!test("abcd", &int_)));
}
return boost::report_errors();
}

65
test/x3/attr.cpp Normal file
View File

@@ -0,0 +1,65 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#include <boost/detail/lightweight_test.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <vector>
#include "test.hpp"
int
main()
{
using spirit_test::test_attr;
using boost::spirit::x3::attr;
using boost::spirit::x3::int_;
{
int d = 0;
BOOST_TEST(test_attr("", attr(1), d) && d == 1);
int d1 = 1;
BOOST_TEST(test_attr("", attr(d1), d) && d == 1);
std::pair<int, int> p;
BOOST_TEST(test_attr("1", int_ >> attr(1), p) &&
p.first == 1 && p.second == 1);
char c = '\0';
BOOST_TEST(test_attr("", attr('a'), c) && c == 'a');
// $$$ Needs some special is_convertible support, or
// str ends up with an explicit null-terminator... $$$
//~ std::string str;
//~ BOOST_TEST(test_attr("", attr("test"), str) && str == "test");
int array[] = {0, 1, 2};
std::vector<int> vec;
BOOST_TEST(test_attr("", attr(array), vec) && vec.size() == 3 &&
vec[0] == 0 && vec[1] == 1 && vec[2] == 2);
}
//~ { // testing lazy constructs
//~ using boost::phoenix::val;
//~ using boost::phoenix::ref;
//~ int d = 0;
//~ BOOST_TEST(test_attr("", attr(val(1)), d) && d == 1);
//~ int d1 = 2;
//~ BOOST_TEST(test_attr("", attr(ref(d1)), d) && d == 2);
//~ }
{
std::string s;
BOOST_TEST(test_attr("s", "s" >> attr(std::string("123")), s) &&
s == "123");
}
return boost::report_errors();
}

155
test/x3/char1.cpp Normal file
View File

@@ -0,0 +1,155 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2011 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#include <boost/detail/lightweight_test.hpp>
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include "test.hpp"
int
main()
{
using spirit_test::test;
//~ using spirit_test::test_attr;
//~ using spirit_test::print_info;
{
using namespace boost::spirit::x3::ascii;
BOOST_TEST(test("x", 'x'));
BOOST_TEST(test(L"x", L'x'));
BOOST_TEST(!test("y", 'x'));
BOOST_TEST(!test(L"y", L'x'));
BOOST_TEST(test("x", char_));
BOOST_TEST(test("x", char_('x')));
BOOST_TEST(!test("x", char_('y')));
//~ BOOST_TEST(test("x", char_('a', 'z')));
//~ BOOST_TEST(!test("x", char_('0', '9')));
BOOST_TEST(!test("x", ~char_));
BOOST_TEST(!test("x", ~char_('x')));
BOOST_TEST(test(" ", ~char_('x')));
BOOST_TEST(test("X", ~char_('x')));
//~ BOOST_TEST(!test("x", ~char_('b', 'y')));
//~ BOOST_TEST(test("a", ~char_('b', 'y')));
//~ BOOST_TEST(test("z", ~char_('b', 'y')));
BOOST_TEST(test("x", ~~char_));
BOOST_TEST(test("x", ~~char_('x')));
BOOST_TEST(!test(" ", ~~char_('x')));
BOOST_TEST(!test("X", ~~char_('x')));
//~ BOOST_TEST(test("x", ~~char_('b', 'y')));
//~ BOOST_TEST(!test("a", ~~char_('b', 'y')));
//~ BOOST_TEST(!test("z", ~~char_('b', 'y')));
}
{
using namespace boost::spirit::x3::ascii;
BOOST_TEST(test(" x", 'x', space));
BOOST_TEST(test(L" x", L'x', space));
BOOST_TEST(test(" x", char_, space));
BOOST_TEST(test(" x", char_('x'), space));
BOOST_TEST(!test(" x", char_('y'), space));
//~ BOOST_TEST(test(" x", char_('a', 'z'), space));
//~ BOOST_TEST(!test(" x", char_('0', '9'), space));
}
{
using namespace boost::spirit::x3::standard_wide;
BOOST_TEST(test(L"x", char_));
BOOST_TEST(test(L"x", char_(L'x')));
BOOST_TEST(!test(L"x", char_(L'y')));
//~ BOOST_TEST(test(L"x", char_(L'a', L'z')));
//~ BOOST_TEST(!test(L"x", char_(L'0', L'9')));
BOOST_TEST(!test(L"x", ~char_));
BOOST_TEST(!test(L"x", ~char_(L'x')));
BOOST_TEST(test(L" ", ~char_(L'x')));
BOOST_TEST(test(L"X", ~char_(L'x')));
//~ BOOST_TEST(!test(L"x", ~char_(L'b', L'y')));
//~ BOOST_TEST(test(L"a", ~char_(L'b', L'y')));
//~ BOOST_TEST(test(L"z", ~char_(L'b', L'y')));
BOOST_TEST(test(L"x", ~~char_));
BOOST_TEST(test(L"x", ~~char_(L'x')));
BOOST_TEST(!test(L" ", ~~char_(L'x')));
BOOST_TEST(!test(L"X", ~~char_(L'x')));
//~ BOOST_TEST(test(L"x", ~~char_(L'b', L'y')));
//~ BOOST_TEST(!test(L"a", ~~char_(L'b', L'y')));
//~ BOOST_TEST(!test(L"z", ~~char_(L'b', L'y')));
}
//~ { // single char strings!
//~ namespace ascii = boost::spirit::x3::ascii;
//~ namespace wide = boost::spirit::x3::standard_wide;
//~ BOOST_TEST(test("x", "x"));
//~ BOOST_TEST(test(L"x", L"x"));
//~ BOOST_TEST(test("x", ascii::char_("x")));
//~ BOOST_TEST(test(L"x", wide::char_(L"x")));
//~ BOOST_TEST(test("x", ascii::char_("a", "z")));
//~ BOOST_TEST(test(L"x", ascii::char_(L"a", L"z")));
//~ }
//~ {
//~ // chsets
//~ namespace ascii = boost::spirit::x3::ascii;
//~ namespace wide = boost::spirit::x3::standard_wide;
//~ BOOST_TEST(test("x", ascii::char_("a-z")));
//~ BOOST_TEST(!test("1", ascii::char_("a-z")));
//~ BOOST_TEST(test("1", ascii::char_("a-z0-9")));
//~ BOOST_TEST(test("x", wide::char_(L"a-z")));
//~ BOOST_TEST(!test("1", wide::char_(L"a-z")));
//~ BOOST_TEST(test("1", wide::char_(L"a-z0-9")));
//~ std::string set = "a-z0-9";
//~ BOOST_TEST(test("x", ascii::char_(set)));
//~ #ifdef SPIRIT_NO_COMPILE_CHECK
//~ test("", ascii::char_(L"a-z0-9"));
//~ #endif
//~ }
//~ { // lazy chars
//~ using namespace boost::spirit::x3::ascii;
//~ using boost::phoenix::val;
//~ using boost::phoenix::ref;
//~ using boost::spirit::x3::_1;
//~ BOOST_TEST((test("x", char_(val('x')))));
//~ BOOST_TEST((test("h", char_(val('a'), val('n')))));
//~ BOOST_TEST(test("0", char_(val("a-z0-9"))));
//~ char ch; // make sure lazy chars have an attribute
//~ BOOST_TEST(test("x", char_(val('x'))[ref(ch) = _1]));
//~ BOOST_TEST(ch == 'x');
//~ }
//~ { // testing "what"
//~ using boost::spirit::x3::what;
//~ using boost::spirit::x3::ascii::char_;
//~ using boost::spirit::x3::ascii::alpha;
//~ print_info(what('x'));
//~ print_info(what(char_('a','z')));
//~ print_info(what(alpha));
//~ }
return boost::report_errors();
}

257
test/x3/char_class.cpp Normal file
View File

@@ -0,0 +1,257 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Copyright (c) 2001-2010 Hartmut Kaiser
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
// this file intentionally contains non-ascii characters
// boostinspect:noascii
#define BOOST_SPIRIT_X3_UNICODE
#include <boost/detail/lightweight_test.hpp>
#include <boost/spirit/home/x3.hpp>
//~ #include <boost/phoenix/core.hpp>
//~ #include <boost/phoenix/operator.hpp>
#include <boost/type_traits/is_same.hpp>
#include <iostream>
#include "test.hpp"
int
main()
{
using spirit_test::test;
using spirit_test::test_attr;
using boost::spirit::x3::unused_type;
{
using namespace boost::spirit::x3::ascii;
BOOST_TEST(test("1", alnum));
BOOST_TEST(!test(" ", alnum));
BOOST_TEST(!test("1", alpha));
BOOST_TEST(test("x", alpha));
BOOST_TEST(test(" ", blank));
BOOST_TEST(!test("x", blank));
BOOST_TEST(test("1", digit));
BOOST_TEST(!test("x", digit));
BOOST_TEST(test("a", lower));
BOOST_TEST(!test("A", lower));
BOOST_TEST(test("!", punct));
BOOST_TEST(!test("x", punct));
BOOST_TEST(test(" ", space));
BOOST_TEST(test("\n", space));
BOOST_TEST(test("\r", space));
BOOST_TEST(test("\t", space));
BOOST_TEST(test("A", upper));
BOOST_TEST(!test("a", upper));
BOOST_TEST(test("A", xdigit));
BOOST_TEST(test("0", xdigit));
BOOST_TEST(test("f", xdigit));
BOOST_TEST(!test("g", xdigit));
}
{
using namespace boost::spirit::x3::ascii;
BOOST_TEST(!test("1", ~alnum));
BOOST_TEST(test(" ", ~alnum));
BOOST_TEST(test("1", ~alpha));
BOOST_TEST(!test("x", ~alpha));
BOOST_TEST(!test(" ", ~blank));
BOOST_TEST(test("x", ~blank));
BOOST_TEST(!test("1", ~digit));
BOOST_TEST(test("x", ~digit));
BOOST_TEST(!test("a", ~lower));
BOOST_TEST(test("A", ~lower));
BOOST_TEST(!test("!", ~punct));
BOOST_TEST(test("x", ~punct));
BOOST_TEST(!test(" ", ~space));
BOOST_TEST(!test("\n", ~space));
BOOST_TEST(!test("\r", ~space));
BOOST_TEST(!test("\t", ~space));
BOOST_TEST(!test("A", ~upper));
BOOST_TEST(test("a", ~upper));
BOOST_TEST(!test("A", ~xdigit));
BOOST_TEST(!test("0", ~xdigit));
BOOST_TEST(!test("f", ~xdigit));
BOOST_TEST(test("g", ~xdigit));
}
{
using namespace boost::spirit::x3::iso8859_1;
BOOST_TEST(test("1", alnum));
BOOST_TEST(!test(" ", alnum));
BOOST_TEST(!test("1", alpha));
BOOST_TEST(test("x", alpha));
BOOST_TEST(test(" ", blank));
BOOST_TEST(!test("x", blank));
BOOST_TEST(test("1", digit));
BOOST_TEST(!test("x", digit));
BOOST_TEST(test("a", lower));
BOOST_TEST(!test("A", lower));
BOOST_TEST(test("!", punct));
BOOST_TEST(!test("x", punct));
BOOST_TEST(test(" ", space));
BOOST_TEST(test("\n", space));
BOOST_TEST(test("\r", space));
BOOST_TEST(test("\t", space));
BOOST_TEST(test("A", upper));
BOOST_TEST(!test("a", upper));
BOOST_TEST(test("A", xdigit));
BOOST_TEST(test("0", xdigit));
BOOST_TEST(test("f", xdigit));
BOOST_TEST(!test("g", xdigit));
// needed for VC7.1 only
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
#pragma setlocale("german")
#endif
BOOST_TEST(test("é", alpha));
BOOST_TEST(test("é", lower));
BOOST_TEST(!test("é", upper));
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
#pragma setlocale("")
#endif
}
{
using namespace boost::spirit::x3::standard;
BOOST_TEST(test("1", alnum));
BOOST_TEST(!test(" ", alnum));
BOOST_TEST(!test("1", alpha));
BOOST_TEST(test("x", alpha));
BOOST_TEST(test(" ", blank));
BOOST_TEST(!test("x", blank));
BOOST_TEST(test("1", digit));
BOOST_TEST(!test("x", digit));
BOOST_TEST(test("a", lower));
BOOST_TEST(!test("A", lower));
BOOST_TEST(test("!", punct));
BOOST_TEST(!test("x", punct));
BOOST_TEST(test(" ", space));
BOOST_TEST(test("\n", space));
BOOST_TEST(test("\r", space));
BOOST_TEST(test("\t", space));
BOOST_TEST(test("A", upper));
BOOST_TEST(!test("a", upper));
BOOST_TEST(test("A", xdigit));
BOOST_TEST(test("0", xdigit));
BOOST_TEST(test("f", xdigit));
BOOST_TEST(!test("g", xdigit));
}
{
using namespace boost::spirit::x3::standard_wide;
BOOST_TEST(test(L"1", alnum));
BOOST_TEST(!test(L" ", alnum));
BOOST_TEST(!test(L"1", alpha));
BOOST_TEST(test(L"x", alpha));
BOOST_TEST(test(L" ", blank));
BOOST_TEST(!test(L"x", blank));
BOOST_TEST(test(L"1", digit));
BOOST_TEST(!test(L"x", digit));
BOOST_TEST(test(L"a", lower));
BOOST_TEST(!test(L"A", lower));
BOOST_TEST(test(L"!", punct));
BOOST_TEST(!test(L"x", punct));
BOOST_TEST(test(L" ", space));
BOOST_TEST(test(L"\n", space));
BOOST_TEST(test(L"\r", space));
BOOST_TEST(test(L"\t", space));
BOOST_TEST(test(L"A", upper));
BOOST_TEST(!test(L"a", upper));
BOOST_TEST(test(L"A", xdigit));
BOOST_TEST(test(L"0", xdigit));
BOOST_TEST(test(L"f", xdigit));
BOOST_TEST(!test(L"g", xdigit));
}
{
using namespace boost::spirit::x3::unicode;
BOOST_TEST(test(L"1", alnum));
BOOST_TEST(!test(L" ", alnum));
BOOST_TEST(!test(L"1", alpha));
BOOST_TEST(test(L"x", alpha));
BOOST_TEST(test(L" ", blank));
BOOST_TEST(!test(L"x", blank));
BOOST_TEST(test(L"1", digit));
BOOST_TEST(!test(L"x", digit));
BOOST_TEST(test(L"a", lower));
BOOST_TEST(!test(L"A", lower));
BOOST_TEST(test(L"!", punct));
BOOST_TEST(!test(L"x", punct));
BOOST_TEST(test(L" ", space));
BOOST_TEST(test(L"\n", space));
BOOST_TEST(test(L"\r", space));
BOOST_TEST(test(L"\t", space));
BOOST_TEST(test(L"A", upper));
BOOST_TEST(!test(L"a", upper));
BOOST_TEST(test(L"A", xdigit));
BOOST_TEST(test(L"0", xdigit));
BOOST_TEST(test(L"f", xdigit));
BOOST_TEST(!test(L"g", xdigit));
BOOST_TEST(test(L"A", alphabetic));
BOOST_TEST(test(L"9", decimal_number));
BOOST_TEST(test(L"\u2800", braille));
BOOST_TEST(!test(L" ", braille));
BOOST_TEST(test(L" ", ~braille));
// $$$ TODO $$$ Add more unicode tests
// needed for VC7.1 only
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
#pragma setlocale("german")
#endif
BOOST_TEST(test("é", alpha));
BOOST_TEST(test("é", lower));
BOOST_TEST(!test("é", upper));
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
#pragma setlocale("")
#endif
}
{ // test attribute extraction
using boost::spirit::x3::traits::attribute_of;
using boost::spirit::x3::iso8859_1::alpha;
using boost::spirit::x3::iso8859_1::alpha_type;
static_assert(
boost::is_same<
attribute_of<alpha_type, unused_type>::type
, unsigned char>::value
, "Wrong attribute type!"
);
int attr = 0;
BOOST_TEST(test_attr("a", alpha, attr));
BOOST_TEST(attr == 'a');
}
{ // test attribute extraction
using boost::spirit::x3::iso8859_1::alpha;
using boost::spirit::x3::iso8859_1::space;
char attr = 0;
BOOST_TEST(test_attr(" a", alpha, attr, space));
BOOST_TEST(attr == 'a');
}
// $$$ Not yet implemented $$$
//~ { // test action
//~ using namespace boost::spirit::x3::ascii;
//~ using boost::phoenix::ref;
//~ using boost::spirit::x3::_1;
//~ char ch;
//~ BOOST_TEST(test("x", alnum[ref(ch) = _1]));
//~ BOOST_TEST(ch == 'x');
//~ BOOST_TEST(test(" A", alnum[ref(ch) = _1], space));
//~ BOOST_TEST(ch == 'A');
//~ }
return boost::report_errors();
}

121
test/x3/debug.cpp Normal file
View File

@@ -0,0 +1,121 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#define BOOST_SPIRIT_X3_DEBUG
#include <boost/detail/lightweight_test.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/fusion/include/vector.hpp>
#include <vector>
#include <string>
#include <cstring>
#include <iostream>
#include "test.hpp"
struct my_error_handler
{
template <typename Iterator, typename Exception, typename Context>
boost::spirit::x3::error_handler_result
operator()(Iterator&, Exception const& x, Context const&) const
{
std::cout
<< "Error! Expecting: "
<< x.what_
<< ", got: \""
<< std::string(x.first, x.last)
<< "\""
<< std::endl;
return boost::spirit::x3::fail;
}
};
int
main()
{
using spirit_test::test_attr;
using spirit_test::test;
using namespace boost::spirit::x3::ascii;
//~ using namespace boost::spirit::x3::labels;
//~ using boost::spirit::x3::locals;
using boost::spirit::x3::rule;
using boost::spirit::x3::int_;
//~ using boost::spirit::x3::fail;
//~ using boost::spirit::x3::on_error;
//~ using boost::spirit::x3::debug;
using boost::spirit::x3::alpha;
//~ namespace phx = boost::phoenix;
{ // basic tests
auto a = rule<class a>("a") = 'a';
auto b = rule<class b>("b") = 'b';
auto c = rule<class c>("c") = 'c';
{
auto start = *(a | b | c);
BOOST_TEST(test("abcabcacb", start));
}
{
rule<class start> start("start");
auto start_def =
start = (a | b) >> (start | b);
BOOST_TEST(test("aaaabababaaabbb", start_def));
BOOST_TEST(test("aaaabababaaabba", start_def, false));
}
}
{ // basic tests w/ skipper
auto a = rule<class a>("a") = 'a';
auto b = rule<class b>("b") = 'b';
auto c = rule<class c>("c") = 'c';
{
auto start = *(a | b | c);
BOOST_TEST(test(" a b c a b c a c b ", start, space));
}
{
rule<class start> start("start");
auto start_def =
start = (a | b) >> (start | b);
BOOST_TEST(test(" a a a a b a b a b a a a b b b ", start_def, space));
BOOST_TEST(test(" a a a a b a b a b a a a b b a ", start_def, space, false));
}
}
{ // std::container attributes
typedef boost::fusion::vector<int, char> fs;
rule<class start, std::vector<fs>> start("start");
auto start_def =
start = *(int_ >> alpha);
BOOST_TEST(test("1 a 2 b 3 c", start_def, space));
}
{ // error handling
auto r_def = '(' > int_ > ',' > int_ > ')';
auto r = r_def.on_error(my_error_handler());
BOOST_TEST(test("(123,456)", r));
BOOST_TEST(!test("(abc,def)", r));
BOOST_TEST(!test("(123,456]", r));
BOOST_TEST(!test("(123;456)", r));
BOOST_TEST(!test("[123,456]", r));
}
return boost::report_errors();
}

82
test/x3/difference.cpp Normal file
View File

@@ -0,0 +1,82 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#include <boost/detail/lightweight_test.hpp>
#include <boost/spirit/home/x3.hpp>
//~ #include <boost/phoenix/core.hpp>
//~ #include <boost/phoenix/operator.hpp>
#include <string>
#include <iostream>
#include "test.hpp"
int
main()
{
using boost::spirit::x3::ascii::char_;
using boost::spirit::x3::lit;
using spirit_test::test;
using spirit_test::test_attr;
// Basic tests
{
BOOST_TEST(test("b", char_ - 'a'));
BOOST_TEST(!test("a", char_ - 'a'));
BOOST_TEST(test("/* abcdefghijk */", "/*" >> *(char_ - "*/") >> "*/"));
BOOST_TEST(!test("switch", lit("switch") - "switch"));
}
// Test attributes
{
char attr;
BOOST_TEST(test_attr("xg", (char_ - 'g') >> 'g', attr));
BOOST_TEST(attr == 'x');
}
// Test handling of container attributes
{
std::string attr;
BOOST_TEST(test_attr("abcdefg", *(char_ - 'g') >> 'g', attr));
BOOST_TEST(attr == "abcdef");
}
// $$$ Not yet implemented
//~ {
//~ BOOST_TEST(test("b", char_ - no_case['a']));
//~ BOOST_TEST(!test("a", char_ - no_case['a']));
//~ BOOST_TEST(!test("A", char_ - no_case['a']));
//~ BOOST_TEST(test("b", no_case[lower - 'a']));
//~ BOOST_TEST(test("B", no_case[lower - 'a']));
//~ BOOST_TEST(!test("a", no_case[lower - 'a']));
//~ BOOST_TEST(!test("A", no_case[lower - 'a']));
//~ }
// $$$ Not yet implemented
//~ {
//~ using boost::spirit::x3::_1;
//~ namespace phx = boost::phoenix;
//~ std::string s;
//~ BOOST_TEST(test(
//~ "/*abcdefghijk*/"
//~ , "/*" >> *(char_ - "*/")[phx::ref(s) += _1] >> "*/"
//~ ));
//~ BOOST_TEST(s == "abcdefghijk");
//~ s.clear();
//~ BOOST_TEST(test(
//~ " /*abcdefghijk*/"
//~ , "/*" >> *(char_ - "*/")[phx::ref(s) += _1] >> "*/"
//~ , space
//~ ));
//~ BOOST_TEST(s == "abcdefghijk");
//~ }
return boost::report_errors();
}

29
test/x3/eoi.cpp Normal file
View File

@@ -0,0 +1,29 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#include <boost/detail/lightweight_test.hpp>
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include "test.hpp"
int
main()
{
using spirit_test::test;
using boost::spirit::x3::eoi;
{
BOOST_TEST((test("", eoi)));
BOOST_TEST(!(test("x", eoi)));
}
{
BOOST_TEST(what(eoi) == "eoi");
}
return boost::report_errors();
}

32
test/x3/eol.cpp Normal file
View File

@@ -0,0 +1,32 @@
/*=============================================================================
Copyright (c) 2001-2013 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#include <boost/detail/lightweight_test.hpp>
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include "test.hpp"
int
main()
{
using spirit_test::test;
using boost::spirit::x3::eol;
{
BOOST_TEST((test("\r\n", eol)));
BOOST_TEST((test("\r", eol)));
BOOST_TEST((test("\n", eol)));
BOOST_TEST((!test("\n\r", eol)));
BOOST_TEST((!test("", eol)));
}
{
BOOST_TEST(what(eol) == "eol");
}
return boost::report_errors();
}

Some files were not shown because too many files have changed in this diff Show More