mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-26 06:15:16 +00:00
add spirit
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@9299 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
2621ad0763
commit
0d8fade81b
@ -1,3 +1,7 @@
|
||||
2004-11-24 Lars Gullik Bjønnes <larsbj@gullik.net>
|
||||
|
||||
* add spirit to the collection
|
||||
|
||||
2004-11-20 Lars Gullik Bjonnes <larsbj@gullik.net>
|
||||
|
||||
* update boost to version 1.32.0
|
||||
|
96
boost/boost/spirit/actor/assign_actor.hpp
Normal file
96
boost/boost/spirit/actor/assign_actor.hpp
Normal file
@ -0,0 +1,96 @@
|
||||
/*=============================================================================
|
||||
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
|
97
boost/boost/spirit/actor/push_back_actor.hpp
Normal file
97
boost/boost/spirit/actor/push_back_actor.hpp
Normal file
@ -0,0 +1,97 @@
|
||||
/*=============================================================================
|
||||
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
|
73
boost/boost/spirit/actor/ref_const_ref_actor.hpp
Normal file
73
boost/boost/spirit/actor/ref_const_ref_actor.hpp
Normal file
@ -0,0 +1,73 @@
|
||||
/*=============================================================================
|
||||
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
|
65
boost/boost/spirit/actor/ref_value_actor.hpp
Normal file
65
boost/boost/spirit/actor/ref_value_actor.hpp
Normal file
@ -0,0 +1,65 @@
|
||||
/*=============================================================================
|
||||
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
|
38
boost/boost/spirit/attribute.hpp
Normal file
38
boost/boost/spirit/attribute.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
/*=============================================================================
|
||||
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)
|
1078
boost/boost/spirit/attribute/closure.hpp
Normal file
1078
boost/boost/spirit/attribute/closure.hpp
Normal file
File diff suppressed because it is too large
Load Diff
51
boost/boost/spirit/attribute/closure_context.hpp
Normal file
51
boost/boost/spirit/attribute/closure_context.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
/*=============================================================================
|
||||
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
|
140
boost/boost/spirit/attribute/parametric.hpp
Normal file
140
boost/boost/spirit/attribute/parametric.hpp
Normal file
@ -0,0 +1,140 @@
|
||||
/*=============================================================================
|
||||
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
|
74
boost/boost/spirit/core.hpp
Normal file
74
boost/boost/spirit/core.hpp
Normal file
@ -0,0 +1,74 @@
|
||||
/*=============================================================================
|
||||
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
|
||||
|
146
boost/boost/spirit/debug.hpp
Normal file
146
boost/boost/spirit/debug.hpp
Normal file
@ -0,0 +1,146 @@
|
||||
/*=============================================================================
|
||||
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
|
||||
|
82
boost/boost/spirit/debug/minimal.hpp
Normal file
82
boost/boost/spirit/debug/minimal.hpp
Normal file
@ -0,0 +1,82 @@
|
||||
/*=============================================================================
|
||||
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)
|
224
boost/boost/spirit/dynamic/if.hpp
Normal file
224
boost/boost/spirit/dynamic/if.hpp
Normal file
@ -0,0 +1,224 @@
|
||||
/*=============================================================================
|
||||
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.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
|
100
boost/boost/spirit/dynamic/impl/conditions.ipp
Normal file
100
boost/boost/spirit/dynamic/impl/conditions.ipp
Normal file
@ -0,0 +1,100 @@
|
||||
/*=============================================================================
|
||||
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
|
22
boost/boost/spirit/error_handling.hpp
Normal file
22
boost/boost/spirit/error_handling.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
/*=============================================================================
|
||||
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)
|
360
boost/boost/spirit/error_handling/exceptions.hpp
Normal file
360
boost/boost/spirit/error_handling/exceptions.hpp
Normal file
@ -0,0 +1,360 @@
|
||||
/*=============================================================================
|
||||
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>
|
||||
|
||||
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&) {}
|
||||
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 = char const*>
|
||||
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)
|
||||
: 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 = nil_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>
|
||||
struct guard;
|
||||
|
||||
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
|
||||
|
85
boost/boost/spirit/error_handling/impl/exceptions.ipp
Normal file
85
boost/boost/spirit/error_handling/impl/exceptions.ipp
Normal file
@ -0,0 +1,85 @@
|
||||
/*=============================================================================
|
||||
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
|
||||
|
26
boost/boost/spirit/iterator.hpp
Normal file
26
boost/boost/spirit/iterator.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
/*=============================================================================
|
||||
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)
|
238
boost/boost/spirit/iterator/file_iterator.hpp
Normal file
238
boost/boost/spirit/iterator/file_iterator.hpp
Normal file
@ -0,0 +1,238 @@
|
||||
/*=============================================================================
|
||||
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>
|
||||
|
||||
#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 {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace fileiter_impl {
|
||||
|
||||
// Forward declarations
|
||||
template <typename CharT = char>
|
||||
class std_file_iterator;
|
||||
|
||||
#if !defined(BOOST_SPIRIT_FILEITERATOR_STD)
|
||||
template <typename CharT = char>
|
||||
class mmap_file_iterator;
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace fileiter_impl
|
||||
|
||||
template <
|
||||
typename CharT = char,
|
||||
typename BaseIterator =
|
||||
#ifndef BOOST_SPIRIT_FILEITERATOR_WINDOWS
|
||||
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,
|
||||
signed long
|
||||
> 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 "impl/file_iterator.ipp" /* implementation */
|
||||
|
||||
#endif /* BOOST_SPIRIT_FILE_ITERATOR_HPP */
|
||||
|
398
boost/boost/spirit/iterator/fixed_size_queue.hpp
Normal file
398
boost/boost/spirit/iterator/fixed_size_queue.hpp
Normal file
@ -0,0 +1,398 @@
|
||||
/*=============================================================================
|
||||
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
|
459
boost/boost/spirit/iterator/impl/file_iterator.ipp
Normal file
459
boost/boost/spirit/iterator/impl/file_iterator.ipp
Normal file
@ -0,0 +1,459 @@
|
||||
/*=============================================================================
|
||||
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 {
|
||||
|
||||
using namespace std;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
fseek(m_file.get(), 0, SEEK_END);
|
||||
m_pos = ftell(m_file.get()) / sizeof(CharT);
|
||||
m_eof = true;
|
||||
}
|
||||
|
||||
void advance(signed long n)
|
||||
{
|
||||
m_pos += n * sizeof(CharT);
|
||||
update_char();
|
||||
}
|
||||
|
||||
long distance(const std_file_iterator& iter) const
|
||||
{
|
||||
return (long)(m_pos - iter.m_pos) / sizeof(CharT);
|
||||
}
|
||||
|
||||
private:
|
||||
boost::shared_ptr<FILE> m_file;
|
||||
std::size_t m_pos;
|
||||
CharT m_curChar;
|
||||
bool m_eof;
|
||||
|
||||
void update_char(void)
|
||||
{
|
||||
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(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.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 */
|
131
boost/boost/spirit/iterator/impl/position_iterator.ipp
Normal file
131
boost/boost/spirit/iterator/impl/position_iterator.ipp
Normal file
@ -0,0 +1,131 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2002 Juan Carlos Arevalo-Baeza
|
||||
Copyright (c) 2002-2003 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 <>
|
||||
class position_policy<file_position_without_column> {
|
||||
|
||||
public:
|
||||
void next_line(file_position_without_column& pos)
|
||||
{
|
||||
++pos.line;
|
||||
}
|
||||
|
||||
void set_tab_chars(unsigned int /*chars*/){}
|
||||
void next_char(file_position_without_column& /*pos*/) {}
|
||||
void tabulation(file_position_without_column& /*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 <>
|
||||
class position_policy<file_position> {
|
||||
|
||||
public:
|
||||
position_policy()
|
||||
: m_CharsPerTab(4)
|
||||
{}
|
||||
|
||||
void next_line(file_position& pos)
|
||||
{
|
||||
++pos.line;
|
||||
pos.column = 1;
|
||||
}
|
||||
|
||||
void set_tab_chars(unsigned int chars)
|
||||
{
|
||||
m_CharsPerTab = chars;
|
||||
}
|
||||
|
||||
void next_char(file_position& pos)
|
||||
{
|
||||
++pos.column;
|
||||
}
|
||||
|
||||
void tabulation(file_position& 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
|
1302
boost/boost/spirit/iterator/multi_pass.hpp
Normal file
1302
boost/boost/spirit/iterator/multi_pass.hpp
Normal file
File diff suppressed because it is too large
Load Diff
432
boost/boost/spirit/iterator/position_iterator.hpp
Normal file
432
boost/boost/spirit/iterator/position_iterator.hpp
Normal file
@ -0,0 +1,432 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2002 Juan Carlos Arevalo-Baeza
|
||||
Copyright (c) 2002-2003 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>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// file_position_without_column
|
||||
//
|
||||
// A structure to hold positional information. This includes the file,
|
||||
// and the line number
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct file_position_without_column {
|
||||
std::string file;
|
||||
int line;
|
||||
|
||||
file_position_without_column(std::string const& file_ = std::string(),
|
||||
int line_ = 1):
|
||||
file (file_),
|
||||
line (line_)
|
||||
{}
|
||||
|
||||
bool operator==(const file_position_without_column& fp) const
|
||||
{ return line == fp.line && file == fp.file; }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// file_position
|
||||
//
|
||||
// This structure holds complete file position, including file name,
|
||||
// line and column number
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct file_position : public file_position_without_column {
|
||||
int column;
|
||||
|
||||
file_position(std::string const& file_ = std::string(),
|
||||
int line_ = 1, int column_ = 1):
|
||||
file_position_without_column (file_, line_),
|
||||
column (column_)
|
||||
{}
|
||||
|
||||
bool operator==(const file_position& fp) const
|
||||
{ return column == fp.column && line == fp.line && 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;
|
||||
|
||||
|
||||
// Forward declaration
|
||||
template <typename ForwardIteratorT, typename PositionT, typename SelfT>
|
||||
class position_iterator;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}} /* namespace boost::spirit */
|
||||
|
||||
|
||||
// This must be included here for full compatibility with old MSVC
|
||||
#include "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 = file_position,
|
||||
typename SelfT = nil_t
|
||||
>
|
||||
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 = file_position
|
||||
>
|
||||
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
|
27
boost/boost/spirit/meta.hpp
Normal file
27
boost/boost/spirit/meta.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
/*=============================================================================
|
||||
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
|
||||
|
109
boost/boost/spirit/meta/as_parser.hpp
Normal file
109
boost/boost/spirit/meta/as_parser.hpp
Normal file
@ -0,0 +1,109 @@
|
||||
/*=============================================================================
|
||||
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
|
52
boost/boost/spirit/meta/fundamental.hpp
Normal file
52
boost/boost/spirit/meta/fundamental.hpp
Normal file
@ -0,0 +1,52 @@
|
||||
/*=============================================================================
|
||||
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)
|
305
boost/boost/spirit/meta/impl/fundamental.ipp
Normal file
305
boost/boost/spirit/meta/impl/fundamental.ipp
Normal file
@ -0,0 +1,305 @@
|
||||
/*=============================================================================
|
||||
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)
|
187
boost/boost/spirit/meta/impl/parser_traits.ipp
Normal file
187
boost/boost/spirit/meta/impl/parser_traits.ipp
Normal file
@ -0,0 +1,187 @@
|
||||
/*=============================================================================
|
||||
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)
|
447
boost/boost/spirit/meta/impl/refactoring.ipp
Normal file
447
boost/boost/spirit/meta/impl/refactoring.ipp
Normal file
@ -0,0 +1,447 @@
|
||||
/*=============================================================================
|
||||
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
|
||||
|
389
boost/boost/spirit/meta/impl/traverse.ipp
Normal file
389
boost/boost/spirit/meta/impl/traverse.ipp
Normal file
@ -0,0 +1,389 @@
|
||||
/*=============================================================================
|
||||
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)
|
316
boost/boost/spirit/meta/parser_traits.hpp
Normal file
316
boost/boost/spirit/meta/parser_traits.hpp
Normal file
@ -0,0 +1,316 @@
|
||||
/*=============================================================================
|
||||
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)
|
274
boost/boost/spirit/meta/refactoring.hpp
Normal file
274
boost/boost/spirit/meta/refactoring.hpp
Normal file
@ -0,0 +1,274 @@
|
||||
/*=============================================================================
|
||||
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
|
||||
|
218
boost/boost/spirit/meta/traverse.hpp
Normal file
218
boost/boost/spirit/meta/traverse.hpp
Normal file
@ -0,0 +1,218 @@
|
||||
/*=============================================================================
|
||||
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)
|
26
boost/boost/spirit/phoenix.hpp
Normal file
26
boost/boost/spirit/phoenix.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
/*=============================================================================
|
||||
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)
|
613
boost/boost/spirit/phoenix/actor.hpp
Normal file
613
boost/boost/spirit/phoenix/actor.hpp
Normal file
@ -0,0 +1,613 @@
|
||||
/*=============================================================================
|
||||
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;
|
||||
}
|
||||
|
||||
namespace impl {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// if_t selects type A or B depending on the condition C If C is of
|
||||
// type char[2], B is selected, otherwise A
|
||||
//
|
||||
// TODO: This should be part of a common meta-library
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename C, typename A, typename B>
|
||||
struct if_t { typedef A type; };
|
||||
|
||||
template <typename A, typename B>
|
||||
struct if_t<char[2], A, B> { typedef B type; };
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 ---------|
|
||||
// arg3 ---------|---> 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
|
4067
boost/boost/spirit/phoenix/binders.hpp
Normal file
4067
boost/boost/spirit/phoenix/binders.hpp
Normal file
File diff suppressed because it is too large
Load Diff
1471
boost/boost/spirit/phoenix/casts.hpp
Normal file
1471
boost/boost/spirit/phoenix/casts.hpp
Normal file
File diff suppressed because it is too large
Load Diff
422
boost/boost/spirit/phoenix/closures.hpp
Normal file
422
boost/boost/spirit/phoenix/closures.hpp
Normal file
@ -0,0 +1,422 @@
|
||||
/*=============================================================================
|
||||
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>
|
||||
#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;
|
||||
|
||||
static holder_t &
|
||||
closure_frame_holder_ref(holder_t* holder_ = 0)
|
||||
{
|
||||
#ifdef PHOENIX_THREADSAFE
|
||||
static boost::thread_specific_ptr<holder_t*> tsp_frame;
|
||||
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
|
1423
boost/boost/spirit/phoenix/composite.hpp
Normal file
1423
boost/boost/spirit/phoenix/composite.hpp
Normal file
File diff suppressed because it is too large
Load Diff
761
boost/boost/spirit/phoenix/functions.hpp
Normal file
761
boost/boost/spirit/phoenix/functions.hpp
Normal file
@ -0,0 +1,761 @@
|
||||
/*=============================================================================
|
||||
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
|
1285
boost/boost/spirit/phoenix/new.hpp
Normal file
1285
boost/boost/spirit/phoenix/new.hpp
Normal file
File diff suppressed because it is too large
Load Diff
2214
boost/boost/spirit/phoenix/operators.hpp
Normal file
2214
boost/boost/spirit/phoenix/operators.hpp
Normal file
File diff suppressed because it is too large
Load Diff
248
boost/boost/spirit/phoenix/primitives.hpp
Normal file
248
boost/boost/spirit/phoenix/primitives.hpp
Normal file
@ -0,0 +1,248 @@
|
||||
/*=============================================================================
|
||||
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
|
342
boost/boost/spirit/phoenix/special_ops.hpp
Normal file
342
boost/boost/spirit/phoenix/special_ops.hpp
Normal file
@ -0,0 +1,342 @@
|
||||
/*=============================================================================
|
||||
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
|
444
boost/boost/spirit/phoenix/statements.hpp
Normal file
444
boost/boost/spirit/phoenix/statements.hpp
Normal file
@ -0,0 +1,444 @@
|
||||
/*=============================================================================
|
||||
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
|
1076
boost/boost/spirit/phoenix/tuple_helpers.hpp
Normal file
1076
boost/boost/spirit/phoenix/tuple_helpers.hpp
Normal file
File diff suppressed because it is too large
Load Diff
1330
boost/boost/spirit/phoenix/tuples.hpp
Normal file
1330
boost/boost/spirit/phoenix/tuples.hpp
Normal file
File diff suppressed because it is too large
Load Diff
22
boost/boost/spirit/symbols.hpp
Normal file
22
boost/boost/spirit/symbols.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
/*=============================================================================
|
||||
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_SYMBOLS_MAIN_HPP)
|
||||
#define BOOST_SPIRIT_SYMBOLS_MAIN_HPP
|
||||
|
||||
#include <boost/spirit/version.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Master header for Spirit.Symbols
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <boost/spirit/symbols/symbols.hpp>
|
||||
|
||||
#endif // !defined(BOOST_SPIRIT_SYMBOLS_MAIN_HPP)
|
113
boost/boost/spirit/symbols/impl/symbols.ipp
Normal file
113
boost/boost/spirit/symbols/impl/symbols.ipp
Normal file
@ -0,0 +1,113 @@
|
||||
/*=============================================================================
|
||||
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_SYMBOLS_IPP
|
||||
#define BOOST_SPIRIT_SYMBOLS_IPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/spirit/symbols/impl/tst.ipp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
// MSVC: void warning about the use of 'this' pointer in constructors
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(disable : 4355)
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// symbols class implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename CharT, typename SetT>
|
||||
inline symbols<T, CharT, SetT>::symbols()
|
||||
: SetT()
|
||||
, add(*this)
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename T, typename CharT, typename SetT>
|
||||
symbols<T, CharT, SetT>::symbols(symbols const& other)
|
||||
: SetT(other)
|
||||
// Tru64 CXX seems to be confused by the explicit call of the default
|
||||
// constructor and generates wrong code which invalidates the just contructed
|
||||
// first base class in the line above.
|
||||
#if !BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590041))
|
||||
, parser<symbols<T, CharT, SetT> >()
|
||||
#endif
|
||||
, add(*this)
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename T, typename CharT, typename SetT>
|
||||
inline symbols<T, CharT, SetT>::~symbols()
|
||||
{}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename T, typename CharT, typename SetT>
|
||||
inline symbols<T, CharT, SetT>&
|
||||
symbols<T, CharT, SetT>::operator=(symbols const& other)
|
||||
{
|
||||
SetT::operator=(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename T, typename CharT, typename SetT>
|
||||
inline symbol_inserter<T, SetT> const&
|
||||
symbols<T, CharT, SetT>::operator=(CharT const* str)
|
||||
{
|
||||
return add, str;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Symbol table utilities
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename CharT, typename SetT>
|
||||
inline T*
|
||||
find(symbols<T, CharT, SetT> const& table, CharT const* sym)
|
||||
{
|
||||
CharT const* last = sym;
|
||||
while (*last)
|
||||
last++;
|
||||
scanner<CharT const *> scan(sym, last);
|
||||
T* result = table.find(scan);
|
||||
return scan.at_end()? result: 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename T, typename CharT, typename SetT>
|
||||
inline T*
|
||||
add(symbols<T, CharT, SetT>& table, CharT const* sym, T const& data)
|
||||
{
|
||||
CharT const* first = sym;
|
||||
CharT const* last = sym;
|
||||
while (*last)
|
||||
last++;
|
||||
scanner<CharT const *> scan(first, last);
|
||||
if (table.find(scan) && scan.at_end())
|
||||
return 0; // symbol already contained in symbol table
|
||||
table.add(sym, last, data);
|
||||
first = sym;
|
||||
return table.find(scan); // refind the inserted symbol
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(default : 4355)
|
||||
#endif
|
||||
|
||||
#endif
|
270
boost/boost/spirit/symbols/impl/tst.ipp
Normal file
270
boost/boost/spirit/symbols/impl/tst.ipp
Normal file
@ -0,0 +1,270 @@
|
||||
/*=============================================================================
|
||||
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_TST_IPP
|
||||
#define BOOST_SPIRIT_TST_IPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <memory> // for std::auto_ptr
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
namespace impl
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// tst class
|
||||
//
|
||||
// Ternary Search Tree implementation. The data structure is faster than
|
||||
// hashing for many typical search problems especially when the search
|
||||
// interface is iterator based. Searching for a string of length k in a
|
||||
// ternary search tree with n strings will require at most O(log n+k)
|
||||
// character comparisons. TSTs are many times faster than hash tables
|
||||
// for unsuccessful searches since mismatches are discovered earlier
|
||||
// after examining only a few characters. Hash tables always examine an
|
||||
// entire key when searching.
|
||||
//
|
||||
// For details see http://www.cs.princeton.edu/~rs/strings/.
|
||||
//
|
||||
// *** This is a low level class and is
|
||||
// not meant for public consumption ***
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename CharT>
|
||||
struct tst_node
|
||||
{
|
||||
tst_node(CharT value_)
|
||||
: value(value_)
|
||||
, left(0)
|
||||
, right(0)
|
||||
{ middle.link = 0; }
|
||||
|
||||
~tst_node()
|
||||
{
|
||||
delete left;
|
||||
delete right;
|
||||
if (value)
|
||||
delete middle.link;
|
||||
else
|
||||
delete middle.data;
|
||||
}
|
||||
|
||||
tst_node*
|
||||
clone() const
|
||||
{
|
||||
std::auto_ptr<tst_node> copy(new tst_node(value));
|
||||
|
||||
if (left)
|
||||
copy->left = left->clone();
|
||||
if (right)
|
||||
copy->right = right->clone();
|
||||
|
||||
if (value && middle.link)
|
||||
{
|
||||
copy->middle.link = middle.link->clone();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::auto_ptr<T> mid_data(new T(*middle.data));
|
||||
copy->middle.data = mid_data.release();
|
||||
}
|
||||
|
||||
return copy.release();
|
||||
}
|
||||
|
||||
union center {
|
||||
|
||||
tst_node* link;
|
||||
T* data;
|
||||
};
|
||||
|
||||
CharT value;
|
||||
tst_node* left;
|
||||
center middle;
|
||||
tst_node* right;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename CharT>
|
||||
class tst
|
||||
{
|
||||
public:
|
||||
|
||||
struct search_info
|
||||
{
|
||||
T* data;
|
||||
std::size_t length;
|
||||
};
|
||||
|
||||
tst()
|
||||
: root(0) {}
|
||||
|
||||
tst(tst const& other)
|
||||
: root(other.root ? other.root->clone() : 0) {}
|
||||
|
||||
~tst()
|
||||
{ delete root; }
|
||||
|
||||
tst&
|
||||
operator=(tst const& other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
node_t* new_root = other.root ? other.root->clone() : 0;
|
||||
delete root;
|
||||
root = new_root;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename IteratorT>
|
||||
T* add(IteratorT first, IteratorT const& last, T const& data)
|
||||
{
|
||||
if (first == last)
|
||||
return 0;
|
||||
|
||||
node_t** np = &root;
|
||||
CharT ch = *first;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (*np == 0 || ch == 0)
|
||||
{
|
||||
node_t* right = 0;
|
||||
if (np != 0)
|
||||
right = *np;
|
||||
*np = new node_t(ch);
|
||||
if (right)
|
||||
(**np).right = right;
|
||||
}
|
||||
|
||||
if (ch < (**np).value)
|
||||
{
|
||||
np = &(**np).left;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ch == (**np).value)
|
||||
{
|
||||
if (ch == 0)
|
||||
{
|
||||
if ((**np).middle.data == 0)
|
||||
{
|
||||
(**np).middle.data = new T(data);
|
||||
return (**np).middle.data;
|
||||
}
|
||||
else
|
||||
{
|
||||
// re-addition is disallowed
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
++first;
|
||||
ch = (first == last) ? 0 : *first;
|
||||
np = &(**np).middle.link;
|
||||
}
|
||||
else
|
||||
{
|
||||
np = &(**np).right;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
search_info find(ScannerT const& scan) const
|
||||
{
|
||||
search_info result = { 0, 0 };
|
||||
if (scan.at_end()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef typename ScannerT::iterator_t iterator_t;
|
||||
node_t* np = root;
|
||||
CharT ch = *scan;
|
||||
iterator_t save = scan.first;
|
||||
iterator_t latest = scan.first;
|
||||
std::size_t latest_len = 0;
|
||||
|
||||
while (np)
|
||||
{
|
||||
if (ch < np->value)
|
||||
{
|
||||
if (np->value == 0)
|
||||
{
|
||||
result.data = np->middle.data;
|
||||
if (result.data)
|
||||
{
|
||||
latest = scan.first;
|
||||
latest_len = result.length;
|
||||
}
|
||||
}
|
||||
np = np->left;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ch == np->value)
|
||||
{
|
||||
if (scan.at_end())
|
||||
{
|
||||
result.data = np->middle.data;
|
||||
if (result.data)
|
||||
{
|
||||
latest = scan.first;
|
||||
latest_len = result.length;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
++scan;
|
||||
ch = scan.at_end() ? 0 : *scan;
|
||||
np = np->middle.link;
|
||||
++result.length;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (np->value == 0)
|
||||
{
|
||||
result.data = np->middle.data;
|
||||
if (result.data)
|
||||
{
|
||||
latest = scan.first;
|
||||
latest_len = result.length;
|
||||
}
|
||||
}
|
||||
np = np->right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result.data == 0)
|
||||
{
|
||||
scan.first = save;
|
||||
}
|
||||
else
|
||||
{
|
||||
scan.first = latest;
|
||||
result.length = latest_len;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typedef tst_node<T, CharT> node_t;
|
||||
node_t* root;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace impl
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
237
boost/boost/spirit/symbols/symbols.hpp
Normal file
237
boost/boost/spirit/symbols/symbols.hpp
Normal file
@ -0,0 +1,237 @@
|
||||
/*=============================================================================
|
||||
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_SYMBOLS_HPP
|
||||
#define BOOST_SPIRIT_SYMBOLS_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <string>
|
||||
|
||||
#include <boost/ref.hpp>
|
||||
|
||||
#include <boost/spirit/core/parser.hpp>
|
||||
#include <boost/spirit/core/composite/directives.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Forward Declarations
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template <typename CharT, typename T>
|
||||
class tst;
|
||||
}
|
||||
|
||||
template <typename T, typename SetT>
|
||||
class symbol_inserter;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// symbols class
|
||||
//
|
||||
// This class implements a symbol table. The symbol table holds a
|
||||
// dictionary of symbols where each symbol is a sequence of CharTs.
|
||||
// The template class can work efficiently with 8, 16 and 32 bit
|
||||
// characters. Mutable data of type T is associated with each
|
||||
// symbol.
|
||||
//
|
||||
// The class is a parser. The parse member function returns
|
||||
// additional information in the symbol_match class (see below).
|
||||
// The additional data is a pointer to some data associated with
|
||||
// the matching symbol.
|
||||
//
|
||||
// The actual set implementation is supplied by the SetT template
|
||||
// parameter. By default, this uses the tst class (see tst.ipp).
|
||||
//
|
||||
// Symbols are added into the symbol table statically using the
|
||||
// construct:
|
||||
//
|
||||
// sym = a, b, c, d ...;
|
||||
//
|
||||
// where sym is a symbol table and a..d are strings. Example:
|
||||
//
|
||||
// sym = "pineapple", "orange", "banana", "apple";
|
||||
//
|
||||
// Alternatively, symbols may be added dynamically through the
|
||||
// member functor 'add' (see symbol_inserter below). The member
|
||||
// functor 'add' may be attached to a parser as a semantic action
|
||||
// taking in a begin/end pair:
|
||||
//
|
||||
// p[sym.add]
|
||||
//
|
||||
// where p is a parser (and sym is a symbol table). On success,
|
||||
// the matching portion of the input is added to the symbol table.
|
||||
//
|
||||
// 'add' may also be used to directly initialize data. Examples:
|
||||
//
|
||||
// sym.add("hello", 1)("crazy", 2)("world", 3);
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template
|
||||
<
|
||||
typename T = int,
|
||||
typename CharT = char,
|
||||
typename SetT = impl::tst<T, CharT>
|
||||
>
|
||||
class symbols
|
||||
: private SetT
|
||||
, public parser<symbols<T, CharT, SetT> >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef parser<symbols<T, CharT, SetT> > parser_base_t;
|
||||
typedef symbols<T, CharT, SetT> self_t;
|
||||
typedef self_t const& embed_t;
|
||||
typedef T symbol_data_t;
|
||||
typedef boost::reference_wrapper<T> symbol_ref_t;
|
||||
|
||||
symbols();
|
||||
symbols(symbols const& other);
|
||||
~symbols();
|
||||
|
||||
symbols&
|
||||
operator=(symbols const& other);
|
||||
|
||||
symbol_inserter<T, SetT> const&
|
||||
operator=(CharT const* str);
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, symbol_ref_t>::type type;
|
||||
};
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse_main(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename ScannerT::iterator_t iterator_t;
|
||||
iterator_t first = scan.first;
|
||||
typename SetT::search_info result = SetT::find(scan);
|
||||
|
||||
if (result.data)
|
||||
return scan.
|
||||
create_match(
|
||||
result.length,
|
||||
symbol_ref_t(*result.data),
|
||||
first,
|
||||
scan.first);
|
||||
else
|
||||
return scan.no_match();
|
||||
}
|
||||
|
||||
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::implicit_lexeme_parse<result_t>
|
||||
(*this, scan, scan);
|
||||
}
|
||||
|
||||
template < typename ScannerT >
|
||||
T* find(ScannerT const& scan) const
|
||||
{ return SetT::find(scan).data; }
|
||||
|
||||
symbol_inserter<T, SetT> const add;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Symbol table utilities
|
||||
//
|
||||
// add
|
||||
//
|
||||
// adds a symbol 'sym' (string) to a symbol table 'table' plus an
|
||||
// optional data 'data' associated with the symbol. Returns a pointer to
|
||||
// the data associated with the symbol or NULL if add failed (e.g. when
|
||||
// the symbol is already added before).
|
||||
//
|
||||
// find
|
||||
//
|
||||
// finds a symbol 'sym' (string) from a symbol table 'table'. Returns a
|
||||
// pointer to the data associated with the symbol or NULL if not found
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename CharT, typename SetT>
|
||||
T* add(symbols<T, CharT, SetT>& table, CharT const* sym, T const& data = T());
|
||||
|
||||
template <typename T, typename CharT, typename SetT>
|
||||
T* find(symbols<T, CharT, SetT> const& table, CharT const* sym);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// symbol_inserter class
|
||||
//
|
||||
// The symbols class holds an instance of this class named 'add'.
|
||||
// This can be called directly just like a member function,
|
||||
// passing in a first/last iterator and optional data:
|
||||
//
|
||||
// sym.add(first, last, data);
|
||||
//
|
||||
// Or, passing in a C string and optional data:
|
||||
//
|
||||
// sym.add(c_string, data);
|
||||
//
|
||||
// where sym is a symbol table. The 'data' argument is optional.
|
||||
// This may also be used as a semantic action since it conforms
|
||||
// to the action interface (see action.hpp):
|
||||
//
|
||||
// p[sym.add]
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename SetT>
|
||||
class symbol_inserter
|
||||
{
|
||||
public:
|
||||
|
||||
symbol_inserter(SetT& set_)
|
||||
: set(set_) {}
|
||||
|
||||
template <typename IteratorT>
|
||||
symbol_inserter const&
|
||||
operator()(IteratorT first, IteratorT const& last, T const& data = T()) const
|
||||
{
|
||||
set.add(first, last, data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
symbol_inserter const&
|
||||
operator()(CharT const* str, T const& data = T()) const
|
||||
{
|
||||
CharT const* last = str;
|
||||
while (*last)
|
||||
last++;
|
||||
set.add(str, last, data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
symbol_inserter const&
|
||||
operator,(CharT const* str) const
|
||||
{
|
||||
CharT const* last = str;
|
||||
while (*last)
|
||||
last++;
|
||||
set.add(str, last, T());
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
SetT& set;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#include <boost/spirit/symbols/impl/symbols.ipp>
|
||||
#endif
|
41
boost/boost/spirit/utility.hpp
Normal file
41
boost/boost/spirit/utility.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
/*=============================================================================
|
||||
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 Juan Carlos Arevalo-Baeza
|
||||
Copyright (c) 2002 Raghavendra Satish
|
||||
Copyright (c) 2002 Jeff Westfahl
|
||||
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_UTILITY_MAIN_HPP)
|
||||
#define BOOST_SPIRIT_UTILITY_MAIN_HPP
|
||||
|
||||
#include <boost/spirit/version.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Master header for Spirit.Utilities
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Utility.Parsers
|
||||
#include <boost/spirit/utility/chset.hpp>
|
||||
#include <boost/spirit/utility/chset_operators.hpp>
|
||||
#include <boost/spirit/utility/escape_char.hpp>
|
||||
#include <boost/spirit/utility/functor_parser.hpp>
|
||||
#include <boost/spirit/utility/loops.hpp>
|
||||
#include <boost/spirit/utility/confix.hpp>
|
||||
#include <boost/spirit/utility/lists.hpp>
|
||||
#include <boost/spirit/utility/distinct.hpp>
|
||||
|
||||
// Utility.Support
|
||||
#include <boost/spirit/utility/flush_multi_pass.hpp>
|
||||
#include <boost/spirit/utility/scoped_lock.hpp>
|
||||
|
||||
|
||||
#endif // !defined(BOOST_SPIRIT_UTILITY_MAIN_HPP)
|
183
boost/boost/spirit/utility/chset.hpp
Normal file
183
boost/boost/spirit/utility/chset.hpp
Normal file
@ -0,0 +1,183 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2003 Joel de Guzman
|
||||
Copyright (c) 2001-2003 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)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_CHSET_HPP
|
||||
#define BOOST_SPIRIT_CHSET_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/spirit/core/primitives/primitives.hpp>
|
||||
#include <boost/spirit/utility/impl/chset/basic_chset.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
namespace utility { namespace impl {
|
||||
|
||||
// This is here because some compilers choke on out-of-line member
|
||||
// template functions. And we don't want to put the whole algorithm
|
||||
// in the chset constructor in the class definition.
|
||||
template <typename CharT, typename CharT2>
|
||||
void construct_chset(boost::shared_ptr<basic_chset<CharT> >& ptr,
|
||||
CharT2 const* definition);
|
||||
|
||||
}} // namespace utility::impl
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// chset class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT = char>
|
||||
class chset: public char_parser<chset<CharT> > {
|
||||
|
||||
public:
|
||||
chset();
|
||||
chset(chset const& arg_);
|
||||
explicit chset(CharT arg_);
|
||||
explicit chset(anychar_parser arg_);
|
||||
explicit chset(nothing_parser arg_);
|
||||
explicit chset(chlit<CharT> const& arg_);
|
||||
explicit chset(range<CharT> const& arg_);
|
||||
explicit chset(negated_char_parser<chlit<CharT> > const& arg_);
|
||||
explicit chset(negated_char_parser<range<CharT> > const& arg_);
|
||||
|
||||
template <typename CharT2>
|
||||
explicit chset(CharT2 const* definition)
|
||||
: ptr(new basic_chset<CharT>())
|
||||
{
|
||||
utility::impl::construct_chset(ptr, definition);
|
||||
}
|
||||
~chset();
|
||||
|
||||
chset& operator=(chset const& rhs);
|
||||
chset& operator=(CharT rhs);
|
||||
chset& operator=(anychar_parser rhs);
|
||||
chset& operator=(nothing_parser rhs);
|
||||
chset& operator=(chlit<CharT> const& rhs);
|
||||
chset& operator=(range<CharT> const& rhs);
|
||||
chset& operator=(negated_char_parser<chlit<CharT> > const& rhs);
|
||||
chset& operator=(negated_char_parser<range<CharT> > const& rhs);
|
||||
|
||||
void set(range<CharT> const& arg_);
|
||||
void set(negated_char_parser<chlit<CharT> > const& arg_);
|
||||
void set(negated_char_parser<range<CharT> > const& arg_);
|
||||
|
||||
void clear(range<CharT> const& arg_);
|
||||
void clear(negated_char_parser<range<CharT> > const& arg_);
|
||||
bool test(CharT ch) const;
|
||||
chset& inverse();
|
||||
void swap(chset& x);
|
||||
|
||||
chset& operator|=(chset const& x);
|
||||
chset& operator&=(chset const& x);
|
||||
chset& operator-=(chset const& x);
|
||||
chset& operator^=(chset const& x);
|
||||
|
||||
private:
|
||||
|
||||
boost::shared_ptr<basic_chset<CharT> > ptr;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generator functions
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
chset_p(chlit<CharT> const& arg_)
|
||||
{ return chset<CharT>(arg_); }
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
chset_p(range<CharT> const& arg_)
|
||||
{ return chset<CharT>(arg_); }
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
chset_p(negated_char_parser<chlit<CharT> > const& arg_)
|
||||
{ return chset<CharT>(arg_); }
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
chset_p(negated_char_parser<range<CharT> > const& arg_)
|
||||
{ return chset<CharT>(arg_); }
|
||||
|
||||
//////////////////////////////////
|
||||
inline chset<char>
|
||||
chset_p(char const* init)
|
||||
{ return chset<char>(init); }
|
||||
|
||||
//////////////////////////////////
|
||||
inline chset<wchar_t>
|
||||
chset_p(wchar_t const* init)
|
||||
{ return chset<wchar_t>(init); }
|
||||
|
||||
//////////////////////////////////
|
||||
inline chset<char>
|
||||
chset_p(char ch)
|
||||
{ return chset<char>(ch); }
|
||||
|
||||
//////////////////////////////////
|
||||
inline chset<wchar_t>
|
||||
chset_p(wchar_t ch)
|
||||
{ return chset<wchar_t>(ch); }
|
||||
|
||||
//////////////////////////////////
|
||||
inline chset<int>
|
||||
chset_p(int ch)
|
||||
{ return chset<int>(ch); }
|
||||
|
||||
//////////////////////////////////
|
||||
inline chset<unsigned int>
|
||||
chset_p(unsigned int ch)
|
||||
{ return chset<unsigned int>(ch); }
|
||||
|
||||
//////////////////////////////////
|
||||
inline chset<short>
|
||||
chset_p(short ch)
|
||||
{ return chset<short>(ch); }
|
||||
|
||||
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
//////////////////////////////////
|
||||
inline chset<unsigned short>
|
||||
chset_p(unsigned short ch)
|
||||
{ return chset<unsigned short>(ch); }
|
||||
#endif
|
||||
//////////////////////////////////
|
||||
inline chset<long>
|
||||
chset_p(long ch)
|
||||
{ return chset<long>(ch); }
|
||||
|
||||
//////////////////////////////////
|
||||
inline chset<unsigned long>
|
||||
chset_p(unsigned long ch)
|
||||
{ return chset<unsigned long>(ch); }
|
||||
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
//////////////////////////////////
|
||||
inline chset< ::boost::long_long_type>
|
||||
chset_p( ::boost::long_long_type ch)
|
||||
{ return chset< ::boost::long_long_type>(ch); }
|
||||
|
||||
//////////////////////////////////
|
||||
inline chset< ::boost::ulong_long_type>
|
||||
chset_p( ::boost::ulong_long_type ch)
|
||||
{ return chset< ::boost::ulong_long_type>(ch); }
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/utility/impl/chset.ipp>
|
||||
#include <boost/spirit/utility/chset_operators.hpp>
|
398
boost/boost/spirit/utility/chset_operators.hpp
Normal file
398
boost/boost/spirit/utility/chset_operators.hpp
Normal file
@ -0,0 +1,398 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2003 Joel de Guzman
|
||||
Copyright (c) 2001-2003 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)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_CHSET_OPERATORS_HPP
|
||||
#define BOOST_SPIRIT_CHSET_OPERATORS_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/spirit/utility/chset.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// chset free operators
|
||||
//
|
||||
// Where a and b are both chsets, implements:
|
||||
//
|
||||
// a | b, a & b, a - b, a ^ b
|
||||
//
|
||||
// Where a is a chset, implements:
|
||||
//
|
||||
// ~a
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator~(chset<CharT> const& a);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator|(chset<CharT> const& a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator&(chset<CharT> const& a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator-(chset<CharT> const& a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator^(chset<CharT> const& a, chset<CharT> const& b);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// range <--> chset free operators
|
||||
//
|
||||
// Where a is a chset and b is a range, and vice-versa, implements:
|
||||
//
|
||||
// a | b, a & b, a - b, a ^ b
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator|(chset<CharT> const& a, range<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator&(chset<CharT> const& a, range<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator-(chset<CharT> const& a, range<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator^(chset<CharT> const& a, range<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator|(range<CharT> const& a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator&(range<CharT> const& a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator-(range<CharT> const& a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator^(range<CharT> const& a, chset<CharT> const& b);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// chlit <--> chset free operators
|
||||
//
|
||||
// Where a is a chset and b is a chlit, and vice-versa, implements:
|
||||
//
|
||||
// a | b, a & b, a - b, a ^ b
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator|(chset<CharT> const& a, chlit<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator&(chset<CharT> const& a, chlit<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator-(chset<CharT> const& a, chlit<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator^(chset<CharT> const& a, chlit<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator|(chlit<CharT> const& a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator&(chlit<CharT> const& a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator-(chlit<CharT> const& a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator^(chlit<CharT> const& a, chset<CharT> const& b);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// negated_char_parser<range> <--> chset free operators
|
||||
//
|
||||
// Where a is a chset and b is a range, and vice-versa, implements:
|
||||
//
|
||||
// a | b, a & b, a - b, a ^ b
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator|(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator&(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator-(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator^(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator|(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator&(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator-(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator^(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// negated_char_parser<chlit> <--> chset free operators
|
||||
//
|
||||
// Where a is a chset and b is a chlit, and vice-versa, implements:
|
||||
//
|
||||
// a | b, a & b, a - b, a ^ b
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator|(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator&(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator-(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator^(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator|(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator&(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator-(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator^(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// literal primitives <--> chset free operators
|
||||
//
|
||||
// Where a is a chset and b is a literal primitive,
|
||||
// and vice-versa, implements:
|
||||
//
|
||||
// a | b, a & b, a - b, a ^ b
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator|(chset<CharT> const& a, CharT b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator&(chset<CharT> const& a, CharT b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator-(chset<CharT> const& a, CharT b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator^(chset<CharT> const& a, CharT b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator|(CharT a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator&(CharT a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator-(CharT a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator^(CharT a, chset<CharT> const& b);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// anychar_parser <--> chset free operators
|
||||
//
|
||||
// Where a is chset and b is a anychar_parser, and vice-versa, implements:
|
||||
//
|
||||
// a | b, a & b, a - b, a ^ b
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator|(chset<CharT> const& a, anychar_parser b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator&(chset<CharT> const& a, anychar_parser b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator-(chset<CharT> const& a, anychar_parser b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator^(chset<CharT> const& a, anychar_parser b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator|(anychar_parser a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator&(anychar_parser a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator-(anychar_parser a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator^(anychar_parser a, chset<CharT> const& b);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// nothing_parser <--> chset free operators
|
||||
//
|
||||
// Where a is chset and b is nothing_parser, and vice-versa, implements:
|
||||
//
|
||||
// a | b, a & b, a - b, a ^ b
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator|(chset<CharT> const& a, nothing_parser b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator&(chset<CharT> const& a, nothing_parser b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator-(chset<CharT> const& a, nothing_parser b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator^(chset<CharT> const& a, nothing_parser b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator|(nothing_parser a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator&(nothing_parser a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator-(nothing_parser a, chset<CharT> const& b);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
chset<CharT>
|
||||
operator^(nothing_parser a, chset<CharT> const& b);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/utility/impl/chset_operators.ipp>
|
396
boost/boost/spirit/utility/confix.hpp
Normal file
396
boost/boost/spirit/utility/confix.hpp
Normal file
@ -0,0 +1,396 @@
|
||||
/*=============================================================================
|
||||
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_CONFIX_HPP
|
||||
#define BOOST_SPIRIT_CONFIX_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/spirit/meta/as_parser.hpp>
|
||||
#include <boost/spirit/core/composite/operators.hpp>
|
||||
#include <boost/spirit/utility/impl/confix.ipp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// confix_parser class
|
||||
//
|
||||
// Parses a sequence of 3 sub-matches. This class may
|
||||
// be used to parse structures, where the opening part is possibly
|
||||
// contained in the expression part and the whole sequence is only
|
||||
// parsed after seeing the closing part matching the first opening
|
||||
// subsequence. Example: C-comments:
|
||||
//
|
||||
// /* This is a C-comment */
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename NestedT = non_nested, typename LexemeT = non_lexeme>
|
||||
struct confix_parser_gen;
|
||||
|
||||
template <
|
||||
typename OpenT, typename ExprT, typename CloseT, typename CategoryT,
|
||||
typename NestedT = non_nested, typename LexemeT = non_lexeme
|
||||
>
|
||||
struct confix_parser :
|
||||
public parser<
|
||||
confix_parser<OpenT, ExprT, CloseT, CategoryT, NestedT, LexemeT>
|
||||
>
|
||||
{
|
||||
typedef
|
||||
confix_parser<OpenT, ExprT, CloseT, CategoryT, NestedT, LexemeT>
|
||||
self_t;
|
||||
|
||||
confix_parser(OpenT const &open_, ExprT const &expr_, CloseT const &close_)
|
||||
: open(open_), expr(expr_), close(close_)
|
||||
{}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
return impl::confix_parser_type<CategoryT>::
|
||||
parse(NestedT(), LexemeT(), *this, scan, open, expr, close);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typename as_parser<OpenT>::type::embed_t open;
|
||||
typename as_parser<ExprT>::type::embed_t expr;
|
||||
typename as_parser<CloseT>::type::embed_t close;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Confix parser generator template
|
||||
//
|
||||
// This is a helper for generating a correct confix_parser<> from
|
||||
// auxiliary parameters. There are the following types supported as
|
||||
// parameters yet: parsers, single characters and strings (see
|
||||
// as_parser).
|
||||
//
|
||||
// If the body parser is an action_parser_category type parser (a parser
|
||||
// with an attached semantic action) we have to do something special. This
|
||||
// happens, if the user wrote something like:
|
||||
//
|
||||
// confix_p(open, body[f], close)
|
||||
//
|
||||
// where 'body' is the parser matching the body of the confix sequence
|
||||
// and 'f' is a functor to be called after matching the body. If we would
|
||||
// do nothing, the resulting code would parse the sequence as follows:
|
||||
//
|
||||
// start >> (body[f] - close) >> close
|
||||
//
|
||||
// what in most cases is not what the user expects.
|
||||
// (If this _is_ what you've expected, then please use the confix_p
|
||||
// generator function 'direct()', which will inhibit
|
||||
// re-attaching the actor to the body parser).
|
||||
//
|
||||
// To make the confix parser behave as expected:
|
||||
//
|
||||
// start >> (body - close)[f] >> close
|
||||
//
|
||||
// the actor attached to the 'body' parser has to be re-attached to the
|
||||
// (body - close) parser construct, which will make the resulting confix
|
||||
// parser 'do the right thing'. This refactoring is done by the help of
|
||||
// the refactoring parsers (see the files refactoring.[hi]pp).
|
||||
//
|
||||
// Additionally special care must be taken, if the body parser is a
|
||||
// unary_parser_category type parser as
|
||||
//
|
||||
// confix_p(open, *anychar_p, close)
|
||||
//
|
||||
// which without any refactoring would result in
|
||||
//
|
||||
// start >> (*anychar_p - close) >> close
|
||||
//
|
||||
// and will not give the expected result (*anychar_p will eat up all the
|
||||
// input up to the end of the input stream). So we have to refactor this
|
||||
// into:
|
||||
//
|
||||
// start >> *(anychar_p - close) >> close
|
||||
//
|
||||
// what will give the correct result.
|
||||
//
|
||||
// The case, where the body parser is a combination of the two mentioned
|
||||
// problems (i.e. the body parser is a unary parser with an attached
|
||||
// action), is handled accordingly too:
|
||||
//
|
||||
// confix_p(start, (*anychar_p)[f], end)
|
||||
//
|
||||
// will be parsed as expected:
|
||||
//
|
||||
// start >> (*(anychar_p - end))[f] >> end.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename NestedT, typename LexemeT>
|
||||
struct confix_parser_gen
|
||||
{
|
||||
// Generic generator function for creation of concrete confix parsers
|
||||
|
||||
template<typename StartT, typename ExprT, typename EndT>
|
||||
confix_parser<
|
||||
typename as_parser<StartT>::type,
|
||||
typename as_parser<ExprT>::type,
|
||||
typename as_parser<EndT>::type,
|
||||
typename as_parser<ExprT>::type::parser_category_t,
|
||||
NestedT,
|
||||
LexemeT
|
||||
>
|
||||
operator()(
|
||||
StartT const &start_, ExprT const &expr_, EndT const &end_) const
|
||||
{
|
||||
typedef typename as_parser<StartT>::type start_t;
|
||||
typedef typename as_parser<ExprT>::type expr_t;
|
||||
typedef typename as_parser<EndT>::type end_t;
|
||||
typedef
|
||||
typename as_parser<ExprT>::type::parser_category_t
|
||||
parser_category_t;
|
||||
|
||||
typedef
|
||||
confix_parser<
|
||||
start_t, expr_t, end_t, parser_category_t, NestedT, LexemeT
|
||||
>
|
||||
return_t;
|
||||
|
||||
return return_t(
|
||||
as_parser<StartT>::convert(start_),
|
||||
as_parser<ExprT>::convert(expr_),
|
||||
as_parser<EndT>::convert(end_)
|
||||
);
|
||||
}
|
||||
|
||||
// Generic generator function for creation of concrete confix parsers
|
||||
// which have an action directly attached to the ExprT part of the
|
||||
// parser (see comment above, no automatic refactoring)
|
||||
|
||||
template<typename StartT, typename ExprT, typename EndT>
|
||||
confix_parser<
|
||||
typename as_parser<StartT>::type,
|
||||
typename as_parser<ExprT>::type,
|
||||
typename as_parser<EndT>::type,
|
||||
plain_parser_category, // do not re-attach action
|
||||
NestedT,
|
||||
LexemeT
|
||||
>
|
||||
direct(StartT const &start_, ExprT const &expr_, EndT const &end_) const
|
||||
{
|
||||
typedef typename as_parser<StartT>::type start_t;
|
||||
typedef typename as_parser<ExprT>::type expr_t;
|
||||
typedef typename as_parser<EndT>::type end_t;
|
||||
typedef plain_parser_category parser_category_t;
|
||||
|
||||
typedef
|
||||
confix_parser<
|
||||
start_t, expr_t, end_t, parser_category_t, NestedT, LexemeT
|
||||
>
|
||||
return_t;
|
||||
|
||||
return return_t(
|
||||
as_parser<StartT>::convert(start_),
|
||||
as_parser<ExprT>::convert(expr_),
|
||||
as_parser<EndT>::convert(end_)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Predefined non_nested confix parser generators
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const confix_parser_gen<non_nested, non_lexeme> confix_p =
|
||||
confix_parser_gen<non_nested, non_lexeme>();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Comments are special types of confix parsers
|
||||
//
|
||||
// Comment parser generator template. This is a helper for generating a
|
||||
// correct confix_parser<> from auxiliary parameters, which is able to
|
||||
// parse comment constructs: (StartToken >> Comment text >> EndToken).
|
||||
//
|
||||
// There are the following types supported as parameters yet: parsers,
|
||||
// single characters and strings (see as_parser).
|
||||
//
|
||||
// There are two diffenerent predefined comment parser generators
|
||||
// (comment_p and comment_nest_p, see below), which may be used for
|
||||
// creating special comment parsers in two different ways.
|
||||
//
|
||||
// If these are used with one parameter, a comment starting with the given
|
||||
// first parser parameter up to the end of the line is matched. So for
|
||||
// instance the following parser matches C++ style comments:
|
||||
//
|
||||
// comment_p("//").
|
||||
//
|
||||
// If these are used with two parameters, a comment starting with the
|
||||
// first parser parameter up to the second parser parameter is matched.
|
||||
// For instance a C style comment parser should be constrcuted as:
|
||||
//
|
||||
// comment_p("/*", "*/").
|
||||
//
|
||||
// Please note, that a comment is parsed implicitly as if the whole
|
||||
// comment_p(...) statement were embedded into a lexeme_d[] directive.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename NestedT>
|
||||
struct comment_parser_gen
|
||||
{
|
||||
// Generic generator function for creation of concrete comment parsers
|
||||
// from an open token. The newline parser eol_p is used as the
|
||||
// closing token.
|
||||
|
||||
template<typename StartT>
|
||||
confix_parser<
|
||||
typename as_parser<StartT>::type,
|
||||
kleene_star<anychar_parser>,
|
||||
alternative<eol_parser, end_parser>,
|
||||
unary_parser_category, // there is no action to re-attach
|
||||
NestedT,
|
||||
is_lexeme // insert implicit lexeme_d[]
|
||||
>
|
||||
operator() (StartT const &start_) const
|
||||
{
|
||||
typedef typename as_parser<StartT>::type start_t;
|
||||
typedef kleene_star<anychar_parser> expr_t;
|
||||
typedef alternative<eol_parser, end_parser> end_t;
|
||||
typedef unary_parser_category parser_category_t;
|
||||
|
||||
typedef
|
||||
confix_parser<
|
||||
start_t, expr_t, end_t, parser_category_t, NestedT, is_lexeme
|
||||
>
|
||||
return_t;
|
||||
|
||||
return return_t(
|
||||
as_parser<StartT>::convert(start_),
|
||||
*anychar_p,
|
||||
eol_p | end_p
|
||||
);
|
||||
}
|
||||
|
||||
// Generic generator function for creation of concrete comment parsers
|
||||
// from an open and a close tokens.
|
||||
|
||||
template<typename StartT, typename EndT>
|
||||
confix_parser<
|
||||
typename as_parser<StartT>::type,
|
||||
kleene_star<anychar_parser>,
|
||||
typename as_parser<EndT>::type,
|
||||
unary_parser_category, // there is no action to re-attach
|
||||
NestedT,
|
||||
is_lexeme // insert implicit lexeme_d[]
|
||||
>
|
||||
operator() (StartT const &start_, EndT const &end_) const
|
||||
{
|
||||
typedef typename as_parser<StartT>::type start_t;
|
||||
typedef kleene_star<anychar_parser> expr_t;
|
||||
typedef typename as_parser<EndT>::type end_t;
|
||||
typedef unary_parser_category parser_category_t;
|
||||
|
||||
typedef
|
||||
confix_parser<
|
||||
start_t, expr_t, end_t, parser_category_t, NestedT, is_lexeme
|
||||
>
|
||||
return_t;
|
||||
|
||||
return return_t(
|
||||
as_parser<StartT>::convert(start_),
|
||||
*anychar_p,
|
||||
as_parser<EndT>::convert(end_)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Predefined non_nested comment parser generator
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const comment_parser_gen<non_nested> comment_p =
|
||||
comment_parser_gen<non_nested>();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// comment_nest_parser class
|
||||
//
|
||||
// Parses a nested comments.
|
||||
// Example: nested PASCAL-comments:
|
||||
//
|
||||
// { This is a { nested } PASCAL-comment }
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename OpenT, typename CloseT>
|
||||
struct comment_nest_parser:
|
||||
public parser<comment_nest_parser<OpenT, CloseT> >
|
||||
{
|
||||
typedef comment_nest_parser<OpenT, CloseT> self_t;
|
||||
|
||||
comment_nest_parser(OpenT const &open_, CloseT const &close_):
|
||||
open(open_), close(close_)
|
||||
{}
|
||||
|
||||
template<typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const &scan) const
|
||||
{
|
||||
return do_parse(
|
||||
open >> *(*this | (anychar_p - close)) >> close,
|
||||
scan);
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename ParserT, typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
do_parse(ParserT const &p, ScannerT const &scan) const
|
||||
{
|
||||
return
|
||||
impl::contiguous_parser_parse<
|
||||
BOOST_DEDUCED_TYPENAME parser_result<ParserT, ScannerT>::type
|
||||
>(p, scan, scan);
|
||||
}
|
||||
|
||||
typename as_parser<OpenT>::type::embed_t open;
|
||||
typename as_parser<CloseT>::type::embed_t close;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Predefined nested comment parser generator
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename OpenT, typename CloseT>
|
||||
inline
|
||||
comment_nest_parser<
|
||||
typename as_parser<OpenT>::type,
|
||||
typename as_parser<CloseT>::type
|
||||
>
|
||||
comment_nest_p(OpenT const &open, CloseT const &close)
|
||||
{
|
||||
return
|
||||
comment_nest_parser<
|
||||
BOOST_DEDUCED_TYPENAME as_parser<OpenT>::type,
|
||||
BOOST_DEDUCED_TYPENAME as_parser<CloseT>::type
|
||||
>(
|
||||
as_parser<OpenT>::convert(open),
|
||||
as_parser<CloseT>::convert(close)
|
||||
);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
225
boost/boost/spirit/utility/distinct.hpp
Normal file
225
boost/boost/spirit/utility/distinct.hpp
Normal file
@ -0,0 +1,225 @@
|
||||
/*=============================================================================
|
||||
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_DISTINCT_HPP)
|
||||
#define BOOST_SPIRIT_DISTINCT_HPP
|
||||
|
||||
#include <boost/spirit/core/parser.hpp>
|
||||
#include <boost/spirit/core/primitives/primitives.hpp>
|
||||
#include <boost/spirit/core/composite/operators.hpp>
|
||||
#include <boost/spirit/core/composite/directives.hpp>
|
||||
#include <boost/spirit/core/composite/epsilon.hpp>
|
||||
#include <boost/spirit/core/non_terminal/rule.hpp>
|
||||
#include <boost/spirit/utility/chset.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace spirit {
|
||||
//-----------------------------------------------------------------------------
|
||||
// distinct_parser class
|
||||
|
||||
template <typename CharT = char, typename TailT = chset<CharT> >
|
||||
class distinct_parser
|
||||
{
|
||||
public:
|
||||
typedef
|
||||
contiguous<
|
||||
sequence<
|
||||
chseq<CharT const*>,
|
||||
negated_empty_match_parser<
|
||||
TailT
|
||||
>
|
||||
>
|
||||
>
|
||||
result_t;
|
||||
|
||||
distinct_parser()
|
||||
: tail(chset<CharT>())
|
||||
{
|
||||
}
|
||||
|
||||
explicit distinct_parser(parser<TailT> const & tail_)
|
||||
: tail(tail_.derived())
|
||||
{
|
||||
}
|
||||
|
||||
explicit distinct_parser(CharT const* letters)
|
||||
: tail(chset_p(letters))
|
||||
{
|
||||
}
|
||||
|
||||
result_t operator()(CharT const* str) const
|
||||
{
|
||||
return lexeme_d[chseq_p(str) >> ~epsilon_p(tail)];
|
||||
}
|
||||
|
||||
TailT tail;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// distinct_directive class
|
||||
|
||||
template <typename CharT = char, typename TailT = chset<CharT> >
|
||||
class distinct_directive
|
||||
{
|
||||
public:
|
||||
template<typename ParserT>
|
||||
struct result {
|
||||
typedef
|
||||
contiguous<
|
||||
sequence<
|
||||
ParserT,
|
||||
negated_empty_match_parser<
|
||||
TailT
|
||||
>
|
||||
>
|
||||
>
|
||||
type;
|
||||
};
|
||||
|
||||
distinct_directive()
|
||||
: tail(chset<CharT>())
|
||||
{
|
||||
}
|
||||
|
||||
explicit distinct_directive(CharT const* letters)
|
||||
: tail(chset_p(letters))
|
||||
{
|
||||
}
|
||||
|
||||
explicit distinct_directive(parser<TailT> const & tail_)
|
||||
: tail(tail_.derived())
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ParserT>
|
||||
typename result<typename as_parser<ParserT>::type>::type
|
||||
operator[](ParserT const &subject) const
|
||||
{
|
||||
return
|
||||
lexeme_d[as_parser<ParserT>::convert(subject) >> ~epsilon_p(tail)];
|
||||
}
|
||||
|
||||
TailT tail;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// dynamic_distinct_parser class
|
||||
|
||||
template <typename ScannerT = scanner<> >
|
||||
class dynamic_distinct_parser
|
||||
{
|
||||
public:
|
||||
typedef typename ScannerT::value_t char_t;
|
||||
|
||||
typedef
|
||||
rule<
|
||||
typename no_actions_scanner<
|
||||
typename lexeme_scanner<ScannerT>::type
|
||||
>::type
|
||||
>
|
||||
tail_t;
|
||||
|
||||
typedef
|
||||
contiguous<
|
||||
sequence<
|
||||
chseq<char_t const*>,
|
||||
negated_empty_match_parser<
|
||||
tail_t
|
||||
>
|
||||
>
|
||||
>
|
||||
result_t;
|
||||
|
||||
dynamic_distinct_parser()
|
||||
: tail(nothing_p)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ParserT>
|
||||
explicit dynamic_distinct_parser(parser<ParserT> const & tail_)
|
||||
: tail(tail_.derived())
|
||||
{
|
||||
}
|
||||
|
||||
explicit dynamic_distinct_parser(char_t const* letters)
|
||||
: tail(chset_p(letters))
|
||||
{
|
||||
}
|
||||
|
||||
result_t operator()(char_t const* str) const
|
||||
{
|
||||
return lexeme_d[chseq_p(str) >> ~epsilon_p(tail)];
|
||||
}
|
||||
|
||||
tail_t tail;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// dynamic_distinct_directive class
|
||||
|
||||
template <typename ScannerT = scanner<> >
|
||||
class dynamic_distinct_directive
|
||||
{
|
||||
public:
|
||||
typedef typename ScannerT::value_t char_t;
|
||||
|
||||
typedef
|
||||
rule<
|
||||
typename no_actions_scanner<
|
||||
typename lexeme_scanner<ScannerT>::type
|
||||
>::type
|
||||
>
|
||||
tail_t;
|
||||
|
||||
template<typename ParserT>
|
||||
struct result {
|
||||
typedef
|
||||
contiguous<
|
||||
sequence<
|
||||
ParserT,
|
||||
negated_empty_match_parser<
|
||||
tail_t
|
||||
>
|
||||
>
|
||||
>
|
||||
type;
|
||||
};
|
||||
|
||||
dynamic_distinct_directive()
|
||||
: tail(nothing_p)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ParserT>
|
||||
explicit dynamic_distinct_directive(parser<ParserT> const & tail_)
|
||||
: tail(tail_.derived())
|
||||
{
|
||||
}
|
||||
|
||||
explicit dynamic_distinct_directive(char_t const* letters)
|
||||
: tail(chset_p(letters))
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ParserT>
|
||||
typename result<typename as_parser<ParserT>::type>::type
|
||||
operator[](ParserT const &subject) const
|
||||
{
|
||||
return
|
||||
lexeme_d[as_parser<ParserT>::convert(subject) >> ~epsilon_p(tail)];
|
||||
}
|
||||
|
||||
tail_t tail;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
} // namespace spirit
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(BOOST_SPIRIT_DISTINCT_HPP)
|
177
boost/boost/spirit/utility/escape_char.hpp
Normal file
177
boost/boost/spirit/utility/escape_char.hpp
Normal file
@ -0,0 +1,177 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2003 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)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_ESCAPE_CHAR_HPP
|
||||
#define BOOST_SPIRIT_ESCAPE_CHAR_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <string>
|
||||
#include <iterator>
|
||||
#include <cctype>
|
||||
#include <boost/limits.hpp>
|
||||
|
||||
#include <boost/spirit/utility/impl/escape_char.ipp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// escape_char_action class
|
||||
//
|
||||
// Links an escape char parser with a user defined semantic action.
|
||||
// The semantic action may be a function or a functor. A function
|
||||
// should be compatible with the interface:
|
||||
//
|
||||
// void f(CharT ch);
|
||||
//
|
||||
// A functor should have a member operator() with a compatible signature
|
||||
// as above. The matching character is passed into the function/functor.
|
||||
// This is the default class that character parsers use when dealing with
|
||||
// the construct:
|
||||
//
|
||||
// p[f]
|
||||
//
|
||||
// where p is a parser and f is a function or functor.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename ParserT, typename ActionT,
|
||||
unsigned long Flags, typename CharT
|
||||
>
|
||||
struct escape_char_action
|
||||
: public unary<ParserT,
|
||||
parser<escape_char_action<ParserT, ActionT, Flags, CharT> > >
|
||||
{
|
||||
typedef escape_char_action
|
||||
<ParserT, ActionT, Flags, CharT> self_t;
|
||||
typedef action_parser_category parser_category_t;
|
||||
typedef unary<ParserT, parser<self_t> > base_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, CharT>::type type;
|
||||
};
|
||||
|
||||
escape_char_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
|
||||
{
|
||||
return impl::escape_char_action_parse<Flags, CharT>::
|
||||
parse(scan, *this);
|
||||
}
|
||||
|
||||
ActionT const& predicate() const { return actor; }
|
||||
|
||||
private:
|
||||
|
||||
ActionT actor;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// escape_char_parser class
|
||||
//
|
||||
// The escape_char_parser helps in conjunction with the escape_char_action
|
||||
// template class (see above) in parsing escaped characters. There are two
|
||||
// different variants of this parser: one for parsing C style escaped
|
||||
// characters and one for parsing LEX style escaped characters.
|
||||
//
|
||||
// The C style escaped character parser is generated, when the template
|
||||
// parameter 'Flags' is equal to 'c_escapes' (a constant defined in the
|
||||
// file impl/escape_char.ipp). This parser recognizes all valid C escape
|
||||
// character sequences: '\t', '\b', '\f', '\n', '\r', '\"', '\'', '\\'
|
||||
// and the numeric style escapes '\120' (octal) and '\x2f' (hexadecimal)
|
||||
// and converts these to their character equivalent, for instance the
|
||||
// sequence of a backslash and a 'b' is parsed as the character '\b'.
|
||||
// All other escaped characters are rejected by this parser.
|
||||
//
|
||||
// The LEX style escaped character parser is generated, when the template
|
||||
// parameter 'Flags' is equal to 'lex_escapes' (a constant defined in the
|
||||
// file impl/escape_char.ipp). This parser recognizes all the C style
|
||||
// escaped character sequences (as described above) and additionally
|
||||
// does not reject all other escape sequences. All not mentioned escape
|
||||
// sequences are converted by the parser to the plain character, for
|
||||
// instance '\a' will be parsed as 'a'.
|
||||
//
|
||||
// All not escaped characters are parsed without modification.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <unsigned long Flags, typename CharT>
|
||||
struct escape_char_action_parser_gen;
|
||||
|
||||
template <unsigned long Flags, typename CharT = char>
|
||||
struct escape_char_parser :
|
||||
public parser<escape_char_parser<Flags, CharT> > {
|
||||
|
||||
// only the values c_escapes and lex_escapes are valid for Flags
|
||||
BOOST_STATIC_ASSERT(Flags == c_escapes || Flags == lex_escapes);
|
||||
|
||||
typedef escape_char_parser<Flags, CharT> self_t;
|
||||
typedef
|
||||
escape_char_action_parser_gen<Flags, CharT>
|
||||
action_parser_generator_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result {
|
||||
|
||||
typedef typename match_result<ScannerT, CharT>::type type;
|
||||
};
|
||||
|
||||
template <typename ActionT>
|
||||
escape_char_action<self_t, ActionT, Flags, CharT>
|
||||
operator[](ActionT const& actor) const
|
||||
{
|
||||
return escape_char_action<self_t, ActionT, Flags, CharT>(*this, actor);
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const &scan) const
|
||||
{
|
||||
return impl::escape_char_parse<CharT>::parse(scan, *this);
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned long Flags, typename CharT>
|
||||
struct escape_char_action_parser_gen {
|
||||
|
||||
template <typename ParserT, typename ActionT>
|
||||
static escape_char_action<ParserT, ActionT, Flags, CharT>
|
||||
generate (ParserT const &p, ActionT const &actor)
|
||||
{
|
||||
typedef
|
||||
escape_char_action<ParserT, ActionT, Flags, CharT>
|
||||
action_parser_t;
|
||||
return action_parser_t(p, actor);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// predefined escape_char_parser objects
|
||||
//
|
||||
// These objects should be used for generating correct escaped character
|
||||
// parsers.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
const escape_char_parser<lex_escapes> lex_escape_ch_p =
|
||||
escape_char_parser<lex_escapes>();
|
||||
|
||||
const escape_char_parser<c_escapes> c_escape_ch_p =
|
||||
escape_char_parser<c_escapes>();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
73
boost/boost/spirit/utility/flush_multi_pass.hpp
Normal file
73
boost/boost/spirit/utility/flush_multi_pass.hpp
Normal file
@ -0,0 +1,73 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2003 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)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_FLUSH_MULTI_PASS_HPP
|
||||
#define BOOST_SPIRIT_FLUSH_MULTI_PASS_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/spirit/core.hpp>
|
||||
#include <boost/spirit/iterator/multi_pass.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
namespace impl {
|
||||
|
||||
template <typename T>
|
||||
void flush_iterator(T &) {}
|
||||
|
||||
template <typename T1, typename T2, typename T3, typename T4>
|
||||
void flush_iterator(boost::spirit::multi_pass<
|
||||
T1, T2, T3, T4, boost::spirit::multi_pass_policies::std_deque> &i)
|
||||
{
|
||||
i.clear_queue();
|
||||
}
|
||||
|
||||
} // namespace impl
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// flush_multi_pass_parser
|
||||
//
|
||||
// The flush_multi_pass_parser flushes an underlying
|
||||
// multi_pass_iterator during the normal parsing process. This may
|
||||
// be used at certain points during the parsing process, when it is
|
||||
// clear, that no backtracking is needed anymore and the input
|
||||
// gathered so far may be discarded.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
class flush_multi_pass_parser
|
||||
: public parser<flush_multi_pass_parser>
|
||||
{
|
||||
public:
|
||||
typedef flush_multi_pass_parser this_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<this_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
impl::flush_iterator(scan.first);
|
||||
return scan.empty_match();
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// predefined flush_multi_pass_p object
|
||||
//
|
||||
// This object should may used to flush a multi_pass_iterator along
|
||||
// the way during the normal parsing process.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
flush_multi_pass_parser const
|
||||
flush_multi_pass_p = flush_multi_pass_parser();
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif // BOOST_SPIRIT_FLUSH_MULTI_PASS_HPP
|
67
boost/boost/spirit/utility/functor_parser.hpp
Normal file
67
boost/boost/spirit/utility/functor_parser.hpp
Normal file
@ -0,0 +1,67 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2002-2003 Joel de Guzman
|
||||
Copyright (c) 2002-2003 Juan Carlos Arevalo-Baeza
|
||||
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_FUNCTOR_PARSER_HPP
|
||||
#define BOOST_SPIRIT_FUNCTOR_PARSER_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/spirit/core/parser.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// functor_parser class
|
||||
//
|
||||
// Once a functor parser has been defined, you can build a real
|
||||
// parser from it by passing it to this class as the template
|
||||
// parameter.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template < class FunctorT >
|
||||
struct functor_parser : public parser<functor_parser<FunctorT> >
|
||||
{
|
||||
FunctorT functor;
|
||||
|
||||
functor_parser(): functor() {}
|
||||
functor_parser(FunctorT const& functor_): functor(functor_) {}
|
||||
|
||||
typedef typename FunctorT::result_t functor_result_t;
|
||||
typedef functor_parser<FunctorT> self_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, functor_result_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;
|
||||
|
||||
iterator_t const s(scan.first);
|
||||
functor_result_t result;
|
||||
std::ptrdiff_t len = functor(scan, result);
|
||||
|
||||
if (len < 0)
|
||||
return scan.no_match();
|
||||
else
|
||||
return scan.create_match(std::size_t(len), result, s, scan.first);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
362
boost/boost/spirit/utility/impl/chset.ipp
Normal file
362
boost/boost/spirit/utility/impl/chset.ipp
Normal file
@ -0,0 +1,362 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2003 Joel de Guzman
|
||||
Copyright (c) 2001-2003 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)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_CHSET_IPP
|
||||
#define BOOST_SPIRIT_CHSET_IPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/spirit/utility/chset.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// chset class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace utility { namespace impl {
|
||||
template <typename CharT>
|
||||
inline void
|
||||
detach(boost::shared_ptr<basic_chset<CharT> >& ptr)
|
||||
{
|
||||
if (!ptr.unique())
|
||||
ptr = boost::shared_ptr<basic_chset<CharT> >
|
||||
(new basic_chset<CharT>(*ptr));
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline void
|
||||
detach_clear(boost::shared_ptr<basic_chset<CharT> >& ptr)
|
||||
{
|
||||
if (ptr.unique())
|
||||
ptr->clear();
|
||||
else
|
||||
ptr.reset(new basic_chset<CharT>());
|
||||
}
|
||||
|
||||
template <typename CharT, typename CharT2>
|
||||
void construct_chset(boost::shared_ptr<basic_chset<CharT> >& ptr,
|
||||
CharT2 const* definition)
|
||||
{
|
||||
CharT2 ch = *definition++;
|
||||
while (ch)
|
||||
{
|
||||
CharT2 next = *definition++;
|
||||
if (next == '-')
|
||||
{
|
||||
next = *definition++;
|
||||
if (next == 0)
|
||||
{
|
||||
ptr->set(ch);
|
||||
ptr->set('-');
|
||||
break;
|
||||
}
|
||||
ptr->set(ch, next);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr->set(ch);
|
||||
}
|
||||
ch = next;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
|
||||
template <typename CharT, typename FakeT>
|
||||
void chset_negated_set(boost::shared_ptr<basic_chset<CharT> > &ptr, chlit<CharT> const &ch,
|
||||
FakeT)
|
||||
{
|
||||
if(ch.ch != (std::numeric_limits<CharT>::min)()) {
|
||||
ptr->set((std::numeric_limits<CharT>::min)(), ch.ch - 1);
|
||||
}
|
||||
if(ch.ch != (std::numeric_limits<CharT>::max)()) {
|
||||
ptr->set(ch.ch + 1, (std::numeric_limits<CharT>::max)());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CharT, typename FakeT>
|
||||
void chset_negated_set(boost::shared_ptr<basic_chset<CharT> > &ptr,
|
||||
spirit::range<CharT> const &rng, FakeT)
|
||||
{
|
||||
if(rng.first != (std::numeric_limits<CharT>::min)()) {
|
||||
ptr->set((std::numeric_limits<CharT>::min)(), rng.first - 1);
|
||||
}
|
||||
if(rng.last != (std::numeric_limits<CharT>::max)()) {
|
||||
ptr->set(rng.last + 1, (std::numeric_limits<CharT>::max)());
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
|
||||
//////////////////////////////////
|
||||
|
||||
}} // namespace utility::impl
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>::chset()
|
||||
: ptr(new basic_chset<CharT>()) {}
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>::chset(chset const& arg_)
|
||||
: ptr(new basic_chset<CharT>(*arg_.ptr)) {}
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>::chset(CharT arg_)
|
||||
: ptr(new basic_chset<CharT>())
|
||||
{ ptr->set(arg_); }
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>::chset(anychar_parser /*arg*/)
|
||||
: ptr(new basic_chset<CharT>())
|
||||
{
|
||||
ptr->set(
|
||||
(std::numeric_limits<CharT>::min)(),
|
||||
(std::numeric_limits<CharT>::max)()
|
||||
);
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>::chset(nothing_parser arg_)
|
||||
: ptr(new basic_chset<CharT>()) {}
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>::chset(chlit<CharT> const& arg_)
|
||||
: ptr(new basic_chset<CharT>())
|
||||
{ ptr->set(arg_.ch); }
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>::chset(range<CharT> const& arg_)
|
||||
: ptr(new basic_chset<CharT>())
|
||||
{ ptr->set(arg_.first, arg_.last); }
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>::chset(negated_char_parser<chlit<CharT> > const& arg_)
|
||||
: ptr(new basic_chset<CharT>())
|
||||
{
|
||||
set(arg_);
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>::chset(negated_char_parser<range<CharT> > const& arg_)
|
||||
: ptr(new basic_chset<CharT>())
|
||||
{
|
||||
set(arg_);
|
||||
}
|
||||
|
||||
#endif // !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>::~chset() {}
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>&
|
||||
chset<CharT>::operator=(chset const& rhs)
|
||||
{
|
||||
ptr = rhs.ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>&
|
||||
chset<CharT>::operator=(CharT rhs)
|
||||
{
|
||||
utility::impl::detach_clear(ptr);
|
||||
ptr->set(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>&
|
||||
chset<CharT>::operator=(anychar_parser rhs)
|
||||
{
|
||||
utility::impl::detach_clear(ptr);
|
||||
ptr->set(
|
||||
(std::numeric_limits<CharT>::min)(),
|
||||
(std::numeric_limits<CharT>::max)()
|
||||
);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>&
|
||||
chset<CharT>::operator=(nothing_parser rhs)
|
||||
{
|
||||
utility::impl::detach_clear(ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>&
|
||||
chset<CharT>::operator=(chlit<CharT> const& rhs)
|
||||
{
|
||||
utility::impl::detach_clear(ptr);
|
||||
ptr->set(rhs.ch);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>&
|
||||
chset<CharT>::operator=(range<CharT> const& rhs)
|
||||
{
|
||||
utility::impl::detach_clear(ptr);
|
||||
ptr->set(rhs.first, rhs.last);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>&
|
||||
chset<CharT>::operator=(negated_char_parser<chlit<CharT> > const& rhs)
|
||||
{
|
||||
utility::impl::detach_clear(ptr);
|
||||
set(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>&
|
||||
chset<CharT>::operator=(negated_char_parser<range<CharT> > const& rhs)
|
||||
{
|
||||
utility::impl::detach_clear(ptr);
|
||||
set(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif // !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
|
||||
template <typename CharT>
|
||||
inline void
|
||||
chset<CharT>::set(range<CharT> const& arg_)
|
||||
{
|
||||
utility::impl::detach(ptr);
|
||||
ptr->set(arg_.first, arg_.last);
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
|
||||
template <typename CharT>
|
||||
inline void
|
||||
chset<CharT>::set(negated_char_parser<chlit<CharT> > const& arg_)
|
||||
{
|
||||
utility::impl::detach(ptr);
|
||||
|
||||
if(arg_.positive.ch != (std::numeric_limits<CharT>::min)()) {
|
||||
ptr->set((std::numeric_limits<CharT>::min)(), arg_.positive.ch - 1);
|
||||
}
|
||||
if(arg_.positive.ch != (std::numeric_limits<CharT>::max)()) {
|
||||
ptr->set(arg_.positive.ch + 1, (std::numeric_limits<CharT>::max)());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline void
|
||||
chset<CharT>::set(negated_char_parser<range<CharT> > const& arg_)
|
||||
{
|
||||
utility::impl::detach(ptr);
|
||||
|
||||
if(arg_.positive.first != (std::numeric_limits<CharT>::min)()) {
|
||||
ptr->set((std::numeric_limits<CharT>::min)(), arg_.positive.first - 1);
|
||||
}
|
||||
if(arg_.positive.last != (std::numeric_limits<CharT>::max)()) {
|
||||
ptr->set(arg_.positive.last + 1, (std::numeric_limits<CharT>::max)());
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
|
||||
template <typename CharT>
|
||||
inline void
|
||||
chset<CharT>::clear(range<CharT> const& arg_)
|
||||
{
|
||||
utility::impl::detach(ptr);
|
||||
ptr->clear(arg_.first, arg_.last);
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline void
|
||||
chset<CharT>::clear(negated_char_parser<range<CharT> > const& arg_)
|
||||
{
|
||||
utility::impl::detach(ptr);
|
||||
|
||||
if(arg_.positive.first != (std::numeric_limits<CharT>::min)()) {
|
||||
ptr->clear((std::numeric_limits<CharT>::min)(), arg_.positive.first - 1);
|
||||
}
|
||||
if(arg_.positive.last != (std::numeric_limits<CharT>::max)()) {
|
||||
ptr->clear(arg_.positive.last + 1, (std::numeric_limits<CharT>::max)());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
chset<CharT>::test(CharT ch) const
|
||||
{ return ptr->test(ch); }
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>&
|
||||
chset<CharT>::inverse()
|
||||
{
|
||||
utility::impl::detach(ptr);
|
||||
ptr->inverse();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline void
|
||||
chset<CharT>::swap(chset& x)
|
||||
{ ptr.swap(x.ptr); }
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>&
|
||||
chset<CharT>::operator|=(chset const& x)
|
||||
{
|
||||
utility::impl::detach(ptr);
|
||||
*ptr |= *x.ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>&
|
||||
chset<CharT>::operator&=(chset const& x)
|
||||
{
|
||||
utility::impl::detach(ptr);
|
||||
*ptr &= *x.ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>&
|
||||
chset<CharT>::operator-=(chset const& x)
|
||||
{
|
||||
utility::impl::detach(ptr);
|
||||
*ptr -= *x.ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline chset<CharT>&
|
||||
chset<CharT>::operator^=(chset const& x)
|
||||
{
|
||||
utility::impl::detach(ptr);
|
||||
*ptr ^= *x.ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
|
102
boost/boost/spirit/utility/impl/chset/basic_chset.hpp
Normal file
102
boost/boost/spirit/utility/impl/chset/basic_chset.hpp
Normal file
@ -0,0 +1,102 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2003 Joel de Guzman
|
||||
Copyright (c) 2001-2003 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)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_BASIC_CHSET_HPP
|
||||
#define BOOST_SPIRIT_BASIC_CHSET_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <bitset>
|
||||
#include <boost/spirit/utility/impl/chset/range_run.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// basic_chset: basic character set implementation using range_run
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
class basic_chset
|
||||
{
|
||||
public:
|
||||
basic_chset();
|
||||
basic_chset(basic_chset const& arg_);
|
||||
|
||||
bool test(CharT v) const;
|
||||
void set(CharT from, CharT to);
|
||||
void set(CharT c);
|
||||
void clear(CharT from, CharT to);
|
||||
void clear(CharT c);
|
||||
void clear();
|
||||
|
||||
void inverse();
|
||||
void swap(basic_chset& x);
|
||||
|
||||
basic_chset& operator|=(basic_chset const& x);
|
||||
basic_chset& operator&=(basic_chset const& x);
|
||||
basic_chset& operator-=(basic_chset const& x);
|
||||
basic_chset& operator^=(basic_chset const& x);
|
||||
|
||||
private: utility::impl::range_run<CharT> rr;
|
||||
};
|
||||
|
||||
#if (CHAR_BIT == 8)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// basic_chset: specializations for 8 bit chars using std::bitset
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
class basic_chset_8bit {
|
||||
|
||||
public:
|
||||
basic_chset_8bit();
|
||||
basic_chset_8bit(basic_chset_8bit const& arg_);
|
||||
|
||||
bool test(CharT v) const;
|
||||
void set(CharT from, CharT to);
|
||||
void set(CharT c);
|
||||
void clear(CharT from, CharT to);
|
||||
void clear(CharT c);
|
||||
void clear();
|
||||
|
||||
void inverse();
|
||||
void swap(basic_chset_8bit& x);
|
||||
|
||||
basic_chset_8bit& operator|=(basic_chset_8bit const& x);
|
||||
basic_chset_8bit& operator&=(basic_chset_8bit const& x);
|
||||
basic_chset_8bit& operator-=(basic_chset_8bit const& x);
|
||||
basic_chset_8bit& operator^=(basic_chset_8bit const& x);
|
||||
|
||||
private: std::bitset<256> bset;
|
||||
};
|
||||
|
||||
/////////////////////////////////
|
||||
template <>
|
||||
class basic_chset<char>
|
||||
: public basic_chset_8bit<char> {};
|
||||
|
||||
/////////////////////////////////
|
||||
template <>
|
||||
class basic_chset<signed char>
|
||||
: public basic_chset_8bit<signed char> {};
|
||||
|
||||
/////////////////////////////////
|
||||
template <>
|
||||
class basic_chset<unsigned char>
|
||||
: public basic_chset_8bit<unsigned char> {};
|
||||
|
||||
#endif
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/utility/impl/chset/basic_chset.ipp>
|
241
boost/boost/spirit/utility/impl/chset/basic_chset.ipp
Normal file
241
boost/boost/spirit/utility/impl/chset/basic_chset.ipp
Normal file
@ -0,0 +1,241 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2003 Joel de Guzman
|
||||
Copyright (c) 2001-2003 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)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_BASIC_CHSET_IPP
|
||||
#define BOOST_SPIRIT_BASIC_CHSET_IPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <bitset>
|
||||
#include <boost/spirit/utility/impl/chset/basic_chset.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// basic_chset: character set implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline basic_chset<CharT>::basic_chset() {}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline basic_chset<CharT>::basic_chset(basic_chset const& arg_)
|
||||
: rr(arg_.rr) {}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
basic_chset<CharT>::test(CharT v) const
|
||||
{ return rr.test(v); }
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline void
|
||||
basic_chset<CharT>::set(CharT from, CharT to)
|
||||
{ rr.set(utility::impl::range<CharT>(from, to)); }
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline void
|
||||
basic_chset<CharT>::set(CharT c)
|
||||
{ rr.set(utility::impl::range<CharT>(c, c)); }
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline void
|
||||
basic_chset<CharT>::clear(CharT from, CharT to)
|
||||
{ rr.clear(utility::impl::range<CharT>(from, to)); }
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline void
|
||||
basic_chset<CharT>::clear()
|
||||
{ rr.clear(); }
|
||||
|
||||
/////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline void
|
||||
basic_chset<CharT>::inverse()
|
||||
{
|
||||
basic_chset inv;
|
||||
inv.set(
|
||||
(std::numeric_limits<CharT>::min)(),
|
||||
(std::numeric_limits<CharT>::max)()
|
||||
);
|
||||
inv -= *this;
|
||||
swap(inv);
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline void
|
||||
basic_chset<CharT>::swap(basic_chset& x)
|
||||
{ rr.swap(x.rr); }
|
||||
|
||||
/////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline basic_chset<CharT>&
|
||||
basic_chset<CharT>::operator|=(basic_chset<CharT> const& x)
|
||||
{
|
||||
typedef typename utility::impl::range_run<CharT>::const_iterator const_iterator;
|
||||
for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
|
||||
rr.set(*iter);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline basic_chset<CharT>&
|
||||
basic_chset<CharT>::operator&=(basic_chset<CharT> const& x)
|
||||
{
|
||||
basic_chset inv;
|
||||
inv.set(
|
||||
(std::numeric_limits<CharT>::min)(),
|
||||
(std::numeric_limits<CharT>::max)()
|
||||
);
|
||||
inv -= x;
|
||||
*this -= inv;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline basic_chset<CharT>&
|
||||
basic_chset<CharT>::operator-=(basic_chset<CharT> const& x)
|
||||
{
|
||||
typedef typename utility::impl::range_run<CharT>::const_iterator const_iterator;
|
||||
for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
|
||||
rr.clear(*iter);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline basic_chset<CharT>&
|
||||
basic_chset<CharT>::operator^=(basic_chset<CharT> const& x)
|
||||
{
|
||||
basic_chset bma = x;
|
||||
bma -= *this;
|
||||
*this -= x;
|
||||
*this |= bma;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if (CHAR_BIT == 8)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// basic_chset: specializations for 8 bit chars using std::bitset
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline basic_chset_8bit<CharT>::basic_chset_8bit() {}
|
||||
|
||||
/////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline basic_chset_8bit<CharT>::basic_chset_8bit(basic_chset_8bit const& arg_)
|
||||
: bset(arg_.bset) {}
|
||||
|
||||
/////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
basic_chset_8bit<CharT>::test(CharT v) const
|
||||
{ return bset.test((unsigned char)v); }
|
||||
|
||||
/////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline void
|
||||
basic_chset_8bit<CharT>::set(CharT from, CharT to)
|
||||
{
|
||||
for (int i = from; i <= to; ++i)
|
||||
bset.set((unsigned char)i);
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline void
|
||||
basic_chset_8bit<CharT>::set(CharT c)
|
||||
{ bset.set((unsigned char)c); }
|
||||
|
||||
/////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline void
|
||||
basic_chset_8bit<CharT>::clear(CharT from, CharT to)
|
||||
{
|
||||
for (int i = from; i <= to; ++i)
|
||||
bset.reset((unsigned char)i);
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline void
|
||||
basic_chset_8bit<CharT>::clear(CharT c)
|
||||
{ bset.reset((unsigned char)c); }
|
||||
|
||||
/////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline void
|
||||
basic_chset_8bit<CharT>::clear()
|
||||
{ bset.reset(); }
|
||||
|
||||
/////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline void
|
||||
basic_chset_8bit<CharT>::inverse()
|
||||
{ bset.flip(); }
|
||||
|
||||
/////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline void
|
||||
basic_chset_8bit<CharT>::swap(basic_chset_8bit& x)
|
||||
{ std::swap(bset, x.bset); }
|
||||
|
||||
/////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline basic_chset_8bit<CharT>&
|
||||
basic_chset_8bit<CharT>::operator|=(basic_chset_8bit const& x)
|
||||
{
|
||||
bset |= x.bset;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline basic_chset_8bit<CharT>&
|
||||
basic_chset_8bit<CharT>::operator&=(basic_chset_8bit const& x)
|
||||
{
|
||||
bset &= x.bset;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline basic_chset_8bit<CharT>&
|
||||
basic_chset_8bit<CharT>::operator-=(basic_chset_8bit const& x)
|
||||
{
|
||||
bset &= ~x.bset;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline basic_chset_8bit<CharT>&
|
||||
basic_chset_8bit<CharT>::operator^=(basic_chset_8bit const& x)
|
||||
{
|
||||
bset ^= x.bset;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
|
111
boost/boost/spirit/utility/impl/chset/range_run.hpp
Normal file
111
boost/boost/spirit/utility/impl/chset/range_run.hpp
Normal file
@ -0,0 +1,111 @@
|
||||
/*=============================================================================
|
||||
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_RANGE_RUN_HPP
|
||||
#define BOOST_SPIRIT_RANGE_RUN_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <vector>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace utility { namespace impl {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// range class
|
||||
//
|
||||
// Implements a closed range of values. This class is used in
|
||||
// the implementation of the range_run class.
|
||||
//
|
||||
// { Low level implementation detail }
|
||||
// { Not to be confused with boost::spirit::range }
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
struct range {
|
||||
|
||||
range(CharT first, CharT last);
|
||||
|
||||
bool is_valid() const;
|
||||
bool includes(CharT v) const;
|
||||
bool includes(range const& r) const;
|
||||
bool overlaps(range const& r) const;
|
||||
void merge(range const& r);
|
||||
|
||||
CharT first;
|
||||
CharT last;
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
struct range_char_compare {
|
||||
|
||||
bool operator()(range<CharT> const& x, const CharT y) const
|
||||
{ return x.first < y; }
|
||||
|
||||
bool operator()(const CharT x, range<CharT> const& y) const
|
||||
{ return x < y.first; }
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
struct range_compare {
|
||||
|
||||
bool operator()(range<CharT> const& x, range<CharT> const& y) const
|
||||
{ return x.first < y.first; }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// range_run
|
||||
//
|
||||
// An implementation of a sparse bit (boolean) set. The set uses
|
||||
// a sorted vector of disjoint ranges. This class implements the
|
||||
// bare minimum essentials from which the full range of set
|
||||
// operators can be implemented. The set is constructed from
|
||||
// ranges. Internally, adjacent or overlapping ranges are
|
||||
// coalesced.
|
||||
//
|
||||
// range_runs are very space-economical in situations where there
|
||||
// are lots of ranges and a few individual disjoint values.
|
||||
// Searching is O(log n) where n is the number of ranges.
|
||||
//
|
||||
// { Low level implementation detail }
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
class range_run {
|
||||
|
||||
public:
|
||||
|
||||
typedef range<CharT> range_t;
|
||||
typedef std::vector<range_t> run_t;
|
||||
typedef typename run_t::iterator iterator;
|
||||
typedef typename run_t::const_iterator const_iterator;
|
||||
|
||||
void swap(range_run& rr);
|
||||
bool test(CharT v) const;
|
||||
void set(range_t const& r);
|
||||
void clear(range_t const& r);
|
||||
void clear();
|
||||
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
|
||||
private:
|
||||
|
||||
void merge(iterator iter, range_t const& r);
|
||||
|
||||
run_t run;
|
||||
};
|
||||
|
||||
}}}} // namespace boost::spirit::utility::impl
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/utility/impl/chset/range_run.ipp>
|
212
boost/boost/spirit/utility/impl/chset/range_run.ipp
Normal file
212
boost/boost/spirit/utility/impl/chset/range_run.ipp
Normal file
@ -0,0 +1,212 @@
|
||||
/*=============================================================================
|
||||
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_RANGE_RUN_IPP
|
||||
#define BOOST_SPIRIT_RANGE_RUN_IPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <algorithm> // for std::lower_bound
|
||||
#include <boost/spirit/core/assert.hpp> // for BOOST_SPIRIT_ASSERT
|
||||
#include <boost/spirit/utility/impl/chset/range_run.hpp>
|
||||
#include <boost/spirit/debug.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
namespace utility { namespace impl {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// range class implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline range<CharT>::range(CharT first_, CharT last_)
|
||||
: first(first_), last(last_) {}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
range<CharT>::is_valid() const
|
||||
{ return first <= last; }
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
range<CharT>::includes(range const& r) const
|
||||
{ return (first <= r.first) && (last >= r.last); }
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
range<CharT>::includes(CharT v) const
|
||||
{ return (first <= v) && (last >= v); }
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
range<CharT>::overlaps(range const& r) const
|
||||
{
|
||||
CharT decr_first =
|
||||
first == (std::numeric_limits<CharT>::min)() ? first : first-1;
|
||||
CharT incr_last =
|
||||
last == (std::numeric_limits<CharT>::max)() ? last : last+1;
|
||||
|
||||
return (decr_first <= r.last) && (incr_last >= r.first);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline void
|
||||
range<CharT>::merge(range const& r)
|
||||
{
|
||||
first = (std::min)(first, r.first);
|
||||
last = (std::max)(last, r.last);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// range_run class implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
range_run<CharT>::test(CharT v) const
|
||||
{
|
||||
if (!run.empty())
|
||||
{
|
||||
const_iterator iter =
|
||||
std::lower_bound(
|
||||
run.begin(), run.end(), v,
|
||||
range_char_compare<CharT>()
|
||||
);
|
||||
|
||||
if (iter != run.end() && iter->includes(v))
|
||||
return true;
|
||||
if (iter != run.begin())
|
||||
return (--iter)->includes(v);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline void
|
||||
range_run<CharT>::swap(range_run& rr)
|
||||
{ run.swap(rr.run); }
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
void
|
||||
range_run<CharT>::merge(iterator iter, range<CharT> const& r)
|
||||
{
|
||||
iter->merge(r);
|
||||
iterator i = iter + 1;
|
||||
|
||||
while (i != run.end() && iter->overlaps(*i))
|
||||
iter->merge(*i++);
|
||||
|
||||
run.erase(iter+1, i);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
void
|
||||
range_run<CharT>::set(range<CharT> const& r)
|
||||
{
|
||||
BOOST_SPIRIT_ASSERT(r.is_valid());
|
||||
if (!run.empty())
|
||||
{
|
||||
iterator iter =
|
||||
std::lower_bound(
|
||||
run.begin(), run.end(), r,
|
||||
range_compare<CharT>()
|
||||
);
|
||||
|
||||
if (iter != run.end() && iter->includes(r) ||
|
||||
((iter != run.begin()) && (iter - 1)->includes(r)))
|
||||
return;
|
||||
|
||||
if (iter != run.begin() && (iter - 1)->overlaps(r))
|
||||
merge(--iter, r);
|
||||
|
||||
else if (iter != run.end() && iter->overlaps(r))
|
||||
merge(iter, r);
|
||||
|
||||
else
|
||||
run.insert(iter, r);
|
||||
}
|
||||
else
|
||||
{
|
||||
run.push_back(r);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
void
|
||||
range_run<CharT>::clear(range<CharT> const& r)
|
||||
{
|
||||
BOOST_SPIRIT_ASSERT(r.is_valid());
|
||||
if (!run.empty())
|
||||
{
|
||||
iterator iter =
|
||||
std::lower_bound(
|
||||
run.begin(), run.end(), r,
|
||||
range_compare<CharT>()
|
||||
);
|
||||
|
||||
iterator left_iter;
|
||||
|
||||
if ((iter != run.begin()) &&
|
||||
(left_iter = (iter - 1))->includes(r.first))
|
||||
if (left_iter->last > r.last)
|
||||
{
|
||||
CharT save_last = left_iter->last;
|
||||
left_iter->last = r.first-1;
|
||||
run.insert(iter, range<CharT>(r.last+1, save_last));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
left_iter->last = r.first-1;
|
||||
}
|
||||
|
||||
iterator i = iter;
|
||||
while (i != run.end() && r.includes(*i))
|
||||
i++;
|
||||
if (i != run.end() && i->includes(r.last))
|
||||
i->first = r.last+1;
|
||||
run.erase(iter, i);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline void
|
||||
range_run<CharT>::clear()
|
||||
{ run.clear(); }
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline typename range_run<CharT>::const_iterator
|
||||
range_run<CharT>::begin() const
|
||||
{ return run.begin(); }
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline typename range_run<CharT>::const_iterator
|
||||
range_run<CharT>::end() const
|
||||
{ return run.end(); }
|
||||
|
||||
}} // namespace utility::impl
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
662
boost/boost/spirit/utility/impl/chset_operators.ipp
Normal file
662
boost/boost/spirit/utility/impl/chset_operators.ipp
Normal file
@ -0,0 +1,662 @@
|
||||
/*=============================================================================
|
||||
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_CHSET_OPERATORS_IPP
|
||||
#define BOOST_SPIRIT_CHSET_OPERATORS_IPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/limits.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// chset free operators implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator|(chset<CharT> const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) |= b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator-(chset<CharT> const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) -= b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator~(chset<CharT> const& a)
|
||||
{
|
||||
return chset<CharT>(a).inverse();
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator&(chset<CharT> const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) &= b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator^(chset<CharT> const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) ^= b;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// range <--> chset free operators implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator|(chset<CharT> const& a, range<CharT> const& b)
|
||||
{
|
||||
chset<CharT> a_(a);
|
||||
a_.set(b);
|
||||
return a_;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator&(chset<CharT> const& a, range<CharT> const& b)
|
||||
{
|
||||
chset<CharT> a_(a);
|
||||
if(b.first != (std::numeric_limits<CharT>::min)()) {
|
||||
a_.clear(range<CharT>((std::numeric_limits<CharT>::min)(), b.first - 1));
|
||||
}
|
||||
if(b.last != (std::numeric_limits<CharT>::max)()) {
|
||||
a_.clear(range<CharT>(b.last + 1, (std::numeric_limits<CharT>::max)()));
|
||||
}
|
||||
return a_;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator-(chset<CharT> const& a, range<CharT> const& b)
|
||||
{
|
||||
chset<CharT> a_(a);
|
||||
a_.clear(b);
|
||||
return a_;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator^(chset<CharT> const& a, range<CharT> const& b)
|
||||
{
|
||||
return a ^ chset<CharT>(b);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator|(range<CharT> const& a, chset<CharT> const& b)
|
||||
{
|
||||
chset<CharT> b_(b);
|
||||
b_.set(a);
|
||||
return b_;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator&(range<CharT> const& a, chset<CharT> const& b)
|
||||
{
|
||||
chset<CharT> b_(b);
|
||||
if(a.first != (std::numeric_limits<CharT>::min)()) {
|
||||
b_.clear(range<CharT>((std::numeric_limits<CharT>::min)(), a.first - 1));
|
||||
}
|
||||
if(a.last != (std::numeric_limits<CharT>::max)()) {
|
||||
b_.clear(range<CharT>(a.last + 1, (std::numeric_limits<CharT>::max)()));
|
||||
}
|
||||
return b_;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator-(range<CharT> const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) - b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator^(range<CharT> const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) ^ b;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// literal primitives <--> chset free operators implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator|(chset<CharT> const& a, CharT b)
|
||||
{
|
||||
return a | chset<CharT>(b);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator&(chset<CharT> const& a, CharT b)
|
||||
{
|
||||
return a & chset<CharT>(b);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator-(chset<CharT> const& a, CharT b)
|
||||
{
|
||||
return a - chset<CharT>(b);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator^(chset<CharT> const& a, CharT b)
|
||||
{
|
||||
return a ^ chset<CharT>(b);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator|(CharT a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) | b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator&(CharT a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) & b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator-(CharT a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) - b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator^(CharT a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) ^ b;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// chlit <--> chset free operators implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator|(chset<CharT> const& a, chlit<CharT> const& b)
|
||||
{
|
||||
return a | chset<CharT>(b.ch);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator&(chset<CharT> const& a, chlit<CharT> const& b)
|
||||
{
|
||||
return a & chset<CharT>(b.ch);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator-(chset<CharT> const& a, chlit<CharT> const& b)
|
||||
{
|
||||
return a - chset<CharT>(b.ch);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator^(chset<CharT> const& a, chlit<CharT> const& b)
|
||||
{
|
||||
return a ^ chset<CharT>(b.ch);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator|(chlit<CharT> const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a.ch) | b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator&(chlit<CharT> const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a.ch) & b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator-(chlit<CharT> const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a.ch) - b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator^(chlit<CharT> const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a.ch) ^ b;
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// negated_char_parser <--> chset free operators implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT, typename ParserT>
|
||||
inline chset<CharT>
|
||||
operator|(chset<CharT> const& a, negated_char_parser<ParserT> const& b)
|
||||
{
|
||||
return a | chset<CharT>(b);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT, typename ParserT>
|
||||
inline chset<CharT>
|
||||
operator&(chset<CharT> const& a, negated_char_parser<ParserT> const& b)
|
||||
{
|
||||
return a & chset<CharT>(b);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT, typename ParserT>
|
||||
inline chset<CharT>
|
||||
operator-(chset<CharT> const& a, negated_char_parser<ParserT> const& b)
|
||||
{
|
||||
return a - chset<CharT>(b);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT, typename ParserT>
|
||||
inline chset<CharT>
|
||||
operator^(chset<CharT> const& a, negated_char_parser<ParserT> const& b)
|
||||
{
|
||||
return a ^ chset<CharT>(b);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT, typename ParserT>
|
||||
inline chset<CharT>
|
||||
operator|(negated_char_parser<ParserT> const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) | b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT, typename ParserT>
|
||||
inline chset<CharT>
|
||||
operator&(negated_char_parser<ParserT> const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) & b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT, typename ParserT>
|
||||
inline chset<CharT>
|
||||
operator-(negated_char_parser<ParserT> const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) - b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT, typename ParserT>
|
||||
inline chset<CharT>
|
||||
operator^(negated_char_parser<ParserT> const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) ^ b;
|
||||
}
|
||||
|
||||
#else // BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// negated_char_parser<range> <--> chset free operators implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator|(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b)
|
||||
{
|
||||
return a | chset<CharT>(b);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator&(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b)
|
||||
{
|
||||
return a & chset<CharT>(b);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator-(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b)
|
||||
{
|
||||
return a - chset<CharT>(b);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator^(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b)
|
||||
{
|
||||
return a ^ chset<CharT>(b);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator|(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) | b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator&(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) & b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator-(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) - b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator^(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) ^ b;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// negated_char_parser<chlit> <--> chset free operators implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator|(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b)
|
||||
{
|
||||
return a | chset<CharT>(b);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator&(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b)
|
||||
{
|
||||
return a & chset<CharT>(b);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator-(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b)
|
||||
{
|
||||
return a - chset<CharT>(b);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator^(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b)
|
||||
{
|
||||
return a ^ chset<CharT>(b);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator|(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) | b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator&(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) & b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator-(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) - b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator^(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b)
|
||||
{
|
||||
return chset<CharT>(a) ^ b;
|
||||
}
|
||||
|
||||
#endif // BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// anychar_parser <--> chset free operators
|
||||
//
|
||||
// Where a is chset and b is a anychar_parser, and vice-versa, implements:
|
||||
//
|
||||
// a | b, a & b, a - b, a ^ b
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace impl {
|
||||
|
||||
template <typename CharT>
|
||||
inline boost::spirit::range<CharT> const&
|
||||
full()
|
||||
{
|
||||
static boost::spirit::range<CharT> full_(
|
||||
(std::numeric_limits<CharT>::min)(),
|
||||
(std::numeric_limits<CharT>::max)());
|
||||
return full_;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline boost::spirit::range<CharT> const&
|
||||
empty()
|
||||
{
|
||||
static boost::spirit::range<CharT> empty_;
|
||||
return empty_;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator|(chset<CharT> const&, anychar_parser)
|
||||
{
|
||||
return chset<CharT>(impl::full<CharT>());
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator&(chset<CharT> const& a, anychar_parser)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator-(chset<CharT> const&, anychar_parser)
|
||||
{
|
||||
return chset<CharT>();
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator^(chset<CharT> const& a, anychar_parser)
|
||||
{
|
||||
return ~a;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator|(anychar_parser, chset<CharT> const& /*b*/)
|
||||
{
|
||||
return chset<CharT>(impl::full<CharT>());
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator&(anychar_parser, chset<CharT> const& b)
|
||||
{
|
||||
return b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator-(anychar_parser, chset<CharT> const& b)
|
||||
{
|
||||
return ~b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator^(anychar_parser, chset<CharT> const& b)
|
||||
{
|
||||
return ~b;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// nothing_parser <--> chset free operators implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator|(chset<CharT> const& a, nothing_parser)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator&(chset<CharT> const& /*a*/, nothing_parser)
|
||||
{
|
||||
return impl::empty<CharT>();
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator-(chset<CharT> const& a, nothing_parser)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator^(chset<CharT> const& a, nothing_parser)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator|(nothing_parser, chset<CharT> const& b)
|
||||
{
|
||||
return b;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator&(nothing_parser, chset<CharT> const& /*b*/)
|
||||
{
|
||||
return impl::empty<CharT>();
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator-(nothing_parser, chset<CharT> const& /*b*/)
|
||||
{
|
||||
return impl::empty<CharT>();
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
inline chset<CharT>
|
||||
operator^(nothing_parser, chset<CharT> const& b)
|
||||
{
|
||||
return b;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
|
217
boost/boost/spirit/utility/impl/confix.ipp
Normal file
217
boost/boost/spirit/utility/impl/confix.ipp
Normal file
@ -0,0 +1,217 @@
|
||||
/*=============================================================================
|
||||
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_CONFIX_IPP
|
||||
#define BOOST_SPIRIT_CONFIX_IPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/spirit/meta/refactoring.hpp>
|
||||
#include <boost/spirit/core/composite/impl/directives.ipp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Types to distinguish nested and non-nested confix parsers
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct is_nested {};
|
||||
struct non_nested {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Types to distinguish between confix parsers, which are implicitly lexems
|
||||
// and without this behaviour
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct is_lexeme {};
|
||||
struct non_lexeme {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// confix_parser_type class implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace impl {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// implicitly insert a lexeme_d into the parsing process
|
||||
|
||||
template <typename LexemeT>
|
||||
struct select_confix_parse_lexeme;
|
||||
|
||||
template <>
|
||||
struct select_confix_parse_lexeme<is_lexeme> {
|
||||
|
||||
template <typename ParserT, typename ScannerT>
|
||||
static typename parser_result<ParserT, ScannerT>::type
|
||||
parse(ParserT const& p, ScannerT const& scan)
|
||||
{
|
||||
typedef typename parser_result<ParserT, ScannerT>::type result_t;
|
||||
return contiguous_parser_parse<result_t>(p, scan, scan);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct select_confix_parse_lexeme<non_lexeme> {
|
||||
|
||||
template <typename ParserT, typename ScannerT>
|
||||
static typename parser_result<ParserT, ScannerT>::type
|
||||
parse(ParserT const& p, ScannerT const& scan)
|
||||
{
|
||||
return p.parse(scan);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// parse confix sequences with refactoring
|
||||
|
||||
template <typename NestedT>
|
||||
struct select_confix_parse_refactor;
|
||||
|
||||
template <>
|
||||
struct select_confix_parse_refactor<is_nested> {
|
||||
|
||||
template <
|
||||
typename LexemeT, typename ParserT, typename ScannerT,
|
||||
typename OpenT, typename ExprT, typename CloseT
|
||||
>
|
||||
static typename parser_result<ParserT, ScannerT>::type
|
||||
parse(
|
||||
LexemeT const &, ParserT const& this_, ScannerT const& scan,
|
||||
OpenT const& open, ExprT const& expr, CloseT const& close)
|
||||
{
|
||||
typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
|
||||
const refactor_t refactor_body_d = refactor_t(refactor_unary_d);
|
||||
|
||||
return select_confix_parse_lexeme<LexemeT>::parse((
|
||||
open
|
||||
>> (this_ | refactor_body_d[expr - close])
|
||||
>> close
|
||||
), scan);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct select_confix_parse_refactor<non_nested> {
|
||||
|
||||
template <
|
||||
typename LexemeT, typename ParserT, typename ScannerT,
|
||||
typename OpenT, typename ExprT, typename CloseT
|
||||
>
|
||||
static typename parser_result<ParserT, ScannerT>::type
|
||||
parse(
|
||||
LexemeT const &, ParserT const& /*this_*/, ScannerT const& scan,
|
||||
OpenT const& open, ExprT const& expr, CloseT const& close)
|
||||
{
|
||||
typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
|
||||
const refactor_t refactor_body_d = refactor_t(refactor_unary_d);
|
||||
|
||||
return select_confix_parse_lexeme<LexemeT>::parse((
|
||||
open
|
||||
>> refactor_body_d[expr - close]
|
||||
>> close
|
||||
), scan);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// parse confix sequences without refactoring
|
||||
|
||||
template <typename NestedT>
|
||||
struct select_confix_parse_no_refactor;
|
||||
|
||||
template <>
|
||||
struct select_confix_parse_no_refactor<is_nested> {
|
||||
|
||||
template <
|
||||
typename LexemeT, typename ParserT, typename ScannerT,
|
||||
typename OpenT, typename ExprT, typename CloseT
|
||||
>
|
||||
static typename parser_result<ParserT, ScannerT>::type
|
||||
parse(
|
||||
LexemeT const &, ParserT const& this_, ScannerT const& scan,
|
||||
OpenT const& open, ExprT const& expr, CloseT const& close)
|
||||
{
|
||||
return select_confix_parse_lexeme<LexemeT>::parse((
|
||||
open
|
||||
>> (this_ | (expr - close))
|
||||
>> close
|
||||
), scan);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct select_confix_parse_no_refactor<non_nested> {
|
||||
|
||||
template <
|
||||
typename LexemeT, typename ParserT, typename ScannerT,
|
||||
typename OpenT, typename ExprT, typename CloseT
|
||||
>
|
||||
static typename parser_result<ParserT, ScannerT>::type
|
||||
parse(
|
||||
LexemeT const &, ParserT const & /*this_*/, ScannerT const& scan,
|
||||
OpenT const& open, ExprT const& expr, CloseT const& close)
|
||||
{
|
||||
return select_confix_parse_lexeme<LexemeT>::parse((
|
||||
open
|
||||
>> (expr - close)
|
||||
>> close
|
||||
), scan);
|
||||
}
|
||||
};
|
||||
|
||||
// the refactoring is handled by the refactoring parsers, so here there
|
||||
// is no need to pay attention to these issues.
|
||||
|
||||
template <typename CategoryT>
|
||||
struct confix_parser_type {
|
||||
|
||||
template <
|
||||
typename NestedT, typename LexemeT,
|
||||
typename ParserT, typename ScannerT,
|
||||
typename OpenT, typename ExprT, typename CloseT
|
||||
>
|
||||
static typename parser_result<ParserT, ScannerT>::type
|
||||
parse(
|
||||
NestedT const &, LexemeT const &lexeme,
|
||||
ParserT const& this_, ScannerT const& scan,
|
||||
OpenT const& open, ExprT const& expr, CloseT const& close)
|
||||
{
|
||||
return select_confix_parse_refactor<NestedT>::
|
||||
parse(lexeme, this_, scan, open, expr, close);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct confix_parser_type<plain_parser_category> {
|
||||
|
||||
template <
|
||||
typename NestedT, typename LexemeT,
|
||||
typename ParserT, typename ScannerT,
|
||||
typename OpenT, typename ExprT, typename CloseT
|
||||
>
|
||||
static typename parser_result<ParserT, ScannerT>::type
|
||||
parse(
|
||||
NestedT const &, LexemeT const &lexeme,
|
||||
ParserT const& this_, ScannerT const& scan,
|
||||
OpenT const& open, ExprT const& expr, CloseT const& close)
|
||||
{
|
||||
return select_confix_parse_no_refactor<NestedT>::
|
||||
parse(lexeme, this_, scan, open, expr, close);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
|
215
boost/boost/spirit/utility/impl/escape_char.ipp
Normal file
215
boost/boost/spirit/utility/impl/escape_char.ipp
Normal file
@ -0,0 +1,215 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2003 Daniel Nuffer
|
||||
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_ESCAPE_CHAR_IPP
|
||||
#define BOOST_SPIRIT_ESCAPE_CHAR_IPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// escape_char_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const unsigned long c_escapes = 1;
|
||||
const unsigned long lex_escapes = c_escapes << 1;
|
||||
|
||||
//////////////////////////////////
|
||||
namespace impl {
|
||||
|
||||
//////////////////////////////////
|
||||
#if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310))
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127)
|
||||
#endif
|
||||
template <unsigned long Flags, typename CharT>
|
||||
struct escape_char_action_parse {
|
||||
|
||||
template <typename ParserT, typename ScannerT>
|
||||
static typename parser_result<ParserT, ScannerT>::type
|
||||
parse(ScannerT const& scan, ParserT const &p)
|
||||
{
|
||||
// Actually decode the escape char.
|
||||
typedef CharT char_t;
|
||||
typedef typename ScannerT::iterator_t iterator_t;
|
||||
typedef typename parser_result<ParserT, ScannerT>::type result_t;
|
||||
|
||||
if (scan.first != scan.last) {
|
||||
|
||||
iterator_t save = scan.first;
|
||||
if (result_t hit = p.subject().parse(scan)) {
|
||||
|
||||
char_t unescaped;
|
||||
|
||||
scan.first = save;
|
||||
if (*scan.first == '\\') {
|
||||
|
||||
++scan.first;
|
||||
switch (*scan.first) {
|
||||
case 'b': unescaped = '\b'; ++scan.first; break;
|
||||
case 't': unescaped = '\t'; ++scan.first; break;
|
||||
case 'n': unescaped = '\n'; ++scan.first; break;
|
||||
case 'f': unescaped = '\f'; ++scan.first; break;
|
||||
case 'r': unescaped = '\r'; ++scan.first; break;
|
||||
case '"': unescaped = '"'; ++scan.first; break;
|
||||
case '\'': unescaped = '\''; ++scan.first; break;
|
||||
case '\\': unescaped = '\\'; ++scan.first; break;
|
||||
|
||||
case 'x': case 'X':
|
||||
{
|
||||
char_t hex = 0;
|
||||
char_t const lim =
|
||||
(std::numeric_limits<char_t>::max)() >> 4;
|
||||
|
||||
++scan.first;
|
||||
while (scan.first != scan.last)
|
||||
{
|
||||
char_t c = *scan.first;
|
||||
if (hex > lim && impl::isxdigit_(c))
|
||||
{
|
||||
// overflow detected
|
||||
scan.first = save;
|
||||
return scan.no_match();
|
||||
}
|
||||
if (impl::isdigit_(c))
|
||||
{
|
||||
hex <<= 4;
|
||||
hex |= c - '0';
|
||||
++scan.first;
|
||||
}
|
||||
else if (impl::isxdigit_(c))
|
||||
{
|
||||
hex <<= 4;
|
||||
c = impl::toupper_(c);
|
||||
hex |= c - 'A' + 0xA;
|
||||
++scan.first;
|
||||
}
|
||||
else
|
||||
{
|
||||
break; // reached the end of the number
|
||||
}
|
||||
}
|
||||
unescaped = hex;
|
||||
}
|
||||
break;
|
||||
|
||||
case '0': case '1': case '2': case '3':
|
||||
case '4': case '5': case '6': case '7':
|
||||
{
|
||||
char_t oct = 0;
|
||||
char_t const lim =
|
||||
(std::numeric_limits<char_t>::max)() >> 3;
|
||||
while (scan.first != scan.last)
|
||||
{
|
||||
char_t c = *scan.first;
|
||||
if (oct > lim && (c >= '0' && c <= '7'))
|
||||
{
|
||||
// overflow detected
|
||||
scan.first = save;
|
||||
return scan.no_match();
|
||||
}
|
||||
|
||||
if (c >= '0' && c <= '7')
|
||||
{
|
||||
oct <<= 3;
|
||||
oct |= c - '0';
|
||||
++scan.first;
|
||||
}
|
||||
else
|
||||
{
|
||||
break; // reached end of digits
|
||||
}
|
||||
}
|
||||
unescaped = oct;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (Flags & c_escapes)
|
||||
{
|
||||
// illegal C escape sequence
|
||||
scan.first = save;
|
||||
return scan.no_match();
|
||||
}
|
||||
else
|
||||
{
|
||||
unescaped = *scan.first;
|
||||
++scan.first;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
unescaped = *scan.first;
|
||||
++scan.first;
|
||||
}
|
||||
|
||||
scan.do_action(p.predicate(), unescaped, save, scan.first);
|
||||
return hit;
|
||||
}
|
||||
}
|
||||
return scan.no_match(); // overflow detected
|
||||
}
|
||||
};
|
||||
#if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310))
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename CharT>
|
||||
struct escape_char_parse {
|
||||
|
||||
template <typename ScannerT, typename ParserT>
|
||||
static typename parser_result<ParserT, ScannerT>::type
|
||||
parse(ScannerT const &scan, ParserT const &/*p*/)
|
||||
{
|
||||
typedef
|
||||
uint_parser<CharT, 8, 1,
|
||||
std::numeric_limits<CharT>::digits / 3 + 1
|
||||
>
|
||||
oct_parser_t;
|
||||
typedef
|
||||
uint_parser<CharT, 16, 1,
|
||||
std::numeric_limits<CharT>::digits / 4 + 1
|
||||
>
|
||||
hex_parser_t;
|
||||
|
||||
typedef alternative<difference<anychar_parser, chlit<CharT> >,
|
||||
sequence<chlit<CharT>, alternative<alternative<oct_parser_t,
|
||||
sequence<inhibit_case<chlit<CharT> >, hex_parser_t > >,
|
||||
difference<difference<anychar_parser,
|
||||
inhibit_case<chlit<CharT> > >, oct_parser_t > > > >
|
||||
parser_t;
|
||||
|
||||
static parser_t p =
|
||||
( (anychar_p - chlit<CharT>(CharT('\\')))
|
||||
| (chlit<CharT>(CharT('\\')) >>
|
||||
( oct_parser_t()
|
||||
| as_lower_d[chlit<CharT>(CharT('x'))] >> hex_parser_t()
|
||||
| (anychar_p - as_lower_d[chlit<CharT>(CharT('x'))] - oct_parser_t())
|
||||
)
|
||||
));
|
||||
|
||||
BOOST_SPIRIT_DEBUG_TRACE_NODE(p,
|
||||
(BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_ESCAPE_CHAR) != 0);
|
||||
|
||||
return p.parse(scan);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace impl
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
|
164
boost/boost/spirit/utility/impl/lists.ipp
Normal file
164
boost/boost/spirit/utility/impl/lists.ipp
Normal file
@ -0,0 +1,164 @@
|
||||
/*=============================================================================
|
||||
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_LISTS_IPP
|
||||
#define BOOST_SPIRIT_LISTS_IPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/spirit/meta/refactoring.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// list_parser_type class implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct no_list_endtoken { typedef no_list_endtoken embed_t; };
|
||||
|
||||
namespace impl {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Refactor the original list item parser
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// match list with 'extended' syntax
|
||||
template <typename EndT>
|
||||
struct select_list_parse_refactor {
|
||||
|
||||
template <
|
||||
typename ParserT, typename ScannerT,
|
||||
typename ItemT, typename DelimT
|
||||
>
|
||||
static typename parser_result<ParserT, ScannerT>::type
|
||||
parse(ScannerT const& scan, ParserT const& /*p*/,
|
||||
ItemT const &item, DelimT const &delim, EndT const &end)
|
||||
{
|
||||
typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
|
||||
const refactor_t refactor_item_d = refactor_t(refactor_unary_d);
|
||||
|
||||
return (
|
||||
refactor_item_d[item - (end | delim)]
|
||||
>> *(delim >> refactor_item_d[item - (end | delim)])
|
||||
>> !(delim >> end)
|
||||
).parse(scan);
|
||||
}
|
||||
};
|
||||
|
||||
// match list with 'normal' syntax (without an 'end' parser)
|
||||
template <>
|
||||
struct select_list_parse_refactor<no_list_endtoken> {
|
||||
|
||||
template <
|
||||
typename ParserT, typename ScannerT,
|
||||
typename ItemT, typename DelimT
|
||||
>
|
||||
static typename parser_result<ParserT, ScannerT>::type
|
||||
parse(ScannerT const& scan, ParserT const& /*p*/,
|
||||
ItemT const &item, DelimT const &delim, no_list_endtoken const&)
|
||||
{
|
||||
typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
|
||||
const refactor_t refactor_item_d = refactor_t(refactor_unary_d);
|
||||
|
||||
return (
|
||||
refactor_item_d[item - delim]
|
||||
>> *(delim >> refactor_item_d[item - delim])
|
||||
).parse(scan);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Do not refactor the original list item parser.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// match list with 'extended' syntax
|
||||
template <typename EndT>
|
||||
struct select_list_parse_no_refactor {
|
||||
|
||||
template <
|
||||
typename ParserT, typename ScannerT,
|
||||
typename ItemT, typename DelimT
|
||||
>
|
||||
static typename parser_result<ParserT, ScannerT>::type
|
||||
parse(ScannerT const& scan, ParserT const& /*p*/,
|
||||
ItemT const &item, DelimT const &delim, EndT const &end)
|
||||
{
|
||||
return (
|
||||
(item - (end | delim))
|
||||
>> *(delim >> (item - (end | delim)))
|
||||
>> !(delim >> end)
|
||||
).parse(scan);
|
||||
}
|
||||
};
|
||||
|
||||
// match list with 'normal' syntax (without an 'end' parser)
|
||||
template <>
|
||||
struct select_list_parse_no_refactor<no_list_endtoken> {
|
||||
|
||||
template <
|
||||
typename ParserT, typename ScannerT,
|
||||
typename ItemT, typename DelimT
|
||||
>
|
||||
static typename parser_result<ParserT, ScannerT>::type
|
||||
parse(ScannerT const& scan, ParserT const& /*p*/,
|
||||
ItemT const &item, DelimT const &delim, no_list_endtoken const&)
|
||||
{
|
||||
return (
|
||||
(item - delim)
|
||||
>> *(delim >> (item - delim))
|
||||
).parse(scan);
|
||||
}
|
||||
};
|
||||
|
||||
// the refactoring is handled by the refactoring parsers, so here there
|
||||
// is no need to pay attention to these issues.
|
||||
|
||||
template <typename CategoryT>
|
||||
struct list_parser_type {
|
||||
|
||||
template <
|
||||
typename ParserT, typename ScannerT,
|
||||
typename ItemT, typename DelimT, typename EndT
|
||||
>
|
||||
static typename parser_result<ParserT, ScannerT>::type
|
||||
parse(ScannerT const& scan, ParserT const& p,
|
||||
ItemT const &item, DelimT const &delim, EndT const &end)
|
||||
{
|
||||
return select_list_parse_refactor<EndT>::
|
||||
parse(scan, p, item, delim, end);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct list_parser_type<plain_parser_category> {
|
||||
|
||||
template <
|
||||
typename ParserT, typename ScannerT,
|
||||
typename ItemT, typename DelimT, typename EndT
|
||||
>
|
||||
static typename parser_result<ParserT, ScannerT>::type
|
||||
parse(ScannerT const& scan, ParserT const& p,
|
||||
ItemT const &item, DelimT const &delim, EndT const &end)
|
||||
{
|
||||
return select_list_parse_no_refactor<EndT>::
|
||||
parse(scan, p, item, delim, end);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
|
335
boost/boost/spirit/utility/lists.hpp
Normal file
335
boost/boost/spirit/utility/lists.hpp
Normal file
@ -0,0 +1,335 @@
|
||||
/*=============================================================================
|
||||
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_LISTS_HPP
|
||||
#define BOOST_SPIRIT_LISTS_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/spirit/meta/as_parser.hpp>
|
||||
#include <boost/spirit/core/parser.hpp>
|
||||
#include <boost/spirit/core/composite/composite.hpp>
|
||||
#include <boost/spirit/utility/impl/lists.ipp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// list_parser class
|
||||
//
|
||||
// List parsers allow to parse constructs like
|
||||
//
|
||||
// item >> *(delim >> item)
|
||||
//
|
||||
// where 'item' is an auxiliary expression to parse and 'delim' is an
|
||||
// auxiliary delimiter to parse.
|
||||
//
|
||||
// The list_parser class also can match an optional closing delimiter
|
||||
// represented by the 'end' parser at the end of the list:
|
||||
//
|
||||
// item >> *(delim >> item) >> !end.
|
||||
//
|
||||
// If ItemT is an action_parser_category type (parser with an attached
|
||||
// semantic action) we have to do something special. This happens, if the
|
||||
// user wrote something like:
|
||||
//
|
||||
// list_p(item[f], delim)
|
||||
//
|
||||
// where 'item' is the parser matching one item of the list sequence and
|
||||
// 'f' is a functor to be called after matching one item. If we would do
|
||||
// nothing, the resulting code would parse the sequence as follows:
|
||||
//
|
||||
// (item[f] - delim) >> *(delim >> (item[f] - delim))
|
||||
//
|
||||
// what in most cases is not what the user expects.
|
||||
// (If this _is_ what you've expected, then please use one of the list_p
|
||||
// generator functions 'direct()', which will inhibit re-attaching
|
||||
// the actor to the item parser).
|
||||
//
|
||||
// To make the list parser behave as expected:
|
||||
//
|
||||
// (item - delim)[f] >> *(delim >> (item - delim)[f])
|
||||
//
|
||||
// the actor attached to the 'item' parser has to be re-attached to the
|
||||
// *(item - delim) parser construct, which will make the resulting list
|
||||
// parser 'do the right thing'.
|
||||
//
|
||||
// Additionally special care must be taken, if the item parser is a
|
||||
// unary_parser_category type parser as
|
||||
//
|
||||
// list_p(*anychar_p, ',')
|
||||
//
|
||||
// which without any refactoring would result in
|
||||
//
|
||||
// (*anychar_p - ch_p(','))
|
||||
// >> *( ch_p(',') >> (*anychar_p - ch_p(',')) )
|
||||
//
|
||||
// and will not give the expected result (the first *anychar_p will eat up
|
||||
// all the input up to the end of the input stream). So we have to
|
||||
// refactor this into:
|
||||
//
|
||||
// *(anychar_p - ch_p(','))
|
||||
// >> *( ch_p(',') >> *(anychar_p - ch_p(',')) )
|
||||
//
|
||||
// what will give the correct result.
|
||||
//
|
||||
// The case, where the item parser is a combination of the two mentioned
|
||||
// problems (i.e. the item parser is a unary parser with an attached
|
||||
// action), is handled accordingly too:
|
||||
//
|
||||
// list_p((*anychar_p)[f], ',')
|
||||
//
|
||||
// will be parsed as expected:
|
||||
//
|
||||
// (*(anychar_p - ch_p(',')))[f]
|
||||
// >> *( ch_p(',') >> (*(anychar_p - ch_p(',')))[f] ).
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename ItemT, typename DelimT, typename EndT = no_list_endtoken,
|
||||
typename CategoryT = plain_parser_category
|
||||
>
|
||||
struct list_parser :
|
||||
public parser<list_parser<ItemT, DelimT, EndT, CategoryT> > {
|
||||
|
||||
typedef list_parser<ItemT, DelimT, EndT, CategoryT> self_t;
|
||||
typedef CategoryT parser_category_t;
|
||||
|
||||
list_parser(ItemT const &item_, DelimT const &delim_,
|
||||
EndT const& end_ = no_list_endtoken())
|
||||
: item(item_), delim(delim_), end(end_)
|
||||
{}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
return impl::list_parser_type<CategoryT>
|
||||
::parse(scan, *this, item, delim, end);
|
||||
}
|
||||
|
||||
private:
|
||||
typename as_parser<ItemT>::type::embed_t item;
|
||||
typename as_parser<DelimT>::type::embed_t delim;
|
||||
typename as_parser<EndT>::type::embed_t end;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// List parser generator template
|
||||
//
|
||||
// This is a helper for generating a correct list_parser<> from
|
||||
// auxiliary parameters. There are the following types supported as
|
||||
// parameters yet: parsers, single characters and strings (see
|
||||
// as_parser<> in meta/as_parser.hpp).
|
||||
//
|
||||
// The list_parser_gen by itself can be used for parsing comma separated
|
||||
// lists without item formatting:
|
||||
//
|
||||
// list_p.parse(...)
|
||||
// matches any comma separated list.
|
||||
//
|
||||
// If list_p is used with one parameter, this parameter is used to match
|
||||
// the delimiter:
|
||||
//
|
||||
// list_p(';').parse(...)
|
||||
// matches any semicolon separated list.
|
||||
//
|
||||
// If list_p is used with two parameters, the first parameter is used to
|
||||
// match the items and the second parameter matches the delimiters:
|
||||
//
|
||||
// list_p(uint_p, ',').parse(...)
|
||||
// matches comma separated unsigned integers.
|
||||
//
|
||||
// If list_p is used with three parameters, the first parameter is used
|
||||
// to match the items, the second one is used to match the delimiters and
|
||||
// the third one is used to match an optional ending token sequence:
|
||||
//
|
||||
// list_p(real_p, ';', eol_p).parse(...)
|
||||
// matches a semicolon separated list of real numbers optionally
|
||||
// followed by an end of line.
|
||||
//
|
||||
// The list_p in the previous examples denotes the predefined parser
|
||||
// generator, which should be used to define list parsers (see below).
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename CharT = char>
|
||||
struct list_parser_gen :
|
||||
public list_parser<kleene_star<anychar_parser>, chlit<CharT> >
|
||||
{
|
||||
typedef list_parser_gen<CharT> self_t;
|
||||
|
||||
// construct the list_parser_gen object as an list parser for comma separated
|
||||
// lists without item formatting.
|
||||
list_parser_gen()
|
||||
: list_parser<kleene_star<anychar_parser>, chlit<CharT> >
|
||||
(*anychar_p, chlit<CharT>(','))
|
||||
{}
|
||||
|
||||
// The following generator functions should be used under normal circumstances.
|
||||
// (the operator()(...) functions)
|
||||
|
||||
// Generic generator functions for creation of concrete list parsers, which
|
||||
// support 'normal' syntax:
|
||||
//
|
||||
// item >> *(delim >> item)
|
||||
//
|
||||
// If item isn't given, everything between two delimiters is matched.
|
||||
|
||||
template<typename DelimT>
|
||||
list_parser<
|
||||
kleene_star<anychar_parser>,
|
||||
typename as_parser<DelimT>::type,
|
||||
no_list_endtoken,
|
||||
unary_parser_category // there is no action to re-attach
|
||||
>
|
||||
operator()(DelimT const &delim_) const
|
||||
{
|
||||
typedef kleene_star<anychar_parser> item_t;
|
||||
typedef typename as_parser<DelimT>::type delim_t;
|
||||
|
||||
typedef
|
||||
list_parser<item_t, delim_t, no_list_endtoken, unary_parser_category>
|
||||
return_t;
|
||||
|
||||
return return_t(*anychar_p, as_parser<DelimT>::convert(delim_));
|
||||
}
|
||||
|
||||
template<typename ItemT, typename DelimT>
|
||||
list_parser<
|
||||
typename as_parser<ItemT>::type,
|
||||
typename as_parser<DelimT>::type,
|
||||
no_list_endtoken,
|
||||
typename as_parser<ItemT>::type::parser_category_t
|
||||
>
|
||||
operator()(ItemT const &item_, DelimT const &delim_) const
|
||||
{
|
||||
typedef typename as_parser<ItemT>::type item_t;
|
||||
typedef typename as_parser<DelimT>::type delim_t;
|
||||
typedef list_parser<item_t, delim_t, no_list_endtoken,
|
||||
BOOST_DEDUCED_TYPENAME item_t::parser_category_t>
|
||||
return_t;
|
||||
|
||||
return return_t(
|
||||
as_parser<ItemT>::convert(item_),
|
||||
as_parser<DelimT>::convert(delim_)
|
||||
);
|
||||
}
|
||||
|
||||
// Generic generator function for creation of concrete list parsers, which
|
||||
// support 'extended' syntax:
|
||||
//
|
||||
// item >> *(delim >> item) >> !end
|
||||
|
||||
template<typename ItemT, typename DelimT, typename EndT>
|
||||
list_parser<
|
||||
typename as_parser<ItemT>::type,
|
||||
typename as_parser<DelimT>::type,
|
||||
typename as_parser<EndT>::type,
|
||||
typename as_parser<ItemT>::type::parser_category_t
|
||||
>
|
||||
operator()(
|
||||
ItemT const &item_, DelimT const &delim_, EndT const &end_) const
|
||||
{
|
||||
typedef typename as_parser<ItemT>::type item_t;
|
||||
typedef typename as_parser<DelimT>::type delim_t;
|
||||
typedef typename as_parser<EndT>::type end_t;
|
||||
|
||||
typedef list_parser<item_t, delim_t, end_t,
|
||||
BOOST_DEDUCED_TYPENAME item_t::parser_category_t>
|
||||
return_t;
|
||||
|
||||
return return_t(
|
||||
as_parser<ItemT>::convert(item_),
|
||||
as_parser<DelimT>::convert(delim_),
|
||||
as_parser<EndT>::convert(end_)
|
||||
);
|
||||
}
|
||||
|
||||
// The following functions should be used, if the 'item' parser has an attached
|
||||
// semantic action or is a unary_parser_category type parser and the structure
|
||||
// of the resulting list parser should _not_ be refactored during parser
|
||||
// construction (see comment above).
|
||||
|
||||
// Generic generator function for creation of concrete list parsers, which
|
||||
// support 'normal' syntax:
|
||||
//
|
||||
// item >> *(delim >> item)
|
||||
|
||||
template<typename ItemT, typename DelimT>
|
||||
list_parser<
|
||||
typename as_parser<ItemT>::type,
|
||||
typename as_parser<DelimT>::type,
|
||||
no_list_endtoken,
|
||||
plain_parser_category // inhibit action re-attachment
|
||||
>
|
||||
direct(ItemT const &item_, DelimT const &delim_) const
|
||||
{
|
||||
typedef typename as_parser<ItemT>::type item_t;
|
||||
typedef typename as_parser<DelimT>::type delim_t;
|
||||
typedef list_parser<item_t, delim_t, no_list_endtoken,
|
||||
plain_parser_category>
|
||||
return_t;
|
||||
|
||||
return return_t(
|
||||
as_parser<ItemT>::convert(item_),
|
||||
as_parser<DelimT>::convert(delim_)
|
||||
);
|
||||
}
|
||||
|
||||
// Generic generator function for creation of concrete list parsers, which
|
||||
// support 'extended' syntax:
|
||||
//
|
||||
// item >> *(delim >> item) >> !end
|
||||
|
||||
template<typename ItemT, typename DelimT, typename EndT>
|
||||
list_parser<
|
||||
typename as_parser<ItemT>::type,
|
||||
typename as_parser<DelimT>::type,
|
||||
typename as_parser<EndT>::type,
|
||||
plain_parser_category // inhibit action re-attachment
|
||||
>
|
||||
direct(
|
||||
ItemT const &item_, DelimT const &delim_, EndT const &end_) const
|
||||
{
|
||||
typedef typename as_parser<ItemT>::type item_t;
|
||||
typedef typename as_parser<DelimT>::type delim_t;
|
||||
typedef typename as_parser<EndT>::type end_t;
|
||||
|
||||
typedef
|
||||
list_parser<item_t, delim_t, end_t, plain_parser_category>
|
||||
return_t;
|
||||
|
||||
return return_t(
|
||||
as_parser<ItemT>::convert(item_),
|
||||
as_parser<DelimT>::convert(delim_),
|
||||
as_parser<EndT>::convert(end_)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Predefined list parser generator
|
||||
//
|
||||
// The list_p parser generator can be used
|
||||
// - by itself for parsing comma separated lists without item formatting
|
||||
// or
|
||||
// - for generating list parsers with auxiliary parser parameters
|
||||
// for the 'item', 'delim' and 'end' subsequences.
|
||||
// (see comment above)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
const list_parser_gen<> list_p = list_parser_gen<>();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
313
boost/boost/spirit/utility/loops.hpp
Normal file
313
boost/boost/spirit/utility/loops.hpp
Normal file
@ -0,0 +1,313 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2002 Raghavendra Satish
|
||||
Copyright (c) 2002 Jeff Westfahl
|
||||
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_LOOPS_HPP)
|
||||
#define BOOST_SPIRIT_LOOPS_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/spirit/core/parser.hpp>
|
||||
#include <boost/spirit/core/composite/composite.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// fixed_loop class
|
||||
//
|
||||
// This class takes care of the construct:
|
||||
//
|
||||
// repeat_p (exact) [p]
|
||||
//
|
||||
// where 'p' is a parser and 'exact' is the number of times to
|
||||
// repeat. The parser iterates over the input exactly 'exact' times.
|
||||
// The parse function fails if the parser does not match the input
|
||||
// exactly 'exact' times.
|
||||
//
|
||||
// This class is parametizable and can accept constant arguments
|
||||
// (e.g. repeat_p (5) [p]) as well as references to variables (e.g.
|
||||
// repeat_p (ref (n)) [p]).
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename ParserT, typename ExactT>
|
||||
class fixed_loop
|
||||
: public unary<ParserT, parser <fixed_loop <ParserT, ExactT> > >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef fixed_loop<ParserT, ExactT> self_t;
|
||||
typedef unary<ParserT, parser<self_t> > base_t;
|
||||
|
||||
fixed_loop (ParserT const & subject, ExactT const & exact)
|
||||
: base_t(subject), m_exact(exact) {}
|
||||
|
||||
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 = scan.empty_match();
|
||||
std::size_t n = m_exact;
|
||||
|
||||
for (std::size_t i = 0; i < n; ++i)
|
||||
{
|
||||
if (result_t next = this->subject().parse(scan))
|
||||
{
|
||||
scan.concat_match(hit, next);
|
||||
}
|
||||
else
|
||||
{
|
||||
return scan.no_match();
|
||||
}
|
||||
}
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, nil_t>::type type;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
ExactT m_exact;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// finite_loop class
|
||||
//
|
||||
// This class takes care of the construct:
|
||||
//
|
||||
// repeat_p (min, max) [p]
|
||||
//
|
||||
// where 'p' is a parser, 'min' and 'max' specifies the minimum and
|
||||
// maximum iterations over 'p'. The parser iterates over the input
|
||||
// at least 'min' times and at most 'max' times. The parse function
|
||||
// fails if the parser does not match the input at least 'min' times
|
||||
// and at most 'max' times.
|
||||
//
|
||||
// This class is parametizable and can accept constant arguments
|
||||
// (e.g. repeat_p (5, 10) [p]) as well as references to variables
|
||||
// (e.g. repeat_p (ref (n1), ref (n2)) [p]).
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename ParserT, typename MinT, typename MaxT>
|
||||
class finite_loop
|
||||
: public unary<ParserT, parser<finite_loop<ParserT, MinT, MaxT> > >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef finite_loop <ParserT, MinT, MaxT> self_t;
|
||||
typedef unary<ParserT, parser<self_t> > base_t;
|
||||
|
||||
finite_loop (ParserT const & subject, MinT const & min, MaxT const & max)
|
||||
: base_t(subject), m_min(min), m_max(max) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result <self_t, ScannerT>::type
|
||||
parse(ScannerT const & scan) const
|
||||
{
|
||||
BOOST_SPIRIT_ASSERT(m_min <= m_max);
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
result_t hit = scan.empty_match();
|
||||
|
||||
std::size_t n1 = m_min;
|
||||
std::size_t n2 = m_max;
|
||||
|
||||
for (std::size_t i = 0; i < n2; ++i)
|
||||
{
|
||||
typename ScannerT::iterator_t save = scan.first;
|
||||
result_t next = this->subject().parse(scan);
|
||||
|
||||
if (!next)
|
||||
{
|
||||
if (i >= n1)
|
||||
{
|
||||
scan.first = save;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
return scan.no_match();
|
||||
}
|
||||
}
|
||||
|
||||
scan.concat_match(hit, next);
|
||||
}
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, nil_t>::type type;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
MinT m_min;
|
||||
MaxT m_max;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// infinite_loop class
|
||||
//
|
||||
// This class takes care of the construct:
|
||||
//
|
||||
// repeat_p (min, more) [p]
|
||||
//
|
||||
// where 'p' is a parser, 'min' is the minimum iteration over 'p'
|
||||
// and more specifies that the iteration should proceed
|
||||
// indefinitely. The parser iterates over the input at least 'min'
|
||||
// times and continues indefinitely until 'p' fails or all of the
|
||||
// input is parsed. The parse function fails if the parser does not
|
||||
// match the input at least 'min' times.
|
||||
//
|
||||
// This class is parametizable and can accept constant arguments
|
||||
// (e.g. repeat_p (5, more) [p]) as well as references to variables
|
||||
// (e.g. repeat_p (ref (n), more) [p]).
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct more_t {};
|
||||
more_t const more = more_t ();
|
||||
|
||||
template <typename ParserT, typename MinT>
|
||||
class infinite_loop
|
||||
: public unary<ParserT, parser<infinite_loop<ParserT, MinT> > >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef infinite_loop <ParserT, MinT> self_t;
|
||||
typedef unary<ParserT, parser<self_t> > base_t;
|
||||
|
||||
infinite_loop (
|
||||
ParserT const& subject,
|
||||
MinT const& min,
|
||||
more_t const&
|
||||
)
|
||||
: base_t(subject), m_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 = scan.empty_match();
|
||||
std::size_t n = m_min;
|
||||
|
||||
for (std::size_t i = 0; ; ++i)
|
||||
{
|
||||
typename ScannerT::iterator_t save = scan.first;
|
||||
result_t next = this->subject().parse(scan);
|
||||
|
||||
if (!next)
|
||||
{
|
||||
if (i >= n)
|
||||
{
|
||||
scan.first = save;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
return scan.no_match();
|
||||
}
|
||||
}
|
||||
|
||||
scan.concat_match(hit, next);
|
||||
}
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, nil_t>::type type;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
MinT m_min;
|
||||
};
|
||||
|
||||
template <typename ExactT>
|
||||
struct fixed_loop_gen
|
||||
{
|
||||
fixed_loop_gen (ExactT const & exact)
|
||||
: m_exact (exact) {}
|
||||
|
||||
template <typename ParserT>
|
||||
fixed_loop <ParserT, ExactT>
|
||||
operator[](parser <ParserT> const & subject) const
|
||||
{
|
||||
return fixed_loop <ParserT, ExactT> (subject.derived (), m_exact);
|
||||
}
|
||||
|
||||
ExactT m_exact;
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
|
||||
template <typename ParserT, typename MinT, typename MaxT>
|
||||
struct loop_traits
|
||||
{
|
||||
typedef typename mpl::if_<
|
||||
boost::is_same<MaxT, more_t>,
|
||||
infinite_loop<ParserT, MinT>,
|
||||
finite_loop<ParserT, MinT, MaxT>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
template <typename MinT, typename MaxT>
|
||||
struct nonfixed_loop_gen
|
||||
{
|
||||
nonfixed_loop_gen (MinT min, MaxT max)
|
||||
: m_min (min), m_max (max) {}
|
||||
|
||||
template <typename ParserT>
|
||||
typename impl::loop_traits<ParserT, MinT, MaxT>::type
|
||||
operator[](parser <ParserT> const & subject) const
|
||||
{
|
||||
typedef typename impl::loop_traits<ParserT, MinT, MaxT>::type ret_t;
|
||||
return ret_t(
|
||||
subject.derived(),
|
||||
m_min,
|
||||
m_max);
|
||||
}
|
||||
|
||||
MinT m_min;
|
||||
MaxT m_max;
|
||||
};
|
||||
|
||||
template <typename ExactT>
|
||||
fixed_loop_gen <ExactT>
|
||||
repeat_p(ExactT const & exact)
|
||||
{
|
||||
return fixed_loop_gen <ExactT> (exact);
|
||||
}
|
||||
|
||||
template <typename MinT, typename MaxT>
|
||||
nonfixed_loop_gen <MinT, MaxT>
|
||||
repeat_p(MinT const & min, MaxT const & max)
|
||||
{
|
||||
return nonfixed_loop_gen <MinT, MaxT> (min, max);
|
||||
}
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif // #if !defined(BOOST_SPIRIT_LOOPS_HPP)
|
108
boost/boost/spirit/utility/scoped_lock.hpp
Normal file
108
boost/boost/spirit/utility/scoped_lock.hpp
Normal file
@ -0,0 +1,108 @@
|
||||
/*=============================================================================
|
||||
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)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_UTILITY_SCOPED_LOCK_HPP
|
||||
#define BOOST_SPIRIT_UTILITY_SCOPED_LOCK_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(BOOST_SPIRIT_COMPOSITE_HPP)
|
||||
#include <boost/spirit/core/composite.hpp>
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// scoped_lock_parser class
|
||||
//
|
||||
// implements locking of a mutex during execution of
|
||||
// the parse method of an embedded parser
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename MutexT, typename ParserT>
|
||||
struct scoped_lock_parser
|
||||
: public unary< ParserT, parser< scoped_lock_parser<MutexT, ParserT> > >
|
||||
{
|
||||
typedef scoped_lock_parser<MutexT, ParserT> self_t;
|
||||
typedef MutexT mutex_t;
|
||||
typedef ParserT parser_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename parser_result<parser_t, ScannerT>::type type;
|
||||
};
|
||||
|
||||
scoped_lock_parser(mutex_t &m, parser_t const &p)
|
||||
: unary< ParserT, parser< scoped_lock_parser<MutexT, ParserT> > >(p)
|
||||
, mutex(m)
|
||||
{}
|
||||
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const &scan) const
|
||||
{
|
||||
typedef typename mutex_t::scoped_lock scoped_lock_t;
|
||||
scoped_lock_t lock(mutex);
|
||||
return this->subject().parse(scan);
|
||||
}
|
||||
|
||||
mutex_t &mutex;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// scoped_lock_parser_gen
|
||||
//
|
||||
// generator for scoped_lock_parser objects
|
||||
// operator[] returns scoped_lock_parser according to its argument
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename MutexT>
|
||||
struct scoped_lock_parser_gen
|
||||
{
|
||||
typedef MutexT mutex_t;
|
||||
explicit scoped_lock_parser_gen(mutex_t &m) : mutex(m) {}
|
||||
|
||||
template<typename ParserT>
|
||||
scoped_lock_parser
|
||||
<
|
||||
MutexT,
|
||||
typename as_parser<ParserT>::type
|
||||
>
|
||||
operator[](ParserT const &p) const
|
||||
{
|
||||
typedef ::boost::spirit::as_parser<ParserT> as_parser_t;
|
||||
typedef typename as_parser_t::type parser_t;
|
||||
|
||||
return scoped_lock_parser<mutex_t, parser_t>
|
||||
(mutex, as_parser_t::convert(p));
|
||||
}
|
||||
|
||||
mutex_t &mutex;
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// scoped_lock_d parser directive
|
||||
//
|
||||
// constructs a scoped_lock_parser generator from its argument
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename MutexT>
|
||||
scoped_lock_parser_gen<MutexT>
|
||||
scoped_lock_d(MutexT &mutex)
|
||||
{
|
||||
return scoped_lock_parser_gen<MutexT>(mutex);
|
||||
}
|
||||
|
||||
}} // namespace boost::spirit
|
||||
#endif // BOOST_SPIRIT_UTILITY_SCOPED_LOCK_HPP
|
31
boost/boost/spirit/version.hpp
Normal file
31
boost/boost/spirit/version.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
/*=============================================================================
|
||||
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(SPIRIT_VERSION_HPP)
|
||||
#define SPIRIT_VERSION_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This checks, whether the used Boost library is at least V1.32.0
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#if BOOST_VERSION < 103200
|
||||
#error "Spirit V1.8.1 needs at least Boost V1.32.0 to compile successfully."
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This is the version of the current Spirit distribution
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define SPIRIT_VERSION 0x1801
|
||||
#define SPIRIT_PIZZA_VERSION SPIRIT_FOUR_SEASONS // :-)
|
||||
|
||||
#endif // defined(SPIRIT_VERSION_HPP)
|
Loading…
Reference in New Issue
Block a user