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:
BIN
doc/x3/cppnow_2013/Inside Spirit X3.pptx
Normal file
BIN
doc/x3/cppnow_2013/Inside Spirit X3.pptx
Normal file
Binary file not shown.
281
example/x3/calc4.cpp
Normal file
281
example/x3/calc4.cpp
Normal 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
275
example/x3/calc4b.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
27
include/boost/spirit/home/x3.hpp
Normal file
27
include/boost/spirit/home/x3.hpp
Normal 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
|
||||
24
include/boost/spirit/home/x3/auxiliary.hpp
Normal file
24
include/boost/spirit/home/x3/auxiliary.hpp
Normal 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
|
||||
74
include/boost/spirit/home/x3/auxiliary/action.hpp
Normal file
74
include/boost/spirit/home/x3/auxiliary/action.hpp
Normal 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
|
||||
133
include/boost/spirit/home/x3/auxiliary/attr.hpp
Normal file
133
include/boost/spirit/home/x3/auxiliary/attr.hpp
Normal 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
|
||||
45
include/boost/spirit/home/x3/auxiliary/eoi.hpp
Normal file
45
include/boost/spirit/home/x3/auxiliary/eoi.hpp
Normal 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
|
||||
59
include/boost/spirit/home/x3/auxiliary/eol.hpp
Normal file
59
include/boost/spirit/home/x3/auxiliary/eol.hpp
Normal 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
|
||||
91
include/boost/spirit/home/x3/auxiliary/eps.hpp
Normal file
91
include/boost/spirit/home/x3/auxiliary/eps.hpp
Normal 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
|
||||
72
include/boost/spirit/home/x3/auxiliary/guard.hpp
Normal file
72
include/boost/spirit/home/x3/auxiliary/guard.hpp
Normal 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
|
||||
23
include/boost/spirit/home/x3/char.hpp
Normal file
23
include/boost/spirit/home/x3/char.hpp
Normal 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
|
||||
41
include/boost/spirit/home/x3/char/any_char.hpp
Normal file
41
include/boost/spirit/home/x3/char/any_char.hpp
Normal 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
|
||||
88
include/boost/spirit/home/x3/char/char.hpp
Normal file
88
include/boost/spirit/home/x3/char/char.hpp
Normal 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
|
||||
148
include/boost/spirit/home/x3/char/char_class.hpp
Normal file
148
include/boost/spirit/home/x3/char/char_class.hpp
Normal 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
|
||||
44
include/boost/spirit/home/x3/char/char_parser.hpp
Normal file
44
include/boost/spirit/home/x3/char/char_parser.hpp
Normal 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
|
||||
58
include/boost/spirit/home/x3/char/detail/cast_char.hpp
Normal file
58
include/boost/spirit/home/x3/char/detail/cast_char.hpp
Normal 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
|
||||
|
||||
|
||||
54
include/boost/spirit/home/x3/char/literal_char.hpp
Normal file
54
include/boost/spirit/home/x3/char/literal_char.hpp
Normal 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
|
||||
65
include/boost/spirit/home/x3/char/negated_char_parser.hpp
Normal file
65
include/boost/spirit/home/x3/char/negated_char_parser.hpp
Normal 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
|
||||
617
include/boost/spirit/home/x3/char/unicode.hpp
Normal file
617
include/boost/spirit/home/x3/char/unicode.hpp
Normal 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
|
||||
19
include/boost/spirit/home/x3/core.hpp
Normal file
19
include/boost/spirit/home/x3/core.hpp
Normal 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
|
||||
@@ -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
|
||||
102
include/boost/spirit/home/x3/core/parse.hpp
Normal file
102
include/boost/spirit/home/x3/core/parse.hpp
Normal 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
|
||||
|
||||
250
include/boost/spirit/home/x3/core/parser.hpp
Normal file
250
include/boost/spirit/home/x3/core/parser.hpp
Normal 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
|
||||
52
include/boost/spirit/home/x3/core/proxy.hpp
Normal file
52
include/boost/spirit/home/x3/core/proxy.hpp
Normal 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
|
||||
104
include/boost/spirit/home/x3/core/skip_over.hpp
Normal file
104
include/boost/spirit/home/x3/core/skip_over.hpp
Normal 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
|
||||
27
include/boost/spirit/home/x3/directive.hpp
Normal file
27
include/boost/spirit/home/x3/directive.hpp
Normal 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
|
||||
73
include/boost/spirit/home/x3/directive/expect.hpp
Normal file
73
include/boost/spirit/home/x3/directive/expect.hpp
Normal 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
|
||||
80
include/boost/spirit/home/x3/directive/lexeme.hpp
Normal file
80
include/boost/spirit/home/x3/directive/lexeme.hpp
Normal 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
|
||||
78
include/boost/spirit/home/x3/directive/no_skip.hpp
Normal file
78
include/boost/spirit/home/x3/directive/no_skip.hpp
Normal 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
|
||||
55
include/boost/spirit/home/x3/directive/omit.hpp
Normal file
55
include/boost/spirit/home/x3/directive/omit.hpp
Normal 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
|
||||
118
include/boost/spirit/home/x3/directive/skip.hpp
Normal file
118
include/boost/spirit/home/x3/directive/skip.hpp
Normal 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
|
||||
20
include/boost/spirit/home/x3/nonterminal.hpp
Normal file
20
include/boost/spirit/home/x3/nonterminal.hpp
Normal 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
|
||||
@@ -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
|
||||
189
include/boost/spirit/home/x3/nonterminal/detail/rule.hpp
Normal file
189
include/boost/spirit/home/x3/nonterminal/detail/rule.hpp
Normal 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
|
||||
@@ -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
|
||||
161
include/boost/spirit/home/x3/nonterminal/grammar.hpp
Normal file
161
include/boost/spirit/home/x3/nonterminal/grammar.hpp
Normal 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
|
||||
142
include/boost/spirit/home/x3/nonterminal/rule.hpp
Normal file
142
include/boost/spirit/home/x3/nonterminal/rule.hpp
Normal 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
|
||||
150
include/boost/spirit/home/x3/nonterminal/simple_trace.hpp
Normal file
150
include/boost/spirit/home/x3/nonterminal/simple_trace.hpp
Normal 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
|
||||
19
include/boost/spirit/home/x3/numeric.hpp
Normal file
19
include/boost/spirit/home/x3/numeric.hpp
Normal 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
|
||||
66
include/boost/spirit/home/x3/numeric/int.hpp
Normal file
66
include/boost/spirit/home/x3/numeric/int.hpp
Normal 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
|
||||
66
include/boost/spirit/home/x3/numeric/real.hpp
Normal file
66
include/boost/spirit/home/x3/numeric/real.hpp
Normal 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
|
||||
186
include/boost/spirit/home/x3/numeric/real_policies.hpp
Normal file
186
include/boost/spirit/home/x3/numeric/real_policies.hpp
Normal 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
|
||||
79
include/boost/spirit/home/x3/numeric/uint.hpp
Normal file
79
include/boost/spirit/home/x3/numeric/uint.hpp
Normal 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
|
||||
26
include/boost/spirit/home/x3/operator.hpp
Normal file
26
include/boost/spirit/home/x3/operator.hpp
Normal 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
|
||||
67
include/boost/spirit/home/x3/operator/alternative.hpp
Normal file
67
include/boost/spirit/home/x3/operator/alternative.hpp
Normal 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
|
||||
46
include/boost/spirit/home/x3/operator/and_predicate.hpp
Normal file
46
include/boost/spirit/home/x3/operator/and_predicate.hpp
Normal 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
|
||||
366
include/boost/spirit/home/x3/operator/detail/alternative.hpp
Normal file
366
include/boost/spirit/home/x3/operator/detail/alternative.hpp
Normal 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
|
||||
425
include/boost/spirit/home/x3/operator/detail/sequence.hpp
Normal file
425
include/boost/spirit/home/x3/operator/detail/sequence.hpp
Normal 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
|
||||
74
include/boost/spirit/home/x3/operator/difference.hpp
Normal file
74
include/boost/spirit/home/x3/operator/difference.hpp
Normal 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
|
||||
58
include/boost/spirit/home/x3/operator/kleene.hpp
Normal file
58
include/boost/spirit/home/x3/operator/kleene.hpp
Normal 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
|
||||
72
include/boost/spirit/home/x3/operator/list.hpp
Normal file
72
include/boost/spirit/home/x3/operator/list.hpp
Normal 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
|
||||
46
include/boost/spirit/home/x3/operator/not_predicate.hpp
Normal file
46
include/boost/spirit/home/x3/operator/not_predicate.hpp
Normal 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
|
||||
82
include/boost/spirit/home/x3/operator/optional.hpp
Normal file
82
include/boost/spirit/home/x3/operator/optional.hpp
Normal 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
|
||||
62
include/boost/spirit/home/x3/operator/plus.hpp
Normal file
62
include/boost/spirit/home/x3/operator/plus.hpp
Normal 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
|
||||
79
include/boost/spirit/home/x3/operator/sequence.hpp
Normal file
79
include/boost/spirit/home/x3/operator/sequence.hpp
Normal 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
|
||||
17
include/boost/spirit/home/x3/string.hpp
Normal file
17
include/boost/spirit/home/x3/string.hpp
Normal 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
|
||||
89
include/boost/spirit/home/x3/string/detail/string_parse.hpp
Normal file
89
include/boost/spirit/home/x3/string/detail/string_parse.hpp
Normal 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
|
||||
213
include/boost/spirit/home/x3/string/detail/tst.hpp
Normal file
213
include/boost/spirit/home/x3/string/detail/tst.hpp
Normal 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
|
||||
124
include/boost/spirit/home/x3/string/literal_string.hpp
Normal file
124
include/boost/spirit/home/x3/string/literal_string.hpp
Normal 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
|
||||
358
include/boost/spirit/home/x3/string/symbols.hpp
Normal file
358
include/boost/spirit/home/x3/string/symbols.hpp
Normal 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
|
||||
137
include/boost/spirit/home/x3/string/tst.hpp
Normal file
137
include/boost/spirit/home/x3/string/tst.hpp
Normal 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
|
||||
216
include/boost/spirit/home/x3/string/tst_map.hpp
Normal file
216
include/boost/spirit/home/x3/string/tst_map.hpp
Normal 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
|
||||
110
include/boost/spirit/home/x3/support/context.hpp
Normal file
110
include/boost/spirit/home/x3/support/context.hpp
Normal 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
116
include/boost/spirit/home/x3/support/numeric_utils/pow10.hpp
Normal file
116
include/boost/spirit/home/x3/support/numeric_utils/pow10.hpp
Normal 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
|
||||
48
include/boost/spirit/home/x3/support/numeric_utils/sign.hpp
Normal file
48
include/boost/spirit/home/x3/support/numeric_utils/sign.hpp
Normal 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
|
||||
75
include/boost/spirit/home/x3/support/subcontext.hpp
Normal file
75
include/boost/spirit/home/x3/support/subcontext.hpp
Normal 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
|
||||
@@ -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
|
||||
59
include/boost/spirit/home/x3/support/traits/attribute_of.hpp
Normal file
59
include/boost/spirit/home/x3/support/traits/attribute_of.hpp
Normal 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
|
||||
@@ -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
|
||||
304
include/boost/spirit/home/x3/support/traits/container_traits.hpp
Normal file
304
include/boost/spirit/home/x3/support/traits/container_traits.hpp
Normal 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
45
include/boost/spirit/home/x3/support/traits/is_variant.hpp
Normal file
45
include/boost/spirit/home/x3/support/traits/is_variant.hpp
Normal 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
|
||||
@@ -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
|
||||
154
include/boost/spirit/home/x3/support/traits/move_to.hpp
Normal file
154
include/boost/spirit/home/x3/support/traits/move_to.hpp
Normal 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
|
||||
128
include/boost/spirit/home/x3/support/traits/numeric_traits.hpp
Normal file
128
include/boost/spirit/home/x3/support/traits/numeric_traits.hpp
Normal 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
|
||||
@@ -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
|
||||
150
include/boost/spirit/home/x3/support/traits/print_attribute.hpp
Normal file
150
include/boost/spirit/home/x3/support/traits/print_attribute.hpp
Normal 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
|
||||
79
include/boost/spirit/home/x3/support/traits/print_token.hpp
Normal file
79
include/boost/spirit/home/x3/support/traits/print_token.hpp
Normal 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
|
||||
291
include/boost/spirit/home/x3/support/traits/string_traits.hpp
Normal file
291
include/boost/spirit/home/x3/support/traits/string_traits.hpp
Normal 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
|
||||
@@ -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
|
||||
52
include/boost/spirit/home/x3/support/traits/tuple_traits.hpp
Normal file
52
include/boost/spirit/home/x3/support/traits/tuple_traits.hpp
Normal 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
|
||||
30
include/boost/spirit/home/x3/support/traits/value_traits.hpp
Normal file
30
include/boost/spirit/home/x3/support/traits/value_traits.hpp
Normal 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
|
||||
29
include/boost/spirit/home/x3/support/utility/sfinae.hpp
Normal file
29
include/boost/spirit/home/x3/support/utility/sfinae.hpp
Normal 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
|
||||
72
include/boost/spirit/home/x3/support/utility/utf8.hpp
Normal file
72
include/boost/spirit/home/x3/support/utility/utf8.hpp
Normal 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
5
test/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/bin/
|
||||
/.DS_Store
|
||||
/*.gitignore
|
||||
/test_dfa.hpp
|
||||
/test_switch.hpp
|
||||
293
test/x3/alternative.cpp
Normal file
293
test/x3/alternative.cpp
Normal 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
25
test/x3/and_predicate.cpp
Normal 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
65
test/x3/attr.cpp
Normal 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
155
test/x3/char1.cpp
Normal 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
257
test/x3/char_class.cpp
Normal 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
121
test/x3/debug.cpp
Normal 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
82
test/x3/difference.cpp
Normal 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
29
test/x3/eoi.cpp
Normal 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
32
test/x3/eol.cpp
Normal 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
Reference in New Issue
Block a user