mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 13:18:28 +00:00
unused
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@21889 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
d70c139c2f
commit
10e961f629
@ -1,96 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_ACTOR_ASSIGN_ACTOR_HPP
|
|
||||||
#define BOOST_SPIRIT_ACTOR_ASSIGN_ACTOR_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/actor/ref_value_actor.hpp>
|
|
||||||
#include <boost/spirit/actor/ref_const_ref_actor.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// Summary:
|
|
||||||
// A semantic action policy that applies the assignement operator.
|
|
||||||
// (This doc uses convention available in actors.hpp)
|
|
||||||
//
|
|
||||||
// Actions (what it does):
|
|
||||||
// ref = value;
|
|
||||||
// ref = T(first,last);
|
|
||||||
// ref = value_ref;
|
|
||||||
//
|
|
||||||
// Policy name:
|
|
||||||
// assign_action
|
|
||||||
//
|
|
||||||
// Policy holder, corresponding helper method:
|
|
||||||
// ref_value_actor, assign_a( ref );
|
|
||||||
// ref_const_ref_actor, assign_a( ref, value_ref );
|
|
||||||
//
|
|
||||||
// () operators: both
|
|
||||||
//
|
|
||||||
// See also ref_value_actor and ref_const_ref_actor for more details.
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct assign_action
|
|
||||||
{
|
|
||||||
template<
|
|
||||||
typename T,
|
|
||||||
typename ValueT
|
|
||||||
>
|
|
||||||
void act(T& ref_, ValueT const& value_) const
|
|
||||||
{
|
|
||||||
ref_ = value_;
|
|
||||||
}
|
|
||||||
template<
|
|
||||||
typename T,
|
|
||||||
typename IteratorT
|
|
||||||
>
|
|
||||||
void act(
|
|
||||||
T& ref_,
|
|
||||||
IteratorT const& first_,
|
|
||||||
IteratorT const& last_
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
typedef T value_type;
|
|
||||||
#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
|
|
||||||
value_type value(first_,last_);
|
|
||||||
#else
|
|
||||||
value_type value;
|
|
||||||
std::copy(first_, last_, std::inserter(value, value.end()));
|
|
||||||
#endif
|
|
||||||
ref_ = value;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Deprecated. Please use assign_a
|
|
||||||
template<typename T>
|
|
||||||
inline ref_value_actor<T,assign_action> assign(T& ref_)
|
|
||||||
{
|
|
||||||
return ref_value_actor<T,assign_action>(ref_);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline ref_value_actor<T,assign_action> assign_a(T& ref_)
|
|
||||||
{
|
|
||||||
return ref_value_actor<T,assign_action>(ref_);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<
|
|
||||||
typename T,
|
|
||||||
typename ValueT
|
|
||||||
>
|
|
||||||
inline ref_const_ref_actor<T,ValueT,assign_action> assign_a(
|
|
||||||
T& ref_,
|
|
||||||
ValueT const& value_
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return ref_const_ref_actor<T,ValueT,assign_action>(ref_,value_);
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,97 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_ACTOR_PUSH_BACK_ACTOR_HPP
|
|
||||||
#define BOOST_SPIRIT_ACTOR_PUSH_BACK_ACTOR_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/actor/ref_value_actor.hpp>
|
|
||||||
#include <boost/spirit/actor/ref_const_ref_actor.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// Summary:
|
|
||||||
//
|
|
||||||
// A semantic action policy that appends a value to the back of a
|
|
||||||
// container.
|
|
||||||
// (This doc uses convention available in actors.hpp)
|
|
||||||
//
|
|
||||||
// Actions (what it does and what ref, value_ref must support):
|
|
||||||
// ref.push_back( value );
|
|
||||||
// ref.push_back( T::value_type(first,last) );
|
|
||||||
// ref.push_back( value_ref );
|
|
||||||
//
|
|
||||||
// Policy name:
|
|
||||||
// push_back_action
|
|
||||||
//
|
|
||||||
// Policy holder, corresponding helper method:
|
|
||||||
// ref_value_actor, push_back_a( ref );
|
|
||||||
// ref_const_ref_actor, push_back_a( ref, value_ref );
|
|
||||||
//
|
|
||||||
// () operators: both
|
|
||||||
//
|
|
||||||
// See also ref_value_actor and ref_const_ref_actor for more details.
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct push_back_action
|
|
||||||
{
|
|
||||||
template<
|
|
||||||
typename T,
|
|
||||||
typename ValueT
|
|
||||||
>
|
|
||||||
void act(T& ref_, ValueT const& value_) const
|
|
||||||
{
|
|
||||||
ref_.push_back( value_ );
|
|
||||||
}
|
|
||||||
template<
|
|
||||||
typename T,
|
|
||||||
typename IteratorT
|
|
||||||
>
|
|
||||||
void act(
|
|
||||||
T& ref_,
|
|
||||||
IteratorT const& first_,
|
|
||||||
IteratorT const& last_
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
typedef typename T::value_type value_type;
|
|
||||||
value_type value(first_,last_);
|
|
||||||
|
|
||||||
ref_.push_back( value );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Deprecated interface. Use push_back_a
|
|
||||||
template<typename T>
|
|
||||||
inline ref_value_actor<T,push_back_action>
|
|
||||||
append(T& ref_)
|
|
||||||
{
|
|
||||||
return ref_value_actor<T,push_back_action>(ref_);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline ref_value_actor<T,push_back_action>
|
|
||||||
push_back_a(T& ref_)
|
|
||||||
{
|
|
||||||
return ref_value_actor<T,push_back_action>(ref_);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<
|
|
||||||
typename T,
|
|
||||||
typename ValueT
|
|
||||||
>
|
|
||||||
inline ref_const_ref_actor<T,ValueT,push_back_action>
|
|
||||||
push_back_a(
|
|
||||||
T& ref_,
|
|
||||||
ValueT const& value_
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return ref_const_ref_actor<T,ValueT,push_back_action>(ref_,value_);
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,73 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_ACTOR_REF_CONST_REF_ACTOR_HPP
|
|
||||||
#define BOOST_SPIRIT_ACTOR_REF_CONST_REF_ACTOR_HPP
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// Summary:
|
|
||||||
// A semantic action policy holder. This holder stores a reference to ref
|
|
||||||
// and a const reference to value_ref.
|
|
||||||
// act methods are feed with ref and value_ref. The parse result is
|
|
||||||
// not used by this holder.
|
|
||||||
//
|
|
||||||
// (This doc uses convention available in actors.hpp)
|
|
||||||
//
|
|
||||||
// Constructor:
|
|
||||||
// ...(T& ref_, ValueT const& value_ref_);
|
|
||||||
// where ref_ and value_ref_ are stored in the holder.
|
|
||||||
//
|
|
||||||
// Action calls:
|
|
||||||
// act(ref, value_ref);
|
|
||||||
//
|
|
||||||
// () operators: both
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template<
|
|
||||||
typename T,
|
|
||||||
typename ValueT,
|
|
||||||
typename ActionT
|
|
||||||
>
|
|
||||||
class ref_const_ref_actor : public ActionT
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
T& ref;
|
|
||||||
ValueT const& value_ref;
|
|
||||||
public:
|
|
||||||
ref_const_ref_actor(
|
|
||||||
T& ref_,
|
|
||||||
ValueT const& value_ref_
|
|
||||||
)
|
|
||||||
:
|
|
||||||
ref(ref_),
|
|
||||||
value_ref(value_ref_)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T2>
|
|
||||||
void operator()(T2 const& /*val*/) const
|
|
||||||
{
|
|
||||||
this->act(ref,value_ref); // defined in ActionT
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename IteratorT>
|
|
||||||
void operator()(
|
|
||||||
IteratorT const& /*first*/,
|
|
||||||
IteratorT const& /*last*/
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
this->act(ref,value_ref); // defined in ActionT
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,65 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_ACTOR_REF_VALUE_ACTOR_HPP
|
|
||||||
#define BOOST_SPIRIT_ACTOR_REF_VALUE_ACTOR_HPP
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// Summary:
|
|
||||||
// A semantic action policy holder. This holder stores a reference to ref.
|
|
||||||
// act methods are feed with ref and the parse result.
|
|
||||||
//
|
|
||||||
// (This doc uses convention available in actors.hpp)
|
|
||||||
//
|
|
||||||
// Constructor:
|
|
||||||
// ...(T& ref_);
|
|
||||||
// where ref_ is stored.
|
|
||||||
//
|
|
||||||
// Action calls:
|
|
||||||
// act(ref, value);
|
|
||||||
// act(ref, first,last);
|
|
||||||
//
|
|
||||||
// () operators: both
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template<
|
|
||||||
typename T,
|
|
||||||
typename ActionT
|
|
||||||
>
|
|
||||||
class ref_value_actor : public ActionT
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
T& ref;
|
|
||||||
public:
|
|
||||||
explicit
|
|
||||||
ref_value_actor(T& ref_)
|
|
||||||
: ref(ref_){}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T2>
|
|
||||||
void operator()(T2 const& val_) const
|
|
||||||
{
|
|
||||||
this->act(ref,val_); // defined in ActionT
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<typename IteratorT>
|
|
||||||
void operator()(
|
|
||||||
IteratorT const& first_,
|
|
||||||
IteratorT const& last_
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
this->act(ref,first_,last_); // defined in ActionT
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,38 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2001-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_ATTRIBUTE_MAIN_HPP)
|
|
||||||
#define BOOST_SPIRIT_ATTRIBUTE_MAIN_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/version.hpp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Master header for Spirit.Attributes
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Phoenix predefined maximum limit. This limit defines the maximum
|
|
||||||
// number of elements a tuple can hold. This number defaults to 3. The
|
|
||||||
// actual maximum is rounded up in multiples of 3. Thus, if this value
|
|
||||||
// is 4, the actual limit is 6. The ultimate maximum limit in this
|
|
||||||
// implementation is 15.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#if !defined(PHOENIX_LIMIT)
|
|
||||||
#define PHOENIX_LIMIT 3
|
|
||||||
#endif // !defined(PHOENIX_LIMIT)
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <boost/spirit/attribute/parametric.hpp>
|
|
||||||
#include <boost/spirit/attribute/closure.hpp>
|
|
||||||
|
|
||||||
#endif // !defined(BOOST_SPIRIT_ATTRIBUTE_MAIN_HPP)
|
|
File diff suppressed because it is too large
Load Diff
@ -1,51 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2002-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_CLOSURE_CONTEXT_HPP)
|
|
||||||
#define BOOST_SPIRIT_CLOSURE_CONTEXT_HPP
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED)
|
|
||||||
#define BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// closure_context_linker
|
|
||||||
// { helper template for the closure extendability }
|
|
||||||
//
|
|
||||||
// This classes can be 'overloaded' (defined elsewhere), to plug
|
|
||||||
// in additional functionality into the closure parsing process.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template<typename ContextT>
|
|
||||||
struct closure_context_linker : public ContextT
|
|
||||||
{
|
|
||||||
template <typename ParserT>
|
|
||||||
closure_context_linker(ParserT const& p)
|
|
||||||
: ContextT(p) {}
|
|
||||||
|
|
||||||
template <typename ParserT, typename ScannerT>
|
|
||||||
void pre_parse(ParserT const& p, ScannerT const& scan)
|
|
||||||
{ ContextT::pre_parse(p, scan); }
|
|
||||||
|
|
||||||
template <typename ResultT, typename ParserT, typename ScannerT>
|
|
||||||
ResultT&
|
|
||||||
post_parse(ResultT& hit, ParserT const& p, ScannerT const& scan)
|
|
||||||
{ return ContextT::post_parse(hit, p, scan); }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // !defined(BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED)
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif // BOOST_SPIRIT_CLOSURE_CONTEXT_HPP
|
|
@ -1,140 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2001-2003 Joel de Guzman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_PARAMETRIC_HPP
|
|
||||||
#define BOOST_SPIRIT_PARAMETRIC_HPP
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
#include <boost/spirit/core/primitives/primitives.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// f_chlit class [ functional version of chlit ]
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ChGenT>
|
|
||||||
struct f_chlit : public char_parser<f_chlit<ChGenT> >
|
|
||||||
{
|
|
||||||
f_chlit(ChGenT chgen_)
|
|
||||||
: chgen(chgen_) {}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool test(T ch) const
|
|
||||||
{ return ch == chgen(); }
|
|
||||||
|
|
||||||
ChGenT chgen;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ChGenT>
|
|
||||||
inline f_chlit<ChGenT>
|
|
||||||
f_ch_p(ChGenT chgen)
|
|
||||||
{ return f_chlit<ChGenT>(chgen); }
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// f_range class [ functional version of range ]
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ChGenAT, typename ChGenBT>
|
|
||||||
struct f_range : public char_parser<f_range<ChGenAT, ChGenBT> >
|
|
||||||
{
|
|
||||||
f_range(ChGenAT first_, ChGenBT last_)
|
|
||||||
: first(first_), last(last_)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool test(T ch) const
|
|
||||||
{
|
|
||||||
BOOST_SPIRIT_ASSERT(first() <= last());
|
|
||||||
return (ch >= first()) && (ch <= last());
|
|
||||||
}
|
|
||||||
|
|
||||||
ChGenAT first;
|
|
||||||
ChGenBT last;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ChGenAT, typename ChGenBT>
|
|
||||||
inline f_range<ChGenAT, ChGenBT>
|
|
||||||
f_range_p(ChGenAT first, ChGenBT last)
|
|
||||||
{ return f_range<ChGenAT, ChGenBT>(first, last); }
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// f_chseq class [ functional version of chseq ]
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename IterGenAT, typename IterGenBT>
|
|
||||||
class f_chseq : public parser<f_chseq<IterGenAT, IterGenBT> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef f_chseq<IterGenAT, IterGenBT> self_t;
|
|
||||||
|
|
||||||
f_chseq(IterGenAT first_, IterGenBT last_)
|
|
||||||
: first(first_), last(last_) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
return impl::string_parser_parse<result_t>(first(), last(), scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
IterGenAT first;
|
|
||||||
IterGenBT last;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename IterGenAT, typename IterGenBT>
|
|
||||||
inline f_chseq<IterGenAT, IterGenBT>
|
|
||||||
f_chseq_p(IterGenAT first, IterGenBT last)
|
|
||||||
{ return f_chseq<IterGenAT, IterGenBT>(first, last); }
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// f_strlit class [ functional version of strlit ]
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename IterGenAT, typename IterGenBT>
|
|
||||||
class f_strlit : public parser<f_strlit<IterGenAT, IterGenBT> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef f_strlit<IterGenAT, IterGenBT> self_t;
|
|
||||||
|
|
||||||
f_strlit(IterGenAT first, IterGenBT last)
|
|
||||||
: seq(first, last) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
return impl::contiguous_parser_parse<result_t>
|
|
||||||
(seq, scan, scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
f_chseq<IterGenAT, IterGenBT> seq;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename IterGenAT, typename IterGenBT>
|
|
||||||
inline f_strlit<IterGenAT, IterGenBT>
|
|
||||||
f_str_p(IterGenAT first, IterGenBT last)
|
|
||||||
{ return f_strlit<IterGenAT, IterGenBT>(first, last); }
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,74 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001-2003 Daniel Nuffer
|
|
||||||
Copyright (c) 2001-2003 Hartmut Kaiser
|
|
||||||
Copyright (c) 2002-2003 Martin Wille
|
|
||||||
Copyright (c) 2002 Raghavendra Satish
|
|
||||||
Copyright (c) 2001 Bruce Florman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_CORE_MAIN_HPP)
|
|
||||||
#define BOOST_SPIRIT_CORE_MAIN_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/version.hpp>
|
|
||||||
#include <boost/spirit/debug.hpp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Spirit.Core includes
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Spirit.Core.Kernel
|
|
||||||
#include <boost/spirit/core/config.hpp>
|
|
||||||
#include <boost/spirit/core/nil.hpp>
|
|
||||||
#include <boost/spirit/core/match.hpp>
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
|
|
||||||
// Spirit.Core.Primitives
|
|
||||||
#include <boost/spirit/core/primitives/primitives.hpp>
|
|
||||||
#include <boost/spirit/core/primitives/numerics.hpp>
|
|
||||||
|
|
||||||
// Spirit.Core.Scanner
|
|
||||||
#include <boost/spirit/core/scanner/scanner.hpp>
|
|
||||||
#include <boost/spirit/core/scanner/skipper.hpp>
|
|
||||||
|
|
||||||
// Spirit.Core.NonTerminal
|
|
||||||
#include <boost/spirit/core/non_terminal/subrule.hpp>
|
|
||||||
#include <boost/spirit/core/non_terminal/rule.hpp>
|
|
||||||
#include <boost/spirit/core/non_terminal/grammar.hpp>
|
|
||||||
|
|
||||||
// Spirit.Core.Composite
|
|
||||||
#include <boost/spirit/core/composite/actions.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
#include <boost/spirit/core/composite/directives.hpp>
|
|
||||||
#include <boost/spirit/core/composite/epsilon.hpp>
|
|
||||||
#include <boost/spirit/core/composite/sequence.hpp>
|
|
||||||
#include <boost/spirit/core/composite/sequential_and.hpp>
|
|
||||||
#include <boost/spirit/core/composite/sequential_or.hpp>
|
|
||||||
#include <boost/spirit/core/composite/alternative.hpp>
|
|
||||||
#include <boost/spirit/core/composite/difference.hpp>
|
|
||||||
#include <boost/spirit/core/composite/intersection.hpp>
|
|
||||||
#include <boost/spirit/core/composite/exclusive_or.hpp>
|
|
||||||
#include <boost/spirit/core/composite/kleene_star.hpp>
|
|
||||||
#include <boost/spirit/core/composite/positive.hpp>
|
|
||||||
#include <boost/spirit/core/composite/optional.hpp>
|
|
||||||
#include <boost/spirit/core/composite/list.hpp>
|
|
||||||
#include <boost/spirit/core/composite/no_actions.hpp>
|
|
||||||
|
|
||||||
// Deprecated interface includes
|
|
||||||
#include <boost/spirit/actor/assign_actor.hpp>
|
|
||||||
#include <boost/spirit/actor/push_back_actor.hpp>
|
|
||||||
|
|
||||||
#if defined(BOOST_SPIRIT_DEBUG)
|
|
||||||
//////////////////////////////////
|
|
||||||
#include <boost/spirit/debug/parser_names.hpp>
|
|
||||||
|
|
||||||
#endif // BOOST_SPIRIT_DEBUG
|
|
||||||
|
|
||||||
#endif // BOOST_SPIRIT_CORE_MAIN_HPP
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2001-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_ASSERT_HPP)
|
|
||||||
#define BOOST_SPIRIT_ASSERT_HPP
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <boost/throw_exception.hpp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// BOOST_SPIRIT_ASSERT is used throughout the framework. It can be
|
|
||||||
// overridden by the user. If BOOST_SPIRIT_ASSERT_EXCEPTION is defined,
|
|
||||||
// then that will be thrown, otherwise, BOOST_SPIRIT_ASSERT simply turns
|
|
||||||
// into a plain assert()
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#if !defined(BOOST_SPIRIT_ASSERT)
|
|
||||||
#if defined(NDEBUG)
|
|
||||||
#define BOOST_SPIRIT_ASSERT(x)
|
|
||||||
#elif defined (BOOST_SPIRIT_ASSERT_EXCEPTION)
|
|
||||||
#define BOOST_SPIRIT_ASSERT_AUX(f, l, x) BOOST_SPIRIT_ASSERT_AUX2(f, l, x)
|
|
||||||
#define BOOST_SPIRIT_ASSERT_AUX2(f, l, x) \
|
|
||||||
do{ if (!(x)) boost::throw_exception( \
|
|
||||||
BOOST_SPIRIT_ASSERT_EXCEPTION(f "(" #l "): " #x)); } while(0)
|
|
||||||
#define BOOST_SPIRIT_ASSERT(x) BOOST_SPIRIT_ASSERT_AUX(__FILE__, __LINE__, x)
|
|
||||||
#else
|
|
||||||
#include <cassert>
|
|
||||||
#define BOOST_SPIRIT_ASSERT(x) assert(x)
|
|
||||||
#endif
|
|
||||||
#endif // !defined(BOOST_SPIRIT_ASSERT)
|
|
||||||
|
|
||||||
#endif // BOOST_SPIRIT_ASSERT_HPP
|
|
@ -1,123 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_ACTIONS_HPP
|
|
||||||
#define BOOST_SPIRIT_ACTIONS_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// action class
|
|
||||||
//
|
|
||||||
// The action class binds a parser with a user defined semantic
|
|
||||||
// action. Instances of action are never created manually. Instead,
|
|
||||||
// action objects are typically created indirectly through
|
|
||||||
// expression templates of the form:
|
|
||||||
//
|
|
||||||
// p[f]
|
|
||||||
//
|
|
||||||
// where p is a parser and f is a function or functor. The semantic
|
|
||||||
// action may be a function or a functor. When the parser is
|
|
||||||
// successful, the actor calls the scanner's action_policy policy
|
|
||||||
// (see scanner.hpp):
|
|
||||||
//
|
|
||||||
// scan.do_action(actor, attribute, first, last);
|
|
||||||
//
|
|
||||||
// passing in these information:
|
|
||||||
//
|
|
||||||
// actor: The action's function or functor
|
|
||||||
// attribute: The match (returned by the parser) object's
|
|
||||||
// attribute (see match.hpp)
|
|
||||||
// first: Iterator pointing to the start of the matching
|
|
||||||
// portion of the input
|
|
||||||
// last: Iterator pointing to one past the end of the
|
|
||||||
// matching portion of the input
|
|
||||||
//
|
|
||||||
// It is the responsibility of the scanner's action_policy policy to
|
|
||||||
// dispatch the function or functor as it sees fit. The expected
|
|
||||||
// function or functor signature depends on the parser being
|
|
||||||
// wrapped. In general, if the attribute type of the parser being
|
|
||||||
// wrapped is a nil_t, the function or functor expect the signature:
|
|
||||||
//
|
|
||||||
// void func(Iterator first, Iterator last); // functions
|
|
||||||
//
|
|
||||||
// struct ftor // functors
|
|
||||||
// {
|
|
||||||
// void func(Iterator first, Iterator last) const;
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// where Iterator is the type of the iterator that is being used and
|
|
||||||
// first and last are the iterators pointing to the matching portion
|
|
||||||
// of the input.
|
|
||||||
//
|
|
||||||
// If the attribute type of the parser being wrapped is not a nil_t,
|
|
||||||
// the function or functor usually expect the signature:
|
|
||||||
//
|
|
||||||
// void func(T val); // functions
|
|
||||||
//
|
|
||||||
// struct ftor // functors
|
|
||||||
// {
|
|
||||||
// void func(T val) const;
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// where T is the attribute type and val is the attribute value
|
|
||||||
// returned by the parser being wrapped.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ParserT, typename ActionT>
|
|
||||||
class action : public unary<ParserT, parser<action<ParserT, ActionT> > >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef action<ParserT, ActionT> self_t;
|
|
||||||
typedef action_parser_category parser_category_t;
|
|
||||||
typedef unary<ParserT, parser<self_t> > base_t;
|
|
||||||
typedef ActionT predicate_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename parser_result<ParserT, ScannerT>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
action(ParserT const& p, ActionT const& a)
|
|
||||||
: base_t(p)
|
|
||||||
, actor(a) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename ScannerT::iterator_t iterator_t;
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
|
|
||||||
scan.at_end(); // allow skipper to take effect
|
|
||||||
iterator_t save = scan.first;
|
|
||||||
result_t hit = this->subject().parse(scan);
|
|
||||||
if (hit)
|
|
||||||
{
|
|
||||||
typename result_t::return_t val = hit.value();
|
|
||||||
scan.do_action(actor, val, save, scan.first);
|
|
||||||
}
|
|
||||||
return hit;
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionT const& predicate() const { return actor; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
ActionT actor;
|
|
||||||
};
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,134 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_ALTERNATIVE_HPP)
|
|
||||||
#define BOOST_SPIRIT_ALTERNATIVE_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/primitives/primitives.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
#include <boost/spirit/meta/as_parser.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// alternative class
|
|
||||||
//
|
|
||||||
// Handles expressions of the form:
|
|
||||||
//
|
|
||||||
// a | b
|
|
||||||
//
|
|
||||||
// where a and b are parsers. The expression returns a composite
|
|
||||||
// parser that matches a or b. One (not both) of the operands may
|
|
||||||
// be a literal char, wchar_t or a primitive string char const*,
|
|
||||||
// wchar_t const*.
|
|
||||||
//
|
|
||||||
// The expression is short circuit evaluated. b is never touched
|
|
||||||
// when a is returns a successful match.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct alternative_parser_gen;
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct alternative
|
|
||||||
: public binary<A, B, parser<alternative<A, B> > >
|
|
||||||
{
|
|
||||||
typedef alternative<A, B> self_t;
|
|
||||||
typedef binary_parser_category parser_category_t;
|
|
||||||
typedef alternative_parser_gen parser_generator_t;
|
|
||||||
typedef binary<A, B, parser<self_t> > base_t;
|
|
||||||
|
|
||||||
alternative(A const& a, B const& b)
|
|
||||||
: base_t(a, b) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
typedef typename ScannerT::iterator_t iterator_t;
|
|
||||||
{ // scope for save
|
|
||||||
iterator_t save = scan.first;
|
|
||||||
if (result_t hit = this->left().parse(scan))
|
|
||||||
return hit;
|
|
||||||
scan.first = save;
|
|
||||||
}
|
|
||||||
return this->right().parse(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct alternative_parser_gen
|
|
||||||
{
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
alternative<
|
|
||||||
typename as_parser<A>::type
|
|
||||||
, typename as_parser<B>::type
|
|
||||||
>
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
static alternative<
|
|
||||||
typename as_parser<A>::type
|
|
||||||
, typename as_parser<B>::type
|
|
||||||
>
|
|
||||||
generate(A const& a, B const& b)
|
|
||||||
{
|
|
||||||
return alternative<BOOST_DEDUCED_TYPENAME as_parser<A>::type,
|
|
||||||
BOOST_DEDUCED_TYPENAME as_parser<B>::type>
|
|
||||||
(as_parser<A>::convert(a), as_parser<B>::convert(b));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
alternative<A, B>
|
|
||||||
operator|(parser<A> const& a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
alternative<A, chlit<char> >
|
|
||||||
operator|(parser<A> const& a, char b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
alternative<chlit<char>, B>
|
|
||||||
operator|(char a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
alternative<A, strlit<char const*> >
|
|
||||||
operator|(parser<A> const& a, char const* b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
alternative<strlit<char const*>, B>
|
|
||||||
operator|(char const* a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
alternative<A, chlit<wchar_t> >
|
|
||||||
operator|(parser<A> const& a, wchar_t b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
alternative<chlit<wchar_t>, B>
|
|
||||||
operator|(wchar_t a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
alternative<A, strlit<wchar_t const*> >
|
|
||||||
operator|(parser<A> const& a, wchar_t const* b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
alternative<strlit<wchar_t const*>, B>
|
|
||||||
operator|(wchar_t const* a, parser<B> const& b);
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/spirit/core/composite/impl/alternative.ipp>
|
|
@ -1,138 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_COMPOSITE_HPP)
|
|
||||||
#define BOOST_SPIRIT_COMPOSITE_HPP
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <boost/compressed_pair.hpp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// unary class.
|
|
||||||
//
|
|
||||||
// Composite class composed of a single subject. This template class
|
|
||||||
// is parameterized by the subject type S and a base class to
|
|
||||||
// inherit from, BaseT. The unary class is meant to be a base class
|
|
||||||
// to inherit from. The inheritance structure, given the BaseT
|
|
||||||
// template parameter places the unary class in the middle of a
|
|
||||||
// linear, single parent hierarchy. For instance, given a class S
|
|
||||||
// and a base class B, a class D can derive from unary:
|
|
||||||
//
|
|
||||||
// struct D : public unary<S, B> {...};
|
|
||||||
//
|
|
||||||
// The inheritance structure is thus:
|
|
||||||
//
|
|
||||||
// B
|
|
||||||
// |
|
|
||||||
// unary (has S)
|
|
||||||
// |
|
|
||||||
// D
|
|
||||||
//
|
|
||||||
// The subject can be accessed from the derived class D as:
|
|
||||||
// this->subject();
|
|
||||||
//
|
|
||||||
// Typically, the subject S is specified as typename S::embed_t.
|
|
||||||
// embed_t specifies how the subject is embedded in the composite
|
|
||||||
// (See parser.hpp for details).
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename S, typename BaseT>
|
|
||||||
class unary : public BaseT
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef BaseT base_t;
|
|
||||||
typedef typename boost::call_traits<S>::param_type param_t;
|
|
||||||
typedef typename boost::call_traits<S>::const_reference return_t;
|
|
||||||
typedef S subject_t;
|
|
||||||
typedef typename S::embed_t subject_embed_t;
|
|
||||||
|
|
||||||
unary(param_t subj_)
|
|
||||||
: base_t(), subj(subj_) {}
|
|
||||||
|
|
||||||
unary(BaseT const& base, param_t subj_)
|
|
||||||
: base_t(base), subj(subj_) {}
|
|
||||||
|
|
||||||
return_t
|
|
||||||
subject() const
|
|
||||||
{ return subj; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
subject_embed_t subj;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// binary class.
|
|
||||||
//
|
|
||||||
// Composite class composed of a pair (left and right). This
|
|
||||||
// template class is parameterized by the left and right subject
|
|
||||||
// types A and B and a base class to inherit from, BaseT. The binary
|
|
||||||
// class is meant to be a base class to inherit from. The
|
|
||||||
// inheritance structure, given the BaseT template parameter places
|
|
||||||
// the binary class in the middle of a linear, single parent
|
|
||||||
// hierarchy. For instance, given classes X and Y and a base class
|
|
||||||
// B, a class D can derive from binary:
|
|
||||||
//
|
|
||||||
// struct D : public binary<X, Y, B> {...};
|
|
||||||
//
|
|
||||||
// The inheritance structure is thus:
|
|
||||||
//
|
|
||||||
// B
|
|
||||||
// |
|
|
||||||
// binary (has X and Y)
|
|
||||||
// |
|
|
||||||
// D
|
|
||||||
//
|
|
||||||
// The left and right subjects can be accessed from the derived
|
|
||||||
// class D as: this->left(); and this->right();
|
|
||||||
//
|
|
||||||
// Typically, the pairs X and Y are specified as typename X::embed_t
|
|
||||||
// and typename Y::embed_t. embed_t specifies how the subject is
|
|
||||||
// embedded in the composite (See parser.hpp for details).
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename A, typename B, typename BaseT>
|
|
||||||
class binary : public BaseT
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef BaseT base_t;
|
|
||||||
typedef typename boost::call_traits<A>::param_type left_param_t;
|
|
||||||
typedef typename boost::call_traits<A>::const_reference left_return_t;
|
|
||||||
typedef typename boost::call_traits<B>::param_type right_param_t;
|
|
||||||
typedef typename boost::call_traits<B>::const_reference right_return_t;
|
|
||||||
typedef A left_t;
|
|
||||||
typedef typename A::embed_t left_embed_t;
|
|
||||||
typedef B right_t;
|
|
||||||
typedef typename B::embed_t right_embed_t;
|
|
||||||
|
|
||||||
binary(left_param_t a, right_param_t b)
|
|
||||||
: base_t(), subj(a, b) {}
|
|
||||||
|
|
||||||
left_return_t
|
|
||||||
left() const
|
|
||||||
{ return subj.first(); }
|
|
||||||
|
|
||||||
right_return_t
|
|
||||||
right() const
|
|
||||||
{ return subj.second(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
boost::compressed_pair<left_embed_t, right_embed_t> subj;
|
|
||||||
};
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,137 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_DIFFERENCE_HPP)
|
|
||||||
#define BOOST_SPIRIT_DIFFERENCE_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/primitives/primitives.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
#include <boost/spirit/meta/as_parser.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// difference: a - b; Matches a but not b
|
|
||||||
//
|
|
||||||
// Handles expressions of the form:
|
|
||||||
//
|
|
||||||
// a - b
|
|
||||||
//
|
|
||||||
// where a and b are parsers. The expression returns a composite
|
|
||||||
// parser that matches a but not b. One (not both) of the operands
|
|
||||||
// may be a literal char, wchar_t or a primitive string char const*,
|
|
||||||
// wchar_t const*.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct difference_parser_gen;
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct difference
|
|
||||||
: public binary<A, B, parser<difference<A, B> > >
|
|
||||||
{
|
|
||||||
typedef difference<A, B> self_t;
|
|
||||||
typedef binary_parser_category parser_category_t;
|
|
||||||
typedef difference_parser_gen parser_generator_t;
|
|
||||||
typedef binary<A, B, parser<self_t> > base_t;
|
|
||||||
|
|
||||||
difference(A const& a, B const& b)
|
|
||||||
: base_t(a, b) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
typedef typename ScannerT::iterator_t iterator_t;
|
|
||||||
iterator_t save = scan.first;
|
|
||||||
if (result_t hl = this->left().parse(scan))
|
|
||||||
{
|
|
||||||
std::swap(save, scan.first);
|
|
||||||
result_t hr = this->right().parse(scan);
|
|
||||||
if (!hr || (hr.length() < hl.length()))
|
|
||||||
{
|
|
||||||
scan.first = save;
|
|
||||||
return hl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct difference_parser_gen
|
|
||||||
{
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
difference<
|
|
||||||
typename as_parser<A>::type
|
|
||||||
, typename as_parser<B>::type
|
|
||||||
>
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
static difference<
|
|
||||||
typename as_parser<A>::type
|
|
||||||
, typename as_parser<B>::type
|
|
||||||
>
|
|
||||||
generate(A const& a, B const& b)
|
|
||||||
{
|
|
||||||
return difference<BOOST_DEDUCED_TYPENAME as_parser<A>::type,
|
|
||||||
BOOST_DEDUCED_TYPENAME as_parser<B>::type>
|
|
||||||
(as_parser<A>::convert(a), as_parser<B>::convert(b));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
difference<A, B>
|
|
||||||
operator-(parser<A> const& a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
difference<A, chlit<char> >
|
|
||||||
operator-(parser<A> const& a, char b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
difference<chlit<char>, B>
|
|
||||||
operator-(char a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
difference<A, strlit<char const*> >
|
|
||||||
operator-(parser<A> const& a, char const* b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
difference<strlit<char const*>, B>
|
|
||||||
operator-(char const* a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
difference<A, chlit<wchar_t> >
|
|
||||||
operator-(parser<A> const& a, wchar_t b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
difference<chlit<wchar_t>, B>
|
|
||||||
operator-(wchar_t a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
difference<A, strlit<wchar_t const*> >
|
|
||||||
operator-(parser<A> const& a, wchar_t const* b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
difference<strlit<wchar_t const*>, B>
|
|
||||||
operator-(wchar_t const* a, parser<B> const& b);
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/spirit/core/composite/impl/difference.ipp>
|
|
@ -1,603 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_DIRECTIVES_HPP)
|
|
||||||
#define BOOST_SPIRIT_DIRECTIVES_HPP
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/scanner/skipper.hpp>
|
|
||||||
#include <boost/spirit/core/primitives/primitives.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
#include <boost/spirit/core/composite/impl/directives.ipp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// contiguous class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct lexeme_parser_gen;
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
struct contiguous
|
|
||||||
: public unary<ParserT, parser<contiguous<ParserT> > >
|
|
||||||
{
|
|
||||||
typedef contiguous<ParserT> self_t;
|
|
||||||
typedef unary_parser_category parser_category_t;
|
|
||||||
typedef lexeme_parser_gen parser_generator_t;
|
|
||||||
typedef unary<ParserT, parser<self_t> > base_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename parser_result<ParserT, ScannerT>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
contiguous(ParserT const& p)
|
|
||||||
: base_t(p) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
return impl::contiguous_parser_parse<result_t>
|
|
||||||
(this->subject(), scan, scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct lexeme_parser_gen
|
|
||||||
{
|
|
||||||
template <typename ParserT>
|
|
||||||
struct result {
|
|
||||||
|
|
||||||
typedef contiguous<ParserT> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
static contiguous<ParserT>
|
|
||||||
generate(parser<ParserT> const& subject)
|
|
||||||
{
|
|
||||||
return contiguous<ParserT>(subject.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
contiguous<ParserT>
|
|
||||||
operator[](parser<ParserT> const& subject) const
|
|
||||||
{
|
|
||||||
return contiguous<ParserT>(subject.derived());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
const lexeme_parser_gen lexeme_d = lexeme_parser_gen();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// lexeme_scanner
|
|
||||||
//
|
|
||||||
// Given a Scanner, return the correct scanner type that
|
|
||||||
// the lexeme_d uses. Scanner is assumed to be a phrase
|
|
||||||
// level scanner (see skipper.hpp)
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct lexeme_scanner
|
|
||||||
{
|
|
||||||
typedef scanner_policies<
|
|
||||||
no_skipper_iteration_policy<
|
|
||||||
typename ScannerT::iteration_policy_t>,
|
|
||||||
typename ScannerT::match_policy_t,
|
|
||||||
typename ScannerT::action_policy_t
|
|
||||||
> policies_t;
|
|
||||||
|
|
||||||
typedef typename
|
|
||||||
rebind_scanner_policies<ScannerT, policies_t>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// inhibit_case_iteration_policy class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
struct inhibit_case_iteration_policy : public BaseT
|
|
||||||
{
|
|
||||||
typedef BaseT base_t;
|
|
||||||
|
|
||||||
inhibit_case_iteration_policy()
|
|
||||||
: BaseT() {}
|
|
||||||
|
|
||||||
template <typename PolicyT>
|
|
||||||
inhibit_case_iteration_policy(PolicyT const& other)
|
|
||||||
: BaseT(other) {}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
CharT filter(CharT ch) const
|
|
||||||
{ return impl::tolower_(ch); }
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// inhibit_case class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct inhibit_case_parser_gen;
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
struct inhibit_case
|
|
||||||
: public unary<ParserT, parser<inhibit_case<ParserT> > >
|
|
||||||
{
|
|
||||||
typedef inhibit_case<ParserT> self_t;
|
|
||||||
typedef unary_parser_category parser_category_t;
|
|
||||||
typedef inhibit_case_parser_gen parser_generator_t;
|
|
||||||
typedef unary<ParserT, parser<self_t> > base_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename parser_result<ParserT, ScannerT>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
inhibit_case(ParserT const& p)
|
|
||||||
: base_t(p) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
return impl::inhibit_case_parser_parse<result_t>
|
|
||||||
(this->subject(), scan, scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <int N>
|
|
||||||
struct inhibit_case_parser_gen_base
|
|
||||||
{
|
|
||||||
// This hack is needed to make borland happy.
|
|
||||||
// If these member operators were defined in the
|
|
||||||
// inhibit_case_parser_gen class, or if this class
|
|
||||||
// is non-templated, borland ICEs.
|
|
||||||
|
|
||||||
static inhibit_case<strlit<char const*> >
|
|
||||||
generate(char const* str)
|
|
||||||
{ return inhibit_case<strlit<char const*> >(str); }
|
|
||||||
|
|
||||||
static inhibit_case<strlit<wchar_t const*> >
|
|
||||||
generate(wchar_t const* str)
|
|
||||||
{ return inhibit_case<strlit<wchar_t const*> >(str); }
|
|
||||||
|
|
||||||
static inhibit_case<chlit<char> >
|
|
||||||
generate(char ch)
|
|
||||||
{ return inhibit_case<chlit<char> >(ch); }
|
|
||||||
|
|
||||||
static inhibit_case<chlit<wchar_t> >
|
|
||||||
generate(wchar_t ch)
|
|
||||||
{ return inhibit_case<chlit<wchar_t> >(ch); }
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
static inhibit_case<ParserT>
|
|
||||||
generate(parser<ParserT> const& subject)
|
|
||||||
{ return inhibit_case<ParserT>(subject.derived()); }
|
|
||||||
|
|
||||||
inhibit_case<strlit<char const*> >
|
|
||||||
operator[](char const* str) const
|
|
||||||
{ return inhibit_case<strlit<char const*> >(str); }
|
|
||||||
|
|
||||||
inhibit_case<strlit<wchar_t const*> >
|
|
||||||
operator[](wchar_t const* str) const
|
|
||||||
{ return inhibit_case<strlit<wchar_t const*> >(str); }
|
|
||||||
|
|
||||||
inhibit_case<chlit<char> >
|
|
||||||
operator[](char ch) const
|
|
||||||
{ return inhibit_case<chlit<char> >(ch); }
|
|
||||||
|
|
||||||
inhibit_case<chlit<wchar_t> >
|
|
||||||
operator[](wchar_t ch) const
|
|
||||||
{ return inhibit_case<chlit<wchar_t> >(ch); }
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
inhibit_case<ParserT>
|
|
||||||
operator[](parser<ParserT> const& subject) const
|
|
||||||
{ return inhibit_case<ParserT>(subject.derived()); }
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
struct inhibit_case_parser_gen : public inhibit_case_parser_gen_base<0>
|
|
||||||
{
|
|
||||||
inhibit_case_parser_gen() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
// Depracated
|
|
||||||
const inhibit_case_parser_gen nocase_d = inhibit_case_parser_gen();
|
|
||||||
|
|
||||||
// Preferred syntax
|
|
||||||
const inhibit_case_parser_gen as_lower_d = inhibit_case_parser_gen();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// as_lower_scanner
|
|
||||||
//
|
|
||||||
// Given a Scanner, return the correct scanner type that
|
|
||||||
// the as_lower_d uses. Scanner is assumed to be a scanner
|
|
||||||
// with an inhibit_case_iteration_policy.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct as_lower_scanner
|
|
||||||
{
|
|
||||||
typedef scanner_policies<
|
|
||||||
inhibit_case_iteration_policy<
|
|
||||||
typename ScannerT::iteration_policy_t>,
|
|
||||||
typename ScannerT::match_policy_t,
|
|
||||||
typename ScannerT::action_policy_t
|
|
||||||
> policies_t;
|
|
||||||
|
|
||||||
typedef typename
|
|
||||||
rebind_scanner_policies<ScannerT, policies_t>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// longest_alternative class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct longest_parser_gen;
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct longest_alternative
|
|
||||||
: public binary<A, B, parser<longest_alternative<A, B> > >
|
|
||||||
{
|
|
||||||
typedef longest_alternative<A, B> self_t;
|
|
||||||
typedef binary_parser_category parser_category_t;
|
|
||||||
typedef longest_parser_gen parser_generator_t;
|
|
||||||
typedef binary<A, B, parser<self_t> > base_t;
|
|
||||||
|
|
||||||
longest_alternative(A const& a, B const& b)
|
|
||||||
: base_t(a, b) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
typename ScannerT::iterator_t save = scan.first;
|
|
||||||
result_t l = this->left().parse(scan);
|
|
||||||
std::swap(scan.first, save);
|
|
||||||
result_t r = this->right().parse(scan);
|
|
||||||
|
|
||||||
if (l || r)
|
|
||||||
{
|
|
||||||
if (l.length() > r.length())
|
|
||||||
{
|
|
||||||
scan.first = save;
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct longest_parser_gen
|
|
||||||
{
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct result {
|
|
||||||
|
|
||||||
typedef typename
|
|
||||||
impl::to_longest_alternative<alternative<A, B> >::result_t
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
static typename
|
|
||||||
impl::to_longest_alternative<alternative<A, B> >::result_t
|
|
||||||
generate(alternative<A, B> const& alt)
|
|
||||||
{
|
|
||||||
return impl::to_longest_alternative<alternative<A, B> >::
|
|
||||||
convert(alt);
|
|
||||||
}
|
|
||||||
|
|
||||||
//'generate' for binary composite
|
|
||||||
template <typename A, typename B>
|
|
||||||
static
|
|
||||||
longest_alternative<A, B>
|
|
||||||
generate(A const &left, B const &right)
|
|
||||||
{
|
|
||||||
return longest_alternative<A, B>(left, right);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
typename impl::to_longest_alternative<alternative<A, B> >::result_t
|
|
||||||
operator[](alternative<A, B> const& alt) const
|
|
||||||
{
|
|
||||||
return impl::to_longest_alternative<alternative<A, B> >::
|
|
||||||
convert(alt);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const longest_parser_gen longest_d = longest_parser_gen();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// shortest_alternative class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct shortest_parser_gen;
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct shortest_alternative
|
|
||||||
: public binary<A, B, parser<shortest_alternative<A, B> > >
|
|
||||||
{
|
|
||||||
typedef shortest_alternative<A, B> self_t;
|
|
||||||
typedef binary_parser_category parser_category_t;
|
|
||||||
typedef shortest_parser_gen parser_generator_t;
|
|
||||||
typedef binary<A, B, parser<self_t> > base_t;
|
|
||||||
|
|
||||||
shortest_alternative(A const& a, B const& b)
|
|
||||||
: base_t(a, b) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
typename ScannerT::iterator_t save = scan.first;
|
|
||||||
result_t l = this->left().parse(scan);
|
|
||||||
std::swap(scan.first, save);
|
|
||||||
result_t r = this->right().parse(scan);
|
|
||||||
|
|
||||||
if (l || r)
|
|
||||||
{
|
|
||||||
if (l.length() < r.length() && l || !r)
|
|
||||||
{
|
|
||||||
scan.first = save;
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct shortest_parser_gen
|
|
||||||
{
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct result {
|
|
||||||
|
|
||||||
typedef typename
|
|
||||||
impl::to_shortest_alternative<alternative<A, B> >::result_t
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
static typename
|
|
||||||
impl::to_shortest_alternative<alternative<A, B> >::result_t
|
|
||||||
generate(alternative<A, B> const& alt)
|
|
||||||
{
|
|
||||||
return impl::to_shortest_alternative<alternative<A, B> >::
|
|
||||||
convert(alt);
|
|
||||||
}
|
|
||||||
|
|
||||||
//'generate' for binary composite
|
|
||||||
template <typename A, typename B>
|
|
||||||
static
|
|
||||||
shortest_alternative<A, B>
|
|
||||||
generate(A const &left, B const &right)
|
|
||||||
{
|
|
||||||
return shortest_alternative<A, B>(left, right);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
typename impl::to_shortest_alternative<alternative<A, B> >::result_t
|
|
||||||
operator[](alternative<A, B> const& alt) const
|
|
||||||
{
|
|
||||||
return impl::to_shortest_alternative<alternative<A, B> >::
|
|
||||||
convert(alt);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const shortest_parser_gen shortest_d = shortest_parser_gen();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// min_bounded class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename BoundsT>
|
|
||||||
struct min_bounded_gen;
|
|
||||||
|
|
||||||
template <typename ParserT, typename BoundsT>
|
|
||||||
struct min_bounded
|
|
||||||
: public unary<ParserT, parser<min_bounded<ParserT, BoundsT> > >
|
|
||||||
{
|
|
||||||
typedef min_bounded<ParserT, BoundsT> self_t;
|
|
||||||
typedef unary_parser_category parser_category_t;
|
|
||||||
typedef min_bounded_gen<BoundsT> parser_generator_t;
|
|
||||||
typedef unary<ParserT, parser<self_t> > base_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename parser_result<ParserT, ScannerT>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
min_bounded(ParserT const& p, BoundsT const& min__)
|
|
||||||
: base_t(p)
|
|
||||||
, min_(min__) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
result_t hit = this->subject().parse(scan);
|
|
||||||
if (hit.has_valid_attribute() && hit.value() < min_)
|
|
||||||
return scan.no_match();
|
|
||||||
return hit;
|
|
||||||
}
|
|
||||||
|
|
||||||
BoundsT min_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename BoundsT>
|
|
||||||
struct min_bounded_gen
|
|
||||||
{
|
|
||||||
min_bounded_gen(BoundsT const& min__)
|
|
||||||
: min_(min__) {}
|
|
||||||
|
|
||||||
template <typename DerivedT>
|
|
||||||
min_bounded<DerivedT, BoundsT>
|
|
||||||
operator[](parser<DerivedT> const& p) const
|
|
||||||
{ return min_bounded<DerivedT, BoundsT>(p.derived(), min_); }
|
|
||||||
|
|
||||||
BoundsT min_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename BoundsT>
|
|
||||||
inline min_bounded_gen<BoundsT>
|
|
||||||
min_limit_d(BoundsT const& min_)
|
|
||||||
{ return min_bounded_gen<BoundsT>(min_); }
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// max_bounded class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename BoundsT>
|
|
||||||
struct max_bounded_gen;
|
|
||||||
|
|
||||||
template <typename ParserT, typename BoundsT>
|
|
||||||
struct max_bounded
|
|
||||||
: public unary<ParserT, parser<max_bounded<ParserT, BoundsT> > >
|
|
||||||
{
|
|
||||||
typedef max_bounded<ParserT, BoundsT> self_t;
|
|
||||||
typedef unary_parser_category parser_category_t;
|
|
||||||
typedef max_bounded_gen<BoundsT> parser_generator_t;
|
|
||||||
typedef unary<ParserT, parser<self_t> > base_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename parser_result<ParserT, ScannerT>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
max_bounded(ParserT const& p, BoundsT const& max__)
|
|
||||||
: base_t(p)
|
|
||||||
, max_(max__) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
result_t hit = this->subject().parse(scan);
|
|
||||||
if (hit.has_valid_attribute() && hit.value() > max_)
|
|
||||||
return scan.no_match();
|
|
||||||
return hit;
|
|
||||||
}
|
|
||||||
|
|
||||||
BoundsT max_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename BoundsT>
|
|
||||||
struct max_bounded_gen
|
|
||||||
{
|
|
||||||
max_bounded_gen(BoundsT const& max__)
|
|
||||||
: max_(max__) {}
|
|
||||||
|
|
||||||
template <typename DerivedT>
|
|
||||||
max_bounded<DerivedT, BoundsT>
|
|
||||||
operator[](parser<DerivedT> const& p) const
|
|
||||||
{ return max_bounded<DerivedT, BoundsT>(p.derived(), max_); }
|
|
||||||
|
|
||||||
BoundsT max_;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BoundsT>
|
|
||||||
inline max_bounded_gen<BoundsT>
|
|
||||||
max_limit_d(BoundsT const& max_)
|
|
||||||
{ return max_bounded_gen<BoundsT>(max_); }
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// bounded class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename BoundsT>
|
|
||||||
struct bounded_gen;
|
|
||||||
|
|
||||||
template <typename ParserT, typename BoundsT>
|
|
||||||
struct bounded
|
|
||||||
: public unary<ParserT, parser<bounded<ParserT, BoundsT> > >
|
|
||||||
{
|
|
||||||
typedef bounded<ParserT, BoundsT> self_t;
|
|
||||||
typedef unary_parser_category parser_category_t;
|
|
||||||
typedef bounded_gen<BoundsT> parser_generator_t;
|
|
||||||
typedef unary<ParserT, parser<self_t> > base_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename parser_result<ParserT, ScannerT>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
bounded(ParserT const& p, BoundsT const& min__, BoundsT const& max__)
|
|
||||||
: base_t(p)
|
|
||||||
, min_(min__)
|
|
||||||
, max_(max__) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
result_t hit = this->subject().parse(scan);
|
|
||||||
if (hit.has_valid_attribute() &&
|
|
||||||
(hit.value() < min_ || hit.value() > max_))
|
|
||||||
return scan.no_match();
|
|
||||||
return hit;
|
|
||||||
}
|
|
||||||
|
|
||||||
BoundsT min_, max_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename BoundsT>
|
|
||||||
struct bounded_gen
|
|
||||||
{
|
|
||||||
bounded_gen(BoundsT const& min__, BoundsT const& max__)
|
|
||||||
: min_(min__)
|
|
||||||
, max_(max__) {}
|
|
||||||
|
|
||||||
template <typename DerivedT>
|
|
||||||
bounded<DerivedT, BoundsT>
|
|
||||||
operator[](parser<DerivedT> const& p) const
|
|
||||||
{ return bounded<DerivedT, BoundsT>(p.derived(), min_, max_); }
|
|
||||||
|
|
||||||
BoundsT min_, max_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename BoundsT>
|
|
||||||
inline bounded_gen<BoundsT>
|
|
||||||
limit_d(BoundsT const& min_, BoundsT const& max_)
|
|
||||||
{ return bounded_gen<BoundsT>(min_, max_); }
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,272 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2002-2003 Martin Wille
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_EPSILON_HPP
|
|
||||||
#define BOOST_SPIRIT_EPSILON_HPP
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/meta/parser_traits.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
#include <boost/spirit/core/composite/no_actions.hpp>
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// condition_parser class
|
|
||||||
//
|
|
||||||
// handles expresions of the form
|
|
||||||
//
|
|
||||||
// epsilon_p(cond)
|
|
||||||
//
|
|
||||||
// where cond is a function or a functor that returns a value suitable
|
|
||||||
// to be used in boolean context. The expression returns a parser that
|
|
||||||
// returns an empty match when the condition evaluates to true.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename CondT, bool positive_ = true>
|
|
||||||
struct condition_parser : parser<condition_parser<CondT, positive_> >
|
|
||||||
{
|
|
||||||
typedef condition_parser<CondT, positive_> self_t;
|
|
||||||
|
|
||||||
// not explicit! (needed for implementation of if_p et al.)
|
|
||||||
condition_parser(CondT const& cond_) : cond(cond_) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
if (positive_ == bool(cond())) // allow cond to return int
|
|
||||||
return scan.empty_match();
|
|
||||||
else
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
|
|
||||||
condition_parser<CondT, !positive_>
|
|
||||||
negate() const
|
|
||||||
{ return condition_parser<CondT, !positive_>(cond); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
CondT cond;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, == 1310) || \
|
|
||||||
BOOST_WORKAROUND(BOOST_MSVC, == 1400) || \
|
|
||||||
BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580)
|
|
||||||
// VC 7.1, VC8 and Sun CC <= 5.8 do not support general
|
|
||||||
// expressions of non-type template parameters in instantiations
|
|
||||||
template <typename CondT>
|
|
||||||
inline condition_parser<CondT, false>
|
|
||||||
operator~(condition_parser<CondT, true> const& p)
|
|
||||||
{ return p.negate(); }
|
|
||||||
|
|
||||||
template <typename CondT>
|
|
||||||
inline condition_parser<CondT, true>
|
|
||||||
operator~(condition_parser<CondT, false> const& p)
|
|
||||||
{ return p.negate(); }
|
|
||||||
#else // BOOST_WORKAROUND(BOOST_MSVC, == 1310) || == 1400
|
|
||||||
template <typename CondT, bool positive>
|
|
||||||
inline condition_parser<CondT, !positive>
|
|
||||||
operator~(condition_parser<CondT, positive> const& p)
|
|
||||||
{ return p.negate(); }
|
|
||||||
#endif // BOOST_WORKAROUND(BOOST_MSVC, == 1310) || == 1400
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// empty_match_parser class
|
|
||||||
//
|
|
||||||
// handles expressions of the form
|
|
||||||
// epsilon_p(subject)
|
|
||||||
// where subject is a parser. The expresion returns a composite
|
|
||||||
// parser that returns an empty match if the subject parser matches.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
struct empty_match_parser_gen;
|
|
||||||
struct negated_empty_match_parser_gen;
|
|
||||||
|
|
||||||
template <typename SubjectT>
|
|
||||||
struct negated_empty_match_parser; // Forward declaration
|
|
||||||
|
|
||||||
template<typename SubjectT>
|
|
||||||
struct empty_match_parser
|
|
||||||
: unary<SubjectT, parser<empty_match_parser<SubjectT> > >
|
|
||||||
{
|
|
||||||
typedef empty_match_parser<SubjectT> self_t;
|
|
||||||
typedef unary<SubjectT, parser<self_t> > base_t;
|
|
||||||
typedef unary_parser_category parser_category_t;
|
|
||||||
typedef empty_match_parser_gen parser_genererator_t;
|
|
||||||
typedef self_t embed_t;
|
|
||||||
|
|
||||||
explicit empty_match_parser(SubjectT const& p) : base_t(p) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{ typedef typename match_result<ScannerT, nil_t>::type type; };
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typename ScannerT::iterator_t save(scan.first);
|
|
||||||
|
|
||||||
typedef typename no_actions_scanner<ScannerT>::policies_t
|
|
||||||
policies_t;
|
|
||||||
|
|
||||||
bool matches = this->subject().parse(
|
|
||||||
scan.change_policies(policies_t(scan)));
|
|
||||||
if (matches)
|
|
||||||
{
|
|
||||||
scan.first = save; // reset the position
|
|
||||||
return scan.empty_match();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
negated_empty_match_parser<SubjectT>
|
|
||||||
negate() const
|
|
||||||
{ return negated_empty_match_parser<SubjectT>(this->subject()); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename SubjectT>
|
|
||||||
struct negated_empty_match_parser
|
|
||||||
: public unary<SubjectT, parser<negated_empty_match_parser<SubjectT> > >
|
|
||||||
{
|
|
||||||
typedef negated_empty_match_parser<SubjectT> self_t;
|
|
||||||
typedef unary<SubjectT, parser<self_t> > base_t;
|
|
||||||
typedef unary_parser_category parser_category_t;
|
|
||||||
typedef negated_empty_match_parser_gen parser_genererator_t;
|
|
||||||
|
|
||||||
explicit negated_empty_match_parser(SubjectT const& p) : base_t(p) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{ typedef typename match_result<ScannerT, nil_t>::type type; };
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typename ScannerT::iterator_t save(scan.first);
|
|
||||||
|
|
||||||
typedef typename no_actions_scanner<ScannerT>::policies_t
|
|
||||||
policies_t;
|
|
||||||
|
|
||||||
bool matches = this->subject().parse(
|
|
||||||
scan.change_policies(policies_t(scan)));
|
|
||||||
if (!matches)
|
|
||||||
{
|
|
||||||
scan.first = save; // reset the position
|
|
||||||
return scan.empty_match();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
empty_match_parser<SubjectT>
|
|
||||||
negate() const
|
|
||||||
{ return empty_match_parser<SubjectT>(this->subject()); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct empty_match_parser_gen
|
|
||||||
{
|
|
||||||
template <typename SubjectT>
|
|
||||||
struct result
|
|
||||||
{ typedef empty_match_parser<SubjectT> type; };
|
|
||||||
|
|
||||||
template <typename SubjectT>
|
|
||||||
static empty_match_parser<SubjectT>
|
|
||||||
generate(parser<SubjectT> const& subject)
|
|
||||||
{ return empty_match_parser<SubjectT>(subject.derived()); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct negated_empty_match_parser_gen
|
|
||||||
{
|
|
||||||
template <typename SubjectT>
|
|
||||||
struct result
|
|
||||||
{ typedef negated_empty_match_parser<SubjectT> type; };
|
|
||||||
|
|
||||||
template <typename SubjectT>
|
|
||||||
static negated_empty_match_parser<SubjectT>
|
|
||||||
generate(parser<SubjectT> const& subject)
|
|
||||||
{ return negated_empty_match_parser<SubjectT>(subject.derived()); }
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////
|
|
||||||
template <typename SubjectT>
|
|
||||||
inline negated_empty_match_parser<SubjectT>
|
|
||||||
operator~(empty_match_parser<SubjectT> const& p)
|
|
||||||
{ return p.negate(); }
|
|
||||||
|
|
||||||
template <typename SubjectT>
|
|
||||||
inline empty_match_parser<SubjectT>
|
|
||||||
operator~(negated_empty_match_parser<SubjectT> const& p)
|
|
||||||
{ return p.negate(); }
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// epsilon_ parser and parser generator class
|
|
||||||
//
|
|
||||||
// Operates as primitive parser that always matches an empty sequence.
|
|
||||||
//
|
|
||||||
// Also operates as a parser generator. According to the type of the
|
|
||||||
// argument an instance of empty_match_parser<> (when the argument is
|
|
||||||
// a parser) or condition_parser<> (when the argument is not a parser)
|
|
||||||
// is returned by operator().
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
template <typename SubjectT>
|
|
||||||
struct epsilon_selector
|
|
||||||
{
|
|
||||||
typedef typename as_parser<SubjectT>::type subject_t;
|
|
||||||
typedef typename
|
|
||||||
mpl::if_<
|
|
||||||
is_parser<subject_t>
|
|
||||||
,empty_match_parser<subject_t>
|
|
||||||
,condition_parser<subject_t>
|
|
||||||
>::type type;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
struct epsilon_parser : public parser<epsilon_parser>
|
|
||||||
{
|
|
||||||
typedef epsilon_parser self_t;
|
|
||||||
|
|
||||||
epsilon_parser() {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{ return scan.empty_match(); }
|
|
||||||
|
|
||||||
template <typename SubjectT>
|
|
||||||
typename impl::epsilon_selector<SubjectT>::type
|
|
||||||
operator()(SubjectT const& subject) const
|
|
||||||
{
|
|
||||||
typedef typename impl::epsilon_selector<SubjectT>::type result_t;
|
|
||||||
return result_t(subject);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
epsilon_parser const epsilon_p = epsilon_parser();
|
|
||||||
epsilon_parser const eps_p = epsilon_parser();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,138 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_EXCLUSIVE_OR_HPP)
|
|
||||||
#define BOOST_SPIRIT_EXCLUSIVE_OR_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/primitives/primitives.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
#include <boost/spirit/meta/as_parser.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// exclusive_or class
|
|
||||||
//
|
|
||||||
// Handles expressions of the form:
|
|
||||||
//
|
|
||||||
// a ^ b
|
|
||||||
//
|
|
||||||
// where a and b are parsers. The expression returns a composite
|
|
||||||
// parser that matches a or b but not both. One (not both) of the
|
|
||||||
// operands may be a literal char, wchar_t or a primitive string
|
|
||||||
// char const*, wchar_t const*.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct exclusive_or_parser_gen;
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct exclusive_or
|
|
||||||
: public binary<A, B, parser<exclusive_or<A, B> > >
|
|
||||||
{
|
|
||||||
typedef exclusive_or<A, B> self_t;
|
|
||||||
typedef binary_parser_category parser_category_t;
|
|
||||||
typedef exclusive_or_parser_gen parser_generator_t;
|
|
||||||
typedef binary<A, B, parser<self_t> > base_t;
|
|
||||||
|
|
||||||
exclusive_or(A const& a, B const& b)
|
|
||||||
: base_t(a, b) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
typedef typename ScannerT::iterator_t iterator_t;
|
|
||||||
|
|
||||||
iterator_t save = scan.first;
|
|
||||||
result_t l = this->left().parse(scan);
|
|
||||||
std::swap(save, scan.first);
|
|
||||||
result_t r = this->right().parse(scan);
|
|
||||||
|
|
||||||
if (l ? !bool(r) : bool(r))
|
|
||||||
{
|
|
||||||
if (l)
|
|
||||||
scan.first = save;
|
|
||||||
return l ? l : r;
|
|
||||||
}
|
|
||||||
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct exclusive_or_parser_gen
|
|
||||||
{
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
exclusive_or<
|
|
||||||
typename as_parser<A>::type
|
|
||||||
, typename as_parser<B>::type
|
|
||||||
>
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
static exclusive_or<
|
|
||||||
typename as_parser<A>::type
|
|
||||||
, typename as_parser<B>::type
|
|
||||||
>
|
|
||||||
generate(A const& a, B const& b)
|
|
||||||
{
|
|
||||||
return exclusive_or<BOOST_DEDUCED_TYPENAME as_parser<A>::type,
|
|
||||||
BOOST_DEDUCED_TYPENAME as_parser<B>::type>
|
|
||||||
(as_parser<A>::convert(a), as_parser<B>::convert(b));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
exclusive_or<A, B>
|
|
||||||
operator^(parser<A> const& a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
exclusive_or<A, chlit<char> >
|
|
||||||
operator^(parser<A> const& a, char b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
exclusive_or<chlit<char>, B>
|
|
||||||
operator^(char a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
exclusive_or<A, strlit<char const*> >
|
|
||||||
operator^(parser<A> const& a, char const* b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
exclusive_or<strlit<char const*>, B>
|
|
||||||
operator^(char const* a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
exclusive_or<A, chlit<wchar_t> >
|
|
||||||
operator^(parser<A> const& a, wchar_t b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
exclusive_or<chlit<wchar_t>, B>
|
|
||||||
operator^(wchar_t a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
exclusive_or<A, strlit<wchar_t const*> >
|
|
||||||
operator^(parser<A> const& a, wchar_t const* b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
exclusive_or<strlit<wchar_t const*>, B>
|
|
||||||
operator^(wchar_t const* a, parser<B> const& b);
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/spirit/core/composite/impl/exclusive_or.ipp>
|
|
@ -1,86 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_ALTERNATIVE_IPP)
|
|
||||||
#define BOOST_SPIRIT_ALTERNATIVE_IPP
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// alternative class implementation
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename A, typename B>
|
|
||||||
inline alternative<A, B>
|
|
||||||
operator|(parser<A> const& a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return alternative<A, B>(a.derived(), b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline alternative<A, chlit<char> >
|
|
||||||
operator|(parser<A> const& a, char b)
|
|
||||||
{
|
|
||||||
return alternative<A, chlit<char> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline alternative<chlit<char>, B>
|
|
||||||
operator|(char a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return alternative<chlit<char>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline alternative<A, strlit<char const*> >
|
|
||||||
operator|(parser<A> const& a, char const* b)
|
|
||||||
{
|
|
||||||
return alternative<A, strlit<char const*> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline alternative<strlit<char const*>, B>
|
|
||||||
operator|(char const* a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return alternative<strlit<char const*>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline alternative<A, chlit<wchar_t> >
|
|
||||||
operator|(parser<A> const& a, wchar_t b)
|
|
||||||
{
|
|
||||||
return alternative<A, chlit<wchar_t> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline alternative<chlit<wchar_t>, B>
|
|
||||||
operator|(wchar_t a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return alternative<chlit<wchar_t>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline alternative<A, strlit<wchar_t const*> >
|
|
||||||
operator|(parser<A> const& a, wchar_t const* b)
|
|
||||||
{
|
|
||||||
return alternative<A, strlit<wchar_t const*> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline alternative<strlit<wchar_t const*>, B>
|
|
||||||
operator|(wchar_t const* a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return alternative<strlit<wchar_t const*>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,86 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_DIFFERENCE_IPP)
|
|
||||||
#define BOOST_SPIRIT_DIFFERENCE_IPP
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// difference class implementation
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename A, typename B>
|
|
||||||
inline difference<A, B>
|
|
||||||
operator-(parser<A> const& a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return difference<A, B>(a.derived(), b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline difference<A, chlit<char> >
|
|
||||||
operator-(parser<A> const& a, char b)
|
|
||||||
{
|
|
||||||
return difference<A, chlit<char> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline difference<chlit<char>, B>
|
|
||||||
operator-(char a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return difference<chlit<char>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline difference<A, strlit<char const*> >
|
|
||||||
operator-(parser<A> const& a, char const* b)
|
|
||||||
{
|
|
||||||
return difference<A, strlit<char const*> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline difference<strlit<char const*>, B>
|
|
||||||
operator-(char const* a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return difference<strlit<char const*>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline difference<A, chlit<wchar_t> >
|
|
||||||
operator-(parser<A> const& a, wchar_t b)
|
|
||||||
{
|
|
||||||
return difference<A, chlit<wchar_t> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline difference<chlit<wchar_t>, B>
|
|
||||||
operator-(wchar_t a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return difference<chlit<wchar_t>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline difference<A, strlit<wchar_t const*> >
|
|
||||||
operator-(parser<A> const& a, wchar_t const* b)
|
|
||||||
{
|
|
||||||
return difference<A, strlit<wchar_t const*> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline difference<strlit<wchar_t const*>, B>
|
|
||||||
operator-(wchar_t const* a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return difference<strlit<wchar_t const*>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,370 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2001 Bruce Florman
|
|
||||||
Copyright (c) 2002 Raghavendra Satish
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_DIRECTIVES_IPP)
|
|
||||||
#define BOOST_SPIRIT_DIRECTIVES_IPP
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <boost/spirit/core/scanner/skipper.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
template <typename BaseT>
|
|
||||||
struct no_skipper_iteration_policy;
|
|
||||||
|
|
||||||
template <typename BaseT>
|
|
||||||
struct inhibit_case_iteration_policy;
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct alternative;
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct longest_alternative;
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct shortest_alternative;
|
|
||||||
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
template <typename RT, typename ST, typename ScannerT, typename BaseT>
|
|
||||||
inline RT
|
|
||||||
contiguous_parser_parse(
|
|
||||||
ST const& s,
|
|
||||||
ScannerT const& scan,
|
|
||||||
skipper_iteration_policy<BaseT> const&)
|
|
||||||
{
|
|
||||||
typedef scanner_policies<
|
|
||||||
no_skipper_iteration_policy<
|
|
||||||
BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>,
|
|
||||||
BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t,
|
|
||||||
BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t
|
|
||||||
> policies_t;
|
|
||||||
|
|
||||||
scan.skip(scan);
|
|
||||||
RT hit = s.parse(scan.change_policies(policies_t(scan)));
|
|
||||||
// We will not do a post skip!!!
|
|
||||||
return hit;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename RT, typename ST, typename ScannerT, typename BaseT>
|
|
||||||
inline RT
|
|
||||||
contiguous_parser_parse(
|
|
||||||
ST const& s,
|
|
||||||
ScannerT const& scan,
|
|
||||||
no_skipper_iteration_policy<BaseT> const&)
|
|
||||||
{
|
|
||||||
return s.parse(scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename RT, typename ST, typename ScannerT>
|
|
||||||
inline RT
|
|
||||||
contiguous_parser_parse(
|
|
||||||
ST const& s,
|
|
||||||
ScannerT const& scan,
|
|
||||||
iteration_policy const&)
|
|
||||||
{
|
|
||||||
return s.parse(scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename RT,
|
|
||||||
typename ParserT,
|
|
||||||
typename ScannerT,
|
|
||||||
typename BaseT>
|
|
||||||
inline RT
|
|
||||||
implicit_lexeme_parse(
|
|
||||||
ParserT const& p,
|
|
||||||
ScannerT const& scan,
|
|
||||||
skipper_iteration_policy<BaseT> const&)
|
|
||||||
{
|
|
||||||
typedef scanner_policies<
|
|
||||||
no_skipper_iteration_policy<
|
|
||||||
BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>,
|
|
||||||
BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t,
|
|
||||||
BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t
|
|
||||||
> policies_t;
|
|
||||||
|
|
||||||
scan.skip(scan);
|
|
||||||
RT hit = p.parse_main(scan.change_policies(policies_t(scan)));
|
|
||||||
// We will not do a post skip!!!
|
|
||||||
return hit;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename RT,
|
|
||||||
typename ParserT,
|
|
||||||
typename ScannerT,
|
|
||||||
typename BaseT>
|
|
||||||
inline RT
|
|
||||||
implicit_lexeme_parse(
|
|
||||||
ParserT const& p,
|
|
||||||
ScannerT const& scan,
|
|
||||||
no_skipper_iteration_policy<BaseT> const&)
|
|
||||||
{
|
|
||||||
return p.parse_main(scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename RT, typename ParserT, typename ScannerT>
|
|
||||||
inline RT
|
|
||||||
implicit_lexeme_parse(
|
|
||||||
ParserT const& p,
|
|
||||||
ScannerT const& scan,
|
|
||||||
iteration_policy const&)
|
|
||||||
{
|
|
||||||
return p.parse_main(scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename RT, typename ST, typename ScannerT>
|
|
||||||
inline RT
|
|
||||||
inhibit_case_parser_parse(
|
|
||||||
ST const& s,
|
|
||||||
ScannerT const& scan,
|
|
||||||
iteration_policy const&)
|
|
||||||
{
|
|
||||||
typedef scanner_policies<
|
|
||||||
inhibit_case_iteration_policy<
|
|
||||||
BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>,
|
|
||||||
BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t,
|
|
||||||
BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t
|
|
||||||
> policies_t;
|
|
||||||
|
|
||||||
return s.parse(scan.change_policies(policies_t(scan)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename RT, typename ST, typename ScannerT, typename BaseT>
|
|
||||||
inline RT
|
|
||||||
inhibit_case_parser_parse(
|
|
||||||
ST const& s,
|
|
||||||
ScannerT const& scan,
|
|
||||||
inhibit_case_iteration_policy<BaseT> const&)
|
|
||||||
{
|
|
||||||
return s.parse(scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// from spirit 1.1 (copyright (c) 2001 Bruce Florman)
|
|
||||||
// various workarounds to support longest and shortest directives
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
struct is_alternative
|
|
||||||
{
|
|
||||||
// Determine at compile time (without partial specialization)
|
|
||||||
// whether a given type is an instance of the alternative<A,B>
|
|
||||||
|
|
||||||
static T t();
|
|
||||||
template <typename A, typename B>
|
|
||||||
static char test_(alternative<A, B> const&); // no implementation
|
|
||||||
static int test_(...); // no implementation
|
|
||||||
enum { r = sizeof(char) == sizeof(test_(t())) };
|
|
||||||
typedef mpl::bool_<r> value;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T> struct select_to_longest;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct to_longest_alternative
|
|
||||||
{
|
|
||||||
typedef typename select_to_longest<T>::result_t result_t;
|
|
||||||
typedef typename select_to_longest<T>::plain_t plain_t;
|
|
||||||
typedef typename select_to_longest<T>::choose_t choose_t;
|
|
||||||
static result_t convert(T const& a);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct to_longest_generic
|
|
||||||
{
|
|
||||||
typedef T const& result_t;
|
|
||||||
typedef T plain_t;
|
|
||||||
typedef mpl::false_ choose_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T const&
|
|
||||||
to_longest_convert(T const& a, mpl::false_)
|
|
||||||
{ return a; }
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct to_longest_recursive
|
|
||||||
{
|
|
||||||
typedef typename to_longest_alternative<
|
|
||||||
typename T::left_t>::plain_t a_t;
|
|
||||||
typedef typename to_longest_alternative<
|
|
||||||
typename T::right_t>::plain_t b_t;
|
|
||||||
|
|
||||||
typedef longest_alternative<a_t, b_t> result_t;
|
|
||||||
|
|
||||||
typedef result_t plain_t;
|
|
||||||
typedef mpl::true_ choose_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
inline typename to_longest_alternative<alternative<A, B> >::result_t
|
|
||||||
to_longest_convert(alternative<A, B> const& alt, mpl::true_)
|
|
||||||
{
|
|
||||||
typedef typename to_longest_alternative<
|
|
||||||
alternative<A, B> >::result_t result_t;
|
|
||||||
return result_t(
|
|
||||||
to_longest_alternative<A>::convert(alt.left()),
|
|
||||||
to_longest_alternative<B>::convert(alt.right()));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline typename to_longest_alternative<T>::result_t
|
|
||||||
to_longest_alternative<T>::convert(T const& a)
|
|
||||||
{
|
|
||||||
return to_longest_convert(
|
|
||||||
a, to_longest_alternative<T>::choose_t());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct select_to_longest
|
|
||||||
{
|
|
||||||
typedef typename mpl::if_<
|
|
||||||
is_alternative<T> // IF
|
|
||||||
, to_longest_recursive<T> // THEN
|
|
||||||
, to_longest_generic<T> // ELSE
|
|
||||||
>::type type;
|
|
||||||
|
|
||||||
typedef typename select_to_longest::type::result_t result_t;
|
|
||||||
typedef typename select_to_longest::type::plain_t plain_t;
|
|
||||||
typedef typename select_to_longest::type::choose_t choose_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T> struct select_to_shortest;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct to_shortest_alternative
|
|
||||||
{
|
|
||||||
typedef typename select_to_shortest<T>::result_t result_t;
|
|
||||||
typedef typename select_to_shortest<T>::plain_t plain_t;
|
|
||||||
typedef typename select_to_shortest<T>::choose_t choose_t;
|
|
||||||
static result_t convert(T const& a);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct to_shortest_generic
|
|
||||||
{
|
|
||||||
typedef T const& result_t;
|
|
||||||
typedef T plain_t;
|
|
||||||
typedef mpl::false_ choose_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline T const&
|
|
||||||
to_shortest_convert(T const& a, mpl::false_) { return a; }
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct to_shortest_recursive
|
|
||||||
{
|
|
||||||
typedef typename to_shortest_alternative<
|
|
||||||
typename T::left_t>::plain_t a_t;
|
|
||||||
typedef typename to_shortest_alternative<
|
|
||||||
typename T::right_t>::plain_t b_t;
|
|
||||||
|
|
||||||
typedef shortest_alternative<a_t, b_t> result_t;
|
|
||||||
|
|
||||||
typedef result_t plain_t;
|
|
||||||
typedef mpl::true_ choose_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
inline typename to_shortest_alternative<alternative<A, B> >::result_t
|
|
||||||
to_shortest_convert(alternative<A, B> const& alt, mpl::true_)
|
|
||||||
{
|
|
||||||
typedef typename to_shortest_alternative<
|
|
||||||
alternative<A, B> >::result_t result_t;
|
|
||||||
return result_t(
|
|
||||||
to_shortest_alternative<A>::convert(alt.left()),
|
|
||||||
to_shortest_alternative<B>::convert(alt.right()));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline typename to_shortest_alternative<T>::result_t
|
|
||||||
to_shortest_alternative<T>::convert(T const& a)
|
|
||||||
{
|
|
||||||
return to_shortest_convert(
|
|
||||||
a, to_shortest_alternative<T>::choose_t());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct select_to_shortest
|
|
||||||
{
|
|
||||||
typedef typename mpl::if_<
|
|
||||||
is_alternative<T> // IF
|
|
||||||
, to_shortest_recursive<T> // THEN
|
|
||||||
, to_shortest_generic<T> // ELSE
|
|
||||||
>::type type;
|
|
||||||
|
|
||||||
typedef typename select_to_shortest::type::result_t result_t;
|
|
||||||
typedef typename select_to_shortest::type::plain_t plain_t;
|
|
||||||
typedef typename select_to_shortest::type::choose_t choose_t;
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
template <typename T>
|
|
||||||
struct to_longest_alternative
|
|
||||||
{
|
|
||||||
typedef T result_t;
|
|
||||||
static result_t const&
|
|
||||||
convert(T const& a) // Special (end) case
|
|
||||||
{ return a; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct to_longest_alternative<alternative<A, B> >
|
|
||||||
{
|
|
||||||
typedef typename to_longest_alternative<A>::result_t a_t;
|
|
||||||
typedef typename to_longest_alternative<B>::result_t b_t;
|
|
||||||
typedef longest_alternative<a_t, b_t> result_t;
|
|
||||||
|
|
||||||
static result_t
|
|
||||||
convert(alternative<A, B> const& alt) // Recursive case
|
|
||||||
{
|
|
||||||
return result_t(
|
|
||||||
to_longest_alternative<A>::convert(alt.left()),
|
|
||||||
to_longest_alternative<B>::convert(alt.right()));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct to_shortest_alternative
|
|
||||||
{
|
|
||||||
typedef T result_t;
|
|
||||||
static result_t const&
|
|
||||||
convert(T const& a) // Special (end) case
|
|
||||||
{ return a; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct to_shortest_alternative<alternative<A, B> >
|
|
||||||
{
|
|
||||||
typedef typename to_shortest_alternative<A>::result_t a_t;
|
|
||||||
typedef typename to_shortest_alternative<B>::result_t b_t;
|
|
||||||
typedef shortest_alternative<a_t, b_t> result_t;
|
|
||||||
|
|
||||||
static result_t
|
|
||||||
convert(alternative<A, B> const& alt) // Recursive case
|
|
||||||
{
|
|
||||||
return result_t(
|
|
||||||
to_shortest_alternative<A>::convert(alt.left()),
|
|
||||||
to_shortest_alternative<B>::convert(alt.right()));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_EXCLUSIVE_OR_IPP)
|
|
||||||
#define BOOST_SPIRIT_EXCLUSIVE_OR_IPP
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// exclusive_or class implementation
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename A, typename B>
|
|
||||||
inline exclusive_or<A, B>
|
|
||||||
operator^(parser<A> const& a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return exclusive_or<A, B>(a.derived(), b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline exclusive_or<A, chlit<char> >
|
|
||||||
operator^(parser<A> const& a, char b)
|
|
||||||
{
|
|
||||||
return exclusive_or<A, chlit<char> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline exclusive_or<chlit<char>, B>
|
|
||||||
operator^(char a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return exclusive_or<chlit<char>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline exclusive_or<A, strlit<char const*> >
|
|
||||||
operator^(parser<A> const& a, char const* b)
|
|
||||||
{
|
|
||||||
return exclusive_or<A, strlit<char const*> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline exclusive_or<strlit<char const*>, B>
|
|
||||||
operator^(char const* a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return exclusive_or<strlit<char const*>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline exclusive_or<A, chlit<wchar_t> >
|
|
||||||
operator^(parser<A> const& a, wchar_t b)
|
|
||||||
{
|
|
||||||
return exclusive_or<A, chlit<wchar_t> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline exclusive_or<chlit<wchar_t>, B>
|
|
||||||
operator^(wchar_t a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return exclusive_or<chlit<wchar_t>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline exclusive_or<A, strlit<wchar_t const*> >
|
|
||||||
operator^(parser<A> const& a, wchar_t const* b)
|
|
||||||
{
|
|
||||||
return exclusive_or<A, strlit<wchar_t const*> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline exclusive_or<strlit<wchar_t const*>, B>
|
|
||||||
operator^(wchar_t const* a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return exclusive_or<strlit<wchar_t const*>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,86 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_INTERSECTION_IPP)
|
|
||||||
#define BOOST_SPIRIT_INTERSECTION_IPP
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// intersection class implementation
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename A, typename B>
|
|
||||||
inline intersection<A, B>
|
|
||||||
operator&(parser<A> const& a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return intersection<A, B>(a.derived(), b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline intersection<A, chlit<char> >
|
|
||||||
operator&(parser<A> const& a, char b)
|
|
||||||
{
|
|
||||||
return intersection<A, chlit<char> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline intersection<chlit<char>, B>
|
|
||||||
operator&(char a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return intersection<chlit<char>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline intersection<A, strlit<char const*> >
|
|
||||||
operator&(parser<A> const& a, char const* b)
|
|
||||||
{
|
|
||||||
return intersection<A, strlit<char const*> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline intersection<strlit<char const*>, B>
|
|
||||||
operator&(char const* a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return intersection<strlit<char const*>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline intersection<A, chlit<wchar_t> >
|
|
||||||
operator&(parser<A> const& a, wchar_t b)
|
|
||||||
{
|
|
||||||
return intersection<A, chlit<wchar_t> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline intersection<chlit<wchar_t>, B>
|
|
||||||
operator&(wchar_t a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return intersection<chlit<wchar_t>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline intersection<A, strlit<wchar_t const*> >
|
|
||||||
operator&(parser<A> const& a, wchar_t const* b)
|
|
||||||
{
|
|
||||||
return intersection<A, strlit<wchar_t const*> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline intersection<strlit<wchar_t const*>, B>
|
|
||||||
operator&(wchar_t const* a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return intersection<strlit<wchar_t const*>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,30 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_KLEENE_STAR_IPP)
|
|
||||||
#define BOOST_SPIRIT_KLEENE_STAR_IPP
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// kleene_star class implementation
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename S>
|
|
||||||
inline kleene_star<S>
|
|
||||||
operator*(parser<S> const& a)
|
|
||||||
{
|
|
||||||
return kleene_star<S>(a.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,89 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_LIST_IPP)
|
|
||||||
#define BOOST_SPIRIT_LIST_IPP
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// operator% is defined as:
|
|
||||||
// a % b ---> a >> *(b >> a)
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename A, typename B>
|
|
||||||
inline sequence<A, kleene_star<sequence<B, A> > >
|
|
||||||
operator%(parser<A> const& a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return a.derived() >> *(b.derived() >> a.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline sequence<A, kleene_star<sequence<chlit<char>, A> > >
|
|
||||||
operator%(parser<A> const& a, char b)
|
|
||||||
{
|
|
||||||
return a.derived() >> *(b >> a.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline sequence<chlit<char>, kleene_star<sequence<B, chlit<char> > > >
|
|
||||||
operator%(char a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return a >> *(b.derived() >> a);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline sequence<A, kleene_star<sequence<strlit<char const*>, A> > >
|
|
||||||
operator%(parser<A> const& a, char const* b)
|
|
||||||
{
|
|
||||||
return a.derived() >> *(b >> a.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline sequence<strlit<char const*>,
|
|
||||||
kleene_star<sequence<B, strlit<char const*> > > >
|
|
||||||
operator%(char const* a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return a >> *(b.derived() >> a);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline sequence<A, kleene_star<sequence<chlit<wchar_t>, A> > >
|
|
||||||
operator%(parser<A> const& a, wchar_t b)
|
|
||||||
{
|
|
||||||
return a.derived() >> *(b >> a.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline sequence<chlit<wchar_t>, kleene_star<sequence<B, chlit<wchar_t> > > >
|
|
||||||
operator%(wchar_t a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return a >> *(b.derived() >> a);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline sequence<A, kleene_star<sequence<strlit<wchar_t const*>, A> > >
|
|
||||||
operator%(parser<A> const& a, wchar_t const* b)
|
|
||||||
{
|
|
||||||
return a.derived() >> *(b >> a.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline sequence<strlit<wchar_t const*>,
|
|
||||||
kleene_star<sequence<B, strlit<wchar_t const*> > > >
|
|
||||||
operator%(wchar_t const* a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return a >> *(b.derived() >> a);
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,30 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_OPTIONAL_IPP)
|
|
||||||
#define BOOST_SPIRIT_OPTIONAL_IPP
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// optional class implementation
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename S>
|
|
||||||
optional<S>
|
|
||||||
operator!(parser<S> const& a)
|
|
||||||
{
|
|
||||||
return optional<S>(a.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,30 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_POSITIVE_IPP)
|
|
||||||
#define BOOST_SPIRIT_POSITIVE_IPP
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// positive class implementation
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename S>
|
|
||||||
inline positive<S>
|
|
||||||
operator+(parser<S> const& a)
|
|
||||||
{
|
|
||||||
return positive<S>(a.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,86 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_SEQUENCE_IPP)
|
|
||||||
#define BOOST_SPIRIT_SEQUENCE_IPP
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// sequence class implementation
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename A, typename B>
|
|
||||||
inline sequence<A, B>
|
|
||||||
operator>>(parser<A> const& a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return sequence<A, B>(a.derived(), b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline sequence<A, chlit<char> >
|
|
||||||
operator>>(parser<A> const& a, char b)
|
|
||||||
{
|
|
||||||
return sequence<A, chlit<char> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline sequence<chlit<char>, B>
|
|
||||||
operator>>(char a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return sequence<chlit<char>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline sequence<A, strlit<char const*> >
|
|
||||||
operator>>(parser<A> const& a, char const* b)
|
|
||||||
{
|
|
||||||
return sequence<A, strlit<char const*> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline sequence<strlit<char const*>, B>
|
|
||||||
operator>>(char const* a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return sequence<strlit<char const*>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline sequence<A, chlit<wchar_t> >
|
|
||||||
operator>>(parser<A> const& a, wchar_t b)
|
|
||||||
{
|
|
||||||
return sequence<A, chlit<wchar_t> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline sequence<chlit<wchar_t>, B>
|
|
||||||
operator>>(wchar_t a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return sequence<chlit<wchar_t>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline sequence<A, strlit<wchar_t const*> >
|
|
||||||
operator>>(parser<A> const& a, wchar_t const* b)
|
|
||||||
{
|
|
||||||
return sequence<A, strlit<wchar_t const*> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline sequence<strlit<wchar_t const*>, B>
|
|
||||||
operator>>(wchar_t const* a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return sequence<strlit<wchar_t const*>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,86 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_SEQUENTIAL_AND_IPP)
|
|
||||||
#define BOOST_SPIRIT_SEQUENTIAL_AND_IPP
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// sequential-and operators implementation
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename A, typename B>
|
|
||||||
inline sequence<A, B>
|
|
||||||
operator&&(parser<A> const& a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return sequence<A, B>(a.derived(), b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline sequence<A, chlit<char> >
|
|
||||||
operator&&(parser<A> const& a, char b)
|
|
||||||
{
|
|
||||||
return sequence<A, chlit<char> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline sequence<chlit<char>, B>
|
|
||||||
operator&&(char a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return sequence<chlit<char>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline sequence<A, strlit<char const*> >
|
|
||||||
operator&&(parser<A> const& a, char const* b)
|
|
||||||
{
|
|
||||||
return sequence<A, strlit<char const*> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline sequence<strlit<char const*>, B>
|
|
||||||
operator&&(char const* a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return sequence<strlit<char const*>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline sequence<A, chlit<wchar_t> >
|
|
||||||
operator&&(parser<A> const& a, wchar_t b)
|
|
||||||
{
|
|
||||||
return sequence<A, chlit<wchar_t> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline sequence<chlit<wchar_t>, B>
|
|
||||||
operator&&(wchar_t a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return sequence<chlit<wchar_t>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline sequence<A, strlit<wchar_t const*> >
|
|
||||||
operator&&(parser<A> const& a, wchar_t const* b)
|
|
||||||
{
|
|
||||||
return sequence<A, strlit<wchar_t const*> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline sequence<strlit<wchar_t const*>, B>
|
|
||||||
operator&&(wchar_t const* a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return sequence<strlit<wchar_t const*>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,86 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_SEQUENTIAL_OR_IPP)
|
|
||||||
#define BOOST_SPIRIT_SEQUENTIAL_OR_IPP
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// sequential-or class implementation
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename A, typename B>
|
|
||||||
inline sequential_or<A, B>
|
|
||||||
operator||(parser<A> const& a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return sequential_or<A, B>(a.derived(), b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline sequential_or<A, chlit<char> >
|
|
||||||
operator||(parser<A> const& a, char b)
|
|
||||||
{
|
|
||||||
return sequential_or<A, chlit<char> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline sequential_or<chlit<char>, B>
|
|
||||||
operator||(char a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return sequential_or<chlit<char>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline sequential_or<A, strlit<char const*> >
|
|
||||||
operator||(parser<A> const& a, char const* b)
|
|
||||||
{
|
|
||||||
return sequential_or<A, strlit<char const*> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline sequential_or<strlit<char const*>, B>
|
|
||||||
operator||(char const* a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return sequential_or<strlit<char const*>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline sequential_or<A, chlit<wchar_t> >
|
|
||||||
operator||(parser<A> const& a, wchar_t b)
|
|
||||||
{
|
|
||||||
return sequential_or<A, chlit<wchar_t> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline sequential_or<chlit<wchar_t>, B>
|
|
||||||
operator||(wchar_t a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return sequential_or<chlit<wchar_t>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
inline sequential_or<A, strlit<wchar_t const*> >
|
|
||||||
operator||(parser<A> const& a, wchar_t const* b)
|
|
||||||
{
|
|
||||||
return sequential_or<A, strlit<wchar_t const*> >(a.derived(), b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
inline sequential_or<strlit<wchar_t const*>, B>
|
|
||||||
operator||(wchar_t const* a, parser<B> const& b)
|
|
||||||
{
|
|
||||||
return sequential_or<strlit<wchar_t const*>, B>(a, b.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,138 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_INTERSECTION_HPP)
|
|
||||||
#define BOOST_SPIRIT_INTERSECTION_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/primitives/primitives.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
#include <boost/spirit/meta/as_parser.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// intersection class
|
|
||||||
//
|
|
||||||
// Handles expressions of the form:
|
|
||||||
//
|
|
||||||
// a & b
|
|
||||||
//
|
|
||||||
// where a and b are parsers. The expression returns a composite
|
|
||||||
// parser that matches a and b. One (not both) of the operands may
|
|
||||||
// be a literal char, wchar_t or a primitive string char const*,
|
|
||||||
// wchar_t const*.
|
|
||||||
//
|
|
||||||
// The expression is short circuit evaluated. b is never touched
|
|
||||||
// when a is returns a no-match.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct intersection_parser_gen;
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct intersection
|
|
||||||
: public binary<A, B, parser<intersection<A, B> > >
|
|
||||||
{
|
|
||||||
typedef intersection<A, B> self_t;
|
|
||||||
typedef binary_parser_category parser_category_t;
|
|
||||||
typedef intersection_parser_gen parser_generator_t;
|
|
||||||
typedef binary<A, B, parser<self_t> > base_t;
|
|
||||||
|
|
||||||
intersection(A const& a, B const& b)
|
|
||||||
: base_t(a, b) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
typedef typename ScannerT::iterator_t iterator_t;
|
|
||||||
iterator_t save = scan.first;
|
|
||||||
if (result_t hl = this->left().parse(scan))
|
|
||||||
{
|
|
||||||
ScannerT bscan(scan.first, scan.first, scan);
|
|
||||||
scan.first = save;
|
|
||||||
result_t hr = this->right().parse(bscan);
|
|
||||||
if (hl.length() == hr.length())
|
|
||||||
return hl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct intersection_parser_gen
|
|
||||||
{
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
intersection<
|
|
||||||
typename as_parser<A>::type
|
|
||||||
, typename as_parser<B>::type
|
|
||||||
>
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
static intersection<
|
|
||||||
typename as_parser<A>::type
|
|
||||||
, typename as_parser<B>::type
|
|
||||||
>
|
|
||||||
generate(A const& a, B const& b)
|
|
||||||
{
|
|
||||||
return intersection<BOOST_DEDUCED_TYPENAME as_parser<A>::type,
|
|
||||||
BOOST_DEDUCED_TYPENAME as_parser<B>::type>
|
|
||||||
(as_parser<A>::convert(a), as_parser<B>::convert(b));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
intersection<A, B>
|
|
||||||
operator&(parser<A> const& a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
intersection<A, chlit<char> >
|
|
||||||
operator&(parser<A> const& a, char b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
intersection<chlit<char>, B>
|
|
||||||
operator&(char a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
intersection<A, strlit<char const*> >
|
|
||||||
operator&(parser<A> const& a, char const* b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
intersection<strlit<char const*>, B>
|
|
||||||
operator&(char const* a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
intersection<A, chlit<wchar_t> >
|
|
||||||
operator&(parser<A> const& a, wchar_t b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
intersection<chlit<wchar_t>, B>
|
|
||||||
operator&(wchar_t a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
intersection<A, strlit<wchar_t const*> >
|
|
||||||
operator&(parser<A> const& a, wchar_t const* b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
intersection<strlit<wchar_t const*>, B>
|
|
||||||
operator&(wchar_t const* a, parser<B> const& b);
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/spirit/core/composite/impl/intersection.ipp>
|
|
@ -1,96 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_KLEENE_STAR_HPP)
|
|
||||||
#define BOOST_SPIRIT_KLEENE_STAR_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/primitives/primitives.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
#include <boost/spirit/meta/as_parser.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// kleene_star class
|
|
||||||
//
|
|
||||||
// Handles expressions of the form:
|
|
||||||
//
|
|
||||||
// *a
|
|
||||||
//
|
|
||||||
// where a is a parser. The expression returns a composite
|
|
||||||
// parser that matches its subject zero (0) or more times.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct kleene_star_parser_gen;
|
|
||||||
|
|
||||||
template <typename S>
|
|
||||||
struct kleene_star
|
|
||||||
: public unary<S, parser<kleene_star<S> > >
|
|
||||||
{
|
|
||||||
typedef kleene_star<S> self_t;
|
|
||||||
typedef unary_parser_category parser_category_t;
|
|
||||||
typedef kleene_star_parser_gen parser_generator_t;
|
|
||||||
typedef unary<S, parser<self_t> > base_t;
|
|
||||||
|
|
||||||
kleene_star(S const& a)
|
|
||||||
: base_t(a) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
typedef typename ScannerT::iterator_t iterator_t;
|
|
||||||
result_t hit = scan.empty_match();
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
iterator_t save = scan.first;
|
|
||||||
if (result_t next = this->subject().parse(scan))
|
|
||||||
{
|
|
||||||
scan.concat_match(hit, next);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
scan.first = save;
|
|
||||||
return hit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct kleene_star_parser_gen
|
|
||||||
{
|
|
||||||
template <typename S>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef kleene_star<S> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename S>
|
|
||||||
static kleene_star<S>
|
|
||||||
generate(parser<S> const& a)
|
|
||||||
{
|
|
||||||
return kleene_star<S>(a.derived());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename S>
|
|
||||||
kleene_star<S>
|
|
||||||
operator*(parser<S> const& a);
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/spirit/core/composite/impl/kleene_star.ipp>
|
|
@ -1,69 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_LIST_HPP)
|
|
||||||
#define BOOST_SPIRIT_LIST_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/primitives/primitives.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
#include <boost/spirit/meta/as_parser.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// operator% is defined as:
|
|
||||||
// a % b ---> a >> *(b >> a)
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename A, typename B>
|
|
||||||
sequence<A, kleene_star<sequence<B, A> > >
|
|
||||||
operator%(parser<A> const& a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
sequence<A, kleene_star<sequence<chlit<char>, A> > >
|
|
||||||
operator%(parser<A> const& a, char b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
sequence<chlit<char>, kleene_star<sequence<B, chlit<char> > > >
|
|
||||||
operator%(char a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
sequence<A, kleene_star<sequence<strlit<char const*>, A> > >
|
|
||||||
operator%(parser<A> const& a, char const* b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
sequence<strlit<char const*>,
|
|
||||||
kleene_star<sequence<B, strlit<char const*> > > >
|
|
||||||
operator%(char const* a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
sequence<A, kleene_star<sequence<chlit<wchar_t>, A> > >
|
|
||||||
operator%(parser<A> const& a, wchar_t b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
sequence<chlit<wchar_t>, kleene_star<sequence<B, chlit<wchar_t> > > >
|
|
||||||
operator%(wchar_t a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
sequence<A, kleene_star<sequence<strlit<wchar_t const*>, A> > >
|
|
||||||
operator%(parser<A> const& a, wchar_t const* b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
sequence<strlit<wchar_t const*>,
|
|
||||||
kleene_star<sequence<B, strlit<wchar_t const*> > > >
|
|
||||||
operator%(wchar_t const* a, parser<B> const& b);
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/spirit/core/composite/impl/list.ipp>
|
|
@ -1,163 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2003 Vaclav Vesely
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_NO_ACTIONS_HPP)
|
|
||||||
#define BOOST_SPIRIT_NO_ACTIONS_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
#include <boost/spirit/core/non_terminal/rule.hpp>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace spirit {
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// no_actions_action_policy
|
|
||||||
|
|
||||||
template<typename BaseT = action_policy>
|
|
||||||
struct no_actions_action_policy:
|
|
||||||
public BaseT
|
|
||||||
{
|
|
||||||
typedef BaseT base_t;
|
|
||||||
|
|
||||||
no_actions_action_policy():
|
|
||||||
BaseT()
|
|
||||||
{}
|
|
||||||
|
|
||||||
template<typename PolicyT>
|
|
||||||
no_actions_action_policy(PolicyT const& other):
|
|
||||||
BaseT(other)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template<typename ActorT, typename AttrT, typename IteratorT>
|
|
||||||
void
|
|
||||||
do_action(
|
|
||||||
ActorT const& actor,
|
|
||||||
AttrT& val,
|
|
||||||
IteratorT const& first,
|
|
||||||
IteratorT const& last) const
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// no_actions_scanner
|
|
||||||
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
template <typename ActionPolicy>
|
|
||||||
struct compute_no_actions_action_policy
|
|
||||||
{
|
|
||||||
typedef no_actions_action_policy<ActionPolicy> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ActionPolicy>
|
|
||||||
struct compute_no_actions_action_policy<no_actions_action_policy<ActionPolicy> >
|
|
||||||
{
|
|
||||||
typedef no_actions_action_policy<ActionPolicy> type;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ScannerT = scanner<> >
|
|
||||||
struct no_actions_scanner
|
|
||||||
{
|
|
||||||
typedef scanner_policies<
|
|
||||||
typename ScannerT::iteration_policy_t,
|
|
||||||
typename ScannerT::match_policy_t,
|
|
||||||
typename detail::compute_no_actions_action_policy<typename ScannerT::action_policy_t>::type
|
|
||||||
> policies_t;
|
|
||||||
|
|
||||||
typedef typename
|
|
||||||
rebind_scanner_policies<ScannerT, policies_t>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
|
|
||||||
|
|
||||||
template<typename ScannerT = scanner<> >
|
|
||||||
struct no_actions_scanner_list
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
scanner_list<
|
|
||||||
ScannerT,
|
|
||||||
typename no_actions_scanner<ScannerT>::type
|
|
||||||
>
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// no_actions_parser
|
|
||||||
|
|
||||||
struct no_actions_parser_gen;
|
|
||||||
|
|
||||||
template<typename ParserT>
|
|
||||||
struct no_actions_parser:
|
|
||||||
public unary<ParserT, parser<no_actions_parser<ParserT> > >
|
|
||||||
{
|
|
||||||
typedef no_actions_parser<ParserT> self_t;
|
|
||||||
typedef unary_parser_category parser_category_t;
|
|
||||||
typedef no_actions_parser_gen parser_generator_t;
|
|
||||||
typedef unary<ParserT, parser<self_t> > base_t;
|
|
||||||
|
|
||||||
template<typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename parser_result<ParserT, ScannerT>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
no_actions_parser(ParserT const& p)
|
|
||||||
: base_t(p)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template<typename ScannerT>
|
|
||||||
typename result<ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename no_actions_scanner<ScannerT>::policies_t policies_t;
|
|
||||||
|
|
||||||
return this->subject().parse(scan.change_policies(policies_t(scan)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// no_actions_parser_gen
|
|
||||||
|
|
||||||
struct no_actions_parser_gen
|
|
||||||
{
|
|
||||||
template<typename ParserT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef no_actions_parser<ParserT> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ParserT>
|
|
||||||
static no_actions_parser<ParserT>
|
|
||||||
generate(parser<ParserT> const& subject)
|
|
||||||
{
|
|
||||||
return no_actions_parser<ParserT>(subject.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ParserT>
|
|
||||||
no_actions_parser<ParserT>
|
|
||||||
operator[](parser<ParserT> const& subject) const
|
|
||||||
{
|
|
||||||
return no_actions_parser<ParserT>(subject.derived());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// no_actions_d
|
|
||||||
|
|
||||||
const no_actions_parser_gen no_actions_d = no_actions_parser_gen();
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
} // namespace spirit
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // !defined(BOOST_SPIRIT_NO_ACTIONS_HPP)
|
|
@ -1,26 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_OPERATORS_HPP)
|
|
||||||
#define BOOST_SPIRIT_OPERATORS_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/core/composite/sequence.hpp>
|
|
||||||
#include <boost/spirit/core/composite/sequential_and.hpp>
|
|
||||||
#include <boost/spirit/core/composite/sequential_or.hpp>
|
|
||||||
#include <boost/spirit/core/composite/alternative.hpp>
|
|
||||||
#include <boost/spirit/core/composite/difference.hpp>
|
|
||||||
#include <boost/spirit/core/composite/intersection.hpp>
|
|
||||||
#include <boost/spirit/core/composite/exclusive_or.hpp>
|
|
||||||
#include <boost/spirit/core/composite/kleene_star.hpp>
|
|
||||||
#include <boost/spirit/core/composite/positive.hpp>
|
|
||||||
#include <boost/spirit/core/composite/optional.hpp>
|
|
||||||
#include <boost/spirit/core/composite/list.hpp>
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,90 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_OPTIONAL_HPP)
|
|
||||||
#define BOOST_SPIRIT_OPTIONAL_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/primitives/primitives.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
#include <boost/spirit/meta/as_parser.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// optional class
|
|
||||||
//
|
|
||||||
// Handles expressions of the form:
|
|
||||||
//
|
|
||||||
// !a
|
|
||||||
//
|
|
||||||
// where a is a parser. The expression returns a composite
|
|
||||||
// parser that matches its subject zero (0) or one (1) time.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct optional_parser_gen;
|
|
||||||
|
|
||||||
template <typename S>
|
|
||||||
struct optional
|
|
||||||
: public unary<S, parser<optional<S> > >
|
|
||||||
{
|
|
||||||
typedef optional<S> self_t;
|
|
||||||
typedef unary_parser_category parser_category_t;
|
|
||||||
typedef optional_parser_gen parser_generator_t;
|
|
||||||
typedef unary<S, parser<self_t> > base_t;
|
|
||||||
|
|
||||||
optional(S const& a)
|
|
||||||
: base_t(a) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
typedef typename ScannerT::iterator_t iterator_t;
|
|
||||||
iterator_t save = scan.first;
|
|
||||||
if (result_t r = this->subject().parse(scan))
|
|
||||||
{
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
scan.first = save;
|
|
||||||
return scan.empty_match();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct optional_parser_gen
|
|
||||||
{
|
|
||||||
template <typename S>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef optional<S> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename S>
|
|
||||||
static optional<S>
|
|
||||||
generate(parser<S> const& a)
|
|
||||||
{
|
|
||||||
return optional<S>(a.derived());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename S>
|
|
||||||
optional<S>
|
|
||||||
operator!(parser<S> const& a);
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/spirit/core/composite/impl/optional.ipp>
|
|
@ -1,99 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_POSITIVE_HPP)
|
|
||||||
#define BOOST_SPIRIT_POSITIVE_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/primitives/primitives.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
#include <boost/spirit/meta/as_parser.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// positive class
|
|
||||||
//
|
|
||||||
// Handles expressions of the form:
|
|
||||||
//
|
|
||||||
// +a
|
|
||||||
//
|
|
||||||
// where a is a parser. The expression returns a composite
|
|
||||||
// parser that matches its subject one (1) or more times.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct positive_parser_gen;
|
|
||||||
|
|
||||||
template <typename S>
|
|
||||||
struct positive
|
|
||||||
: public unary<S, parser<positive<S> > >
|
|
||||||
{
|
|
||||||
typedef positive<S> self_t;
|
|
||||||
typedef unary_parser_category parser_category_t;
|
|
||||||
typedef positive_parser_gen parser_generator_t;
|
|
||||||
typedef unary<S, parser<self_t> > base_t;
|
|
||||||
|
|
||||||
positive(S const& a)
|
|
||||||
: base_t(a) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
typedef typename ScannerT::iterator_t iterator_t;
|
|
||||||
result_t hit = this->subject().parse(scan);
|
|
||||||
|
|
||||||
if (hit)
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
iterator_t save = scan.first;
|
|
||||||
if (result_t next = this->subject().parse(scan))
|
|
||||||
{
|
|
||||||
scan.concat_match(hit, next);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
scan.first = save;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hit;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct positive_parser_gen
|
|
||||||
{
|
|
||||||
template <typename S>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef positive<S> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename S>
|
|
||||||
static positive<S>
|
|
||||||
generate(parser<S> const& a)
|
|
||||||
{
|
|
||||||
return positive<S>(a.derived());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename S>
|
|
||||||
inline positive<S>
|
|
||||||
operator+(parser<S> const& a);
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/spirit/core/composite/impl/positive.ipp>
|
|
@ -1,129 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_SEQUENCE_HPP)
|
|
||||||
#define BOOST_SPIRIT_SEQUENCE_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/primitives/primitives.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
#include <boost/spirit/meta/as_parser.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// sequence class
|
|
||||||
//
|
|
||||||
// Handles expressions of the form:
|
|
||||||
//
|
|
||||||
// a >> b
|
|
||||||
//
|
|
||||||
// where a and b are parsers. The expression returns a composite
|
|
||||||
// parser that matches a and b in sequence. One (not both) of the
|
|
||||||
// operands may be a literal char, wchar_t or a primitive string
|
|
||||||
// char const*, wchar_t const*.
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
struct sequence_parser_gen;
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct sequence : public binary<A, B, parser<sequence<A, B> > >
|
|
||||||
{
|
|
||||||
typedef sequence<A, B> self_t;
|
|
||||||
typedef binary_parser_category parser_category_t;
|
|
||||||
typedef sequence_parser_gen parser_generator_t;
|
|
||||||
typedef binary<A, B, parser<self_t> > base_t;
|
|
||||||
|
|
||||||
sequence(A const& a, B const& b)
|
|
||||||
: base_t(a, b) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
if (result_t ma = this->left().parse(scan))
|
|
||||||
if (result_t mb = this->right().parse(scan))
|
|
||||||
{
|
|
||||||
scan.concat_match(ma, mb);
|
|
||||||
return ma;
|
|
||||||
}
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sequence_parser_gen
|
|
||||||
{
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
sequence<
|
|
||||||
typename as_parser<A>::type
|
|
||||||
, typename as_parser<B>::type
|
|
||||||
>
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
static sequence<
|
|
||||||
typename as_parser<A>::type
|
|
||||||
, typename as_parser<B>::type
|
|
||||||
>
|
|
||||||
generate(A const& a, B const& b)
|
|
||||||
{
|
|
||||||
return sequence<BOOST_DEDUCED_TYPENAME as_parser<A>::type,
|
|
||||||
BOOST_DEDUCED_TYPENAME as_parser<B>::type>
|
|
||||||
(as_parser<A>::convert(a), as_parser<B>::convert(b));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
sequence<A, B>
|
|
||||||
operator>>(parser<A> const& a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
sequence<A, chlit<char> >
|
|
||||||
operator>>(parser<A> const& a, char b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
sequence<chlit<char>, B>
|
|
||||||
operator>>(char a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
sequence<A, strlit<char const*> >
|
|
||||||
operator>>(parser<A> const& a, char const* b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
sequence<strlit<char const*>, B>
|
|
||||||
operator>>(char const* a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
sequence<A, chlit<wchar_t> >
|
|
||||||
operator>>(parser<A> const& a, wchar_t b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
sequence<chlit<wchar_t>, B>
|
|
||||||
operator>>(wchar_t a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
sequence<A, strlit<wchar_t const*> >
|
|
||||||
operator>>(parser<A> const& a, wchar_t const* b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
sequence<strlit<wchar_t const*>, B>
|
|
||||||
operator>>(wchar_t const* a, parser<B> const& b);
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/spirit/core/composite/impl/sequence.ipp>
|
|
@ -1,72 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_SEQUENTIAL_AND_HPP)
|
|
||||||
#define BOOST_SPIRIT_SEQUENTIAL_AND_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/primitives/primitives.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
#include <boost/spirit/meta/as_parser.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// sequential-and operators
|
|
||||||
//
|
|
||||||
// Handles expressions of the form:
|
|
||||||
//
|
|
||||||
// a && b
|
|
||||||
//
|
|
||||||
// Same as a >> b.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename A, typename B>
|
|
||||||
sequence<A, B>
|
|
||||||
operator&&(parser<A> const& a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
sequence<A, chlit<char> >
|
|
||||||
operator&&(parser<A> const& a, char b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
sequence<chlit<char>, B>
|
|
||||||
operator&&(char a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
sequence<A, strlit<char const*> >
|
|
||||||
operator&&(parser<A> const& a, char const* b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
sequence<strlit<char const*>, B>
|
|
||||||
operator&&(char const* a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
sequence<A, chlit<wchar_t> >
|
|
||||||
operator&&(parser<A> const& a, wchar_t b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
sequence<chlit<wchar_t>, B>
|
|
||||||
operator&&(wchar_t a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
sequence<A, strlit<wchar_t const*> >
|
|
||||||
operator&&(parser<A> const& a, wchar_t const* b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
sequence<strlit<wchar_t const*>, B>
|
|
||||||
operator&&(wchar_t const* a, parser<B> const& b);
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/spirit/core/composite/impl/sequential_and.ipp>
|
|
@ -1,150 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
Copyright (c) 2002 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_SEQUENTIAL_OR_HPP)
|
|
||||||
#define BOOST_SPIRIT_SEQUENTIAL_OR_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/primitives/primitives.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
#include <boost/spirit/meta/as_parser.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// sequential-or class
|
|
||||||
//
|
|
||||||
// Handles expressions of the form:
|
|
||||||
//
|
|
||||||
// a || b
|
|
||||||
//
|
|
||||||
// Equivalent to
|
|
||||||
//
|
|
||||||
// a | b | a >> b;
|
|
||||||
//
|
|
||||||
// where a and b are parsers. The expression returns a composite
|
|
||||||
// parser that matches matches a or b in sequence. One (not both) of
|
|
||||||
// the operands may be a literal char, wchar_t or a primitive string
|
|
||||||
// char const*, wchar_t const*.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct sequential_or_parser_gen;
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct sequential_or : public binary<A, B, parser<sequential_or<A, B> > >
|
|
||||||
{
|
|
||||||
typedef sequential_or<A, B> self_t;
|
|
||||||
typedef binary_parser_category parser_category_t;
|
|
||||||
typedef sequential_or_parser_gen parser_generator_t;
|
|
||||||
typedef binary<A, B, parser<self_t> > base_t;
|
|
||||||
|
|
||||||
sequential_or(A const& a, B const& b)
|
|
||||||
: base_t(a, b) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
typedef typename ScannerT::iterator_t iterator_t;
|
|
||||||
{ // scope for save
|
|
||||||
iterator_t save = scan.first;
|
|
||||||
if (result_t ma = this->left().parse(scan))
|
|
||||||
{
|
|
||||||
save = scan.first;
|
|
||||||
if (result_t mb = this->right().parse(scan))
|
|
||||||
{
|
|
||||||
// matched a b
|
|
||||||
scan.concat_match(ma, mb);
|
|
||||||
return ma;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// matched a
|
|
||||||
scan.first = save;
|
|
||||||
return ma;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scan.first = save;
|
|
||||||
}
|
|
||||||
|
|
||||||
// matched b
|
|
||||||
return this->right().parse(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sequential_or_parser_gen
|
|
||||||
{
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
sequential_or<
|
|
||||||
typename as_parser<A>::type
|
|
||||||
, typename as_parser<B>::type
|
|
||||||
>
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
static sequential_or<
|
|
||||||
typename as_parser<A>::type
|
|
||||||
, typename as_parser<B>::type
|
|
||||||
>
|
|
||||||
generate(A const& a, B const& b)
|
|
||||||
{
|
|
||||||
return sequential_or<BOOST_DEDUCED_TYPENAME as_parser<A>::type,
|
|
||||||
BOOST_DEDUCED_TYPENAME as_parser<B>::type>
|
|
||||||
(as_parser<A>::convert(a), as_parser<B>::convert(b));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
sequential_or<A, B>
|
|
||||||
operator||(parser<A> const& a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
sequential_or<A, chlit<char> >
|
|
||||||
operator||(parser<A> const& a, char b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
sequential_or<chlit<char>, B>
|
|
||||||
operator||(char a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
sequential_or<A, strlit<char const*> >
|
|
||||||
operator||(parser<A> const& a, char const* b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
sequential_or<strlit<char const*>, B>
|
|
||||||
operator||(char const* a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
sequential_or<A, chlit<wchar_t> >
|
|
||||||
operator||(parser<A> const& a, wchar_t b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
sequential_or<chlit<wchar_t>, B>
|
|
||||||
operator||(wchar_t a, parser<B> const& b);
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
sequential_or<A, strlit<wchar_t const*> >
|
|
||||||
operator||(parser<A> const& a, wchar_t const* b);
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
sequential_or<strlit<wchar_t const*>, B>
|
|
||||||
operator||(wchar_t const* a, parser<B> const& b);
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/spirit/core/composite/impl/sequential_or.ipp>
|
|
@ -1,63 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2001-2003 Joel de Guzman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_CONFIG_HPP)
|
|
||||||
#define BOOST_SPIRIT_CONFIG_HPP
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Compiler check:
|
|
||||||
//
|
|
||||||
// Historically, Spirit supported a lot of compilers, including (to some
|
|
||||||
// extent) poorly conforming compilers such as VC6. Spirit v1.6.x will be
|
|
||||||
// the last release that will support older poorly conforming compilers.
|
|
||||||
// Starting from Spirit v1.8.0, ill conforming compilers will not be
|
|
||||||
// supported. If you are still using one of these older compilers, you can
|
|
||||||
// still use Spirit v1.6.x.
|
|
||||||
//
|
|
||||||
// The reason why Spirit v1.6.x worked on old non-conforming compilers is
|
|
||||||
// that the authors laboriously took the trouble of searching for
|
|
||||||
// workarounds to make these compilers happy. The process takes a lot of
|
|
||||||
// time and energy, especially when one encounters the dreaded ICE or
|
|
||||||
// "Internal Compiler Error". Sometimes searching for a single workaround
|
|
||||||
// takes days or even weeks. Sometimes, there are no known workarounds. This
|
|
||||||
// stifles progress a lot. And, as the library gets more progressive and
|
|
||||||
// takes on more advanced C++ techniques, the difficulty is escalated to
|
|
||||||
// even new heights.
|
|
||||||
//
|
|
||||||
// Spirit v1.6.x will still be supported. Maintenance and bug fixes will
|
|
||||||
// still be applied. There will still be active development for the back-
|
|
||||||
// porting of new features introduced in Spirit v1.8.0 (and Spirit 1.9.0)
|
|
||||||
// to lesser able compilers; hopefully, fueled by contributions from the
|
|
||||||
// community. For instance, there is already a working AST tree back-port
|
|
||||||
// for VC6 and VC7 by Peder Holt.
|
|
||||||
//
|
|
||||||
// If you got here somehow, your compiler is known to be poorly conforming
|
|
||||||
// WRT ANSI/ISO C++ standard. Library implementers get a bad reputation when
|
|
||||||
// someone attempts to compile the code on a non-conforming compiler. She'll
|
|
||||||
// be confronted with tons of compiler errors when she tries to compile the
|
|
||||||
// library. Such errors will somehow make less informed users conclude that
|
|
||||||
// the code is poorly written. It's better for the user to see a message
|
|
||||||
// "sorry, this code has not been ported to your compiler yet", than to see
|
|
||||||
// pages and pages of compiler error messages.
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
|
||||||
#if (defined(BOOST_MSVC) && (BOOST_MSVC < 1310)) \
|
|
||||||
|| (defined(__BORLANDC__) && (__BORLANDC__ <= 0x570)) \
|
|
||||||
|| (defined(__GNUC__) && (__GNUC__ < 3)) \
|
|
||||||
|| (defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ < 1))
|
|
||||||
# error "Compiler not supported. See note in <boost/spirit/core/config.hpp>"
|
|
||||||
#else
|
|
||||||
// Pass... Compiler supported.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_MATCH_IPP)
|
|
||||||
#define BOOST_SPIRIT_MATCH_IPP
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit
|
|
||||||
{
|
|
||||||
template <typename T>
|
|
||||||
inline match<T>::match()
|
|
||||||
: len(-1), val() {}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline match<T>::match(std::size_t length)
|
|
||||||
: len(length), val() {}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline match<T>::match(std::size_t length, ctor_param_t val_)
|
|
||||||
: len(length), val(val_) {}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool
|
|
||||||
match<T>::operator!() const
|
|
||||||
{
|
|
||||||
return len < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline std::ptrdiff_t
|
|
||||||
match<T>::length() const
|
|
||||||
{
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool
|
|
||||||
match<T>::has_valid_attribute() const
|
|
||||||
{
|
|
||||||
return val.is_initialized();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline typename match<T>::return_t
|
|
||||||
match<T>::value() const
|
|
||||||
{
|
|
||||||
BOOST_SPIRIT_ASSERT(val.is_initialized());
|
|
||||||
return *val;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline void
|
|
||||||
match<T>::swap(match& other)
|
|
||||||
{
|
|
||||||
std::swap(len, other.len);
|
|
||||||
std::swap(val, other.val);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline match<nil_t>::match()
|
|
||||||
: len(-1) {}
|
|
||||||
|
|
||||||
inline match<nil_t>::match(std::size_t length)
|
|
||||||
: len(length) {}
|
|
||||||
|
|
||||||
inline match<nil_t>::match(std::size_t length, nil_t)
|
|
||||||
: len(length) {}
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
match<nil_t>::operator!() const
|
|
||||||
{
|
|
||||||
return len < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
match<nil_t>::has_valid_attribute() const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::ptrdiff_t
|
|
||||||
match<nil_t>::length() const
|
|
||||||
{
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline nil_t
|
|
||||||
match<nil_t>::value() const
|
|
||||||
{
|
|
||||||
return nil_t();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
match<nil_t>::value(nil_t) {}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
match<nil_t>::swap(match<nil_t>& other)
|
|
||||||
{
|
|
||||||
std::swap(len, other.len);
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_MATCH_ATTR_TRAITS_IPP)
|
|
||||||
#define BOOST_SPIRIT_MATCH_ATTR_TRAITS_IPP
|
|
||||||
|
|
||||||
#include <boost/optional.hpp>
|
|
||||||
#include <boost/mpl/bool.hpp>
|
|
||||||
#include <boost/mpl/or.hpp>
|
|
||||||
#include <boost/type_traits/is_convertible.hpp>
|
|
||||||
#include <boost/type_traits/is_same.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit { namespace impl
|
|
||||||
{
|
|
||||||
template <typename T>
|
|
||||||
struct match_attr_traits
|
|
||||||
{
|
|
||||||
typedef typename
|
|
||||||
boost::optional<T>::reference_const_type
|
|
||||||
const_reference;
|
|
||||||
|
|
||||||
// case where src *IS* convertible to T (dest)
|
|
||||||
template <typename T2>
|
|
||||||
static void
|
|
||||||
convert(boost::optional<T>& dest, T2 const& src, mpl::true_)
|
|
||||||
{
|
|
||||||
dest.reset(src);
|
|
||||||
}
|
|
||||||
|
|
||||||
// case where src *IS NOT* convertible to T (dest)
|
|
||||||
template <typename T2>
|
|
||||||
static void
|
|
||||||
convert(boost::optional<T>& dest, T2 const& /*src*/, mpl::false_)
|
|
||||||
{
|
|
||||||
dest.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
convert(boost::optional<T>& dest, nil_t/*src*/)
|
|
||||||
{
|
|
||||||
dest.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T2>
|
|
||||||
static void
|
|
||||||
convert(boost::optional<T>& dest, T2 const& src)
|
|
||||||
{
|
|
||||||
convert(dest, src, is_convertible<T2, T>());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OtherMatchT>
|
|
||||||
static void
|
|
||||||
copy(boost::optional<T>& dest, OtherMatchT const& src)
|
|
||||||
{
|
|
||||||
if (src.has_valid_attribute())
|
|
||||||
convert(dest, src.value());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OtherMatchT>
|
|
||||||
static void
|
|
||||||
assign(boost::optional<T>& dest, OtherMatchT const& src)
|
|
||||||
{
|
|
||||||
if (src.has_valid_attribute())
|
|
||||||
convert(dest, src.value());
|
|
||||||
else
|
|
||||||
dest.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// T is not reference
|
|
||||||
template <typename ValueT>
|
|
||||||
static void
|
|
||||||
set_value(boost::optional<T>& dest, ValueT const& val, mpl::false_)
|
|
||||||
{
|
|
||||||
dest.reset(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
// T is a reference
|
|
||||||
template <typename ValueT>
|
|
||||||
static void
|
|
||||||
set_value(boost::optional<T>& dest, ValueT const& val, mpl::true_)
|
|
||||||
{
|
|
||||||
dest.get() = val;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}}} // namespace boost::spirit::impl
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_PARSER_IPP)
|
|
||||||
#define BOOST_SPIRIT_PARSER_IPP
|
|
||||||
|
|
||||||
namespace boost { namespace spirit
|
|
||||||
{
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generic parse function implementation
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename IteratorT, typename DerivedT>
|
|
||||||
inline parse_info<IteratorT>
|
|
||||||
parse(
|
|
||||||
IteratorT const& first_
|
|
||||||
, IteratorT const& last
|
|
||||||
, parser<DerivedT> const& p)
|
|
||||||
{
|
|
||||||
IteratorT first = first_;
|
|
||||||
scanner<IteratorT, scanner_policies<> > scan(first, last);
|
|
||||||
match<nil_t> hit = p.derived().parse(scan);
|
|
||||||
return parse_info<IteratorT>(
|
|
||||||
first, hit, hit && (first == last), hit.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Parse function for null terminated strings implementation
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename CharT, typename DerivedT>
|
|
||||||
inline parse_info<CharT const*>
|
|
||||||
parse(CharT const* str, parser<DerivedT> const& p)
|
|
||||||
{
|
|
||||||
CharT const* last = str;
|
|
||||||
while (*last)
|
|
||||||
last++;
|
|
||||||
return parse(str, last, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,181 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_MATCH_HPP)
|
|
||||||
#define BOOST_SPIRIT_MATCH_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/core/config.hpp>
|
|
||||||
#include <boost/spirit/core/nil.hpp>
|
|
||||||
#include <boost/call_traits.hpp>
|
|
||||||
#include <boost/optional.hpp>
|
|
||||||
#include <boost/spirit/core/assert.hpp>
|
|
||||||
#include <boost/spirit/core/safe_bool.hpp>
|
|
||||||
#include <boost/spirit/core/impl/match_attr_traits.ipp>
|
|
||||||
#include <boost/type_traits/add_const.hpp>
|
|
||||||
#include <boost/type_traits/is_reference.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit
|
|
||||||
{
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// match class
|
|
||||||
//
|
|
||||||
// The match holds the result of a parser. A match object evaluates
|
|
||||||
// to true when a successful match is found, otherwise false. The
|
|
||||||
// length of the match is the number of characters (or tokens) that
|
|
||||||
// is successfully matched. This can be queried through its length()
|
|
||||||
// member function. A negative value means that the match is
|
|
||||||
// unsucessful.
|
|
||||||
//
|
|
||||||
// Each parser may have an associated attribute. This attribute is
|
|
||||||
// also returned back to the client on a successful parse through
|
|
||||||
// the match object. The match's value() member function returns the
|
|
||||||
// match's attribute.
|
|
||||||
//
|
|
||||||
// A match attribute is valid:
|
|
||||||
//
|
|
||||||
// * on a successful match
|
|
||||||
// * when its value is set through the value(val) member function
|
|
||||||
// * if it is assigned or copied from a compatible match object
|
|
||||||
// (e.g. match<double> from match<int>) with a valid attribute.
|
|
||||||
//
|
|
||||||
// The match attribute is undefined:
|
|
||||||
//
|
|
||||||
// * on an unsuccessful match
|
|
||||||
// * when an attempt to copy or assign from another match object
|
|
||||||
// with an incompatible attribute type (e.g. match<std::string>
|
|
||||||
// from match<int>).
|
|
||||||
//
|
|
||||||
// The member function has_valid_attribute() can be queried to know if
|
|
||||||
// it is safe to get the match's attribute. The attribute may be set
|
|
||||||
// through the member function value(v) where v is the new attribute
|
|
||||||
// value.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T = nil_t>
|
|
||||||
class match : public safe_bool<match<T> >
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef typename boost::optional<T> optional_type;
|
|
||||||
typedef typename optional_type::argument_type ctor_param_t;
|
|
||||||
typedef typename optional_type::reference_const_type return_t;
|
|
||||||
typedef T attr_t;
|
|
||||||
|
|
||||||
match();
|
|
||||||
explicit match(std::size_t length);
|
|
||||||
match(std::size_t length, ctor_param_t val);
|
|
||||||
|
|
||||||
bool operator!() const;
|
|
||||||
std::ptrdiff_t length() const;
|
|
||||||
bool has_valid_attribute() const;
|
|
||||||
return_t value() const;
|
|
||||||
void swap(match& other);
|
|
||||||
|
|
||||||
template <typename T2>
|
|
||||||
match(match<T2> const& other)
|
|
||||||
: len(other.length()), val()
|
|
||||||
{
|
|
||||||
impl::match_attr_traits<T>::copy(val, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T2>
|
|
||||||
match&
|
|
||||||
operator=(match<T2> const& other)
|
|
||||||
{
|
|
||||||
impl::match_attr_traits<T>::assign(val, other);
|
|
||||||
len = other.length();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename MatchT>
|
|
||||||
void
|
|
||||||
concat(MatchT const& other)
|
|
||||||
{
|
|
||||||
BOOST_SPIRIT_ASSERT(*this && other);
|
|
||||||
len += other.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ValueT>
|
|
||||||
void
|
|
||||||
value(ValueT const& val_)
|
|
||||||
{
|
|
||||||
impl::match_attr_traits<T>::set_value(val, val_, is_reference<T>());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator_bool() const
|
|
||||||
{
|
|
||||||
return len >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::ptrdiff_t len;
|
|
||||||
optional_type val;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// match class specialization for nil_t values
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <>
|
|
||||||
class match<nil_t> : public safe_bool<match<nil_t> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef nil_t attr_t;
|
|
||||||
typedef nil_t return_t;
|
|
||||||
|
|
||||||
match();
|
|
||||||
explicit match(std::size_t length);
|
|
||||||
match(std::size_t length, nil_t);
|
|
||||||
|
|
||||||
bool operator!() const;
|
|
||||||
bool has_valid_attribute() const;
|
|
||||||
std::ptrdiff_t length() const;
|
|
||||||
nil_t value() const;
|
|
||||||
void value(nil_t);
|
|
||||||
void swap(match& other);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
match(match<T> const& other)
|
|
||||||
: len(other.length()) {}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
match<>&
|
|
||||||
operator=(match<T> const& other)
|
|
||||||
{
|
|
||||||
len = other.length();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void
|
|
||||||
concat(match<T> const& other)
|
|
||||||
{
|
|
||||||
BOOST_SPIRIT_ASSERT(*this && other);
|
|
||||||
len += other.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator_bool() const
|
|
||||||
{
|
|
||||||
return len >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::ptrdiff_t len;
|
|
||||||
};
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#include <boost/spirit/core/impl/match.ipp>
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2001-2003 Joel de Guzman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_NIL_HPP)
|
|
||||||
#define BOOST_SPIRIT_NIL_HPP
|
|
||||||
|
|
||||||
namespace boost { namespace spirit
|
|
||||||
{
|
|
||||||
struct nil_t {};
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2001-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2002-2003 Martin Wille
|
|
||||||
Copyright (c) 2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_GRAMMAR_HPP)
|
|
||||||
#define BOOST_SPIRIT_GRAMMAR_HPP
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#if defined(BOOST_SPIRIT_THREADSAFE) && defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
|
|
||||||
#undef BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/non_terminal/parser_context.hpp>
|
|
||||||
#include <boost/spirit/core/non_terminal/impl/grammar.ipp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// grammar class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename DerivedT, typename ContextT = parser_context<> >
|
|
||||||
struct grammar
|
|
||||||
: public parser<DerivedT>
|
|
||||||
, public ContextT::base_t
|
|
||||||
, public context_aux<ContextT, DerivedT>
|
|
||||||
BOOST_SPIRIT_GRAMMAR_ID
|
|
||||||
{
|
|
||||||
typedef grammar<DerivedT, ContextT> self_t;
|
|
||||||
typedef DerivedT const& embed_t;
|
|
||||||
typedef typename ContextT::context_linker_t context_t;
|
|
||||||
typedef typename context_t::attr_t attr_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename match_result<ScannerT, attr_t>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
grammar() {}
|
|
||||||
~grammar() { impl::grammar_destruct(this); }
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse_main(ScannerT const& scan) const
|
|
||||||
{ return impl::grammar_parser_parse<0>(this, scan); }
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
typedef parser_scanner_linker<ScannerT> scanner_t;
|
|
||||||
BOOST_SPIRIT_CONTEXT_PARSE(scan, *this, scanner_t, context_t, result_t)
|
|
||||||
}
|
|
||||||
|
|
||||||
template <int N>
|
|
||||||
impl::entry_grammar<DerivedT, N, ContextT>
|
|
||||||
use_parser() const
|
|
||||||
{ return impl::entry_grammar<DerivedT, N, ContextT>( this->derived()); }
|
|
||||||
|
|
||||||
BOOST_SPIRIT_GRAMMAR_STATE
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#undef BOOST_SPIRIT_GRAMMAR_ID
|
|
||||||
#undef BOOST_SPIRIT_GRAMMAR_ACCESS
|
|
||||||
#undef BOOST_SPIRIT_GRAMMAR_STATE
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,388 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2001-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2002-2003 Martin Wille
|
|
||||||
Copyright (c) 2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_GRAMMAR_IPP
|
|
||||||
#define BOOST_SPIRIT_GRAMMAR_IPP
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
|
|
||||||
#include <boost/spirit/core/non_terminal/impl/object_with_id.ipp>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <functional>
|
|
||||||
#include <memory> // for std::auto_ptr
|
|
||||||
#include <boost/weak_ptr.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
|
||||||
#include <boost/thread/tss.hpp>
|
|
||||||
#include <boost/thread/mutex.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
template <typename DerivedT, typename ContextT>
|
|
||||||
struct grammar;
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
|
||||||
|
|
||||||
BOOST_SPIRIT_DEPENDENT_TEMPLATE_WRAPPER(grammar_definition_wrapper, definition);
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename GrammarT, typename ScannerT>
|
|
||||||
struct grammar_definition
|
|
||||||
{
|
|
||||||
typedef typename impl::grammar_definition_wrapper<GrammarT>
|
|
||||||
::template result_<ScannerT>::param_t type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename GrammarT, typename ScannerT>
|
|
||||||
struct grammar_definition
|
|
||||||
{
|
|
||||||
typedef typename GrammarT::template definition<ScannerT> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
|
|
||||||
struct grammar_tag {};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename GrammarT>
|
|
||||||
struct grammar_helper_base
|
|
||||||
{
|
|
||||||
virtual int undefine(GrammarT *) = 0;
|
|
||||||
virtual ~grammar_helper_base() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename GrammarT>
|
|
||||||
struct grammar_helper_list
|
|
||||||
{
|
|
||||||
typedef GrammarT grammar_t;
|
|
||||||
typedef grammar_helper_base<GrammarT> helper_t;
|
|
||||||
typedef std::vector<helper_t*> vector_t;
|
|
||||||
|
|
||||||
grammar_helper_list() {}
|
|
||||||
grammar_helper_list(grammar_helper_list const& /*x*/)
|
|
||||||
{ // Does _not_ copy the helpers member !
|
|
||||||
}
|
|
||||||
|
|
||||||
grammar_helper_list& operator=(grammar_helper_list const& x)
|
|
||||||
{ // Does _not_ copy the helpers member !
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void push_back(helper_t *helper)
|
|
||||||
{ helpers.push_back(helper); }
|
|
||||||
|
|
||||||
void pop_back()
|
|
||||||
{ helpers.pop_back(); }
|
|
||||||
|
|
||||||
typename vector_t::size_type
|
|
||||||
size() const
|
|
||||||
{ return helpers.size(); }
|
|
||||||
|
|
||||||
typename vector_t::reverse_iterator
|
|
||||||
rbegin()
|
|
||||||
{ return helpers.rbegin(); }
|
|
||||||
|
|
||||||
typename vector_t::reverse_iterator
|
|
||||||
rend()
|
|
||||||
{ return helpers.rend(); }
|
|
||||||
|
|
||||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
|
||||||
boost::mutex & mutex()
|
|
||||||
{ return m; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
vector_t helpers;
|
|
||||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
|
||||||
boost::mutex m;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
struct grammartract_helper_list;
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) \
|
|
||||||
&& (!defined(__GNUC__) || (__GNUC__ > 2))
|
|
||||||
|
|
||||||
struct grammartract_helper_list
|
|
||||||
{
|
|
||||||
template<typename GrammarT>
|
|
||||||
static grammar_helper_list<GrammarT>&
|
|
||||||
do_(GrammarT const* g)
|
|
||||||
{
|
|
||||||
return g->helpers;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename GrammarT, typename DerivedT, typename ScannerT>
|
|
||||||
struct grammar_helper : private grammar_helper_base<GrammarT>
|
|
||||||
{
|
|
||||||
typedef GrammarT grammar_t;
|
|
||||||
typedef ScannerT scanner_t;
|
|
||||||
typedef DerivedT derived_t;
|
|
||||||
typedef typename grammar_definition<DerivedT, ScannerT>::type definition_t;
|
|
||||||
|
|
||||||
typedef grammar_helper<grammar_t, derived_t, scanner_t> helper_t;
|
|
||||||
typedef boost::shared_ptr<helper_t> helper_ptr_t;
|
|
||||||
typedef boost::weak_ptr<helper_t> helper_weak_ptr_t;
|
|
||||||
|
|
||||||
grammar_helper*
|
|
||||||
this_() { return this; }
|
|
||||||
|
|
||||||
grammar_helper(helper_weak_ptr_t& p)
|
|
||||||
: definitions_cnt(0)
|
|
||||||
, self(this_())
|
|
||||||
{ p = self; }
|
|
||||||
|
|
||||||
definition_t&
|
|
||||||
define(grammar_t const* target_grammar)
|
|
||||||
{
|
|
||||||
grammar_helper_list<GrammarT> &helpers =
|
|
||||||
#if !defined(__GNUC__) || (__GNUC__ > 2)
|
|
||||||
grammartract_helper_list::do_(target_grammar);
|
|
||||||
#else
|
|
||||||
target_grammar->helpers;
|
|
||||||
#endif
|
|
||||||
typename grammar_t::object_id id = target_grammar->get_object_id();
|
|
||||||
|
|
||||||
if (definitions.size()<=id)
|
|
||||||
definitions.resize(id*3/2+1);
|
|
||||||
if (definitions[id]!=0)
|
|
||||||
return *definitions[id];
|
|
||||||
|
|
||||||
std::auto_ptr<definition_t>
|
|
||||||
result(new definition_t(target_grammar->derived()));
|
|
||||||
|
|
||||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
|
||||||
boost::mutex::scoped_lock lock(helpers.mutex());
|
|
||||||
#endif
|
|
||||||
helpers.push_back(this);
|
|
||||||
|
|
||||||
++definitions_cnt;
|
|
||||||
definitions[id] = result.get();
|
|
||||||
return *(result.release());
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
undefine(grammar_t* target_grammar)
|
|
||||||
{
|
|
||||||
typename grammar_t::object_id id = target_grammar->get_object_id();
|
|
||||||
|
|
||||||
if (definitions.size()<=id)
|
|
||||||
return 0;
|
|
||||||
delete definitions[id];
|
|
||||||
definitions[id] = 0;
|
|
||||||
if (--definitions_cnt==0)
|
|
||||||
self.reset();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::vector<definition_t*> definitions;
|
|
||||||
unsigned long definitions_cnt;
|
|
||||||
helper_ptr_t self;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) */
|
|
||||||
|
|
||||||
template<typename DerivedT, typename ContextT, typename ScannerT>
|
|
||||||
inline typename DerivedT::template definition<ScannerT> &
|
|
||||||
get_definition(grammar<DerivedT, ContextT> const* self)
|
|
||||||
{
|
|
||||||
#if defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
|
|
||||||
|
|
||||||
typedef typename DerivedT::template definition<ScannerT> definition_t;
|
|
||||||
static definition_t def(self->derived());
|
|
||||||
return def;
|
|
||||||
#else
|
|
||||||
typedef grammar<DerivedT, ContextT> self_t;
|
|
||||||
typedef impl::grammar_helper<self_t, DerivedT, ScannerT> helper_t;
|
|
||||||
typedef typename helper_t::helper_weak_ptr_t ptr_t;
|
|
||||||
|
|
||||||
# ifdef BOOST_SPIRIT_THREADSAFE
|
|
||||||
static boost::thread_specific_ptr<ptr_t> tld_helper;
|
|
||||||
if (!tld_helper.get())
|
|
||||||
tld_helper.reset(new ptr_t);
|
|
||||||
ptr_t &helper = *tld_helper;
|
|
||||||
# else
|
|
||||||
static ptr_t helper;
|
|
||||||
# endif
|
|
||||||
if (!boost::make_shared(helper).get())
|
|
||||||
new helper_t(helper);
|
|
||||||
return boost::make_shared(helper)->define(self);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
|
||||||
template <int N>
|
|
||||||
struct call_helper {
|
|
||||||
|
|
||||||
template <typename RT, typename DefinitionT, typename ScannerT>
|
|
||||||
static void
|
|
||||||
do_ (RT &result, DefinitionT &def, ScannerT const &scan)
|
|
||||||
{
|
|
||||||
result = def.template get_start_parser<N>()->parse(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
// The grammar_def stuff isn't supported for compilers, which do not
|
|
||||||
// support partial template specialization
|
|
||||||
template <int N> struct call_helper;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct call_helper<0> {
|
|
||||||
|
|
||||||
template <typename RT, typename DefinitionT, typename ScannerT>
|
|
||||||
static void
|
|
||||||
do_ (RT &result, DefinitionT &def, ScannerT const &scan)
|
|
||||||
{
|
|
||||||
result = def.start().parse(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template<int N, typename DerivedT, typename ContextT, typename ScannerT>
|
|
||||||
inline typename parser_result<grammar<DerivedT, ContextT>, ScannerT>::type
|
|
||||||
grammar_parser_parse(
|
|
||||||
grammar<DerivedT, ContextT> const* self,
|
|
||||||
ScannerT const &scan)
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
typename parser_result<grammar<DerivedT, ContextT>, ScannerT>::type
|
|
||||||
result_t;
|
|
||||||
typedef typename DerivedT::template definition<ScannerT> definition_t;
|
|
||||||
|
|
||||||
result_t result;
|
|
||||||
definition_t &def = get_definition<DerivedT, ContextT, ScannerT>(self);
|
|
||||||
|
|
||||||
call_helper<N>::do_(result, def, scan);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template<typename GrammarT>
|
|
||||||
inline void
|
|
||||||
grammar_destruct(GrammarT* self)
|
|
||||||
{
|
|
||||||
#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
|
|
||||||
typedef impl::grammar_helper_base<GrammarT> helper_base_t;
|
|
||||||
typedef grammar_helper_list<GrammarT> helper_list_t;
|
|
||||||
typedef typename helper_list_t::vector_t::reverse_iterator iterator_t;
|
|
||||||
|
|
||||||
helper_list_t& helpers =
|
|
||||||
# if !defined(__GNUC__) || (__GNUC__ > 2)
|
|
||||||
grammartract_helper_list::do_(self);
|
|
||||||
# else
|
|
||||||
self->helpers;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if (defined(BOOST_MSVC) && (BOOST_MSVC < 1300)) \
|
|
||||||
|| defined(BOOST_INTEL_CXX_VERSION)
|
|
||||||
for (iterator_t i = helpers.rbegin(); i != helpers.rend(); ++i)
|
|
||||||
(*i)->undefine(self);
|
|
||||||
# else
|
|
||||||
std::for_each(helpers.rbegin(), helpers.rend(),
|
|
||||||
std::bind2nd(std::mem_fun(&helper_base_t::undefine), self));
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
(void)self;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// entry_grammar class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename DerivedT, int N, typename ContextT>
|
|
||||||
class entry_grammar
|
|
||||||
: public parser<entry_grammar<DerivedT, N, ContextT> >
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef entry_grammar<DerivedT, N, ContextT> self_t;
|
|
||||||
typedef self_t embed_t;
|
|
||||||
typedef typename ContextT::context_linker_t context_t;
|
|
||||||
typedef typename context_t::attr_t attr_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename match_result<ScannerT, attr_t>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
entry_grammar(DerivedT const &p) : target_grammar(p) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse_main(ScannerT const& scan) const
|
|
||||||
{ return impl::grammar_parser_parse<N>(&target_grammar, scan); }
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
typedef parser_scanner_linker<ScannerT> scanner_t;
|
|
||||||
BOOST_SPIRIT_CONTEXT_PARSE(scan, target_grammar, scanner_t,
|
|
||||||
context_t, result_t)
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
DerivedT const &target_grammar;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace impl
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
|
|
||||||
#define BOOST_SPIRIT_GRAMMAR_ID , public impl::object_with_id<impl::grammar_tag>
|
|
||||||
#else
|
|
||||||
#define BOOST_SPIRIT_GRAMMAR_ID
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
#if !defined(__GNUC__) || (__GNUC__ > 2)
|
|
||||||
#define BOOST_SPIRIT_GRAMMAR_ACCESS private:
|
|
||||||
#else
|
|
||||||
#define BOOST_SPIRIT_GRAMMAR_ACCESS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
|
||||||
#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
|
|
||||||
#define BOOST_SPIRIT_GRAMMAR_STATE \
|
|
||||||
BOOST_SPIRIT_GRAMMAR_ACCESS \
|
|
||||||
friend struct impl::grammartract_helper_list; \
|
|
||||||
mutable impl::grammar_helper_list<self_t> helpers;
|
|
||||||
#else
|
|
||||||
#define BOOST_SPIRIT_GRAMMAR_STATE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,185 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2002-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2002-2003 Martin Wille
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_OBJECT_WITH_ID_IPP
|
|
||||||
#define BOOST_SPIRIT_OBJECT_WITH_ID_IPP
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
|
|
||||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
|
||||||
#include <boost/thread/mutex.hpp>
|
|
||||||
#include <boost/thread/once.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename IdT = std::size_t>
|
|
||||||
struct object_with_id_base_supply
|
|
||||||
{
|
|
||||||
typedef IdT object_id;
|
|
||||||
typedef std::vector<object_id> id_vector;
|
|
||||||
|
|
||||||
object_with_id_base_supply() : max_id(object_id()) {}
|
|
||||||
|
|
||||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
|
||||||
boost::mutex mutex;
|
|
||||||
#endif
|
|
||||||
object_id max_id;
|
|
||||||
id_vector free_ids;
|
|
||||||
|
|
||||||
object_id acquire();
|
|
||||||
void release(object_id);
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename TagT, typename IdT = std::size_t>
|
|
||||||
struct object_with_id_base
|
|
||||||
{
|
|
||||||
typedef TagT tag_t;
|
|
||||||
typedef IdT object_id;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
object_id acquire_object_id();
|
|
||||||
void release_object_id(object_id);
|
|
||||||
|
|
||||||
private:
|
|
||||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
|
||||||
static boost::mutex &mutex_instance();
|
|
||||||
static void mutex_init();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
boost::shared_ptr<object_with_id_base_supply<IdT> > id_supply;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template<class TagT, typename IdT = std::size_t>
|
|
||||||
struct object_with_id : private object_with_id_base<TagT, IdT>
|
|
||||||
{
|
|
||||||
typedef object_with_id<TagT, IdT> self_t;
|
|
||||||
typedef object_with_id_base<TagT, IdT> base_t;
|
|
||||||
typedef IdT object_id;
|
|
||||||
|
|
||||||
object_with_id() : id(base_t::acquire_object_id()) {}
|
|
||||||
object_with_id(self_t const &other)
|
|
||||||
: base_t(other)
|
|
||||||
, id(base_t::acquire_object_id())
|
|
||||||
{} // don't copy id
|
|
||||||
self_t &operator = (self_t const &other)
|
|
||||||
{ // don't assign id
|
|
||||||
base_t::operator=(other);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
~object_with_id() { base_t::release_object_id(id); }
|
|
||||||
object_id get_object_id() const { return id; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
object_id const id;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename IdT>
|
|
||||||
inline IdT
|
|
||||||
object_with_id_base_supply<IdT>::acquire()
|
|
||||||
{
|
|
||||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
|
||||||
boost::mutex::scoped_lock lock(mutex);
|
|
||||||
#endif
|
|
||||||
if (free_ids.size())
|
|
||||||
{
|
|
||||||
object_id id = *free_ids.rbegin();
|
|
||||||
free_ids.pop_back();
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (free_ids.capacity()<=max_id)
|
|
||||||
free_ids.reserve(max_id*3/2+1);
|
|
||||||
return ++max_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename IdT>
|
|
||||||
inline void
|
|
||||||
object_with_id_base_supply<IdT>::release(IdT id)
|
|
||||||
{
|
|
||||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
|
||||||
boost::mutex::scoped_lock lock(mutex);
|
|
||||||
#endif
|
|
||||||
if (max_id == id)
|
|
||||||
max_id--;
|
|
||||||
else
|
|
||||||
free_ids.push_back(id); // doesn't throw
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename TagT, typename IdT>
|
|
||||||
inline IdT
|
|
||||||
object_with_id_base<TagT, IdT>::acquire_object_id()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
|
||||||
static boost::once_flag been_here = BOOST_ONCE_INIT;
|
|
||||||
boost::call_once(mutex_init, been_here);
|
|
||||||
boost::mutex &mutex = mutex_instance();
|
|
||||||
boost::mutex::scoped_lock lock(mutex);
|
|
||||||
#endif
|
|
||||||
static boost::shared_ptr<object_with_id_base_supply<IdT> >
|
|
||||||
static_supply;
|
|
||||||
|
|
||||||
if (!static_supply.get())
|
|
||||||
static_supply.reset(new object_with_id_base_supply<IdT>());
|
|
||||||
id_supply = static_supply;
|
|
||||||
}
|
|
||||||
|
|
||||||
return id_supply->acquire();
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename TagT, typename IdT>
|
|
||||||
inline void
|
|
||||||
object_with_id_base<TagT, IdT>::release_object_id(IdT id)
|
|
||||||
{
|
|
||||||
id_supply->release(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
|
||||||
template <typename TagT, typename IdT>
|
|
||||||
inline boost::mutex &
|
|
||||||
object_with_id_base<TagT, IdT>::mutex_instance()
|
|
||||||
{
|
|
||||||
static boost::mutex mutex;
|
|
||||||
return mutex;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
|
||||||
template <typename TagT, typename IdT>
|
|
||||||
inline void
|
|
||||||
object_with_id_base<TagT, IdT>::mutex_init()
|
|
||||||
{
|
|
||||||
mutex_instance();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace impl
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,407 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_RULE_IPP)
|
|
||||||
#define BOOST_SPIRIT_RULE_IPP
|
|
||||||
|
|
||||||
#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
|
|
||||||
#include <boost/preprocessor/repeat.hpp>
|
|
||||||
#include <boost/preprocessor/repeat_from_to.hpp>
|
|
||||||
#include <boost/preprocessor/enum_params.hpp>
|
|
||||||
#include <boost/preprocessor/enum_params_with_defaults.hpp>
|
|
||||||
#include <boost/preprocessor/facilities/intercept.hpp>
|
|
||||||
#include <boost/preprocessor/inc.hpp>
|
|
||||||
#include <boost/preprocessor/cat.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/scanner/scanner.hpp>
|
|
||||||
#include <boost/spirit/core/non_terminal/parser_context.hpp>
|
|
||||||
#include <boost/spirit/core/non_terminal/parser_id.hpp>
|
|
||||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
|
|
||||||
|
|
||||||
template <
|
|
||||||
BOOST_PP_ENUM_BINARY_PARAMS(
|
|
||||||
BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT,
|
|
||||||
typename ScannerT, = mpl::void_ BOOST_PP_INTERCEPT
|
|
||||||
)
|
|
||||||
>
|
|
||||||
struct scanner_list;
|
|
||||||
|
|
||||||
#endif // BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
template <typename BaseT, typename DefaultT
|
|
||||||
, typename T0, typename T1, typename T2>
|
|
||||||
struct get_param
|
|
||||||
{
|
|
||||||
typedef typename mpl::if_<
|
|
||||||
is_base_and_derived<BaseT, T0>
|
|
||||||
, T0
|
|
||||||
, typename mpl::if_<
|
|
||||||
is_base_and_derived<BaseT, T1>
|
|
||||||
, T1
|
|
||||||
, typename mpl::if_<
|
|
||||||
is_base_and_derived<BaseT, T2>
|
|
||||||
, T2
|
|
||||||
, DefaultT
|
|
||||||
>::type
|
|
||||||
>::type
|
|
||||||
>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T0, typename T1, typename T2>
|
|
||||||
struct get_context
|
|
||||||
{
|
|
||||||
typedef typename get_param<
|
|
||||||
parser_context_base, parser_context<>, T0, T1, T2>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T0, typename T1, typename T2>
|
|
||||||
struct get_tag
|
|
||||||
{
|
|
||||||
typedef typename get_param<
|
|
||||||
parser_tag_base, parser_address_tag, T0, T1, T2>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T0, typename T1, typename T2>
|
|
||||||
struct get_scanner
|
|
||||||
{
|
|
||||||
typedef typename get_param<
|
|
||||||
scanner_base, scanner<>, T0, T1, T2>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// rule_base class
|
|
||||||
//
|
|
||||||
// The rule_base class implements the basic plumbing for rules
|
|
||||||
// minus the storage mechanism. It is up to the derived class
|
|
||||||
// to actually store the definition somewhere. The rule_base
|
|
||||||
// class assumes that the derived class provides a get() function
|
|
||||||
// that will return a pointer to a parser. The get() function
|
|
||||||
// may return NULL. See rule below for details.
|
|
||||||
//
|
|
||||||
// <<< For framework use only. Not for public consumption. >>>
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
template <
|
|
||||||
typename DerivedT // derived class
|
|
||||||
, typename EmbedT // how derived class is embedded
|
|
||||||
, typename T0 = nil_t // see rule class
|
|
||||||
, typename T1 = nil_t // see rule class
|
|
||||||
, typename T2 = nil_t // see rule class
|
|
||||||
>
|
|
||||||
class rule_base; // forward declaration
|
|
||||||
|
|
||||||
class rule_base_access
|
|
||||||
{
|
|
||||||
#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \
|
|
||||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
|
||||||
public: // YUCK!
|
|
||||||
#else
|
|
||||||
template <
|
|
||||||
typename DerivedT
|
|
||||||
, typename EmbedT
|
|
||||||
, typename T0
|
|
||||||
, typename T1
|
|
||||||
, typename T2
|
|
||||||
>
|
|
||||||
friend class rule_base;
|
|
||||||
#endif
|
|
||||||
template <typename RuleT>
|
|
||||||
static typename RuleT::abstract_parser_t*
|
|
||||||
get(RuleT const& r)
|
|
||||||
{
|
|
||||||
return r.get();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename DerivedT // derived class
|
|
||||||
, typename EmbedT // how derived class is embedded
|
|
||||||
, typename T0 // see rule class
|
|
||||||
, typename T1 // see rule class
|
|
||||||
, typename T2 // see rule class
|
|
||||||
>
|
|
||||||
class rule_base
|
|
||||||
: public parser<DerivedT>
|
|
||||||
, public impl::get_context<T0, T1, T2>::type::base_t
|
|
||||||
, public context_aux<
|
|
||||||
typename impl::get_context<T0, T1, T2>::type, DerivedT>
|
|
||||||
, public impl::get_tag<T0, T1, T2>::type
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef typename impl::get_scanner<T0, T1, T2>::type scanner_t;
|
|
||||||
typedef typename impl::get_context<T0, T1, T2>::type context_t;
|
|
||||||
typedef typename impl::get_tag<T0, T1, T2>::type tag_t;
|
|
||||||
|
|
||||||
typedef EmbedT embed_t;
|
|
||||||
typedef typename context_t::context_linker_t linked_context_t;
|
|
||||||
typedef typename linked_context_t::attr_t attr_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename match_result<ScannerT, attr_t>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<DerivedT, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef parser_scanner_linker<ScannerT> linked_scanner_t;
|
|
||||||
typedef typename parser_result<DerivedT, ScannerT>::type result_t;
|
|
||||||
BOOST_SPIRIT_CONTEXT_PARSE(
|
|
||||||
scan, *this, linked_scanner_t, linked_context_t, result_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<DerivedT, ScannerT>::type
|
|
||||||
parse_main(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typename parser_result<DerivedT, ScannerT>::type hit;
|
|
||||||
|
|
||||||
// MWCW 8.3 needs this cast to be done through a pointer,
|
|
||||||
// not a reference. Otherwise, it will silently construct
|
|
||||||
// a temporary, causing an infinite runtime recursion.
|
|
||||||
DerivedT const* derived_this = static_cast<DerivedT const*>(this);
|
|
||||||
|
|
||||||
if (rule_base_access::get(*derived_this))
|
|
||||||
{
|
|
||||||
typename ScannerT::iterator_t s(scan.first);
|
|
||||||
hit = rule_base_access::get(*derived_this)
|
|
||||||
->do_parse_virtual(scan);
|
|
||||||
scan.group_match(hit, this->id(), s, scan.first);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hit = scan.no_match();
|
|
||||||
}
|
|
||||||
return hit;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// abstract_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ScannerT, typename AttrT>
|
|
||||||
struct abstract_parser
|
|
||||||
{
|
|
||||||
abstract_parser() {}
|
|
||||||
virtual ~abstract_parser() {}
|
|
||||||
|
|
||||||
virtual typename match_result<ScannerT, AttrT>::type
|
|
||||||
do_parse_virtual(ScannerT const& scan) const = 0;
|
|
||||||
|
|
||||||
virtual abstract_parser*
|
|
||||||
clone() const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// concrete_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ParserT, typename ScannerT, typename AttrT>
|
|
||||||
struct concrete_parser : abstract_parser<ScannerT, AttrT>
|
|
||||||
{
|
|
||||||
concrete_parser(ParserT const& p) : p(p) {}
|
|
||||||
virtual ~concrete_parser() {}
|
|
||||||
|
|
||||||
virtual typename match_result<ScannerT, AttrT>::type
|
|
||||||
do_parse_virtual(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
return p.parse(scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual abstract_parser<ScannerT, AttrT>*
|
|
||||||
clone() const
|
|
||||||
{
|
|
||||||
return new concrete_parser(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
typename ParserT::embed_t p;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// This generates partial specializations for the class
|
|
||||||
//
|
|
||||||
// abstract_parser
|
|
||||||
//
|
|
||||||
// with an increasing number of different ScannerT template parameters
|
|
||||||
// and corresponding do_parse_virtual function declarations for each
|
|
||||||
// of the different required scanner types:
|
|
||||||
//
|
|
||||||
// template <typename ScannerT0, ..., typename AttrT>
|
|
||||||
// struct abstract_parser<scanner_list<ScannerT0, ...>, AttrT>
|
|
||||||
// {
|
|
||||||
// abstract_parser() {}
|
|
||||||
// virtual ~abstract_parser() {}
|
|
||||||
//
|
|
||||||
// virtual typename match_result<ScannerT0, AttrT>::type
|
|
||||||
// do_parse_virtual(ScannerT0 const &scan) const = 0;
|
|
||||||
//
|
|
||||||
// virtual abstract_parser*
|
|
||||||
// clone() const = 0;
|
|
||||||
//
|
|
||||||
// ...
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
#define BOOST_SPIRIT_RULE_ENUM_DOPARSE_A(z, N, _) \
|
|
||||||
virtual typename match_result< \
|
|
||||||
BOOST_PP_CAT(ScannerT, N), AttrT \
|
|
||||||
>::type \
|
|
||||||
do_parse_virtual( \
|
|
||||||
BOOST_PP_CAT(ScannerT, N) const& scan) const = 0; \
|
|
||||||
|
|
||||||
#define BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS(z, N, _) \
|
|
||||||
template < \
|
|
||||||
BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename ScannerT), \
|
|
||||||
typename AttrT \
|
|
||||||
> \
|
|
||||||
struct abstract_parser< \
|
|
||||||
scanner_list< \
|
|
||||||
BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \
|
|
||||||
>, \
|
|
||||||
AttrT \
|
|
||||||
> \
|
|
||||||
{ \
|
|
||||||
abstract_parser() {} \
|
|
||||||
virtual ~abstract_parser() {} \
|
|
||||||
\
|
|
||||||
BOOST_PP_REPEAT_ ## z( \
|
|
||||||
BOOST_PP_INC(N), BOOST_SPIRIT_RULE_ENUM_DOPARSE_A, _) \
|
|
||||||
\
|
|
||||||
virtual abstract_parser* \
|
|
||||||
clone() const = 0; \
|
|
||||||
}; \
|
|
||||||
|
|
||||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT,
|
|
||||||
BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS, _)
|
|
||||||
|
|
||||||
#undef BOOST_SPIRIT_RULE_ENUM_DOPARSE_A
|
|
||||||
#undef BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// This generates partial specializations for the class
|
|
||||||
//
|
|
||||||
// concrete_parser
|
|
||||||
//
|
|
||||||
// with an increasing number of different ScannerT template parameters
|
|
||||||
// and corresponding do_parse_virtual function declarations for each
|
|
||||||
// of the different required scanner types:
|
|
||||||
//
|
|
||||||
// template <
|
|
||||||
// typename ParserT, typename ScannerT0, ..., typename AttrT
|
|
||||||
// >
|
|
||||||
// struct concrete_parser<
|
|
||||||
// ParserT, scanner_list<ScannerT0, ...>, AttrT
|
|
||||||
// >
|
|
||||||
// : public abstract_parser<scanner_list<ScannerT0, ...>, AttrT>
|
|
||||||
// {
|
|
||||||
// concrete_parser(ParserT const& p_) : p(p_) {}
|
|
||||||
// virtual ~concrete_parser() {}
|
|
||||||
//
|
|
||||||
// virtual typename match_result<ScannerT0, AttrT>::type
|
|
||||||
// do_parse_virtual(ScannerT0 const &scan) const
|
|
||||||
// { return p.parse(scan); }
|
|
||||||
//
|
|
||||||
// virtual abstract_parser<scanner_list<ScannerT0, ...>, AttrT>*
|
|
||||||
// clone() const
|
|
||||||
// {
|
|
||||||
// return new concrete_parser(p);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ...
|
|
||||||
//
|
|
||||||
// typename ParserT::embed_t p;
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
#define BOOST_SPIRIT_RULE_ENUM_DOPARSE_C(z, N, _) \
|
|
||||||
virtual typename match_result< \
|
|
||||||
BOOST_PP_CAT(ScannerT, N), AttrT \
|
|
||||||
>::type \
|
|
||||||
do_parse_virtual( \
|
|
||||||
BOOST_PP_CAT(ScannerT, N) const& scan) const \
|
|
||||||
{ return p.parse(scan); } \
|
|
||||||
|
|
||||||
#define BOOST_SPIRIT_ENUM_CONCRETE_PARSERS(z, N, _) \
|
|
||||||
template < \
|
|
||||||
typename ParserT, \
|
|
||||||
BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename ScannerT), \
|
|
||||||
typename AttrT \
|
|
||||||
> \
|
|
||||||
struct concrete_parser< \
|
|
||||||
ParserT, \
|
|
||||||
scanner_list< \
|
|
||||||
BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \
|
|
||||||
>, \
|
|
||||||
AttrT \
|
|
||||||
> \
|
|
||||||
: abstract_parser< \
|
|
||||||
scanner_list< \
|
|
||||||
BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \
|
|
||||||
>, \
|
|
||||||
AttrT \
|
|
||||||
> \
|
|
||||||
{ \
|
|
||||||
concrete_parser(ParserT const& p_) : p(p_) {} \
|
|
||||||
virtual ~concrete_parser() {} \
|
|
||||||
\
|
|
||||||
BOOST_PP_REPEAT_ ## z( \
|
|
||||||
BOOST_PP_INC(N), BOOST_SPIRIT_RULE_ENUM_DOPARSE_C, _) \
|
|
||||||
\
|
|
||||||
virtual abstract_parser< \
|
|
||||||
scanner_list< \
|
|
||||||
BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \
|
|
||||||
>, \
|
|
||||||
AttrT \
|
|
||||||
>* \
|
|
||||||
clone() const \
|
|
||||||
{ \
|
|
||||||
return new concrete_parser(p); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
typename ParserT::embed_t p; \
|
|
||||||
}; \
|
|
||||||
|
|
||||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT,
|
|
||||||
BOOST_SPIRIT_ENUM_CONCRETE_PARSERS, _)
|
|
||||||
|
|
||||||
#undef BOOST_SPIRIT_ENUM_CONCRETE_PARSERS
|
|
||||||
#undef BOOST_SPIRIT_RULE_ENUM_DOPARSE_C
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#endif // BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
|
|
||||||
|
|
||||||
} // namespace impl
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,205 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2002-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_SUBRULE_IPP)
|
|
||||||
#define BOOST_SPIRIT_SUBRULE_IPP
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
template <typename FirstT, typename RestT>
|
|
||||||
struct subrule_list;
|
|
||||||
|
|
||||||
template <int ID, typename DefT, typename ContextT>
|
|
||||||
struct subrule_parser;
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
|
||||||
|
|
||||||
template <int N, typename ListT>
|
|
||||||
struct get_subrule;
|
|
||||||
|
|
||||||
template <int N, typename ListT>
|
|
||||||
struct get_subrule_chooser
|
|
||||||
{
|
|
||||||
static ListT t();
|
|
||||||
static char test(nil_t);
|
|
||||||
static int test(...);
|
|
||||||
|
|
||||||
// Set value to
|
|
||||||
// 0: ListT is empty
|
|
||||||
// 1: ListT's first item has same ID
|
|
||||||
// 2: ListT's first item has a different ID
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
id = ListT::first_t::id,
|
|
||||||
is_same_id = N == id,
|
|
||||||
is_nil_t = sizeof(char) == sizeof(test(t())),
|
|
||||||
value = is_nil_t ? 0 : (is_same_id ? 1 : 2)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <int N>
|
|
||||||
struct subrule_chooser;
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct subrule_chooser<0>
|
|
||||||
{
|
|
||||||
// First case. ListT is empty
|
|
||||||
|
|
||||||
template <int N, typename ListT>
|
|
||||||
struct result
|
|
||||||
{ typedef nil_t type; };
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct subrule_chooser<1>
|
|
||||||
{
|
|
||||||
// Second case. ListT is non-empty and the list's
|
|
||||||
// first item has the ID we are looking for.
|
|
||||||
|
|
||||||
template <int N, typename ListT>
|
|
||||||
struct result
|
|
||||||
{ typedef typename ListT::first_t::def_t type; };
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct subrule_chooser<2>
|
|
||||||
{
|
|
||||||
// Third case. ListT is non-empty but the list's
|
|
||||||
// first item does not have the ID we are looking for.
|
|
||||||
|
|
||||||
template <int N, typename ListT>
|
|
||||||
struct result
|
|
||||||
{ typedef typename get_subrule<N, ListT::rest_t>::type type; };
|
|
||||||
};
|
|
||||||
|
|
||||||
template <int N, typename ListT>
|
|
||||||
struct get_subrule
|
|
||||||
{
|
|
||||||
enum { n = get_subrule_chooser<N, ListT>::value };
|
|
||||||
typedef typename subrule_chooser<n>::template
|
|
||||||
result<N, ListT>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
template <int N, typename ListT>
|
|
||||||
struct get_subrule
|
|
||||||
{
|
|
||||||
// First case. ListT is non-empty but the list's
|
|
||||||
// first item does not have the ID we are looking for.
|
|
||||||
|
|
||||||
typedef typename get_subrule<N, typename ListT::rest_t>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <int ID, typename DefT, typename ContextT, typename RestT>
|
|
||||||
struct get_subrule<
|
|
||||||
ID,
|
|
||||||
subrule_list<
|
|
||||||
subrule_parser<ID, DefT, ContextT>,
|
|
||||||
RestT> >
|
|
||||||
{
|
|
||||||
// Second case. ListT is non-empty and the list's
|
|
||||||
// first item has the ID we are looking for.
|
|
||||||
|
|
||||||
typedef DefT type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <int ID>
|
|
||||||
struct get_subrule<ID, nil_t>
|
|
||||||
{
|
|
||||||
// Third case. ListT is empty
|
|
||||||
typedef nil_t type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
|
||||||
struct get_result_t {
|
|
||||||
|
|
||||||
// If the result type dictated by the context is nil_t (no closures
|
|
||||||
// present), then the whole subrule_parser return type is equal to
|
|
||||||
// the return type of the right hand side of this subrule_parser,
|
|
||||||
// otherwise it is equal to the dictated return value.
|
|
||||||
|
|
||||||
typedef typename mpl::if_<
|
|
||||||
boost::is_same<T1, nil_t>, T2, T1
|
|
||||||
>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <int ID, typename ScannerT, typename ContextResultT>
|
|
||||||
struct get_subrule_result
|
|
||||||
{
|
|
||||||
typedef typename
|
|
||||||
impl::get_subrule<ID, typename ScannerT::list_t>::type
|
|
||||||
parser_t;
|
|
||||||
|
|
||||||
typedef typename parser_result<parser_t, ScannerT>::type
|
|
||||||
def_result_t;
|
|
||||||
|
|
||||||
typedef typename match_result<ScannerT, ContextResultT>::type
|
|
||||||
context_result_t;
|
|
||||||
|
|
||||||
typedef typename get_result_t<context_result_t, def_result_t>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename DefT, typename ScannerT, typename ContextResultT>
|
|
||||||
struct get_subrule_parser_result
|
|
||||||
{
|
|
||||||
typedef typename parser_result<DefT, ScannerT>::type
|
|
||||||
def_result_t;
|
|
||||||
|
|
||||||
typedef typename match_result<ScannerT, ContextResultT>::type
|
|
||||||
context_result_t;
|
|
||||||
|
|
||||||
typedef typename get_result_t<context_result_t, def_result_t>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename SubruleT, int ID>
|
|
||||||
struct same_subrule_id
|
|
||||||
{
|
|
||||||
BOOST_STATIC_CONSTANT(bool, value = (SubruleT::id == ID));
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename RT, typename ScannerT, int ID>
|
|
||||||
struct parse_subrule
|
|
||||||
{
|
|
||||||
template <typename ListT>
|
|
||||||
static void
|
|
||||||
do_parse(RT& r, ScannerT const& scan, ListT const& list, mpl::true_)
|
|
||||||
{
|
|
||||||
r = list.first.rhs.parse(scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ListT>
|
|
||||||
static void
|
|
||||||
do_parse(RT& r, ScannerT const& scan, ListT const& list, mpl::false_)
|
|
||||||
{
|
|
||||||
typedef typename ListT::rest_t::first_t subrule_t;
|
|
||||||
mpl::bool_<same_subrule_id<subrule_t, ID>::value> same_id;
|
|
||||||
do_parse(r, scan, list.rest, same_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
do_(RT& r, ScannerT const& scan)
|
|
||||||
{
|
|
||||||
typedef typename ScannerT::list_t::first_t subrule_t;
|
|
||||||
mpl::bool_<same_subrule_id<subrule_t, ID>::value> same_id;
|
|
||||||
do_parse(r, scan, scan.list, same_id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}}} // namespace boost::spirit::impl
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,147 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2002-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_PARSER_CONTEXT_HPP)
|
|
||||||
#define BOOST_SPIRIT_PARSER_CONTEXT_HPP
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
namespace spirit
|
|
||||||
{
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// default_parser_context_base class { default context base }
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct default_parser_context_base
|
|
||||||
{
|
|
||||||
template <typename DerivedT>
|
|
||||||
struct aux {};
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// parser_context_base class { base class of all context classes }
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct parser_context_base {};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// parser_context class { default context }
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct nil_t;
|
|
||||||
template<typename ContextT> struct parser_context_linker;
|
|
||||||
|
|
||||||
template<typename AttrT = nil_t>
|
|
||||||
struct parser_context : parser_context_base
|
|
||||||
{
|
|
||||||
typedef AttrT attr_t;
|
|
||||||
typedef default_parser_context_base base_t;
|
|
||||||
typedef parser_context_linker<parser_context<AttrT> > context_linker_t;
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
parser_context(ParserT const&) {}
|
|
||||||
|
|
||||||
template <typename ParserT, typename ScannerT>
|
|
||||||
void
|
|
||||||
pre_parse(ParserT const&, ScannerT const&) {}
|
|
||||||
|
|
||||||
template <typename ResultT, typename ParserT, typename ScannerT>
|
|
||||||
ResultT&
|
|
||||||
post_parse(ResultT& hit, ParserT const&, ScannerT const&)
|
|
||||||
{ return hit; }
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// context_aux class
|
|
||||||
//
|
|
||||||
// context_aux<ContextT, DerivedT> is a class derived from the
|
|
||||||
// ContextT's nested base_t::base<DerivedT> template class. (see
|
|
||||||
// default_parser_context_base::aux for an example).
|
|
||||||
//
|
|
||||||
// Basically, this class provides ContextT dependent optional
|
|
||||||
// functionality to the derived class DerivedT through the CRTP
|
|
||||||
// idiom (Curiously recurring template pattern).
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ContextT, typename DerivedT>
|
|
||||||
struct context_aux : public ContextT::base_t::template aux<DerivedT> {};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// parser_scanner_linker and parser_scanner_linker classes
|
|
||||||
// { helper templates for the rule extensibility }
|
|
||||||
//
|
|
||||||
// This classes can be 'overloaded' (defined elsewhere), to plug
|
|
||||||
// in additional functionality into the non-terminal parsing process.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
#if !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED)
|
|
||||||
#define BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED
|
|
||||||
|
|
||||||
template<typename ScannerT>
|
|
||||||
struct parser_scanner_linker : public ScannerT
|
|
||||||
{
|
|
||||||
parser_scanner_linker(ScannerT const scan_) : ScannerT(scan_) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED)
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
#if !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED)
|
|
||||||
#define BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED
|
|
||||||
|
|
||||||
template<typename ContextT>
|
|
||||||
struct parser_context_linker : public ContextT
|
|
||||||
{
|
|
||||||
template <typename ParserT>
|
|
||||||
parser_context_linker(ParserT const& p)
|
|
||||||
: ContextT(p) {}
|
|
||||||
|
|
||||||
template <typename ParserT, typename ScannerT>
|
|
||||||
void pre_parse(ParserT const& p, ScannerT const& scan)
|
|
||||||
{ ContextT::pre_parse(p, scan); }
|
|
||||||
|
|
||||||
template <typename ResultT, typename ParserT, typename ScannerT>
|
|
||||||
ResultT&
|
|
||||||
post_parse(ResultT& hit, ParserT const& p, ScannerT const& scan)
|
|
||||||
{ return ContextT::post_parse(hit, p, scan); }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED)
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// BOOST_SPIRIT_CONTEXT_PARSE helper macro
|
|
||||||
//
|
|
||||||
// The original implementation uses a template class. However, we
|
|
||||||
// need to lessen the template instantiation depth to help inferior
|
|
||||||
// compilers that sometimes choke on deep template instantiations.
|
|
||||||
// The objective is to avoid code redundancy. A macro, in this case
|
|
||||||
// is an obvious solution. Sigh!
|
|
||||||
//
|
|
||||||
// WARNING: INTERNAL USE ONLY. NOT FOR PUBLIC CONSUMPTION.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
#define BOOST_SPIRIT_CONTEXT_PARSE(scan, this_, scanner_t, context_t, result_t) \
|
|
||||||
scanner_t scan_wrap(scan); \
|
|
||||||
context_t context_wrap(this_); \
|
|
||||||
context_wrap.pre_parse(this_, scan_wrap); \
|
|
||||||
result_t hit = parse_main(scan); \
|
|
||||||
return context_wrap.post_parse(hit, this_, scan_wrap);
|
|
||||||
|
|
||||||
} // namespace spirit
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,118 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2001-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001 Daniel Nuffer
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_PARSER_ID_HPP)
|
|
||||||
#define BOOST_SPIRIT_PARSER_ID_HPP
|
|
||||||
|
|
||||||
#if defined(BOOST_SPIRIT_DEBUG)
|
|
||||||
# include <ostream>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// parser_id class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
class parser_id
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
parser_id() : p(0) {}
|
|
||||||
explicit parser_id(void const* prule) : p(prule) {}
|
|
||||||
parser_id(std::size_t l_) : l(l_) {}
|
|
||||||
|
|
||||||
bool operator==(parser_id const& x) const { return p == x.p; }
|
|
||||||
bool operator!=(parser_id const& x) const { return !(*this == x); }
|
|
||||||
bool operator<(parser_id const& x) const { return p < x.p; }
|
|
||||||
std::size_t to_long() const { return l; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
union
|
|
||||||
{
|
|
||||||
void const* p;
|
|
||||||
std::size_t l;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(BOOST_SPIRIT_DEBUG)
|
|
||||||
inline std::ostream&
|
|
||||||
operator<<(std::ostream& out, parser_id const& rid)
|
|
||||||
{
|
|
||||||
out << rid.to_long();
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// parser_tag_base class: base class of all parser tags
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct parser_tag_base {};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// parser_address_tag class: tags a parser with its address
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct parser_address_tag : parser_tag_base
|
|
||||||
{
|
|
||||||
parser_id id() const
|
|
||||||
{ return parser_id(reinterpret_cast<std::size_t>(this)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// parser_tag class: tags a parser with an integer ID
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <int N>
|
|
||||||
struct parser_tag : parser_tag_base
|
|
||||||
{
|
|
||||||
static parser_id id()
|
|
||||||
{ return parser_id(std::size_t(N)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// dynamic_parser_tag class: tags a parser with a dynamically changeable
|
|
||||||
// integer ID
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
class dynamic_parser_tag : public parser_tag_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
dynamic_parser_tag()
|
|
||||||
: tag(std::size_t(0)) {}
|
|
||||||
|
|
||||||
parser_id
|
|
||||||
id() const
|
|
||||||
{
|
|
||||||
return
|
|
||||||
tag.to_long()
|
|
||||||
? tag
|
|
||||||
: parser_id(reinterpret_cast<std::size_t>(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_id(parser_id id) { tag = id; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
parser_id tag;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,168 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_RULE_HPP)
|
|
||||||
#define BOOST_SPIRIT_RULE_HPP
|
|
||||||
|
|
||||||
#include <boost/static_assert.hpp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Spirit predefined maximum number of simultaneously usable different
|
|
||||||
// scanner types.
|
|
||||||
//
|
|
||||||
// This limit defines the maximum number of of possible different scanner
|
|
||||||
// types for which a specific rule<> may be used. If this isn't defined, a
|
|
||||||
// rule<> may be used with one scanner type only (multiple scanner support
|
|
||||||
// is disabled).
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#if !defined(BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT)
|
|
||||||
# define BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Ensure a meaningful maximum number of simultaneously usable scanner types
|
|
||||||
BOOST_STATIC_ASSERT(BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 0);
|
|
||||||
|
|
||||||
#include <boost/scoped_ptr.hpp>
|
|
||||||
#include <boost/spirit/core/non_terminal/impl/rule.ipp>
|
|
||||||
|
|
||||||
#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
|
|
||||||
# include <boost/preprocessor/enum_params.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// scanner_list (a fake scanner)
|
|
||||||
//
|
|
||||||
// Typically, rules are tied to a specific scanner type and
|
|
||||||
// a particular rule cannot be used with anything else. Sometimes
|
|
||||||
// there's a need for rules that can accept more than one scanner
|
|
||||||
// type. The scanner_list<S0, ...SN> can be used as a template
|
|
||||||
// parameter to the rule class to specify up to the number of
|
|
||||||
// scanner types defined by the BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT
|
|
||||||
// constant. Example:
|
|
||||||
//
|
|
||||||
// rule<scanner_list<ScannerT0, ScannerT1> > r;
|
|
||||||
//
|
|
||||||
// *** This feature is available only to compilers that support
|
|
||||||
// partial template specialization. ***
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <
|
|
||||||
BOOST_PP_ENUM_PARAMS(
|
|
||||||
BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT,
|
|
||||||
typename ScannerT
|
|
||||||
)
|
|
||||||
>
|
|
||||||
struct scanner_list : scanner_base {};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// rule class
|
|
||||||
//
|
|
||||||
// The rule is a polymorphic parser that acts as a named place-
|
|
||||||
// holder capturing the behavior of an EBNF expression assigned to
|
|
||||||
// it.
|
|
||||||
//
|
|
||||||
// The rule is a template class parameterized by:
|
|
||||||
//
|
|
||||||
// 1) scanner (scanner_t, see scanner.hpp),
|
|
||||||
// 2) the rule's context (context_t, see parser_context.hpp)
|
|
||||||
// 3) an arbitrary tag (tag_t, see parser_id.hpp) that allows
|
|
||||||
// a rule to be tagged for identification.
|
|
||||||
//
|
|
||||||
// These template parameters may be specified in any order. The
|
|
||||||
// scanner will default to scanner<> when it is not specified.
|
|
||||||
// The context will default to parser_context when not specified.
|
|
||||||
// The tag will default to parser_address_tag when not specified.
|
|
||||||
//
|
|
||||||
// The definition of the rule (its right hand side, RHS) held by
|
|
||||||
// the rule through a scoped_ptr. When a rule is seen in the RHS
|
|
||||||
// of an assignment or copy construction EBNF expression, the rule
|
|
||||||
// is held by the LHS rule by reference.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <
|
|
||||||
typename T0 = nil_t
|
|
||||||
, typename T1 = nil_t
|
|
||||||
, typename T2 = nil_t
|
|
||||||
>
|
|
||||||
class rule
|
|
||||||
: public impl::rule_base<
|
|
||||||
rule<T0, T1, T2>
|
|
||||||
, rule<T0, T1, T2> const&
|
|
||||||
, T0, T1, T2>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef rule<T0, T1, T2> self_t;
|
|
||||||
typedef impl::rule_base<
|
|
||||||
self_t
|
|
||||||
, self_t const&
|
|
||||||
, T0, T1, T2>
|
|
||||||
base_t;
|
|
||||||
|
|
||||||
typedef typename base_t::scanner_t scanner_t;
|
|
||||||
typedef typename base_t::attr_t attr_t;
|
|
||||||
typedef impl::abstract_parser<scanner_t, attr_t> abstract_parser_t;
|
|
||||||
|
|
||||||
rule() : ptr() {}
|
|
||||||
~rule() {}
|
|
||||||
|
|
||||||
rule(rule const& r)
|
|
||||||
: ptr(new impl::concrete_parser<rule, scanner_t, attr_t>(r)) {}
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
rule(ParserT const& p)
|
|
||||||
: ptr(new impl::concrete_parser<ParserT, scanner_t, attr_t>(p)) {}
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
rule& operator=(ParserT const& p)
|
|
||||||
{
|
|
||||||
ptr.reset(new impl::concrete_parser<ParserT, scanner_t, attr_t>(p));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
rule& operator=(rule const& r)
|
|
||||||
{
|
|
||||||
ptr.reset(new impl::concrete_parser<rule, scanner_t, attr_t>(r));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
rule<T0, T1, T2>
|
|
||||||
copy() const
|
|
||||||
{
|
|
||||||
return rule<T0, T1, T2>(ptr.get() ? ptr->clone() : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class impl::rule_base_access;
|
|
||||||
|
|
||||||
abstract_parser_t*
|
|
||||||
get() const
|
|
||||||
{
|
|
||||||
return ptr.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
rule(abstract_parser_t const* ptr)
|
|
||||||
: ptr(ptr) {}
|
|
||||||
|
|
||||||
scoped_ptr<abstract_parser_t> ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,296 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2002-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_SUBRULE_HPP)
|
|
||||||
#define BOOST_SPIRIT_SUBRULE_HPP
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <boost/static_assert.hpp>
|
|
||||||
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/non_terminal/parser_context.hpp>
|
|
||||||
|
|
||||||
#include <boost/spirit/core/non_terminal/subrule_fwd.hpp>
|
|
||||||
#include <boost/spirit/core/non_terminal/impl/subrule.ipp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// subrules_scanner class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ScannerT, typename ListT>
|
|
||||||
struct subrules_scanner : public ScannerT
|
|
||||||
{
|
|
||||||
typedef ScannerT scanner_t;
|
|
||||||
typedef ListT list_t;
|
|
||||||
typedef subrules_scanner<ScannerT, ListT> self_t;
|
|
||||||
|
|
||||||
subrules_scanner(ScannerT const& scan, ListT const& list_)
|
|
||||||
: ScannerT(scan), list(list_) {}
|
|
||||||
|
|
||||||
template <typename PoliciesT>
|
|
||||||
struct rebind_policies
|
|
||||||
{
|
|
||||||
typedef typename rebind_scanner_policies<ScannerT, PoliciesT>::type
|
|
||||||
rebind_scanner;
|
|
||||||
typedef subrules_scanner<rebind_scanner, ListT> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename PoliciesT>
|
|
||||||
subrules_scanner<
|
|
||||||
typename rebind_scanner_policies<ScannerT, PoliciesT>::type,
|
|
||||||
ListT>
|
|
||||||
change_policies(PoliciesT const& policies) const
|
|
||||||
{
|
|
||||||
typedef subrules_scanner<
|
|
||||||
BOOST_DEDUCED_TYPENAME
|
|
||||||
rebind_scanner_policies<ScannerT, PoliciesT>::type,
|
|
||||||
ListT>
|
|
||||||
subrules_scanner_t;
|
|
||||||
|
|
||||||
return subrules_scanner_t(
|
|
||||||
ScannerT::change_policies(policies),
|
|
||||||
list);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename IteratorT>
|
|
||||||
struct rebind_iterator
|
|
||||||
{
|
|
||||||
typedef typename rebind_scanner_iterator<ScannerT, IteratorT>::type
|
|
||||||
rebind_scanner;
|
|
||||||
typedef subrules_scanner<rebind_scanner, ListT> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename IteratorT>
|
|
||||||
subrules_scanner<
|
|
||||||
typename rebind_scanner_iterator<ScannerT, IteratorT>::type,
|
|
||||||
ListT>
|
|
||||||
change_iterator(IteratorT const& first, IteratorT const &last) const
|
|
||||||
{
|
|
||||||
typedef subrules_scanner<
|
|
||||||
BOOST_DEDUCED_TYPENAME
|
|
||||||
rebind_scanner_iterator<ScannerT, IteratorT>::type,
|
|
||||||
ListT>
|
|
||||||
subrules_scanner_t;
|
|
||||||
|
|
||||||
return subrules_scanner_t(
|
|
||||||
ScannerT::change_iterator(first, last),
|
|
||||||
list);
|
|
||||||
}
|
|
||||||
|
|
||||||
ListT const& list;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// subrule_scanner type computer class
|
|
||||||
//
|
|
||||||
// This computer ensures that the scanner will not be recursively
|
|
||||||
// instantiated if it's not needed.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ScannerT, typename ListT>
|
|
||||||
struct subrules_scanner_finder
|
|
||||||
{
|
|
||||||
typedef subrules_scanner<ScannerT, ListT> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ScannerT, typename ListT>
|
|
||||||
struct subrules_scanner_finder<subrules_scanner<ScannerT, ListT>, ListT>
|
|
||||||
{
|
|
||||||
typedef subrules_scanner<ScannerT, ListT> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// subrule_list class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename FirstT, typename RestT>
|
|
||||||
struct subrule_list : public parser<subrule_list<FirstT, RestT> >
|
|
||||||
{
|
|
||||||
typedef subrule_list<FirstT, RestT> self_t;
|
|
||||||
typedef FirstT first_t;
|
|
||||||
typedef RestT rest_t;
|
|
||||||
|
|
||||||
subrule_list(FirstT const& first_, RestT const& rest_)
|
|
||||||
: first(first_), rest(rest_) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename parser_result<FirstT, ScannerT>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename subrules_scanner_finder<ScannerT, self_t>::type
|
|
||||||
subrules_scanner_t;
|
|
||||||
subrules_scanner_t g_arg(scan, *this);
|
|
||||||
return first.start.parse(g_arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <int ID, typename DefT, typename ContextT>
|
|
||||||
subrule_list<
|
|
||||||
FirstT,
|
|
||||||
subrule_list<
|
|
||||||
subrule_parser<ID, DefT, ContextT>,
|
|
||||||
RestT> >
|
|
||||||
operator,(subrule_parser<ID, DefT, ContextT> const& rhs)
|
|
||||||
{
|
|
||||||
return subrule_list<
|
|
||||||
FirstT,
|
|
||||||
subrule_list<
|
|
||||||
subrule_parser<ID, DefT, ContextT>,
|
|
||||||
RestT> >(
|
|
||||||
first,
|
|
||||||
subrule_list<
|
|
||||||
subrule_parser<ID, DefT, ContextT>,
|
|
||||||
RestT>(rhs, rest));
|
|
||||||
}
|
|
||||||
|
|
||||||
FirstT first;
|
|
||||||
RestT rest;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// subrule_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <int ID, typename DefT, typename ContextT>
|
|
||||||
struct subrule_parser
|
|
||||||
: public parser<subrule_parser<ID, DefT, ContextT> >
|
|
||||||
{
|
|
||||||
typedef subrule_parser<ID, DefT, ContextT> self_t;
|
|
||||||
typedef subrule<ID, ContextT> subrule_t;
|
|
||||||
typedef DefT def_t;
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(int, id = ID);
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename
|
|
||||||
impl::get_subrule_parser_result<
|
|
||||||
DefT, ScannerT, typename subrule_t::attr_t>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
subrule_parser(subrule_t const& start_, DefT const& rhs_)
|
|
||||||
: rhs(rhs_), start(start_) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
// This will only be called when parsing single subrules.
|
|
||||||
typedef subrule_list<self_t, nil_t> list_t;
|
|
||||||
typedef subrules_scanner<ScannerT, list_t> scanner_t;
|
|
||||||
|
|
||||||
list_t list(*this, nil_t());
|
|
||||||
scanner_t g_arg(scan, list);
|
|
||||||
return start.parse(g_arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <int ID2, typename DefT2, typename ContextT2>
|
|
||||||
inline subrule_list<
|
|
||||||
self_t,
|
|
||||||
subrule_list<
|
|
||||||
subrule_parser<ID2, DefT2, ContextT2>,
|
|
||||||
nil_t> >
|
|
||||||
operator,(subrule_parser<ID2, DefT2, ContextT2> const& rhs) const
|
|
||||||
{
|
|
||||||
return subrule_list<
|
|
||||||
self_t,
|
|
||||||
subrule_list<
|
|
||||||
subrule_parser<ID2, DefT2, ContextT2>,
|
|
||||||
nil_t> >(
|
|
||||||
*this,
|
|
||||||
subrule_list<
|
|
||||||
subrule_parser<ID2, DefT2, ContextT2>, nil_t>(
|
|
||||||
rhs, nil_t()));
|
|
||||||
}
|
|
||||||
|
|
||||||
typename DefT::embed_t rhs;
|
|
||||||
subrule_t const& start;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// subrule class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <int ID, typename ContextT>
|
|
||||||
struct subrule
|
|
||||||
: public parser<subrule<ID, ContextT> >
|
|
||||||
, public ContextT::base_t
|
|
||||||
, public context_aux<ContextT, subrule<ID, ContextT> >
|
|
||||||
{
|
|
||||||
typedef subrule<ID, ContextT> self_t;
|
|
||||||
typedef subrule<ID, ContextT> const& embed_t;
|
|
||||||
|
|
||||||
typedef typename ContextT::context_linker_t context_t;
|
|
||||||
typedef typename context_t::attr_t attr_t;
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(int, id = ID);
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename
|
|
||||||
impl::get_subrule_result<ID, ScannerT, attr_t>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse_main(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
result_t result;
|
|
||||||
impl::parse_subrule<result_t, ScannerT, ID>::
|
|
||||||
do_(result, scan);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
typedef parser_scanner_linker<ScannerT> scanner_t;
|
|
||||||
BOOST_SPIRIT_CONTEXT_PARSE(
|
|
||||||
scan, *this, scanner_t, context_t, result_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename DefT>
|
|
||||||
subrule_parser<ID, DefT, ContextT>
|
|
||||||
operator=(parser<DefT> const& rhs) const
|
|
||||||
{
|
|
||||||
return subrule_parser<ID, DefT, ContextT>(*this, rhs.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// assignment of subrules is not allowed. Use subrules
|
|
||||||
// with identical IDs if you want to have aliases.
|
|
||||||
|
|
||||||
subrule& operator=(subrule const&);
|
|
||||||
|
|
||||||
template <int ID2, typename ContextT2>
|
|
||||||
subrule& operator=(subrule<ID2, ContextT2> const&);
|
|
||||||
};
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,219 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_PARSER_HPP)
|
|
||||||
#define BOOST_SPIRIT_PARSER_HPP
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <boost/type_traits.hpp>
|
|
||||||
#include <boost/spirit/core/scanner/scanner.hpp>
|
|
||||||
#include <boost/spirit/core/nil.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit
|
|
||||||
{
|
|
||||||
template <typename ParserT, typename ActionT>
|
|
||||||
class action; // forward declaration
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Parser categories
|
|
||||||
//
|
|
||||||
// Helper template classes to distinguish different types of
|
|
||||||
// parsers. The following categories are the most generic. More
|
|
||||||
// specific types may inherit from these. Each parser has a typedef
|
|
||||||
// parser_category_t that defines its category. By default, if one
|
|
||||||
// is not specified, it will inherit from the base parser class
|
|
||||||
// which typedefs its parser_category_t as plain_parser_category.
|
|
||||||
//
|
|
||||||
// - plain parser has nothing special
|
|
||||||
// - binary parser has subject a and b (e.g. alternative)
|
|
||||||
// - unary parser has single subject (e.g. kleene star)
|
|
||||||
// - action parser has an attached action parser
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct plain_parser_category {};
|
|
||||||
struct binary_parser_category : plain_parser_category {};
|
|
||||||
struct unary_parser_category : plain_parser_category {};
|
|
||||||
struct action_parser_category : unary_parser_category {};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// parser_result metafunction
|
|
||||||
//
|
|
||||||
// Given a scanner type ScannerT and a parser type ParserT, the
|
|
||||||
// parser_result metafunction provides the actual result of the
|
|
||||||
// parser.
|
|
||||||
//
|
|
||||||
// Usage:
|
|
||||||
//
|
|
||||||
// typename parser_result<ParserT, ScannerT>::type
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ParserT, typename ScannerT>
|
|
||||||
struct parser_result
|
|
||||||
{
|
|
||||||
typedef typename boost::remove_reference<ParserT>::type parser_type;
|
|
||||||
typedef typename parser_type::template result<ScannerT>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// parser class
|
|
||||||
//
|
|
||||||
// This class is a protocol base class for all parsers. This is
|
|
||||||
// essentially an interface contract. The parser class does not
|
|
||||||
// really know how to parse anything but instead relies on the
|
|
||||||
// template parameter DerivedT (which obviously is assumed to be a
|
|
||||||
// subclass) to do the actual parsing.
|
|
||||||
//
|
|
||||||
// Concrete sub-classes inheriting from parser must have a
|
|
||||||
// corresponding member function parse(...) compatible with the
|
|
||||||
// conceptual Interface:
|
|
||||||
//
|
|
||||||
// template <typename ScannerT>
|
|
||||||
// RT parse(ScannerT const& scan) const;
|
|
||||||
//
|
|
||||||
// where RT is the desired return type of the parser and ScannerT
|
|
||||||
// scan is the scanner (see scanner.hpp).
|
|
||||||
//
|
|
||||||
// Concrete sub-classes inheriting from parser in most cases need to
|
|
||||||
// have a nested meta-function result that returns the result type
|
|
||||||
// of the parser's parse member function, given a scanner type. The
|
|
||||||
// meta-function has the form:
|
|
||||||
//
|
|
||||||
// template <typename ScannerT>
|
|
||||||
// struct result
|
|
||||||
// {
|
|
||||||
// typedef RT type;
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// where RT is the desired return type of the parser. This is
|
|
||||||
// usually, but not always, dependent on the template parameter
|
|
||||||
// ScannerT. If a parser does not supply a result metafunction, a
|
|
||||||
// default is provided by the base parser class.
|
|
||||||
//
|
|
||||||
// The parser's derived() member function returns a reference to the
|
|
||||||
// parser as its derived object.
|
|
||||||
//
|
|
||||||
// An operator[] is provided. The operator returns a semantic action
|
|
||||||
// handler (see actions.hpp).
|
|
||||||
//
|
|
||||||
// Each parser has a typedef embed_t. This typedef specifies how a
|
|
||||||
// parser is embedded in a composite (see composite.hpp). By
|
|
||||||
// default, if one is not specified, the parser will be embedded by
|
|
||||||
// value. That is, a copy of the parser is placed as a member
|
|
||||||
// variable of the composite. Most parsers are embedded by value. In
|
|
||||||
// certain situations however, this is not desirable or possible.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename DerivedT>
|
|
||||||
struct parser
|
|
||||||
{
|
|
||||||
typedef DerivedT embed_t;
|
|
||||||
typedef DerivedT derived_t;
|
|
||||||
typedef plain_parser_category parser_category_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename match_result<ScannerT, nil_t>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
DerivedT& derived()
|
|
||||||
{
|
|
||||||
return *static_cast<DerivedT*>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
DerivedT const& derived() const
|
|
||||||
{
|
|
||||||
return *static_cast<DerivedT const*>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ActionT>
|
|
||||||
action<DerivedT, ActionT>
|
|
||||||
operator[](ActionT const& actor) const
|
|
||||||
{
|
|
||||||
return action<DerivedT, ActionT>(derived(), actor);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// parse_info
|
|
||||||
//
|
|
||||||
// Results returned by the free parse functions:
|
|
||||||
//
|
|
||||||
// stop: points to the final parse position (i.e parsing
|
|
||||||
// processed the input up to this point).
|
|
||||||
//
|
|
||||||
// hit: true if parsing is successful. This may be full:
|
|
||||||
// the parser consumed all the input, or partial:
|
|
||||||
// the parser consumed only a portion of the input.
|
|
||||||
//
|
|
||||||
// full: true when we have a full hit (i.e the parser
|
|
||||||
// consumed all the input.
|
|
||||||
//
|
|
||||||
// length: The number of characters consumed by the parser.
|
|
||||||
// This is valid only if we have a successful hit
|
|
||||||
// (either partial or full).
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename IteratorT = char const*>
|
|
||||||
struct parse_info
|
|
||||||
{
|
|
||||||
IteratorT stop;
|
|
||||||
bool hit;
|
|
||||||
bool full;
|
|
||||||
std::size_t length;
|
|
||||||
|
|
||||||
parse_info(
|
|
||||||
IteratorT const& stop_ = IteratorT(),
|
|
||||||
bool hit_ = false,
|
|
||||||
bool full_ = false,
|
|
||||||
std::size_t length_ = 0)
|
|
||||||
: stop(stop_)
|
|
||||||
, hit(hit_)
|
|
||||||
, full(full_)
|
|
||||||
, length(length_) {}
|
|
||||||
|
|
||||||
template <typename ParseInfoT>
|
|
||||||
parse_info(ParseInfoT const& pi)
|
|
||||||
: stop(pi.stop)
|
|
||||||
, hit(pi.hit)
|
|
||||||
, full(pi.full)
|
|
||||||
, length(pi.length) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generic parse function
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename IteratorT, typename DerivedT>
|
|
||||||
parse_info<IteratorT>
|
|
||||||
parse(
|
|
||||||
IteratorT const& first,
|
|
||||||
IteratorT const& last,
|
|
||||||
parser<DerivedT> const& p);
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Parse function for null terminated strings
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename CharT, typename DerivedT>
|
|
||||||
parse_info<CharT const*>
|
|
||||||
parse(
|
|
||||||
CharT const* str,
|
|
||||||
parser<DerivedT> const& p);
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/spirit/core/impl/parser.ipp>
|
|
@ -1,531 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001-2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_NUMERICS_IPP
|
|
||||||
#define BOOST_SPIRIT_NUMERICS_IPP
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
|
||||||
# define BOOST_SPIRIT_IMPL_STD_NS
|
|
||||||
#else
|
|
||||||
# define BOOST_SPIRIT_IMPL_STD_NS std
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
struct sign_parser; // forward declaration only
|
|
||||||
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Extract the prefix sign (- or +)
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ScannerT>
|
|
||||||
bool
|
|
||||||
extract_sign(ScannerT const& scan, std::size_t& count)
|
|
||||||
{
|
|
||||||
// Extract the sign
|
|
||||||
count = 0;
|
|
||||||
bool neg = *scan == '-';
|
|
||||||
if (neg || (*scan == '+'))
|
|
||||||
{
|
|
||||||
++scan;
|
|
||||||
++count;
|
|
||||||
return neg;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Traits class for radix specific number conversion
|
|
||||||
//
|
|
||||||
// Test the validity of a single character:
|
|
||||||
//
|
|
||||||
// template<typename CharT> static bool is_valid(CharT ch);
|
|
||||||
//
|
|
||||||
// Convert a digit from character representation to binary
|
|
||||||
// representation:
|
|
||||||
//
|
|
||||||
// template<typename CharT> static int digit(CharT ch);
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
template<const int Radix>
|
|
||||||
struct radix_traits;
|
|
||||||
|
|
||||||
////////////////////////////////// Binary
|
|
||||||
template<>
|
|
||||||
struct radix_traits<2>
|
|
||||||
{
|
|
||||||
template<typename CharT>
|
|
||||||
static bool is_valid(CharT ch)
|
|
||||||
{
|
|
||||||
return ('0' == ch || '1' == ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename CharT>
|
|
||||||
static int digit(CharT ch)
|
|
||||||
{
|
|
||||||
return ch - '0';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////// Octal
|
|
||||||
template<>
|
|
||||||
struct radix_traits<8>
|
|
||||||
{
|
|
||||||
template<typename CharT>
|
|
||||||
static bool is_valid(CharT ch)
|
|
||||||
{
|
|
||||||
return ('0' <= ch && ch <= '7');
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename CharT>
|
|
||||||
static int digit(CharT ch)
|
|
||||||
{
|
|
||||||
return ch - '0';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////// Decimal
|
|
||||||
template<>
|
|
||||||
struct radix_traits<10>
|
|
||||||
{
|
|
||||||
template<typename CharT>
|
|
||||||
static bool is_valid(CharT ch)
|
|
||||||
{
|
|
||||||
return impl::isdigit_(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename CharT>
|
|
||||||
static int digit(CharT ch)
|
|
||||||
{
|
|
||||||
return ch - '0';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////// Hexadecimal
|
|
||||||
template<>
|
|
||||||
struct radix_traits<16>
|
|
||||||
{
|
|
||||||
template<typename CharT>
|
|
||||||
static bool is_valid(CharT ch)
|
|
||||||
{
|
|
||||||
return impl::isxdigit_(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename CharT>
|
|
||||||
static int digit(CharT ch)
|
|
||||||
{
|
|
||||||
if (impl::isdigit_(ch))
|
|
||||||
return ch - '0';
|
|
||||||
return impl::tolower_(ch) - 'a' + 10;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Helper templates for encapsulation of radix specific
|
|
||||||
// conversion of an input string to an integral value.
|
|
||||||
//
|
|
||||||
// main entry point:
|
|
||||||
//
|
|
||||||
// extract_int<Radix, MinDigits, MaxDigits, Accumulate>
|
|
||||||
// ::f(first, last, n, count);
|
|
||||||
//
|
|
||||||
// The template parameter Radix represents the radix of the
|
|
||||||
// number contained in the parsed string. The template
|
|
||||||
// parameter MinDigits specifies the minimum digits to
|
|
||||||
// accept. The template parameter MaxDigits specifies the
|
|
||||||
// maximum digits to parse. A -1 value for MaxDigits will
|
|
||||||
// make it parse an arbitrarilly large number as long as the
|
|
||||||
// numeric type can hold it. Accumulate is either
|
|
||||||
// positive_accumulate<Radix> (default) for parsing positive
|
|
||||||
// numbers or negative_accumulate<Radix> otherwise.
|
|
||||||
//
|
|
||||||
// scan.first and scan.last are iterators as usual (i.e.
|
|
||||||
// first is mutable and is moved forward when a match is
|
|
||||||
// found), n is a variable that holds the number (passed by
|
|
||||||
// reference). The number of parsed characters is added to
|
|
||||||
// count (also passed by reference)
|
|
||||||
//
|
|
||||||
// NOTE:
|
|
||||||
// Returns a non-match, if the number to parse
|
|
||||||
// overflows (or underflows) the used integral type.
|
|
||||||
// Overflow (or underflow) is detected when an
|
|
||||||
// operation wraps a value from its maximum to its
|
|
||||||
// minimum (or vice-versa). For example, overflow
|
|
||||||
// occurs when the result of the expression n * x is
|
|
||||||
// less than n (assuming n is positive and x is
|
|
||||||
// greater than 1).
|
|
||||||
//
|
|
||||||
// BEWARE:
|
|
||||||
// the parameters 'n' and 'count' should be properly
|
|
||||||
// initialized before calling this function.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
template <int Radix>
|
|
||||||
struct positive_accumulate
|
|
||||||
{
|
|
||||||
// Use this accumulator if number is positive
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static bool check(T const& n, T const& prev)
|
|
||||||
{
|
|
||||||
return n < prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename CharT>
|
|
||||||
static void add(T& n, CharT ch)
|
|
||||||
{
|
|
||||||
n += radix_traits<Radix>::digit(ch);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <int Radix>
|
|
||||||
struct negative_accumulate
|
|
||||||
{
|
|
||||||
// Use this accumulator if number is negative
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
static bool check(T const& n, T const& prev)
|
|
||||||
{
|
|
||||||
return n > prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename CharT>
|
|
||||||
static void add(T& n, CharT ch)
|
|
||||||
{
|
|
||||||
n -= radix_traits<Radix>::digit(ch);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <int Radix, typename Accumulate>
|
|
||||||
struct extract_int_base
|
|
||||||
{
|
|
||||||
// Common code for extract_int specializations
|
|
||||||
template <typename ScannerT, typename T>
|
|
||||||
static bool
|
|
||||||
f(ScannerT& scan, T& n)
|
|
||||||
{
|
|
||||||
T prev = n;
|
|
||||||
n *= Radix;
|
|
||||||
if (Accumulate::check(n, prev))
|
|
||||||
return false; // over/underflow!
|
|
||||||
prev = n;
|
|
||||||
Accumulate::add(n, *scan);
|
|
||||||
if (Accumulate::check(n, prev))
|
|
||||||
return false; // over/underflow!
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <bool Bounded>
|
|
||||||
struct extract_int_
|
|
||||||
{
|
|
||||||
template <
|
|
||||||
int Radix,
|
|
||||||
unsigned MinDigits,
|
|
||||||
int MaxDigits,
|
|
||||||
typename Accumulate
|
|
||||||
>
|
|
||||||
struct apply
|
|
||||||
{
|
|
||||||
typedef extract_int_base<Radix, Accumulate> base;
|
|
||||||
typedef radix_traits<Radix> check;
|
|
||||||
|
|
||||||
template <typename ScannerT, typename T>
|
|
||||||
static bool
|
|
||||||
f(ScannerT& scan, T& n, std::size_t& count)
|
|
||||||
{
|
|
||||||
std::size_t i = 0;
|
|
||||||
for (; (i < MaxDigits) && !scan.at_end()
|
|
||||||
&& check::is_valid(*scan);
|
|
||||||
++i, ++scan, ++count)
|
|
||||||
{
|
|
||||||
if (!base::f(scan, n))
|
|
||||||
return false; // over/underflow!
|
|
||||||
}
|
|
||||||
return i >= MinDigits;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct extract_int_<false>
|
|
||||||
{
|
|
||||||
template <
|
|
||||||
int Radix,
|
|
||||||
unsigned MinDigits,
|
|
||||||
int MaxDigits,
|
|
||||||
typename Accumulate
|
|
||||||
>
|
|
||||||
struct apply
|
|
||||||
{
|
|
||||||
typedef extract_int_base<Radix, Accumulate> base;
|
|
||||||
typedef radix_traits<Radix> check;
|
|
||||||
|
|
||||||
template <typename ScannerT, typename T>
|
|
||||||
static bool
|
|
||||||
f(ScannerT& scan, T& n, std::size_t& count)
|
|
||||||
{
|
|
||||||
std::size_t i = 0;
|
|
||||||
for (; !scan.at_end() && check::is_valid(*scan);
|
|
||||||
++i, ++scan, ++count)
|
|
||||||
{
|
|
||||||
if (!base::f(scan, n))
|
|
||||||
return false; // over/underflow!
|
|
||||||
}
|
|
||||||
return i >= MinDigits;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <
|
|
||||||
int Radix, unsigned MinDigits, int MaxDigits,
|
|
||||||
typename Accumulate = positive_accumulate<Radix>
|
|
||||||
>
|
|
||||||
struct extract_int
|
|
||||||
{
|
|
||||||
template <typename ScannerT, typename T>
|
|
||||||
static bool
|
|
||||||
f(ScannerT& scan, T& n, std::size_t& count)
|
|
||||||
{
|
|
||||||
typedef typename extract_int_<(MaxDigits >= 0)>::template
|
|
||||||
apply<Radix, MinDigits, MaxDigits, Accumulate> extractor;
|
|
||||||
return extractor::f(scan, n, count);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// uint_parser_impl class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
template <
|
|
||||||
typename T = unsigned,
|
|
||||||
int Radix = 10,
|
|
||||||
unsigned MinDigits = 1,
|
|
||||||
int MaxDigits = -1
|
|
||||||
>
|
|
||||||
struct uint_parser_impl
|
|
||||||
: parser<uint_parser_impl<T, Radix, MinDigits, MaxDigits> >
|
|
||||||
{
|
|
||||||
typedef uint_parser_impl<T, Radix, MinDigits, MaxDigits> self_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename match_result<ScannerT, T>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
if (!scan.at_end())
|
|
||||||
{
|
|
||||||
T n = 0;
|
|
||||||
std::size_t count = 0;
|
|
||||||
typename ScannerT::iterator_t save = scan.first;
|
|
||||||
if (extract_int<Radix, MinDigits, MaxDigits>::
|
|
||||||
f(scan, n, count))
|
|
||||||
{
|
|
||||||
return scan.create_match(count, n, save, scan.first);
|
|
||||||
}
|
|
||||||
// return no-match if number overflows
|
|
||||||
}
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// int_parser_impl class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
template <
|
|
||||||
typename T = unsigned,
|
|
||||||
int Radix = 10,
|
|
||||||
unsigned MinDigits = 1,
|
|
||||||
int MaxDigits = -1
|
|
||||||
>
|
|
||||||
struct int_parser_impl
|
|
||||||
: parser<int_parser_impl<T, Radix, MinDigits, MaxDigits> >
|
|
||||||
{
|
|
||||||
typedef int_parser_impl<T, Radix, MinDigits, MaxDigits> self_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename match_result<ScannerT, T>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef extract_int<Radix, MinDigits, MaxDigits,
|
|
||||||
negative_accumulate<Radix> > extract_int_neg_t;
|
|
||||||
typedef extract_int<Radix, MinDigits, MaxDigits>
|
|
||||||
extract_int_pos_t;
|
|
||||||
|
|
||||||
if (!scan.at_end())
|
|
||||||
{
|
|
||||||
T n = 0;
|
|
||||||
std::size_t count = 0;
|
|
||||||
typename ScannerT::iterator_t save = scan.first;
|
|
||||||
|
|
||||||
bool hit = impl::extract_sign(scan, count);
|
|
||||||
|
|
||||||
if (hit)
|
|
||||||
hit = extract_int_neg_t::f(scan, n, count);
|
|
||||||
else
|
|
||||||
hit = extract_int_pos_t::f(scan, n, count);
|
|
||||||
|
|
||||||
if (hit)
|
|
||||||
return scan.create_match(count, n, save, scan.first);
|
|
||||||
else
|
|
||||||
scan.first = save;
|
|
||||||
// return no-match if number overflows or underflows
|
|
||||||
}
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// real_parser_impl class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
#if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310))
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable:4127)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename RT, typename T, typename RealPoliciesT>
|
|
||||||
struct real_parser_impl
|
|
||||||
{
|
|
||||||
typedef real_parser_impl<RT, T, RealPoliciesT> self_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
RT parse_main(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
if (scan.at_end())
|
|
||||||
return scan.no_match();
|
|
||||||
typename ScannerT::iterator_t save = scan.first;
|
|
||||||
|
|
||||||
typedef typename parser_result<sign_parser, ScannerT>::type
|
|
||||||
sign_match_t;
|
|
||||||
typedef typename parser_result<chlit<>, ScannerT>::type
|
|
||||||
exp_match_t;
|
|
||||||
|
|
||||||
sign_match_t sign_match = RealPoliciesT::parse_sign(scan);
|
|
||||||
std::size_t count = sign_match ? sign_match.length() : 0;
|
|
||||||
bool neg = sign_match.has_valid_attribute() ?
|
|
||||||
sign_match.value() : false;
|
|
||||||
|
|
||||||
RT n_match = RealPoliciesT::parse_n(scan);
|
|
||||||
T n = n_match.has_valid_attribute() ?
|
|
||||||
n_match.value() : T(0);
|
|
||||||
bool got_a_number = n_match;
|
|
||||||
exp_match_t e_hit;
|
|
||||||
|
|
||||||
if (!got_a_number && !RealPoliciesT::allow_leading_dot)
|
|
||||||
return scan.no_match();
|
|
||||||
else
|
|
||||||
count += n_match.length();
|
|
||||||
|
|
||||||
if (neg)
|
|
||||||
n = -n;
|
|
||||||
|
|
||||||
if (RealPoliciesT::parse_dot(scan))
|
|
||||||
{
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
if (RT hit = RealPoliciesT::parse_frac_n(scan))
|
|
||||||
{
|
|
||||||
hit.value(hit.value()
|
|
||||||
* BOOST_SPIRIT_IMPL_STD_NS::
|
|
||||||
pow(T(10), T(-hit.length())));
|
|
||||||
if (neg)
|
|
||||||
n -= hit.value();
|
|
||||||
else
|
|
||||||
n += hit.value();
|
|
||||||
count += hit.length() + 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (!got_a_number ||
|
|
||||||
!RealPoliciesT::allow_trailing_dot)
|
|
||||||
return scan.no_match();
|
|
||||||
|
|
||||||
e_hit = RealPoliciesT::parse_exp(scan);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// We have reached a point where we
|
|
||||||
// still haven't seen a number at all.
|
|
||||||
// We return early with a no-match.
|
|
||||||
if (!got_a_number)
|
|
||||||
return scan.no_match();
|
|
||||||
|
|
||||||
// If we must expect a dot and we didn't see
|
|
||||||
// an exponent, return early with a no-match.
|
|
||||||
e_hit = RealPoliciesT::parse_exp(scan);
|
|
||||||
if (RealPoliciesT::expect_dot && !e_hit)
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
|
|
||||||
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.
|
|
||||||
if (RT e_n_hit = RealPoliciesT::parse_exp_n(scan))
|
|
||||||
{
|
|
||||||
n *= BOOST_SPIRIT_IMPL_STD_NS::
|
|
||||||
pow(T(10), T(e_n_hit.value()));
|
|
||||||
count += e_n_hit.length() + e_hit.length();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Oops, no exponent, return a no-match
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return scan.create_match(count, n, save, scan.first);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
static RT parse(ScannerT const& scan)
|
|
||||||
{
|
|
||||||
static self_t this_;
|
|
||||||
return impl::implicit_lexeme_parse<RT>(this_, scan, scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310))
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace impl
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#undef BOOST_SPIRIT_IMPL_STD_NS
|
|
@ -1,465 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2003 Martin Wille
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_PRIMITIVES_IPP)
|
|
||||||
#define BOOST_SPIRIT_PRIMITIVES_IPP
|
|
||||||
|
|
||||||
// This should eventually go to a config file.
|
|
||||||
#if defined(__GNUC__) && (__GNUC__ < 3) && !defined(_STLPORT_VERSION)
|
|
||||||
# ifndef BOOST_SPIRIT_NO_CHAR_TRAITS
|
|
||||||
# define BOOST_SPIRIT_NO_CHAR_TRAITS
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cctype>
|
|
||||||
#if !defined(BOOST_NO_CWCTYPE)
|
|
||||||
#include <cwctype>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BOOST_SPIRIT_NO_CHAR_TRAITS
|
|
||||||
# include <string> // char_traits
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC)
|
|
||||||
# pragma warning(disable:4800)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
template <typename DrivedT> struct char_parser;
|
|
||||||
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
template <typename IteratorT>
|
|
||||||
inline IteratorT
|
|
||||||
get_last(IteratorT first)
|
|
||||||
{
|
|
||||||
while (*first)
|
|
||||||
first++;
|
|
||||||
return first;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<
|
|
||||||
typename RT,
|
|
||||||
typename IteratorT,
|
|
||||||
typename ScannerT>
|
|
||||||
inline RT
|
|
||||||
string_parser_parse(
|
|
||||||
IteratorT str_first,
|
|
||||||
IteratorT str_last,
|
|
||||||
ScannerT& scan)
|
|
||||||
{
|
|
||||||
typedef typename ScannerT::iterator_t iterator_t;
|
|
||||||
iterator_t saved = scan.first;
|
|
||||||
std::size_t slen = str_last - str_first;
|
|
||||||
|
|
||||||
while (str_first != str_last)
|
|
||||||
{
|
|
||||||
if (scan.at_end() || (*str_first != *scan))
|
|
||||||
return scan.no_match();
|
|
||||||
++str_first;
|
|
||||||
++scan;
|
|
||||||
}
|
|
||||||
|
|
||||||
return scan.create_match(slen, nil_t(), saved, scan.first);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Conversion from char_type to int_type
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef BOOST_SPIRIT_NO_CHAR_TRAITS
|
|
||||||
# define BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE std
|
|
||||||
#else
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
struct char_traits
|
|
||||||
{
|
|
||||||
typedef CharT int_type;
|
|
||||||
typedef CharT char_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct char_traits<char>
|
|
||||||
{
|
|
||||||
typedef int int_type;
|
|
||||||
typedef char char_type;
|
|
||||||
|
|
||||||
static char_type
|
|
||||||
to_char_type(int_type c)
|
|
||||||
{
|
|
||||||
return static_cast<char_type>(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
to_int_type(char c)
|
|
||||||
{
|
|
||||||
return static_cast<unsigned char>(c);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct char_traits<unsigned char>
|
|
||||||
{
|
|
||||||
typedef int int_type;
|
|
||||||
typedef unsigned char char_type;
|
|
||||||
|
|
||||||
static char_type
|
|
||||||
to_char_type(int_type c)
|
|
||||||
{
|
|
||||||
return static_cast<char_type>(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
to_int_type(unsigned char c)
|
|
||||||
{
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
# define BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE impl
|
|
||||||
# ifndef BOOST_NO_CWCTYPE
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct char_traits<wchar_t>
|
|
||||||
{
|
|
||||||
typedef wint_t int_type;
|
|
||||||
typedef wchar_t char_type;
|
|
||||||
|
|
||||||
static char_type
|
|
||||||
to_char_type(int_type c)
|
|
||||||
{
|
|
||||||
return static_cast<char_type>(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static wint_t
|
|
||||||
to_int_type(wchar_t c)
|
|
||||||
{
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
# endif
|
|
||||||
#endif // BOOST_SPIRIT_NO_CHAR_TRAITS
|
|
||||||
|
|
||||||
// Use char_traits for char and wchar_t only, as these are the only
|
|
||||||
// specializations provided in the standard. Other types are on their
|
|
||||||
// own.
|
|
||||||
//
|
|
||||||
// For UDT, one may override:
|
|
||||||
//
|
|
||||||
// isalnum
|
|
||||||
// isalpha
|
|
||||||
// iscntrl
|
|
||||||
// isdigit
|
|
||||||
// isgraph
|
|
||||||
// islower
|
|
||||||
// isprint
|
|
||||||
// ispunct
|
|
||||||
// isspace
|
|
||||||
// isupper
|
|
||||||
// isxdigit
|
|
||||||
// isblank
|
|
||||||
// isupper
|
|
||||||
// tolower
|
|
||||||
// toupper
|
|
||||||
//
|
|
||||||
// in a namespace suitable for Argument Dependent lookup or in
|
|
||||||
// namespace std (disallowed by the standard).
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
struct char_type_char_traits_helper
|
|
||||||
{
|
|
||||||
typedef CharT char_type;
|
|
||||||
typedef typename BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE
|
|
||||||
::char_traits<CharT>::int_type int_type;
|
|
||||||
|
|
||||||
static int_type to_int_type(CharT c)
|
|
||||||
{
|
|
||||||
return BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE
|
|
||||||
::char_traits<CharT>::to_int_type(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char_type to_char_type(int_type i)
|
|
||||||
{
|
|
||||||
return BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE
|
|
||||||
::char_traits<CharT>::to_char_type(i);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
struct char_traits_helper
|
|
||||||
{
|
|
||||||
typedef CharT char_type;
|
|
||||||
typedef CharT int_type;
|
|
||||||
|
|
||||||
static CharT & to_int_type(CharT & c)
|
|
||||||
{
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CharT & to_char_type(CharT & c)
|
|
||||||
{
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct char_traits_helper<char>
|
|
||||||
: char_type_char_traits_helper<char>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CWCTYPE)
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct char_traits_helper<wchar_t>
|
|
||||||
: char_type_char_traits_helper<wchar_t>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline typename char_traits_helper<CharT>::int_type
|
|
||||||
to_int_type(CharT c)
|
|
||||||
{
|
|
||||||
return char_traits_helper<CharT>::to_int_type(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline CharT
|
|
||||||
to_char_type(typename char_traits_helper<CharT>::int_type c)
|
|
||||||
{
|
|
||||||
return char_traits_helper<CharT>::to_char_type(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Convenience functions
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline bool
|
|
||||||
isalnum_(CharT c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return isalnum(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline bool
|
|
||||||
isalpha_(CharT c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return isalpha(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline bool
|
|
||||||
iscntrl_(CharT c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return iscntrl(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline bool
|
|
||||||
isdigit_(CharT c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return isdigit(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline bool
|
|
||||||
isgraph_(CharT c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return isgraph(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline bool
|
|
||||||
islower_(CharT c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return islower(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline bool
|
|
||||||
isprint_(CharT c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return isprint(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline bool
|
|
||||||
ispunct_(CharT c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return ispunct(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline bool
|
|
||||||
isspace_(CharT c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return isspace(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline bool
|
|
||||||
isupper_(CharT c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return isupper(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline bool
|
|
||||||
isxdigit_(CharT c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return isxdigit(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline bool
|
|
||||||
isblank_(CharT c)
|
|
||||||
{
|
|
||||||
return (c == ' ' || c == '\t');
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline CharT
|
|
||||||
tolower_(CharT c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return to_char_type<CharT>(tolower(to_int_type(c)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline CharT
|
|
||||||
toupper_(CharT c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return to_char_type<CharT>(toupper(to_int_type(c)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CWCTYPE)
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
isalnum_(wchar_t c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return iswalnum(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
isalpha_(wchar_t c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return iswalpha(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
iscntrl_(wchar_t c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return iswcntrl(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
isdigit_(wchar_t c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return iswdigit(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
isgraph_(wchar_t c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return iswgraph(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
islower_(wchar_t c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return iswlower(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
isprint_(wchar_t c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return iswprint(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
ispunct_(wchar_t c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return iswpunct(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
isspace_(wchar_t c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return iswspace(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
isupper_(wchar_t c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return iswupper(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
isxdigit_(wchar_t c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return iswxdigit(to_int_type(c)) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool
|
|
||||||
isblank_(wchar_t c)
|
|
||||||
{
|
|
||||||
return (c == L' ' || c == L'\t');
|
|
||||||
}
|
|
||||||
|
|
||||||
inline wchar_t
|
|
||||||
tolower_(wchar_t c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return to_char_type<wchar_t>(towlower(to_int_type(c)));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline wchar_t
|
|
||||||
toupper_(wchar_t c)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
return to_char_type<wchar_t>(towupper(to_int_type(c)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // !defined(BOOST_NO_CWCTYPE)
|
|
||||||
|
|
||||||
}}} // namespace boost::spirit::impl
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,285 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001-2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_NUMERICS_HPP
|
|
||||||
#define BOOST_SPIRIT_NUMERICS_HPP
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/composite/directives.hpp>
|
|
||||||
|
|
||||||
#include <boost/spirit/core/primitives/numerics_fwd.hpp>
|
|
||||||
#include <boost/spirit/core/primitives/impl/numerics.ipp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit
|
|
||||||
{
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// uint_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <
|
|
||||||
typename T,
|
|
||||||
int Radix,
|
|
||||||
unsigned MinDigits,
|
|
||||||
int MaxDigits
|
|
||||||
>
|
|
||||||
struct uint_parser : parser<uint_parser<T, Radix, MinDigits, MaxDigits> >
|
|
||||||
{
|
|
||||||
typedef uint_parser<T, Radix, MinDigits, MaxDigits> self_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename match_result<ScannerT, T>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef impl::uint_parser_impl<T, Radix, MinDigits, MaxDigits> impl_t;
|
|
||||||
typedef typename parser_result<impl_t, ScannerT>::type result_t;
|
|
||||||
return impl::contiguous_parser_parse<result_t>(impl_t(), scan, scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// int_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <
|
|
||||||
typename T,
|
|
||||||
int Radix,
|
|
||||||
unsigned MinDigits,
|
|
||||||
int MaxDigits
|
|
||||||
>
|
|
||||||
struct int_parser : parser<int_parser<T, Radix, MinDigits, MaxDigits> >
|
|
||||||
{
|
|
||||||
typedef int_parser<T, Radix, MinDigits, MaxDigits> self_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename match_result<ScannerT, T>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef impl::int_parser_impl<T, Radix, MinDigits, MaxDigits> impl_t;
|
|
||||||
typedef typename parser_result<impl_t, ScannerT>::type result_t;
|
|
||||||
return impl::contiguous_parser_parse<result_t>(impl_t(), scan, scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// uint_parser/int_parser instantiations
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
int_parser<int> const
|
|
||||||
int_p = int_parser<int>();
|
|
||||||
|
|
||||||
uint_parser<unsigned> const
|
|
||||||
uint_p = uint_parser<unsigned>();
|
|
||||||
|
|
||||||
uint_parser<unsigned, 2> const
|
|
||||||
bin_p = uint_parser<unsigned, 2>();
|
|
||||||
|
|
||||||
uint_parser<unsigned, 8> const
|
|
||||||
oct_p = uint_parser<unsigned, 8>();
|
|
||||||
|
|
||||||
uint_parser<unsigned, 16> const
|
|
||||||
hex_p = uint_parser<unsigned, 16>();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// sign_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
// Utility to extract the prefix sign ('-' | '+')
|
|
||||||
template <typename ScannerT>
|
|
||||||
bool extract_sign(ScannerT const& scan, std::size_t& count);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sign_parser : public parser<sign_parser>
|
|
||||||
{
|
|
||||||
typedef sign_parser self_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename match_result<ScannerT, bool>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
sign_parser() {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
if (!scan.at_end())
|
|
||||||
{
|
|
||||||
std::size_t length;
|
|
||||||
typename ScannerT::iterator_t save(scan.first);
|
|
||||||
bool neg = impl::extract_sign(scan, length);
|
|
||||||
if (length)
|
|
||||||
return scan.create_match(1, neg, save, scan.first);
|
|
||||||
}
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
sign_parser const sign_p = sign_parser();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// default real number policies
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
struct ureal_parser_policies
|
|
||||||
{
|
|
||||||
// trailing dot policy suggested suggested by Gustavo Guerra
|
|
||||||
BOOST_STATIC_CONSTANT(bool, allow_leading_dot = true);
|
|
||||||
BOOST_STATIC_CONSTANT(bool, allow_trailing_dot = true);
|
|
||||||
BOOST_STATIC_CONSTANT(bool, expect_dot = false);
|
|
||||||
|
|
||||||
typedef uint_parser<T, 10, 1, -1> uint_parser_t;
|
|
||||||
typedef int_parser<T, 10, 1, -1> int_parser_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
static typename match_result<ScannerT, nil_t>::type
|
|
||||||
parse_sign(ScannerT& scan)
|
|
||||||
{
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
static typename parser_result<uint_parser_t, ScannerT>::type
|
|
||||||
parse_n(ScannerT& scan)
|
|
||||||
{
|
|
||||||
return uint_parser_t().parse(scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
static typename parser_result<chlit<>, ScannerT>::type
|
|
||||||
parse_dot(ScannerT& scan)
|
|
||||||
{
|
|
||||||
return ch_p('.').parse(scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
static typename parser_result<uint_parser_t, ScannerT>::type
|
|
||||||
parse_frac_n(ScannerT& scan)
|
|
||||||
{
|
|
||||||
return uint_parser_t().parse(scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
static typename parser_result<chlit<>, ScannerT>::type
|
|
||||||
parse_exp(ScannerT& scan)
|
|
||||||
{
|
|
||||||
return as_lower_d['e'].parse(scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
static typename parser_result<int_parser_t, ScannerT>::type
|
|
||||||
parse_exp_n(ScannerT& scan)
|
|
||||||
{
|
|
||||||
return int_parser_t().parse(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct real_parser_policies : public ureal_parser_policies<T>
|
|
||||||
{
|
|
||||||
template <typename ScannerT>
|
|
||||||
static typename parser_result<sign_parser, ScannerT>::type
|
|
||||||
parse_sign(ScannerT& scan)
|
|
||||||
{
|
|
||||||
return sign_p.parse(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// real_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <
|
|
||||||
typename T,
|
|
||||||
typename RealPoliciesT
|
|
||||||
>
|
|
||||||
struct real_parser
|
|
||||||
: public parser<real_parser<T, RealPoliciesT> >
|
|
||||||
{
|
|
||||||
typedef real_parser<T, RealPoliciesT> self_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename match_result<ScannerT, T>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
real_parser() {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
return impl::real_parser_impl<result_t, T, RealPoliciesT>::parse(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// real_parser instantiations
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
real_parser<double, ureal_parser_policies<double> > const
|
|
||||||
ureal_p = real_parser<double, ureal_parser_policies<double> >();
|
|
||||||
|
|
||||||
real_parser<double, real_parser_policies<double> > const
|
|
||||||
real_p = real_parser<double, real_parser_policies<double> >();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// strict reals (do not allow plain integers (no decimal point))
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
struct strict_ureal_parser_policies : public ureal_parser_policies<T>
|
|
||||||
{
|
|
||||||
BOOST_STATIC_CONSTANT(bool, expect_dot = true);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct strict_real_parser_policies : public real_parser_policies<T>
|
|
||||||
{
|
|
||||||
BOOST_STATIC_CONSTANT(bool, expect_dot = true);
|
|
||||||
};
|
|
||||||
|
|
||||||
real_parser<double, strict_ureal_parser_policies<double> > const
|
|
||||||
strict_ureal_p
|
|
||||||
= real_parser<double, strict_ureal_parser_policies<double> >();
|
|
||||||
|
|
||||||
real_parser<double, strict_real_parser_policies<double> > const
|
|
||||||
strict_real_p
|
|
||||||
= real_parser<double, strict_real_parser_policies<double> >();
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,645 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2003 Martin Wille
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_PRIMITIVES_HPP)
|
|
||||||
#define BOOST_SPIRIT_PRIMITIVES_HPP
|
|
||||||
|
|
||||||
#include <boost/ref.hpp>
|
|
||||||
#include <boost/spirit/core/assert.hpp>
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/composite/impl/directives.ipp>
|
|
||||||
#include <boost/spirit/core/primitives/impl/primitives.ipp>
|
|
||||||
|
|
||||||
#ifdef BOOST_MSVC
|
|
||||||
#pragma warning(disable : 4512)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// char_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename DerivedT>
|
|
||||||
struct char_parser : public parser<DerivedT>
|
|
||||||
{
|
|
||||||
typedef DerivedT self_t;
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename match_result<
|
|
||||||
ScannerT,
|
|
||||||
typename ScannerT::value_t
|
|
||||||
>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
typedef typename ScannerT::value_t value_t;
|
|
||||||
typedef typename ScannerT::iterator_t iterator_t;
|
|
||||||
|
|
||||||
if (!scan.at_end())
|
|
||||||
{
|
|
||||||
value_t ch = *scan;
|
|
||||||
if (this->derived().test(ch))
|
|
||||||
{
|
|
||||||
iterator_t save(scan.first);
|
|
||||||
++scan.first;
|
|
||||||
return scan.create_match(1, ch, save, scan.first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// negation of char_parsers
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename PositiveT>
|
|
||||||
struct negated_char_parser
|
|
||||||
: public char_parser<negated_char_parser<PositiveT> >
|
|
||||||
{
|
|
||||||
typedef negated_char_parser<PositiveT> self_t;
|
|
||||||
typedef PositiveT positive_t;
|
|
||||||
|
|
||||||
negated_char_parser(positive_t const& p)
|
|
||||||
: positive(p.derived()) {}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool test(T ch) const
|
|
||||||
{
|
|
||||||
return !positive.test(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
positive_t const positive;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
inline negated_char_parser<ParserT>
|
|
||||||
operator~(char_parser<ParserT> const& p)
|
|
||||||
{
|
|
||||||
return negated_char_parser<ParserT>(p.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
inline ParserT
|
|
||||||
operator~(negated_char_parser<ParserT> const& n)
|
|
||||||
{
|
|
||||||
return n.positive;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// chlit class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename CharT = char>
|
|
||||||
struct chlit : public char_parser<chlit<CharT> >
|
|
||||||
{
|
|
||||||
chlit(CharT ch_)
|
|
||||||
: ch(ch_) {}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool test(T ch_) const
|
|
||||||
{
|
|
||||||
return ch_ == ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
CharT ch;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline chlit<CharT>
|
|
||||||
ch_p(CharT ch)
|
|
||||||
{
|
|
||||||
return chlit<CharT>(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This should take care of ch_p("a") "bugs"
|
|
||||||
template <typename CharT, std::size_t N>
|
|
||||||
inline chlit<CharT>
|
|
||||||
ch_p(CharT const (& str)[N])
|
|
||||||
{
|
|
||||||
// ch_p's argument should be a single character or a null-terminated
|
|
||||||
// string with a single character
|
|
||||||
BOOST_STATIC_ASSERT(N < 3);
|
|
||||||
return chlit<CharT>(str[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// range class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename CharT = char>
|
|
||||||
struct range : public char_parser<range<CharT> >
|
|
||||||
{
|
|
||||||
range(CharT first_, CharT last_)
|
|
||||||
: first(first_), last(last_)
|
|
||||||
{
|
|
||||||
BOOST_SPIRIT_ASSERT(!(last < first));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool test(T ch) const
|
|
||||||
{
|
|
||||||
return !(CharT(ch) < first) && !(last < CharT(ch));
|
|
||||||
}
|
|
||||||
|
|
||||||
CharT first;
|
|
||||||
CharT last;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline range<CharT>
|
|
||||||
range_p(CharT first, CharT last)
|
|
||||||
{
|
|
||||||
return range<CharT>(first, last);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// chseq class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename IteratorT = char const*>
|
|
||||||
class chseq : public parser<chseq<IteratorT> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef chseq<IteratorT> self_t;
|
|
||||||
|
|
||||||
chseq(IteratorT first_, IteratorT last_)
|
|
||||||
: first(first_), last(last_) {}
|
|
||||||
|
|
||||||
chseq(IteratorT first_)
|
|
||||||
: first(first_), last(impl::get_last(first_)) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename boost::unwrap_reference<IteratorT>::type striter_t;
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
return impl::string_parser_parse<result_t>(
|
|
||||||
striter_t(first),
|
|
||||||
striter_t(last),
|
|
||||||
scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
IteratorT first;
|
|
||||||
IteratorT last;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline chseq<CharT const*>
|
|
||||||
chseq_p(CharT const* str)
|
|
||||||
{
|
|
||||||
return chseq<CharT const*>(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename IteratorT>
|
|
||||||
inline chseq<IteratorT>
|
|
||||||
chseq_p(IteratorT first, IteratorT last)
|
|
||||||
{
|
|
||||||
return chseq<IteratorT>(first, last);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// strlit class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename IteratorT = char const*>
|
|
||||||
class strlit : public parser<strlit<IteratorT> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef strlit<IteratorT> self_t;
|
|
||||||
|
|
||||||
strlit(IteratorT first, IteratorT last)
|
|
||||||
: seq(first, last) {}
|
|
||||||
|
|
||||||
strlit(IteratorT first)
|
|
||||||
: seq(first) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
return impl::contiguous_parser_parse<result_t>
|
|
||||||
(seq, scan, scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
chseq<IteratorT> seq;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline strlit<CharT const*>
|
|
||||||
str_p(CharT const* str)
|
|
||||||
{
|
|
||||||
return strlit<CharT const*>(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
inline strlit<CharT *>
|
|
||||||
str_p(CharT * str)
|
|
||||||
{
|
|
||||||
return strlit<CharT *>(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename IteratorT>
|
|
||||||
inline strlit<IteratorT>
|
|
||||||
str_p(IteratorT first, IteratorT last)
|
|
||||||
{
|
|
||||||
return strlit<IteratorT>(first, last);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This should take care of str_p('a') "bugs"
|
|
||||||
template <typename CharT>
|
|
||||||
inline chlit<CharT>
|
|
||||||
str_p(CharT ch)
|
|
||||||
{
|
|
||||||
return chlit<CharT>(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// nothing_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct nothing_parser : public parser<nothing_parser>
|
|
||||||
{
|
|
||||||
typedef nothing_parser self_t;
|
|
||||||
|
|
||||||
nothing_parser() {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
nothing_parser const nothing_p = nothing_parser();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// anychar_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct anychar_parser : public char_parser<anychar_parser>
|
|
||||||
{
|
|
||||||
typedef anychar_parser self_t;
|
|
||||||
|
|
||||||
anychar_parser() {}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
bool test(CharT) const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
anychar_parser const anychar_p = anychar_parser();
|
|
||||||
|
|
||||||
inline nothing_parser
|
|
||||||
operator~(anychar_parser)
|
|
||||||
{
|
|
||||||
return nothing_p;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// alnum_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct alnum_parser : public char_parser<alnum_parser>
|
|
||||||
{
|
|
||||||
typedef alnum_parser self_t;
|
|
||||||
|
|
||||||
alnum_parser() {}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
bool test(CharT ch) const
|
|
||||||
{
|
|
||||||
return impl::isalnum_(ch);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
alnum_parser const alnum_p = alnum_parser();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// alpha_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct alpha_parser : public char_parser<alpha_parser>
|
|
||||||
{
|
|
||||||
typedef alpha_parser self_t;
|
|
||||||
|
|
||||||
alpha_parser() {}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
bool test(CharT ch) const
|
|
||||||
{
|
|
||||||
return impl::isalpha_(ch);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
alpha_parser const alpha_p = alpha_parser();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// cntrl_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct cntrl_parser : public char_parser<cntrl_parser>
|
|
||||||
{
|
|
||||||
typedef cntrl_parser self_t;
|
|
||||||
|
|
||||||
cntrl_parser() {}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
bool test(CharT ch) const
|
|
||||||
{
|
|
||||||
return impl::iscntrl_(ch);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
cntrl_parser const cntrl_p = cntrl_parser();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// digit_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct digit_parser : public char_parser<digit_parser>
|
|
||||||
{
|
|
||||||
typedef digit_parser self_t;
|
|
||||||
|
|
||||||
digit_parser() {}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
bool test(CharT ch) const
|
|
||||||
{
|
|
||||||
return impl::isdigit_(ch);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
digit_parser const digit_p = digit_parser();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// graph_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct graph_parser : public char_parser<graph_parser>
|
|
||||||
{
|
|
||||||
typedef graph_parser self_t;
|
|
||||||
|
|
||||||
graph_parser() {}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
bool test(CharT ch) const
|
|
||||||
{
|
|
||||||
return impl::isgraph_(ch);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
graph_parser const graph_p = graph_parser();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// lower_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct lower_parser : public char_parser<lower_parser>
|
|
||||||
{
|
|
||||||
typedef lower_parser self_t;
|
|
||||||
|
|
||||||
lower_parser() {}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
bool test(CharT ch) const
|
|
||||||
{
|
|
||||||
return impl::islower_(ch);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
lower_parser const lower_p = lower_parser();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// print_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct print_parser : public char_parser<print_parser>
|
|
||||||
{
|
|
||||||
typedef print_parser self_t;
|
|
||||||
|
|
||||||
print_parser() {}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
bool test(CharT ch) const
|
|
||||||
{
|
|
||||||
return impl::isprint_(ch);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
print_parser const print_p = print_parser();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// punct_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct punct_parser : public char_parser<punct_parser>
|
|
||||||
{
|
|
||||||
typedef punct_parser self_t;
|
|
||||||
|
|
||||||
punct_parser() {}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
bool test(CharT ch) const
|
|
||||||
{
|
|
||||||
return impl::ispunct_(ch);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
punct_parser const punct_p = punct_parser();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// blank_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct blank_parser : public char_parser<blank_parser>
|
|
||||||
{
|
|
||||||
typedef blank_parser self_t;
|
|
||||||
|
|
||||||
blank_parser() {}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
bool test(CharT ch) const
|
|
||||||
{
|
|
||||||
return impl::isblank_(ch);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
blank_parser const blank_p = blank_parser();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// space_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct space_parser : public char_parser<space_parser>
|
|
||||||
{
|
|
||||||
typedef space_parser self_t;
|
|
||||||
|
|
||||||
space_parser() {}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
bool test(CharT ch) const
|
|
||||||
{
|
|
||||||
return impl::isspace_(ch);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
space_parser const space_p = space_parser();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// upper_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct upper_parser : public char_parser<upper_parser>
|
|
||||||
{
|
|
||||||
typedef upper_parser self_t;
|
|
||||||
|
|
||||||
upper_parser() {}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
bool test(CharT ch) const
|
|
||||||
{
|
|
||||||
return impl::isupper_(ch);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
upper_parser const upper_p = upper_parser();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// xdigit_parser class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct xdigit_parser : public char_parser<xdigit_parser>
|
|
||||||
{
|
|
||||||
typedef xdigit_parser self_t;
|
|
||||||
|
|
||||||
xdigit_parser() {}
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
bool test(CharT ch) const
|
|
||||||
{
|
|
||||||
return impl::isxdigit_(ch);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
xdigit_parser const xdigit_p = xdigit_parser();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// eol_parser class (contributed by Martin Wille)
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct eol_parser : public parser<eol_parser>
|
|
||||||
{
|
|
||||||
typedef eol_parser self_t;
|
|
||||||
|
|
||||||
eol_parser() {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typename ScannerT::iterator_t save = scan.first;
|
|
||||||
std::size_t len = 0;
|
|
||||||
|
|
||||||
if (!scan.at_end() && *scan == '\r') // CR
|
|
||||||
{
|
|
||||||
++scan.first;
|
|
||||||
++len;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't call skipper here
|
|
||||||
if (scan.first != scan.last && *scan == '\n') // LF
|
|
||||||
{
|
|
||||||
++scan.first;
|
|
||||||
++len;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len)
|
|
||||||
return scan.create_match(len, nil_t(), save, scan.first);
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
eol_parser const eol_p = eol_parser();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// end_parser class (suggested by Markus Schöpflin)
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct end_parser : public parser<end_parser>
|
|
||||||
{
|
|
||||||
typedef end_parser self_t;
|
|
||||||
|
|
||||||
end_parser() {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
if (scan.at_end())
|
|
||||||
return scan.empty_match();
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
end_parser const end_p = end_parser();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// the pizza_p parser :-)
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
inline strlit<char const*> const
|
|
||||||
pizza_p(char const* your_favorite_pizza)
|
|
||||||
{
|
|
||||||
return your_favorite_pizza;
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,59 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2003 Joel de Guzman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_SAFE_BOOL_HPP)
|
|
||||||
#define BOOST_SPIRIT_SAFE_BOOL_HPP
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <boost/detail/workaround.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit
|
|
||||||
{
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
template <typename T>
|
|
||||||
struct no_base {};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct safe_bool_impl
|
|
||||||
{
|
|
||||||
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
|
|
||||||
void stub(T*) {};
|
|
||||||
typedef void (safe_bool_impl::*type)(T*);
|
|
||||||
#else
|
|
||||||
typedef T* TP; // workaround to make parsing easier
|
|
||||||
TP stub;
|
|
||||||
typedef TP safe_bool_impl::*type;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename DerivedT, typename BaseT = impl::no_base<DerivedT> >
|
|
||||||
struct safe_bool : BaseT
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef impl::safe_bool_impl<DerivedT> impl_t;
|
|
||||||
typedef typename impl_t::type bool_type;
|
|
||||||
|
|
||||||
public:
|
|
||||||
operator bool_type() const
|
|
||||||
{
|
|
||||||
return static_cast<const DerivedT*>(this)->operator_bool() ?
|
|
||||||
&impl_t::stub : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator bool_type()
|
|
||||||
{
|
|
||||||
return static_cast<DerivedT*>(this)->operator_bool() ?
|
|
||||||
&impl_t::stub : 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,177 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_SKIPPER_IPP)
|
|
||||||
#define BOOST_SPIRIT_SKIPPER_IPP
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
struct space_parser;
|
|
||||||
template <typename BaseT>
|
|
||||||
struct no_skipper_iteration_policy;
|
|
||||||
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
template <typename ST, typename ScannerT, typename BaseT>
|
|
||||||
inline void
|
|
||||||
skipper_skip(
|
|
||||||
ST const& s,
|
|
||||||
ScannerT const& scan,
|
|
||||||
skipper_iteration_policy<BaseT> const&)
|
|
||||||
{
|
|
||||||
typedef scanner_policies<
|
|
||||||
no_skipper_iteration_policy<
|
|
||||||
BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>,
|
|
||||||
BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t,
|
|
||||||
BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t
|
|
||||||
> policies_t;
|
|
||||||
|
|
||||||
scanner<BOOST_DEDUCED_TYPENAME ScannerT::iterator_t, policies_t>
|
|
||||||
scan2(scan.first, scan.last, policies_t(scan));
|
|
||||||
typedef typename ScannerT::iterator_t iterator_t;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
iterator_t save = scan.first;
|
|
||||||
if (!s.parse(scan2))
|
|
||||||
{
|
|
||||||
scan.first = save;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ST, typename ScannerT, typename BaseT>
|
|
||||||
inline void
|
|
||||||
skipper_skip(
|
|
||||||
ST const& s,
|
|
||||||
ScannerT const& scan,
|
|
||||||
no_skipper_iteration_policy<BaseT> const&)
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
typedef typename ScannerT::iterator_t iterator_t;
|
|
||||||
iterator_t save = scan.first;
|
|
||||||
if (!s.parse(scan))
|
|
||||||
{
|
|
||||||
scan.first = save;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ST, typename ScannerT>
|
|
||||||
inline void
|
|
||||||
skipper_skip(
|
|
||||||
ST const& s,
|
|
||||||
ScannerT const& scan,
|
|
||||||
iteration_policy const&)
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
typedef typename ScannerT::iterator_t iterator_t;
|
|
||||||
iterator_t save = scan.first;
|
|
||||||
if (!s.parse(scan))
|
|
||||||
{
|
|
||||||
scan.first = save;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename SkipT>
|
|
||||||
struct phrase_parser
|
|
||||||
{
|
|
||||||
template <typename IteratorT, typename ParserT>
|
|
||||||
static parse_info<IteratorT>
|
|
||||||
parse(
|
|
||||||
IteratorT const& first_,
|
|
||||||
IteratorT const& last,
|
|
||||||
ParserT const& p,
|
|
||||||
SkipT const& skip)
|
|
||||||
{
|
|
||||||
typedef skip_parser_iteration_policy<SkipT> iter_policy_t;
|
|
||||||
typedef scanner_policies<iter_policy_t> scanner_policies_t;
|
|
||||||
typedef scanner<IteratorT, scanner_policies_t> scanner_t;
|
|
||||||
|
|
||||||
iter_policy_t iter_policy(skip);
|
|
||||||
scanner_policies_t policies(iter_policy);
|
|
||||||
IteratorT first = first_;
|
|
||||||
scanner_t scan(first, last, policies);
|
|
||||||
match<nil_t> hit = p.parse(scan);
|
|
||||||
return parse_info<IteratorT>(
|
|
||||||
first, hit, hit && (first == last),
|
|
||||||
hit.length());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct phrase_parser<space_parser>
|
|
||||||
{
|
|
||||||
template <typename IteratorT, typename ParserT>
|
|
||||||
static parse_info<IteratorT>
|
|
||||||
parse(
|
|
||||||
IteratorT const& first_,
|
|
||||||
IteratorT const& last,
|
|
||||||
ParserT const& p,
|
|
||||||
space_parser const&)
|
|
||||||
{
|
|
||||||
typedef skipper_iteration_policy<> iter_policy_t;
|
|
||||||
typedef scanner_policies<iter_policy_t> scanner_policies_t;
|
|
||||||
typedef scanner<IteratorT, scanner_policies_t> scanner_t;
|
|
||||||
|
|
||||||
IteratorT first = first_;
|
|
||||||
scanner_t scan(first, last);
|
|
||||||
match<nil_t> hit = p.parse(scan);
|
|
||||||
return parse_info<IteratorT>(
|
|
||||||
first, hit, hit && (first == last),
|
|
||||||
hit.length());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Free parse functions using the skippers
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename IteratorT, typename ParserT, typename SkipT>
|
|
||||||
inline parse_info<IteratorT>
|
|
||||||
parse(
|
|
||||||
IteratorT const& first,
|
|
||||||
IteratorT const& last,
|
|
||||||
parser<ParserT> const& p,
|
|
||||||
parser<SkipT> const& skip)
|
|
||||||
{
|
|
||||||
return impl::phrase_parser<SkipT>::
|
|
||||||
parse(first, last, p.derived(), skip.derived());
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Parse function for null terminated strings using the skippers
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename CharT, typename ParserT, typename SkipT>
|
|
||||||
inline parse_info<CharT const*>
|
|
||||||
parse(
|
|
||||||
CharT const* str,
|
|
||||||
parser<ParserT> const& p,
|
|
||||||
parser<SkipT> const& skip)
|
|
||||||
{
|
|
||||||
CharT const* last = str;
|
|
||||||
while (*last)
|
|
||||||
last++;
|
|
||||||
return parse(str, last, p, skip);
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,320 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2002 Joel de Guzman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_SCANNER_HPP)
|
|
||||||
#define BOOST_SPIRIT_SCANNER_HPP
|
|
||||||
|
|
||||||
#include <iterator>
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <boost/spirit/core/match.hpp>
|
|
||||||
#include <boost/spirit/core/non_terminal/parser_id.hpp>
|
|
||||||
#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
|
|
||||||
|
|
||||||
#include <boost/spirit/core/scanner/scanner_fwd.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit
|
|
||||||
{
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// iteration_policy class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct iteration_policy
|
|
||||||
{
|
|
||||||
template <typename ScannerT>
|
|
||||||
void
|
|
||||||
advance(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
++scan.first;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
bool at_end(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
return scan.first == scan.last;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T filter(T ch) const
|
|
||||||
{
|
|
||||||
return ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename ScannerT::ref_t
|
|
||||||
get(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
return *scan.first;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// match_policy class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct match_policy
|
|
||||||
{
|
|
||||||
template <typename T>
|
|
||||||
struct result { typedef match<T> type; };
|
|
||||||
|
|
||||||
const match<nil_t>
|
|
||||||
no_match() const
|
|
||||||
{
|
|
||||||
return match<nil_t>();
|
|
||||||
}
|
|
||||||
|
|
||||||
const match<nil_t>
|
|
||||||
empty_match() const
|
|
||||||
{
|
|
||||||
return match<nil_t>(0, nil_t());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename AttrT, typename IteratorT>
|
|
||||||
match<AttrT>
|
|
||||||
create_match(
|
|
||||||
std::size_t length,
|
|
||||||
AttrT const& val,
|
|
||||||
IteratorT const& /*first*/,
|
|
||||||
IteratorT const& /*last*/) const
|
|
||||||
{
|
|
||||||
return match<AttrT>(length, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename MatchT, typename IteratorT>
|
|
||||||
void group_match(
|
|
||||||
MatchT& /*m*/,
|
|
||||||
parser_id const& /*id*/,
|
|
||||||
IteratorT const& /*first*/,
|
|
||||||
IteratorT const& /*last*/) const {}
|
|
||||||
|
|
||||||
template <typename Match1T, typename Match2T>
|
|
||||||
void concat_match(Match1T& l, Match2T const& r) const
|
|
||||||
{
|
|
||||||
l.concat(r);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// match_result class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename MatchPolicyT, typename T>
|
|
||||||
struct match_result
|
|
||||||
{
|
|
||||||
typedef typename MatchPolicyT::template result<T>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// action_policy class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename AttrT>
|
|
||||||
struct attributed_action_policy
|
|
||||||
{
|
|
||||||
template <typename ActorT, typename IteratorT>
|
|
||||||
static void
|
|
||||||
call(
|
|
||||||
ActorT const& actor,
|
|
||||||
AttrT& val,
|
|
||||||
IteratorT const&,
|
|
||||||
IteratorT const&)
|
|
||||||
{
|
|
||||||
actor(val);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <>
|
|
||||||
struct attributed_action_policy<nil_t>
|
|
||||||
{
|
|
||||||
template <typename ActorT, typename IteratorT>
|
|
||||||
static void
|
|
||||||
call(
|
|
||||||
ActorT const& actor,
|
|
||||||
nil_t,
|
|
||||||
IteratorT const& first,
|
|
||||||
IteratorT const& last)
|
|
||||||
{
|
|
||||||
actor(first, last);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
struct action_policy
|
|
||||||
{
|
|
||||||
template <typename ActorT, typename AttrT, typename IteratorT>
|
|
||||||
void
|
|
||||||
do_action(
|
|
||||||
ActorT const& actor,
|
|
||||||
AttrT& val,
|
|
||||||
IteratorT const& first,
|
|
||||||
IteratorT const& last) const
|
|
||||||
{
|
|
||||||
attributed_action_policy<AttrT>::call(actor, val, first, last);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// scanner_policies class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <
|
|
||||||
typename IterationPolicyT,
|
|
||||||
typename MatchPolicyT,
|
|
||||||
typename ActionPolicyT>
|
|
||||||
struct scanner_policies :
|
|
||||||
public IterationPolicyT,
|
|
||||||
public MatchPolicyT,
|
|
||||||
public ActionPolicyT
|
|
||||||
{
|
|
||||||
typedef IterationPolicyT iteration_policy_t;
|
|
||||||
typedef MatchPolicyT match_policy_t;
|
|
||||||
typedef ActionPolicyT action_policy_t;
|
|
||||||
|
|
||||||
scanner_policies(
|
|
||||||
IterationPolicyT const& i_policy = IterationPolicyT(),
|
|
||||||
MatchPolicyT const& m_policy = MatchPolicyT(),
|
|
||||||
ActionPolicyT const& a_policy = ActionPolicyT())
|
|
||||||
: IterationPolicyT(i_policy)
|
|
||||||
, MatchPolicyT(m_policy)
|
|
||||||
, ActionPolicyT(a_policy) {}
|
|
||||||
|
|
||||||
template <typename ScannerPoliciesT>
|
|
||||||
scanner_policies(ScannerPoliciesT const& policies)
|
|
||||||
: IterationPolicyT(policies)
|
|
||||||
, MatchPolicyT(policies)
|
|
||||||
, ActionPolicyT(policies) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// scanner_policies_base class: the base class of all scanners
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct scanner_base {};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// scanner class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <
|
|
||||||
typename IteratorT,
|
|
||||||
typename PoliciesT>
|
|
||||||
class scanner : public PoliciesT, public scanner_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef IteratorT iterator_t;
|
|
||||||
typedef PoliciesT policies_t;
|
|
||||||
|
|
||||||
typedef typename boost::detail::
|
|
||||||
iterator_traits<IteratorT>::value_type value_t;
|
|
||||||
typedef typename boost::detail::
|
|
||||||
iterator_traits<IteratorT>::reference ref_t;
|
|
||||||
typedef typename boost::
|
|
||||||
call_traits<IteratorT>::param_type iter_param_t;
|
|
||||||
|
|
||||||
scanner(
|
|
||||||
IteratorT& first_,
|
|
||||||
iter_param_t last_,
|
|
||||||
PoliciesT const& policies = PoliciesT())
|
|
||||||
: PoliciesT(policies), first(first_), last(last_)
|
|
||||||
{
|
|
||||||
at_end();
|
|
||||||
}
|
|
||||||
|
|
||||||
scanner(scanner const& other)
|
|
||||||
: PoliciesT(other), first(other.first), last(other.last) {}
|
|
||||||
|
|
||||||
scanner(scanner const& other, IteratorT& first_)
|
|
||||||
: PoliciesT(other), first(first_), last(other.last) {}
|
|
||||||
|
|
||||||
bool
|
|
||||||
at_end() const
|
|
||||||
{
|
|
||||||
typedef typename PoliciesT::iteration_policy_t iteration_policy_t;
|
|
||||||
return iteration_policy_t::at_end(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
value_t
|
|
||||||
operator*() const
|
|
||||||
{
|
|
||||||
typedef typename PoliciesT::iteration_policy_t iteration_policy_t;
|
|
||||||
return iteration_policy_t::filter(iteration_policy_t::get(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
scanner const&
|
|
||||||
operator++() const
|
|
||||||
{
|
|
||||||
typedef typename PoliciesT::iteration_policy_t iteration_policy_t;
|
|
||||||
iteration_policy_t::advance(*this);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename PoliciesT2>
|
|
||||||
struct rebind_policies
|
|
||||||
{
|
|
||||||
typedef scanner<IteratorT, PoliciesT2> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename PoliciesT2>
|
|
||||||
scanner<IteratorT, PoliciesT2>
|
|
||||||
change_policies(PoliciesT2 const& policies) const
|
|
||||||
{
|
|
||||||
return scanner<IteratorT, PoliciesT2>(first, last, policies);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename IteratorT2>
|
|
||||||
struct rebind_iterator
|
|
||||||
{
|
|
||||||
typedef scanner<IteratorT2, PoliciesT> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename IteratorT2>
|
|
||||||
scanner<IteratorT2, PoliciesT>
|
|
||||||
change_iterator(IteratorT2 const& first_, IteratorT2 const &last_) const
|
|
||||||
{
|
|
||||||
return scanner<IteratorT2, PoliciesT>(first_, last_, *this);
|
|
||||||
}
|
|
||||||
|
|
||||||
IteratorT& first;
|
|
||||||
IteratorT const last;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
scanner&
|
|
||||||
operator=(scanner const& other);
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// rebind_scanner_policies class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ScannerT, typename PoliciesT>
|
|
||||||
struct rebind_scanner_policies
|
|
||||||
{
|
|
||||||
typedef typename ScannerT::template
|
|
||||||
rebind_policies<PoliciesT>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename ScannerT, typename IteratorT>
|
|
||||||
struct rebind_scanner_iterator
|
|
||||||
{
|
|
||||||
typedef typename ScannerT::template
|
|
||||||
rebind_iterator<IteratorT>::type type;
|
|
||||||
};
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,192 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_SKIPPER_HPP)
|
|
||||||
#define BOOST_SPIRIT_SKIPPER_HPP
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <cctype>
|
|
||||||
|
|
||||||
#include <boost/spirit/core/scanner/scanner.hpp>
|
|
||||||
#include <boost/spirit/core/primitives/impl/primitives.ipp>
|
|
||||||
|
|
||||||
#include <boost/spirit/core/scanner/skipper_fwd.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// skipper_iteration_policy class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
struct skipper_iteration_policy : public BaseT
|
|
||||||
{
|
|
||||||
typedef BaseT base_t;
|
|
||||||
|
|
||||||
skipper_iteration_policy()
|
|
||||||
: BaseT() {}
|
|
||||||
|
|
||||||
template <typename PolicyT>
|
|
||||||
skipper_iteration_policy(PolicyT const& other)
|
|
||||||
: BaseT(other) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
void
|
|
||||||
advance(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
BaseT::advance(scan);
|
|
||||||
scan.skip(scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
bool
|
|
||||||
at_end(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
scan.skip(scan);
|
|
||||||
return BaseT::at_end(scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
void
|
|
||||||
skip(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
while (!BaseT::at_end(scan) && impl::isspace_(BaseT::get(scan)))
|
|
||||||
BaseT::advance(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// no_skipper_iteration_policy class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
struct no_skipper_iteration_policy : public BaseT
|
|
||||||
{
|
|
||||||
typedef BaseT base_t;
|
|
||||||
|
|
||||||
no_skipper_iteration_policy()
|
|
||||||
: BaseT() {}
|
|
||||||
|
|
||||||
template <typename PolicyT>
|
|
||||||
no_skipper_iteration_policy(PolicyT const& other)
|
|
||||||
: BaseT(other) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
void
|
|
||||||
skip(ScannerT const& /*scan*/) const {}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// skip_parser_iteration_policy class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
template <typename ST, typename ScannerT, typename BaseT>
|
|
||||||
void
|
|
||||||
skipper_skip(
|
|
||||||
ST const& s,
|
|
||||||
ScannerT const& scan,
|
|
||||||
skipper_iteration_policy<BaseT> const&);
|
|
||||||
|
|
||||||
template <typename ST, typename ScannerT, typename BaseT>
|
|
||||||
void
|
|
||||||
skipper_skip(
|
|
||||||
ST const& s,
|
|
||||||
ScannerT const& scan,
|
|
||||||
no_skipper_iteration_policy<BaseT> const&);
|
|
||||||
|
|
||||||
template <typename ST, typename ScannerT>
|
|
||||||
void
|
|
||||||
skipper_skip(
|
|
||||||
ST const& s,
|
|
||||||
ScannerT const& scan,
|
|
||||||
iteration_policy const&);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ParserT, typename BaseT>
|
|
||||||
class skip_parser_iteration_policy : public skipper_iteration_policy<BaseT>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef skipper_iteration_policy<BaseT> base_t;
|
|
||||||
|
|
||||||
skip_parser_iteration_policy(
|
|
||||||
ParserT const& skip_parser,
|
|
||||||
base_t const& base = base_t())
|
|
||||||
: base_t(base), subject(skip_parser) {}
|
|
||||||
|
|
||||||
template <typename PolicyT>
|
|
||||||
skip_parser_iteration_policy(PolicyT const& other)
|
|
||||||
: base_t(other), subject(other.skipper()) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
void
|
|
||||||
skip(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
impl::skipper_skip(subject, scan, scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
ParserT const&
|
|
||||||
skipper() const
|
|
||||||
{
|
|
||||||
return subject;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
ParserT const& subject;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Free parse functions using the skippers
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename IteratorT, typename ParserT, typename SkipT>
|
|
||||||
parse_info<IteratorT>
|
|
||||||
parse(
|
|
||||||
IteratorT const& first,
|
|
||||||
IteratorT const& last,
|
|
||||||
parser<ParserT> const& p,
|
|
||||||
parser<SkipT> const& skip);
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Parse function for null terminated strings using the skippers
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename CharT, typename ParserT, typename SkipT>
|
|
||||||
parse_info<CharT const*>
|
|
||||||
parse(
|
|
||||||
CharT const* str,
|
|
||||||
parser<ParserT> const& p,
|
|
||||||
parser<SkipT> const& skip);
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// phrase_scanner_t and wide_phrase_scanner_t
|
|
||||||
//
|
|
||||||
// The most common scanners. Use these typedefs when you need
|
|
||||||
// a scanner that skips white spaces.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
typedef skipper_iteration_policy<> iter_policy_t;
|
|
||||||
typedef scanner_policies<iter_policy_t> scanner_policies_t;
|
|
||||||
typedef scanner<char const*, scanner_policies_t> phrase_scanner_t;
|
|
||||||
typedef scanner<wchar_t const*, scanner_policies_t> wide_phrase_scanner_t;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#include <boost/spirit/core/scanner/impl/skipper.ipp>
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,146 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2001-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_DEBUG_MAIN_HPP)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_MAIN_HPP
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
#if defined(BOOST_SPIRIT_DEBUG)
|
|
||||||
|
|
||||||
#include <boost/spirit/version.hpp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Spirit.Debug includes and defines
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// The BOOST_SPIRIT_DEBUG_OUT defines the stream object, which should be used
|
|
||||||
// for debug diagnostics. This defaults to std::cout.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_OUT)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_OUT std::cout
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// The BOOST_SPIRIT_DEBUG_PRINT_SOME constant defines the number of characters
|
|
||||||
// from the stream to be printed for diagnosis. This defaults to the first
|
|
||||||
// 20 characters.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_PRINT_SOME)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_PRINT_SOME 20
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Additional BOOST_SPIRIT_DEBUG_FLAGS control the level of diagnostics printed
|
|
||||||
// Basic constants are defined in debug/minimal.hpp.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
#define BOOST_SPIRIT_DEBUG_FLAGS_NODES 0x0001 // node diagnostics
|
|
||||||
#define BOOST_SPIRIT_DEBUG_FLAGS_ESCAPE_CHAR 0x0002 // escape_char_parse diagnostics
|
|
||||||
#define BOOST_SPIRIT_DEBUG_FLAGS_TREES 0x0004 // parse tree/ast diagnostics
|
|
||||||
#define BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES 0x0008 // closure diagnostics
|
|
||||||
#define BOOST_SPIRIT_DEBUG_FLAGS_SLEX 0x8000 // slex diagnostics
|
|
||||||
|
|
||||||
#define BOOST_SPIRIT_DEBUG_FLAGS_MAX 0xFFFF // print maximal diagnostics
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_FLAGS)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_FLAGS BOOST_SPIRIT_DEBUG_FLAGS_MAX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// By default all nodes are traced (even those, not registered with
|
|
||||||
// BOOST_SPIRIT_DEBUG_RULE et.al. - see below). The following constant may be
|
|
||||||
// used to redefine this default.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_TRACENODE)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_TRACENODE (true)
|
|
||||||
#endif // !defined(BOOST_SPIRIT_DEBUG_TRACENODE)
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Helper macros for giving rules and subrules a name accessible through
|
|
||||||
// parser_name() functions (see parser_names.hpp).
|
|
||||||
//
|
|
||||||
// Additionally, the macros BOOST_SPIRIT_DEBUG_RULE, SPIRIT_DEBUG_NODE and
|
|
||||||
// BOOST_SPIRIT_DEBUG_GRAMMAR enable/disable the tracing of the
|
|
||||||
// correspondingnode accordingly to the PP constant
|
|
||||||
// BOOST_SPIRIT_DEBUG_TRACENODE.
|
|
||||||
//
|
|
||||||
// The macros BOOST_SPIRIT_DEBUG_TRACE_RULE, BOOST_SPIRIT_DEBUG_TRACE_NODE
|
|
||||||
// and BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR allow to specify a flag to define,
|
|
||||||
// whether the corresponding node is to be traced or not.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_RULE)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_RULE(r) \
|
|
||||||
::boost::spirit::impl::get_node_registry().register_node(&r, #r, BOOST_SPIRIT_DEBUG_TRACENODE)
|
|
||||||
#endif // !defined(BOOST_SPIRIT_DEBUG_RULE)
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_NODE)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_NODE(r) \
|
|
||||||
::boost::spirit::impl::get_node_registry().register_node(&r, #r, BOOST_SPIRIT_DEBUG_TRACENODE)
|
|
||||||
#endif // !defined(BOOST_SPIRIT_DEBUG_NODE)
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_GRAMMAR)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_GRAMMAR(r) \
|
|
||||||
::boost::spirit::impl::get_node_registry().register_node(&r, #r, BOOST_SPIRIT_DEBUG_TRACENODE)
|
|
||||||
#endif // !defined(BOOST_SPIRIT_DEBUG_GRAMMAR)
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_RULE)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_TRACE_RULE(r, t) \
|
|
||||||
::boost::spirit::impl::get_node_registry().register_node(&r, #r, (t))
|
|
||||||
#endif // !defined(BOOST_SPIRIT_TRACE_RULE)
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_TRACE_NODE(r, t) \
|
|
||||||
::boost::spirit::impl::get_node_registry().register_node(&r, #r, (t))
|
|
||||||
#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE)
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR(r, t) \
|
|
||||||
::boost::spirit::impl::get_node_registry().register_node(&r, #r, (t))
|
|
||||||
#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR)
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME(r, n, t) \
|
|
||||||
::boost::spirit::impl::get_node_registry().register_node(&r, (n), (t))
|
|
||||||
#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME)
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME(r, n, t) \
|
|
||||||
::boost::spirit::impl::get_node_registry().register_node(&r, (n), (t))
|
|
||||||
#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME)
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(r, n, t) \
|
|
||||||
::boost::spirit::impl::get_node_registry().register_node(&r, (n), (t))
|
|
||||||
#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME)
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
#include <boost/spirit/debug/debug_node.hpp>
|
|
||||||
|
|
||||||
#else
|
|
||||||
//////////////////////////////////
|
|
||||||
#include <boost/spirit/debug/minimal.hpp>
|
|
||||||
|
|
||||||
#endif // BOOST_SPIRIT_DEBUG
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2001-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_MINIMAL_DEBUG_HPP)
|
|
||||||
#define BOOST_SPIRIT_MINIMAL_DEBUG_HPP
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_MAIN_HPP)
|
|
||||||
#error "You must include boost/spirit/debug.hpp, not boost/spirit/debug/minimal.hpp"
|
|
||||||
#endif
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Minimum debugging tools support
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_OUT)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_OUT std::cout
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// BOOST_SPIRIT_DEBUG_FLAGS controls the level of diagnostics printed
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_FLAGS_NONE)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_FLAGS_NONE 0x0000 // no diagnostics at all
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_FLAGS_MAX)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_FLAGS_MAX 0xFFFF // print maximal diagnostics
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_FLAGS)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_FLAGS SPIRIT_DEBUG_FLAGS_MAX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_PRINT_SOME)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_PRINT_SOME 20
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_RULE)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_RULE(r)
|
|
||||||
#endif // !defined(BOOST_SPIRIT_DEBUG_RULE)
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_NODE)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_NODE(r)
|
|
||||||
#endif // !defined(BOOST_SPIRIT_DEBUG_NODE)
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_GRAMMAR)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_GRAMMAR(r)
|
|
||||||
#endif // !defined(BOOST_SPIRIT_DEBUG_GRAMMAR)
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_RULE)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_TRACE_RULE(r, t)
|
|
||||||
#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_RULE)
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_TRACE_NODE(r, t)
|
|
||||||
#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE)
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR(r, t)
|
|
||||||
#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR)
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME(r, n, t)
|
|
||||||
#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME)
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME(r, n, t)
|
|
||||||
#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME)
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME)
|
|
||||||
#define BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(r, n, t)
|
|
||||||
#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME)
|
|
||||||
|
|
||||||
#endif // !defined(BOOST_SPIRIT_MINIMAL_DEBUG_HPP)
|
|
@ -1,225 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2002-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2002 Juan Carlos Arevalo-Baeza
|
|
||||||
Copyright (c) 2002-2003 Martin Wille
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_IF_HPP
|
|
||||||
#define BOOST_SPIRIT_IF_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
#include <boost/spirit/dynamic/impl/conditions.ipp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
// if-else-parser, holds two alternative parsers and a conditional functor
|
|
||||||
// that selects between them.
|
|
||||||
template <typename ParsableTrueT, typename ParsableFalseT, typename CondT>
|
|
||||||
struct if_else_parser
|
|
||||||
: public condition_evaluator<typename as_parser<CondT>::type>
|
|
||||||
, public binary
|
|
||||||
<
|
|
||||||
typename as_parser<ParsableTrueT>::type,
|
|
||||||
typename as_parser<ParsableFalseT>::type,
|
|
||||||
parser< if_else_parser<ParsableTrueT, ParsableFalseT, CondT> >
|
|
||||||
>
|
|
||||||
{
|
|
||||||
typedef if_else_parser<ParsableTrueT, ParsableFalseT, CondT> self_t;
|
|
||||||
|
|
||||||
typedef as_parser<ParsableTrueT> as_parser_true_t;
|
|
||||||
typedef as_parser<ParsableFalseT> as_parser_false_t;
|
|
||||||
typedef typename as_parser_true_t::type parser_true_t;
|
|
||||||
typedef typename as_parser_false_t::type parser_false_t;
|
|
||||||
typedef as_parser<CondT> cond_as_parser_t;
|
|
||||||
typedef typename cond_as_parser_t::type condition_t;
|
|
||||||
|
|
||||||
typedef binary<parser_true_t, parser_false_t, parser<self_t> > base_t;
|
|
||||||
typedef condition_evaluator<condition_t> eval_t;
|
|
||||||
|
|
||||||
if_else_parser
|
|
||||||
(
|
|
||||||
ParsableTrueT const& p_true,
|
|
||||||
ParsableFalseT const& p_false,
|
|
||||||
CondT const& cond_
|
|
||||||
)
|
|
||||||
: eval_t(cond_as_parser_t::convert(cond_))
|
|
||||||
, base_t
|
|
||||||
(
|
|
||||||
as_parser_true_t::convert(p_true),
|
|
||||||
as_parser_false_t::convert(p_false)
|
|
||||||
)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename match_result<ScannerT, nil_t>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result
|
|
||||||
<parser_true_t, ScannerT>::type then_result_t;
|
|
||||||
typedef typename parser_result
|
|
||||||
<parser_false_t, ScannerT>::type else_result_t;
|
|
||||||
|
|
||||||
typename ScannerT::iterator_t const save(scan.first);
|
|
||||||
|
|
||||||
std::ptrdiff_t length = this->evaluate(scan);
|
|
||||||
if (length >= 0)
|
|
||||||
{
|
|
||||||
then_result_t then_result(this->left().parse(scan));
|
|
||||||
if (then_result)
|
|
||||||
{
|
|
||||||
length += then_result.length();
|
|
||||||
return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
else_result_t else_result(this->right().parse(scan));
|
|
||||||
if (else_result)
|
|
||||||
{
|
|
||||||
length = else_result.length();
|
|
||||||
return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
// if-else-parser generator, takes the false-parser in brackets
|
|
||||||
// and returns the if-else-parser.
|
|
||||||
template <typename ParsableTrueT, typename CondT>
|
|
||||||
struct if_else_parser_gen
|
|
||||||
{
|
|
||||||
if_else_parser_gen(ParsableTrueT const& p_true_, CondT const& cond_)
|
|
||||||
: p_true(p_true_)
|
|
||||||
, cond(cond_) {}
|
|
||||||
|
|
||||||
template <typename ParsableFalseT>
|
|
||||||
if_else_parser
|
|
||||||
<
|
|
||||||
ParsableTrueT,
|
|
||||||
ParsableFalseT,
|
|
||||||
CondT
|
|
||||||
>
|
|
||||||
operator[](ParsableFalseT const& p_false) const
|
|
||||||
{
|
|
||||||
return if_else_parser<ParsableTrueT, ParsableFalseT, CondT>
|
|
||||||
(
|
|
||||||
p_true,
|
|
||||||
p_false,
|
|
||||||
cond
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ParsableTrueT const &p_true;
|
|
||||||
CondT const &cond;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
// if-parser, conditionally runs a parser is a functor condition is true.
|
|
||||||
// If the condition is fales, it fails the parse.
|
|
||||||
// It can optionally become an if-else-parser through the member else_p.
|
|
||||||
template <typename ParsableT, typename CondT>
|
|
||||||
struct if_parser
|
|
||||||
: public condition_evaluator<typename as_parser<CondT>::type>
|
|
||||||
, public unary
|
|
||||||
<
|
|
||||||
typename as_parser<ParsableT>::type,
|
|
||||||
parser<if_parser<ParsableT, CondT> > >
|
|
||||||
{
|
|
||||||
typedef if_parser<ParsableT, CondT> self_t;
|
|
||||||
typedef as_parser<ParsableT> as_parser_t;
|
|
||||||
typedef typename as_parser_t::type parser_t;
|
|
||||||
|
|
||||||
typedef as_parser<CondT> cond_as_parser_t;
|
|
||||||
typedef typename cond_as_parser_t::type condition_t;
|
|
||||||
typedef condition_evaluator<condition_t> eval_t;
|
|
||||||
typedef unary<parser_t, parser<self_t> > base_t;
|
|
||||||
|
|
||||||
if_parser(ParsableT const& p, CondT const& cond_)
|
|
||||||
: eval_t(cond_as_parser_t::convert(cond_))
|
|
||||||
, base_t(as_parser_t::convert(p))
|
|
||||||
, else_p(p, cond_)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename match_result<ScannerT, nil_t>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<parser_t, ScannerT>::type t_result_t;
|
|
||||||
typename ScannerT::iterator_t const save(scan.first);
|
|
||||||
|
|
||||||
std::ptrdiff_t length = this->evaluate(scan);
|
|
||||||
if (length >= 0)
|
|
||||||
{
|
|
||||||
t_result_t then_result(this->subject().parse(scan));
|
|
||||||
if (then_result)
|
|
||||||
{
|
|
||||||
length += then_result.length();
|
|
||||||
return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
|
|
||||||
}
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
return scan.empty_match();
|
|
||||||
}
|
|
||||||
|
|
||||||
if_else_parser_gen<ParsableT, CondT> else_p;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
// if-parser generator, takes the true-parser in brackets and returns the
|
|
||||||
// if-parser.
|
|
||||||
template <typename CondT>
|
|
||||||
struct if_parser_gen
|
|
||||||
{
|
|
||||||
if_parser_gen(CondT const& cond_) : cond(cond_) {}
|
|
||||||
|
|
||||||
template <typename ParsableT>
|
|
||||||
if_parser
|
|
||||||
<
|
|
||||||
ParsableT,
|
|
||||||
CondT
|
|
||||||
>
|
|
||||||
operator[](ParsableT const& subject) const
|
|
||||||
{
|
|
||||||
return if_parser<ParsableT, CondT>(subject, cond);
|
|
||||||
}
|
|
||||||
|
|
||||||
CondT const &cond;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace impl
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
// if_p function, returns "if" parser generator
|
|
||||||
|
|
||||||
template <typename CondT>
|
|
||||||
impl::if_parser_gen<CondT>
|
|
||||||
if_p(CondT const& cond)
|
|
||||||
{
|
|
||||||
return impl::if_parser_gen<CondT>(cond);
|
|
||||||
}
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif // BOOST_SPIRIT_IF_HPP
|
|
@ -1,100 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2002-2003 Martin Wille
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_CONDITIONS_IPP
|
|
||||||
#define BOOST_SPIRIT_CONDITIONS_IPP
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <boost/spirit/meta/parser_traits.hpp>
|
|
||||||
#include <boost/spirit/core/composite/epsilon.hpp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// condition evaluation
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//////////////////////////////////
|
|
||||||
// condition_parser_selector, decides which parser to use for a condition
|
|
||||||
// If the template argument is a parser then that parser is used.
|
|
||||||
// If the template argument is a functor then a condition parser using
|
|
||||||
// the functor is chosen
|
|
||||||
|
|
||||||
template <typename T> struct embed_t_accessor
|
|
||||||
{
|
|
||||||
typedef typename T::embed_t type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
|
|
||||||
template <> struct embed_t_accessor<int>
|
|
||||||
{
|
|
||||||
typedef int type;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename ConditionT>
|
|
||||||
struct condition_parser_selector
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
typename mpl::if_<
|
|
||||||
is_parser<ConditionT>,
|
|
||||||
ConditionT,
|
|
||||||
condition_parser<ConditionT>
|
|
||||||
>::type
|
|
||||||
type;
|
|
||||||
|
|
||||||
typedef typename embed_t_accessor<type>::type embed_t;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
// condition_evaluator, uses a parser to check wether a condition is met
|
|
||||||
// takes a parser or a functor that can be evaluated in boolean context
|
|
||||||
// as template parameter.
|
|
||||||
|
|
||||||
// JDG 4-15-03 refactored
|
|
||||||
template <typename ConditionT>
|
|
||||||
struct condition_evaluator
|
|
||||||
{
|
|
||||||
typedef condition_parser_selector<ConditionT> selector_t;
|
|
||||||
typedef typename selector_t::type selected_t;
|
|
||||||
typedef typename selector_t::embed_t cond_embed_t;
|
|
||||||
|
|
||||||
typedef typename boost::call_traits<cond_embed_t>::param_type
|
|
||||||
param_t;
|
|
||||||
|
|
||||||
condition_evaluator(param_t s) : cond(s) {}
|
|
||||||
|
|
||||||
/////////////////////////////
|
|
||||||
// evaluate, checks wether condition is met
|
|
||||||
// returns length of a match or a negative number for no-match
|
|
||||||
template <typename ScannerT>
|
|
||||||
std::ptrdiff_t
|
|
||||||
evaluate(ScannerT const &scan) const
|
|
||||||
{
|
|
||||||
typedef typename ScannerT::iterator_t iterator_t;
|
|
||||||
typedef typename parser_result<selected_t, ScannerT>::type cres_t;
|
|
||||||
iterator_t save(scan.first);
|
|
||||||
cres_t result = cond.parse(scan);
|
|
||||||
if (!result) // reset the position if evaluation
|
|
||||||
scan.first = save; // fails.
|
|
||||||
return result.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
cond_embed_t cond;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
} // namespace impl
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,22 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2001-2003 Joel de Guzman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_ERROR_HANDLING_MAIN_HPP)
|
|
||||||
#define BOOST_SPIRIT_ERROR_HANDLING_MAIN_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/version.hpp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Master header for Spirit.ErrorHandling
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include <boost/spirit/error_handling/exceptions.hpp>
|
|
||||||
|
|
||||||
#endif // !defined(BOOST_SPIRIT_ERROR_HANDLING_MAIN_HPP)
|
|
@ -1,361 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2001-2003 Joel de Guzman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_EXCEPTIONS_HPP
|
|
||||||
#define BOOST_SPIRIT_EXCEPTIONS_HPP
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <boost/throw_exception.hpp>
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
#include <exception>
|
|
||||||
|
|
||||||
#include <boost/spirit/error_handling/exceptions_fwd.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// parser_error_base class
|
|
||||||
//
|
|
||||||
// This is the base class of parser_error (see below). This may be
|
|
||||||
// used to catch any type of parser error.
|
|
||||||
//
|
|
||||||
// This exception shouldn't propagate outside the parser. However to
|
|
||||||
// avoid quirks of many platforms/implementations which fall outside
|
|
||||||
// the C++ standard, we derive parser_error_base from std::exception
|
|
||||||
// to allow a single catch handler to catch all exceptions.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
class parser_error_base : public std::exception
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
|
|
||||||
parser_error_base() {}
|
|
||||||
virtual ~parser_error_base() throw() {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
parser_error_base(parser_error_base const& rhs)
|
|
||||||
: std::exception(rhs) {}
|
|
||||||
parser_error_base& operator=(parser_error_base const&)
|
|
||||||
{
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// parser_error class
|
|
||||||
//
|
|
||||||
// Generic parser exception class. This is the base class for all
|
|
||||||
// parser exceptions. The exception holds the iterator position
|
|
||||||
// where the error was encountered in its member variable "where".
|
|
||||||
// The parser_error also holds information regarding the error
|
|
||||||
// (error descriptor) in its member variable "descriptor".
|
|
||||||
//
|
|
||||||
// The throw_ function creates and throws a parser_error given
|
|
||||||
// an iterator and an error descriptor.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ErrorDescrT, typename IteratorT>
|
|
||||||
struct parser_error : public parser_error_base
|
|
||||||
{
|
|
||||||
typedef ErrorDescrT error_descr_t;
|
|
||||||
typedef IteratorT iterator_t;
|
|
||||||
|
|
||||||
parser_error(IteratorT where_, ErrorDescrT descriptor_)
|
|
||||||
: where(where_), descriptor(descriptor_) {}
|
|
||||||
|
|
||||||
parser_error(parser_error const& rhs)
|
|
||||||
: parser_error_base(rhs)
|
|
||||||
, where(rhs.where), descriptor(rhs.descriptor) {}
|
|
||||||
|
|
||||||
parser_error&
|
|
||||||
operator=(parser_error const& rhs)
|
|
||||||
{
|
|
||||||
where = rhs.where;
|
|
||||||
descriptor = rhs.descriptor;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual
|
|
||||||
~parser_error() throw() {}
|
|
||||||
|
|
||||||
virtual const char*
|
|
||||||
what() const throw()
|
|
||||||
{
|
|
||||||
return "boost::spirit::parser_error";
|
|
||||||
}
|
|
||||||
|
|
||||||
IteratorT where;
|
|
||||||
ErrorDescrT descriptor;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename ErrorDescrT, typename IteratorT>
|
|
||||||
inline void
|
|
||||||
throw_(IteratorT where, ErrorDescrT descriptor)
|
|
||||||
{
|
|
||||||
boost::throw_exception(
|
|
||||||
parser_error<ErrorDescrT, IteratorT>(where, descriptor));
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// assertive_parser class
|
|
||||||
//
|
|
||||||
// An assertive_parser class is a parser that throws an exception
|
|
||||||
// in response to a parsing failure. The assertive_parser throws a
|
|
||||||
// parser_error exception rather than returning an unsuccessful
|
|
||||||
// match to signal that the parser failed to match the input.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ErrorDescrT, typename ParserT>
|
|
||||||
struct assertive_parser
|
|
||||||
: public unary<ParserT, parser<assertive_parser<ErrorDescrT, ParserT> > >
|
|
||||||
{
|
|
||||||
typedef assertive_parser<ErrorDescrT, ParserT> self_t;
|
|
||||||
typedef unary<ParserT, parser<self_t> > base_t;
|
|
||||||
typedef unary_parser_category parser_category_t;
|
|
||||||
|
|
||||||
assertive_parser(ParserT const& parser, ErrorDescrT descriptor)
|
|
||||||
: base_t(parser), descriptor(descriptor) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename parser_result<ParserT, ScannerT>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<ParserT, ScannerT>::type result_t;
|
|
||||||
typedef typename ScannerT::iterator_t iterator_t;
|
|
||||||
|
|
||||||
result_t hit = this->subject().parse(scan);
|
|
||||||
if (!hit)
|
|
||||||
{
|
|
||||||
throw_(scan.first, descriptor);
|
|
||||||
}
|
|
||||||
return hit;
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorDescrT descriptor;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// assertion class
|
|
||||||
//
|
|
||||||
// assertive_parsers are never instantiated directly. The assertion
|
|
||||||
// class is used to indirectly create an assertive_parser object.
|
|
||||||
// Before declaring the grammar, we declare some assertion objects.
|
|
||||||
// Examples:
|
|
||||||
//
|
|
||||||
// enum Errors
|
|
||||||
// {
|
|
||||||
// program_expected, begin_expected, end_expected
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// assertion<Errors> expect_program(program_expected);
|
|
||||||
// assertion<Errors> expect_begin(begin_expected);
|
|
||||||
// assertion<Errors> expect_end(end_expected);
|
|
||||||
//
|
|
||||||
// Now, we can use these assertions as wrappers around parsers:
|
|
||||||
//
|
|
||||||
// expect_end(str_p("end"))
|
|
||||||
//
|
|
||||||
// Take note that although the example uses enums to hold the
|
|
||||||
// information regarding the error (error desccriptor), we are free
|
|
||||||
// to use other types such as integers and strings. Enums are
|
|
||||||
// convenient for error handlers to easily catch since C++ treats
|
|
||||||
// enums as unique types.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ErrorDescrT>
|
|
||||||
struct assertion
|
|
||||||
{
|
|
||||||
assertion(ErrorDescrT descriptor_)
|
|
||||||
: descriptor(descriptor_) {}
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
assertive_parser<ErrorDescrT, ParserT>
|
|
||||||
operator()(ParserT const& parser) const
|
|
||||||
{
|
|
||||||
return assertive_parser<ErrorDescrT, ParserT>(parser, descriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorDescrT descriptor;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// error_status<T>
|
|
||||||
//
|
|
||||||
// Where T is an attribute type compatible with the match attribute
|
|
||||||
// of the fallback_parser's subject (defaults to nil_t). The class
|
|
||||||
// error_status reports the result of an error handler (see
|
|
||||||
// fallback_parser). result can be one of:
|
|
||||||
//
|
|
||||||
// fail: quit and fail (return a no_match)
|
|
||||||
// retry: attempt error recovery, possibly moving the scanner
|
|
||||||
// accept: force success returning a matching length, moving
|
|
||||||
// the scanner appropriately and returning an attribute
|
|
||||||
// value
|
|
||||||
// rethrow: rethrows the error.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
struct error_status
|
|
||||||
{
|
|
||||||
enum result_t { fail, retry, accept, rethrow };
|
|
||||||
|
|
||||||
error_status(
|
|
||||||
result_t result_ = fail,
|
|
||||||
std::ptrdiff_t length = -1,
|
|
||||||
T const& value_ = T())
|
|
||||||
: result(result_), length(length), value(value_) {}
|
|
||||||
|
|
||||||
result_t result;
|
|
||||||
std::ptrdiff_t length;
|
|
||||||
T value;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// fallback_parser class
|
|
||||||
//
|
|
||||||
// Handles exceptions of type parser_error<ErrorDescrT, IteratorT>
|
|
||||||
// thrown somewhere inside its embedded ParserT object. The class
|
|
||||||
// sets up a try block before delegating parsing to its subject.
|
|
||||||
// When an exception is caught, the catch block then calls the
|
|
||||||
// HandlerT object. HandlerT may be a function or a functor (with
|
|
||||||
// an operator() member function) compatible with the interface:
|
|
||||||
//
|
|
||||||
// error_status<T>
|
|
||||||
// handler(ScannerT const& scan, ErrorT error);
|
|
||||||
//
|
|
||||||
// Where scan points to the scanner state prior to parsing and error
|
|
||||||
// is the error that arose (see parser_error). The handler must
|
|
||||||
// return an error_status<T> object (see above).
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
template <typename RT, typename ParserT, typename ScannerT>
|
|
||||||
RT fallback_parser_parse(ParserT const& p, ScannerT const& scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ErrorDescrT, typename ParserT, typename HandlerT>
|
|
||||||
struct fallback_parser
|
|
||||||
: public unary<ParserT,
|
|
||||||
parser<fallback_parser<ErrorDescrT, ParserT, HandlerT> > >
|
|
||||||
{
|
|
||||||
typedef fallback_parser<ErrorDescrT, ParserT, HandlerT>
|
|
||||||
self_t;
|
|
||||||
typedef ErrorDescrT
|
|
||||||
error_descr_t;
|
|
||||||
typedef unary<ParserT, parser<self_t> >
|
|
||||||
base_t;
|
|
||||||
typedef unary_parser_category
|
|
||||||
parser_category_t;
|
|
||||||
|
|
||||||
fallback_parser(ParserT const& parser, HandlerT const& handler_)
|
|
||||||
: base_t(parser), handler(handler_) {}
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename parser_result<ParserT, ScannerT>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
|
||||||
return impl::fallback_parser_parse<result_t>(*this, scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
HandlerT handler;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// guard class
|
|
||||||
//
|
|
||||||
// fallback_parser objects are not instantiated directly. The guard
|
|
||||||
// class is used to indirectly create a fallback_parser object.
|
|
||||||
// guards are typically predeclared just like assertions (see the
|
|
||||||
// assertion class above; the example extends the previous example
|
|
||||||
// introduced in the assertion class above):
|
|
||||||
//
|
|
||||||
// guard<Errors> my_guard;
|
|
||||||
//
|
|
||||||
// Errors, in this example is the error descriptor type we want to
|
|
||||||
// detect; This is essentially the ErrorDescrT template parameter
|
|
||||||
// of the fallback_parser class.
|
|
||||||
//
|
|
||||||
// my_guard may now be used in a grammar declaration as:
|
|
||||||
//
|
|
||||||
// my_guard(p)[h]
|
|
||||||
//
|
|
||||||
// where p is a parser, h is a function or functor compatible with
|
|
||||||
// fallback_parser's HandlerT (see above).
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ErrorDescrT, typename ParserT>
|
|
||||||
struct guard_gen : public unary<ParserT, nil_t>
|
|
||||||
{
|
|
||||||
typedef guard<ErrorDescrT> parser_generator_t;
|
|
||||||
typedef unary_parser_category parser_category_t;
|
|
||||||
|
|
||||||
guard_gen(ParserT const& p)
|
|
||||||
: unary<ParserT, nil_t>(p) {}
|
|
||||||
|
|
||||||
template <typename HandlerT>
|
|
||||||
fallback_parser<ErrorDescrT, ParserT, HandlerT>
|
|
||||||
operator[](HandlerT const& handler) const
|
|
||||||
{
|
|
||||||
return fallback_parser<ErrorDescrT, ParserT, HandlerT>
|
|
||||||
(this->subject(), handler);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ErrorDescrT>
|
|
||||||
struct guard
|
|
||||||
{
|
|
||||||
template <typename ParserT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef guard_gen<ErrorDescrT, ParserT> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
static guard_gen<ErrorDescrT, ParserT>
|
|
||||||
generate(ParserT const& parser)
|
|
||||||
{
|
|
||||||
return guard_gen<ErrorDescrT, ParserT>(parser);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
guard_gen<ErrorDescrT, ParserT>
|
|
||||||
operator()(ParserT const& parser) const
|
|
||||||
{
|
|
||||||
return guard_gen<ErrorDescrT, ParserT>(parser);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#include <boost/spirit/error_handling/impl/exceptions.ipp>
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,85 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2001-2003 Joel de Guzman
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_EXCEPTIONS_IPP
|
|
||||||
#define BOOST_SPIRIT_EXCEPTIONS_IPP
|
|
||||||
|
|
||||||
namespace boost { namespace spirit { namespace impl {
|
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
template <typename ParserT, typename ScannerT>
|
|
||||||
typename parser_result<ParserT, ScannerT>::type
|
|
||||||
fallback_parser_helper(ParserT const& subject, ScannerT const& scan);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename RT, typename ParserT, typename ScannerT>
|
|
||||||
RT fallback_parser_parse(ParserT const& p, ScannerT const& scan)
|
|
||||||
{
|
|
||||||
typedef typename ScannerT::iterator_t iterator_t;
|
|
||||||
typedef typename RT::attr_t attr_t;
|
|
||||||
typedef error_status<attr_t> error_status_t;
|
|
||||||
typedef typename ParserT::error_descr_t error_descr_t;
|
|
||||||
|
|
||||||
iterator_t save = scan.first;
|
|
||||||
error_status_t hr(error_status_t::retry);
|
|
||||||
|
|
||||||
while (hr.result == error_status_t::retry)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
#ifndef __BORLANDC__
|
|
||||||
return p.subject().parse(scan);
|
|
||||||
#else
|
|
||||||
return impl::fallback_parser_helper(p, scan);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
catch (parser_error<error_descr_t, iterator_t>& error)
|
|
||||||
{
|
|
||||||
scan.first = save;
|
|
||||||
hr = p.handler(scan, error);
|
|
||||||
switch (hr.result)
|
|
||||||
{
|
|
||||||
case error_status_t::fail:
|
|
||||||
return scan.no_match();
|
|
||||||
case error_status_t::accept:
|
|
||||||
return scan.create_match
|
|
||||||
(std::size_t(hr.length), hr.value, save, scan.first);
|
|
||||||
case error_status_t::rethrow:
|
|
||||||
boost::throw_exception(error);
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return scan.no_match();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Borland does not like calling the subject directly in the try block.
|
|
||||||
// Removing the #ifdef __BORLANDC__ code makes Borland complain that
|
|
||||||
// some variables and types cannot be found in the catch block. Weird!
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
|
|
||||||
template <typename ParserT, typename ScannerT>
|
|
||||||
typename parser_result<ParserT, ScannerT>::type
|
|
||||||
fallback_parser_helper(ParserT const& p, ScannerT const& scan)
|
|
||||||
{
|
|
||||||
return p.subject().parse(scan);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}}} // namespace boost::spirit::impl
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2001-2003 Daniel Nuffer
|
|
||||||
Copyright (c) 2003 Giovanni Bajo
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_ITERATOR_MAIN_HPP)
|
|
||||||
#define BOOST_SPIRIT_ITERATOR_MAIN_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/version.hpp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Master header for Spirit.Iterators
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include <boost/spirit/iterator/file_iterator.hpp>
|
|
||||||
#include <boost/spirit/iterator/fixed_size_queue.hpp>
|
|
||||||
#include <boost/spirit/iterator/position_iterator.hpp>
|
|
||||||
#include <boost/spirit/iterator/multi_pass.hpp>
|
|
||||||
|
|
||||||
#endif // !defined(BOOST_SPIRIT_ITERATOR_MAIN_HPP)
|
|
@ -1,225 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2003 Giovanni Bajo
|
|
||||||
Copyright (c) 2003 Thomas Witt
|
|
||||||
Copyright (c) 2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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)
|
|
||||||
=============================================================================*/
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// File Iterator structure
|
|
||||||
//
|
|
||||||
// The new structure is designed on layers. The top class (used by the user)
|
|
||||||
// is file_iterator, which implements a full random access iterator through
|
|
||||||
// the file, and some specific member functions (constructor that opens
|
|
||||||
// the file, make_end() to generate the end iterator, operator bool to check
|
|
||||||
// if the file was opened correctly).
|
|
||||||
//
|
|
||||||
// file_iterator implements the random access iterator interface by the means
|
|
||||||
// of boost::iterator_adaptor, that is inhering an object created with it.
|
|
||||||
// iterator_adaptor gets a low-level file iterator implementation (with just
|
|
||||||
// a few member functions) and a policy (that basically describes to it how
|
|
||||||
// the low-level file iterator interface is). The advantage is that
|
|
||||||
// with boost::iterator_adaptor only 5 functions are needed to implement
|
|
||||||
// a fully conformant random access iterator, instead of dozens of functions
|
|
||||||
// and operators.
|
|
||||||
//
|
|
||||||
// There are two low-level file iterators implemented in this module. The
|
|
||||||
// first (std_file_iterator) uses cstdio stream functions (fopen/fread), which
|
|
||||||
// support full buffering, and is available everywhere (it's standard C++).
|
|
||||||
// The second (mmap_file_iterator) is currently available only on Windows
|
|
||||||
// platforms, and uses memory mapped files, which gives a decent speed boost.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TODO LIST:
|
|
||||||
//
|
|
||||||
// - In the Win32 mmap iterator, we could check if keeping a handle to the
|
|
||||||
// opened file is really required. If it's not, we can just store the file
|
|
||||||
// length (for make_end()) and save performance. Notice that this should be
|
|
||||||
// tested under different Windows versions, the behaviour might change.
|
|
||||||
// - Add some error support (by the means of some exceptions) in case of
|
|
||||||
// low-level I/O failure.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef BOOST_SPIRIT_FILE_ITERATOR_HPP
|
|
||||||
#define BOOST_SPIRIT_FILE_ITERATOR_HPP
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <boost/iterator_adaptors.hpp>
|
|
||||||
#include <boost/spirit/core/safe_bool.hpp>
|
|
||||||
|
|
||||||
#include <boost/spirit/iterator/file_iterator_fwd.hpp>
|
|
||||||
|
|
||||||
#if !defined(BOOST_SPIRIT_FILEITERATOR_STD)
|
|
||||||
# if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) \
|
|
||||||
&& !defined(BOOST_DISABLE_WIN32)
|
|
||||||
# define BOOST_SPIRIT_FILEITERATOR_WINDOWS
|
|
||||||
# elif defined(BOOST_HAS_UNISTD_H)
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
# include <unistd.h>
|
|
||||||
}
|
|
||||||
# ifdef _POSIX_MAPPED_FILES
|
|
||||||
# define BOOST_SPIRIT_FILEITERATOR_POSIX
|
|
||||||
# endif // _POSIX_MAPPED_FILES
|
|
||||||
# endif // BOOST_HAS_UNISTD_H
|
|
||||||
|
|
||||||
# if !defined(BOOST_SPIRIT_FILEITERATOR_WINDOWS) && \
|
|
||||||
!defined(BOOST_SPIRIT_FILEITERATOR_POSIX)
|
|
||||||
# define BOOST_SPIRIT_FILEITERATOR_STD
|
|
||||||
# endif
|
|
||||||
#endif // BOOST_SPIRIT_FILEITERATOR_STD
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename CharT = char,
|
|
||||||
typename BaseIterator =
|
|
||||||
#ifdef BOOST_SPIRIT_FILEITERATOR_STD
|
|
||||||
fileiter_impl::std_file_iterator<CharT>
|
|
||||||
#else
|
|
||||||
fileiter_impl::mmap_file_iterator<CharT>
|
|
||||||
#endif
|
|
||||||
> class file_iterator;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace fileiter_impl {
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// file_iter_generator
|
|
||||||
//
|
|
||||||
// Template meta-function to invoke boost::iterator_adaptor
|
|
||||||
// NOTE: This cannot be moved into the implementation file because of
|
|
||||||
// a bug of MSVC 7.0 and previous versions (base classes types are
|
|
||||||
// looked up at compilation time, not instantion types, and
|
|
||||||
// file_iterator would break).
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \
|
|
||||||
BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
|
|
||||||
#error "Please use at least Boost V1.31.0 while compiling the file_iterator class!"
|
|
||||||
#else // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
|
|
||||||
|
|
||||||
template <typename CharT, typename BaseIteratorT>
|
|
||||||
struct file_iter_generator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef BaseIteratorT adapted_t;
|
|
||||||
typedef typename adapted_t::value_type value_type;
|
|
||||||
|
|
||||||
typedef boost::iterator_adaptor <
|
|
||||||
file_iterator<CharT, BaseIteratorT>,
|
|
||||||
adapted_t,
|
|
||||||
value_type const,
|
|
||||||
std::random_access_iterator_tag,
|
|
||||||
boost::use_default,
|
|
||||||
std::ptrdiff_t
|
|
||||||
> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
} /* namespace impl */
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// file_iterator
|
|
||||||
//
|
|
||||||
// Iterates through an opened file.
|
|
||||||
//
|
|
||||||
// The main iterator interface is implemented by the iterator_adaptors
|
|
||||||
// library, which wraps a conforming iterator interface around the
|
|
||||||
// impl::BaseIterator class. This class merely derives the iterator_adaptors
|
|
||||||
// generated class to implement the custom constructors and make_end()
|
|
||||||
// member function.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template<typename CharT, typename BaseIteratorT>
|
|
||||||
class file_iterator
|
|
||||||
: public fileiter_impl::file_iter_generator<CharT, BaseIteratorT>::type,
|
|
||||||
public safe_bool<file_iterator<CharT, BaseIteratorT> >
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef typename
|
|
||||||
fileiter_impl::file_iter_generator<CharT, BaseIteratorT>::type
|
|
||||||
base_t;
|
|
||||||
typedef typename
|
|
||||||
fileiter_impl::file_iter_generator<CharT, BaseIteratorT>::adapted_t
|
|
||||||
adapted_t;
|
|
||||||
|
|
||||||
public:
|
|
||||||
file_iterator()
|
|
||||||
{}
|
|
||||||
|
|
||||||
file_iterator(std::string fileName)
|
|
||||||
: base_t(adapted_t(fileName))
|
|
||||||
{}
|
|
||||||
|
|
||||||
file_iterator(const base_t& iter)
|
|
||||||
: base_t(iter)
|
|
||||||
{}
|
|
||||||
|
|
||||||
inline file_iterator& operator=(const base_t& iter);
|
|
||||||
file_iterator make_end(void);
|
|
||||||
|
|
||||||
// operator bool. This borrows a trick from boost::shared_ptr to avoid
|
|
||||||
// to interfere with arithmetic operations.
|
|
||||||
bool operator_bool(void) const
|
|
||||||
{ return this->base(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class ::boost::iterator_core_access;
|
|
||||||
|
|
||||||
typename base_t::reference dereference() const
|
|
||||||
{
|
|
||||||
return this->base_reference().get_cur_char();
|
|
||||||
}
|
|
||||||
|
|
||||||
void increment()
|
|
||||||
{
|
|
||||||
this->base_reference().next_char();
|
|
||||||
}
|
|
||||||
|
|
||||||
void decrement()
|
|
||||||
{
|
|
||||||
this->base_reference().prev_char();
|
|
||||||
}
|
|
||||||
|
|
||||||
void advance(typename base_t::difference_type n)
|
|
||||||
{
|
|
||||||
this->base_reference().advance(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename OtherDerivedT, typename OtherIteratorT,
|
|
||||||
typename V, typename C, typename R, typename D
|
|
||||||
>
|
|
||||||
typename base_t::difference_type distance_to(
|
|
||||||
iterator_adaptor<OtherDerivedT, OtherIteratorT, V, C, R, D>
|
|
||||||
const &x) const
|
|
||||||
{
|
|
||||||
return x.base().distance(this->base_reference());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
}} /* namespace boost::spirit */
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <boost/spirit/iterator/impl/file_iterator.ipp> /* implementation */
|
|
||||||
|
|
||||||
#endif /* BOOST_SPIRIT_FILE_ITERATOR_HPP */
|
|
||||||
|
|
@ -1,398 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2001, Daniel C. Nuffer
|
|
||||||
Copyright (c) 2003, Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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 FIXED_SIZE_QUEUE
|
|
||||||
#define FIXED_SIZE_QUEUE
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <iterator>
|
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
#include <boost/spirit/core/assert.hpp> // for BOOST_SPIRIT_ASSERT
|
|
||||||
|
|
||||||
// FIXES for broken compilers
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <boost/iterator_adaptors.hpp>
|
|
||||||
|
|
||||||
#define BOOST_SPIRIT_ASSERT_FSQ_SIZE \
|
|
||||||
BOOST_SPIRIT_ASSERT(((m_tail + N + 1) - m_head) % (N+1) == m_size % (N+1)) \
|
|
||||||
/**/
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
#if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \
|
|
||||||
BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
|
|
||||||
#error "Please use at least Boost V1.31.0 while compiling the fixed_size_queue class!"
|
|
||||||
#else // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
|
|
||||||
|
|
||||||
template <typename QueueT, typename T, typename PointerT>
|
|
||||||
class fsq_iterator
|
|
||||||
: public boost::iterator_adaptor<
|
|
||||||
fsq_iterator<QueueT, T, PointerT>,
|
|
||||||
PointerT,
|
|
||||||
T,
|
|
||||||
std::random_access_iterator_tag
|
|
||||||
>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef typename QueueT::position_t position;
|
|
||||||
typedef boost::iterator_adaptor<
|
|
||||||
fsq_iterator<QueueT, T, PointerT>, PointerT, T,
|
|
||||||
std::random_access_iterator_tag
|
|
||||||
> base_t;
|
|
||||||
|
|
||||||
fsq_iterator() {}
|
|
||||||
fsq_iterator(position const &p_) : p(p_) {}
|
|
||||||
|
|
||||||
position const &get_position() const { return p; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class boost::iterator_core_access;
|
|
||||||
|
|
||||||
typename base_t::reference dereference() const
|
|
||||||
{
|
|
||||||
return p.self->m_queue[p.pos];
|
|
||||||
}
|
|
||||||
|
|
||||||
void increment()
|
|
||||||
{
|
|
||||||
++p.pos;
|
|
||||||
if (p.pos == QueueT::MAX_SIZE+1)
|
|
||||||
p.pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void decrement()
|
|
||||||
{
|
|
||||||
if (p.pos == 0)
|
|
||||||
p.pos = QueueT::MAX_SIZE;
|
|
||||||
else
|
|
||||||
--p.pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename OtherDerivedT, typename OtherIteratorT,
|
|
||||||
typename V, typename C, typename R, typename D
|
|
||||||
>
|
|
||||||
bool equal(iterator_adaptor<OtherDerivedT, OtherIteratorT, V, C, R, D>
|
|
||||||
const &x) const
|
|
||||||
{
|
|
||||||
position const &rhs_pos =
|
|
||||||
static_cast<OtherDerivedT const &>(x).get_position();
|
|
||||||
return (p.self == rhs_pos.self) && (p.pos == rhs_pos.pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename OtherDerivedT, typename OtherIteratorT,
|
|
||||||
typename V, typename C, typename R, typename D
|
|
||||||
>
|
|
||||||
typename base_t::difference_type distance_to(
|
|
||||||
iterator_adaptor<OtherDerivedT, OtherIteratorT, V, C, R, D>
|
|
||||||
const &x) const
|
|
||||||
{
|
|
||||||
typedef typename base_t::difference_type diff_t;
|
|
||||||
|
|
||||||
position const &p2 =
|
|
||||||
static_cast<OtherDerivedT const &>(x).get_position();
|
|
||||||
std::size_t pos1 = p.pos;
|
|
||||||
std::size_t pos2 = p2.pos;
|
|
||||||
|
|
||||||
// Undefined behaviour if the iterators come from different
|
|
||||||
// containers
|
|
||||||
BOOST_SPIRIT_ASSERT(p.self == p2.self);
|
|
||||||
|
|
||||||
if (pos1 < p.self->m_head)
|
|
||||||
pos1 += QueueT::MAX_SIZE;
|
|
||||||
if (pos2 < p2.self->m_head)
|
|
||||||
pos2 += QueueT::MAX_SIZE;
|
|
||||||
|
|
||||||
if (pos2 > pos1)
|
|
||||||
return diff_t(pos2 - pos1);
|
|
||||||
else
|
|
||||||
return -diff_t(pos1 - pos2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void advance(typename base_t::difference_type n)
|
|
||||||
{
|
|
||||||
// Notice that we don't care values of n that can
|
|
||||||
// wrap around more than one time, since it would
|
|
||||||
// be undefined behaviour anyway (going outside
|
|
||||||
// the begin/end range). Negative wrapping is a bit
|
|
||||||
// cumbersome because we don't want to case p.pos
|
|
||||||
// to signed.
|
|
||||||
if (n < 0)
|
|
||||||
{
|
|
||||||
n = -n;
|
|
||||||
if (p.pos < (std::size_t)n)
|
|
||||||
p.pos = QueueT::MAX_SIZE+1 - (n - p.pos);
|
|
||||||
else
|
|
||||||
p.pos -= n;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p.pos += n;
|
|
||||||
if (p.pos >= QueueT::MAX_SIZE+1)
|
|
||||||
p.pos -= QueueT::MAX_SIZE+1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
position p;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
} /* namespace impl */
|
|
||||||
|
|
||||||
template <typename T, std::size_t N>
|
|
||||||
class fixed_size_queue
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
struct position
|
|
||||||
{
|
|
||||||
fixed_size_queue* self;
|
|
||||||
std::size_t pos;
|
|
||||||
|
|
||||||
position() : self(0), pos(0) {}
|
|
||||||
|
|
||||||
// The const_cast here is just to avoid to have two different
|
|
||||||
// position structures for the const and non-const case.
|
|
||||||
// The const semantic is guaranteed by the iterator itself
|
|
||||||
position(const fixed_size_queue* s, std::size_t p)
|
|
||||||
: self(const_cast<fixed_size_queue*>(s)), pos(p)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Declare the iterators
|
|
||||||
typedef impl::fsq_iterator<fixed_size_queue<T, N>, T, T*> iterator;
|
|
||||||
typedef impl::fsq_iterator<fixed_size_queue<T, N>, T const, T const*>
|
|
||||||
const_iterator;
|
|
||||||
typedef position position_t;
|
|
||||||
|
|
||||||
friend class impl::fsq_iterator<fixed_size_queue<T, N>, T, T*>;
|
|
||||||
friend class impl::fsq_iterator<fixed_size_queue<T, N>, T const, T const*>;
|
|
||||||
|
|
||||||
fixed_size_queue();
|
|
||||||
fixed_size_queue(const fixed_size_queue& x);
|
|
||||||
fixed_size_queue& operator=(const fixed_size_queue& x);
|
|
||||||
~fixed_size_queue();
|
|
||||||
|
|
||||||
void push_back(const T& e);
|
|
||||||
void push_front(const T& e);
|
|
||||||
void serve(T& e);
|
|
||||||
void pop_front();
|
|
||||||
|
|
||||||
bool empty() const
|
|
||||||
{
|
|
||||||
return m_size == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool full() const
|
|
||||||
{
|
|
||||||
return m_size == N;
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator begin()
|
|
||||||
{
|
|
||||||
return iterator(position(this, m_head));
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator begin() const
|
|
||||||
{
|
|
||||||
return const_iterator(position(this, m_head));
|
|
||||||
}
|
|
||||||
|
|
||||||
iterator end()
|
|
||||||
{
|
|
||||||
return iterator(position(this, m_tail));
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator end() const
|
|
||||||
{
|
|
||||||
return const_iterator(position(this, m_tail));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t size() const
|
|
||||||
{
|
|
||||||
return m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
T& front()
|
|
||||||
{
|
|
||||||
return m_queue[m_head];
|
|
||||||
}
|
|
||||||
|
|
||||||
const T& front() const
|
|
||||||
{
|
|
||||||
return m_queue[m_head];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Redefine the template parameters to avoid using partial template
|
|
||||||
// specialization on the iterator policy to extract N.
|
|
||||||
BOOST_STATIC_CONSTANT(std::size_t, MAX_SIZE = N);
|
|
||||||
|
|
||||||
std::size_t m_head;
|
|
||||||
std::size_t m_tail;
|
|
||||||
std::size_t m_size;
|
|
||||||
T m_queue[N+1];
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, std::size_t N>
|
|
||||||
inline
|
|
||||||
fixed_size_queue<T, N>::fixed_size_queue()
|
|
||||||
: m_head(0)
|
|
||||||
, m_tail(0)
|
|
||||||
, m_size(0)
|
|
||||||
{
|
|
||||||
BOOST_SPIRIT_ASSERT(m_size <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
|
||||||
BOOST_SPIRIT_ASSERT(m_head <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT(m_tail <= N+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, std::size_t N>
|
|
||||||
inline
|
|
||||||
fixed_size_queue<T, N>::fixed_size_queue(const fixed_size_queue& x)
|
|
||||||
: m_head(x.m_head)
|
|
||||||
, m_tail(x.m_tail)
|
|
||||||
, m_size(x.m_size)
|
|
||||||
{
|
|
||||||
copy(x.begin(), x.end(), begin());
|
|
||||||
BOOST_SPIRIT_ASSERT(m_size <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
|
||||||
BOOST_SPIRIT_ASSERT(m_head <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT(m_tail <= N+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, std::size_t N>
|
|
||||||
inline fixed_size_queue<T, N>&
|
|
||||||
fixed_size_queue<T, N>::operator=(const fixed_size_queue& x)
|
|
||||||
{
|
|
||||||
if (this != &x)
|
|
||||||
{
|
|
||||||
m_head = x.m_head;
|
|
||||||
m_tail = x.m_tail;
|
|
||||||
m_size = x.m_size;
|
|
||||||
copy(x.begin(), x.end(), begin());
|
|
||||||
}
|
|
||||||
BOOST_SPIRIT_ASSERT(m_size <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
|
||||||
BOOST_SPIRIT_ASSERT(m_head <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT(m_tail <= N+1);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, std::size_t N>
|
|
||||||
inline
|
|
||||||
fixed_size_queue<T, N>::~fixed_size_queue()
|
|
||||||
{
|
|
||||||
BOOST_SPIRIT_ASSERT(m_size <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
|
||||||
BOOST_SPIRIT_ASSERT(m_head <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT(m_tail <= N+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, std::size_t N>
|
|
||||||
inline void
|
|
||||||
fixed_size_queue<T, N>::push_back(const T& e)
|
|
||||||
{
|
|
||||||
BOOST_SPIRIT_ASSERT(m_size <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
|
||||||
BOOST_SPIRIT_ASSERT(m_head <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT(m_tail <= N+1);
|
|
||||||
|
|
||||||
BOOST_SPIRIT_ASSERT(!full());
|
|
||||||
|
|
||||||
m_queue[m_tail] = e;
|
|
||||||
++m_size;
|
|
||||||
++m_tail;
|
|
||||||
if (m_tail == N+1)
|
|
||||||
m_tail = 0;
|
|
||||||
|
|
||||||
|
|
||||||
BOOST_SPIRIT_ASSERT(m_size <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
|
||||||
BOOST_SPIRIT_ASSERT(m_head <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT(m_tail <= N+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, std::size_t N>
|
|
||||||
inline void
|
|
||||||
fixed_size_queue<T, N>::push_front(const T& e)
|
|
||||||
{
|
|
||||||
BOOST_SPIRIT_ASSERT(m_size <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
|
||||||
BOOST_SPIRIT_ASSERT(m_head <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT(m_tail <= N+1);
|
|
||||||
|
|
||||||
BOOST_SPIRIT_ASSERT(!full());
|
|
||||||
|
|
||||||
if (m_head == 0)
|
|
||||||
m_head = N;
|
|
||||||
else
|
|
||||||
--m_head;
|
|
||||||
|
|
||||||
m_queue[m_head] = e;
|
|
||||||
++m_size;
|
|
||||||
|
|
||||||
BOOST_SPIRIT_ASSERT(m_size <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
|
||||||
BOOST_SPIRIT_ASSERT(m_head <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT(m_tail <= N+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T, std::size_t N>
|
|
||||||
inline void
|
|
||||||
fixed_size_queue<T, N>::serve(T& e)
|
|
||||||
{
|
|
||||||
BOOST_SPIRIT_ASSERT(m_size <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
|
||||||
BOOST_SPIRIT_ASSERT(m_head <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT(m_tail <= N+1);
|
|
||||||
|
|
||||||
e = m_queue[m_head];
|
|
||||||
pop_front();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T, std::size_t N>
|
|
||||||
inline void
|
|
||||||
fixed_size_queue<T, N>::pop_front()
|
|
||||||
{
|
|
||||||
BOOST_SPIRIT_ASSERT(m_size <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
|
||||||
BOOST_SPIRIT_ASSERT(m_head <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT(m_tail <= N+1);
|
|
||||||
|
|
||||||
++m_head;
|
|
||||||
if (m_head == N+1)
|
|
||||||
m_head = 0;
|
|
||||||
--m_size;
|
|
||||||
|
|
||||||
BOOST_SPIRIT_ASSERT(m_size <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
|
||||||
BOOST_SPIRIT_ASSERT(m_head <= N+1);
|
|
||||||
BOOST_SPIRIT_ASSERT(m_tail <= N+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#undef BOOST_SPIRIT_ASSERT_FSQ_SIZE
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,460 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2003 Giovanni Bajo
|
|
||||||
Copyright (c) 2003 Martin Wille
|
|
||||||
Copyright (c) 2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_FILE_ITERATOR_IPP
|
|
||||||
#define BOOST_SPIRIT_FILE_ITERATOR_IPP
|
|
||||||
|
|
||||||
#ifdef BOOST_SPIRIT_FILEITERATOR_WINDOWS
|
|
||||||
# define WIN32_LEAN_AND_MEAN
|
|
||||||
# include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
|
|
||||||
#ifdef BOOST_SPIRIT_FILEITERATOR_WINDOWS
|
|
||||||
# include <boost/type_traits/remove_pointer.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BOOST_SPIRIT_FILEITERATOR_POSIX
|
|
||||||
# include <sys/types.h> // open, stat, mmap, munmap
|
|
||||||
# include <sys/stat.h> // stat
|
|
||||||
# include <fcntl.h> // open
|
|
||||||
# include <unistd.h> // stat, mmap, munmap
|
|
||||||
# include <sys/mman.h> // mmap, mmunmap
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace fileiter_impl {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// std_file_iterator
|
|
||||||
//
|
|
||||||
// Base class that implements iteration through a file using standard C
|
|
||||||
// stream library (fopen and friends). This class and the following are
|
|
||||||
// the base components on which the iterator is built (through the
|
|
||||||
// iterator adaptor library).
|
|
||||||
//
|
|
||||||
// The opened file stream (FILE) is held with a shared_ptr<>, whose
|
|
||||||
// custom deleter invokes fcose(). This makes the syntax of the class
|
|
||||||
// very easy, especially everything related to copying.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template <typename CharT>
|
|
||||||
class std_file_iterator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef CharT value_type;
|
|
||||||
|
|
||||||
std_file_iterator()
|
|
||||||
{}
|
|
||||||
|
|
||||||
explicit std_file_iterator(std::string fileName)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
FILE* f = fopen(fileName.c_str(), "rb");
|
|
||||||
|
|
||||||
// If the file was opened, store it into
|
|
||||||
// the smart pointer.
|
|
||||||
if (f)
|
|
||||||
{
|
|
||||||
m_file.reset(f, fclose);
|
|
||||||
m_pos = 0;
|
|
||||||
m_eof = false;
|
|
||||||
update_char();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std_file_iterator(const std_file_iterator& iter)
|
|
||||||
{ *this = iter; }
|
|
||||||
|
|
||||||
std_file_iterator& operator=(const std_file_iterator& iter)
|
|
||||||
{
|
|
||||||
m_file = iter.m_file;
|
|
||||||
m_curChar = iter.m_curChar;
|
|
||||||
m_eof = iter.m_eof;
|
|
||||||
m_pos = iter.m_pos;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nasty bug in Comeau up to 4.3.0.1, we need explicit boolean context
|
|
||||||
// for shared_ptr to evaluate correctly
|
|
||||||
operator bool() const
|
|
||||||
{ return m_file ? true : false; }
|
|
||||||
|
|
||||||
bool operator==(const std_file_iterator& iter) const
|
|
||||||
{
|
|
||||||
return (m_file == iter.m_file) && (m_eof == iter.m_eof) &&
|
|
||||||
(m_pos == iter.m_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
const CharT& get_cur_char(void) const
|
|
||||||
{
|
|
||||||
return m_curChar;
|
|
||||||
}
|
|
||||||
|
|
||||||
void prev_char(void)
|
|
||||||
{
|
|
||||||
m_pos -= sizeof(CharT);
|
|
||||||
update_char();
|
|
||||||
}
|
|
||||||
|
|
||||||
void next_char(void)
|
|
||||||
{
|
|
||||||
m_pos += sizeof(CharT);
|
|
||||||
update_char();
|
|
||||||
}
|
|
||||||
|
|
||||||
void seek_end(void)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
fseek(m_file.get(), 0, SEEK_END);
|
|
||||||
m_pos = ftell(m_file.get()) / sizeof(CharT);
|
|
||||||
m_eof = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void advance(std::ptrdiff_t n)
|
|
||||||
{
|
|
||||||
m_pos += n * sizeof(CharT);
|
|
||||||
update_char();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ptrdiff_t distance(const std_file_iterator& iter) const
|
|
||||||
{
|
|
||||||
return (std::ptrdiff_t)(m_pos - iter.m_pos) / sizeof(CharT);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
boost::shared_ptr<std::FILE> m_file;
|
|
||||||
std::size_t m_pos;
|
|
||||||
CharT m_curChar;
|
|
||||||
bool m_eof;
|
|
||||||
|
|
||||||
void update_char(void)
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
if ((std::size_t)ftell(m_file.get()) != m_pos)
|
|
||||||
fseek(m_file.get(), m_pos, SEEK_SET);
|
|
||||||
|
|
||||||
m_eof = (fread(&m_curChar, sizeof(CharT), 1, m_file.get()) < 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// mmap_file_iterator
|
|
||||||
//
|
|
||||||
// File iterator for memory mapped files, for now implemented on Windows and
|
|
||||||
// POSIX platforms. This class has the same interface of std_file_iterator,
|
|
||||||
// and can be used in its place (in fact, it's the default for Windows and
|
|
||||||
// POSIX).
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// mmap_file_iterator, Windows version
|
|
||||||
#ifdef BOOST_SPIRIT_FILEITERATOR_WINDOWS
|
|
||||||
template <typename CharT>
|
|
||||||
class mmap_file_iterator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef CharT value_type;
|
|
||||||
|
|
||||||
mmap_file_iterator()
|
|
||||||
{}
|
|
||||||
|
|
||||||
explicit mmap_file_iterator(std::string fileName)
|
|
||||||
{
|
|
||||||
HANDLE hFile = ::CreateFileA(
|
|
||||||
fileName.c_str(),
|
|
||||||
GENERIC_READ,
|
|
||||||
FILE_SHARE_READ,
|
|
||||||
NULL,
|
|
||||||
OPEN_EXISTING,
|
|
||||||
FILE_FLAG_SEQUENTIAL_SCAN,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
if (hFile == INVALID_HANDLE_VALUE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Store the size of the file, it's used to construct
|
|
||||||
// the end iterator
|
|
||||||
m_filesize = ::GetFileSize(hFile, NULL);
|
|
||||||
|
|
||||||
HANDLE hMap = ::CreateFileMapping(
|
|
||||||
hFile,
|
|
||||||
NULL,
|
|
||||||
PAGE_READONLY,
|
|
||||||
0, 0,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
if (hMap == NULL)
|
|
||||||
{
|
|
||||||
::CloseHandle(hFile);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LPVOID pMem = ::MapViewOfFile(
|
|
||||||
hMap,
|
|
||||||
FILE_MAP_READ,
|
|
||||||
0, 0, 0
|
|
||||||
);
|
|
||||||
|
|
||||||
if (pMem == NULL)
|
|
||||||
{
|
|
||||||
::CloseHandle(hMap);
|
|
||||||
::CloseHandle(hFile);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We hold both the file handle and the memory pointer.
|
|
||||||
// We can close the hMap handle now because Windows holds internally
|
|
||||||
// a reference to it since there is a view mapped.
|
|
||||||
::CloseHandle(hMap);
|
|
||||||
|
|
||||||
// It seems like we can close the file handle as well (because
|
|
||||||
// a reference is hold by the filemap object).
|
|
||||||
::CloseHandle(hFile);
|
|
||||||
|
|
||||||
// Store the handles inside the shared_ptr (with the custom destructors)
|
|
||||||
m_mem.reset(static_cast<CharT*>(pMem), ::UnmapViewOfFile);
|
|
||||||
|
|
||||||
// Start of the file
|
|
||||||
m_curChar = m_mem.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
mmap_file_iterator(const mmap_file_iterator& iter)
|
|
||||||
{ *this = iter; }
|
|
||||||
|
|
||||||
mmap_file_iterator& operator=(const mmap_file_iterator& iter)
|
|
||||||
{
|
|
||||||
m_curChar = iter.m_curChar;
|
|
||||||
m_mem = iter.m_mem;
|
|
||||||
m_filesize = iter.m_filesize;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nasty bug in Comeau up to 4.3.0.1, we need explicit boolean context
|
|
||||||
// for shared_ptr to evaluate correctly
|
|
||||||
operator bool() const
|
|
||||||
{ return m_mem ? true : false; }
|
|
||||||
|
|
||||||
bool operator==(const mmap_file_iterator& iter) const
|
|
||||||
{ return m_curChar == iter.m_curChar; }
|
|
||||||
|
|
||||||
const CharT& get_cur_char(void) const
|
|
||||||
{ return *m_curChar; }
|
|
||||||
|
|
||||||
void next_char(void)
|
|
||||||
{ m_curChar++; }
|
|
||||||
|
|
||||||
void prev_char(void)
|
|
||||||
{ m_curChar--; }
|
|
||||||
|
|
||||||
void advance(std::ptrdiff_t n)
|
|
||||||
{ m_curChar += n; }
|
|
||||||
|
|
||||||
std::ptrdiff_t distance(const mmap_file_iterator& iter) const
|
|
||||||
{ return m_curChar - iter.m_curChar; }
|
|
||||||
|
|
||||||
void seek_end(void)
|
|
||||||
{
|
|
||||||
m_curChar = m_mem.get() +
|
|
||||||
(m_filesize / sizeof(CharT));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
|
||||||
typedef boost::remove_pointer<HANDLE>::type handle_t;
|
|
||||||
#else
|
|
||||||
typedef void handle_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
boost::shared_ptr<CharT> m_mem;
|
|
||||||
std::size_t m_filesize;
|
|
||||||
CharT* m_curChar;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // BOOST_SPIRIT_FILEITERATOR_WINDOWS
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// mmap_file_iterator, POSIX version
|
|
||||||
#ifdef BOOST_SPIRIT_FILEITERATOR_POSIX
|
|
||||||
template <typename CharT>
|
|
||||||
class mmap_file_iterator
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
struct mapping
|
|
||||||
{
|
|
||||||
mapping(void *p, off_t len)
|
|
||||||
: data(p)
|
|
||||||
, size(len)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
CharT const *begin() const
|
|
||||||
{
|
|
||||||
return static_cast<CharT *>(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
CharT const *end() const
|
|
||||||
{
|
|
||||||
return static_cast<CharT *>(data) + size/sizeof(CharT);
|
|
||||||
}
|
|
||||||
|
|
||||||
~mapping()
|
|
||||||
{
|
|
||||||
munmap(data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void *data;
|
|
||||||
off_t size;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef CharT value_type;
|
|
||||||
|
|
||||||
mmap_file_iterator()
|
|
||||||
{}
|
|
||||||
|
|
||||||
explicit mmap_file_iterator(std::string file_name)
|
|
||||||
{
|
|
||||||
// open the file
|
|
||||||
int fd = open(file_name.c_str(),
|
|
||||||
#ifdef O_NOCTTY
|
|
||||||
O_NOCTTY | // if stdin was closed then opening a file
|
|
||||||
// would cause the file to become the controlling
|
|
||||||
// terminal if the filename refers to a tty. Setting
|
|
||||||
// O_NOCTTY inhibits this.
|
|
||||||
#endif
|
|
||||||
O_RDONLY);
|
|
||||||
|
|
||||||
if (fd == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// call fstat to find get information about the file just
|
|
||||||
// opened (size and file type)
|
|
||||||
struct stat stat_buf;
|
|
||||||
if ((fstat(fd, &stat_buf) != 0) || !S_ISREG(stat_buf.st_mode))
|
|
||||||
{ // if fstat returns an error or if the file isn't a
|
|
||||||
// regular file we give up.
|
|
||||||
close(fd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// perform the actual mapping
|
|
||||||
void *p = mmap(0, stat_buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
|
||||||
// it is safe to close() here. POSIX requires that the OS keeps a
|
|
||||||
// second handle to the file while the file is mmapped.
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
if (p == MAP_FAILED)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mapping *m = 0;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
m = new mapping(p, stat_buf.st_size);
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
munmap(p, stat_buf.st_size);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_mem.reset(m);
|
|
||||||
|
|
||||||
// Start of the file
|
|
||||||
m_curChar = m_mem->begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
mmap_file_iterator(const mmap_file_iterator& iter)
|
|
||||||
{ *this = iter; }
|
|
||||||
|
|
||||||
mmap_file_iterator& operator=(const mmap_file_iterator& iter)
|
|
||||||
{
|
|
||||||
m_curChar = iter.m_curChar;
|
|
||||||
m_mem = iter.m_mem;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nasty bug in Comeau up to 4.3.0.1, we need explicit boolean context
|
|
||||||
// for shared_ptr to evaluate correctly
|
|
||||||
operator bool() const
|
|
||||||
{ return m_mem ? true : false; }
|
|
||||||
|
|
||||||
bool operator==(const mmap_file_iterator& iter) const
|
|
||||||
{ return m_curChar == iter.m_curChar; }
|
|
||||||
|
|
||||||
const CharT& get_cur_char(void) const
|
|
||||||
{ return *m_curChar; }
|
|
||||||
|
|
||||||
void next_char(void)
|
|
||||||
{ m_curChar++; }
|
|
||||||
|
|
||||||
void prev_char(void)
|
|
||||||
{ m_curChar--; }
|
|
||||||
|
|
||||||
void advance(signed long n)
|
|
||||||
{ m_curChar += n; }
|
|
||||||
|
|
||||||
long distance(const mmap_file_iterator& iter) const
|
|
||||||
{ return m_curChar - iter.m_curChar; }
|
|
||||||
|
|
||||||
void seek_end(void)
|
|
||||||
{
|
|
||||||
m_curChar = m_mem->end();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
boost::shared_ptr<mapping> m_mem;
|
|
||||||
CharT const* m_curChar;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // BOOST_SPIRIT_FILEITERATOR_POSIX
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
} /* namespace boost::spirit::fileiter_impl */
|
|
||||||
|
|
||||||
template <typename CharT, typename BaseIteratorT>
|
|
||||||
file_iterator<CharT,BaseIteratorT>
|
|
||||||
file_iterator<CharT,BaseIteratorT>::make_end(void)
|
|
||||||
{
|
|
||||||
file_iterator iter(*this);
|
|
||||||
iter.base_reference().seek_end();
|
|
||||||
return iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename CharT, typename BaseIteratorT>
|
|
||||||
file_iterator<CharT,BaseIteratorT>&
|
|
||||||
file_iterator<CharT,BaseIteratorT>::operator=(const base_t& iter)
|
|
||||||
{
|
|
||||||
base_t::operator=(iter);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
}} /* namespace boost::spirit */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* BOOST_SPIRIT_FILE_ITERATOR_IPP */
|
|
@ -1,131 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2002 Juan Carlos Arevalo-Baeza
|
|
||||||
Copyright (c) 2002-2006 Hartmut Kaiser
|
|
||||||
Copyright (c) 2003 Giovanni Bajo
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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 POSITION_ITERATOR_IPP
|
|
||||||
#define POSITION_ITERATOR_IPP
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <boost/iterator_adaptors.hpp>
|
|
||||||
#include <boost/type_traits/add_const.hpp>
|
|
||||||
#include <boost/mpl/if.hpp>
|
|
||||||
#include <boost/type_traits/is_same.hpp>
|
|
||||||
#include <boost/spirit/core/nil.hpp> // for nil_t
|
|
||||||
#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// position_policy<file_position_without_column>
|
|
||||||
//
|
|
||||||
// Specialization to handle file_position_without_column. Only take care of
|
|
||||||
// newlines since no column tracking is needed.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename String>
|
|
||||||
class position_policy<file_position_without_column_base<String> > {
|
|
||||||
|
|
||||||
public:
|
|
||||||
void next_line(file_position_without_column_base<String>& pos)
|
|
||||||
{
|
|
||||||
++pos.line;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_tab_chars(unsigned int /*chars*/){}
|
|
||||||
void next_char(file_position_without_column_base<String>& /*pos*/) {}
|
|
||||||
void tabulation(file_position_without_column_base<String>& /*pos*/) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// position_policy<file_position>
|
|
||||||
//
|
|
||||||
// Specialization to handle file_position. Track characters and tabulation
|
|
||||||
// to compute the current column correctly.
|
|
||||||
//
|
|
||||||
// Default tab size is 4. You can change this with the set_tabchars member
|
|
||||||
// of position_iterator.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename String>
|
|
||||||
class position_policy<file_position_base<String> > {
|
|
||||||
|
|
||||||
public:
|
|
||||||
position_policy()
|
|
||||||
: m_CharsPerTab(4)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void next_line(file_position_base<String>& pos)
|
|
||||||
{
|
|
||||||
++pos.line;
|
|
||||||
pos.column = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_tab_chars(unsigned int chars)
|
|
||||||
{
|
|
||||||
m_CharsPerTab = chars;
|
|
||||||
}
|
|
||||||
|
|
||||||
void next_char(file_position_base<String>& pos)
|
|
||||||
{
|
|
||||||
++pos.column;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tabulation(file_position_base<String>& pos)
|
|
||||||
{
|
|
||||||
pos.column += m_CharsPerTab - (pos.column - 1) % m_CharsPerTab;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
unsigned int m_CharsPerTab;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* namespace boost::spirit { */ namespace iterator_ { namespace impl {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// position_iterator_base_generator
|
|
||||||
//
|
|
||||||
// Metafunction to generate the iterator type using boost::iterator_adaptors,
|
|
||||||
// hiding all the metaprogramming thunking code in it. It is used
|
|
||||||
// mainly to keep the public interface (position_iterator) cleanear.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename MainIterT, typename ForwardIterT, typename PositionT>
|
|
||||||
struct position_iterator_base_generator
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef boost::detail::iterator_traits<ForwardIterT> traits;
|
|
||||||
typedef typename traits::value_type value_type;
|
|
||||||
typedef typename traits::iterator_category iter_category_t;
|
|
||||||
|
|
||||||
// Position iterator is always a non-mutable iterator
|
|
||||||
typedef typename boost::add_const<value_type>::type const_value_type;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Check if the MainIterT is nil. If it's nil, it means that the actual
|
|
||||||
// self type is position_iterator. Otherwise, it's a real type we
|
|
||||||
// must use
|
|
||||||
typedef typename boost::mpl::if_<
|
|
||||||
typename boost::is_same<MainIterT, nil_t>::type,
|
|
||||||
position_iterator<ForwardIterT, PositionT, nil_t>,
|
|
||||||
MainIterT
|
|
||||||
>::type main_iter_t;
|
|
||||||
|
|
||||||
typedef boost::iterator_adaptor<
|
|
||||||
main_iter_t,
|
|
||||||
ForwardIterT,
|
|
||||||
const_value_type
|
|
||||||
> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
}}}} /* namespace boost::spirit::iterator_::impl */
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
@ -1,429 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2002 Juan Carlos Arevalo-Baeza
|
|
||||||
Copyright (c) 2002-2006 Hartmut Kaiser
|
|
||||||
Copyright (c) 2003 Giovanni Bajo
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_POSITION_ITERATOR_HPP
|
|
||||||
#define BOOST_SPIRIT_POSITION_ITERATOR_HPP
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#include <boost/concept_check.hpp>
|
|
||||||
|
|
||||||
#include <boost/spirit/iterator/position_iterator_fwd.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// file_position_without_column
|
|
||||||
//
|
|
||||||
// A structure to hold positional information. This includes the file,
|
|
||||||
// and the line number
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename String>
|
|
||||||
struct file_position_without_column_base {
|
|
||||||
String file;
|
|
||||||
int line;
|
|
||||||
|
|
||||||
file_position_without_column_base(String const& file_ = String(),
|
|
||||||
int line_ = 1):
|
|
||||||
file (file_),
|
|
||||||
line (line_)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool operator==(const file_position_without_column_base& fp) const
|
|
||||||
{ return line == fp.line && file == fp.file; }
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// file_position
|
|
||||||
//
|
|
||||||
// This structure holds complete file position, including file name,
|
|
||||||
// line and column number
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename String>
|
|
||||||
struct file_position_base : public file_position_without_column_base<String> {
|
|
||||||
int column;
|
|
||||||
|
|
||||||
file_position_base(String const& file_ = String(),
|
|
||||||
int line_ = 1, int column_ = 1):
|
|
||||||
file_position_without_column_base<String> (file_, line_),
|
|
||||||
column (column_)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool operator==(const file_position_base& fp) const
|
|
||||||
{ return column == fp.column && this->line == fp.line && this->file == fp.file; }
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// position_policy<>
|
|
||||||
//
|
|
||||||
// This template is the policy to handle the file position. It is specialized
|
|
||||||
// on the position type. Providing a custom file_position also requires
|
|
||||||
// providing a specialization of this class.
|
|
||||||
//
|
|
||||||
// Policy interface:
|
|
||||||
//
|
|
||||||
// Default constructor of the custom position class must be accessible.
|
|
||||||
// set_tab_chars(unsigned int chars) - Set the tabstop width
|
|
||||||
// next_char(PositionT& pos) - Notify that a new character has been
|
|
||||||
// processed
|
|
||||||
// tabulation(PositionT& pos) - Notify that a tab character has been
|
|
||||||
// processed
|
|
||||||
// next_line(PositionT& pos) - Notify that a new line delimiter has
|
|
||||||
// been reached.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename PositionT> class position_policy;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
}} /* namespace boost::spirit */
|
|
||||||
|
|
||||||
|
|
||||||
// This must be included here for full compatibility with old MSVC
|
|
||||||
#include "boost/spirit/iterator/impl/position_iterator.ipp"
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// position_iterator
|
|
||||||
//
|
|
||||||
// It wraps an iterator, and keeps track of the current position in the input,
|
|
||||||
// as it gets incremented.
|
|
||||||
//
|
|
||||||
// The wrapped iterator must be at least a Forward iterator. The position
|
|
||||||
// iterator itself will always be a non-mutable Forward iterator.
|
|
||||||
//
|
|
||||||
// In order to have begin/end iterators constructed, the end iterator must be
|
|
||||||
// empty constructed. Similar to what happens with stream iterators. The begin
|
|
||||||
// iterator must be constructed from both, the begin and end iterators of the
|
|
||||||
// wrapped iterator type. This is necessary to implement the lookahead of
|
|
||||||
// characters necessary to parse CRLF sequences.
|
|
||||||
//
|
|
||||||
// In order to extract the current positional data from the iterator, you may
|
|
||||||
// use the get_position member function.
|
|
||||||
//
|
|
||||||
// You can also use the set_position member function to reset the current
|
|
||||||
// position to something new.
|
|
||||||
//
|
|
||||||
// The structure that holds the current position can be customized through a
|
|
||||||
// template parameter, and the class position_policy must be specialized
|
|
||||||
// on the new type to define how to handle it. Currently, it's possible
|
|
||||||
// to choose between the file_position and file_position_without_column
|
|
||||||
// (which saves some overhead if managing current column is not required).
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \
|
|
||||||
BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
|
|
||||||
#error "Please use at least Boost V1.31.0 while compiling the position_iterator class!"
|
|
||||||
#else // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Uses the newer iterator_adaptor version (should be released with
|
|
||||||
// Boost V1.31.0)
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <
|
|
||||||
typename ForwardIteratorT,
|
|
||||||
typename PositionT,
|
|
||||||
typename SelfT
|
|
||||||
>
|
|
||||||
class position_iterator
|
|
||||||
: public iterator_::impl::position_iterator_base_generator<
|
|
||||||
SelfT,
|
|
||||||
ForwardIteratorT,
|
|
||||||
PositionT
|
|
||||||
>::type,
|
|
||||||
public position_policy<PositionT>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
typedef position_policy<PositionT> position_policy_t;
|
|
||||||
typedef typename iterator_::impl::position_iterator_base_generator<
|
|
||||||
SelfT,
|
|
||||||
ForwardIteratorT,
|
|
||||||
PositionT
|
|
||||||
>::type base_t;
|
|
||||||
typedef typename iterator_::impl::position_iterator_base_generator<
|
|
||||||
SelfT,
|
|
||||||
ForwardIteratorT,
|
|
||||||
PositionT
|
|
||||||
>::main_iter_t main_iter_t;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef PositionT position_t;
|
|
||||||
|
|
||||||
position_iterator()
|
|
||||||
: _isend(true)
|
|
||||||
{}
|
|
||||||
|
|
||||||
position_iterator(
|
|
||||||
const ForwardIteratorT& begin,
|
|
||||||
const ForwardIteratorT& end)
|
|
||||||
: base_t(begin), _end(end), _pos(PositionT()), _isend(begin == end)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template <typename FileNameT>
|
|
||||||
position_iterator(
|
|
||||||
const ForwardIteratorT& begin,
|
|
||||||
const ForwardIteratorT& end,
|
|
||||||
FileNameT fileName)
|
|
||||||
: base_t(begin), _end(end), _pos(PositionT(fileName)),
|
|
||||||
_isend(begin == end)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template <typename FileNameT, typename LineT>
|
|
||||||
position_iterator(
|
|
||||||
const ForwardIteratorT& begin,
|
|
||||||
const ForwardIteratorT& end,
|
|
||||||
FileNameT fileName, LineT line)
|
|
||||||
: base_t(begin), _end(end), _pos(PositionT(fileName, line)),
|
|
||||||
_isend(begin == end)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template <typename FileNameT, typename LineT, typename ColumnT>
|
|
||||||
position_iterator(
|
|
||||||
const ForwardIteratorT& begin,
|
|
||||||
const ForwardIteratorT& end,
|
|
||||||
FileNameT fileName, LineT line, ColumnT column)
|
|
||||||
: base_t(begin), _end(end), _pos(PositionT(fileName, line, column)),
|
|
||||||
_isend(begin == end)
|
|
||||||
{}
|
|
||||||
|
|
||||||
position_iterator(
|
|
||||||
const ForwardIteratorT& begin,
|
|
||||||
const ForwardIteratorT& end,
|
|
||||||
const PositionT& pos)
|
|
||||||
: base_t(begin), _end(end), _pos(pos), _isend(begin == end)
|
|
||||||
{}
|
|
||||||
|
|
||||||
position_iterator(const position_iterator& iter)
|
|
||||||
: base_t(iter.base()), position_policy_t(iter),
|
|
||||||
_end(iter._end), _pos(iter._pos), _isend(iter._isend)
|
|
||||||
{}
|
|
||||||
|
|
||||||
position_iterator& operator=(const position_iterator& iter)
|
|
||||||
{
|
|
||||||
base_t::operator=(iter);
|
|
||||||
position_policy_t::operator=(iter);
|
|
||||||
_end = iter._end;
|
|
||||||
_pos = iter._pos;
|
|
||||||
_isend = iter._isend;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_position(PositionT const& newpos) { _pos = newpos; }
|
|
||||||
PositionT& get_position() { return _pos; }
|
|
||||||
PositionT const& get_position() const { return _pos; }
|
|
||||||
|
|
||||||
void set_tabchars(unsigned int chars)
|
|
||||||
{
|
|
||||||
// This function (which comes from the position_policy) has a
|
|
||||||
// different name on purpose, to avoid messing with using
|
|
||||||
// declarations or qualified calls to access the base template
|
|
||||||
// function, which might break some compilers.
|
|
||||||
this->position_policy_t::set_tab_chars(chars);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class boost::iterator_core_access;
|
|
||||||
|
|
||||||
void increment()
|
|
||||||
{
|
|
||||||
typename base_t::reference val = *(this->base());
|
|
||||||
if (val == '\n' || val == '\r') {
|
|
||||||
++this->base_reference();
|
|
||||||
if (this->base_reference() != _end) {
|
|
||||||
typename base_t::reference val2 = *(this->base());
|
|
||||||
if ((val == '\n' && val2 == '\r')
|
|
||||||
|| (val == '\r' && val2 == '\n'))
|
|
||||||
{
|
|
||||||
++this->base_reference();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this->next_line(_pos);
|
|
||||||
static_cast<main_iter_t &>(*this).newline();
|
|
||||||
}
|
|
||||||
else if (val == '\t') {
|
|
||||||
this->tabulation(_pos);
|
|
||||||
++this->base_reference();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this->next_char(_pos);
|
|
||||||
++this->base_reference();
|
|
||||||
}
|
|
||||||
|
|
||||||
// The iterator is at the end only if it's the same
|
|
||||||
// of the
|
|
||||||
_isend = (this->base_reference() == _end);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename OtherDerivedT, typename OtherIteratorT,
|
|
||||||
typename V, typename C, typename R, typename D
|
|
||||||
>
|
|
||||||
bool equal(iterator_adaptor<OtherDerivedT, OtherIteratorT, V, C, R, D>
|
|
||||||
const &x) const
|
|
||||||
{
|
|
||||||
OtherDerivedT const &rhs = static_cast<OtherDerivedT const &>(x);
|
|
||||||
bool x_is_end = rhs._isend;
|
|
||||||
|
|
||||||
return (_isend && x_is_end) ||
|
|
||||||
(!_isend && !x_is_end && this->base() == rhs.base());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
void newline(void)
|
|
||||||
{}
|
|
||||||
|
|
||||||
ForwardIteratorT _end;
|
|
||||||
PositionT _pos;
|
|
||||||
bool _isend;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// position_iterator2
|
|
||||||
//
|
|
||||||
// Equivalent to position_iterator, but it is able to extract the current
|
|
||||||
// line into a string. This is very handy for error reports.
|
|
||||||
//
|
|
||||||
// Notice that the footprint of this class is higher than position_iterator,
|
|
||||||
// (how much depends on how bulky the underlying iterator is), so it should
|
|
||||||
// be used only if necessary.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template
|
|
||||||
<
|
|
||||||
typename ForwardIteratorT,
|
|
||||||
typename PositionT
|
|
||||||
>
|
|
||||||
class position_iterator2
|
|
||||||
: public position_iterator
|
|
||||||
<
|
|
||||||
ForwardIteratorT,
|
|
||||||
PositionT,
|
|
||||||
position_iterator2<ForwardIteratorT, PositionT>
|
|
||||||
>
|
|
||||||
{
|
|
||||||
typedef position_iterator
|
|
||||||
<
|
|
||||||
ForwardIteratorT,
|
|
||||||
PositionT,
|
|
||||||
position_iterator2<ForwardIteratorT, PositionT> // JDG 4-15-03
|
|
||||||
> base_t;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef typename base_t::value_type value_type;
|
|
||||||
typedef PositionT position_t;
|
|
||||||
|
|
||||||
position_iterator2()
|
|
||||||
{}
|
|
||||||
|
|
||||||
position_iterator2(
|
|
||||||
const ForwardIteratorT& begin,
|
|
||||||
const ForwardIteratorT& end):
|
|
||||||
base_t(begin, end),
|
|
||||||
_startline(begin)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template <typename FileNameT>
|
|
||||||
position_iterator2(
|
|
||||||
const ForwardIteratorT& begin,
|
|
||||||
const ForwardIteratorT& end,
|
|
||||||
FileNameT file):
|
|
||||||
base_t(begin, end, file),
|
|
||||||
_startline(begin)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template <typename FileNameT, typename LineT>
|
|
||||||
position_iterator2(
|
|
||||||
const ForwardIteratorT& begin,
|
|
||||||
const ForwardIteratorT& end,
|
|
||||||
FileNameT file, LineT line):
|
|
||||||
base_t(begin, end, file, line),
|
|
||||||
_startline(begin)
|
|
||||||
{}
|
|
||||||
|
|
||||||
template <typename FileNameT, typename LineT, typename ColumnT>
|
|
||||||
position_iterator2(
|
|
||||||
const ForwardIteratorT& begin,
|
|
||||||
const ForwardIteratorT& end,
|
|
||||||
FileNameT file, LineT line, ColumnT column):
|
|
||||||
base_t(begin, end, file, line, column),
|
|
||||||
_startline(begin)
|
|
||||||
{}
|
|
||||||
|
|
||||||
position_iterator2(
|
|
||||||
const ForwardIteratorT& begin,
|
|
||||||
const ForwardIteratorT& end,
|
|
||||||
const PositionT& pos):
|
|
||||||
base_t(begin, end, pos),
|
|
||||||
_startline(begin)
|
|
||||||
{}
|
|
||||||
|
|
||||||
position_iterator2(const position_iterator2& iter)
|
|
||||||
: base_t(iter), _startline(iter._startline)
|
|
||||||
{}
|
|
||||||
|
|
||||||
position_iterator2& operator=(const position_iterator2& iter)
|
|
||||||
{
|
|
||||||
base_t::operator=(iter);
|
|
||||||
_startline = iter._startline;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
ForwardIteratorT get_currentline_begin(void) const
|
|
||||||
{ return _startline; }
|
|
||||||
|
|
||||||
ForwardIteratorT get_currentline_end(void) const
|
|
||||||
{ return get_endline(); }
|
|
||||||
|
|
||||||
std::basic_string<value_type> get_currentline(void) const
|
|
||||||
{
|
|
||||||
return std::basic_string<value_type>
|
|
||||||
(get_currentline_begin(), get_currentline_end());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
ForwardIteratorT _startline;
|
|
||||||
|
|
||||||
friend class position_iterator<ForwardIteratorT, PositionT,
|
|
||||||
position_iterator2<ForwardIteratorT, PositionT> >;
|
|
||||||
|
|
||||||
ForwardIteratorT get_endline() const
|
|
||||||
{
|
|
||||||
ForwardIteratorT endline = _startline;
|
|
||||||
while (endline != this->_end && *endline != '\r' && *endline != '\n')
|
|
||||||
{
|
|
||||||
++endline;
|
|
||||||
}
|
|
||||||
return endline;
|
|
||||||
}
|
|
||||||
|
|
||||||
void newline(void)
|
|
||||||
{ _startline = this->base(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,27 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 1998-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2001-2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_META_MAIN_HPP)
|
|
||||||
#define BOOST_SPIRIT_META_MAIN_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/version.hpp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Master header for Spirit.Meta
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include <boost/spirit/meta/fundamental.hpp>
|
|
||||||
#include <boost/spirit/meta/parser_traits.hpp>
|
|
||||||
#include <boost/spirit/meta/as_parser.hpp>
|
|
||||||
#include <boost/spirit/meta/traverse.hpp>
|
|
||||||
|
|
||||||
#endif // BOOST_SPIRIT_CORE_MAIN_HPP
|
|
||||||
|
|
@ -1,109 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2002-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_AS_PARSER_HPP)
|
|
||||||
#define BOOST_SPIRIT_AS_PARSER_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/core/primitives/primitives.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Helper templates to derive the parser type from an auxilliary type
|
|
||||||
// and to generate an object of the required parser type given an
|
|
||||||
// auxilliary object. Supported types to convert are parsers,
|
|
||||||
// single characters and character strings.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
template<typename T>
|
|
||||||
struct default_as_parser
|
|
||||||
{
|
|
||||||
typedef T type;
|
|
||||||
static type const& convert(type const& p)
|
|
||||||
{
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct char_as_parser
|
|
||||||
{
|
|
||||||
typedef chlit<char> type;
|
|
||||||
static type convert(char ch)
|
|
||||||
{
|
|
||||||
return type(ch);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct wchar_as_parser
|
|
||||||
{
|
|
||||||
typedef chlit<wchar_t> type;
|
|
||||||
static type convert(wchar_t ch)
|
|
||||||
{
|
|
||||||
return type(ch);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct string_as_parser
|
|
||||||
{
|
|
||||||
typedef strlit<char const*> type;
|
|
||||||
static type convert(char const* str)
|
|
||||||
{
|
|
||||||
return type(str);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct wstring_as_parser
|
|
||||||
{
|
|
||||||
typedef strlit<wchar_t const*> type;
|
|
||||||
static type convert(wchar_t const* str)
|
|
||||||
{
|
|
||||||
return type(str);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct as_parser : impl::default_as_parser<T> {};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct as_parser<char> : impl::char_as_parser {};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct as_parser<wchar_t> : impl::wchar_as_parser {};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct as_parser<char*> : impl::string_as_parser {};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct as_parser<char const*> : impl::string_as_parser {};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct as_parser<wchar_t*> : impl::wstring_as_parser {};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct as_parser<wchar_t const*> : impl::wstring_as_parser {};
|
|
||||||
|
|
||||||
template<int N>
|
|
||||||
struct as_parser<char[N]> : impl::string_as_parser {};
|
|
||||||
|
|
||||||
template<int N>
|
|
||||||
struct as_parser<wchar_t[N]> : impl::wstring_as_parser {};
|
|
||||||
|
|
||||||
template<int N>
|
|
||||||
struct as_parser<char const[N]> : impl::string_as_parser {};
|
|
||||||
|
|
||||||
template<int N>
|
|
||||||
struct as_parser<wchar_t const[N]> : impl::wstring_as_parser {};
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,52 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_FUNDAMENTAL_HPP)
|
|
||||||
#define BOOST_SPIRIT_FUNDAMENTAL_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/meta/impl/fundamental.ipp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit
|
|
||||||
{
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Helper template for counting the number of nodes contained in a
|
|
||||||
// given parser type.
|
|
||||||
// All parser_category type parsers are counted as nodes.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ParserT>
|
|
||||||
struct node_count {
|
|
||||||
|
|
||||||
typedef typename ParserT::parser_category_t parser_category_t;
|
|
||||||
typedef typename impl::nodes<parser_category_t>
|
|
||||||
::template count<ParserT, mpl::int_<0> > count_t;
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(int, value = count_t::value);
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Helper template for counting the number of leaf nodes contained in a
|
|
||||||
// given parser type.
|
|
||||||
// Only plain_parser_category type parsers are counted as leaf nodes.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ParserT>
|
|
||||||
struct leaf_count {
|
|
||||||
|
|
||||||
typedef typename ParserT::parser_category_t parser_category_t;
|
|
||||||
typedef typename impl::leafs<parser_category_t>
|
|
||||||
::template count<ParserT, mpl::int_<0> > count_t;
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(int, value = count_t::value);
|
|
||||||
};
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif // !defined(BOOST_SPIRIT_FUNDAMENTAL_HPP)
|
|
@ -1,305 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_FUNDAMENTAL_IPP)
|
|
||||||
#define BOOST_SPIRIT_FUNDAMENTAL_IPP
|
|
||||||
|
|
||||||
#include <boost/mpl/int.hpp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
|
|
||||||
BOOST_SPIRIT_DEPENDENT_TEMPLATE_WRAPPER2(count_wrapper, count);
|
|
||||||
#endif // defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
|
|
||||||
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Helper template for counting the number of nodes contained in a
|
|
||||||
// given parser type.
|
|
||||||
// All parser_category type parsers are counted as nodes.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename CategoryT>
|
|
||||||
struct nodes;
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct nodes<plain_parser_category> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename LeafCountT>
|
|
||||||
struct count {
|
|
||||||
|
|
||||||
// __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT
|
|
||||||
enum { value = (LeafCountT::value + 1) };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct nodes<unary_parser_category> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename LeafCountT>
|
|
||||||
struct count {
|
|
||||||
|
|
||||||
typedef typename ParserT::subject_t subject_t;
|
|
||||||
typedef typename subject_t::parser_category_t subject_category_t;
|
|
||||||
|
|
||||||
typedef nodes<subject_category_t> nodes_t;
|
|
||||||
typedef typename count_wrapper<nodes_t>
|
|
||||||
::template result_<subject_t, LeafCountT> count_t;
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(int, value = count_t::value + 1);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct nodes<action_parser_category> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename LeafCountT>
|
|
||||||
struct count {
|
|
||||||
|
|
||||||
typedef typename ParserT::subject_t subject_t;
|
|
||||||
typedef typename subject_t::parser_category_t subject_category_t;
|
|
||||||
|
|
||||||
typedef nodes<subject_category_t> nodes_t;
|
|
||||||
typedef typename count_wrapper<nodes_t>
|
|
||||||
::template result_<subject_t, LeafCountT> count_t;
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(int, value = count_t::value + 1);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct nodes<binary_parser_category> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename LeafCountT>
|
|
||||||
struct count {
|
|
||||||
|
|
||||||
typedef typename ParserT::left_t left_t;
|
|
||||||
typedef typename ParserT::right_t right_t;
|
|
||||||
typedef typename left_t::parser_category_t left_category_t;
|
|
||||||
typedef typename right_t::parser_category_t right_category_t;
|
|
||||||
|
|
||||||
typedef nodes<left_category_t> left_nodes_t;
|
|
||||||
typedef typename count_wrapper<left_nodes_t>
|
|
||||||
::template result_<left_t, LeafCountT> left_count_t;
|
|
||||||
|
|
||||||
typedef nodes<right_category_t> right_nodes_t;
|
|
||||||
typedef typename count_wrapper<right_nodes_t>
|
|
||||||
::template result_<right_t, LeafCountT> right_count_t;
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(int,
|
|
||||||
value = (left_count_t::value + right_count_t::value + 1));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct nodes<unary_parser_category> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename LeafCountT>
|
|
||||||
struct count {
|
|
||||||
|
|
||||||
typedef typename ParserT::subject_t subject_t;
|
|
||||||
typedef typename subject_t::parser_category_t subject_category_t;
|
|
||||||
|
|
||||||
// __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT
|
|
||||||
enum { value = (nodes<subject_category_t>
|
|
||||||
::template count<subject_t, LeafCountT>::value + 1) };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct nodes<action_parser_category> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename LeafCountT>
|
|
||||||
struct count {
|
|
||||||
|
|
||||||
typedef typename ParserT::subject_t subject_t;
|
|
||||||
typedef typename subject_t::parser_category_t subject_category_t;
|
|
||||||
|
|
||||||
// __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT
|
|
||||||
enum { value = (nodes<subject_category_t>
|
|
||||||
::template count<subject_t, LeafCountT>::value + 1) };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct nodes<binary_parser_category> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename LeafCountT>
|
|
||||||
struct count {
|
|
||||||
|
|
||||||
typedef typename ParserT::left_t left_t;
|
|
||||||
typedef typename ParserT::right_t right_t;
|
|
||||||
typedef typename left_t::parser_category_t left_category_t;
|
|
||||||
typedef typename right_t::parser_category_t right_category_t;
|
|
||||||
|
|
||||||
typedef count self_t;
|
|
||||||
|
|
||||||
// __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT
|
|
||||||
enum {
|
|
||||||
leftcount = (nodes<left_category_t>
|
|
||||||
::template count<left_t, LeafCountT>::value),
|
|
||||||
rightcount = (nodes<right_category_t>
|
|
||||||
::template count<right_t, LeafCountT>::value),
|
|
||||||
value = ((self_t::leftcount) + (self_t::rightcount) + 1)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Helper template for counting the number of leaf nodes contained in a
|
|
||||||
// given parser type.
|
|
||||||
// Only plain_parser_category type parsers are counted as leaf nodes.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename CategoryT>
|
|
||||||
struct leafs;
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct leafs<plain_parser_category> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename LeafCountT>
|
|
||||||
struct count {
|
|
||||||
|
|
||||||
// __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT
|
|
||||||
enum { value = (LeafCountT::value + 1) };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct leafs<unary_parser_category> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename LeafCountT>
|
|
||||||
struct count {
|
|
||||||
|
|
||||||
typedef typename ParserT::subject_t subject_t;
|
|
||||||
typedef typename subject_t::parser_category_t subject_category_t;
|
|
||||||
|
|
||||||
typedef leafs<subject_category_t> nodes_t;
|
|
||||||
typedef typename count_wrapper<nodes_t>
|
|
||||||
::template result_<subject_t, LeafCountT> count_t;
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(int, value = count_t::value);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct leafs<action_parser_category> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename LeafCountT>
|
|
||||||
struct count {
|
|
||||||
|
|
||||||
typedef typename ParserT::subject_t subject_t;
|
|
||||||
typedef typename subject_t::parser_category_t subject_category_t;
|
|
||||||
|
|
||||||
typedef leafs<subject_category_t> nodes_t;
|
|
||||||
typedef typename count_wrapper<nodes_t>
|
|
||||||
::template result_<subject_t, LeafCountT> count_t;
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(int, value = count_t::value);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct leafs<binary_parser_category> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename LeafCountT>
|
|
||||||
struct count {
|
|
||||||
|
|
||||||
typedef typename ParserT::left_t left_t;
|
|
||||||
typedef typename ParserT::right_t right_t;
|
|
||||||
typedef typename left_t::parser_category_t left_category_t;
|
|
||||||
typedef typename right_t::parser_category_t right_category_t;
|
|
||||||
|
|
||||||
typedef leafs<left_category_t> left_nodes_t;
|
|
||||||
typedef typename count_wrapper<left_nodes_t>
|
|
||||||
::template result_<left_t, LeafCountT> left_count_t;
|
|
||||||
|
|
||||||
typedef leafs<right_category_t> right_nodes_t;
|
|
||||||
typedef typename count_wrapper<right_nodes_t>
|
|
||||||
::template result_<right_t, LeafCountT> right_count_t;
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(int,
|
|
||||||
value = (left_count_t::value + right_count_t::value));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct leafs<unary_parser_category> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename LeafCountT>
|
|
||||||
struct count {
|
|
||||||
|
|
||||||
typedef typename ParserT::subject_t subject_t;
|
|
||||||
typedef typename subject_t::parser_category_t subject_category_t;
|
|
||||||
|
|
||||||
// __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT
|
|
||||||
enum { value = (leafs<subject_category_t>
|
|
||||||
::template count<subject_t, LeafCountT>::value) };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct leafs<action_parser_category> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename LeafCountT>
|
|
||||||
struct count {
|
|
||||||
|
|
||||||
typedef typename ParserT::subject_t subject_t;
|
|
||||||
typedef typename subject_t::parser_category_t subject_category_t;
|
|
||||||
|
|
||||||
// __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT
|
|
||||||
enum { value = (leafs<subject_category_t>
|
|
||||||
::template count<subject_t, LeafCountT>::value) };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct leafs<binary_parser_category> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename LeafCountT>
|
|
||||||
struct count {
|
|
||||||
|
|
||||||
typedef typename ParserT::left_t left_t;
|
|
||||||
typedef typename ParserT::right_t right_t;
|
|
||||||
typedef typename left_t::parser_category_t left_category_t;
|
|
||||||
typedef typename right_t::parser_category_t right_category_t;
|
|
||||||
|
|
||||||
typedef count self_t;
|
|
||||||
|
|
||||||
// __BORLANDC__ == 0x0561 isn't happy with BOOST_STATIC_CONSTANT
|
|
||||||
enum {
|
|
||||||
leftcount = (leafs<left_category_t>
|
|
||||||
::template count<left_t, LeafCountT>::value),
|
|
||||||
rightcount = (leafs<right_category_t>
|
|
||||||
::template count<right_t, LeafCountT>::value),
|
|
||||||
value = (self_t::leftcount + self_t::rightcount)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace impl
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif // !defined(BOOST_SPIRIT_FUNDAMENTAL_IPP)
|
|
@ -1,187 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2002-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
|
||||||
Copyright (c) 2003 Martin Wille
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_PARSER_TRAITS_IPP)
|
|
||||||
#define BOOST_SPIRIT_PARSER_TRAITS_IPP
|
|
||||||
|
|
||||||
#include <boost/spirit/core/composite/operators.hpp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
|
|
||||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// from spirit 1.1 (copyright (c) 2001 Bruce Florman)
|
|
||||||
// various workarounds to support compile time decisions without partial
|
|
||||||
// template specialization whether a given type is an instance of a
|
|
||||||
// concrete parser type.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
struct parser_type_traits
|
|
||||||
{
|
|
||||||
// Determine at compile time (without partial specialization)
|
|
||||||
// whether a given type is an instance of the alternative<A,B>
|
|
||||||
|
|
||||||
static T t();
|
|
||||||
|
|
||||||
typedef struct { char dummy[1]; } size1_t;
|
|
||||||
typedef struct { char dummy[2]; } size2_t;
|
|
||||||
typedef struct { char dummy[3]; } size3_t;
|
|
||||||
typedef struct { char dummy[4]; } size4_t;
|
|
||||||
typedef struct { char dummy[5]; } size5_t;
|
|
||||||
typedef struct { char dummy[6]; } size6_t;
|
|
||||||
typedef struct { char dummy[7]; } size7_t;
|
|
||||||
typedef struct { char dummy[8]; } size8_t;
|
|
||||||
typedef struct { char dummy[9]; } size9_t;
|
|
||||||
typedef struct { char dummy[10]; } size10_t;
|
|
||||||
|
|
||||||
// the following functions need no implementation
|
|
||||||
template <typename A, typename B>
|
|
||||||
static size1_t test_(alternative<A, B> const&);
|
|
||||||
template <typename A, typename B>
|
|
||||||
static size2_t test_(sequence<A, B> const&);
|
|
||||||
template <typename A, typename B>
|
|
||||||
static size3_t test_(sequential_or<A, B> const&);
|
|
||||||
template <typename A, typename B>
|
|
||||||
static size4_t test_(intersection<A, B> const&);
|
|
||||||
template <typename A, typename B>
|
|
||||||
static size5_t test_(difference<A, B> const&);
|
|
||||||
template <typename A, typename B>
|
|
||||||
static size6_t test_(exclusive_or<A, B> const&);
|
|
||||||
template <typename S>
|
|
||||||
static size7_t test_(optional<S> const&);
|
|
||||||
template <typename S>
|
|
||||||
static size8_t test_(kleene_star<S> const&);
|
|
||||||
template <typename S>
|
|
||||||
static size9_t test_(positive<S> const&);
|
|
||||||
|
|
||||||
static size10_t test_(...);
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool,
|
|
||||||
is_alternative = (sizeof(size1_t) == sizeof(test_(t()))) );
|
|
||||||
BOOST_STATIC_CONSTANT(bool,
|
|
||||||
is_sequence = (sizeof(size2_t) == sizeof(test_(t()))) );
|
|
||||||
BOOST_STATIC_CONSTANT(bool,
|
|
||||||
is_sequential_or = (sizeof(size3_t) == sizeof(test_(t()))) );
|
|
||||||
BOOST_STATIC_CONSTANT(bool,
|
|
||||||
is_intersection = (sizeof(size4_t) == sizeof(test_(t()))) );
|
|
||||||
BOOST_STATIC_CONSTANT(bool,
|
|
||||||
is_difference = (sizeof(size5_t) == sizeof(test_(t()))) );
|
|
||||||
BOOST_STATIC_CONSTANT(bool,
|
|
||||||
is_exclusive_or = (sizeof(size6_t) == sizeof(test_(t()))) );
|
|
||||||
BOOST_STATIC_CONSTANT(bool,
|
|
||||||
is_optional = (sizeof(size7_t) == sizeof(test_(t()))) );
|
|
||||||
BOOST_STATIC_CONSTANT(bool,
|
|
||||||
is_kleene_star = (sizeof(size8_t) == sizeof(test_(t()))) );
|
|
||||||
BOOST_STATIC_CONSTANT(bool,
|
|
||||||
is_positive = (sizeof(size9_t) == sizeof(test_(t()))) );
|
|
||||||
};
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct parser_type_traits_base {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, is_alternative = false);
|
|
||||||
BOOST_STATIC_CONSTANT(bool, is_sequence = false);
|
|
||||||
BOOST_STATIC_CONSTANT(bool, is_sequential_or = false);
|
|
||||||
BOOST_STATIC_CONSTANT(bool, is_intersection = false);
|
|
||||||
BOOST_STATIC_CONSTANT(bool, is_difference = false);
|
|
||||||
BOOST_STATIC_CONSTANT(bool, is_exclusive_or = false);
|
|
||||||
BOOST_STATIC_CONSTANT(bool, is_optional = false);
|
|
||||||
BOOST_STATIC_CONSTANT(bool, is_kleene_star = false);
|
|
||||||
BOOST_STATIC_CONSTANT(bool, is_positive = false);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
struct parser_type_traits : public parser_type_traits_base {
|
|
||||||
|
|
||||||
// no definition here, fallback for all not explicitly mentioned parser
|
|
||||||
// types
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct parser_type_traits<alternative<A, B> >
|
|
||||||
: public parser_type_traits_base {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, is_alternative = true);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct parser_type_traits<sequence<A, B> >
|
|
||||||
: public parser_type_traits_base {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, is_sequence = true);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct parser_type_traits<sequential_or<A, B> >
|
|
||||||
: public parser_type_traits_base {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, is_sequential_or = true);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct parser_type_traits<intersection<A, B> >
|
|
||||||
: public parser_type_traits_base {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, is_intersection = true);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct parser_type_traits<difference<A, B> >
|
|
||||||
: public parser_type_traits_base {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, is_difference = true);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
struct parser_type_traits<exclusive_or<A, B> >
|
|
||||||
: public parser_type_traits_base {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, is_exclusive_or = true);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename S>
|
|
||||||
struct parser_type_traits<optional<S> >
|
|
||||||
: public parser_type_traits_base {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, is_optional = true);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename S>
|
|
||||||
struct parser_type_traits<kleene_star<S> >
|
|
||||||
: public parser_type_traits_base {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, is_kleene_star = true);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename S>
|
|
||||||
struct parser_type_traits<positive<S> >
|
|
||||||
: public parser_type_traits_base {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, is_positive = true);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
|
||||||
} // namespace impl
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif // !defined(BOOST_SPIRIT_PARSER_TRAITS_IPP)
|
|
@ -1,447 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_REFACTORING_IPP
|
|
||||||
#define BOOST_SPIRIT_REFACTORING_IPP
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// The struct 'self_nested_refactoring' is used to indicate, that the
|
|
||||||
// refactoring algorithm should be 'self-nested'.
|
|
||||||
//
|
|
||||||
// The struct 'non_nested_refactoring' is used to indicate, that no nesting
|
|
||||||
// of refactoring algorithms is reqired.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
struct non_nested_refactoring { typedef non_nested_refactoring embed_t; };
|
|
||||||
struct self_nested_refactoring { typedef self_nested_refactoring embed_t; };
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Helper templates for refactoring parsers
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// refactor the left unary operand of a binary parser
|
|
||||||
//
|
|
||||||
// The refactoring should be done only if the left operand is an
|
|
||||||
// unary_parser_category parser.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename CategoryT>
|
|
||||||
struct refactor_unary_nested {
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename ParserT, typename NestedT,
|
|
||||||
typename ScannerT, typename BinaryT
|
|
||||||
>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &, ScannerT const& scan, BinaryT const& binary,
|
|
||||||
NestedT const& /*nested_d*/)
|
|
||||||
{
|
|
||||||
return binary.parse(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct refactor_unary_nested<unary_parser_category> {
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename ParserT, typename ScannerT, typename BinaryT,
|
|
||||||
typename NestedT
|
|
||||||
>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &, ScannerT const& scan, BinaryT const& binary,
|
|
||||||
NestedT const& nested_d)
|
|
||||||
{
|
|
||||||
typedef typename BinaryT::parser_generator_t op_t;
|
|
||||||
typedef
|
|
||||||
typename BinaryT::left_t::parser_generator_t
|
|
||||||
unary_t;
|
|
||||||
|
|
||||||
return
|
|
||||||
unary_t::generate(
|
|
||||||
nested_d[
|
|
||||||
op_t::generate(binary.left().subject(), binary.right())
|
|
||||||
]
|
|
||||||
).parse(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename CategoryT>
|
|
||||||
struct refactor_unary_non_nested {
|
|
||||||
|
|
||||||
template <typename ParserT, typename ScannerT, typename BinaryT>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &, ScannerT const& scan, BinaryT const& binary)
|
|
||||||
{
|
|
||||||
return binary.parse(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct refactor_unary_non_nested<unary_parser_category> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename ScannerT, typename BinaryT>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &, ScannerT const& scan, BinaryT const& binary)
|
|
||||||
{
|
|
||||||
typedef typename BinaryT::parser_generator_t op_t;
|
|
||||||
typedef
|
|
||||||
typename BinaryT::left_t::parser_generator_t
|
|
||||||
unary_t;
|
|
||||||
|
|
||||||
return unary_t::generate(
|
|
||||||
op_t::generate(binary.left().subject(), binary.right())
|
|
||||||
).parse(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename NestedT>
|
|
||||||
struct refactor_unary_type {
|
|
||||||
|
|
||||||
template <typename ParserT, typename ScannerT, typename BinaryT>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary,
|
|
||||||
NestedT const& nested_d)
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
typename BinaryT::left_t::parser_category_t
|
|
||||||
parser_category_t;
|
|
||||||
|
|
||||||
return refactor_unary_nested<parser_category_t>::
|
|
||||||
parse(p, scan, binary, nested_d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct refactor_unary_type<non_nested_refactoring> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename ScannerT, typename BinaryT>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary,
|
|
||||||
non_nested_refactoring const&)
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
typename BinaryT::left_t::parser_category_t
|
|
||||||
parser_category_t;
|
|
||||||
|
|
||||||
return refactor_unary_non_nested<parser_category_t>::
|
|
||||||
parse(p, scan, binary);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct refactor_unary_type<self_nested_refactoring> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename ScannerT, typename BinaryT>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary,
|
|
||||||
self_nested_refactoring const &nested_tag)
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
typename BinaryT::left_t::parser_category_t
|
|
||||||
parser_category_t;
|
|
||||||
typedef typename ParserT::parser_generator_t parser_generator_t;
|
|
||||||
|
|
||||||
parser_generator_t nested_d(nested_tag);
|
|
||||||
return refactor_unary_nested<parser_category_t>::
|
|
||||||
parse(p, scan, binary, nested_d);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// refactor the action on the left operand of a binary parser
|
|
||||||
//
|
|
||||||
// The refactoring should be done only if the left operand is an
|
|
||||||
// action_parser_category parser.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename CategoryT>
|
|
||||||
struct refactor_action_nested {
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename ParserT, typename ScannerT, typename BinaryT,
|
|
||||||
typename NestedT
|
|
||||||
>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &, ScannerT const& scan, BinaryT const& binary,
|
|
||||||
NestedT const& nested_d)
|
|
||||||
{
|
|
||||||
return nested_d[binary].parse(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct refactor_action_nested<action_parser_category> {
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename ParserT, typename ScannerT, typename BinaryT,
|
|
||||||
typename NestedT
|
|
||||||
>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &, ScannerT const& scan, BinaryT const& binary,
|
|
||||||
NestedT const& nested_d)
|
|
||||||
{
|
|
||||||
typedef typename BinaryT::parser_generator_t binary_gen_t;
|
|
||||||
|
|
||||||
return (
|
|
||||||
nested_d[
|
|
||||||
binary_gen_t::generate(
|
|
||||||
binary.left().subject(),
|
|
||||||
binary.right()
|
|
||||||
)
|
|
||||||
][binary.left().predicate()]
|
|
||||||
).parse(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename CategoryT>
|
|
||||||
struct refactor_action_non_nested {
|
|
||||||
|
|
||||||
template <typename ParserT, typename ScannerT, typename BinaryT>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &, ScannerT const& scan, BinaryT const& binary)
|
|
||||||
{
|
|
||||||
return binary.parse(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct refactor_action_non_nested<action_parser_category> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename ScannerT, typename BinaryT>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &, ScannerT const& scan, BinaryT const& binary)
|
|
||||||
{
|
|
||||||
typedef typename BinaryT::parser_generator_t binary_gen_t;
|
|
||||||
|
|
||||||
return (
|
|
||||||
binary_gen_t::generate(
|
|
||||||
binary.left().subject(),
|
|
||||||
binary.right()
|
|
||||||
)[binary.left().predicate()]
|
|
||||||
).parse(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename NestedT>
|
|
||||||
struct refactor_action_type {
|
|
||||||
|
|
||||||
template <typename ParserT, typename ScannerT, typename BinaryT>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary,
|
|
||||||
NestedT const& nested_d)
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
typename BinaryT::left_t::parser_category_t
|
|
||||||
parser_category_t;
|
|
||||||
|
|
||||||
return refactor_action_nested<parser_category_t>::
|
|
||||||
parse(p, scan, binary, nested_d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct refactor_action_type<non_nested_refactoring> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename ScannerT, typename BinaryT>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary,
|
|
||||||
non_nested_refactoring const&)
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
typename BinaryT::left_t::parser_category_t
|
|
||||||
parser_category_t;
|
|
||||||
|
|
||||||
return refactor_action_non_nested<parser_category_t>::
|
|
||||||
parse(p, scan, binary);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct refactor_action_type<self_nested_refactoring> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename ScannerT, typename BinaryT>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &p, ScannerT const& scan, BinaryT const& binary,
|
|
||||||
self_nested_refactoring const &nested_tag)
|
|
||||||
{
|
|
||||||
typedef typename ParserT::parser_generator_t parser_generator_t;
|
|
||||||
typedef
|
|
||||||
typename BinaryT::left_t::parser_category_t
|
|
||||||
parser_category_t;
|
|
||||||
|
|
||||||
parser_generator_t nested_d(nested_tag);
|
|
||||||
return refactor_action_nested<parser_category_t>::
|
|
||||||
parse(p, scan, binary, nested_d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// refactor the action attached to a binary parser
|
|
||||||
//
|
|
||||||
// The refactoring should be done only if the given parser is an
|
|
||||||
// binary_parser_category parser.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename CategoryT>
|
|
||||||
struct attach_action_nested {
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename ParserT, typename ScannerT, typename ActionT,
|
|
||||||
typename NestedT
|
|
||||||
>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &, ScannerT const& scan, ActionT const &action,
|
|
||||||
NestedT const& nested_d)
|
|
||||||
{
|
|
||||||
return action.parse(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct attach_action_nested<binary_parser_category> {
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename ParserT, typename ScannerT, typename ActionT,
|
|
||||||
typename NestedT
|
|
||||||
>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &, ScannerT const& scan, ActionT const &action,
|
|
||||||
NestedT const& nested_d)
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
typename ActionT::subject_t::parser_generator_t
|
|
||||||
binary_gen_t;
|
|
||||||
|
|
||||||
return (
|
|
||||||
binary_gen_t::generate(
|
|
||||||
nested_d[action.subject().left()[action.predicate()]],
|
|
||||||
nested_d[action.subject().right()[action.predicate()]]
|
|
||||||
)
|
|
||||||
).parse(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename CategoryT>
|
|
||||||
struct attach_action_non_nested {
|
|
||||||
|
|
||||||
template <typename ParserT, typename ScannerT, typename ActionT>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &, ScannerT const& scan, ActionT const &action)
|
|
||||||
{
|
|
||||||
return action.parse(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct attach_action_non_nested<binary_parser_category> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename ScannerT, typename ActionT>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &, ScannerT const& scan, ActionT const &action)
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
typename ActionT::subject_t::parser_generator_t
|
|
||||||
binary_gen_t;
|
|
||||||
|
|
||||||
return (
|
|
||||||
binary_gen_t::generate(
|
|
||||||
action.subject().left()[action.predicate()],
|
|
||||||
action.subject().right()[action.predicate()]
|
|
||||||
)
|
|
||||||
).parse(scan);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename NestedT>
|
|
||||||
struct attach_action_type {
|
|
||||||
|
|
||||||
template <typename ParserT, typename ScannerT, typename ActionT>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &p, ScannerT const& scan, ActionT const& action,
|
|
||||||
NestedT const& nested_d)
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
typename ActionT::subject_t::parser_category_t
|
|
||||||
parser_category_t;
|
|
||||||
|
|
||||||
return attach_action_nested<parser_category_t>::
|
|
||||||
parse(p, scan, action, nested_d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct attach_action_type<non_nested_refactoring> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename ScannerT, typename ActionT>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &p, ScannerT const& scan, ActionT const &action,
|
|
||||||
non_nested_refactoring const&)
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
typename ActionT::subject_t::parser_category_t
|
|
||||||
parser_category_t;
|
|
||||||
|
|
||||||
return attach_action_non_nested<parser_category_t>::
|
|
||||||
parse(p, scan, action);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct attach_action_type<self_nested_refactoring> {
|
|
||||||
|
|
||||||
template <typename ParserT, typename ScannerT, typename ActionT>
|
|
||||||
static typename parser_result<ParserT, ScannerT>::type
|
|
||||||
parse(ParserT const &p, ScannerT const& scan, ActionT const &action,
|
|
||||||
self_nested_refactoring const& nested_tag)
|
|
||||||
{
|
|
||||||
typedef typename ParserT::parser_generator_t parser_generator_t;
|
|
||||||
typedef
|
|
||||||
typename ActionT::subject_t::parser_category_t
|
|
||||||
parser_category_t;
|
|
||||||
|
|
||||||
parser_generator_t nested_d(nested_tag);
|
|
||||||
return attach_action_nested<parser_category_t>::
|
|
||||||
parse(p, scan, action, nested_d);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace impl
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,389 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2002-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_TRAVERSE_IPP)
|
|
||||||
#define BOOST_SPIRIT_TRAVERSE_IPP
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <boost/spirit/meta/fundamental.hpp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
|
|
||||||
template <typename CategoryT>
|
|
||||||
struct traverse_post_order_return_category;
|
|
||||||
|
|
||||||
} // namespace impl
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Environment class for post_order_traversal
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template <int Level, int Node, int Index, int LastLeft>
|
|
||||||
struct traverse_post_order_env {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(int, level = Level);
|
|
||||||
BOOST_STATIC_CONSTANT(int, node = Node);
|
|
||||||
BOOST_STATIC_CONSTANT(int, index = Index);
|
|
||||||
BOOST_STATIC_CONSTANT(int, lastleft = LastLeft);
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// traverse_post_order_return template
|
|
||||||
//
|
|
||||||
// This template is a helper for dispatching the calculation of a parser
|
|
||||||
// type result for a traversal level to the corresponding parser_category
|
|
||||||
// based specialization.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template <typename MetaT, typename ParserT, typename EnvT>
|
|
||||||
struct traverse_post_order_return {
|
|
||||||
|
|
||||||
typedef typename ParserT::parser_category_t parser_category_t;
|
|
||||||
typedef typename impl::traverse_post_order_return_category<parser_category_t>
|
|
||||||
::template result<MetaT, ParserT, EnvT>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// parser_traversal_..._result templates
|
|
||||||
//
|
|
||||||
// These are metafunctions, which calculate the resulting parser type
|
|
||||||
// for all subparsers and feed these types to the user supplied
|
|
||||||
// metafunctions to get back the resulting parser type of this traversal
|
|
||||||
// level.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template <typename MetaT, typename ParserT, typename EnvT>
|
|
||||||
struct parser_traversal_plain_result {
|
|
||||||
|
|
||||||
typedef typename MetaT::template plain_result<ParserT, EnvT>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename MetaT, typename UnaryT, typename SubjectT, typename EnvT>
|
|
||||||
struct parser_traversal_unary_result {
|
|
||||||
|
|
||||||
typedef typename MetaT
|
|
||||||
::template unary_result<UnaryT, SubjectT, EnvT>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename MetaT, typename ActionT, typename SubjectT, typename EnvT>
|
|
||||||
struct parser_traversal_action_result {
|
|
||||||
|
|
||||||
typedef typename MetaT
|
|
||||||
::template action_result<ActionT, SubjectT, EnvT>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <
|
|
||||||
typename MetaT, typename BinaryT, typename LeftT,
|
|
||||||
typename RightT, typename EnvT
|
|
||||||
>
|
|
||||||
struct parser_traversal_binary_result {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(int,
|
|
||||||
thisnum = (node_count<BinaryT>::value + EnvT::lastleft-1));
|
|
||||||
BOOST_STATIC_CONSTANT(int,
|
|
||||||
leftnum = (node_count<LeftT>::value + EnvT::lastleft-1));
|
|
||||||
BOOST_STATIC_CONSTANT(int,
|
|
||||||
leafnum = (leaf_count<LeftT>::value + EnvT::index));
|
|
||||||
|
|
||||||
typedef parser_traversal_binary_result self_t;
|
|
||||||
|
|
||||||
// left traversal environment and resulting parser type
|
|
||||||
typedef traverse_post_order_env<
|
|
||||||
(EnvT::level+1), (self_t::leftnum), (EnvT::index), (EnvT::lastleft)
|
|
||||||
> left_sub_env_t;
|
|
||||||
typedef typename traverse_post_order_return<
|
|
||||||
MetaT, LeftT, left_sub_env_t
|
|
||||||
>::type
|
|
||||||
left_t;
|
|
||||||
|
|
||||||
// right traversal environment and resulting parser type
|
|
||||||
typedef traverse_post_order_env<
|
|
||||||
(EnvT::level+1), (self_t::thisnum-1), (self_t::leafnum), (self_t::leftnum+1)
|
|
||||||
> right_sub_env_t;
|
|
||||||
typedef typename traverse_post_order_return<
|
|
||||||
MetaT, RightT, right_sub_env_t
|
|
||||||
>::type
|
|
||||||
right_t;
|
|
||||||
|
|
||||||
typedef typename MetaT::template binary_result<
|
|
||||||
BinaryT, left_t, right_t, EnvT
|
|
||||||
>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Meta functions, which dispatch the calculation of the return type of
|
|
||||||
// of the post_order traverse function to the result template of the
|
|
||||||
// corresponding parser_category based metafunction template.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template <typename CategoryT>
|
|
||||||
struct traverse_post_order_return_category;
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct traverse_post_order_return_category<plain_parser_category> {
|
|
||||||
|
|
||||||
template <typename MetaT, typename ParserT, typename EnvT>
|
|
||||||
struct result {
|
|
||||||
|
|
||||||
typedef typename parser_traversal_plain_result<
|
|
||||||
MetaT, ParserT, EnvT
|
|
||||||
>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct traverse_post_order_return_category<unary_parser_category> {
|
|
||||||
|
|
||||||
template <typename MetaT, typename ParserT, typename EnvT>
|
|
||||||
struct result {
|
|
||||||
|
|
||||||
typedef typename parser_traversal_unary_result<
|
|
||||||
MetaT, ParserT, typename ParserT::subject_t, EnvT
|
|
||||||
>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct traverse_post_order_return_category<action_parser_category> {
|
|
||||||
|
|
||||||
template <typename MetaT, typename ParserT, typename EnvT>
|
|
||||||
struct result {
|
|
||||||
|
|
||||||
typedef typename parser_traversal_action_result<
|
|
||||||
MetaT, ParserT, typename ParserT::subject_t, EnvT
|
|
||||||
>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct traverse_post_order_return_category<binary_parser_category> {
|
|
||||||
|
|
||||||
template <typename MetaT, typename ParserT, typename EnvT>
|
|
||||||
struct result {
|
|
||||||
|
|
||||||
typedef typename parser_traversal_binary_result<
|
|
||||||
MetaT, ParserT, typename ParserT::left_t,
|
|
||||||
typename ParserT::right_t, EnvT
|
|
||||||
>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Post-order parser traversal
|
|
||||||
//
|
|
||||||
// The following templates contain the parser_category based code for
|
|
||||||
//
|
|
||||||
// - calculating the type of the resulting parser, which is to be
|
|
||||||
// returned from a level of traversal
|
|
||||||
// - traversing down the composite parser structure, this traversal
|
|
||||||
// returnes a new parser object
|
|
||||||
//
|
|
||||||
// Both tasks are delegated to the MetaT metafunction supplied by the
|
|
||||||
// user.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template <typename CategoryT>
|
|
||||||
struct traverse_post_order;
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct traverse_post_order<plain_parser_category> {
|
|
||||||
|
|
||||||
template <typename MetaT, typename ParserT, typename EnvT>
|
|
||||||
struct result {
|
|
||||||
|
|
||||||
typedef
|
|
||||||
typename parser_traversal_plain_result<MetaT, ParserT, EnvT>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename MetaT, typename ParserT, typename EnvT>
|
|
||||||
static
|
|
||||||
typename parser_traversal_plain_result<MetaT, ParserT, EnvT>::type
|
|
||||||
generate(MetaT const &meta_, ParserT const &parser_, EnvT const &env)
|
|
||||||
{
|
|
||||||
return meta_.generate_plain(parser_, env);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct traverse_post_order<unary_parser_category> {
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename MetaT, typename ParserT, typename SubjectT, typename EnvT
|
|
||||||
>
|
|
||||||
struct result {
|
|
||||||
|
|
||||||
typedef typename parser_traversal_unary_result<
|
|
||||||
MetaT, ParserT, SubjectT, EnvT
|
|
||||||
>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename MetaT, typename ParserT, typename EnvT>
|
|
||||||
static
|
|
||||||
typename parser_traversal_unary_result<
|
|
||||||
MetaT, ParserT,
|
|
||||||
typename traverse_post_order_return<
|
|
||||||
MetaT, typename ParserT::subject_t, EnvT
|
|
||||||
>::type,
|
|
||||||
EnvT
|
|
||||||
>::type
|
|
||||||
generate(MetaT const &meta_, ParserT const &unary_, EnvT const &env)
|
|
||||||
{
|
|
||||||
typedef typename ParserT::subject_t subject_t;
|
|
||||||
typedef typename subject_t::parser_category_t subject_category_t;
|
|
||||||
|
|
||||||
return meta_.generate_unary(
|
|
||||||
unary_,
|
|
||||||
traverse_post_order<subject_category_t>::generate(meta_,
|
|
||||||
unary_.subject(),
|
|
||||||
traverse_post_order_env<
|
|
||||||
EnvT::level+1, EnvT::node-1, EnvT::index, EnvT::lastleft
|
|
||||||
>()
|
|
||||||
),
|
|
||||||
env
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct traverse_post_order<action_parser_category> {
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename MetaT, typename ParserT, typename SubjectT, typename EnvT
|
|
||||||
>
|
|
||||||
struct result {
|
|
||||||
|
|
||||||
typedef typename parser_traversal_action_result<
|
|
||||||
MetaT, ParserT, SubjectT, EnvT
|
|
||||||
>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename MetaT, typename ParserT, typename EnvT>
|
|
||||||
static
|
|
||||||
typename parser_traversal_action_result<
|
|
||||||
MetaT, ParserT,
|
|
||||||
typename traverse_post_order_return<
|
|
||||||
MetaT, typename ParserT::subject_t, EnvT
|
|
||||||
>::type,
|
|
||||||
EnvT
|
|
||||||
>::type
|
|
||||||
generate(MetaT const &meta_, ParserT const &action_, EnvT const &env)
|
|
||||||
{
|
|
||||||
typedef typename ParserT::subject_t subject_t;
|
|
||||||
typedef typename subject_t::parser_category_t subject_category_t;
|
|
||||||
|
|
||||||
return meta_.generate_action(
|
|
||||||
action_,
|
|
||||||
traverse_post_order<subject_category_t>::generate(meta_,
|
|
||||||
action_.subject(),
|
|
||||||
traverse_post_order_env<
|
|
||||||
EnvT::level+1, EnvT::node-1, EnvT::index, EnvT::lastleft
|
|
||||||
>()
|
|
||||||
),
|
|
||||||
env
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct traverse_post_order<binary_parser_category> {
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename MetaT, typename ParserT, typename LeftT,
|
|
||||||
typename RightT, typename EnvT
|
|
||||||
>
|
|
||||||
struct result {
|
|
||||||
|
|
||||||
typedef typename parser_traversal_binary_result<
|
|
||||||
MetaT, ParserT, LeftT, RightT, EnvT
|
|
||||||
>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename MetaT, typename ParserT, typename EnvT>
|
|
||||||
static
|
|
||||||
typename parser_traversal_binary_result<
|
|
||||||
MetaT, ParserT,
|
|
||||||
typename traverse_post_order_return<
|
|
||||||
MetaT, typename ParserT::left_t, EnvT
|
|
||||||
>::type,
|
|
||||||
typename traverse_post_order_return<
|
|
||||||
MetaT, typename ParserT::right_t, EnvT
|
|
||||||
>::type,
|
|
||||||
EnvT
|
|
||||||
>::type
|
|
||||||
generate(MetaT const &meta_, ParserT const &binary_, EnvT const& /*env*/)
|
|
||||||
{
|
|
||||||
typedef typename ParserT::left_t left_t;
|
|
||||||
typedef typename ParserT::right_t right_t;
|
|
||||||
typedef typename left_t::parser_category_t left_category_t;
|
|
||||||
typedef typename right_t::parser_category_t right_category_t;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
leftnum = (node_count<left_t>::value + EnvT::lastleft-1),
|
|
||||||
thisnum = (node_count<ParserT>::value + EnvT::lastleft-1),
|
|
||||||
rightnum = (thisnum-1),
|
|
||||||
leafnum = (leaf_count<left_t>::value + EnvT::index)
|
|
||||||
};
|
|
||||||
|
|
||||||
return meta_.generate_binary(
|
|
||||||
binary_,
|
|
||||||
traverse_post_order<left_category_t>::generate(
|
|
||||||
meta_, binary_.left(),
|
|
||||||
traverse_post_order_env<
|
|
||||||
EnvT::level+1, leftnum, EnvT::index, EnvT::lastleft
|
|
||||||
>()
|
|
||||||
),
|
|
||||||
traverse_post_order<right_category_t>::generate(
|
|
||||||
meta_, binary_.right(),
|
|
||||||
traverse_post_order_env<
|
|
||||||
EnvT::level+1, rightnum, leafnum, leftnum+1
|
|
||||||
>()
|
|
||||||
),
|
|
||||||
traverse_post_order_env<
|
|
||||||
EnvT::level, thisnum, EnvT::index, EnvT::lastleft
|
|
||||||
>()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace impl
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif // !defined(BOOST_SPIRIT_TRAVERSE_IPP)
|
|
@ -1,316 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2002-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
|
||||||
Copyright (c) 2003 Martin Wille
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_PARSER_TRAITS_HPP)
|
|
||||||
#define BOOST_SPIRIT_PARSER_TRAITS_HPP
|
|
||||||
|
|
||||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
|
||||||
#include <boost/static_assert.hpp>
|
|
||||||
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/meta/impl/parser_traits.ipp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Parser traits templates
|
|
||||||
//
|
|
||||||
// Used to determine the type and several other characteristics of a given
|
|
||||||
// parser type.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// The is_parser traits template can be used to tell wether a given
|
|
||||||
// class is a parser.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
struct is_parser
|
|
||||||
{
|
|
||||||
BOOST_STATIC_CONSTANT(bool, value =
|
|
||||||
(::boost::is_base_and_derived<parser<T>, T>::value));
|
|
||||||
|
|
||||||
// [JDG 2/3/03] simplified implementation by
|
|
||||||
// using boost::is_base_and_derived
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// The is_unary_composite traits template can be used to tell if a given
|
|
||||||
// parser is a unary parser as for instance kleene_star or optional.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename UnaryT>
|
|
||||||
struct is_unary_composite {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, value = (::boost::is_convertible<
|
|
||||||
typename UnaryT::parser_category_t, unary_parser_category>::value));
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// The is_acction_parser traits template can be used to tell if a given
|
|
||||||
// parser is a action parser, i.e. it is a composite consisting of a
|
|
||||||
// auxilliary parser and an attached semantic action.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ActionT>
|
|
||||||
struct is_action_parser {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, value = (::boost::is_convertible<
|
|
||||||
typename ActionT::parser_category_t, action_parser_category>::value));
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// The is_binary_composite traits template can be used to tell if a given
|
|
||||||
// parser is a binary parser as for instance sequence or difference.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename BinaryT>
|
|
||||||
struct is_binary_composite {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, value = (::boost::is_convertible<
|
|
||||||
typename BinaryT::parser_category_t, binary_parser_category>::value));
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// The is_composite_parser traits template can be used to tell if a given
|
|
||||||
// parser is a unary or a binary parser composite type.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename CompositeT>
|
|
||||||
struct is_composite_parser {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, value = (
|
|
||||||
::boost::spirit::is_unary_composite<CompositeT>::value ||
|
|
||||||
::boost::spirit::is_binary_composite<CompositeT>::value));
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ParserT>
|
|
||||||
struct is_alternative {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, value = (
|
|
||||||
::boost::spirit::impl::parser_type_traits<ParserT>::is_alternative));
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
struct is_sequence {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, value = (
|
|
||||||
::boost::spirit::impl::parser_type_traits<ParserT>::is_sequence));
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
struct is_sequential_or {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, value = (
|
|
||||||
::boost::spirit::impl::parser_type_traits<ParserT>::is_sequential_or));
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
struct is_intersection {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, value = (
|
|
||||||
::boost::spirit::impl::parser_type_traits<ParserT>::is_intersection));
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
struct is_difference {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, value = (
|
|
||||||
::boost::spirit::impl::parser_type_traits<ParserT>::is_difference));
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
struct is_exclusive_or {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, value = (
|
|
||||||
::boost::spirit::impl::parser_type_traits<ParserT>::is_exclusive_or));
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
struct is_optional {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, value = (
|
|
||||||
::boost::spirit::impl::parser_type_traits<ParserT>::is_optional));
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
struct is_kleene_star {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, value = (
|
|
||||||
::boost::spirit::impl::parser_type_traits<ParserT>::is_kleene_star));
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
struct is_positive {
|
|
||||||
|
|
||||||
BOOST_STATIC_CONSTANT(bool, value = (
|
|
||||||
::boost::spirit::impl::parser_type_traits<ParserT>::is_positive));
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Parser extraction templates
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// The unary_subject template can be used to return the type of the
|
|
||||||
// parser used as the subject of an unary parser.
|
|
||||||
// If the parser under inspection is not an unary type parser the compilation
|
|
||||||
// will fail.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename UnaryT>
|
|
||||||
struct unary_subject {
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(::boost::spirit::is_unary_composite<UnaryT>::value);
|
|
||||||
typedef typename UnaryT::subject_t type;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// The get_unary_subject template function returns the parser object, which
|
|
||||||
// is used as the subject of an unary parser.
|
|
||||||
// If the parser under inspection is not an unary type parser the compilation
|
|
||||||
// will fail.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename UnaryT>
|
|
||||||
inline typename unary_subject<UnaryT>::type const &
|
|
||||||
get_unary_subject(UnaryT const &unary_)
|
|
||||||
{
|
|
||||||
BOOST_STATIC_ASSERT(::boost::spirit::is_unary_composite<UnaryT>::value);
|
|
||||||
return unary_.subject();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// The binary_left_subject and binary_right_subject templates can be used to
|
|
||||||
// return the types of the parsers used as the left and right subject of an
|
|
||||||
// binary parser.
|
|
||||||
// If the parser under inspection is not a binary type parser the compilation
|
|
||||||
// will fail.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename BinaryT>
|
|
||||||
struct binary_left_subject {
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(::boost::spirit::is_binary_composite<BinaryT>::value);
|
|
||||||
typedef typename BinaryT::left_t type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename BinaryT>
|
|
||||||
struct binary_right_subject {
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(::boost::spirit::is_binary_composite<BinaryT>::value);
|
|
||||||
typedef typename BinaryT::right_t type;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// The get_binary_left_subject and get_binary_right_subject template functions
|
|
||||||
// return the parser object, which is used as the left or right subject of a
|
|
||||||
// binary parser.
|
|
||||||
// If the parser under inspection is not a binary type parser the compilation
|
|
||||||
// will fail.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename BinaryT>
|
|
||||||
inline typename binary_left_subject<BinaryT>::type const &
|
|
||||||
get_binary_left_subject(BinaryT const &binary_)
|
|
||||||
{
|
|
||||||
BOOST_STATIC_ASSERT(::boost::spirit::is_binary_composite<BinaryT>::value);
|
|
||||||
return binary_.left();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename BinaryT>
|
|
||||||
inline typename binary_right_subject<BinaryT>::type const &
|
|
||||||
get_binary_right_subject(BinaryT const &binary_)
|
|
||||||
{
|
|
||||||
BOOST_STATIC_ASSERT(::boost::spirit::is_binary_composite<BinaryT>::value);
|
|
||||||
return binary_.right();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// The action_subject template can be used to return the type of the
|
|
||||||
// parser used as the subject of an action parser.
|
|
||||||
// If the parser under inspection is not an action type parser the compilation
|
|
||||||
// will fail.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ActionT>
|
|
||||||
struct action_subject {
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(::boost::spirit::is_action_parser<ActionT>::value);
|
|
||||||
typedef typename ActionT::subject_t type;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// The get_action_subject template function returns the parser object, which
|
|
||||||
// is used as the subject of an action parser.
|
|
||||||
// If the parser under inspection is not an action type parser the compilation
|
|
||||||
// will fail.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ActionT>
|
|
||||||
inline typename action_subject<ActionT>::type const &
|
|
||||||
get_action_subject(ActionT const &action_)
|
|
||||||
{
|
|
||||||
BOOST_STATIC_ASSERT(::boost::spirit::is_action_parser<ActionT>::value);
|
|
||||||
return action_.subject();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// The semantic_action template can be used to return the type of the
|
|
||||||
// attached semantic action of an action parser.
|
|
||||||
// If the parser under inspection is not an action type parser the compilation
|
|
||||||
// will fail.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ActionT>
|
|
||||||
struct semantic_action {
|
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(::boost::spirit::is_action_parser<ActionT>::value);
|
|
||||||
typedef typename ActionT::predicate_t type;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// The get_semantic_action template function returns the attached semantic
|
|
||||||
// action of an action parser.
|
|
||||||
// If the parser under inspection is not an action type parser the compilation
|
|
||||||
// will fail.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ActionT>
|
|
||||||
inline typename semantic_action<ActionT>::type const &
|
|
||||||
get_semantic_action(ActionT const &action_)
|
|
||||||
{
|
|
||||||
BOOST_STATIC_ASSERT(::boost::spirit::is_action_parser<ActionT>::value);
|
|
||||||
return action_.predicate();
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif // !defined(BOOST_SPIRIT_PARSER_TRAITS_HPP)
|
|
@ -1,274 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_REFACTORING_HPP
|
|
||||||
#define BOOST_SPIRIT_REFACTORING_HPP
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <boost/static_assert.hpp>
|
|
||||||
#include <boost/spirit/meta/as_parser.hpp>
|
|
||||||
#include <boost/spirit/core/parser.hpp>
|
|
||||||
#include <boost/spirit/core/composite/composite.hpp>
|
|
||||||
#include <boost/spirit/meta/impl/refactoring.ipp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace boost { namespace spirit {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// refactor_unary_parser class
|
|
||||||
//
|
|
||||||
// This helper template allows to attach an unary operation to a newly
|
|
||||||
// constructed parser, which combines the subject of the left operand of
|
|
||||||
// the original given parser (BinaryT) with the right operand of the
|
|
||||||
// original binary parser through the original binary operation and
|
|
||||||
// rewraps the resulting parser with the original unary operator.
|
|
||||||
//
|
|
||||||
// For instance given the parser:
|
|
||||||
// *some_parser - another_parser
|
|
||||||
//
|
|
||||||
// will be refactored to:
|
|
||||||
// *(some_parser - another_parser)
|
|
||||||
//
|
|
||||||
// If the parser to refactor is not a unary parser, no refactoring is done
|
|
||||||
// at all.
|
|
||||||
//
|
|
||||||
// The original parser should be a binary_parser_category parser,
|
|
||||||
// else the compilation will fail
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template <typename NestedT = non_nested_refactoring>
|
|
||||||
class refactor_unary_gen;
|
|
||||||
|
|
||||||
template <typename BinaryT, typename NestedT = non_nested_refactoring>
|
|
||||||
class refactor_unary_parser :
|
|
||||||
public parser<refactor_unary_parser<BinaryT, NestedT> > {
|
|
||||||
|
|
||||||
public:
|
|
||||||
// the parser to refactor has to be at least a binary_parser_category
|
|
||||||
// parser
|
|
||||||
BOOST_STATIC_ASSERT((
|
|
||||||
boost::is_convertible<typename BinaryT::parser_category_t,
|
|
||||||
binary_parser_category>::value
|
|
||||||
));
|
|
||||||
|
|
||||||
refactor_unary_parser(BinaryT const& binary_, NestedT const& nested_)
|
|
||||||
: binary(binary_), nested(nested_) {}
|
|
||||||
|
|
||||||
typedef refactor_unary_parser<BinaryT, NestedT> self_t;
|
|
||||||
typedef refactor_unary_gen<NestedT> parser_generator_t;
|
|
||||||
typedef typename BinaryT::left_t::parser_category_t parser_category_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
return impl::refactor_unary_type<NestedT>::
|
|
||||||
parse(*this, scan, binary, nested);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
typename as_parser<BinaryT>::type::embed_t binary;
|
|
||||||
typename NestedT::embed_t nested;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename NestedT>
|
|
||||||
class refactor_unary_gen {
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef refactor_unary_gen<NestedT> embed_t;
|
|
||||||
|
|
||||||
refactor_unary_gen(NestedT const& nested_ = non_nested_refactoring())
|
|
||||||
: nested(nested_) {}
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
refactor_unary_parser<ParserT, NestedT>
|
|
||||||
operator[](parser<ParserT> const& subject) const
|
|
||||||
{
|
|
||||||
return refactor_unary_parser<ParserT, NestedT>
|
|
||||||
(subject.derived(), nested);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
typename NestedT::embed_t nested;
|
|
||||||
};
|
|
||||||
|
|
||||||
const refactor_unary_gen<> refactor_unary_d = refactor_unary_gen<>();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// refactor_action_parser class
|
|
||||||
//
|
|
||||||
// This helper template allows to attach an action taken from the left
|
|
||||||
// operand of the given binary parser to a newly constructed parser,
|
|
||||||
// which combines the subject of the left operand of the original binary
|
|
||||||
// parser with the right operand of the original binary parser by means of
|
|
||||||
// the original binary operator parser.
|
|
||||||
//
|
|
||||||
// For instance the parser:
|
|
||||||
// some_parser[some_attached_functor] - another_parser
|
|
||||||
//
|
|
||||||
// will be refactored to:
|
|
||||||
// (some_parser - another_parser)[some_attached_functor]
|
|
||||||
//
|
|
||||||
// If the left operand to refactor is not an action parser, no refactoring
|
|
||||||
// is done at all.
|
|
||||||
//
|
|
||||||
// The original parser should be a binary_parser_category parser,
|
|
||||||
// else the compilation will fail
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template <typename NestedT = non_nested_refactoring>
|
|
||||||
class refactor_action_gen;
|
|
||||||
|
|
||||||
template <typename BinaryT, typename NestedT = non_nested_refactoring>
|
|
||||||
class refactor_action_parser :
|
|
||||||
public parser<refactor_action_parser<BinaryT, NestedT> > {
|
|
||||||
|
|
||||||
public:
|
|
||||||
// the parser to refactor has to be at least a binary_parser_category
|
|
||||||
// parser
|
|
||||||
BOOST_STATIC_ASSERT((
|
|
||||||
boost::is_convertible<typename BinaryT::parser_category_t,
|
|
||||||
binary_parser_category>::value
|
|
||||||
));
|
|
||||||
|
|
||||||
refactor_action_parser(BinaryT const& binary_, NestedT const& nested_)
|
|
||||||
: binary(binary_), nested(nested_) {}
|
|
||||||
|
|
||||||
typedef refactor_action_parser<BinaryT, NestedT> self_t;
|
|
||||||
typedef refactor_action_gen<NestedT> parser_generator_t;
|
|
||||||
typedef typename BinaryT::left_t::parser_category_t parser_category_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
return impl::refactor_action_type<NestedT>::
|
|
||||||
parse(*this, scan, binary, nested);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
typename as_parser<BinaryT>::type::embed_t binary;
|
|
||||||
typename NestedT::embed_t nested;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename NestedT>
|
|
||||||
class refactor_action_gen {
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef refactor_action_gen<NestedT> embed_t;
|
|
||||||
|
|
||||||
refactor_action_gen(NestedT const& nested_ = non_nested_refactoring())
|
|
||||||
: nested(nested_) {}
|
|
||||||
|
|
||||||
template <typename ParserT>
|
|
||||||
refactor_action_parser<ParserT, NestedT>
|
|
||||||
operator[](parser<ParserT> const& subject) const
|
|
||||||
{
|
|
||||||
return refactor_action_parser<ParserT, NestedT>
|
|
||||||
(subject.derived(), nested);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
typename NestedT::embed_t nested;
|
|
||||||
};
|
|
||||||
|
|
||||||
const refactor_action_gen<> refactor_action_d = refactor_action_gen<>();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// attach_action_parser class
|
|
||||||
//
|
|
||||||
// This helper template allows to attach an action given separately
|
|
||||||
// to to all parsers, out of which the given parser is constructed and
|
|
||||||
// reconstructs a new parser having the same structure.
|
|
||||||
//
|
|
||||||
// For instance the parser:
|
|
||||||
// (some_parser >> another_parser)[some_attached_functor]
|
|
||||||
//
|
|
||||||
// will be refactored to:
|
|
||||||
// some_parser[some_attached_functor]
|
|
||||||
// >> another_parser[some_attached_functor]
|
|
||||||
//
|
|
||||||
// The original parser should be a action_parser_category parser,
|
|
||||||
// else the compilation will fail
|
|
||||||
//
|
|
||||||
// If the parser, to which the action is attached is not an binary parser,
|
|
||||||
// no refactoring is done at all.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template <typename NestedT = non_nested_refactoring>
|
|
||||||
class attach_action_gen;
|
|
||||||
|
|
||||||
template <typename ActionT, typename NestedT = non_nested_refactoring>
|
|
||||||
class attach_action_parser :
|
|
||||||
public parser<attach_action_parser<ActionT, NestedT> > {
|
|
||||||
|
|
||||||
public:
|
|
||||||
// the parser to refactor has to be at least a action_parser_category
|
|
||||||
// parser
|
|
||||||
BOOST_STATIC_ASSERT((
|
|
||||||
boost::is_convertible<typename ActionT::parser_category_t,
|
|
||||||
action_parser_category>::value
|
|
||||||
));
|
|
||||||
|
|
||||||
attach_action_parser(ActionT const& actor_, NestedT const& nested_)
|
|
||||||
: actor(actor_), nested(nested_) {}
|
|
||||||
|
|
||||||
typedef attach_action_parser<ActionT, NestedT> self_t;
|
|
||||||
typedef attach_action_gen<NestedT> parser_generator_t;
|
|
||||||
typedef typename ActionT::parser_category_t parser_category_t;
|
|
||||||
|
|
||||||
template <typename ScannerT>
|
|
||||||
typename parser_result<self_t, ScannerT>::type
|
|
||||||
parse(ScannerT const& scan) const
|
|
||||||
{
|
|
||||||
return impl::attach_action_type<NestedT>::
|
|
||||||
parse(*this, scan, actor, nested);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
typename as_parser<ActionT>::type::embed_t actor;
|
|
||||||
typename NestedT::embed_t nested;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename NestedT>
|
|
||||||
class attach_action_gen {
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef attach_action_gen<NestedT> embed_t;
|
|
||||||
|
|
||||||
attach_action_gen(NestedT const& nested_ = non_nested_refactoring())
|
|
||||||
: nested(nested_) {}
|
|
||||||
|
|
||||||
template <typename ParserT, typename ActionT>
|
|
||||||
attach_action_parser<action<ParserT, ActionT>, NestedT>
|
|
||||||
operator[](action<ParserT, ActionT> const& actor) const
|
|
||||||
{
|
|
||||||
return attach_action_parser<action<ParserT, ActionT>, NestedT>
|
|
||||||
(actor, nested);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
typename NestedT::embed_t nested;
|
|
||||||
};
|
|
||||||
|
|
||||||
const attach_action_gen<> attach_action_d = attach_action_gen<>();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif // BOOST_SPIRIT_REFACTORING_HPP
|
|
||||||
|
|
@ -1,218 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Copyright (c) 2002-2003 Joel de Guzman
|
|
||||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
|
||||||
http://spirit.sourceforge.net/
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_TRAVERSE_HPP)
|
|
||||||
#define BOOST_SPIRIT_TRAVERSE_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/meta/impl/traverse.ipp>
|
|
||||||
|
|
||||||
namespace boost { namespace spirit
|
|
||||||
{
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Post-order traversal of auxilliary parsers.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
struct post_order
|
|
||||||
{
|
|
||||||
// Return the parser type, which is generated as the result of the
|
|
||||||
// traverse function below.
|
|
||||||
|
|
||||||
template <typename MetaT, typename ParserT>
|
|
||||||
struct result
|
|
||||||
{
|
|
||||||
typedef typename
|
|
||||||
traverse_post_order_return<
|
|
||||||
MetaT
|
|
||||||
, ParserT
|
|
||||||
, traverse_post_order_env<0, 0, 0, 0>
|
|
||||||
>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Traverse a given parser and refactor it with the help of the given
|
|
||||||
// MetaT metafunction template.
|
|
||||||
|
|
||||||
template <typename MetaT, typename ParserT>
|
|
||||||
static typename result<MetaT, ParserT>::type
|
|
||||||
traverse(MetaT const &meta_, ParserT const &parser_)
|
|
||||||
{
|
|
||||||
typedef typename ParserT::parser_category_t parser_category_t;
|
|
||||||
return impl::traverse_post_order<parser_category_t>::generate(
|
|
||||||
meta_, parser_, traverse_post_order_env<0, 0, 0, 0>());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Transform policies
|
|
||||||
//
|
|
||||||
// The following policy classes could be used to assemble some new
|
|
||||||
// transformation metafunction which uses identity transformations
|
|
||||||
// for some parser_category type parsers.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// transform plain parsers
|
|
||||||
template <typename TransformT>
|
|
||||||
struct plain_identity_policy
|
|
||||||
{
|
|
||||||
template <typename ParserT, typename EnvT>
|
|
||||||
struct plain_result
|
|
||||||
{
|
|
||||||
// plain parsers should be embedded and returned correctly
|
|
||||||
typedef typename ParserT::embed_t type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ParserT, typename EnvT>
|
|
||||||
typename parser_traversal_plain_result<TransformT, ParserT, EnvT>::type
|
|
||||||
generate_plain(ParserT const &parser_, EnvT const& /*env*/) const
|
|
||||||
{
|
|
||||||
return parser_;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
// transform unary parsers
|
|
||||||
template <typename UnaryT, typename SubjectT>
|
|
||||||
struct unary_identity_policy_return
|
|
||||||
{
|
|
||||||
typedef typename UnaryT::parser_generator_t parser_generator_t;
|
|
||||||
typedef typename parser_generator_t
|
|
||||||
::template result<SubjectT>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename TransformT>
|
|
||||||
struct unary_identity_policy
|
|
||||||
{
|
|
||||||
template <typename UnaryT, typename SubjectT, typename EnvT>
|
|
||||||
struct unary_result
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
typename unary_identity_policy_return<UnaryT, SubjectT>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename UnaryT, typename SubjectT, typename EnvT>
|
|
||||||
typename parser_traversal_unary_result<
|
|
||||||
TransformT, UnaryT, SubjectT, EnvT>::type
|
|
||||||
generate_unary(
|
|
||||||
UnaryT const &, SubjectT const &subject_, EnvT const& /*env*/) const
|
|
||||||
{
|
|
||||||
typedef typename UnaryT::parser_generator_t parser_generator_t;
|
|
||||||
return parser_generator_t::template generate<SubjectT>(subject_);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
// transform action parsers
|
|
||||||
template <typename TransformT>
|
|
||||||
struct action_identity_policy
|
|
||||||
{
|
|
||||||
template <typename ActionT, typename SubjectT, typename EnvT>
|
|
||||||
struct action_result
|
|
||||||
{
|
|
||||||
typedef action<SubjectT, typename ActionT::predicate_t> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ActionT, typename SubjectT, typename EnvT>
|
|
||||||
typename parser_traversal_action_result<
|
|
||||||
TransformT, ActionT, SubjectT, EnvT
|
|
||||||
>::type
|
|
||||||
generate_action(ActionT const &action_, SubjectT const &subject_,
|
|
||||||
EnvT const& /*env*/) const
|
|
||||||
{
|
|
||||||
return subject_[action_.predicate()];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
// transform binary parsers
|
|
||||||
template <typename BinaryT, typename LeftT, typename RightT>
|
|
||||||
struct binary_identity_policy_return
|
|
||||||
{
|
|
||||||
typedef typename BinaryT::parser_generator_t parser_generator_t;
|
|
||||||
typedef typename parser_generator_t
|
|
||||||
::template result<LeftT, RightT>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename TransformT>
|
|
||||||
struct binary_identity_policy
|
|
||||||
{
|
|
||||||
template <typename BinaryT, typename LeftT
|
|
||||||
, typename RightT, typename EnvT>
|
|
||||||
struct binary_result {
|
|
||||||
|
|
||||||
typedef typename
|
|
||||||
binary_identity_policy_return<BinaryT, LeftT, RightT>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename BinaryT, typename LeftT
|
|
||||||
, typename RightT, typename EnvT>
|
|
||||||
typename parser_traversal_binary_result<
|
|
||||||
TransformT, BinaryT, LeftT, RightT, EnvT
|
|
||||||
>::type
|
|
||||||
generate_binary(
|
|
||||||
BinaryT const &, LeftT const& left_
|
|
||||||
, RightT const& right_, EnvT const& /*env*/) const
|
|
||||||
{
|
|
||||||
typedef typename BinaryT::parser_generator_t parser_generator_t;
|
|
||||||
return parser_generator_t::
|
|
||||||
template generate<LeftT, RightT>(left_, right_);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// transform_policies template
|
|
||||||
//
|
|
||||||
// The transform_policies template metafunction could serve as a
|
|
||||||
// base class for new metafunctions to be passed to the traverse meta
|
|
||||||
// template (see above), where only minimal parts have to be
|
|
||||||
// overwritten.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename TransformT,
|
|
||||||
typename PlainPolicyT = plain_identity_policy<TransformT>,
|
|
||||||
typename UnaryPolicyT = unary_identity_policy<TransformT>,
|
|
||||||
typename ActionPolicyT = action_identity_policy<TransformT>,
|
|
||||||
typename BinaryPolicyT = binary_identity_policy<TransformT>
|
|
||||||
>
|
|
||||||
struct transform_policies :
|
|
||||||
public PlainPolicyT,
|
|
||||||
public UnaryPolicyT,
|
|
||||||
public ActionPolicyT,
|
|
||||||
public BinaryPolicyT
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Identity transformation
|
|
||||||
//
|
|
||||||
// The identity_transform metafunction supplied to the traverse
|
|
||||||
// template will generate a new parser, which will be exactly
|
|
||||||
// identical to the parser given as the parameter to the traverse
|
|
||||||
// metafunction. I.e. the following conceptual 'equation' will be
|
|
||||||
// always true:
|
|
||||||
//
|
|
||||||
// some_parser ==
|
|
||||||
// post_order::traverse(identity_transform(), some_parser)
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
struct identity_transform : transform_policies<identity_transform> {};
|
|
||||||
|
|
||||||
}} // namespace boost::spirit
|
|
||||||
|
|
||||||
#endif // !defined(BOOST_SPIRIT_TRAVERSE_HPP)
|
|
@ -1,26 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Phoenix V1.2.1
|
|
||||||
Copyright (c) 2001-2002 Joel de Guzman
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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_PHOENIX_HPP)
|
|
||||||
#define BOOST_SPIRIT_PHOENIX_HPP
|
|
||||||
|
|
||||||
#include <boost/spirit/phoenix/tuples.hpp>
|
|
||||||
#include <boost/spirit/phoenix/tuple_helpers.hpp>
|
|
||||||
#include <boost/spirit/phoenix/actor.hpp>
|
|
||||||
#include <boost/spirit/phoenix/primitives.hpp>
|
|
||||||
#include <boost/spirit/phoenix/composite.hpp>
|
|
||||||
#include <boost/spirit/phoenix/functions.hpp>
|
|
||||||
#include <boost/spirit/phoenix/operators.hpp>
|
|
||||||
#include <boost/spirit/phoenix/special_ops.hpp>
|
|
||||||
#include <boost/spirit/phoenix/statements.hpp>
|
|
||||||
#include <boost/spirit/phoenix/binders.hpp>
|
|
||||||
#include <boost/spirit/phoenix/closures.hpp>
|
|
||||||
#include <boost/spirit/phoenix/casts.hpp>
|
|
||||||
#include <boost/spirit/phoenix/new.hpp>
|
|
||||||
|
|
||||||
#endif // !defined(BOOST_SPIRIT_PHOENIX_HPP)
|
|
@ -1,596 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Phoenix v1.2
|
|
||||||
Copyright (c) 2001-2002 Joel de Guzman
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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 PHOENIX_ACTOR_HPP
|
|
||||||
#define PHOENIX_ACTOR_HPP
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <boost/spirit/phoenix/tuples.hpp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace phoenix {
|
|
||||||
|
|
||||||
// These are forward declared here because we cannot include impl.hpp
|
|
||||||
// or operators.hpp yet but the actor's assignment operator and index
|
|
||||||
// operator are required to be members.
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
struct assign_op;
|
|
||||||
struct index_op;
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
namespace impl {
|
|
||||||
|
|
||||||
template <typename OperationT, typename BaseT, typename B>
|
|
||||||
struct make_binary1;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// unpack_tuple class
|
|
||||||
//
|
|
||||||
// This class is used to unpack a supplied tuple such, that the members of
|
|
||||||
// this tuple will be handled as if they would be supplied separately.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename TupleT>
|
|
||||||
struct unpack_tuple : public TupleT {
|
|
||||||
|
|
||||||
typedef TupleT tuple_t;
|
|
||||||
|
|
||||||
unpack_tuple() {}
|
|
||||||
unpack_tuple(tuple_t const &tuple_) : TupleT(tuple_) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// actor class
|
|
||||||
//
|
|
||||||
// This class is a protocol class for all actors. This class is
|
|
||||||
// essentially an interface contract. The actor class does not
|
|
||||||
// really know how how to act on anything but instead relies on the
|
|
||||||
// template parameter BaseT (from which the actor will derive from)
|
|
||||||
// to do the actual action.
|
|
||||||
//
|
|
||||||
// An actor is a functor that is capable of accepting arguments up
|
|
||||||
// to a predefined maximum. It is up to the base class to do the
|
|
||||||
// actual processing or possibly to limit the arity (no. of
|
|
||||||
// arguments) passed in. Upon invocation of the functor through a
|
|
||||||
// supplied operator(), the actor funnels the arguments passed in
|
|
||||||
// by the client into a tuple and calls the base eval member
|
|
||||||
// function.
|
|
||||||
//
|
|
||||||
// Schematically:
|
|
||||||
//
|
|
||||||
// arg0 ---------|
|
|
||||||
// arg1 ---------|
|
|
||||||
// arg2 ---------|---> tupled_args ---> base.eval
|
|
||||||
// ... |
|
|
||||||
// argN ---------|
|
|
||||||
//
|
|
||||||
// actor::operator()(arg0, arg1... argN)
|
|
||||||
// ---> BaseT::eval(tupled_args);
|
|
||||||
//
|
|
||||||
// Actor base classes from which this class inherits from are
|
|
||||||
// expected to have a corresponding member function eval compatible
|
|
||||||
// with the conceptual Interface:
|
|
||||||
//
|
|
||||||
// template <typename TupleT>
|
|
||||||
// actor_return_type
|
|
||||||
// eval(TupleT const& args) const;
|
|
||||||
//
|
|
||||||
// where args are the actual arguments passed in by the client
|
|
||||||
// funneled into a tuple (see tuple.hpp for details).
|
|
||||||
//
|
|
||||||
// The actor_return_type can be anything. Base classes are free to
|
|
||||||
// return any type, even argument dependent types (types that are
|
|
||||||
// deduced from the types of the arguments). After evaluating the
|
|
||||||
// parameters and doing some computations or actions, the eval
|
|
||||||
// member function concludes by returning something back to the
|
|
||||||
// client. To do this, the forwarding function (the actor's
|
|
||||||
// operator()) needs to know the return type of the eval member
|
|
||||||
// function that it is calling. For this purpose, actor base
|
|
||||||
// classes are required to provide a nested template class:
|
|
||||||
//
|
|
||||||
// template <typename TupleT>
|
|
||||||
// struct result;
|
|
||||||
//
|
|
||||||
// This auxiliary class provides the result type information
|
|
||||||
// returned by the eval member function of a base actor class. The
|
|
||||||
// nested template class result should have a typedef 'type' that
|
|
||||||
// reflects the return type of its member function eval. It is
|
|
||||||
// basically a type computer that answers the question "given
|
|
||||||
// arguments packed into a TupleT type, what will be the result
|
|
||||||
// type of the eval member function of ActorT?". The template class
|
|
||||||
// actor_result queries this to extract the return type of an
|
|
||||||
// actor. Example:
|
|
||||||
//
|
|
||||||
// typedef typename actor_result<ActorT, TupleT>::type
|
|
||||||
// actor_return_type;
|
|
||||||
//
|
|
||||||
// where actor_return_type is the actual type returned by ActorT's
|
|
||||||
// eval member function given some arguments in a TupleT.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ActorT, typename TupleT>
|
|
||||||
struct actor_result {
|
|
||||||
|
|
||||||
typedef typename ActorT::template result<TupleT>::type type;
|
|
||||||
typedef typename remove_reference<type>::type plain_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
struct actor : public BaseT {
|
|
||||||
|
|
||||||
actor();
|
|
||||||
actor(BaseT const& base);
|
|
||||||
|
|
||||||
typename actor_result<BaseT, tuple<> >::type
|
|
||||||
operator()() const;
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
typename actor_result<BaseT, tuple<A&> >::type
|
|
||||||
operator()(A& a) const;
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
typename actor_result<BaseT, tuple<A&, B&> >::type
|
|
||||||
operator()(A& a, B& b) const;
|
|
||||||
|
|
||||||
template <typename A, typename B, typename C>
|
|
||||||
typename actor_result<BaseT, tuple<A&, B&, C&> >::type
|
|
||||||
operator()(A& a, B& b, C& c) const;
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 3
|
|
||||||
template <typename A, typename B, typename C, typename D>
|
|
||||||
typename actor_result<BaseT, tuple<A&, B&, C&, D&> >::type
|
|
||||||
operator()(A& a, B& b, C& c, D& d) const;
|
|
||||||
|
|
||||||
template <typename A, typename B, typename C, typename D, typename E>
|
|
||||||
typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&> >::type
|
|
||||||
operator()(A& a, B& b, C& c, D& d, E& e) const;
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F>
|
|
||||||
typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&, F&> >::type
|
|
||||||
operator()(A& a, B& b, C& c, D& d, E& e, F& f) const;
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 6
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G>
|
|
||||||
typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&, F&, G&> >::type
|
|
||||||
operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g) const;
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H>
|
|
||||||
typename actor_result<BaseT,
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&>
|
|
||||||
>::type
|
|
||||||
operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h) const;
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I>
|
|
||||||
typename actor_result<BaseT,
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
|
|
||||||
>::type
|
|
||||||
operator()(A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i) const;
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 9
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J>
|
|
||||||
typename actor_result<BaseT,
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
|
|
||||||
>::type
|
|
||||||
operator()(
|
|
||||||
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j) const;
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K>
|
|
||||||
typename actor_result<BaseT,
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
|
|
||||||
>::type
|
|
||||||
operator()(
|
|
||||||
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
|
|
||||||
K& k) const;
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K, typename L>
|
|
||||||
typename actor_result<BaseT,
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
|
|
||||||
>::type
|
|
||||||
operator()(
|
|
||||||
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
|
|
||||||
K& k, L& l) const;
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 12
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K, typename L, typename M>
|
|
||||||
typename actor_result<BaseT,
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
|
|
||||||
>::type
|
|
||||||
operator()(
|
|
||||||
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
|
|
||||||
K& k, L& l, M& m) const;
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K, typename L, typename M, typename N>
|
|
||||||
typename actor_result<BaseT,
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
|
|
||||||
>::type
|
|
||||||
operator()(
|
|
||||||
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
|
|
||||||
K& k, L& l, M& m, N& n) const;
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K, typename L, typename M, typename N, typename O>
|
|
||||||
typename actor_result<BaseT,
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
|
|
||||||
>::type
|
|
||||||
operator()(
|
|
||||||
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
|
|
||||||
K& k, L& l, M& m, N& n, O& o) const;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
typename actor_result<BaseT, unpack_tuple<TupleT> >::type
|
|
||||||
operator()(unpack_tuple<TupleT> const &t) const;
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
typename impl::make_binary1<assign_op, BaseT, B>::type
|
|
||||||
operator=(B const& b) const;
|
|
||||||
|
|
||||||
template <typename B>
|
|
||||||
typename impl::make_binary1<index_op, BaseT, B>::type
|
|
||||||
operator[](B const& b) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// as_actor
|
|
||||||
//
|
|
||||||
// as_actor is a meta-program that converts an arbitrary type into
|
|
||||||
// an actor. All participants in the framework must be first-class
|
|
||||||
// actors. This meta-program is used all throughout the framework
|
|
||||||
// whenever an unknown type needs to be converted to an actor.
|
|
||||||
// as_actor specializations are expected to have a typedef 'type'.
|
|
||||||
// This is the destination actor type. A static member function
|
|
||||||
// 'convert' converts an object to this target type.
|
|
||||||
//
|
|
||||||
// The meta-program does no conversion if the object to be
|
|
||||||
// converted is already an actor.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
struct as_actor;
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
struct as_actor<actor<BaseT> > {
|
|
||||||
|
|
||||||
typedef actor<BaseT> type;
|
|
||||||
static type convert(actor<BaseT> const& x) { return x; }
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <>
|
|
||||||
struct as_actor<nil_t> {
|
|
||||||
|
|
||||||
typedef nil_t type;
|
|
||||||
static nil_t convert(nil_t /*x*/)
|
|
||||||
{ return nil_t(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <>
|
|
||||||
struct as_actor<void> {
|
|
||||||
|
|
||||||
typedef void type;
|
|
||||||
// ERROR!!!
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// actor class implementation
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
actor<BaseT>::actor()
|
|
||||||
: BaseT() {}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
actor<BaseT>::actor(BaseT const& base)
|
|
||||||
: BaseT(base) {}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
inline typename actor_result<BaseT, tuple<> >::type
|
|
||||||
actor<BaseT>::operator()() const
|
|
||||||
{
|
|
||||||
return BaseT::eval(tuple<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
template <typename A>
|
|
||||||
inline typename actor_result<BaseT, tuple<A&> >::type
|
|
||||||
actor<BaseT>::operator()(A& a) const
|
|
||||||
{
|
|
||||||
return BaseT::eval(tuple<A&>(a));
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
template <typename A, typename B>
|
|
||||||
inline typename actor_result<BaseT, tuple<A&, B&> >::type
|
|
||||||
actor<BaseT>::operator()(A& a, B& b) const
|
|
||||||
{
|
|
||||||
return BaseT::eval(tuple<A&, B&>(a, b));
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
template <typename A, typename B, typename C>
|
|
||||||
inline typename actor_result<BaseT, tuple<A&, B&, C&> >::type
|
|
||||||
actor<BaseT>::operator()(A& a, B& b, C& c) const
|
|
||||||
{
|
|
||||||
return BaseT::eval(tuple<A&, B&, C&>(a, b, c));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 3
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
template <typename A, typename B, typename C, typename D>
|
|
||||||
inline typename actor_result<BaseT, tuple<A&, B&, C&, D&> >::type
|
|
||||||
actor<BaseT>::operator()(A& a, B& b, C& c, D& d) const
|
|
||||||
{
|
|
||||||
return BaseT::eval(tuple<A&, B&, C&, D&>(a, b, c, d));
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
template <typename A, typename B, typename C, typename D, typename E>
|
|
||||||
inline typename actor_result<BaseT, tuple<A&, B&, C&, D&, E&> >::type
|
|
||||||
actor<BaseT>::operator()(A& a, B& b, C& c, D& d, E& e) const
|
|
||||||
{
|
|
||||||
return BaseT::eval(tuple<A&, B&, C&, D&, E&>(a, b, c, d, e));
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F>
|
|
||||||
inline typename actor_result<BaseT,
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&>
|
|
||||||
>::type
|
|
||||||
actor<BaseT>::operator()(
|
|
||||||
A& a, B& b, C& c, D& d, E& e, F& f
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return BaseT::eval(
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&>
|
|
||||||
(a, b, c, d, e, f)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 6
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G>
|
|
||||||
inline typename actor_result<BaseT,
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&>
|
|
||||||
>::type
|
|
||||||
actor<BaseT>::operator()(
|
|
||||||
A& a, B& b, C& c, D& d, E& e, F& f, G& g
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return BaseT::eval(
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&>
|
|
||||||
(a, b, c, d, e, f, g)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H>
|
|
||||||
inline typename actor_result<BaseT,
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&>
|
|
||||||
>::type
|
|
||||||
actor<BaseT>::operator()(
|
|
||||||
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return BaseT::eval(
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&>
|
|
||||||
(a, b, c, d, e, f, g, h)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I>
|
|
||||||
inline typename actor_result<BaseT,
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
|
|
||||||
>::type
|
|
||||||
actor<BaseT>::operator()(
|
|
||||||
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return BaseT::eval(
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&>
|
|
||||||
(a, b, c, d, e, f, g, h, i)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 9
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J>
|
|
||||||
inline typename actor_result<BaseT,
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
|
|
||||||
>::type
|
|
||||||
actor<BaseT>::operator()(
|
|
||||||
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return BaseT::eval(
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&>
|
|
||||||
(a, b, c, d, e, f, g, h, i, j)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K>
|
|
||||||
inline typename actor_result<BaseT,
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
|
|
||||||
>::type
|
|
||||||
actor<BaseT>::operator()(
|
|
||||||
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
|
|
||||||
K& k
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return BaseT::eval(
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&>
|
|
||||||
(a, b, c, d, e, f, g, h, i, j, k)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K, typename L>
|
|
||||||
inline typename actor_result<BaseT,
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
|
|
||||||
>::type
|
|
||||||
actor<BaseT>::operator()(
|
|
||||||
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
|
|
||||||
K& k, L& l
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return BaseT::eval(
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&>
|
|
||||||
(a, b, c, d, e, f, g, h, i, j, k, l)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 12
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K, typename L, typename M>
|
|
||||||
inline typename actor_result<BaseT,
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
|
|
||||||
>::type
|
|
||||||
actor<BaseT>::operator()(
|
|
||||||
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
|
|
||||||
K& k, L& l, M& m
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return BaseT::eval(
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&>
|
|
||||||
(a, b, c, d, e, f, g, h, i, j, k, l, m)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K, typename L, typename M, typename N>
|
|
||||||
inline typename actor_result<BaseT,
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
|
|
||||||
>::type
|
|
||||||
actor<BaseT>::operator()(
|
|
||||||
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
|
|
||||||
K& k, L& l, M& m, N& n
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return BaseT::eval(
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&>
|
|
||||||
(a, b, c, d, e, f, g, h, i, j, k, l, m, n)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K, typename L, typename M, typename N, typename O>
|
|
||||||
inline typename actor_result<BaseT,
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
|
|
||||||
>::type
|
|
||||||
actor<BaseT>::operator()(
|
|
||||||
A& a, B& b, C& c, D& d, E& e, F& f, G& g, H& h, I& i, J& j,
|
|
||||||
K& k, L& l, M& m, N& n, O& o
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return BaseT::eval(
|
|
||||||
tuple<A&, B&, C&, D&, E&, F&, G&, H&, I&, J&, K&, L&, M&, N&, O&>
|
|
||||||
(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
template <typename TupleT>
|
|
||||||
typename actor_result<BaseT, unpack_tuple<TupleT> >::type
|
|
||||||
actor<BaseT>::operator()(unpack_tuple<TupleT> const &t) const
|
|
||||||
{
|
|
||||||
return BaseT::eval(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
} // namespace phoenix
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,440 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Phoenix V1.2.1
|
|
||||||
Copyright (c) 2001-2002 Joel de Guzman
|
|
||||||
MT code Copyright (c) 2002-2003 Martin Wille
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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 PHOENIX_CLOSURES_HPP
|
|
||||||
#define PHOENIX_CLOSURES_HPP
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <boost/spirit/phoenix/actor.hpp>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#ifdef PHOENIX_THREADSAFE
|
|
||||||
#include <boost/thread/tss.hpp>
|
|
||||||
#include <boost/thread/once.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace phoenix {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Adaptable closures
|
|
||||||
//
|
|
||||||
// The framework will not be complete without some form of closures
|
|
||||||
// support. Closures encapsulate a stack frame where local
|
|
||||||
// variables are created upon entering a function and destructed
|
|
||||||
// upon exiting. Closures provide an environment for local
|
|
||||||
// variables to reside. Closures can hold heterogeneous types.
|
|
||||||
//
|
|
||||||
// Phoenix closures are true hardware stack based closures. At the
|
|
||||||
// very least, closures enable true reentrancy in lambda functions.
|
|
||||||
// A closure provides access to a function stack frame where local
|
|
||||||
// variables reside. Modeled after Pascal nested stack frames,
|
|
||||||
// closures can be nested just like nested functions where code in
|
|
||||||
// inner closures may access local variables from in-scope outer
|
|
||||||
// closures (accessing inner scopes from outer scopes is an error
|
|
||||||
// and will cause a run-time assertion failure).
|
|
||||||
//
|
|
||||||
// There are three (3) interacting classes:
|
|
||||||
//
|
|
||||||
// 1) closure:
|
|
||||||
//
|
|
||||||
// At the point of declaration, a closure does not yet create a
|
|
||||||
// stack frame nor instantiate any variables. A closure declaration
|
|
||||||
// declares the types and names[note] of the local variables. The
|
|
||||||
// closure class is meant to be subclassed. It is the
|
|
||||||
// responsibility of a closure subclass to supply the names for
|
|
||||||
// each of the local variable in the closure. Example:
|
|
||||||
//
|
|
||||||
// struct my_closure : closure<int, string, double> {
|
|
||||||
//
|
|
||||||
// member1 num; // names the 1st (int) local variable
|
|
||||||
// member2 message; // names the 2nd (string) local variable
|
|
||||||
// member3 real; // names the 3rd (double) local variable
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// my_closure clos;
|
|
||||||
//
|
|
||||||
// Now that we have a closure 'clos', its local variables can be
|
|
||||||
// accessed lazily using the dot notation. Each qualified local
|
|
||||||
// variable can be used just like any primitive actor (see
|
|
||||||
// primitives.hpp). Examples:
|
|
||||||
//
|
|
||||||
// clos.num = 30
|
|
||||||
// clos.message = arg1
|
|
||||||
// clos.real = clos.num * 1e6
|
|
||||||
//
|
|
||||||
// The examples above are lazily evaluated. As usual, these
|
|
||||||
// expressions return composite actors that will be evaluated
|
|
||||||
// through a second function call invocation (see operators.hpp).
|
|
||||||
// Each of the members (clos.xxx) is an actor. As such, applying
|
|
||||||
// the operator() will reveal its identity:
|
|
||||||
//
|
|
||||||
// clos.num() // will return the current value of clos.num
|
|
||||||
//
|
|
||||||
// *** [note] Acknowledgement: Juan Carlos Arevalo-Baeza (JCAB)
|
|
||||||
// introduced and initilally implemented the closure member names
|
|
||||||
// that uses the dot notation.
|
|
||||||
//
|
|
||||||
// 2) closure_member
|
|
||||||
//
|
|
||||||
// The named local variables of closure 'clos' above are actually
|
|
||||||
// closure members. The closure_member class is an actor and
|
|
||||||
// conforms to its conceptual interface. member1..memberN are
|
|
||||||
// predefined typedefs that correspond to each of the listed types
|
|
||||||
// in the closure template parameters.
|
|
||||||
//
|
|
||||||
// 3) closure_frame
|
|
||||||
//
|
|
||||||
// When a closure member is finally evaluated, it should refer to
|
|
||||||
// an actual instance of the variable in the hardware stack.
|
|
||||||
// Without doing so, the process is not complete and the evaluated
|
|
||||||
// member will result to an assertion failure. Remember that the
|
|
||||||
// closure is just a declaration. The local variables that a
|
|
||||||
// closure refers to must still be instantiated.
|
|
||||||
//
|
|
||||||
// The closure_frame class does the actual instantiation of the
|
|
||||||
// local variables and links these variables with the closure and
|
|
||||||
// all its members. There can be multiple instances of
|
|
||||||
// closure_frames typically situated in the stack inside a
|
|
||||||
// function. Each closure_frame instance initiates a stack frame
|
|
||||||
// with a new set of closure local variables. Example:
|
|
||||||
//
|
|
||||||
// void foo()
|
|
||||||
// {
|
|
||||||
// closure_frame<my_closure> frame(clos);
|
|
||||||
// /* do something */
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// where 'clos' is an instance of our closure 'my_closure' above.
|
|
||||||
// Take note that the usage above precludes locally declared
|
|
||||||
// classes. If my_closure is a locally declared type, we can still
|
|
||||||
// use its self_type as a paramater to closure_frame:
|
|
||||||
//
|
|
||||||
// closure_frame<my_closure::self_type> frame(clos);
|
|
||||||
//
|
|
||||||
// Upon instantiation, the closure_frame links the local variables
|
|
||||||
// to the closure. The previous link to another closure_frame
|
|
||||||
// instance created before is saved. Upon destruction, the
|
|
||||||
// closure_frame unlinks itself from the closure and relinks the
|
|
||||||
// preceding closure_frame prior to this instance.
|
|
||||||
//
|
|
||||||
// The local variables in the closure 'clos' above is default
|
|
||||||
// constructed in the stack inside function 'foo'. Once 'foo' is
|
|
||||||
// exited, all of these local variables are destructed. In some
|
|
||||||
// cases, default construction is not desirable and we need to
|
|
||||||
// initialize the local closure variables with some values. This
|
|
||||||
// can be done by passing in the initializers in a compatible
|
|
||||||
// tuple. A compatible tuple is one with the same number of
|
|
||||||
// elements as the destination and where each element from the
|
|
||||||
// destination can be constructed from each corresponding element
|
|
||||||
// in the source. Example:
|
|
||||||
//
|
|
||||||
// tuple<int, char const*, int> init(123, "Hello", 1000);
|
|
||||||
// closure_frame<my_closure> frame(clos, init);
|
|
||||||
//
|
|
||||||
// Here now, our closure_frame's variables are initialized with
|
|
||||||
// int: 123, char const*: "Hello" and int: 1000.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
namespace impl
|
|
||||||
{
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
|
||||||
// closure_frame_holder is a simple class that encapsulates the
|
|
||||||
// storage for a frame pointer. It uses thread specific data in
|
|
||||||
// case when multithreading is enabled, an ordinary pointer otherwise
|
|
||||||
//
|
|
||||||
// it has get() and set() member functions. set() has to be used
|
|
||||||
// _after_ get(). get() contains intialisation code in the multi
|
|
||||||
// threading case
|
|
||||||
//
|
|
||||||
// closure_frame_holder is used by the closure<> class to store
|
|
||||||
// the pointer to the current frame.
|
|
||||||
//
|
|
||||||
#ifndef PHOENIX_THREADSAFE
|
|
||||||
template <typename FrameT>
|
|
||||||
struct closure_frame_holder
|
|
||||||
{
|
|
||||||
typedef FrameT frame_t;
|
|
||||||
typedef frame_t *frame_ptr;
|
|
||||||
|
|
||||||
closure_frame_holder() : frame(0) {}
|
|
||||||
|
|
||||||
frame_ptr &get() { return frame; }
|
|
||||||
void set(frame_t *f) { frame = f; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
frame_ptr frame;
|
|
||||||
|
|
||||||
// no copies, no assignments
|
|
||||||
closure_frame_holder(closure_frame_holder const &);
|
|
||||||
closure_frame_holder &operator=(closure_frame_holder const &);
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
template <typename FrameT>
|
|
||||||
struct closure_frame_holder
|
|
||||||
{
|
|
||||||
typedef FrameT frame_t;
|
|
||||||
typedef frame_t *frame_ptr;
|
|
||||||
|
|
||||||
closure_frame_holder() : tsp_frame() {}
|
|
||||||
|
|
||||||
frame_ptr &get()
|
|
||||||
{
|
|
||||||
if (!tsp_frame.get())
|
|
||||||
tsp_frame.reset(new frame_ptr(0));
|
|
||||||
return *tsp_frame;
|
|
||||||
}
|
|
||||||
void set(frame_ptr f)
|
|
||||||
{
|
|
||||||
*tsp_frame = f;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
boost::thread_specific_ptr<frame_ptr> tsp_frame;
|
|
||||||
|
|
||||||
// no copies, no assignments
|
|
||||||
closure_frame_holder(closure_frame_holder const &);
|
|
||||||
closure_frame_holder &operator=(closure_frame_holder const &);
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
} // namespace phoenix::impl
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// closure_frame class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename ClosureT>
|
|
||||||
class closure_frame : public ClosureT::tuple_t {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
closure_frame(ClosureT const& clos)
|
|
||||||
: ClosureT::tuple_t(), save(clos.frame.get()), frame(clos.frame)
|
|
||||||
{ clos.frame.set(this); }
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
closure_frame(ClosureT const& clos, TupleT const& init)
|
|
||||||
: ClosureT::tuple_t(init), save(clos.frame.get()), frame(clos.frame)
|
|
||||||
{ clos.frame.set(this); }
|
|
||||||
|
|
||||||
~closure_frame()
|
|
||||||
{ frame.set(save); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
closure_frame(closure_frame const&); // no copy
|
|
||||||
closure_frame& operator=(closure_frame const&); // no assign
|
|
||||||
|
|
||||||
closure_frame* save;
|
|
||||||
impl::closure_frame_holder<closure_frame>& frame;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// closure_member class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <int N, typename ClosureT>
|
|
||||||
class closure_member {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef typename ClosureT::tuple_t tuple_t;
|
|
||||||
|
|
||||||
closure_member()
|
|
||||||
: frame(ClosureT::closure_frame_holder_ref()) {}
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
struct result {
|
|
||||||
|
|
||||||
typedef typename tuple_element<
|
|
||||||
N, typename ClosureT::tuple_t
|
|
||||||
>::rtype type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
typename tuple_element<N, typename ClosureT::tuple_t>::rtype
|
|
||||||
eval(TupleT const& /*args*/) const
|
|
||||||
{
|
|
||||||
using namespace std;
|
|
||||||
assert(frame.get() != 0);
|
|
||||||
return (*frame.get())[tuple_index<N>()];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
impl::closure_frame_holder<typename ClosureT::closure_frame_t> &frame;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// closure class
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <
|
|
||||||
typename T0 = nil_t
|
|
||||||
, typename T1 = nil_t
|
|
||||||
, typename T2 = nil_t
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 3
|
|
||||||
, typename T3 = nil_t
|
|
||||||
, typename T4 = nil_t
|
|
||||||
, typename T5 = nil_t
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 6
|
|
||||||
, typename T6 = nil_t
|
|
||||||
, typename T7 = nil_t
|
|
||||||
, typename T8 = nil_t
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 9
|
|
||||||
, typename T9 = nil_t
|
|
||||||
, typename T10 = nil_t
|
|
||||||
, typename T11 = nil_t
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 12
|
|
||||||
, typename T12 = nil_t
|
|
||||||
, typename T13 = nil_t
|
|
||||||
, typename T14 = nil_t
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
>
|
|
||||||
class closure {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef tuple<
|
|
||||||
T0, T1, T2
|
|
||||||
#if PHOENIX_LIMIT > 3
|
|
||||||
, T3, T4, T5
|
|
||||||
#if PHOENIX_LIMIT > 6
|
|
||||||
, T6, T7, T8
|
|
||||||
#if PHOENIX_LIMIT > 9
|
|
||||||
, T9, T10, T11
|
|
||||||
#if PHOENIX_LIMIT > 12
|
|
||||||
, T12, T13, T14
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
> tuple_t;
|
|
||||||
|
|
||||||
typedef closure<
|
|
||||||
T0, T1, T2
|
|
||||||
#if PHOENIX_LIMIT > 3
|
|
||||||
, T3, T4, T5
|
|
||||||
#if PHOENIX_LIMIT > 6
|
|
||||||
, T6, T7, T8
|
|
||||||
#if PHOENIX_LIMIT > 9
|
|
||||||
, T9, T10, T11
|
|
||||||
#if PHOENIX_LIMIT > 12
|
|
||||||
, T12, T13, T14
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
> self_t;
|
|
||||||
|
|
||||||
typedef closure_frame<self_t> closure_frame_t;
|
|
||||||
|
|
||||||
closure()
|
|
||||||
: frame() { closure_frame_holder_ref(&frame); }
|
|
||||||
closure_frame_t& context() { assert(frame!=0); return frame.get(); }
|
|
||||||
closure_frame_t const& context() const { assert(frame!=0); return frame.get(); }
|
|
||||||
|
|
||||||
typedef actor<closure_member<0, self_t> > member1;
|
|
||||||
typedef actor<closure_member<1, self_t> > member2;
|
|
||||||
typedef actor<closure_member<2, self_t> > member3;
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 3
|
|
||||||
typedef actor<closure_member<3, self_t> > member4;
|
|
||||||
typedef actor<closure_member<4, self_t> > member5;
|
|
||||||
typedef actor<closure_member<5, self_t> > member6;
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 6
|
|
||||||
typedef actor<closure_member<6, self_t> > member7;
|
|
||||||
typedef actor<closure_member<7, self_t> > member8;
|
|
||||||
typedef actor<closure_member<8, self_t> > member9;
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 9
|
|
||||||
typedef actor<closure_member<9, self_t> > member10;
|
|
||||||
typedef actor<closure_member<10, self_t> > member11;
|
|
||||||
typedef actor<closure_member<11, self_t> > member12;
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 12
|
|
||||||
typedef actor<closure_member<12, self_t> > member13;
|
|
||||||
typedef actor<closure_member<13, self_t> > member14;
|
|
||||||
typedef actor<closure_member<14, self_t> > member15;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(__MWERKS__) || (__MWERKS__ > 0x3002)
|
|
||||||
private:
|
|
||||||
#endif
|
|
||||||
|
|
||||||
closure(closure const&); // no copy
|
|
||||||
closure& operator=(closure const&); // no assign
|
|
||||||
|
|
||||||
#if !defined(__MWERKS__) || (__MWERKS__ > 0x3002)
|
|
||||||
template <int N, typename ClosureT>
|
|
||||||
friend class closure_member;
|
|
||||||
|
|
||||||
template <typename ClosureT>
|
|
||||||
friend class closure_frame;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef impl::closure_frame_holder<closure_frame_t> holder_t;
|
|
||||||
|
|
||||||
#ifdef PHOENIX_THREADSAFE
|
|
||||||
static boost::thread_specific_ptr<holder_t*> &
|
|
||||||
tsp_frame_instance()
|
|
||||||
{
|
|
||||||
static boost::thread_specific_ptr<holder_t*> the_instance;
|
|
||||||
return the_instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
tsp_frame_instance_init()
|
|
||||||
{
|
|
||||||
tsp_frame_instance();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static holder_t &
|
|
||||||
closure_frame_holder_ref(holder_t* holder_ = 0)
|
|
||||||
{
|
|
||||||
#ifdef PHOENIX_THREADSAFE
|
|
||||||
static boost::once_flag been_here = BOOST_ONCE_INIT;
|
|
||||||
boost::call_once(tsp_frame_instance_init, been_here);
|
|
||||||
boost::thread_specific_ptr<holder_t*> &tsp_frame = tsp_frame_instance();
|
|
||||||
if (!tsp_frame.get())
|
|
||||||
tsp_frame.reset(new holder_t *(0));
|
|
||||||
holder_t *& holder = *tsp_frame;
|
|
||||||
#else
|
|
||||||
static holder_t* holder = 0;
|
|
||||||
#endif
|
|
||||||
if (holder_ != 0)
|
|
||||||
holder = holder_;
|
|
||||||
return *holder;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutable holder_t frame;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
// namespace phoenix
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
@ -1,761 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Phoenix V1.2.1
|
|
||||||
Copyright (c) 2001-2002 Joel de Guzman
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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 PHOENIX_FUNCTIONS_HPP
|
|
||||||
#define PHOENIX_FUNCTIONS_HPP
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <boost/spirit/phoenix/actor.hpp>
|
|
||||||
#include <boost/spirit/phoenix/composite.hpp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace phoenix {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// function class
|
|
||||||
//
|
|
||||||
// Lazy functions
|
|
||||||
//
|
|
||||||
// This class provides a mechanism for lazily evaluating functions.
|
|
||||||
// Syntactically, a lazy function looks like an ordinary C/C++
|
|
||||||
// function. The function call looks the same. However, unlike
|
|
||||||
// ordinary functions, the actual function execution is deferred.
|
|
||||||
// (see actor.hpp, primitives.hpp and composite.hpp for an
|
|
||||||
// overview). For example here are sample factorial function calls:
|
|
||||||
//
|
|
||||||
// factorial(4)
|
|
||||||
// factorial(arg1)
|
|
||||||
// factorial(arg1 * 6)
|
|
||||||
//
|
|
||||||
// These functions are automatically lazily bound unlike ordinary
|
|
||||||
// function pointers or functor objects that need to be explicitly
|
|
||||||
// bound through the bind function (see binders.hpp).
|
|
||||||
//
|
|
||||||
// A lazy function works in conjunction with a user defined functor
|
|
||||||
// (as usual with a member operator()). Only special forms of
|
|
||||||
// functor objects are allowed. This is required to enable true
|
|
||||||
// polymorphism (STL style monomorphic functors and function
|
|
||||||
// pointers can still be used through the bind facility in
|
|
||||||
// binders.hpp).
|
|
||||||
//
|
|
||||||
// This special functor is expected to have a nested template class
|
|
||||||
// result<A...TN> (where N is the number of arguments of its
|
|
||||||
// member operator()). The nested template class result should have
|
|
||||||
// a typedef 'type' that reflects the return type of its member
|
|
||||||
// operator(). This is essentially a type computer that answers the
|
|
||||||
// metaprogramming question "Given arguments of type A...TN, what
|
|
||||||
// will be the operator()'s return type?".
|
|
||||||
//
|
|
||||||
// There is a special case for functors that accept no arguments.
|
|
||||||
// Such nullary functors are only required to define a typedef
|
|
||||||
// result_type that reflects the return type of its operator().
|
|
||||||
//
|
|
||||||
// Here's an example of a simple functor that computes the
|
|
||||||
// factorial of a number:
|
|
||||||
//
|
|
||||||
// struct factorial_impl {
|
|
||||||
//
|
|
||||||
// template <typename Arg>
|
|
||||||
// struct result { typedef Arg type; };
|
|
||||||
//
|
|
||||||
// template <typename Arg>
|
|
||||||
// Arg operator()(Arg n) const
|
|
||||||
// { return (n <= 0) ? 1 : n * this->operator()(n-1); }
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// As can be seen, the functor can be polymorphic. Its arguments
|
|
||||||
// and return type are not fixed to a particular type. The example
|
|
||||||
// above for example, can handle any type as long as it can carry
|
|
||||||
// out the required operations (i.e. <=, * and -).
|
|
||||||
//
|
|
||||||
// We can now declare and instantiate a lazy 'factorial' function:
|
|
||||||
//
|
|
||||||
// function<factorial_impl> factorial;
|
|
||||||
//
|
|
||||||
// Invoking a lazy function 'factorial' does not immediately
|
|
||||||
// execute the functor factorial_impl. Instead, a composite (see
|
|
||||||
// composite.hpp) object is created and returned to the caller.
|
|
||||||
// Example:
|
|
||||||
//
|
|
||||||
// factorial(arg1)
|
|
||||||
//
|
|
||||||
// does nothing more than return a composite. A second function
|
|
||||||
// call will invoke the actual factorial function. Example:
|
|
||||||
//
|
|
||||||
// int i = 4;
|
|
||||||
// cout << factorial(arg1)(i);
|
|
||||||
//
|
|
||||||
// will print out "24".
|
|
||||||
//
|
|
||||||
// Take note that in certain cases (e.g. for functors with state),
|
|
||||||
// an instance may be passed on to the constructor. Example:
|
|
||||||
//
|
|
||||||
// function<factorial_impl> factorial(ftor);
|
|
||||||
//
|
|
||||||
// where ftor is an instance of factorial_impl (this is not
|
|
||||||
// necessary in this case since factorial is a simple stateless
|
|
||||||
// functor). Take care though when using functors with state
|
|
||||||
// because the functors are taken in by value. It is best to keep
|
|
||||||
// the data manipulated by a functor outside the functor itself and
|
|
||||||
// keep a reference to this data inside the functor. Also, it is
|
|
||||||
// best to keep functors as small as possible.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename OperationT>
|
|
||||||
struct function {
|
|
||||||
|
|
||||||
function() : op() {}
|
|
||||||
function(OperationT const& op_) : op(op_) {}
|
|
||||||
|
|
||||||
actor<composite<OperationT> >
|
|
||||||
operator()() const;
|
|
||||||
|
|
||||||
template <typename A>
|
|
||||||
typename impl::make_composite<OperationT, A>::type
|
|
||||||
operator()(A const& a) const;
|
|
||||||
|
|
||||||
template <typename A, typename B>
|
|
||||||
typename impl::make_composite<OperationT, A, B>::type
|
|
||||||
operator()(A const& a, B const& b) const;
|
|
||||||
|
|
||||||
template <typename A, typename B, typename C>
|
|
||||||
typename impl::make_composite<OperationT, A, B, C>::type
|
|
||||||
operator()(A const& a, B const& b, C const& c) const;
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 3
|
|
||||||
|
|
||||||
template <typename A, typename B, typename C, typename D>
|
|
||||||
typename impl::make_composite<OperationT, A, B, C, D>::type
|
|
||||||
operator()(A const& a, B const& b, C const& c, D const& d) const;
|
|
||||||
|
|
||||||
template <typename A, typename B, typename C, typename D, typename E>
|
|
||||||
typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E
|
|
||||||
>::type
|
|
||||||
operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e
|
|
||||||
) const;
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F
|
|
||||||
>
|
|
||||||
typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F
|
|
||||||
>::type
|
|
||||||
operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f
|
|
||||||
) const;
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 6
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G
|
|
||||||
>
|
|
||||||
typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G
|
|
||||||
>::type
|
|
||||||
operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f, G const& g
|
|
||||||
) const;
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H
|
|
||||||
>
|
|
||||||
typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H
|
|
||||||
>::type
|
|
||||||
operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f, G const& g, H const& h
|
|
||||||
) const;
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I
|
|
||||||
>
|
|
||||||
typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I
|
|
||||||
>::type
|
|
||||||
operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f, G const& g, H const& h, I const& i
|
|
||||||
) const;
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 9
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J
|
|
||||||
>
|
|
||||||
typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I, J
|
|
||||||
>::type
|
|
||||||
operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f, G const& g, H const& h, I const& i, J const& j
|
|
||||||
) const;
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K
|
|
||||||
>
|
|
||||||
typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I, J, K
|
|
||||||
>::type
|
|
||||||
operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f, G const& g, H const& h, I const& i, J const& j,
|
|
||||||
K const& k
|
|
||||||
) const;
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K, typename L
|
|
||||||
>
|
|
||||||
typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I, J, K, L
|
|
||||||
>::type
|
|
||||||
operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f, G const& g, H const& h, I const& i, J const& j,
|
|
||||||
K const& k, L const& l
|
|
||||||
) const;
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 12
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K, typename L, typename M
|
|
||||||
>
|
|
||||||
typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M
|
|
||||||
>::type
|
|
||||||
operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f, G const& g, H const& h, I const& i, J const& j,
|
|
||||||
K const& k, L const& l, M const& m
|
|
||||||
) const;
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K, typename L, typename M, typename N
|
|
||||||
>
|
|
||||||
typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N
|
|
||||||
>::type
|
|
||||||
operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f, G const& g, H const& h, I const& i, J const& j,
|
|
||||||
K const& k, L const& l, M const& m, N const& n
|
|
||||||
) const;
|
|
||||||
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K, typename L, typename M, typename N, typename O
|
|
||||||
>
|
|
||||||
typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O
|
|
||||||
>::type
|
|
||||||
operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f, G const& g, H const& h, I const& i, J const& j,
|
|
||||||
K const& k, L const& l, M const& m, N const& n, O const& o
|
|
||||||
) const;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
OperationT op;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// function class implementation
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename OperationT>
|
|
||||||
inline actor<composite<OperationT> >
|
|
||||||
function<OperationT>::operator()() const
|
|
||||||
{
|
|
||||||
return actor<composite<OperationT> >(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename OperationT>
|
|
||||||
template <typename A>
|
|
||||||
inline typename impl::make_composite<OperationT, A>::type
|
|
||||||
function<OperationT>::operator()(A const& a) const
|
|
||||||
{
|
|
||||||
typedef typename impl::make_composite<OperationT, A>::composite_type ret_t;
|
|
||||||
return ret_t
|
|
||||||
(
|
|
||||||
op,
|
|
||||||
as_actor<A>::convert(a)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename OperationT>
|
|
||||||
template <typename A, typename B>
|
|
||||||
inline typename impl::make_composite<OperationT, A, B>::type
|
|
||||||
function<OperationT>::operator()(A const& a, B const& b) const
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
typename impl::make_composite<OperationT, A, B>::composite_type
|
|
||||||
ret_t;
|
|
||||||
|
|
||||||
return ret_t(
|
|
||||||
op,
|
|
||||||
as_actor<A>::convert(a),
|
|
||||||
as_actor<B>::convert(b)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename OperationT>
|
|
||||||
template <typename A, typename B, typename C>
|
|
||||||
inline typename impl::make_composite<OperationT, A, B, C>::type
|
|
||||||
function<OperationT>::operator()(A const& a, B const& b, C const& c) const
|
|
||||||
{
|
|
||||||
typedef
|
|
||||||
typename impl::make_composite<OperationT, A, B, C>::composite_type
|
|
||||||
ret_t;
|
|
||||||
|
|
||||||
return ret_t(
|
|
||||||
op,
|
|
||||||
as_actor<A>::convert(a),
|
|
||||||
as_actor<B>::convert(b),
|
|
||||||
as_actor<C>::convert(c)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 3
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename OperationT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D
|
|
||||||
>
|
|
||||||
inline typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D
|
|
||||||
>::type
|
|
||||||
function<OperationT>::operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
typedef typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D
|
|
||||||
>::composite_type ret_t;
|
|
||||||
|
|
||||||
return ret_t(
|
|
||||||
op,
|
|
||||||
as_actor<A>::convert(a),
|
|
||||||
as_actor<B>::convert(b),
|
|
||||||
as_actor<C>::convert(c),
|
|
||||||
as_actor<D>::convert(d)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename OperationT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E
|
|
||||||
>
|
|
||||||
inline typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E
|
|
||||||
>::type
|
|
||||||
function<OperationT>::operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
typedef typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E
|
|
||||||
>::composite_type ret_t;
|
|
||||||
|
|
||||||
return ret_t(
|
|
||||||
op,
|
|
||||||
as_actor<A>::convert(a),
|
|
||||||
as_actor<B>::convert(b),
|
|
||||||
as_actor<C>::convert(c),
|
|
||||||
as_actor<D>::convert(d),
|
|
||||||
as_actor<E>::convert(e)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename OperationT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F
|
|
||||||
>
|
|
||||||
inline typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F
|
|
||||||
>::type
|
|
||||||
function<OperationT>::operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
typedef typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F
|
|
||||||
>::composite_type ret_t;
|
|
||||||
|
|
||||||
return ret_t(
|
|
||||||
op,
|
|
||||||
as_actor<A>::convert(a),
|
|
||||||
as_actor<B>::convert(b),
|
|
||||||
as_actor<C>::convert(c),
|
|
||||||
as_actor<D>::convert(d),
|
|
||||||
as_actor<E>::convert(e),
|
|
||||||
as_actor<F>::convert(f)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 6
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename OperationT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G
|
|
||||||
>
|
|
||||||
inline typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G
|
|
||||||
>::type
|
|
||||||
function<OperationT>::operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f, G const& g
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
typedef typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G
|
|
||||||
>::composite_type ret_t;
|
|
||||||
|
|
||||||
return ret_t(
|
|
||||||
op,
|
|
||||||
as_actor<A>::convert(a),
|
|
||||||
as_actor<B>::convert(b),
|
|
||||||
as_actor<C>::convert(c),
|
|
||||||
as_actor<D>::convert(d),
|
|
||||||
as_actor<E>::convert(e),
|
|
||||||
as_actor<F>::convert(f),
|
|
||||||
as_actor<G>::convert(g)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename OperationT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H
|
|
||||||
>
|
|
||||||
inline typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H
|
|
||||||
>::type
|
|
||||||
function<OperationT>::operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f, G const& g, H const& h
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
typedef typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H
|
|
||||||
>::composite_type ret_t;
|
|
||||||
|
|
||||||
return ret_t(
|
|
||||||
op,
|
|
||||||
as_actor<A>::convert(a),
|
|
||||||
as_actor<B>::convert(b),
|
|
||||||
as_actor<C>::convert(c),
|
|
||||||
as_actor<D>::convert(d),
|
|
||||||
as_actor<E>::convert(e),
|
|
||||||
as_actor<F>::convert(f),
|
|
||||||
as_actor<G>::convert(g),
|
|
||||||
as_actor<H>::convert(h)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename OperationT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I
|
|
||||||
>
|
|
||||||
inline typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I
|
|
||||||
>::type
|
|
||||||
function<OperationT>::operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f, G const& g, H const& h, I const& i
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
typedef typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I
|
|
||||||
>::composite_type ret_t;
|
|
||||||
|
|
||||||
return ret_t(
|
|
||||||
op,
|
|
||||||
as_actor<A>::convert(a),
|
|
||||||
as_actor<B>::convert(b),
|
|
||||||
as_actor<C>::convert(c),
|
|
||||||
as_actor<D>::convert(d),
|
|
||||||
as_actor<E>::convert(e),
|
|
||||||
as_actor<F>::convert(f),
|
|
||||||
as_actor<G>::convert(g),
|
|
||||||
as_actor<H>::convert(h),
|
|
||||||
as_actor<I>::convert(i)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 9
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename OperationT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J
|
|
||||||
>
|
|
||||||
inline typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I, J
|
|
||||||
>::type
|
|
||||||
function<OperationT>::operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f, G const& g, H const& h, I const& i, J const& j
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
typedef typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I, J
|
|
||||||
>::composite_type ret_t;
|
|
||||||
|
|
||||||
return ret_t(
|
|
||||||
op,
|
|
||||||
as_actor<A>::convert(a),
|
|
||||||
as_actor<B>::convert(b),
|
|
||||||
as_actor<C>::convert(c),
|
|
||||||
as_actor<D>::convert(d),
|
|
||||||
as_actor<E>::convert(e),
|
|
||||||
as_actor<F>::convert(f),
|
|
||||||
as_actor<G>::convert(g),
|
|
||||||
as_actor<H>::convert(h),
|
|
||||||
as_actor<I>::convert(i),
|
|
||||||
as_actor<J>::convert(j)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename OperationT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K
|
|
||||||
>
|
|
||||||
inline typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I, J, K
|
|
||||||
>::type
|
|
||||||
function<OperationT>::operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f, G const& g, H const& h, I const& i, J const& j,
|
|
||||||
K const& k
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
typedef typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I, J, K
|
|
||||||
>::composite_type ret_t;
|
|
||||||
|
|
||||||
return ret_t(
|
|
||||||
op,
|
|
||||||
as_actor<A>::convert(a),
|
|
||||||
as_actor<B>::convert(b),
|
|
||||||
as_actor<C>::convert(c),
|
|
||||||
as_actor<D>::convert(d),
|
|
||||||
as_actor<E>::convert(e),
|
|
||||||
as_actor<F>::convert(f),
|
|
||||||
as_actor<G>::convert(g),
|
|
||||||
as_actor<H>::convert(h),
|
|
||||||
as_actor<I>::convert(i),
|
|
||||||
as_actor<J>::convert(j),
|
|
||||||
as_actor<K>::convert(k)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename OperationT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K, typename L
|
|
||||||
>
|
|
||||||
inline typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I, J, K, L
|
|
||||||
>::type
|
|
||||||
function<OperationT>::operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f, G const& g, H const& h, I const& i, J const& j,
|
|
||||||
K const& k, L const& l
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
typedef typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I, J, K, L
|
|
||||||
>::composite_type ret_t;
|
|
||||||
|
|
||||||
return ret_t(
|
|
||||||
op,
|
|
||||||
as_actor<A>::convert(a),
|
|
||||||
as_actor<B>::convert(b),
|
|
||||||
as_actor<C>::convert(c),
|
|
||||||
as_actor<D>::convert(d),
|
|
||||||
as_actor<E>::convert(e),
|
|
||||||
as_actor<F>::convert(f),
|
|
||||||
as_actor<G>::convert(g),
|
|
||||||
as_actor<H>::convert(h),
|
|
||||||
as_actor<I>::convert(i),
|
|
||||||
as_actor<J>::convert(j),
|
|
||||||
as_actor<K>::convert(k),
|
|
||||||
as_actor<L>::convert(l)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 12
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename OperationT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K, typename L, typename M
|
|
||||||
>
|
|
||||||
inline typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M
|
|
||||||
>::type
|
|
||||||
function<OperationT>::operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f, G const& g, H const& h, I const& i, J const& j,
|
|
||||||
K const& k, L const& l, M const& m
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
typedef typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M
|
|
||||||
>::composite_type ret_t;
|
|
||||||
|
|
||||||
return ret_t(
|
|
||||||
op,
|
|
||||||
as_actor<A>::convert(a),
|
|
||||||
as_actor<B>::convert(b),
|
|
||||||
as_actor<C>::convert(c),
|
|
||||||
as_actor<D>::convert(d),
|
|
||||||
as_actor<E>::convert(e),
|
|
||||||
as_actor<F>::convert(f),
|
|
||||||
as_actor<G>::convert(g),
|
|
||||||
as_actor<H>::convert(h),
|
|
||||||
as_actor<I>::convert(i),
|
|
||||||
as_actor<J>::convert(j),
|
|
||||||
as_actor<K>::convert(k),
|
|
||||||
as_actor<L>::convert(l),
|
|
||||||
as_actor<M>::convert(m)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename OperationT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K, typename L, typename M, typename N
|
|
||||||
>
|
|
||||||
inline typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N
|
|
||||||
>::type
|
|
||||||
function<OperationT>::operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f, G const& g, H const& h, I const& i, J const& j,
|
|
||||||
K const& k, L const& l, M const& m, N const& n
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
typedef typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N
|
|
||||||
>::composite_type ret_t;
|
|
||||||
|
|
||||||
return ret_t(
|
|
||||||
op,
|
|
||||||
as_actor<A>::convert(a),
|
|
||||||
as_actor<B>::convert(b),
|
|
||||||
as_actor<C>::convert(c),
|
|
||||||
as_actor<D>::convert(d),
|
|
||||||
as_actor<E>::convert(e),
|
|
||||||
as_actor<F>::convert(f),
|
|
||||||
as_actor<G>::convert(g),
|
|
||||||
as_actor<H>::convert(h),
|
|
||||||
as_actor<I>::convert(i),
|
|
||||||
as_actor<J>::convert(j),
|
|
||||||
as_actor<K>::convert(k),
|
|
||||||
as_actor<L>::convert(l),
|
|
||||||
as_actor<M>::convert(m),
|
|
||||||
as_actor<N>::convert(n)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename OperationT>
|
|
||||||
template <
|
|
||||||
typename A, typename B, typename C, typename D, typename E,
|
|
||||||
typename F, typename G, typename H, typename I, typename J,
|
|
||||||
typename K, typename L, typename M, typename N, typename O
|
|
||||||
>
|
|
||||||
inline typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O
|
|
||||||
>::type
|
|
||||||
function<OperationT>::operator()(
|
|
||||||
A const& a, B const& b, C const& c, D const& d, E const& e,
|
|
||||||
F const& f, G const& g, H const& h, I const& i, J const& j,
|
|
||||||
K const& k, L const& l, M const& m, N const& n, O const& o
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
typedef typename impl::make_composite<
|
|
||||||
OperationT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O
|
|
||||||
>::composite_type ret_t;
|
|
||||||
|
|
||||||
return ret_t(
|
|
||||||
op,
|
|
||||||
as_actor<A>::convert(a),
|
|
||||||
as_actor<B>::convert(b),
|
|
||||||
as_actor<C>::convert(c),
|
|
||||||
as_actor<D>::convert(d),
|
|
||||||
as_actor<E>::convert(e),
|
|
||||||
as_actor<F>::convert(f),
|
|
||||||
as_actor<G>::convert(g),
|
|
||||||
as_actor<H>::convert(h),
|
|
||||||
as_actor<I>::convert(i),
|
|
||||||
as_actor<J>::convert(j),
|
|
||||||
as_actor<K>::convert(k),
|
|
||||||
as_actor<L>::convert(l),
|
|
||||||
as_actor<M>::convert(m),
|
|
||||||
as_actor<N>::convert(n),
|
|
||||||
as_actor<O>::convert(o)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
} // namespace phoenix
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,248 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Phoenix V1.2.1
|
|
||||||
Copyright (c) 2001-2002 Joel de Guzman
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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 PHOENIX_PRIMITIVES_HPP
|
|
||||||
#define PHOENIX_PRIMITIVES_HPP
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <boost/spirit/phoenix/actor.hpp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace phoenix {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// argument class
|
|
||||||
//
|
|
||||||
// Lazy arguments
|
|
||||||
//
|
|
||||||
// An actor base class that extracts and returns the Nth argument
|
|
||||||
// from the argument list passed in the 'args' tuple in the eval
|
|
||||||
// member function (see actor.hpp). There are some predefined
|
|
||||||
// argument constants that can be used as actors (arg1..argN).
|
|
||||||
//
|
|
||||||
// The argument actor is a place-holder for the actual arguments
|
|
||||||
// passed by the client. For example, wherever arg1 is seen placed
|
|
||||||
// in a lazy function (see functions.hpp) or lazy operator (see
|
|
||||||
// operators.hpp), this will be replaced by the actual first
|
|
||||||
// argument in the actual function evaluation. Argument actors are
|
|
||||||
// essentially lazy arguments. A lazy argument is a full actor in
|
|
||||||
// its own right and can be evaluated through the actor's operator().
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
//
|
|
||||||
// char c = 'A';
|
|
||||||
// int i = 123;
|
|
||||||
// const char* s = "Hello World";
|
|
||||||
//
|
|
||||||
// cout << arg1(c) << ' ';
|
|
||||||
// cout << arg1(i, s) << ' ';
|
|
||||||
// cout << arg2(i, s) << ' ';
|
|
||||||
//
|
|
||||||
// will print out "A 123 Hello World"
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <int N>
|
|
||||||
struct argument {
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
struct result { typedef typename tuple_element<N, TupleT>::type type; };
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
typename tuple_element<N, TupleT>::type
|
|
||||||
eval(TupleT const& args) const
|
|
||||||
{
|
|
||||||
return args[tuple_index<N>()];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
actor<argument<0> > const arg1 = argument<0>();
|
|
||||||
actor<argument<1> > const arg2 = argument<1>();
|
|
||||||
actor<argument<2> > const arg3 = argument<2>();
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 3
|
|
||||||
actor<argument<3> > const arg4 = argument<3>();
|
|
||||||
actor<argument<4> > const arg5 = argument<4>();
|
|
||||||
actor<argument<5> > const arg6 = argument<5>();
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 6
|
|
||||||
actor<argument<6> > const arg7 = argument<6>();
|
|
||||||
actor<argument<7> > const arg8 = argument<7>();
|
|
||||||
actor<argument<8> > const arg9 = argument<8>();
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 9
|
|
||||||
actor<argument<9> > const arg10 = argument<9>();
|
|
||||||
actor<argument<10> > const arg11 = argument<10>();
|
|
||||||
actor<argument<11> > const arg12 = argument<11>();
|
|
||||||
|
|
||||||
#if PHOENIX_LIMIT > 12
|
|
||||||
actor<argument<12> > const arg13 = argument<12>();
|
|
||||||
actor<argument<13> > const arg14 = argument<13>();
|
|
||||||
actor<argument<14> > const arg15 = argument<14>();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// value class
|
|
||||||
//
|
|
||||||
// Lazy values
|
|
||||||
//
|
|
||||||
// A bound actual parameter is kept in a value class for deferred
|
|
||||||
// access later when needed. A value object is immutable. Value
|
|
||||||
// objects are typically created through the val(x) free function
|
|
||||||
// which returns a value<T> with T deduced from the type of x. x is
|
|
||||||
// held in the value<T> object by value.
|
|
||||||
//
|
|
||||||
// Lazy values are actors. As such, lazy values can be evaluated
|
|
||||||
// through the actor's operator(). Such invocation gives the value's
|
|
||||||
// identity. Example:
|
|
||||||
//
|
|
||||||
// cout << val(3)() << val("Hello World")();
|
|
||||||
//
|
|
||||||
// prints out "3 Hello World"
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
struct value {
|
|
||||||
|
|
||||||
typedef typename boost::remove_reference<T>::type plain_t;
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
struct result { typedef plain_t const type; };
|
|
||||||
|
|
||||||
value(plain_t val_)
|
|
||||||
: val(val_) {}
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
plain_t const
|
|
||||||
eval(TupleT const& /*args*/) const
|
|
||||||
{
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
plain_t val;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
inline actor<value<T> > const
|
|
||||||
val(T v)
|
|
||||||
{
|
|
||||||
return value<T>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
void
|
|
||||||
val(actor<BaseT> const& v); // This is undefined and not allowed.
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Arbitrary types T are typically converted to a actor<value<T> >
|
|
||||||
// (see as_actor<T> in actor.hpp). A specialization is also provided
|
|
||||||
// for arrays. T[N] arrays are converted to actor<value<T const*> >.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
struct as_actor {
|
|
||||||
|
|
||||||
typedef actor<value<T> > type;
|
|
||||||
static type convert(T const& x)
|
|
||||||
{ return value<T>(x); }
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename T, int N>
|
|
||||||
struct as_actor<T[N]> {
|
|
||||||
|
|
||||||
typedef actor<value<T const*> > type;
|
|
||||||
static type convert(T const x[N])
|
|
||||||
{ return value<T const*>(x); }
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// variable class
|
|
||||||
//
|
|
||||||
// Lazy variables
|
|
||||||
//
|
|
||||||
// A bound actual parameter may also be held by non-const reference
|
|
||||||
// in a variable class for deferred access later when needed. A
|
|
||||||
// variable object is mutable, i.e. its referenced variable can be
|
|
||||||
// modified. Variable objects are typically created through the
|
|
||||||
// var(x) free function which returns a variable<T> with T deduced
|
|
||||||
// from the type of x. x is held in the value<T> object by
|
|
||||||
// reference.
|
|
||||||
//
|
|
||||||
// Lazy variables are actors. As such, lazy variables can be
|
|
||||||
// evaluated through the actor's operator(). Such invocation gives
|
|
||||||
// the variables's identity. Example:
|
|
||||||
//
|
|
||||||
// int i = 3;
|
|
||||||
// char const* s = "Hello World";
|
|
||||||
// cout << var(i)() << var(s)();
|
|
||||||
//
|
|
||||||
// prints out "3 Hello World"
|
|
||||||
//
|
|
||||||
// Another free function const_(x) may also be used. const_(x) creates
|
|
||||||
// a variable<T const&> object using a constant reference.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
struct variable {
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
struct result { typedef T& type; };
|
|
||||||
|
|
||||||
variable(T& var_)
|
|
||||||
: var(var_) {}
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
T&
|
|
||||||
eval(TupleT const& /*args*/) const
|
|
||||||
{
|
|
||||||
return var;
|
|
||||||
}
|
|
||||||
|
|
||||||
T& var;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
inline actor<variable<T> > const
|
|
||||||
var(T& v)
|
|
||||||
{
|
|
||||||
return variable<T>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
inline actor<variable<T const> > const
|
|
||||||
const_(T const& v)
|
|
||||||
{
|
|
||||||
return variable<T const>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
void
|
|
||||||
var(actor<BaseT> const& v); // This is undefined and not allowed.
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
void
|
|
||||||
const_(actor<BaseT> const& v); // This is undefined and not allowed.
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
} // namespace phoenix
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,342 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Phoenix V1.2.1
|
|
||||||
Copyright (c) 2001-2002 Joel de Guzman
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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 PHOENIX_SPECIAL_OPS_HPP
|
|
||||||
#define PHOENIX_SPECIAL_OPS_HPP
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
|
||||||
#ifdef BOOST_NO_STRINGSTREAM
|
|
||||||
#include <strstream>
|
|
||||||
#define PHOENIX_SSTREAM strstream
|
|
||||||
#else
|
|
||||||
#include <sstream>
|
|
||||||
#define PHOENIX_SSTREAM stringstream
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <boost/spirit/phoenix/operators.hpp>
|
|
||||||
#include <iosfwd>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#if defined(_STLPORT_VERSION) && defined(__STL_USE_OWN_NAMESPACE)
|
|
||||||
#define PHOENIX_STD _STLP_STD
|
|
||||||
#define PHOENIX_NO_STD_NAMESPACE
|
|
||||||
#else
|
|
||||||
#define PHOENIX_STD std
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//#if !defined(PHOENIX_NO_STD_NAMESPACE)
|
|
||||||
namespace PHOENIX_STD
|
|
||||||
{
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
template<typename T> class complex;
|
|
||||||
|
|
||||||
//#if !defined(PHOENIX_NO_STD_NAMESPACE)
|
|
||||||
}
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace phoenix
|
|
||||||
{
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// The following specializations take into account the C++ standard
|
|
||||||
// library components. There are a couple of issues that have to be
|
|
||||||
// dealt with to enable lazy operator overloads for the standard
|
|
||||||
// library classes.
|
|
||||||
//
|
|
||||||
// *iostream (e.g. cout, cin, strstream/ stringstream) uses non-
|
|
||||||
// canonical shift operator overloads where the lhs is taken in
|
|
||||||
// by reference.
|
|
||||||
//
|
|
||||||
// *I/O manipulators overloads for the RHS of the << and >>
|
|
||||||
// operators.
|
|
||||||
//
|
|
||||||
// *STL iterators can be objects that conform to pointer semantics.
|
|
||||||
// Some operators need to be specialized for these.
|
|
||||||
//
|
|
||||||
// *std::complex is given a rank (see rank class in operators.hpp)
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// specialization for rank<std::complex>
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T> struct rank<PHOENIX_STD::complex<T> >
|
|
||||||
{ static int const value = 170 + rank<T>::value; };
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// specializations for std::istream
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
|
||||||
#if defined(_STLPORT_VERSION)
|
|
||||||
#define PHOENIX_ISTREAM _IO_istream_withassign
|
|
||||||
#else
|
|
||||||
#define PHOENIX_ISTREAM PHOENIX_STD::_IO_istream_withassign
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
// #if (defined(__ICL) && defined(_STLPORT_VERSION))
|
|
||||||
// #define PHOENIX_ISTREAM istream_withassign
|
|
||||||
// #else
|
|
||||||
#define PHOENIX_ISTREAM PHOENIX_STD::istream
|
|
||||||
// #endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
|
||||||
// || (defined(__ICL) && defined(_STLPORT_VERSION))
|
|
||||||
template <typename T1>
|
|
||||||
struct binary_operator<shift_r_op, PHOENIX_ISTREAM, T1>
|
|
||||||
{
|
|
||||||
typedef PHOENIX_STD::istream& result_type;
|
|
||||||
static result_type eval(PHOENIX_STD::istream& out, T1& rhs)
|
|
||||||
{ return out >> rhs; }
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename T1>
|
|
||||||
struct binary_operator<shift_r_op, PHOENIX_STD::istream, T1>
|
|
||||||
{
|
|
||||||
typedef PHOENIX_STD::istream& result_type;
|
|
||||||
static result_type eval(PHOENIX_STD::istream& out, T1& rhs)
|
|
||||||
{ return out >> rhs; }
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
inline typename impl::make_binary3
|
|
||||||
<shift_r_op, variable<PHOENIX_ISTREAM>, BaseT>::type
|
|
||||||
operator>>(PHOENIX_ISTREAM& _0, actor<BaseT> const& _1)
|
|
||||||
{
|
|
||||||
return impl::make_binary3
|
|
||||||
<shift_r_op, variable<PHOENIX_ISTREAM>, BaseT>
|
|
||||||
::construct(var(_0), _1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef PHOENIX_ISTREAM
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// specializations for std::ostream
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
|
||||||
#if defined(_STLPORT_VERSION)
|
|
||||||
#define PHOENIX_OSTREAM _IO_ostream_withassign
|
|
||||||
#else
|
|
||||||
#define PHOENIX_OSTREAM PHOENIX_STD::_IO_ostream_withassign
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
// #if (defined(__ICL) && defined(_STLPORT_VERSION))
|
|
||||||
// #define PHOENIX_OSTREAM ostream_withassign
|
|
||||||
// #else
|
|
||||||
#define PHOENIX_OSTREAM PHOENIX_STD::ostream
|
|
||||||
// #endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
|
||||||
// || (defined(__ICL) && defined(_STLPORT_VERSION))
|
|
||||||
template <typename T1>
|
|
||||||
struct binary_operator<shift_l_op, PHOENIX_OSTREAM, T1>
|
|
||||||
{
|
|
||||||
typedef PHOENIX_STD::ostream& result_type;
|
|
||||||
static result_type eval(PHOENIX_STD::ostream& out, T1 const& rhs)
|
|
||||||
{ return out << rhs; }
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename T1>
|
|
||||||
struct binary_operator<shift_l_op, PHOENIX_STD::ostream, T1>
|
|
||||||
{
|
|
||||||
typedef PHOENIX_STD::ostream& result_type;
|
|
||||||
static result_type eval(PHOENIX_STD::ostream& out, T1 const& rhs)
|
|
||||||
{ return out << rhs; }
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
inline typename impl::make_binary3
|
|
||||||
<shift_l_op, variable<PHOENIX_OSTREAM>, BaseT>::type
|
|
||||||
operator<<(PHOENIX_OSTREAM& _0, actor<BaseT> const& _1)
|
|
||||||
{
|
|
||||||
return impl::make_binary3
|
|
||||||
<shift_l_op, variable<PHOENIX_OSTREAM>, BaseT>
|
|
||||||
::construct(var(_0), _1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef PHOENIX_OSTREAM
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// specializations for std::strstream / stringstream
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T1>
|
|
||||||
struct binary_operator<shift_r_op, PHOENIX_STD::PHOENIX_SSTREAM, T1>
|
|
||||||
{
|
|
||||||
typedef PHOENIX_STD::istream& result_type;
|
|
||||||
static result_type eval(PHOENIX_STD::istream& out, T1& rhs)
|
|
||||||
{ return out >> rhs; }
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
inline typename impl::make_binary3
|
|
||||||
<shift_r_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>::type
|
|
||||||
operator>>(PHOENIX_STD::PHOENIX_SSTREAM& _0, actor<BaseT> const& _1)
|
|
||||||
{
|
|
||||||
return impl::make_binary3
|
|
||||||
<shift_r_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>
|
|
||||||
::construct(var(_0), _1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename T1>
|
|
||||||
struct binary_operator<shift_l_op, PHOENIX_STD::PHOENIX_SSTREAM, T1>
|
|
||||||
{
|
|
||||||
typedef PHOENIX_STD::ostream& result_type;
|
|
||||||
static result_type eval(PHOENIX_STD::ostream& out, T1 const& rhs)
|
|
||||||
{ return out << rhs; }
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
inline typename impl::make_binary3
|
|
||||||
<shift_l_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>::type
|
|
||||||
operator<<(PHOENIX_STD::PHOENIX_SSTREAM& _0, actor<BaseT> const& _1)
|
|
||||||
{
|
|
||||||
return impl::make_binary3
|
|
||||||
<shift_l_op, variable<PHOENIX_STD::PHOENIX_SSTREAM>, BaseT>
|
|
||||||
::construct(var(_0), _1);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// I/O manipulator specializations
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#if (!defined(__GNUC__) || (__GNUC__ > 2))
|
|
||||||
// && !(defined(__ICL) && defined(_STLPORT_VERSION))
|
|
||||||
|
|
||||||
typedef PHOENIX_STD::ios_base& (*iomanip_t)(PHOENIX_STD::ios_base&);
|
|
||||||
typedef PHOENIX_STD::istream& (*imanip_t)(PHOENIX_STD::istream&);
|
|
||||||
typedef PHOENIX_STD::ostream& (*omanip_t)(PHOENIX_STD::ostream&);
|
|
||||||
|
|
||||||
#if defined(__BORLANDC__)
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Borland does not like i/o manipulators functions such as endl to
|
|
||||||
// be the rhs of a lazy << operator (Borland incorrectly reports
|
|
||||||
// ambiguity). To get around the problem, we provide function
|
|
||||||
// pointer versions of the same name with a single trailing
|
|
||||||
// underscore.
|
|
||||||
//
|
|
||||||
// You can use the same trick for other i/o manipulators.
|
|
||||||
// Alternatively, you can prefix the manipulator with a '&'
|
|
||||||
// operator. Example:
|
|
||||||
//
|
|
||||||
// cout << arg1 << &endl
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
imanip_t ws_ = &PHOENIX_STD::ws;
|
|
||||||
iomanip_t dec_ = &PHOENIX_STD::dec;
|
|
||||||
iomanip_t hex_ = &PHOENIX_STD::hex;
|
|
||||||
iomanip_t oct_ = &PHOENIX_STD::oct;
|
|
||||||
omanip_t endl_ = &PHOENIX_STD::endl;
|
|
||||||
omanip_t ends_ = &PHOENIX_STD::ends;
|
|
||||||
omanip_t flush_ = &PHOENIX_STD::flush;
|
|
||||||
|
|
||||||
#else // __BORLANDC__
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// The following are overloads for I/O manipulators.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
inline typename impl::make_binary1<shift_l_op, BaseT, imanip_t>::type
|
|
||||||
operator>>(actor<BaseT> const& _0, imanip_t _1)
|
|
||||||
{
|
|
||||||
return impl::make_binary1<shift_l_op, BaseT, imanip_t>::construct(_0, _1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
inline typename impl::make_binary1<shift_l_op, BaseT, iomanip_t>::type
|
|
||||||
operator>>(actor<BaseT> const& _0, iomanip_t _1)
|
|
||||||
{
|
|
||||||
return impl::make_binary1<shift_l_op, BaseT, iomanip_t>::construct(_0, _1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
inline typename impl::make_binary1<shift_l_op, BaseT, omanip_t>::type
|
|
||||||
operator<<(actor<BaseT> const& _0, omanip_t _1)
|
|
||||||
{
|
|
||||||
return impl::make_binary1<shift_l_op, BaseT, omanip_t>::construct(_0, _1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT>
|
|
||||||
inline typename impl::make_binary1<shift_l_op, BaseT, iomanip_t>::type
|
|
||||||
operator<<(actor<BaseT> const& _0, iomanip_t _1)
|
|
||||||
{
|
|
||||||
return impl::make_binary1<shift_l_op, BaseT, iomanip_t>::construct(_0, _1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __BORLANDC__
|
|
||||||
#endif // !defined(__GNUC__) || (__GNUC__ > 2)
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// specializations for stl iterators and containers
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
struct unary_operator<dereference_op, T>
|
|
||||||
{
|
|
||||||
typedef typename T::reference result_type;
|
|
||||||
static result_type eval(T const& iter)
|
|
||||||
{ return *iter; }
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename T0, typename T1>
|
|
||||||
struct binary_operator<index_op, T0, T1>
|
|
||||||
{
|
|
||||||
typedef typename T0::reference result_type;
|
|
||||||
static result_type eval(T0& container, T1 const& index)
|
|
||||||
{ return container[index]; }
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename T0, typename T1>
|
|
||||||
struct binary_operator<index_op, T0 const, T1>
|
|
||||||
{
|
|
||||||
typedef typename T0::const_reference result_type;
|
|
||||||
static result_type eval(T0 const& container, T1 const& index)
|
|
||||||
{ return container[index]; }
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
} // namespace phoenix
|
|
||||||
|
|
||||||
#undef PHOENIX_SSTREAM
|
|
||||||
#undef PHOENIX_STD
|
|
||||||
#endif
|
|
@ -1,444 +0,0 @@
|
|||||||
/*=============================================================================
|
|
||||||
Phoenix V1.2.1
|
|
||||||
Copyright (c) 2001-2002 Joel de Guzman
|
|
||||||
|
|
||||||
Use, modification and distribution is subject to 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 PHOENIX_STATEMENTS_HPP
|
|
||||||
#define PHOENIX_STATEMENTS_HPP
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
#include <boost/spirit/phoenix/composite.hpp>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
namespace phoenix {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// sequential_composite
|
|
||||||
//
|
|
||||||
// Two or more actors separated by the comma generates a
|
|
||||||
// sequential_composite which is a composite actor. Example:
|
|
||||||
//
|
|
||||||
// actor,
|
|
||||||
// actor,
|
|
||||||
// actor
|
|
||||||
//
|
|
||||||
// The actors are evaluated sequentially. The result type of this
|
|
||||||
// is void. Note that the last actor should not have a trailing
|
|
||||||
// comma.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename A0, typename A1>
|
|
||||||
struct sequential_composite {
|
|
||||||
|
|
||||||
typedef sequential_composite<A0, A1> self_t;
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
struct result { typedef void type; };
|
|
||||||
|
|
||||||
sequential_composite(A0 const& _0, A1 const& _1)
|
|
||||||
: a0(_0), a1(_1) {}
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
void
|
|
||||||
eval(TupleT const& args) const
|
|
||||||
{
|
|
||||||
a0.eval(args);
|
|
||||||
a1.eval(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
A0 a0; A1 a1; // actors
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename BaseT0, typename BaseT1>
|
|
||||||
inline actor<sequential_composite<actor<BaseT0>, actor<BaseT1> > >
|
|
||||||
operator,(actor<BaseT0> const& _0, actor<BaseT1> const& _1)
|
|
||||||
{
|
|
||||||
return sequential_composite<actor<BaseT0>, actor<BaseT1> >(_0, _1);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// if_then_else_composite
|
|
||||||
//
|
|
||||||
// This composite has two (2) forms:
|
|
||||||
//
|
|
||||||
// if_(condition)
|
|
||||||
// [
|
|
||||||
// statement
|
|
||||||
// ]
|
|
||||||
//
|
|
||||||
// and
|
|
||||||
//
|
|
||||||
// if_(condition)
|
|
||||||
// [
|
|
||||||
// true_statement
|
|
||||||
// ]
|
|
||||||
// .else_
|
|
||||||
// [
|
|
||||||
// false_statement
|
|
||||||
// ]
|
|
||||||
//
|
|
||||||
// where condition is an actor that evaluates to bool. If condition
|
|
||||||
// is true, the true_statement (again an actor) is executed
|
|
||||||
// otherwise, the false_statement (another actor) is executed. The
|
|
||||||
// result type of this is void. Note the trailing underscore after
|
|
||||||
// if_ and the the leading dot and the trailing underscore before
|
|
||||||
// and after .else_.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename CondT, typename ThenT, typename ElseT>
|
|
||||||
struct if_then_else_composite {
|
|
||||||
|
|
||||||
typedef if_then_else_composite<CondT, ThenT, ElseT> self_t;
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
struct result {
|
|
||||||
|
|
||||||
typedef void type;
|
|
||||||
};
|
|
||||||
|
|
||||||
if_then_else_composite(
|
|
||||||
CondT const& cond_,
|
|
||||||
ThenT const& then_,
|
|
||||||
ElseT const& else__)
|
|
||||||
: cond(cond_), then(then_), else_(else__) {}
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
void eval(TupleT const& args) const
|
|
||||||
{
|
|
||||||
if (cond.eval(args))
|
|
||||||
then.eval(args);
|
|
||||||
else
|
|
||||||
else_.eval(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
CondT cond; ThenT then; ElseT else_; // actors
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename CondT, typename ThenT>
|
|
||||||
struct else_gen {
|
|
||||||
|
|
||||||
else_gen(CondT const& cond_, ThenT const& then_)
|
|
||||||
: cond(cond_), then(then_) {}
|
|
||||||
|
|
||||||
template <typename ElseT>
|
|
||||||
actor<if_then_else_composite<CondT, ThenT,
|
|
||||||
typename as_actor<ElseT>::type> >
|
|
||||||
operator[](ElseT const& else_)
|
|
||||||
{
|
|
||||||
typedef if_then_else_composite<CondT, ThenT,
|
|
||||||
typename as_actor<ElseT>::type>
|
|
||||||
result;
|
|
||||||
|
|
||||||
return result(cond, then, as_actor<ElseT>::convert(else_));
|
|
||||||
}
|
|
||||||
|
|
||||||
CondT cond; ThenT then;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename CondT, typename ThenT>
|
|
||||||
struct if_then_composite {
|
|
||||||
|
|
||||||
typedef if_then_composite<CondT, ThenT> self_t;
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
struct result { typedef void type; };
|
|
||||||
|
|
||||||
if_then_composite(CondT const& cond_, ThenT const& then_)
|
|
||||||
: cond(cond_), then(then_), else_(cond, then) {}
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
void eval(TupleT const& args) const
|
|
||||||
{
|
|
||||||
if (cond.eval(args))
|
|
||||||
then.eval(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
CondT cond; ThenT then; // actors
|
|
||||||
else_gen<CondT, ThenT> else_;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename CondT>
|
|
||||||
struct if_gen {
|
|
||||||
|
|
||||||
if_gen(CondT const& cond_)
|
|
||||||
: cond(cond_) {}
|
|
||||||
|
|
||||||
template <typename ThenT>
|
|
||||||
actor<if_then_composite<
|
|
||||||
typename as_actor<CondT>::type,
|
|
||||||
typename as_actor<ThenT>::type> >
|
|
||||||
operator[](ThenT const& then) const
|
|
||||||
{
|
|
||||||
typedef if_then_composite<
|
|
||||||
typename as_actor<CondT>::type,
|
|
||||||
typename as_actor<ThenT>::type>
|
|
||||||
result;
|
|
||||||
|
|
||||||
return result(
|
|
||||||
as_actor<CondT>::convert(cond),
|
|
||||||
as_actor<ThenT>::convert(then));
|
|
||||||
}
|
|
||||||
|
|
||||||
CondT cond;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename CondT>
|
|
||||||
inline if_gen<CondT>
|
|
||||||
if_(CondT const& cond)
|
|
||||||
{
|
|
||||||
return if_gen<CondT>(cond);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// while_composite
|
|
||||||
//
|
|
||||||
// This composite has the form:
|
|
||||||
//
|
|
||||||
// while_(condition)
|
|
||||||
// [
|
|
||||||
// statement
|
|
||||||
// ]
|
|
||||||
//
|
|
||||||
// While the condition (an actor) evaluates to true, statement
|
|
||||||
// (another actor) is executed. The result type of this is void.
|
|
||||||
// Note the trailing underscore after while_.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename CondT, typename DoT>
|
|
||||||
struct while_composite {
|
|
||||||
|
|
||||||
typedef while_composite<CondT, DoT> self_t;
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
struct result { typedef void type; };
|
|
||||||
|
|
||||||
while_composite(CondT const& cond_, DoT const& do__)
|
|
||||||
: cond(cond_), do_(do__) {}
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
void eval(TupleT const& args) const
|
|
||||||
{
|
|
||||||
while (cond.eval(args))
|
|
||||||
do_.eval(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
CondT cond;
|
|
||||||
DoT do_;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename CondT>
|
|
||||||
struct while_gen {
|
|
||||||
|
|
||||||
while_gen(CondT const& cond_)
|
|
||||||
: cond(cond_) {}
|
|
||||||
|
|
||||||
template <typename DoT>
|
|
||||||
actor<while_composite<
|
|
||||||
typename as_actor<CondT>::type,
|
|
||||||
typename as_actor<DoT>::type> >
|
|
||||||
operator[](DoT const& do_) const
|
|
||||||
{
|
|
||||||
typedef while_composite<
|
|
||||||
typename as_actor<CondT>::type,
|
|
||||||
typename as_actor<DoT>::type>
|
|
||||||
result;
|
|
||||||
|
|
||||||
return result(
|
|
||||||
as_actor<CondT>::convert(cond),
|
|
||||||
as_actor<DoT>::convert(do_));
|
|
||||||
}
|
|
||||||
|
|
||||||
CondT cond;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename CondT>
|
|
||||||
inline while_gen<CondT>
|
|
||||||
while_(CondT const& cond)
|
|
||||||
{
|
|
||||||
return while_gen<CondT>(cond);
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// do_composite
|
|
||||||
//
|
|
||||||
// This composite has the form:
|
|
||||||
//
|
|
||||||
// do_
|
|
||||||
// [
|
|
||||||
// statement
|
|
||||||
// ]
|
|
||||||
// .while_(condition)
|
|
||||||
//
|
|
||||||
// While the condition (an actor) evaluates to true, statement
|
|
||||||
// (another actor) is executed. The statement is executed at least
|
|
||||||
// once. The result type of this is void. Note the trailing
|
|
||||||
// underscore after do_ and the the leading dot and the trailing
|
|
||||||
// underscore before and after .while_.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename DoT, typename CondT>
|
|
||||||
struct do_composite {
|
|
||||||
|
|
||||||
typedef do_composite<DoT, CondT> self_t;
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
struct result { typedef void type; };
|
|
||||||
|
|
||||||
do_composite(DoT const& do__, CondT const& cond_)
|
|
||||||
: do_(do__), cond(cond_) {}
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
void eval(TupleT const& args) const
|
|
||||||
{
|
|
||||||
do
|
|
||||||
do_.eval(args);
|
|
||||||
while (cond.eval(args));
|
|
||||||
}
|
|
||||||
|
|
||||||
DoT do_;
|
|
||||||
CondT cond;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////
|
|
||||||
template <typename DoT>
|
|
||||||
struct do_gen2 {
|
|
||||||
|
|
||||||
do_gen2(DoT const& do__)
|
|
||||||
: do_(do__) {}
|
|
||||||
|
|
||||||
template <typename CondT>
|
|
||||||
actor<do_composite<
|
|
||||||
typename as_actor<DoT>::type,
|
|
||||||
typename as_actor<CondT>::type> >
|
|
||||||
while_(CondT const& cond) const
|
|
||||||
{
|
|
||||||
typedef do_composite<
|
|
||||||
typename as_actor<DoT>::type,
|
|
||||||
typename as_actor<CondT>::type>
|
|
||||||
result;
|
|
||||||
|
|
||||||
return result(
|
|
||||||
as_actor<DoT>::convert(do_),
|
|
||||||
as_actor<CondT>::convert(cond));
|
|
||||||
}
|
|
||||||
|
|
||||||
DoT do_;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////
|
|
||||||
struct do_gen {
|
|
||||||
|
|
||||||
template <typename DoT>
|
|
||||||
do_gen2<DoT>
|
|
||||||
operator[](DoT const& do_) const
|
|
||||||
{
|
|
||||||
return do_gen2<DoT>(do_);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
do_gen const do_ = do_gen();
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// for_composite
|
|
||||||
//
|
|
||||||
// This statement has the form:
|
|
||||||
//
|
|
||||||
// for_(init, condition, step)
|
|
||||||
// [
|
|
||||||
// statement
|
|
||||||
// ]
|
|
||||||
//
|
|
||||||
// Where init, condition, step and statement are all actors. init
|
|
||||||
// is executed once before entering the for-loop. The for-loop
|
|
||||||
// exits once condition evaluates to false. At each loop iteration,
|
|
||||||
// step and statement is called. The result of this statement is
|
|
||||||
// void. Note the trailing underscore after for_.
|
|
||||||
//
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename InitT, typename CondT, typename StepT, typename DoT>
|
|
||||||
struct for_composite {
|
|
||||||
|
|
||||||
typedef composite<InitT, CondT, StepT, DoT> self_t;
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
struct result { typedef void type; };
|
|
||||||
|
|
||||||
for_composite(
|
|
||||||
InitT const& init_,
|
|
||||||
CondT const& cond_,
|
|
||||||
StepT const& step_,
|
|
||||||
DoT const& do__)
|
|
||||||
: init(init_), cond(cond_), step(step_), do_(do__) {}
|
|
||||||
|
|
||||||
template <typename TupleT>
|
|
||||||
void
|
|
||||||
eval(TupleT const& args) const
|
|
||||||
{
|
|
||||||
for (init.eval(args); cond.eval(args); step.eval(args))
|
|
||||||
do_.eval(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
InitT init; CondT cond; StepT step; DoT do_; // actors
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename InitT, typename CondT, typename StepT>
|
|
||||||
struct for_gen {
|
|
||||||
|
|
||||||
for_gen(
|
|
||||||
InitT const& init_,
|
|
||||||
CondT const& cond_,
|
|
||||||
StepT const& step_)
|
|
||||||
: init(init_), cond(cond_), step(step_) {}
|
|
||||||
|
|
||||||
template <typename DoT>
|
|
||||||
actor<for_composite<
|
|
||||||
typename as_actor<InitT>::type,
|
|
||||||
typename as_actor<CondT>::type,
|
|
||||||
typename as_actor<StepT>::type,
|
|
||||||
typename as_actor<DoT>::type> >
|
|
||||||
operator[](DoT const& do_) const
|
|
||||||
{
|
|
||||||
typedef for_composite<
|
|
||||||
typename as_actor<InitT>::type,
|
|
||||||
typename as_actor<CondT>::type,
|
|
||||||
typename as_actor<StepT>::type,
|
|
||||||
typename as_actor<DoT>::type>
|
|
||||||
result;
|
|
||||||
|
|
||||||
return result(
|
|
||||||
as_actor<InitT>::convert(init),
|
|
||||||
as_actor<CondT>::convert(cond),
|
|
||||||
as_actor<StepT>::convert(step),
|
|
||||||
as_actor<DoT>::convert(do_));
|
|
||||||
}
|
|
||||||
|
|
||||||
InitT init; CondT cond; StepT step;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
template <typename InitT, typename CondT, typename StepT>
|
|
||||||
inline for_gen<InitT, CondT, StepT>
|
|
||||||
for_(InitT const& init, CondT const& cond, StepT const& step)
|
|
||||||
{
|
|
||||||
return for_gen<InitT, CondT, StepT>(init, cond, step);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace phoenix
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user