first commit
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2008 Joel de Guzman
|
||||
Copyright (c) 2001-2008 Hartmut Kaiser
|
||||
Copyright (c) 2001-2003 Daniel Nuffer
|
||||
Copyright (c) 2002-2003 Martin Wille
|
||||
Copyright (c) 2002 Juan Carlos Arevalo-Baeza
|
||||
Copyright (c) 2002 Raghavendra Satish
|
||||
Copyright (c) 2002 Jeff Westfahl
|
||||
Copyright (c) 2001 Bruce Florman
|
||||
Copyright (c) 2003 Giovanni Bajo
|
||||
Copyright (c) 2003 Vaclav Vesely
|
||||
Copyright (c) 2003 Jonathan de Halleux
|
||||
http://spirit.sourceforge.net/
|
||||
http://www.boost.org/libs/spirit
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
See http://www.boost.org/libs/spirit for documentation
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_CLASSIC_APRIL_11_2008_0849AM)
|
||||
#define BOOST_SPIRIT_CLASSIC_APRIL_11_2008_0849AM
|
||||
|
||||
#include <boost/spirit/home/classic/core.hpp>
|
||||
#include <boost/spirit/home/classic/meta.hpp>
|
||||
#include <boost/spirit/home/classic/error_handling.hpp>
|
||||
#include <boost/spirit/home/classic/iterator.hpp>
|
||||
#include <boost/spirit/home/classic/symbols.hpp>
|
||||
#include <boost/spirit/home/classic/utility.hpp>
|
||||
#include <boost/spirit/home/classic/attribute.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,113 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_ACTOR_HPP
|
||||
#define BOOST_SPIRIT_ACTOR_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/version.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Actors documentation and convention
|
||||
//
|
||||
// Actors
|
||||
//
|
||||
// Actors are predefined semantic action functors. They are used to do an
|
||||
// action on the parse result if the parser has had a successful match. An
|
||||
// example of actor is the append_actor described in the Spirit
|
||||
// documentation.
|
||||
//
|
||||
// The action takes place through a call to the () operator: single argument
|
||||
// () operator call for character parsers and two argument (first,last) call
|
||||
// for phrase parsers. Actors should implement at least one of the two ()
|
||||
// operator.
|
||||
//
|
||||
// Actor instances are not created direcly since they usually involve a
|
||||
// number of template parameters. Instead generator functions ("helper
|
||||
// functions") are provided to generate actors according to their arguments.
|
||||
// All helper functions have the "_a" suffix. For example, append_actor is
|
||||
// created using the append_a function.
|
||||
//
|
||||
// Policy holder actors and policy actions
|
||||
//
|
||||
// A lot of actors need to store reference to one or more objects. For
|
||||
// example, actions on container need to store a reference to the container.
|
||||
// Therefore, this kind of actor have been broken down into
|
||||
//
|
||||
// - a action policy that does the action (act method),
|
||||
// - a policy holder actor that stores the references and feeds the act
|
||||
// method.
|
||||
//
|
||||
// Policy holder actors
|
||||
//
|
||||
// Policy holder have the following naming convention:
|
||||
// <member>_ >> *<member> >> !value >> actor
|
||||
// where member are the policy stored member, they can be of type:
|
||||
//
|
||||
// - ref, a reference,
|
||||
// - const_ref, a const reference,
|
||||
// - value, by value,
|
||||
// - empty, no stored members
|
||||
// - !value states if the policy uses the parse result or not.
|
||||
//
|
||||
// The available policy holder are enumerated below:
|
||||
//
|
||||
// - empty_actor, nothing stored, feeds parse result
|
||||
// - value_actor, 1 object stored by value, feeds value
|
||||
// - ref_actor, 1 reference stored, feeds ref
|
||||
// - ref_value_actor, 1 reference stored, feeds ref and parse result
|
||||
//
|
||||
// Doc. convention
|
||||
//
|
||||
// - ref is a reference to an object stored in a policy holder actor,
|
||||
// - value_ref,value1_ref, value2_ref are a const reference stored in a
|
||||
// policy holder actor,
|
||||
// - value is the parse result in the single argument () operator,
|
||||
// - first,last are the parse result in the two argument () operator
|
||||
//
|
||||
// Actors (generator functions) and quick description
|
||||
//
|
||||
// - assign_a(ref) assign parse result to ref
|
||||
// - assign_a(ref, value_ref) assign value_ref to ref
|
||||
// - increment_a(ref) increment ref
|
||||
// - decrement_a(ref) decrement ref
|
||||
// - push_back_a(ref) push back the parse result in ref
|
||||
// - push_back_a(ref, value_ref) push back value_ref in ref
|
||||
// - push_front_a(ref) push front the parse result in ref
|
||||
// - push_front_a(ref, value_ref) push front value_ref in ref
|
||||
// - insert_key_a(ref,value_ref) insert value_ref in ref using the
|
||||
// parse result as key
|
||||
// - insert_at_a(ref, key_ref) insert the parse result in ref at key_ref
|
||||
// - insert_at_a(ref, key_ref insert value_ref in ref at key_ref
|
||||
// , value_ref)
|
||||
// - assign_key_a(ref, value_ref) assign value_ref in ref using the
|
||||
// parse result as key
|
||||
// - erase_a(ref, key) erase data at key from ref
|
||||
// - clear_a(ref) clears ref
|
||||
// - swap_a(aref, bref) swaps aref and bref
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <boost/spirit/home/classic/actor/ref_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_value_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_const_ref_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_const_ref_value_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_const_ref_const_ref_a.hpp>
|
||||
|
||||
#include <boost/spirit/home/classic/actor/assign_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/clear_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/increment_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/decrement_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/push_back_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/push_front_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/erase_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/insert_key_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/insert_at_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/assign_key_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/swap_actor.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,100 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_ACTOR_ASSIGN_ACTOR_HPP
|
||||
#define BOOST_SPIRIT_ACTOR_ASSIGN_ACTOR_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_value_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_const_ref_actor.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 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_);
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,96 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_ACTOR_ASSIGN_KEY_ACTOR_HPP
|
||||
#define BOOST_SPIRIT_ACTOR_ASSIGN_KEY_ACTOR_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_const_ref_value_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_const_ref_const_ref_a.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
struct assign_key_action
|
||||
{
|
||||
template<
|
||||
typename T,
|
||||
typename ValueT,
|
||||
typename KeyT
|
||||
>
|
||||
void act(T& ref_, ValueT const& value_, KeyT const& key_) const
|
||||
{
|
||||
ref_[ key_ ] = value_;
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename ValueT,
|
||||
typename IteratorT
|
||||
>
|
||||
void act(
|
||||
T& ref_,
|
||||
ValueT const& value_,
|
||||
IteratorT const& first_,
|
||||
IteratorT const& last_
|
||||
) const
|
||||
{
|
||||
typedef typename T::key_type key_type;
|
||||
key_type key(first_,last_);
|
||||
|
||||
ref_[key] = value_;
|
||||
}
|
||||
};
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename ValueT
|
||||
>
|
||||
inline ref_const_ref_value_actor<T,ValueT,assign_key_action>
|
||||
assign_key_a(T& ref_, ValueT const& value_)
|
||||
{
|
||||
return ref_const_ref_value_actor<T,ValueT,assign_key_action>(
|
||||
ref_,
|
||||
value_
|
||||
);
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename ValueT,
|
||||
typename KeyT
|
||||
>
|
||||
inline ref_const_ref_const_ref_actor<
|
||||
T,
|
||||
ValueT,
|
||||
KeyT,
|
||||
assign_key_action
|
||||
>
|
||||
assign_key_a(
|
||||
T& ref_,
|
||||
ValueT const& value_,
|
||||
KeyT const& key_
|
||||
)
|
||||
{
|
||||
return ref_const_ref_const_ref_actor<
|
||||
T,
|
||||
ValueT,
|
||||
KeyT,
|
||||
assign_key_action
|
||||
>(
|
||||
ref_,
|
||||
value_,
|
||||
key_
|
||||
);
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,61 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_ACTOR_CLEAR_ACTOR_HPP
|
||||
#define BOOST_SPIRIT_ACTOR_CLEAR_ACTOR_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_actor.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Summary:
|
||||
// A semantic action policy that calls clear method.
|
||||
// (This doc uses convention available in actors.hpp)
|
||||
//
|
||||
// Actions (what it does):
|
||||
// ref.clear();
|
||||
//
|
||||
// Policy name:
|
||||
// clear_action
|
||||
//
|
||||
// Policy holder, corresponding helper method:
|
||||
// ref_actor, clear_a( ref );
|
||||
//
|
||||
// () operators: both.
|
||||
//
|
||||
// See also ref_actor for more details.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct clear_action
|
||||
{
|
||||
template<
|
||||
typename T
|
||||
>
|
||||
void act(T& ref_) const
|
||||
{
|
||||
ref_.clear();
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// helper method that creates a and_assign_actor.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
inline ref_actor<T,clear_action> clear_a(T& ref_)
|
||||
{
|
||||
return ref_actor<T,clear_action>(ref_);
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_ACTOR_DECREMENT_ACTOR_HPP
|
||||
#define BOOST_SPIRIT_ACTOR_DECREMENT_ACTOR_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_actor.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Summary:
|
||||
// A semantic action policy that calls the -- operator on a reference.
|
||||
// (This doc uses convention available in actors.hpp)
|
||||
//
|
||||
// Actions:
|
||||
// --ref;
|
||||
//
|
||||
// Policy name:
|
||||
// decrement_action
|
||||
//
|
||||
// Policy holder, corresponding helper method:
|
||||
// ref_actor, decrement_a( ref );
|
||||
//
|
||||
// () operators: both.
|
||||
//
|
||||
// See also ref_actor for more details.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct decrement_action
|
||||
{
|
||||
template<
|
||||
typename T
|
||||
>
|
||||
void act(T& ref_) const
|
||||
{
|
||||
--ref_;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// helper method that creates a and_assign_actor.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
inline ref_actor<T,decrement_action> decrement_a(T& ref_)
|
||||
{
|
||||
return ref_actor<T,decrement_action>(ref_);
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,89 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_ACTOR_ERASE_ACTOR_HPP
|
||||
#define BOOST_SPIRIT_ACTOR_ERASE_ACTOR_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_value_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_const_ref_actor.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Summary:
|
||||
// A semantic action policy that calss the erase method.
|
||||
// (This doc uses convention available in actors.hpp)
|
||||
//
|
||||
// Actions (what it does):
|
||||
// ref.erase( value );
|
||||
// ref.erase( T::key_type(first,last) );
|
||||
// ref.erase( key_ref );
|
||||
//
|
||||
// Policy name:
|
||||
// erase_action
|
||||
//
|
||||
// Policy holder, corresponding helper method:
|
||||
// ref_value_actor, erase_a( ref );
|
||||
// ref_const_ref_actor, erase_a( ref, key_ref );
|
||||
//
|
||||
// () operators: both
|
||||
//
|
||||
// See also ref_value_actor and ref_const_ref_actor for more details.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct erase_action
|
||||
{
|
||||
template<
|
||||
typename T,
|
||||
typename KeyT
|
||||
>
|
||||
void act(T& ref_, KeyT const& key_) const
|
||||
{
|
||||
ref_.erase(key_);
|
||||
}
|
||||
template<
|
||||
typename T,
|
||||
typename IteratorT
|
||||
>
|
||||
void act(
|
||||
T& ref_,
|
||||
IteratorT const& first_,
|
||||
IteratorT const& last_
|
||||
) const
|
||||
{
|
||||
typedef typename T::key_type key_type;
|
||||
key_type key(first_,last_);
|
||||
|
||||
ref_.erase(key);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline ref_value_actor<T,erase_action> erase_a(T& ref_)
|
||||
{
|
||||
return ref_value_actor<T,erase_action>(ref_);
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename KeyT
|
||||
>
|
||||
inline ref_const_ref_actor<T,KeyT,erase_action> erase_a(
|
||||
T& ref_,
|
||||
KeyT const& key_
|
||||
)
|
||||
{
|
||||
return ref_const_ref_actor<T,KeyT,erase_action>(ref_,key_);
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_ACTOR_INCREMENT_ACTOR_HPP
|
||||
#define BOOST_SPIRIT_ACTOR_INCREMENT_ACTOR_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_actor.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Summary:
|
||||
// A semantic action policy that calls the ++ operator on a reference.
|
||||
// (This doc uses convention available in actors.hpp)
|
||||
//
|
||||
// Actions:
|
||||
// ++ref;
|
||||
//
|
||||
// Policy name:
|
||||
// increment_action
|
||||
//
|
||||
// Policy holder, corresponding helper method:
|
||||
// ref_actor, increment_a( ref );
|
||||
//
|
||||
// () operators: both.
|
||||
//
|
||||
// See also ref_actor for more details.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct increment_action
|
||||
{
|
||||
template<
|
||||
typename T
|
||||
>
|
||||
void act(T& ref_) const
|
||||
{
|
||||
++ref_;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// helper method that creates a increment_actor.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
inline ref_actor<T,increment_action> increment_a(T& ref_)
|
||||
{
|
||||
return ref_actor<T,increment_action>(ref_);
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,121 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_ACTOR_INSERT_AT_ACTOR_HPP
|
||||
#define BOOST_SPIRIT_ACTOR_INSERT_AT_ACTOR_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_const_ref_value_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_const_ref_const_ref_a.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Summary:
|
||||
// A semantic action policy that insert data into an associative
|
||||
// container using a const reference to a key.
|
||||
// (This doc uses convention available in actors.hpp)
|
||||
//
|
||||
// Actions (what it does):
|
||||
// ref.insert( T::value_type(key_ref,value) );
|
||||
// ref.insert( T::value_type(key_ref, T::mapped_type(first,last)));;
|
||||
// ref.insert( T::value_type(key_ref,value_ref) );
|
||||
//
|
||||
// Policy name:
|
||||
// insert_at_action
|
||||
//
|
||||
// Policy holder, corresponding helper method:
|
||||
// ref_const_ref_value_actor, insert_at_a( ref, key_ref );
|
||||
// ref_const_ref_const_ref_actor, insert_a( ref, key_ref, value_ref );
|
||||
//
|
||||
// () operators: both
|
||||
//
|
||||
// See also ref_const_ref_value_actor and ref_const_ref_const_ref_actor
|
||||
// for more details.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct insert_at_action
|
||||
{
|
||||
template<
|
||||
typename T,
|
||||
typename ReferentT,
|
||||
typename ValueT
|
||||
>
|
||||
void act(
|
||||
T& ref_,
|
||||
ReferentT const& key_,
|
||||
ValueT const& value_
|
||||
) const
|
||||
{
|
||||
typedef typename T::value_type value_type;
|
||||
ref_.insert( value_type(key_, value_) );
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename ReferentT,
|
||||
typename IteratorT
|
||||
>
|
||||
void act(
|
||||
T& ref_,
|
||||
ReferentT const& key_,
|
||||
IteratorT const& first_,
|
||||
IteratorT const& last_
|
||||
) const
|
||||
{
|
||||
typedef typename T::mapped_type mapped_type;
|
||||
typedef typename T::value_type value_type;
|
||||
|
||||
mapped_type value(first_,last_);
|
||||
value_type key_value(key_, value);
|
||||
ref_.insert( key_value );
|
||||
}
|
||||
};
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename ReferentT
|
||||
>
|
||||
inline ref_const_ref_value_actor<T,ReferentT,insert_at_action>
|
||||
insert_at_a(
|
||||
T& ref_,
|
||||
ReferentT const& key_
|
||||
)
|
||||
{
|
||||
return ref_const_ref_value_actor<
|
||||
T,
|
||||
ReferentT,
|
||||
insert_at_action
|
||||
>(ref_,key_);
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename ReferentT,
|
||||
typename ValueT
|
||||
>
|
||||
inline ref_const_ref_const_ref_actor<T,ReferentT,ValueT,insert_at_action>
|
||||
insert_at_a(
|
||||
T& ref_,
|
||||
ReferentT const& key_,
|
||||
ValueT const& value_
|
||||
)
|
||||
{
|
||||
return ref_const_ref_const_ref_actor<
|
||||
T,
|
||||
ReferentT,
|
||||
ValueT,
|
||||
insert_at_action
|
||||
>(ref_,key_,value_);
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,97 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_ACTOR_INSERT_KEY_ACTOR_HPP
|
||||
#define BOOST_SPIRIT_ACTOR_INSERT_KEY_ACTOR_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_const_ref_value_actor.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Summary:
|
||||
// A semantic action policy that insert data into an associative
|
||||
// container using a const reference to data.
|
||||
// (This doc uses convention available in actors.hpp)
|
||||
//
|
||||
// Actions (what it does):
|
||||
// ref.insert( T::value_type(value,value_ref) );
|
||||
// ref.insert( T::value_type(T::key_type(first,last), value_ref));;
|
||||
//
|
||||
// Policy name:
|
||||
// insert_key_action
|
||||
//
|
||||
// Policy holder, corresponding helper method:
|
||||
// ref_const_ref_value_actor, insert_key_a( ref, value_ref );
|
||||
//
|
||||
// () operators: both
|
||||
//
|
||||
// See also ref_const_ref_value_actor for more details.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct insert_key_action
|
||||
{
|
||||
template<
|
||||
typename T,
|
||||
typename ValueT,
|
||||
typename ReferentT
|
||||
>
|
||||
void act(
|
||||
T& ref_,
|
||||
ValueT const& value_,
|
||||
ReferentT const& key_
|
||||
) const
|
||||
{
|
||||
typedef typename T::value_type value_type;
|
||||
value_type key_value(key_, value_);
|
||||
ref_.insert( key_value );
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename ValueT,
|
||||
typename IteratorT
|
||||
>
|
||||
void act(
|
||||
T& ref_,
|
||||
ValueT const& value_,
|
||||
IteratorT const& first_,
|
||||
IteratorT const& last_
|
||||
) const
|
||||
{
|
||||
typedef typename T::key_type key_type;
|
||||
typedef typename T::value_type value_type;
|
||||
|
||||
key_type key(first_,last_);
|
||||
value_type key_value(key, value_);
|
||||
ref_.insert( key_value );
|
||||
}
|
||||
};
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename ValueT
|
||||
>
|
||||
inline ref_const_ref_value_actor<T,ValueT,insert_key_action> insert_key_a(
|
||||
T& ref_,
|
||||
ValueT const& value_
|
||||
)
|
||||
{
|
||||
return ref_const_ref_value_actor<
|
||||
T,
|
||||
ValueT,
|
||||
insert_key_action
|
||||
>(ref_,value_);
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,101 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_ACTOR_PUSH_BACK_ACTOR_HPP
|
||||
#define BOOST_SPIRIT_ACTOR_PUSH_BACK_ACTOR_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_value_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_const_ref_actor.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 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_);
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,91 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_ACTOR_PUSH_FRONT_ACTOR_HPP
|
||||
#define BOOST_SPIRIT_ACTOR_PUSH_FRONT_ACTOR_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_value_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_const_ref_actor.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Summary:
|
||||
//
|
||||
// A semantic action policy that appends a value to the front of a
|
||||
// container.
|
||||
// (This doc uses convention available in actors.hpp)
|
||||
//
|
||||
// Actions (what it does and what ref, value_ref must support):
|
||||
// ref.push_front( value );
|
||||
// ref.push_front( T::value_type(first,last) );
|
||||
// ref.push_front( value_ref );
|
||||
//
|
||||
// Policy name:
|
||||
// push_front_action
|
||||
//
|
||||
// Policy holder, corresponding helper method:
|
||||
// ref_value_actor, push_front_a( ref );
|
||||
// ref_const_ref_actor, push_front_a( ref, value_ref );
|
||||
//
|
||||
// () operators: both
|
||||
//
|
||||
// See also ref_value_actor and ref_const_ref_actor for more details.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct push_front_action
|
||||
{
|
||||
template<
|
||||
typename T,
|
||||
typename ValueT
|
||||
>
|
||||
void act(T& ref_, ValueT const& value_) const
|
||||
{
|
||||
ref_.push_front( 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_front( value );
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline ref_value_actor<T,push_front_action> push_front_a(T& ref_)
|
||||
{
|
||||
return ref_value_actor<T,push_front_action>(ref_);
|
||||
}
|
||||
|
||||
template<
|
||||
typename T,
|
||||
typename ValueT
|
||||
>
|
||||
inline ref_const_ref_actor<T,ValueT,push_front_action> push_front_a(
|
||||
T& ref_,
|
||||
ValueT const& value_
|
||||
)
|
||||
{
|
||||
return ref_const_ref_actor<T,ValueT,push_front_action>(ref_,value_);
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,70 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_ACTOR_REF_ACTOR_HPP
|
||||
#define BOOST_SPIRIT_ACTOR_REF_ACTOR_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Summary:
|
||||
// A semantic action policy holder. This holder stores a reference to ref,
|
||||
// act methods are fead with this reference. The parse result is not used
|
||||
// by this holder.
|
||||
//
|
||||
// (This doc uses convention available in actors.hpp)
|
||||
//
|
||||
// Constructor:
|
||||
// ...(T& ref_);
|
||||
// where ref_ is stored.
|
||||
//
|
||||
// Action calls:
|
||||
// act(ref);
|
||||
//
|
||||
// () operators: both
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template<
|
||||
typename T,
|
||||
typename ActionT
|
||||
>
|
||||
class ref_actor : public ActionT
|
||||
{
|
||||
private:
|
||||
T& ref;
|
||||
public:
|
||||
explicit
|
||||
ref_actor(T& ref_)
|
||||
: ref(ref_){}
|
||||
|
||||
|
||||
template<typename T2>
|
||||
void operator()(T2 const& /*val*/) const
|
||||
{
|
||||
this->act(ref); // defined in ActionT
|
||||
}
|
||||
|
||||
|
||||
template<typename IteratorT>
|
||||
void operator()(
|
||||
IteratorT const& /*first*/,
|
||||
IteratorT const& /*last*/
|
||||
) const
|
||||
{
|
||||
this->act(ref); // defined in ActionT
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,78 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_ACTOR_REF_CONST_REF_ACTOR_HPP
|
||||
#define BOOST_SPIRIT_ACTOR_REF_CONST_REF_ACTOR_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,87 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_ACTOR_REF_CONST_REF_CONST_REF_ACTOR_HPP
|
||||
#define BOOST_SPIRIT_ACTOR_REF_CONST_REF_CONST_REF_ACTOR_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Summary:
|
||||
// A semantic action policy holder. This holder stores a reference to ref
|
||||
// , a const reference to value1_ref and a const reference to value2_ref.
|
||||
// Typically, value1_ref is a key and value2_ref is value for associative
|
||||
// container operations.
|
||||
// act methods are feed with ref, value1_ref, value2_ref. The parse result
|
||||
// is not used by this holder.
|
||||
//
|
||||
// (This doc uses convention available in actors.hpp)
|
||||
//
|
||||
// Constructor:
|
||||
// ...(
|
||||
// T& ref_,
|
||||
// Value1T const& value1_ref_,
|
||||
// Value2T const& value2_ref_ );
|
||||
// where ref_, value1_ref and value2_ref_ are stored in the holder.
|
||||
//
|
||||
// Action calls:
|
||||
// act(ref, value1_ref, value2_ref);
|
||||
//
|
||||
// () operators: both
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template<
|
||||
typename T,
|
||||
typename Value1T,
|
||||
typename Value2T,
|
||||
typename ActionT
|
||||
>
|
||||
class ref_const_ref_const_ref_actor : public ActionT
|
||||
{
|
||||
private:
|
||||
T& ref;
|
||||
Value1T const& value1_ref;
|
||||
Value2T const& value2_ref;
|
||||
public:
|
||||
ref_const_ref_const_ref_actor(
|
||||
T& ref_,
|
||||
Value1T const& value1_ref_,
|
||||
Value2T const& value2_ref_
|
||||
)
|
||||
:
|
||||
ref(ref_),
|
||||
value1_ref(value1_ref_),
|
||||
value2_ref(value2_ref_)
|
||||
{}
|
||||
|
||||
|
||||
template<typename T2>
|
||||
void operator()(T2 const& /*val*/) const
|
||||
{
|
||||
this->act(ref,value1_ref,value2_ref); // defined in ActionT
|
||||
}
|
||||
|
||||
|
||||
template<typename IteratorT>
|
||||
void operator()(
|
||||
IteratorT const& /*first*/,
|
||||
IteratorT const& /*last*/
|
||||
) const
|
||||
{
|
||||
this->act(ref,value1_ref,value2_ref); // defined in ActionT
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,78 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_ACTOR_REF_CONST_REF_VALUE_ACTOR_HPP
|
||||
#define BOOST_SPIRIT_ACTOR_REF_CONST_REF_VALUE_ACTOR_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 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, value_ref and the parse result.
|
||||
//
|
||||
// (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, value);
|
||||
// act(ref, value_ref, first, last);
|
||||
//
|
||||
// () operators: both
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template<
|
||||
typename T,
|
||||
typename ValueT,
|
||||
typename ActionT
|
||||
>
|
||||
class ref_const_ref_value_actor : public ActionT
|
||||
{
|
||||
private:
|
||||
T& ref;
|
||||
ValueT const& value_ref;
|
||||
public:
|
||||
ref_const_ref_value_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,val_); // defined in ActionT
|
||||
}
|
||||
|
||||
|
||||
template<typename IteratorT>
|
||||
void operator()(
|
||||
IteratorT const& first_,
|
||||
IteratorT const& last_
|
||||
) const
|
||||
{
|
||||
this->act(ref,value_ref,first_,last_); // defined in ActionT
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,82 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
||||
Copyright (c) 2011 Bryce Lelbach
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_ACTOR_REF_VALUE_ACTOR_HPP
|
||||
#define BOOST_SPIRIT_ACTOR_REF_VALUE_ACTOR_HPP
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,85 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Jonathan de Halleux (dehalleux@pelikhan.com)
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_ACTOR_SWAP_ACTOR_HPP
|
||||
#define BOOST_SPIRIT_ACTOR_SWAP_ACTOR_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/actor/ref_value_actor.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Summary:
|
||||
// A semantic action policy that swaps values.
|
||||
// (This doc uses convention available in actors.hpp)
|
||||
//
|
||||
// Actions (what it does):
|
||||
// ref.swap( value_ref );
|
||||
//
|
||||
// Policy name:
|
||||
// swap_action
|
||||
//
|
||||
// Policy holder, corresponding helper method:
|
||||
// ref_value_actor, swap_a( ref );
|
||||
// ref_const_ref_actor, swap_a( ref, value_ref );
|
||||
//
|
||||
// () operators: both
|
||||
//
|
||||
// See also ref_value_actor and ref_const_ref_actor for more details.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template<
|
||||
typename T
|
||||
>
|
||||
class swap_actor
|
||||
{
|
||||
private:
|
||||
T& ref;
|
||||
T& swap_ref;
|
||||
|
||||
public:
|
||||
swap_actor(
|
||||
T& ref_,
|
||||
T& swap_ref_)
|
||||
: ref(ref_), swap_ref(swap_ref_)
|
||||
{};
|
||||
|
||||
template<typename T2>
|
||||
void operator()(T2 const& /*val*/) const
|
||||
{
|
||||
ref.swap(swap_ref);
|
||||
}
|
||||
|
||||
|
||||
template<typename IteratorT>
|
||||
void operator()(
|
||||
IteratorT const& /*first*/,
|
||||
IteratorT const& /*last*/
|
||||
) const
|
||||
{
|
||||
ref.swap(swap_ref);
|
||||
}
|
||||
};
|
||||
|
||||
template<
|
||||
typename T
|
||||
>
|
||||
inline swap_actor<T> swap_a(
|
||||
T& ref_,
|
||||
T& swap_ref_
|
||||
)
|
||||
{
|
||||
return swap_actor<T>(ref_,swap_ref_);
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,74 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2006 Tobias Schwinger
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_ACTOR_TYPEOF_HPP)
|
||||
#define BOOST_SPIRIT_ACTOR_TYPEOF_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
template<typename T, typename ActionT> class ref_actor;
|
||||
|
||||
template<typename T, typename ActionT> class ref_value_actor;
|
||||
|
||||
template<typename T, typename ValueT, typename ActionT>
|
||||
|
||||
class ref_const_ref_actor;
|
||||
template<typename T, typename ValueT, typename ActionT>
|
||||
|
||||
class ref_const_ref_value_actor;
|
||||
template<typename T, typename Value1T, typename Value2T, typename ActionT>
|
||||
|
||||
class ref_const_ref_const_ref_actor;
|
||||
|
||||
struct assign_action;
|
||||
struct clear_action;
|
||||
struct increment_action;
|
||||
struct decrement_action;
|
||||
struct push_back_action;
|
||||
struct push_front_action;
|
||||
struct insert_key_action;
|
||||
struct insert_at_action;
|
||||
struct assign_key_action;
|
||||
|
||||
template<typename T> class swap_actor;
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
|
||||
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
|
||||
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::ref_actor,2)
|
||||
#if !defined(BOOST_SPIRIT_CORE_TYPEOF_HPP)
|
||||
// this part also lives in the core master header and is deprecated there...
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::ref_value_actor,2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::ref_const_ref_actor,3)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::assign_action)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::push_back_action)
|
||||
#endif
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::ref_const_ref_value_actor,3)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::ref_const_ref_const_ref_actor,4)
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::clear_action)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::increment_action)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::decrement_action)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::push_front_action)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::insert_key_action)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::insert_at_action)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::assign_key_action)
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::swap_actor,1)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2003 Joel de Guzman
|
||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_ATTRIBUTE_MAIN_HPP)
|
||||
#define BOOST_SPIRIT_ATTRIBUTE_MAIN_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/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 6
|
||||
#endif // !defined(PHOENIX_LIMIT)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/spirit/home/classic/attribute/parametric.hpp>
|
||||
#include <boost/spirit/home/classic/attribute/closure.hpp>
|
||||
|
||||
#endif // !defined(BOOST_SPIRIT_ATTRIBUTE_MAIN_HPP)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,56 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2002-2003 Joel de Guzman
|
||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_CLOSURE_CONTEXT_HPP)
|
||||
#define BOOST_SPIRIT_CLOSURE_CONTEXT_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
#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)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif // BOOST_SPIRIT_CLOSURE_CONTEXT_HPP
|
||||
@@ -0,0 +1,69 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2006 Tobias Schwinger
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_CLOSURE_FWD_HPP)
|
||||
#define BOOST_SPIRIT_CLOSURE_FWD_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/phoenix/tuples.hpp>
|
||||
|
||||
#if !defined(BOOST_SPIRIT_CLOSURE_LIMIT)
|
||||
# define BOOST_SPIRIT_CLOSURE_LIMIT PHOENIX_LIMIT
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
template<typename ClosureT>
|
||||
class closure_context;
|
||||
|
||||
template <typename ClosureT>
|
||||
class init_closure_context;
|
||||
|
||||
template <typename ParserT, typename ActorTupleT>
|
||||
struct init_closure_parser;
|
||||
|
||||
template <
|
||||
typename DerivedT
|
||||
, typename T0 = ::phoenix::nil_t
|
||||
, typename T1 = ::phoenix::nil_t
|
||||
, typename T2 = ::phoenix::nil_t
|
||||
|
||||
#if BOOST_SPIRIT_CLOSURE_LIMIT > 3
|
||||
, typename T3 = ::phoenix::nil_t
|
||||
, typename T4 = ::phoenix::nil_t
|
||||
, typename T5 = ::phoenix::nil_t
|
||||
|
||||
#if BOOST_SPIRIT_CLOSURE_LIMIT > 6
|
||||
, typename T6 = ::phoenix::nil_t
|
||||
, typename T7 = ::phoenix::nil_t
|
||||
, typename T8 = ::phoenix::nil_t
|
||||
|
||||
#if BOOST_SPIRIT_CLOSURE_LIMIT > 9
|
||||
, typename T9 = ::phoenix::nil_t
|
||||
, typename T10 = ::phoenix::nil_t
|
||||
, typename T11 = ::phoenix::nil_t
|
||||
|
||||
#if BOOST_SPIRIT_CLOSURE_LIMIT > 12
|
||||
, typename T12 = ::phoenix::nil_t
|
||||
, typename T13 = ::phoenix::nil_t
|
||||
, typename T14 = ::phoenix::nil_t
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
>
|
||||
struct closure;
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2003 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_PARAMETRIC_HPP
|
||||
#define BOOST_SPIRIT_PARAMETRIC_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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); }
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,67 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2006 Tobias Schwinger
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_ATTRIBUTE_TYPEOF_HPP)
|
||||
#define BOOST_SPIRIT_ATTRIBUTE_TYPEOF_HPP
|
||||
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/typeof.hpp>
|
||||
#include <boost/spirit/home/classic/attribute/closure_fwd.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
// parametric.hpp
|
||||
template<typename ChGenT> struct f_chlit;
|
||||
template<typename ChGenAT, typename ChGenBT> struct f_range;
|
||||
template<typename IterGenAT, typename IterGenBT> class f_chseq;
|
||||
template<typename IterGenAT, typename IterGenBT> class f_strlit;
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
|
||||
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
|
||||
|
||||
|
||||
// parametric.hpp
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::f_chlit,1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::f_range,2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::f_chseq,2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::f_strlit,2)
|
||||
|
||||
|
||||
// closure.hpp (has forward header)
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::closure,BOOST_SPIRIT_CLOSURE_LIMIT)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::closure_context,1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::init_closure_context,1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::init_closure_parser,2)
|
||||
|
||||
|
||||
#if BOOST_SPIRIT_CLOSURE_LIMIT > 12
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::closure,12)
|
||||
#endif
|
||||
#if BOOST_SPIRIT_CLOSURE_LIMIT > 9
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::closure, 9)
|
||||
#endif
|
||||
#if BOOST_SPIRIT_CLOSURE_LIMIT > 6
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::closure, 6)
|
||||
#endif
|
||||
#if BOOST_SPIRIT_CLOSURE_LIMIT > 3
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::closure, 3)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*=============================================================================
|
||||
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/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_CORE_MAIN_HPP)
|
||||
#define BOOST_SPIRIT_CORE_MAIN_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/version.hpp>
|
||||
#include <boost/spirit/home/classic/debug.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Spirit.Core includes
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Spirit.Core.Kernel
|
||||
#include <boost/spirit/home/classic/core/config.hpp>
|
||||
#include <boost/spirit/home/classic/core/nil.hpp>
|
||||
#include <boost/spirit/home/classic/core/match.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
|
||||
// Spirit.Core.Primitives
|
||||
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
|
||||
#include <boost/spirit/home/classic/core/primitives/numerics.hpp>
|
||||
|
||||
// Spirit.Core.Scanner
|
||||
#include <boost/spirit/home/classic/core/scanner/scanner.hpp>
|
||||
#include <boost/spirit/home/classic/core/scanner/skipper.hpp>
|
||||
|
||||
// Spirit.Core.NonTerminal
|
||||
#include <boost/spirit/home/classic/core/non_terminal/subrule.hpp>
|
||||
#include <boost/spirit/home/classic/core/non_terminal/rule.hpp>
|
||||
#include <boost/spirit/home/classic/core/non_terminal/grammar.hpp>
|
||||
|
||||
// Spirit.Core.Composite
|
||||
#include <boost/spirit/home/classic/core/composite/actions.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/directives.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/epsilon.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/sequence.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/sequential_and.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/sequential_or.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/alternative.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/difference.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/intersection.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/exclusive_or.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/kleene_star.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/positive.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/optional.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/list.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/no_actions.hpp>
|
||||
|
||||
// Deprecated interface includes
|
||||
#include <boost/spirit/home/classic/actor/assign_actor.hpp>
|
||||
#include <boost/spirit/home/classic/actor/push_back_actor.hpp>
|
||||
|
||||
#if defined(BOOST_SPIRIT_DEBUG)
|
||||
//////////////////////////////////
|
||||
#include <boost/spirit/home/classic/debug/parser_names.hpp>
|
||||
|
||||
#endif // BOOST_SPIRIT_DEBUG
|
||||
|
||||
#endif // BOOST_SPIRIT_CORE_MAIN_HPP
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2003 Joel de Guzman
|
||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_ASSERT_HPP)
|
||||
#define BOOST_SPIRIT_ASSERT_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BOOST_SPIRIT_ASSERT is used throughout the framework. It can be
|
||||
// overridden by the user. If BOOST_SPIRIT_ASSERT_EXCEPTION is defined,
|
||||
// then that will be thrown, otherwise, BOOST_SPIRIT_ASSERT simply turns
|
||||
// into a plain BOOST_ASSERT()
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(BOOST_SPIRIT_ASSERT)
|
||||
#if defined(NDEBUG)
|
||||
#define BOOST_SPIRIT_ASSERT(x)
|
||||
#elif defined (BOOST_SPIRIT_ASSERT_EXCEPTION)
|
||||
#define BOOST_SPIRIT_ASSERT_AUX(f, l, x) BOOST_SPIRIT_ASSERT_AUX2(f, l, x)
|
||||
#define BOOST_SPIRIT_ASSERT_AUX2(f, l, x) \
|
||||
do{ if (!(x)) boost::throw_exception( \
|
||||
BOOST_SPIRIT_ASSERT_EXCEPTION(f "(" #l "): " #x)); } while(0)
|
||||
#define BOOST_SPIRIT_ASSERT(x) BOOST_SPIRIT_ASSERT_AUX(__FILE__, __LINE__, x)
|
||||
#else
|
||||
#include <boost/assert.hpp>
|
||||
#define BOOST_SPIRIT_ASSERT(x) BOOST_ASSERT(x)
|
||||
#endif
|
||||
#endif // !defined(BOOST_SPIRIT_ASSERT)
|
||||
|
||||
#endif // BOOST_SPIRIT_ASSERT_HPP
|
||||
@@ -0,0 +1,136 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_ACTIONS_HPP
|
||||
#define BOOST_SPIRIT_ACTIONS_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// action class
|
||||
//
|
||||
// The action class binds a parser with a user defined semantic
|
||||
// action. Instances of action are never created manually. Instead,
|
||||
// action objects are typically created indirectly through
|
||||
// expression templates of the form:
|
||||
//
|
||||
// p[f]
|
||||
//
|
||||
// where p is a parser and f is a function or functor. The semantic
|
||||
// action may be a function or a functor. When the parser is
|
||||
// successful, the actor calls the scanner's action_policy policy
|
||||
// (see scanner.hpp):
|
||||
//
|
||||
// scan.do_action(actor, attribute, first, last);
|
||||
//
|
||||
// passing in these information:
|
||||
//
|
||||
// actor: The action's function or functor
|
||||
// attribute: The match (returned by the parser) object's
|
||||
// attribute (see match.hpp)
|
||||
// first: Iterator pointing to the start of the matching
|
||||
// portion of the input
|
||||
// last: Iterator pointing to one past the end of the
|
||||
// matching portion of the input
|
||||
//
|
||||
// It is the responsibility of the scanner's action_policy policy to
|
||||
// dispatch the function or functor as it sees fit. The expected
|
||||
// function or functor signature depends on the parser being
|
||||
// wrapped. In general, if the attribute type of the parser being
|
||||
// wrapped is a nil_t, the function or functor expect the signature:
|
||||
//
|
||||
// void func(Iterator first, Iterator last); // functions
|
||||
//
|
||||
// struct ftor // functors
|
||||
// {
|
||||
// void func(Iterator first, Iterator last) const;
|
||||
// };
|
||||
//
|
||||
// where Iterator is the type of the iterator that is being used and
|
||||
// first and last are the iterators pointing to the matching portion
|
||||
// of the input.
|
||||
//
|
||||
// If the attribute type of the parser being wrapped is not a nil_t,
|
||||
// the function or functor usually expect the signature:
|
||||
//
|
||||
// void func(T val); // functions
|
||||
//
|
||||
// struct ftor // functors
|
||||
// {
|
||||
// void func(T val) const;
|
||||
// };
|
||||
//
|
||||
// where T is the attribute type and val is the attribute value
|
||||
// returned by the parser being wrapped.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename ParserT, typename ActionT>
|
||||
class action : public unary<ParserT, parser<action<ParserT, ActionT> > >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef action<ParserT, ActionT> self_t;
|
||||
typedef action_parser_category parser_category_t;
|
||||
typedef unary<ParserT, parser<self_t> > base_t;
|
||||
typedef ActionT predicate_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename parser_result<ParserT, ScannerT>::type type;
|
||||
};
|
||||
|
||||
action(ParserT const& p, ActionT const& a)
|
||||
: base_t(p)
|
||||
, actor(a) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename ScannerT::iterator_t iterator_t;
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
|
||||
scan.at_end(); // allow skipper to take effect
|
||||
iterator_t save = scan.first;
|
||||
result_t hit = this->subject().parse(scan);
|
||||
if (hit)
|
||||
{
|
||||
typename result_t::return_t val = hit.value();
|
||||
scan.do_action(actor, val, save, scan.first);
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
||||
ActionT const& predicate() const { return actor; }
|
||||
|
||||
private:
|
||||
|
||||
ActionT actor;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,147 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_ALTERNATIVE_HPP)
|
||||
#define BOOST_SPIRIT_ALTERNATIVE_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/meta/as_parser.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// alternative class
|
||||
//
|
||||
// Handles expressions of the form:
|
||||
//
|
||||
// a | b
|
||||
//
|
||||
// where a and b are parsers. The expression returns a composite
|
||||
// parser that matches a or b. One (not both) of the operands may
|
||||
// be a literal char, wchar_t or a primitive string char const*,
|
||||
// wchar_t const*.
|
||||
//
|
||||
// The expression is short circuit evaluated. b is never touched
|
||||
// when a is returns a successful match.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct alternative_parser_gen;
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
template <typename A, typename B>
|
||||
struct alternative
|
||||
: public binary<A, B, parser<alternative<A, B> > >
|
||||
{
|
||||
typedef alternative<A, B> self_t;
|
||||
typedef binary_parser_category parser_category_t;
|
||||
typedef alternative_parser_gen parser_generator_t;
|
||||
typedef binary<A, B, parser<self_t> > base_t;
|
||||
|
||||
alternative(A const& a, B const& b)
|
||||
: base_t(a, b) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
typedef typename ScannerT::iterator_t iterator_t;
|
||||
{ // scope for save
|
||||
iterator_t save = scan.first;
|
||||
if (result_t hit = this->left().parse(scan))
|
||||
return hit;
|
||||
scan.first = save;
|
||||
}
|
||||
return this->right().parse(scan);
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
struct alternative_parser_gen
|
||||
{
|
||||
template <typename A, typename B>
|
||||
struct result
|
||||
{
|
||||
typedef
|
||||
alternative<
|
||||
typename as_parser<A>::type
|
||||
, typename as_parser<B>::type
|
||||
>
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
static alternative<
|
||||
typename as_parser<A>::type
|
||||
, typename as_parser<B>::type
|
||||
>
|
||||
generate(A const& a, B const& b)
|
||||
{
|
||||
return alternative<BOOST_DEDUCED_TYPENAME as_parser<A>::type,
|
||||
BOOST_DEDUCED_TYPENAME as_parser<B>::type>
|
||||
(as_parser<A>::convert(a), as_parser<B>::convert(b));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
alternative<A, B>
|
||||
operator|(parser<A> const& a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
alternative<A, chlit<char> >
|
||||
operator|(parser<A> const& a, char b);
|
||||
|
||||
template <typename B>
|
||||
alternative<chlit<char>, B>
|
||||
operator|(char a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
alternative<A, strlit<char const*> >
|
||||
operator|(parser<A> const& a, char const* b);
|
||||
|
||||
template <typename B>
|
||||
alternative<strlit<char const*>, B>
|
||||
operator|(char const* a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
alternative<A, chlit<wchar_t> >
|
||||
operator|(parser<A> const& a, wchar_t b);
|
||||
|
||||
template <typename B>
|
||||
alternative<chlit<wchar_t>, B>
|
||||
operator|(wchar_t a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
alternative<A, strlit<wchar_t const*> >
|
||||
operator|(parser<A> const& a, wchar_t const* b);
|
||||
|
||||
template <typename B>
|
||||
alternative<strlit<wchar_t const*>, B>
|
||||
operator|(wchar_t const* a, parser<B> const& b);
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/classic/core/composite/impl/alternative.ipp>
|
||||
@@ -0,0 +1,151 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_COMPOSITE_HPP)
|
||||
#define BOOST_SPIRIT_COMPOSITE_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/compressed_pair.hpp>
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// unary class.
|
||||
//
|
||||
// Composite class composed of a single subject. This template class
|
||||
// is parameterized by the subject type S and a base class to
|
||||
// inherit from, BaseT. The unary class is meant to be a base class
|
||||
// to inherit from. The inheritance structure, given the BaseT
|
||||
// template parameter places the unary class in the middle of a
|
||||
// linear, single parent hierarchy. For instance, given a class S
|
||||
// and a base class B, a class D can derive from unary:
|
||||
//
|
||||
// struct D : public unary<S, B> {...};
|
||||
//
|
||||
// The inheritance structure is thus:
|
||||
//
|
||||
// B
|
||||
// |
|
||||
// unary (has S)
|
||||
// |
|
||||
// D
|
||||
//
|
||||
// The subject can be accessed from the derived class D as:
|
||||
// this->subject();
|
||||
//
|
||||
// Typically, the subject S is specified as typename S::embed_t.
|
||||
// embed_t specifies how the subject is embedded in the composite
|
||||
// (See parser.hpp for details).
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename S, typename BaseT>
|
||||
class unary : public BaseT
|
||||
{
|
||||
public:
|
||||
|
||||
typedef BaseT base_t;
|
||||
typedef typename boost::call_traits<S>::param_type param_t;
|
||||
typedef typename boost::call_traits<S>::const_reference return_t;
|
||||
typedef S subject_t;
|
||||
typedef typename S::embed_t subject_embed_t;
|
||||
|
||||
unary(param_t subj_)
|
||||
: base_t(), subj(subj_) {}
|
||||
|
||||
unary(BaseT const& base, param_t subj_)
|
||||
: base_t(base), subj(subj_) {}
|
||||
|
||||
return_t
|
||||
subject() const
|
||||
{ return subj; }
|
||||
|
||||
private:
|
||||
|
||||
subject_embed_t subj;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// binary class.
|
||||
//
|
||||
// Composite class composed of a pair (left and right). This
|
||||
// template class is parameterized by the left and right subject
|
||||
// types A and B and a base class to inherit from, BaseT. The binary
|
||||
// class is meant to be a base class to inherit from. The
|
||||
// inheritance structure, given the BaseT template parameter places
|
||||
// the binary class in the middle of a linear, single parent
|
||||
// hierarchy. For instance, given classes X and Y and a base class
|
||||
// B, a class D can derive from binary:
|
||||
//
|
||||
// struct D : public binary<X, Y, B> {...};
|
||||
//
|
||||
// The inheritance structure is thus:
|
||||
//
|
||||
// B
|
||||
// |
|
||||
// binary (has X and Y)
|
||||
// |
|
||||
// D
|
||||
//
|
||||
// The left and right subjects can be accessed from the derived
|
||||
// class D as: this->left(); and this->right();
|
||||
//
|
||||
// Typically, the pairs X and Y are specified as typename X::embed_t
|
||||
// and typename Y::embed_t. embed_t specifies how the subject is
|
||||
// embedded in the composite (See parser.hpp for details).
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename A, typename B, typename BaseT>
|
||||
class binary : public BaseT
|
||||
{
|
||||
public:
|
||||
|
||||
typedef BaseT base_t;
|
||||
typedef typename boost::call_traits<A>::param_type left_param_t;
|
||||
typedef typename boost::call_traits<A>::const_reference left_return_t;
|
||||
typedef typename boost::call_traits<B>::param_type right_param_t;
|
||||
typedef typename boost::call_traits<B>::const_reference right_return_t;
|
||||
typedef A left_t;
|
||||
typedef typename A::embed_t left_embed_t;
|
||||
typedef B right_t;
|
||||
typedef typename B::embed_t right_embed_t;
|
||||
|
||||
binary(left_param_t a, right_param_t b)
|
||||
: base_t(), subj(a, b) {}
|
||||
|
||||
left_return_t
|
||||
left() const
|
||||
{ return subj.first(); }
|
||||
|
||||
right_return_t
|
||||
right() const
|
||||
{ return subj.second(); }
|
||||
|
||||
private:
|
||||
|
||||
boost::compressed_pair<left_embed_t, right_embed_t> subj;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,150 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_DIFFERENCE_HPP)
|
||||
#define BOOST_SPIRIT_DIFFERENCE_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/meta/as_parser.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// difference: a - b; Matches a but not b
|
||||
//
|
||||
// Handles expressions of the form:
|
||||
//
|
||||
// a - b
|
||||
//
|
||||
// where a and b are parsers. The expression returns a composite
|
||||
// parser that matches a but not b. One (not both) of the operands
|
||||
// may be a literal char, wchar_t or a primitive string char const*,
|
||||
// wchar_t const*.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct difference_parser_gen;
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
template <typename A, typename B>
|
||||
struct difference
|
||||
: public binary<A, B, parser<difference<A, B> > >
|
||||
{
|
||||
typedef difference<A, B> self_t;
|
||||
typedef binary_parser_category parser_category_t;
|
||||
typedef difference_parser_gen parser_generator_t;
|
||||
typedef binary<A, B, parser<self_t> > base_t;
|
||||
|
||||
difference(A const& a, B const& b)
|
||||
: base_t(a, b) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
typedef typename ScannerT::iterator_t iterator_t;
|
||||
iterator_t save = scan.first;
|
||||
if (result_t hl = this->left().parse(scan))
|
||||
{
|
||||
std::swap(save, scan.first);
|
||||
result_t hr = this->right().parse(scan);
|
||||
if (!hr || (hr.length() < hl.length()))
|
||||
{
|
||||
scan.first = save;
|
||||
return hl;
|
||||
}
|
||||
}
|
||||
|
||||
return scan.no_match();
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
struct difference_parser_gen
|
||||
{
|
||||
template <typename A, typename B>
|
||||
struct result
|
||||
{
|
||||
typedef
|
||||
difference<
|
||||
typename as_parser<A>::type
|
||||
, typename as_parser<B>::type
|
||||
>
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
static difference<
|
||||
typename as_parser<A>::type
|
||||
, typename as_parser<B>::type
|
||||
>
|
||||
generate(A const& a, B const& b)
|
||||
{
|
||||
return difference<BOOST_DEDUCED_TYPENAME as_parser<A>::type,
|
||||
BOOST_DEDUCED_TYPENAME as_parser<B>::type>
|
||||
(as_parser<A>::convert(a), as_parser<B>::convert(b));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
difference<A, B>
|
||||
operator-(parser<A> const& a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
difference<A, chlit<char> >
|
||||
operator-(parser<A> const& a, char b);
|
||||
|
||||
template <typename B>
|
||||
difference<chlit<char>, B>
|
||||
operator-(char a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
difference<A, strlit<char const*> >
|
||||
operator-(parser<A> const& a, char const* b);
|
||||
|
||||
template <typename B>
|
||||
difference<strlit<char const*>, B>
|
||||
operator-(char const* a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
difference<A, chlit<wchar_t> >
|
||||
operator-(parser<A> const& a, wchar_t b);
|
||||
|
||||
template <typename B>
|
||||
difference<chlit<wchar_t>, B>
|
||||
operator-(wchar_t a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
difference<A, strlit<wchar_t const*> >
|
||||
operator-(parser<A> const& a, wchar_t const* b);
|
||||
|
||||
template <typename B>
|
||||
difference<strlit<wchar_t const*>, B>
|
||||
operator-(wchar_t const* a, parser<B> const& b);
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/classic/core/composite/impl/difference.ipp>
|
||||
@@ -0,0 +1,607 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_DIRECTIVES_HPP)
|
||||
#define BOOST_SPIRIT_DIRECTIVES_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/scanner/skipper.hpp>
|
||||
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/impl/directives.ipp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// contiguous class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct lexeme_parser_gen;
|
||||
|
||||
template <typename ParserT>
|
||||
struct contiguous
|
||||
: public unary<ParserT, parser<contiguous<ParserT> > >
|
||||
{
|
||||
typedef contiguous<ParserT> self_t;
|
||||
typedef unary_parser_category parser_category_t;
|
||||
typedef lexeme_parser_gen parser_generator_t;
|
||||
typedef unary<ParserT, parser<self_t> > base_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename parser_result<ParserT, ScannerT>::type type;
|
||||
};
|
||||
|
||||
contiguous(ParserT const& p)
|
||||
: base_t(p) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
return impl::contiguous_parser_parse<result_t>
|
||||
(this->subject(), scan, scan);
|
||||
}
|
||||
};
|
||||
|
||||
struct lexeme_parser_gen
|
||||
{
|
||||
template <typename ParserT>
|
||||
struct result {
|
||||
|
||||
typedef contiguous<ParserT> type;
|
||||
};
|
||||
|
||||
template <typename ParserT>
|
||||
static contiguous<ParserT>
|
||||
generate(parser<ParserT> const& subject)
|
||||
{
|
||||
return contiguous<ParserT>(subject.derived());
|
||||
}
|
||||
|
||||
template <typename ParserT>
|
||||
contiguous<ParserT>
|
||||
operator[](parser<ParserT> const& subject) const
|
||||
{
|
||||
return contiguous<ParserT>(subject.derived());
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
const lexeme_parser_gen lexeme_d = lexeme_parser_gen();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// lexeme_scanner
|
||||
//
|
||||
// Given a Scanner, return the correct scanner type that
|
||||
// the lexeme_d uses. Scanner is assumed to be a phrase
|
||||
// level scanner (see skipper.hpp)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename ScannerT>
|
||||
struct lexeme_scanner
|
||||
{
|
||||
typedef scanner_policies<
|
||||
no_skipper_iteration_policy<
|
||||
typename ScannerT::iteration_policy_t>,
|
||||
typename ScannerT::match_policy_t,
|
||||
typename ScannerT::action_policy_t
|
||||
> policies_t;
|
||||
|
||||
typedef typename
|
||||
rebind_scanner_policies<ScannerT, policies_t>::type type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// inhibit_case_iteration_policy class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename BaseT>
|
||||
struct inhibit_case_iteration_policy : public BaseT
|
||||
{
|
||||
typedef BaseT base_t;
|
||||
|
||||
inhibit_case_iteration_policy()
|
||||
: BaseT() {}
|
||||
|
||||
template <typename PolicyT>
|
||||
inhibit_case_iteration_policy(PolicyT const& other)
|
||||
: BaseT(other) {}
|
||||
|
||||
template <typename CharT>
|
||||
CharT filter(CharT ch) const
|
||||
{ return impl::tolower_(ch); }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// inhibit_case class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct inhibit_case_parser_gen;
|
||||
|
||||
template <typename ParserT>
|
||||
struct inhibit_case
|
||||
: public unary<ParserT, parser<inhibit_case<ParserT> > >
|
||||
{
|
||||
typedef inhibit_case<ParserT> self_t;
|
||||
typedef unary_parser_category parser_category_t;
|
||||
typedef inhibit_case_parser_gen parser_generator_t;
|
||||
typedef unary<ParserT, parser<self_t> > base_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename parser_result<ParserT, ScannerT>::type type;
|
||||
};
|
||||
|
||||
inhibit_case(ParserT const& p)
|
||||
: base_t(p) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
return impl::inhibit_case_parser_parse<result_t>
|
||||
(this->subject(), scan, scan);
|
||||
}
|
||||
};
|
||||
|
||||
template <int N>
|
||||
struct inhibit_case_parser_gen_base
|
||||
{
|
||||
// This hack is needed to make borland happy.
|
||||
// If these member operators were defined in the
|
||||
// inhibit_case_parser_gen class, or if this class
|
||||
// is non-templated, borland ICEs.
|
||||
|
||||
static inhibit_case<strlit<char const*> >
|
||||
generate(char const* str)
|
||||
{ return inhibit_case<strlit<char const*> >(str); }
|
||||
|
||||
static inhibit_case<strlit<wchar_t const*> >
|
||||
generate(wchar_t const* str)
|
||||
{ return inhibit_case<strlit<wchar_t const*> >(str); }
|
||||
|
||||
static inhibit_case<chlit<char> >
|
||||
generate(char ch)
|
||||
{ return inhibit_case<chlit<char> >(ch); }
|
||||
|
||||
static inhibit_case<chlit<wchar_t> >
|
||||
generate(wchar_t ch)
|
||||
{ return inhibit_case<chlit<wchar_t> >(ch); }
|
||||
|
||||
template <typename ParserT>
|
||||
static inhibit_case<ParserT>
|
||||
generate(parser<ParserT> const& subject)
|
||||
{ return inhibit_case<ParserT>(subject.derived()); }
|
||||
|
||||
inhibit_case<strlit<char const*> >
|
||||
operator[](char const* str) const
|
||||
{ return inhibit_case<strlit<char const*> >(str); }
|
||||
|
||||
inhibit_case<strlit<wchar_t const*> >
|
||||
operator[](wchar_t const* str) const
|
||||
{ return inhibit_case<strlit<wchar_t const*> >(str); }
|
||||
|
||||
inhibit_case<chlit<char> >
|
||||
operator[](char ch) const
|
||||
{ return inhibit_case<chlit<char> >(ch); }
|
||||
|
||||
inhibit_case<chlit<wchar_t> >
|
||||
operator[](wchar_t ch) const
|
||||
{ return inhibit_case<chlit<wchar_t> >(ch); }
|
||||
|
||||
template <typename ParserT>
|
||||
inhibit_case<ParserT>
|
||||
operator[](parser<ParserT> const& subject) const
|
||||
{ return inhibit_case<ParserT>(subject.derived()); }
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
struct inhibit_case_parser_gen : public inhibit_case_parser_gen_base<0>
|
||||
{
|
||||
inhibit_case_parser_gen() {}
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
// Depracated
|
||||
const inhibit_case_parser_gen nocase_d = inhibit_case_parser_gen();
|
||||
|
||||
// Preferred syntax
|
||||
const inhibit_case_parser_gen as_lower_d = inhibit_case_parser_gen();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// as_lower_scanner
|
||||
//
|
||||
// Given a Scanner, return the correct scanner type that
|
||||
// the as_lower_d uses. Scanner is assumed to be a scanner
|
||||
// with an inhibit_case_iteration_policy.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename ScannerT>
|
||||
struct as_lower_scanner
|
||||
{
|
||||
typedef scanner_policies<
|
||||
inhibit_case_iteration_policy<
|
||||
typename ScannerT::iteration_policy_t>,
|
||||
typename ScannerT::match_policy_t,
|
||||
typename ScannerT::action_policy_t
|
||||
> policies_t;
|
||||
|
||||
typedef typename
|
||||
rebind_scanner_policies<ScannerT, policies_t>::type type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// longest_alternative class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct longest_parser_gen;
|
||||
|
||||
template <typename A, typename B>
|
||||
struct longest_alternative
|
||||
: public binary<A, B, parser<longest_alternative<A, B> > >
|
||||
{
|
||||
typedef longest_alternative<A, B> self_t;
|
||||
typedef binary_parser_category parser_category_t;
|
||||
typedef longest_parser_gen parser_generator_t;
|
||||
typedef binary<A, B, parser<self_t> > base_t;
|
||||
|
||||
longest_alternative(A const& a, B const& b)
|
||||
: base_t(a, b) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
typename ScannerT::iterator_t save = scan.first;
|
||||
result_t l = this->left().parse(scan);
|
||||
std::swap(scan.first, save);
|
||||
result_t r = this->right().parse(scan);
|
||||
|
||||
if (l || r)
|
||||
{
|
||||
if (l.length() > r.length())
|
||||
{
|
||||
scan.first = save;
|
||||
return l;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
return scan.no_match();
|
||||
}
|
||||
};
|
||||
|
||||
struct longest_parser_gen
|
||||
{
|
||||
template <typename A, typename B>
|
||||
struct result {
|
||||
|
||||
typedef typename
|
||||
impl::to_longest_alternative<alternative<A, B> >::result_t
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
static typename
|
||||
impl::to_longest_alternative<alternative<A, B> >::result_t
|
||||
generate(alternative<A, B> const& alt)
|
||||
{
|
||||
return impl::to_longest_alternative<alternative<A, B> >::
|
||||
convert(alt);
|
||||
}
|
||||
|
||||
//'generate' for binary composite
|
||||
template <typename A, typename B>
|
||||
static
|
||||
longest_alternative<A, B>
|
||||
generate(A const &left, B const &right)
|
||||
{
|
||||
return longest_alternative<A, B>(left, right);
|
||||
}
|
||||
|
||||
template <typename A, typename B>
|
||||
typename impl::to_longest_alternative<alternative<A, B> >::result_t
|
||||
operator[](alternative<A, B> const& alt) const
|
||||
{
|
||||
return impl::to_longest_alternative<alternative<A, B> >::
|
||||
convert(alt);
|
||||
}
|
||||
};
|
||||
|
||||
const longest_parser_gen longest_d = longest_parser_gen();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// shortest_alternative class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct shortest_parser_gen;
|
||||
|
||||
template <typename A, typename B>
|
||||
struct shortest_alternative
|
||||
: public binary<A, B, parser<shortest_alternative<A, B> > >
|
||||
{
|
||||
typedef shortest_alternative<A, B> self_t;
|
||||
typedef binary_parser_category parser_category_t;
|
||||
typedef shortest_parser_gen parser_generator_t;
|
||||
typedef binary<A, B, parser<self_t> > base_t;
|
||||
|
||||
shortest_alternative(A const& a, B const& b)
|
||||
: base_t(a, b) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
typename ScannerT::iterator_t save = scan.first;
|
||||
result_t l = this->left().parse(scan);
|
||||
std::swap(scan.first, save);
|
||||
result_t r = this->right().parse(scan);
|
||||
|
||||
if (l || r)
|
||||
{
|
||||
if ((l.length() < r.length() && l) || !r)
|
||||
{
|
||||
scan.first = save;
|
||||
return l;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
return scan.no_match();
|
||||
}
|
||||
};
|
||||
|
||||
struct shortest_parser_gen
|
||||
{
|
||||
template <typename A, typename B>
|
||||
struct result {
|
||||
|
||||
typedef typename
|
||||
impl::to_shortest_alternative<alternative<A, B> >::result_t
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
static typename
|
||||
impl::to_shortest_alternative<alternative<A, B> >::result_t
|
||||
generate(alternative<A, B> const& alt)
|
||||
{
|
||||
return impl::to_shortest_alternative<alternative<A, B> >::
|
||||
convert(alt);
|
||||
}
|
||||
|
||||
//'generate' for binary composite
|
||||
template <typename A, typename B>
|
||||
static
|
||||
shortest_alternative<A, B>
|
||||
generate(A const &left, B const &right)
|
||||
{
|
||||
return shortest_alternative<A, B>(left, right);
|
||||
}
|
||||
|
||||
template <typename A, typename B>
|
||||
typename impl::to_shortest_alternative<alternative<A, B> >::result_t
|
||||
operator[](alternative<A, B> const& alt) const
|
||||
{
|
||||
return impl::to_shortest_alternative<alternative<A, B> >::
|
||||
convert(alt);
|
||||
}
|
||||
};
|
||||
|
||||
const shortest_parser_gen shortest_d = shortest_parser_gen();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// min_bounded class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename BoundsT>
|
||||
struct min_bounded_gen;
|
||||
|
||||
template <typename ParserT, typename BoundsT>
|
||||
struct min_bounded
|
||||
: public unary<ParserT, parser<min_bounded<ParserT, BoundsT> > >
|
||||
{
|
||||
typedef min_bounded<ParserT, BoundsT> self_t;
|
||||
typedef unary_parser_category parser_category_t;
|
||||
typedef min_bounded_gen<BoundsT> parser_generator_t;
|
||||
typedef unary<ParserT, parser<self_t> > base_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename parser_result<ParserT, ScannerT>::type type;
|
||||
};
|
||||
|
||||
min_bounded(ParserT const& p, BoundsT const& min__)
|
||||
: base_t(p)
|
||||
, min_(min__) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
result_t hit = this->subject().parse(scan);
|
||||
if (hit.has_valid_attribute() && hit.value() < min_)
|
||||
return scan.no_match();
|
||||
return hit;
|
||||
}
|
||||
|
||||
BoundsT min_;
|
||||
};
|
||||
|
||||
template <typename BoundsT>
|
||||
struct min_bounded_gen
|
||||
{
|
||||
min_bounded_gen(BoundsT const& min__)
|
||||
: min_(min__) {}
|
||||
|
||||
template <typename DerivedT>
|
||||
min_bounded<DerivedT, BoundsT>
|
||||
operator[](parser<DerivedT> const& p) const
|
||||
{ return min_bounded<DerivedT, BoundsT>(p.derived(), min_); }
|
||||
|
||||
BoundsT min_;
|
||||
};
|
||||
|
||||
template <typename BoundsT>
|
||||
inline min_bounded_gen<BoundsT>
|
||||
min_limit_d(BoundsT const& min_)
|
||||
{ return min_bounded_gen<BoundsT>(min_); }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// max_bounded class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename BoundsT>
|
||||
struct max_bounded_gen;
|
||||
|
||||
template <typename ParserT, typename BoundsT>
|
||||
struct max_bounded
|
||||
: public unary<ParserT, parser<max_bounded<ParserT, BoundsT> > >
|
||||
{
|
||||
typedef max_bounded<ParserT, BoundsT> self_t;
|
||||
typedef unary_parser_category parser_category_t;
|
||||
typedef max_bounded_gen<BoundsT> parser_generator_t;
|
||||
typedef unary<ParserT, parser<self_t> > base_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename parser_result<ParserT, ScannerT>::type type;
|
||||
};
|
||||
|
||||
max_bounded(ParserT const& p, BoundsT const& max__)
|
||||
: base_t(p)
|
||||
, max_(max__) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
result_t hit = this->subject().parse(scan);
|
||||
if (hit.has_valid_attribute() && hit.value() > max_)
|
||||
return scan.no_match();
|
||||
return hit;
|
||||
}
|
||||
|
||||
BoundsT max_;
|
||||
};
|
||||
|
||||
template <typename BoundsT>
|
||||
struct max_bounded_gen
|
||||
{
|
||||
max_bounded_gen(BoundsT const& max__)
|
||||
: max_(max__) {}
|
||||
|
||||
template <typename DerivedT>
|
||||
max_bounded<DerivedT, BoundsT>
|
||||
operator[](parser<DerivedT> const& p) const
|
||||
{ return max_bounded<DerivedT, BoundsT>(p.derived(), max_); }
|
||||
|
||||
BoundsT max_;
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename BoundsT>
|
||||
inline max_bounded_gen<BoundsT>
|
||||
max_limit_d(BoundsT const& max_)
|
||||
{ return max_bounded_gen<BoundsT>(max_); }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// bounded class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename BoundsT>
|
||||
struct bounded_gen;
|
||||
|
||||
template <typename ParserT, typename BoundsT>
|
||||
struct bounded
|
||||
: public unary<ParserT, parser<bounded<ParserT, BoundsT> > >
|
||||
{
|
||||
typedef bounded<ParserT, BoundsT> self_t;
|
||||
typedef unary_parser_category parser_category_t;
|
||||
typedef bounded_gen<BoundsT> parser_generator_t;
|
||||
typedef unary<ParserT, parser<self_t> > base_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename parser_result<ParserT, ScannerT>::type type;
|
||||
};
|
||||
|
||||
bounded(ParserT const& p, BoundsT const& min__, BoundsT const& max__)
|
||||
: base_t(p)
|
||||
, min_(min__)
|
||||
, max_(max__) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
result_t hit = this->subject().parse(scan);
|
||||
if (hit.has_valid_attribute() &&
|
||||
(hit.value() < min_ || hit.value() > max_))
|
||||
return scan.no_match();
|
||||
return hit;
|
||||
}
|
||||
|
||||
BoundsT min_, max_;
|
||||
};
|
||||
|
||||
template <typename BoundsT>
|
||||
struct bounded_gen
|
||||
{
|
||||
bounded_gen(BoundsT const& min__, BoundsT const& max__)
|
||||
: min_(min__)
|
||||
, max_(max__) {}
|
||||
|
||||
template <typename DerivedT>
|
||||
bounded<DerivedT, BoundsT>
|
||||
operator[](parser<DerivedT> const& p) const
|
||||
{ return bounded<DerivedT, BoundsT>(p.derived(), min_, max_); }
|
||||
|
||||
BoundsT min_, max_;
|
||||
};
|
||||
|
||||
template <typename BoundsT>
|
||||
inline bounded_gen<BoundsT>
|
||||
limit_d(BoundsT const& min_, BoundsT const& max_)
|
||||
{ return bounded_gen<BoundsT>(min_, max_); }
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,276 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2002-2003 Martin Wille
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_EPSILON_HPP
|
||||
#define BOOST_SPIRIT_EPSILON_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/meta/parser_traits.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/no_actions.hpp>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// condition_parser class
|
||||
//
|
||||
// handles expresions of the form
|
||||
//
|
||||
// epsilon_p(cond)
|
||||
//
|
||||
// where cond is a function or a functor that returns a value suitable
|
||||
// to be used in boolean context. The expression returns a parser that
|
||||
// returns an empty match when the condition evaluates to true.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CondT, bool positive_ = true>
|
||||
struct condition_parser : parser<condition_parser<CondT, positive_> >
|
||||
{
|
||||
typedef condition_parser<CondT, positive_> self_t;
|
||||
|
||||
// not explicit! (needed for implementation of if_p et al.)
|
||||
condition_parser(CondT const& cond_) : cond(cond_) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
if (positive_ == bool(cond())) // allow cond to return int
|
||||
return scan.empty_match();
|
||||
else
|
||||
return scan.no_match();
|
||||
}
|
||||
|
||||
condition_parser<CondT, !positive_>
|
||||
negate() const
|
||||
{ return condition_parser<CondT, !positive_>(cond); }
|
||||
|
||||
private:
|
||||
|
||||
CondT cond;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, == 1310) || \
|
||||
BOOST_WORKAROUND(BOOST_MSVC, == 1400) || \
|
||||
BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580)
|
||||
// VC 7.1, VC8 and Sun CC <= 5.8 do not support general
|
||||
// expressions of non-type template parameters in instantiations
|
||||
template <typename CondT>
|
||||
inline condition_parser<CondT, false>
|
||||
operator~(condition_parser<CondT, true> const& p)
|
||||
{ return p.negate(); }
|
||||
|
||||
template <typename CondT>
|
||||
inline condition_parser<CondT, true>
|
||||
operator~(condition_parser<CondT, false> const& p)
|
||||
{ return p.negate(); }
|
||||
#else // BOOST_WORKAROUND(BOOST_MSVC, == 1310) || == 1400
|
||||
template <typename CondT, bool positive>
|
||||
inline condition_parser<CondT, !positive>
|
||||
operator~(condition_parser<CondT, positive> const& p)
|
||||
{ return p.negate(); }
|
||||
#endif // BOOST_WORKAROUND(BOOST_MSVC, == 1310) || == 1400
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// empty_match_parser class
|
||||
//
|
||||
// handles expressions of the form
|
||||
// epsilon_p(subject)
|
||||
// where subject is a parser. The expresion returns a composite
|
||||
// parser that returns an empty match if the subject parser matches.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct empty_match_parser_gen;
|
||||
struct negated_empty_match_parser_gen;
|
||||
|
||||
template <typename SubjectT>
|
||||
struct negated_empty_match_parser; // Forward declaration
|
||||
|
||||
template<typename SubjectT>
|
||||
struct empty_match_parser
|
||||
: unary<SubjectT, parser<empty_match_parser<SubjectT> > >
|
||||
{
|
||||
typedef empty_match_parser<SubjectT> self_t;
|
||||
typedef unary<SubjectT, parser<self_t> > base_t;
|
||||
typedef unary_parser_category parser_category_t;
|
||||
typedef empty_match_parser_gen parser_genererator_t;
|
||||
typedef self_t embed_t;
|
||||
|
||||
explicit empty_match_parser(SubjectT const& p) : base_t(p) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{ typedef typename match_result<ScannerT, nil_t>::type type; };
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typename ScannerT::iterator_t save(scan.first);
|
||||
|
||||
typedef typename no_actions_scanner<ScannerT>::policies_t
|
||||
policies_t;
|
||||
|
||||
bool matches = this->subject().parse(
|
||||
scan.change_policies(policies_t(scan)));
|
||||
if (matches)
|
||||
{
|
||||
scan.first = save; // reset the position
|
||||
return scan.empty_match();
|
||||
}
|
||||
else
|
||||
{
|
||||
return scan.no_match();
|
||||
}
|
||||
}
|
||||
|
||||
negated_empty_match_parser<SubjectT>
|
||||
negate() const
|
||||
{ return negated_empty_match_parser<SubjectT>(this->subject()); }
|
||||
};
|
||||
|
||||
template<typename SubjectT>
|
||||
struct negated_empty_match_parser
|
||||
: public unary<SubjectT, parser<negated_empty_match_parser<SubjectT> > >
|
||||
{
|
||||
typedef negated_empty_match_parser<SubjectT> self_t;
|
||||
typedef unary<SubjectT, parser<self_t> > base_t;
|
||||
typedef unary_parser_category parser_category_t;
|
||||
typedef negated_empty_match_parser_gen parser_genererator_t;
|
||||
|
||||
explicit negated_empty_match_parser(SubjectT const& p) : base_t(p) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{ typedef typename match_result<ScannerT, nil_t>::type type; };
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typename ScannerT::iterator_t save(scan.first);
|
||||
|
||||
typedef typename no_actions_scanner<ScannerT>::policies_t
|
||||
policies_t;
|
||||
|
||||
bool matches = this->subject().parse(
|
||||
scan.change_policies(policies_t(scan)));
|
||||
if (!matches)
|
||||
{
|
||||
scan.first = save; // reset the position
|
||||
return scan.empty_match();
|
||||
}
|
||||
else
|
||||
{
|
||||
return scan.no_match();
|
||||
}
|
||||
}
|
||||
|
||||
empty_match_parser<SubjectT>
|
||||
negate() const
|
||||
{ return empty_match_parser<SubjectT>(this->subject()); }
|
||||
};
|
||||
|
||||
struct empty_match_parser_gen
|
||||
{
|
||||
template <typename SubjectT>
|
||||
struct result
|
||||
{ typedef empty_match_parser<SubjectT> type; };
|
||||
|
||||
template <typename SubjectT>
|
||||
static empty_match_parser<SubjectT>
|
||||
generate(parser<SubjectT> const& subject)
|
||||
{ return empty_match_parser<SubjectT>(subject.derived()); }
|
||||
};
|
||||
|
||||
struct negated_empty_match_parser_gen
|
||||
{
|
||||
template <typename SubjectT>
|
||||
struct result
|
||||
{ typedef negated_empty_match_parser<SubjectT> type; };
|
||||
|
||||
template <typename SubjectT>
|
||||
static negated_empty_match_parser<SubjectT>
|
||||
generate(parser<SubjectT> const& subject)
|
||||
{ return negated_empty_match_parser<SubjectT>(subject.derived()); }
|
||||
};
|
||||
|
||||
//////////////////////////////
|
||||
template <typename SubjectT>
|
||||
inline negated_empty_match_parser<SubjectT>
|
||||
operator~(empty_match_parser<SubjectT> const& p)
|
||||
{ return p.negate(); }
|
||||
|
||||
template <typename SubjectT>
|
||||
inline empty_match_parser<SubjectT>
|
||||
operator~(negated_empty_match_parser<SubjectT> const& p)
|
||||
{ return p.negate(); }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// epsilon_ parser and parser generator class
|
||||
//
|
||||
// Operates as primitive parser that always matches an empty sequence.
|
||||
//
|
||||
// Also operates as a parser generator. According to the type of the
|
||||
// argument an instance of empty_match_parser<> (when the argument is
|
||||
// a parser) or condition_parser<> (when the argument is not a parser)
|
||||
// is returned by operator().
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace impl
|
||||
{
|
||||
template <typename SubjectT>
|
||||
struct epsilon_selector
|
||||
{
|
||||
typedef typename as_parser<SubjectT>::type subject_t;
|
||||
typedef typename
|
||||
mpl::if_<
|
||||
is_parser<subject_t>
|
||||
,empty_match_parser<subject_t>
|
||||
,condition_parser<subject_t>
|
||||
>::type type;
|
||||
};
|
||||
}
|
||||
|
||||
struct epsilon_parser : public parser<epsilon_parser>
|
||||
{
|
||||
typedef epsilon_parser self_t;
|
||||
|
||||
epsilon_parser() {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{ return scan.empty_match(); }
|
||||
|
||||
template <typename SubjectT>
|
||||
typename impl::epsilon_selector<SubjectT>::type
|
||||
operator()(SubjectT const& subject) const
|
||||
{
|
||||
typedef typename impl::epsilon_selector<SubjectT>::type result_t;
|
||||
return result_t(subject);
|
||||
}
|
||||
};
|
||||
|
||||
epsilon_parser const epsilon_p = epsilon_parser();
|
||||
epsilon_parser const eps_p = epsilon_parser();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,142 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_EXCLUSIVE_OR_HPP)
|
||||
#define BOOST_SPIRIT_EXCLUSIVE_OR_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/meta/as_parser.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// exclusive_or class
|
||||
//
|
||||
// Handles expressions of the form:
|
||||
//
|
||||
// a ^ b
|
||||
//
|
||||
// where a and b are parsers. The expression returns a composite
|
||||
// parser that matches a or b but not both. One (not both) of the
|
||||
// operands may be a literal char, wchar_t or a primitive string
|
||||
// char const*, wchar_t const*.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct exclusive_or_parser_gen;
|
||||
|
||||
template <typename A, typename B>
|
||||
struct exclusive_or
|
||||
: public binary<A, B, parser<exclusive_or<A, B> > >
|
||||
{
|
||||
typedef exclusive_or<A, B> self_t;
|
||||
typedef binary_parser_category parser_category_t;
|
||||
typedef exclusive_or_parser_gen parser_generator_t;
|
||||
typedef binary<A, B, parser<self_t> > base_t;
|
||||
|
||||
exclusive_or(A const& a, B const& b)
|
||||
: base_t(a, b) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
typedef typename ScannerT::iterator_t iterator_t;
|
||||
|
||||
iterator_t save = scan.first;
|
||||
result_t l = this->left().parse(scan);
|
||||
std::swap(save, scan.first);
|
||||
result_t r = this->right().parse(scan);
|
||||
|
||||
if (l ? !bool(r) : bool(r))
|
||||
{
|
||||
if (l)
|
||||
scan.first = save;
|
||||
return l ? l : r;
|
||||
}
|
||||
|
||||
return scan.no_match();
|
||||
}
|
||||
};
|
||||
|
||||
struct exclusive_or_parser_gen
|
||||
{
|
||||
template <typename A, typename B>
|
||||
struct result
|
||||
{
|
||||
typedef
|
||||
exclusive_or<
|
||||
typename as_parser<A>::type
|
||||
, typename as_parser<B>::type
|
||||
>
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
static exclusive_or<
|
||||
typename as_parser<A>::type
|
||||
, typename as_parser<B>::type
|
||||
>
|
||||
generate(A const& a, B const& b)
|
||||
{
|
||||
return exclusive_or<BOOST_DEDUCED_TYPENAME as_parser<A>::type,
|
||||
BOOST_DEDUCED_TYPENAME as_parser<B>::type>
|
||||
(as_parser<A>::convert(a), as_parser<B>::convert(b));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
exclusive_or<A, B>
|
||||
operator^(parser<A> const& a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
exclusive_or<A, chlit<char> >
|
||||
operator^(parser<A> const& a, char b);
|
||||
|
||||
template <typename B>
|
||||
exclusive_or<chlit<char>, B>
|
||||
operator^(char a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
exclusive_or<A, strlit<char const*> >
|
||||
operator^(parser<A> const& a, char const* b);
|
||||
|
||||
template <typename B>
|
||||
exclusive_or<strlit<char const*>, B>
|
||||
operator^(char const* a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
exclusive_or<A, chlit<wchar_t> >
|
||||
operator^(parser<A> const& a, wchar_t b);
|
||||
|
||||
template <typename B>
|
||||
exclusive_or<chlit<wchar_t>, B>
|
||||
operator^(wchar_t a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
exclusive_or<A, strlit<wchar_t const*> >
|
||||
operator^(parser<A> const& a, wchar_t const* b);
|
||||
|
||||
template <typename B>
|
||||
exclusive_or<strlit<wchar_t const*>, B>
|
||||
operator^(wchar_t const* a, parser<B> const& b);
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/classic/core/composite/impl/exclusive_or.ipp>
|
||||
@@ -0,0 +1,90 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_ALTERNATIVE_IPP)
|
||||
#define BOOST_SPIRIT_ALTERNATIVE_IPP
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// alternative class implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A, typename B>
|
||||
inline alternative<A, B>
|
||||
operator|(parser<A> const& a, parser<B> const& b)
|
||||
{
|
||||
return alternative<A, B>(a.derived(), b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline alternative<A, chlit<char> >
|
||||
operator|(parser<A> const& a, char b)
|
||||
{
|
||||
return alternative<A, chlit<char> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline alternative<chlit<char>, B>
|
||||
operator|(char a, parser<B> const& b)
|
||||
{
|
||||
return alternative<chlit<char>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline alternative<A, strlit<char const*> >
|
||||
operator|(parser<A> const& a, char const* b)
|
||||
{
|
||||
return alternative<A, strlit<char const*> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline alternative<strlit<char const*>, B>
|
||||
operator|(char const* a, parser<B> const& b)
|
||||
{
|
||||
return alternative<strlit<char const*>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline alternative<A, chlit<wchar_t> >
|
||||
operator|(parser<A> const& a, wchar_t b)
|
||||
{
|
||||
return alternative<A, chlit<wchar_t> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline alternative<chlit<wchar_t>, B>
|
||||
operator|(wchar_t a, parser<B> const& b)
|
||||
{
|
||||
return alternative<chlit<wchar_t>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline alternative<A, strlit<wchar_t const*> >
|
||||
operator|(parser<A> const& a, wchar_t const* b)
|
||||
{
|
||||
return alternative<A, strlit<wchar_t const*> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline alternative<strlit<wchar_t const*>, B>
|
||||
operator|(wchar_t const* a, parser<B> const& b)
|
||||
{
|
||||
return alternative<strlit<wchar_t const*>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,90 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_DIFFERENCE_IPP)
|
||||
#define BOOST_SPIRIT_DIFFERENCE_IPP
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// difference class implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A, typename B>
|
||||
inline difference<A, B>
|
||||
operator-(parser<A> const& a, parser<B> const& b)
|
||||
{
|
||||
return difference<A, B>(a.derived(), b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline difference<A, chlit<char> >
|
||||
operator-(parser<A> const& a, char b)
|
||||
{
|
||||
return difference<A, chlit<char> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline difference<chlit<char>, B>
|
||||
operator-(char a, parser<B> const& b)
|
||||
{
|
||||
return difference<chlit<char>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline difference<A, strlit<char const*> >
|
||||
operator-(parser<A> const& a, char const* b)
|
||||
{
|
||||
return difference<A, strlit<char const*> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline difference<strlit<char const*>, B>
|
||||
operator-(char const* a, parser<B> const& b)
|
||||
{
|
||||
return difference<strlit<char const*>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline difference<A, chlit<wchar_t> >
|
||||
operator-(parser<A> const& a, wchar_t b)
|
||||
{
|
||||
return difference<A, chlit<wchar_t> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline difference<chlit<wchar_t>, B>
|
||||
operator-(wchar_t a, parser<B> const& b)
|
||||
{
|
||||
return difference<chlit<wchar_t>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline difference<A, strlit<wchar_t const*> >
|
||||
operator-(parser<A> const& a, wchar_t const* b)
|
||||
{
|
||||
return difference<A, strlit<wchar_t const*> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline difference<strlit<wchar_t const*>, B>
|
||||
operator-(wchar_t const* a, parser<B> const& b)
|
||||
{
|
||||
return difference<strlit<wchar_t const*>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,374 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2001 Bruce Florman
|
||||
Copyright (c) 2002 Raghavendra Satish
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_DIRECTIVES_IPP)
|
||||
#define BOOST_SPIRIT_DIRECTIVES_IPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/spirit/home/classic/core/scanner/skipper.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
template <typename BaseT>
|
||||
struct no_skipper_iteration_policy;
|
||||
|
||||
template <typename BaseT>
|
||||
struct inhibit_case_iteration_policy;
|
||||
|
||||
template <typename A, typename B>
|
||||
struct alternative;
|
||||
|
||||
template <typename A, typename B>
|
||||
struct longest_alternative;
|
||||
|
||||
template <typename A, typename B>
|
||||
struct shortest_alternative;
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template <typename RT, typename ST, typename ScannerT, typename BaseT>
|
||||
inline RT
|
||||
contiguous_parser_parse(
|
||||
ST const& s,
|
||||
ScannerT const& scan,
|
||||
skipper_iteration_policy<BaseT> const&)
|
||||
{
|
||||
typedef scanner_policies<
|
||||
no_skipper_iteration_policy<
|
||||
BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>,
|
||||
BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t,
|
||||
BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t
|
||||
> policies_t;
|
||||
|
||||
scan.skip(scan);
|
||||
RT hit = s.parse(scan.change_policies(policies_t(scan)));
|
||||
// We will not do a post skip!!!
|
||||
return hit;
|
||||
}
|
||||
|
||||
template <typename RT, typename ST, typename ScannerT, typename BaseT>
|
||||
inline RT
|
||||
contiguous_parser_parse(
|
||||
ST const& s,
|
||||
ScannerT const& scan,
|
||||
no_skipper_iteration_policy<BaseT> const&)
|
||||
{
|
||||
return s.parse(scan);
|
||||
}
|
||||
|
||||
template <typename RT, typename ST, typename ScannerT>
|
||||
inline RT
|
||||
contiguous_parser_parse(
|
||||
ST const& s,
|
||||
ScannerT const& scan,
|
||||
iteration_policy const&)
|
||||
{
|
||||
return s.parse(scan);
|
||||
}
|
||||
|
||||
template <
|
||||
typename RT,
|
||||
typename ParserT,
|
||||
typename ScannerT,
|
||||
typename BaseT>
|
||||
inline RT
|
||||
implicit_lexeme_parse(
|
||||
ParserT const& p,
|
||||
ScannerT const& scan,
|
||||
skipper_iteration_policy<BaseT> const&)
|
||||
{
|
||||
typedef scanner_policies<
|
||||
no_skipper_iteration_policy<
|
||||
BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>,
|
||||
BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t,
|
||||
BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t
|
||||
> policies_t;
|
||||
|
||||
scan.skip(scan);
|
||||
RT hit = p.parse_main(scan.change_policies(policies_t(scan)));
|
||||
// We will not do a post skip!!!
|
||||
return hit;
|
||||
}
|
||||
|
||||
template <
|
||||
typename RT,
|
||||
typename ParserT,
|
||||
typename ScannerT,
|
||||
typename BaseT>
|
||||
inline RT
|
||||
implicit_lexeme_parse(
|
||||
ParserT const& p,
|
||||
ScannerT const& scan,
|
||||
no_skipper_iteration_policy<BaseT> const&)
|
||||
{
|
||||
return p.parse_main(scan);
|
||||
}
|
||||
|
||||
template <typename RT, typename ParserT, typename ScannerT>
|
||||
inline RT
|
||||
implicit_lexeme_parse(
|
||||
ParserT const& p,
|
||||
ScannerT const& scan,
|
||||
iteration_policy const&)
|
||||
{
|
||||
return p.parse_main(scan);
|
||||
}
|
||||
|
||||
template <typename RT, typename ST, typename ScannerT>
|
||||
inline RT
|
||||
inhibit_case_parser_parse(
|
||||
ST const& s,
|
||||
ScannerT const& scan,
|
||||
iteration_policy const&)
|
||||
{
|
||||
typedef scanner_policies<
|
||||
inhibit_case_iteration_policy<
|
||||
BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>,
|
||||
BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t,
|
||||
BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t
|
||||
> policies_t;
|
||||
|
||||
return s.parse(scan.change_policies(policies_t(scan)));
|
||||
}
|
||||
|
||||
template <typename RT, typename ST, typename ScannerT, typename BaseT>
|
||||
inline RT
|
||||
inhibit_case_parser_parse(
|
||||
ST const& s,
|
||||
ScannerT const& scan,
|
||||
inhibit_case_iteration_policy<BaseT> const&)
|
||||
{
|
||||
return s.parse(scan);
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// from spirit 1.1 (copyright (c) 2001 Bruce Florman)
|
||||
// various workarounds to support longest and shortest directives
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct is_alternative
|
||||
{
|
||||
// Determine at compile time (without partial specialization)
|
||||
// whether a given type is an instance of the alternative<A,B>
|
||||
|
||||
static T t();
|
||||
template <typename A, typename B>
|
||||
static char test_(alternative<A, B> const&); // no implementation
|
||||
static int test_(...); // no implementation
|
||||
enum { r = sizeof(char) == sizeof(test_(t())) };
|
||||
typedef mpl::bool_<r> value;
|
||||
};
|
||||
|
||||
template <typename T> struct select_to_longest;
|
||||
|
||||
template <typename T>
|
||||
struct to_longest_alternative
|
||||
{
|
||||
typedef typename select_to_longest<T>::result_t result_t;
|
||||
typedef typename select_to_longest<T>::plain_t plain_t;
|
||||
typedef typename select_to_longest<T>::choose_t choose_t;
|
||||
static result_t convert(T const& a);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct to_longest_generic
|
||||
{
|
||||
typedef T const& result_t;
|
||||
typedef T plain_t;
|
||||
typedef mpl::false_ choose_t;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline T const&
|
||||
to_longest_convert(T const& a, mpl::false_)
|
||||
{ return a; }
|
||||
|
||||
template <typename T>
|
||||
struct to_longest_recursive
|
||||
{
|
||||
typedef typename to_longest_alternative<
|
||||
typename T::left_t>::plain_t a_t;
|
||||
typedef typename to_longest_alternative<
|
||||
typename T::right_t>::plain_t b_t;
|
||||
|
||||
typedef longest_alternative<a_t, b_t> result_t;
|
||||
|
||||
typedef result_t plain_t;
|
||||
typedef mpl::true_ choose_t;
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
inline typename to_longest_alternative<alternative<A, B> >::result_t
|
||||
to_longest_convert(alternative<A, B> const& alt, mpl::true_)
|
||||
{
|
||||
typedef typename to_longest_alternative<
|
||||
alternative<A, B> >::result_t result_t;
|
||||
return result_t(
|
||||
to_longest_alternative<A>::convert(alt.left()),
|
||||
to_longest_alternative<B>::convert(alt.right()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline typename to_longest_alternative<T>::result_t
|
||||
to_longest_alternative<T>::convert(T const& a)
|
||||
{
|
||||
return to_longest_convert(
|
||||
a, to_longest_alternative<T>::choose_t());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct select_to_longest
|
||||
{
|
||||
typedef typename mpl::if_<
|
||||
is_alternative<T> // IF
|
||||
, to_longest_recursive<T> // THEN
|
||||
, to_longest_generic<T> // ELSE
|
||||
>::type type;
|
||||
|
||||
typedef typename select_to_longest::type::result_t result_t;
|
||||
typedef typename select_to_longest::type::plain_t plain_t;
|
||||
typedef typename select_to_longest::type::choose_t choose_t;
|
||||
};
|
||||
|
||||
template <typename T> struct select_to_shortest;
|
||||
|
||||
template <typename T>
|
||||
struct to_shortest_alternative
|
||||
{
|
||||
typedef typename select_to_shortest<T>::result_t result_t;
|
||||
typedef typename select_to_shortest<T>::plain_t plain_t;
|
||||
typedef typename select_to_shortest<T>::choose_t choose_t;
|
||||
static result_t convert(T const& a);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct to_shortest_generic
|
||||
{
|
||||
typedef T const& result_t;
|
||||
typedef T plain_t;
|
||||
typedef mpl::false_ choose_t;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline T const&
|
||||
to_shortest_convert(T const& a, mpl::false_) { return a; }
|
||||
|
||||
template <typename T>
|
||||
struct to_shortest_recursive
|
||||
{
|
||||
typedef typename to_shortest_alternative<
|
||||
typename T::left_t>::plain_t a_t;
|
||||
typedef typename to_shortest_alternative<
|
||||
typename T::right_t>::plain_t b_t;
|
||||
|
||||
typedef shortest_alternative<a_t, b_t> result_t;
|
||||
|
||||
typedef result_t plain_t;
|
||||
typedef mpl::true_ choose_t;
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
inline typename to_shortest_alternative<alternative<A, B> >::result_t
|
||||
to_shortest_convert(alternative<A, B> const& alt, mpl::true_)
|
||||
{
|
||||
typedef typename to_shortest_alternative<
|
||||
alternative<A, B> >::result_t result_t;
|
||||
return result_t(
|
||||
to_shortest_alternative<A>::convert(alt.left()),
|
||||
to_shortest_alternative<B>::convert(alt.right()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline typename to_shortest_alternative<T>::result_t
|
||||
to_shortest_alternative<T>::convert(T const& a)
|
||||
{
|
||||
return to_shortest_convert(
|
||||
a, to_shortest_alternative<T>::choose_t());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct select_to_shortest
|
||||
{
|
||||
typedef typename mpl::if_<
|
||||
is_alternative<T> // IF
|
||||
, to_shortest_recursive<T> // THEN
|
||||
, to_shortest_generic<T> // ELSE
|
||||
>::type type;
|
||||
|
||||
typedef typename select_to_shortest::type::result_t result_t;
|
||||
typedef typename select_to_shortest::type::plain_t plain_t;
|
||||
typedef typename select_to_shortest::type::choose_t choose_t;
|
||||
};
|
||||
#else
|
||||
template <typename T>
|
||||
struct to_longest_alternative
|
||||
{
|
||||
typedef T result_t;
|
||||
static result_t const&
|
||||
convert(T const& a) // Special (end) case
|
||||
{ return a; }
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
struct to_longest_alternative<alternative<A, B> >
|
||||
{
|
||||
typedef typename to_longest_alternative<A>::result_t a_t;
|
||||
typedef typename to_longest_alternative<B>::result_t b_t;
|
||||
typedef longest_alternative<a_t, b_t> result_t;
|
||||
|
||||
static result_t
|
||||
convert(alternative<A, B> const& alt) // Recursive case
|
||||
{
|
||||
return result_t(
|
||||
to_longest_alternative<A>::convert(alt.left()),
|
||||
to_longest_alternative<B>::convert(alt.right()));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct to_shortest_alternative
|
||||
{
|
||||
typedef T result_t;
|
||||
static result_t const&
|
||||
convert(T const& a) // Special (end) case
|
||||
{ return a; }
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
struct to_shortest_alternative<alternative<A, B> >
|
||||
{
|
||||
typedef typename to_shortest_alternative<A>::result_t a_t;
|
||||
typedef typename to_shortest_alternative<B>::result_t b_t;
|
||||
typedef shortest_alternative<a_t, b_t> result_t;
|
||||
|
||||
static result_t
|
||||
convert(alternative<A, B> const& alt) // Recursive case
|
||||
{
|
||||
return result_t(
|
||||
to_shortest_alternative<A>::convert(alt.left()),
|
||||
to_shortest_alternative<B>::convert(alt.right()));
|
||||
}
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_EXCLUSIVE_OR_IPP)
|
||||
#define BOOST_SPIRIT_EXCLUSIVE_OR_IPP
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// exclusive_or class implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A, typename B>
|
||||
inline exclusive_or<A, B>
|
||||
operator^(parser<A> const& a, parser<B> const& b)
|
||||
{
|
||||
return exclusive_or<A, B>(a.derived(), b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline exclusive_or<A, chlit<char> >
|
||||
operator^(parser<A> const& a, char b)
|
||||
{
|
||||
return exclusive_or<A, chlit<char> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline exclusive_or<chlit<char>, B>
|
||||
operator^(char a, parser<B> const& b)
|
||||
{
|
||||
return exclusive_or<chlit<char>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline exclusive_or<A, strlit<char const*> >
|
||||
operator^(parser<A> const& a, char const* b)
|
||||
{
|
||||
return exclusive_or<A, strlit<char const*> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline exclusive_or<strlit<char const*>, B>
|
||||
operator^(char const* a, parser<B> const& b)
|
||||
{
|
||||
return exclusive_or<strlit<char const*>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline exclusive_or<A, chlit<wchar_t> >
|
||||
operator^(parser<A> const& a, wchar_t b)
|
||||
{
|
||||
return exclusive_or<A, chlit<wchar_t> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline exclusive_or<chlit<wchar_t>, B>
|
||||
operator^(wchar_t a, parser<B> const& b)
|
||||
{
|
||||
return exclusive_or<chlit<wchar_t>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline exclusive_or<A, strlit<wchar_t const*> >
|
||||
operator^(parser<A> const& a, wchar_t const* b)
|
||||
{
|
||||
return exclusive_or<A, strlit<wchar_t const*> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline exclusive_or<strlit<wchar_t const*>, B>
|
||||
operator^(wchar_t const* a, parser<B> const& b)
|
||||
{
|
||||
return exclusive_or<strlit<wchar_t const*>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,90 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_INTERSECTION_IPP)
|
||||
#define BOOST_SPIRIT_INTERSECTION_IPP
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// intersection class implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A, typename B>
|
||||
inline intersection<A, B>
|
||||
operator&(parser<A> const& a, parser<B> const& b)
|
||||
{
|
||||
return intersection<A, B>(a.derived(), b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline intersection<A, chlit<char> >
|
||||
operator&(parser<A> const& a, char b)
|
||||
{
|
||||
return intersection<A, chlit<char> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline intersection<chlit<char>, B>
|
||||
operator&(char a, parser<B> const& b)
|
||||
{
|
||||
return intersection<chlit<char>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline intersection<A, strlit<char const*> >
|
||||
operator&(parser<A> const& a, char const* b)
|
||||
{
|
||||
return intersection<A, strlit<char const*> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline intersection<strlit<char const*>, B>
|
||||
operator&(char const* a, parser<B> const& b)
|
||||
{
|
||||
return intersection<strlit<char const*>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline intersection<A, chlit<wchar_t> >
|
||||
operator&(parser<A> const& a, wchar_t b)
|
||||
{
|
||||
return intersection<A, chlit<wchar_t> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline intersection<chlit<wchar_t>, B>
|
||||
operator&(wchar_t a, parser<B> const& b)
|
||||
{
|
||||
return intersection<chlit<wchar_t>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline intersection<A, strlit<wchar_t const*> >
|
||||
operator&(parser<A> const& a, wchar_t const* b)
|
||||
{
|
||||
return intersection<A, strlit<wchar_t const*> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline intersection<strlit<wchar_t const*>, B>
|
||||
operator&(wchar_t const* a, parser<B> const& b)
|
||||
{
|
||||
return intersection<strlit<wchar_t const*>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_KLEENE_STAR_IPP)
|
||||
#define BOOST_SPIRIT_KLEENE_STAR_IPP
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// kleene_star class implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename S>
|
||||
inline kleene_star<S>
|
||||
operator*(parser<S> const& a)
|
||||
{
|
||||
return kleene_star<S>(a.derived());
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,93 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_LIST_IPP)
|
||||
#define BOOST_SPIRIT_LIST_IPP
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// operator% is defined as:
|
||||
// a % b ---> a >> *(b >> a)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A, typename B>
|
||||
inline sequence<A, kleene_star<sequence<B, A> > >
|
||||
operator%(parser<A> const& a, parser<B> const& b)
|
||||
{
|
||||
return a.derived() >> *(b.derived() >> a.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline sequence<A, kleene_star<sequence<chlit<char>, A> > >
|
||||
operator%(parser<A> const& a, char b)
|
||||
{
|
||||
return a.derived() >> *(b >> a.derived());
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline sequence<chlit<char>, kleene_star<sequence<B, chlit<char> > > >
|
||||
operator%(char a, parser<B> const& b)
|
||||
{
|
||||
return a >> *(b.derived() >> a);
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline sequence<A, kleene_star<sequence<strlit<char const*>, A> > >
|
||||
operator%(parser<A> const& a, char const* b)
|
||||
{
|
||||
return a.derived() >> *(b >> a.derived());
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline sequence<strlit<char const*>,
|
||||
kleene_star<sequence<B, strlit<char const*> > > >
|
||||
operator%(char const* a, parser<B> const& b)
|
||||
{
|
||||
return a >> *(b.derived() >> a);
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline sequence<A, kleene_star<sequence<chlit<wchar_t>, A> > >
|
||||
operator%(parser<A> const& a, wchar_t b)
|
||||
{
|
||||
return a.derived() >> *(b >> a.derived());
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline sequence<chlit<wchar_t>, kleene_star<sequence<B, chlit<wchar_t> > > >
|
||||
operator%(wchar_t a, parser<B> const& b)
|
||||
{
|
||||
return a >> *(b.derived() >> a);
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline sequence<A, kleene_star<sequence<strlit<wchar_t const*>, A> > >
|
||||
operator%(parser<A> const& a, wchar_t const* b)
|
||||
{
|
||||
return a.derived() >> *(b >> a.derived());
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline sequence<strlit<wchar_t const*>,
|
||||
kleene_star<sequence<B, strlit<wchar_t const*> > > >
|
||||
operator%(wchar_t const* a, parser<B> const& b)
|
||||
{
|
||||
return a >> *(b.derived() >> a);
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_OPTIONAL_IPP)
|
||||
#define BOOST_SPIRIT_OPTIONAL_IPP
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// optional class implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename S>
|
||||
optional<S>
|
||||
operator!(parser<S> const& a)
|
||||
{
|
||||
return optional<S>(a.derived());
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_POSITIVE_IPP)
|
||||
#define BOOST_SPIRIT_POSITIVE_IPP
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// positive class implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename S>
|
||||
inline positive<S>
|
||||
operator+(parser<S> const& a)
|
||||
{
|
||||
return positive<S>(a.derived());
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,90 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_SEQUENCE_IPP)
|
||||
#define BOOST_SPIRIT_SEQUENCE_IPP
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// sequence class implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A, typename B>
|
||||
inline sequence<A, B>
|
||||
operator>>(parser<A> const& a, parser<B> const& b)
|
||||
{
|
||||
return sequence<A, B>(a.derived(), b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline sequence<A, chlit<char> >
|
||||
operator>>(parser<A> const& a, char b)
|
||||
{
|
||||
return sequence<A, chlit<char> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline sequence<chlit<char>, B>
|
||||
operator>>(char a, parser<B> const& b)
|
||||
{
|
||||
return sequence<chlit<char>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline sequence<A, strlit<char const*> >
|
||||
operator>>(parser<A> const& a, char const* b)
|
||||
{
|
||||
return sequence<A, strlit<char const*> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline sequence<strlit<char const*>, B>
|
||||
operator>>(char const* a, parser<B> const& b)
|
||||
{
|
||||
return sequence<strlit<char const*>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline sequence<A, chlit<wchar_t> >
|
||||
operator>>(parser<A> const& a, wchar_t b)
|
||||
{
|
||||
return sequence<A, chlit<wchar_t> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline sequence<chlit<wchar_t>, B>
|
||||
operator>>(wchar_t a, parser<B> const& b)
|
||||
{
|
||||
return sequence<chlit<wchar_t>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline sequence<A, strlit<wchar_t const*> >
|
||||
operator>>(parser<A> const& a, wchar_t const* b)
|
||||
{
|
||||
return sequence<A, strlit<wchar_t const*> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline sequence<strlit<wchar_t const*>, B>
|
||||
operator>>(wchar_t const* a, parser<B> const& b)
|
||||
{
|
||||
return sequence<strlit<wchar_t const*>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,90 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_SEQUENTIAL_AND_IPP)
|
||||
#define BOOST_SPIRIT_SEQUENTIAL_AND_IPP
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// sequential-and operators implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A, typename B>
|
||||
inline sequence<A, B>
|
||||
operator&&(parser<A> const& a, parser<B> const& b)
|
||||
{
|
||||
return sequence<A, B>(a.derived(), b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline sequence<A, chlit<char> >
|
||||
operator&&(parser<A> const& a, char b)
|
||||
{
|
||||
return sequence<A, chlit<char> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline sequence<chlit<char>, B>
|
||||
operator&&(char a, parser<B> const& b)
|
||||
{
|
||||
return sequence<chlit<char>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline sequence<A, strlit<char const*> >
|
||||
operator&&(parser<A> const& a, char const* b)
|
||||
{
|
||||
return sequence<A, strlit<char const*> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline sequence<strlit<char const*>, B>
|
||||
operator&&(char const* a, parser<B> const& b)
|
||||
{
|
||||
return sequence<strlit<char const*>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline sequence<A, chlit<wchar_t> >
|
||||
operator&&(parser<A> const& a, wchar_t b)
|
||||
{
|
||||
return sequence<A, chlit<wchar_t> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline sequence<chlit<wchar_t>, B>
|
||||
operator&&(wchar_t a, parser<B> const& b)
|
||||
{
|
||||
return sequence<chlit<wchar_t>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline sequence<A, strlit<wchar_t const*> >
|
||||
operator&&(parser<A> const& a, wchar_t const* b)
|
||||
{
|
||||
return sequence<A, strlit<wchar_t const*> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline sequence<strlit<wchar_t const*>, B>
|
||||
operator&&(wchar_t const* a, parser<B> const& b)
|
||||
{
|
||||
return sequence<strlit<wchar_t const*>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,90 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_SEQUENTIAL_OR_IPP)
|
||||
#define BOOST_SPIRIT_SEQUENTIAL_OR_IPP
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// sequential-or class implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A, typename B>
|
||||
inline sequential_or<A, B>
|
||||
operator||(parser<A> const& a, parser<B> const& b)
|
||||
{
|
||||
return sequential_or<A, B>(a.derived(), b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline sequential_or<A, chlit<char> >
|
||||
operator||(parser<A> const& a, char b)
|
||||
{
|
||||
return sequential_or<A, chlit<char> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline sequential_or<chlit<char>, B>
|
||||
operator||(char a, parser<B> const& b)
|
||||
{
|
||||
return sequential_or<chlit<char>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline sequential_or<A, strlit<char const*> >
|
||||
operator||(parser<A> const& a, char const* b)
|
||||
{
|
||||
return sequential_or<A, strlit<char const*> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline sequential_or<strlit<char const*>, B>
|
||||
operator||(char const* a, parser<B> const& b)
|
||||
{
|
||||
return sequential_or<strlit<char const*>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline sequential_or<A, chlit<wchar_t> >
|
||||
operator||(parser<A> const& a, wchar_t b)
|
||||
{
|
||||
return sequential_or<A, chlit<wchar_t> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline sequential_or<chlit<wchar_t>, B>
|
||||
operator||(wchar_t a, parser<B> const& b)
|
||||
{
|
||||
return sequential_or<chlit<wchar_t>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
inline sequential_or<A, strlit<wchar_t const*> >
|
||||
operator||(parser<A> const& a, wchar_t const* b)
|
||||
{
|
||||
return sequential_or<A, strlit<wchar_t const*> >(a.derived(), b);
|
||||
}
|
||||
|
||||
template <typename B>
|
||||
inline sequential_or<strlit<wchar_t const*>, B>
|
||||
operator||(wchar_t const* a, parser<B> const& b)
|
||||
{
|
||||
return sequential_or<strlit<wchar_t const*>, B>(a, b.derived());
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,142 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_INTERSECTION_HPP)
|
||||
#define BOOST_SPIRIT_INTERSECTION_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/meta/as_parser.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// intersection class
|
||||
//
|
||||
// Handles expressions of the form:
|
||||
//
|
||||
// a & b
|
||||
//
|
||||
// where a and b are parsers. The expression returns a composite
|
||||
// parser that matches a and b. One (not both) of the operands may
|
||||
// be a literal char, wchar_t or a primitive string char const*,
|
||||
// wchar_t const*.
|
||||
//
|
||||
// The expression is short circuit evaluated. b is never touched
|
||||
// when a is returns a no-match.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct intersection_parser_gen;
|
||||
|
||||
template <typename A, typename B>
|
||||
struct intersection
|
||||
: public binary<A, B, parser<intersection<A, B> > >
|
||||
{
|
||||
typedef intersection<A, B> self_t;
|
||||
typedef binary_parser_category parser_category_t;
|
||||
typedef intersection_parser_gen parser_generator_t;
|
||||
typedef binary<A, B, parser<self_t> > base_t;
|
||||
|
||||
intersection(A const& a, B const& b)
|
||||
: base_t(a, b) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
typedef typename ScannerT::iterator_t iterator_t;
|
||||
iterator_t save = scan.first;
|
||||
if (result_t hl = this->left().parse(scan))
|
||||
{
|
||||
ScannerT bscan(scan.first, scan.first, scan);
|
||||
scan.first = save;
|
||||
result_t hr = this->right().parse(bscan);
|
||||
if (hl.length() == hr.length())
|
||||
return hl;
|
||||
}
|
||||
|
||||
return scan.no_match();
|
||||
}
|
||||
};
|
||||
|
||||
struct intersection_parser_gen
|
||||
{
|
||||
template <typename A, typename B>
|
||||
struct result
|
||||
{
|
||||
typedef
|
||||
intersection<
|
||||
typename as_parser<A>::type
|
||||
, typename as_parser<B>::type
|
||||
>
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
static intersection<
|
||||
typename as_parser<A>::type
|
||||
, typename as_parser<B>::type
|
||||
>
|
||||
generate(A const& a, B const& b)
|
||||
{
|
||||
return intersection<BOOST_DEDUCED_TYPENAME as_parser<A>::type,
|
||||
BOOST_DEDUCED_TYPENAME as_parser<B>::type>
|
||||
(as_parser<A>::convert(a), as_parser<B>::convert(b));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
intersection<A, B>
|
||||
operator&(parser<A> const& a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
intersection<A, chlit<char> >
|
||||
operator&(parser<A> const& a, char b);
|
||||
|
||||
template <typename B>
|
||||
intersection<chlit<char>, B>
|
||||
operator&(char a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
intersection<A, strlit<char const*> >
|
||||
operator&(parser<A> const& a, char const* b);
|
||||
|
||||
template <typename B>
|
||||
intersection<strlit<char const*>, B>
|
||||
operator&(char const* a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
intersection<A, chlit<wchar_t> >
|
||||
operator&(parser<A> const& a, wchar_t b);
|
||||
|
||||
template <typename B>
|
||||
intersection<chlit<wchar_t>, B>
|
||||
operator&(wchar_t a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
intersection<A, strlit<wchar_t const*> >
|
||||
operator&(parser<A> const& a, wchar_t const* b);
|
||||
|
||||
template <typename B>
|
||||
intersection<strlit<wchar_t const*>, B>
|
||||
operator&(wchar_t const* a, parser<B> const& b);
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/classic/core/composite/impl/intersection.ipp>
|
||||
@@ -0,0 +1,109 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_KLEENE_STAR_HPP)
|
||||
#define BOOST_SPIRIT_KLEENE_STAR_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/meta/as_parser.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// kleene_star class
|
||||
//
|
||||
// Handles expressions of the form:
|
||||
//
|
||||
// *a
|
||||
//
|
||||
// where a is a parser. The expression returns a composite
|
||||
// parser that matches its subject zero (0) or more times.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct kleene_star_parser_gen;
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
template <typename S>
|
||||
struct kleene_star
|
||||
: public unary<S, parser<kleene_star<S> > >
|
||||
{
|
||||
typedef kleene_star<S> self_t;
|
||||
typedef unary_parser_category parser_category_t;
|
||||
typedef kleene_star_parser_gen parser_generator_t;
|
||||
typedef unary<S, parser<self_t> > base_t;
|
||||
|
||||
kleene_star(S const& a)
|
||||
: base_t(a) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
typedef typename ScannerT::iterator_t iterator_t;
|
||||
result_t hit = scan.empty_match();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
iterator_t save = scan.first;
|
||||
if (result_t next = this->subject().parse(scan))
|
||||
{
|
||||
scan.concat_match(hit, next);
|
||||
}
|
||||
else
|
||||
{
|
||||
scan.first = save;
|
||||
return hit;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
struct kleene_star_parser_gen
|
||||
{
|
||||
template <typename S>
|
||||
struct result
|
||||
{
|
||||
typedef kleene_star<S> type;
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
static kleene_star<S>
|
||||
generate(parser<S> const& a)
|
||||
{
|
||||
return kleene_star<S>(a.derived());
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename S>
|
||||
kleene_star<S>
|
||||
operator*(parser<S> const& a);
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/classic/core/composite/impl/kleene_star.ipp>
|
||||
@@ -0,0 +1,73 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_LIST_HPP)
|
||||
#define BOOST_SPIRIT_LIST_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/meta/as_parser.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// operator% is defined as:
|
||||
// a % b ---> a >> *(b >> a)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A, typename B>
|
||||
sequence<A, kleene_star<sequence<B, A> > >
|
||||
operator%(parser<A> const& a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
sequence<A, kleene_star<sequence<chlit<char>, A> > >
|
||||
operator%(parser<A> const& a, char b);
|
||||
|
||||
template <typename B>
|
||||
sequence<chlit<char>, kleene_star<sequence<B, chlit<char> > > >
|
||||
operator%(char a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
sequence<A, kleene_star<sequence<strlit<char const*>, A> > >
|
||||
operator%(parser<A> const& a, char const* b);
|
||||
|
||||
template <typename B>
|
||||
sequence<strlit<char const*>,
|
||||
kleene_star<sequence<B, strlit<char const*> > > >
|
||||
operator%(char const* a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
sequence<A, kleene_star<sequence<chlit<wchar_t>, A> > >
|
||||
operator%(parser<A> const& a, wchar_t b);
|
||||
|
||||
template <typename B>
|
||||
sequence<chlit<wchar_t>, kleene_star<sequence<B, chlit<wchar_t> > > >
|
||||
operator%(wchar_t a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
sequence<A, kleene_star<sequence<strlit<wchar_t const*>, A> > >
|
||||
operator%(parser<A> const& a, wchar_t const* b);
|
||||
|
||||
template <typename B>
|
||||
sequence<strlit<wchar_t const*>,
|
||||
kleene_star<sequence<B, strlit<wchar_t const*> > > >
|
||||
operator%(wchar_t const* a, parser<B> const& b);
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/classic/core/composite/impl/list.ipp>
|
||||
@@ -0,0 +1,165 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2003 Vaclav Vesely
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_NO_ACTIONS_HPP)
|
||||
#define BOOST_SPIRIT_NO_ACTIONS_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/core/non_terminal/rule.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace spirit {
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// no_actions_action_policy
|
||||
|
||||
template<typename BaseT = action_policy>
|
||||
struct no_actions_action_policy:
|
||||
public BaseT
|
||||
{
|
||||
typedef BaseT base_t;
|
||||
|
||||
no_actions_action_policy():
|
||||
BaseT()
|
||||
{}
|
||||
|
||||
template<typename PolicyT>
|
||||
no_actions_action_policy(PolicyT const& other):
|
||||
BaseT(other)
|
||||
{}
|
||||
|
||||
template<typename ActorT, typename AttrT, typename IteratorT>
|
||||
void
|
||||
do_action(
|
||||
ActorT const& actor,
|
||||
AttrT& val,
|
||||
IteratorT const& first,
|
||||
IteratorT const& last) const
|
||||
{}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// no_actions_scanner
|
||||
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename ActionPolicy>
|
||||
struct compute_no_actions_action_policy
|
||||
{
|
||||
typedef no_actions_action_policy<ActionPolicy> type;
|
||||
};
|
||||
|
||||
template <typename ActionPolicy>
|
||||
struct compute_no_actions_action_policy<no_actions_action_policy<ActionPolicy> >
|
||||
{
|
||||
typedef no_actions_action_policy<ActionPolicy> type;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename ScannerT = scanner<> >
|
||||
struct no_actions_scanner
|
||||
{
|
||||
typedef scanner_policies<
|
||||
typename ScannerT::iteration_policy_t,
|
||||
typename ScannerT::match_policy_t,
|
||||
typename detail::compute_no_actions_action_policy<typename ScannerT::action_policy_t>::type
|
||||
> policies_t;
|
||||
|
||||
typedef typename
|
||||
rebind_scanner_policies<ScannerT, policies_t>::type type;
|
||||
};
|
||||
|
||||
#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
|
||||
|
||||
template<typename ScannerT = scanner<> >
|
||||
struct no_actions_scanner_list
|
||||
{
|
||||
typedef
|
||||
scanner_list<
|
||||
ScannerT,
|
||||
typename no_actions_scanner<ScannerT>::type
|
||||
>
|
||||
type;
|
||||
};
|
||||
|
||||
#endif // BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// no_actions_parser
|
||||
|
||||
struct no_actions_parser_gen;
|
||||
|
||||
template<typename ParserT>
|
||||
struct no_actions_parser:
|
||||
public unary<ParserT, parser<no_actions_parser<ParserT> > >
|
||||
{
|
||||
typedef no_actions_parser<ParserT> self_t;
|
||||
typedef unary_parser_category parser_category_t;
|
||||
typedef no_actions_parser_gen parser_generator_t;
|
||||
typedef unary<ParserT, parser<self_t> > base_t;
|
||||
|
||||
template<typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename parser_result<ParserT, ScannerT>::type type;
|
||||
};
|
||||
|
||||
no_actions_parser(ParserT const& p)
|
||||
: base_t(p)
|
||||
{}
|
||||
|
||||
template<typename ScannerT>
|
||||
typename result<ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename no_actions_scanner<ScannerT>::policies_t policies_t;
|
||||
|
||||
return this->subject().parse(scan.change_policies(policies_t(scan)));
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// no_actions_parser_gen
|
||||
|
||||
struct no_actions_parser_gen
|
||||
{
|
||||
template<typename ParserT>
|
||||
struct result
|
||||
{
|
||||
typedef no_actions_parser<ParserT> type;
|
||||
};
|
||||
|
||||
template<typename ParserT>
|
||||
static no_actions_parser<ParserT>
|
||||
generate(parser<ParserT> const& subject)
|
||||
{
|
||||
return no_actions_parser<ParserT>(subject.derived());
|
||||
}
|
||||
|
||||
template<typename ParserT>
|
||||
no_actions_parser<ParserT>
|
||||
operator[](parser<ParserT> const& subject) const
|
||||
{
|
||||
return no_actions_parser<ParserT>(subject.derived());
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// no_actions_d
|
||||
|
||||
const no_actions_parser_gen no_actions_d = no_actions_parser_gen();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
} // namespace spirit
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(BOOST_SPIRIT_NO_ACTIONS_HPP)
|
||||
@@ -0,0 +1,25 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_OPERATORS_HPP)
|
||||
#define BOOST_SPIRIT_OPERATORS_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/core/composite/sequence.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/sequential_and.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/sequential_or.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/alternative.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/difference.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/intersection.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/exclusive_or.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/kleene_star.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/positive.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/optional.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/list.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,94 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_OPTIONAL_HPP)
|
||||
#define BOOST_SPIRIT_OPTIONAL_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/meta/as_parser.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// optional class
|
||||
//
|
||||
// Handles expressions of the form:
|
||||
//
|
||||
// !a
|
||||
//
|
||||
// where a is a parser. The expression returns a composite
|
||||
// parser that matches its subject zero (0) or one (1) time.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct optional_parser_gen;
|
||||
|
||||
template <typename S>
|
||||
struct optional
|
||||
: public unary<S, parser<optional<S> > >
|
||||
{
|
||||
typedef optional<S> self_t;
|
||||
typedef unary_parser_category parser_category_t;
|
||||
typedef optional_parser_gen parser_generator_t;
|
||||
typedef unary<S, parser<self_t> > base_t;
|
||||
|
||||
optional(S const& a)
|
||||
: base_t(a) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
typedef typename ScannerT::iterator_t iterator_t;
|
||||
iterator_t save = scan.first;
|
||||
if (result_t r = this->subject().parse(scan))
|
||||
{
|
||||
return r;
|
||||
}
|
||||
else
|
||||
{
|
||||
scan.first = save;
|
||||
return scan.empty_match();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct optional_parser_gen
|
||||
{
|
||||
template <typename S>
|
||||
struct result
|
||||
{
|
||||
typedef optional<S> type;
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
static optional<S>
|
||||
generate(parser<S> const& a)
|
||||
{
|
||||
return optional<S>(a.derived());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
optional<S>
|
||||
operator!(parser<S> const& a);
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/classic/core/composite/impl/optional.ipp>
|
||||
@@ -0,0 +1,112 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_POSITIVE_HPP)
|
||||
#define BOOST_SPIRIT_POSITIVE_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/meta/as_parser.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// positive class
|
||||
//
|
||||
// Handles expressions of the form:
|
||||
//
|
||||
// +a
|
||||
//
|
||||
// where a is a parser. The expression returns a composite
|
||||
// parser that matches its subject one (1) or more times.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct positive_parser_gen;
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
template <typename S>
|
||||
struct positive
|
||||
: public unary<S, parser<positive<S> > >
|
||||
{
|
||||
typedef positive<S> self_t;
|
||||
typedef unary_parser_category parser_category_t;
|
||||
typedef positive_parser_gen parser_generator_t;
|
||||
typedef unary<S, parser<self_t> > base_t;
|
||||
|
||||
positive(S const& a)
|
||||
: base_t(a) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
typedef typename ScannerT::iterator_t iterator_t;
|
||||
result_t hit = this->subject().parse(scan);
|
||||
|
||||
if (hit)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
iterator_t save = scan.first;
|
||||
if (result_t next = this->subject().parse(scan))
|
||||
{
|
||||
scan.concat_match(hit, next);
|
||||
}
|
||||
else
|
||||
{
|
||||
scan.first = save;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
struct positive_parser_gen
|
||||
{
|
||||
template <typename S>
|
||||
struct result
|
||||
{
|
||||
typedef positive<S> type;
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
static positive<S>
|
||||
generate(parser<S> const& a)
|
||||
{
|
||||
return positive<S>(a.derived());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
inline positive<S>
|
||||
operator+(parser<S> const& a);
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/classic/core/composite/impl/positive.ipp>
|
||||
@@ -0,0 +1,142 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_SEQUENCE_HPP)
|
||||
#define BOOST_SPIRIT_SEQUENCE_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/meta/as_parser.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// sequence class
|
||||
//
|
||||
// Handles expressions of the form:
|
||||
//
|
||||
// a >> b
|
||||
//
|
||||
// where a and b are parsers. The expression returns a composite
|
||||
// parser that matches a and b in sequence. One (not both) of the
|
||||
// operands may be a literal char, wchar_t or a primitive string
|
||||
// char const*, wchar_t const*.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct sequence_parser_gen;
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
template <typename A, typename B>
|
||||
struct sequence : public binary<A, B, parser<sequence<A, B> > >
|
||||
{
|
||||
typedef sequence<A, B> self_t;
|
||||
typedef binary_parser_category parser_category_t;
|
||||
typedef sequence_parser_gen parser_generator_t;
|
||||
typedef binary<A, B, parser<self_t> > base_t;
|
||||
|
||||
sequence(A const& a, B const& b)
|
||||
: base_t(a, b) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
if (result_t ma = this->left().parse(scan))
|
||||
if (result_t mb = this->right().parse(scan))
|
||||
{
|
||||
scan.concat_match(ma, mb);
|
||||
return ma;
|
||||
}
|
||||
return scan.no_match();
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
struct sequence_parser_gen
|
||||
{
|
||||
template <typename A, typename B>
|
||||
struct result
|
||||
{
|
||||
typedef
|
||||
sequence<
|
||||
typename as_parser<A>::type
|
||||
, typename as_parser<B>::type
|
||||
>
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
static sequence<
|
||||
typename as_parser<A>::type
|
||||
, typename as_parser<B>::type
|
||||
>
|
||||
generate(A const& a, B const& b)
|
||||
{
|
||||
return sequence<BOOST_DEDUCED_TYPENAME as_parser<A>::type,
|
||||
BOOST_DEDUCED_TYPENAME as_parser<B>::type>
|
||||
(as_parser<A>::convert(a), as_parser<B>::convert(b));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
sequence<A, B>
|
||||
operator>>(parser<A> const& a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
sequence<A, chlit<char> >
|
||||
operator>>(parser<A> const& a, char b);
|
||||
|
||||
template <typename B>
|
||||
sequence<chlit<char>, B>
|
||||
operator>>(char a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
sequence<A, strlit<char const*> >
|
||||
operator>>(parser<A> const& a, char const* b);
|
||||
|
||||
template <typename B>
|
||||
sequence<strlit<char const*>, B>
|
||||
operator>>(char const* a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
sequence<A, chlit<wchar_t> >
|
||||
operator>>(parser<A> const& a, wchar_t b);
|
||||
|
||||
template <typename B>
|
||||
sequence<chlit<wchar_t>, B>
|
||||
operator>>(wchar_t a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
sequence<A, strlit<wchar_t const*> >
|
||||
operator>>(parser<A> const& a, wchar_t const* b);
|
||||
|
||||
template <typename B>
|
||||
sequence<strlit<wchar_t const*>, B>
|
||||
operator>>(wchar_t const* a, parser<B> const& b);
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/classic/core/composite/impl/sequence.ipp>
|
||||
@@ -0,0 +1,76 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_SEQUENTIAL_AND_HPP)
|
||||
#define BOOST_SPIRIT_SEQUENTIAL_AND_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/meta/as_parser.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// sequential-and operators
|
||||
//
|
||||
// Handles expressions of the form:
|
||||
//
|
||||
// a && b
|
||||
//
|
||||
// Same as a >> b.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A, typename B>
|
||||
sequence<A, B>
|
||||
operator&&(parser<A> const& a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
sequence<A, chlit<char> >
|
||||
operator&&(parser<A> const& a, char b);
|
||||
|
||||
template <typename B>
|
||||
sequence<chlit<char>, B>
|
||||
operator&&(char a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
sequence<A, strlit<char const*> >
|
||||
operator&&(parser<A> const& a, char const* b);
|
||||
|
||||
template <typename B>
|
||||
sequence<strlit<char const*>, B>
|
||||
operator&&(char const* a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
sequence<A, chlit<wchar_t> >
|
||||
operator&&(parser<A> const& a, wchar_t b);
|
||||
|
||||
template <typename B>
|
||||
sequence<chlit<wchar_t>, B>
|
||||
operator&&(wchar_t a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
sequence<A, strlit<wchar_t const*> >
|
||||
operator&&(parser<A> const& a, wchar_t const* b);
|
||||
|
||||
template <typename B>
|
||||
sequence<strlit<wchar_t const*>, B>
|
||||
operator&&(wchar_t const* a, parser<B> const& b);
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/classic/core/composite/impl/sequential_and.ipp>
|
||||
@@ -0,0 +1,154 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
Copyright (c) 2002 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_SEQUENTIAL_OR_HPP)
|
||||
#define BOOST_SPIRIT_SEQUENTIAL_OR_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/meta/as_parser.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// sequential-or class
|
||||
//
|
||||
// Handles expressions of the form:
|
||||
//
|
||||
// a || b
|
||||
//
|
||||
// Equivalent to
|
||||
//
|
||||
// a | b | a >> b;
|
||||
//
|
||||
// where a and b are parsers. The expression returns a composite
|
||||
// parser that matches matches a or b in sequence. One (not both) of
|
||||
// the operands may be a literal char, wchar_t or a primitive string
|
||||
// char const*, wchar_t const*.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct sequential_or_parser_gen;
|
||||
|
||||
template <typename A, typename B>
|
||||
struct sequential_or : public binary<A, B, parser<sequential_or<A, B> > >
|
||||
{
|
||||
typedef sequential_or<A, B> self_t;
|
||||
typedef binary_parser_category parser_category_t;
|
||||
typedef sequential_or_parser_gen parser_generator_t;
|
||||
typedef binary<A, B, parser<self_t> > base_t;
|
||||
|
||||
sequential_or(A const& a, B const& b)
|
||||
: base_t(a, b) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
typedef typename ScannerT::iterator_t iterator_t;
|
||||
{ // scope for save
|
||||
iterator_t save = scan.first;
|
||||
if (result_t ma = this->left().parse(scan))
|
||||
{
|
||||
save = scan.first;
|
||||
if (result_t mb = this->right().parse(scan))
|
||||
{
|
||||
// matched a b
|
||||
scan.concat_match(ma, mb);
|
||||
return ma;
|
||||
}
|
||||
else
|
||||
{
|
||||
// matched a
|
||||
scan.first = save;
|
||||
return ma;
|
||||
}
|
||||
}
|
||||
scan.first = save;
|
||||
}
|
||||
|
||||
// matched b
|
||||
return this->right().parse(scan);
|
||||
}
|
||||
};
|
||||
|
||||
struct sequential_or_parser_gen
|
||||
{
|
||||
template <typename A, typename B>
|
||||
struct result
|
||||
{
|
||||
typedef
|
||||
sequential_or<
|
||||
typename as_parser<A>::type
|
||||
, typename as_parser<B>::type
|
||||
>
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
static sequential_or<
|
||||
typename as_parser<A>::type
|
||||
, typename as_parser<B>::type
|
||||
>
|
||||
generate(A const& a, B const& b)
|
||||
{
|
||||
return sequential_or<BOOST_DEDUCED_TYPENAME as_parser<A>::type,
|
||||
BOOST_DEDUCED_TYPENAME as_parser<B>::type>
|
||||
(as_parser<A>::convert(a), as_parser<B>::convert(b));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
sequential_or<A, B>
|
||||
operator||(parser<A> const& a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
sequential_or<A, chlit<char> >
|
||||
operator||(parser<A> const& a, char b);
|
||||
|
||||
template <typename B>
|
||||
sequential_or<chlit<char>, B>
|
||||
operator||(char a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
sequential_or<A, strlit<char const*> >
|
||||
operator||(parser<A> const& a, char const* b);
|
||||
|
||||
template <typename B>
|
||||
sequential_or<strlit<char const*>, B>
|
||||
operator||(char const* a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
sequential_or<A, chlit<wchar_t> >
|
||||
operator||(parser<A> const& a, wchar_t b);
|
||||
|
||||
template <typename B>
|
||||
sequential_or<chlit<wchar_t>, B>
|
||||
operator||(wchar_t a, parser<B> const& b);
|
||||
|
||||
template <typename A>
|
||||
sequential_or<A, strlit<wchar_t const*> >
|
||||
operator||(parser<A> const& a, wchar_t const* b);
|
||||
|
||||
template <typename B>
|
||||
sequential_or<strlit<wchar_t const*>, B>
|
||||
operator||(wchar_t const* a, parser<B> const& b);
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/classic/core/composite/impl/sequential_or.ipp>
|
||||
@@ -0,0 +1,62 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2003 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_CONFIG_HPP)
|
||||
#define BOOST_SPIRIT_CONFIG_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Compiler check:
|
||||
//
|
||||
// Historically, Spirit supported a lot of compilers, including (to some
|
||||
// extent) poorly conforming compilers such as VC6. Spirit v1.6.x will be
|
||||
// the last release that will support older poorly conforming compilers.
|
||||
// Starting from Spirit v1.8.0, ill conforming compilers will not be
|
||||
// supported. If you are still using one of these older compilers, you can
|
||||
// still use Spirit v1.6.x.
|
||||
//
|
||||
// The reason why Spirit v1.6.x worked on old non-conforming compilers is
|
||||
// that the authors laboriously took the trouble of searching for
|
||||
// workarounds to make these compilers happy. The process takes a lot of
|
||||
// time and energy, especially when one encounters the dreaded ICE or
|
||||
// "Internal Compiler Error". Sometimes searching for a single workaround
|
||||
// takes days or even weeks. Sometimes, there are no known workarounds. This
|
||||
// stifles progress a lot. And, as the library gets more progressive and
|
||||
// takes on more advanced C++ techniques, the difficulty is escalated to
|
||||
// even new heights.
|
||||
//
|
||||
// Spirit v1.6.x will still be supported. Maintenance and bug fixes will
|
||||
// still be applied. There will still be active development for the back-
|
||||
// porting of new features introduced in Spirit v1.8.0 (and Spirit 1.9.0)
|
||||
// to lesser able compilers; hopefully, fueled by contributions from the
|
||||
// community. For instance, there is already a working AST tree back-port
|
||||
// for VC6 and VC7 by Peder Holt.
|
||||
//
|
||||
// If you got here somehow, your compiler is known to be poorly conforming
|
||||
// WRT ANSI/ISO C++ standard. Library implementers get a bad reputation when
|
||||
// someone attempts to compile the code on a non-conforming compiler. She'll
|
||||
// be confronted with tons of compiler errors when she tries to compile the
|
||||
// library. Such errors will somehow make less informed users conclude that
|
||||
// the code is poorly written. It's better for the user to see a message
|
||||
// "sorry, this code has not been ported to your compiler yet", than to see
|
||||
// pages and pages of compiler error messages.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#if (defined(BOOST_MSVC) && (BOOST_MSVC < 1310)) \
|
||||
|| (defined(__BORLANDC__) && (__BORLANDC__ <= 0x570)) \
|
||||
|| (defined(__GNUC__) && (__GNUC__ < 3)) \
|
||||
|| (defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ < 1))
|
||||
# error "Compiler not supported. See note in <boost/spirit/core/config.hpp>"
|
||||
#else
|
||||
// Pass... Compiler supported.
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_MATCH_IPP)
|
||||
#define BOOST_SPIRIT_MATCH_IPP
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
template <typename T>
|
||||
inline match<T>::match()
|
||||
: len(-1), val() {}
|
||||
|
||||
template <typename T>
|
||||
inline match<T>::match(std::size_t length_)
|
||||
: len(length_), val() {}
|
||||
|
||||
template <typename T>
|
||||
inline match<T>::match(std::size_t length_, ctor_param_t val_)
|
||||
: len(length_), val(val_) {}
|
||||
|
||||
template <typename T>
|
||||
inline bool
|
||||
match<T>::operator!() const
|
||||
{
|
||||
return len < 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::ptrdiff_t
|
||||
match<T>::length() const
|
||||
{
|
||||
return len;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool
|
||||
match<T>::has_valid_attribute() const
|
||||
{
|
||||
return val.is_initialized();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline typename match<T>::return_t
|
||||
match<T>::value() const
|
||||
{
|
||||
BOOST_SPIRIT_ASSERT(val.is_initialized());
|
||||
return *val;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void
|
||||
match<T>::swap(match& other)
|
||||
{
|
||||
std::swap(len, other.len);
|
||||
std::swap(val, other.val);
|
||||
}
|
||||
|
||||
inline match<nil_t>::match()
|
||||
: len(-1) {}
|
||||
|
||||
inline match<nil_t>::match(std::size_t length_)
|
||||
: len(length_) {}
|
||||
|
||||
inline match<nil_t>::match(std::size_t length_, nil_t)
|
||||
: len(length_) {}
|
||||
|
||||
inline bool
|
||||
match<nil_t>::operator!() const
|
||||
{
|
||||
return len < 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
match<nil_t>::has_valid_attribute() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
inline std::ptrdiff_t
|
||||
match<nil_t>::length() const
|
||||
{
|
||||
return len;
|
||||
}
|
||||
|
||||
inline nil_t
|
||||
match<nil_t>::value() const
|
||||
{
|
||||
return nil_t();
|
||||
}
|
||||
|
||||
inline void
|
||||
match<nil_t>::value(nil_t) {}
|
||||
|
||||
inline void
|
||||
match<nil_t>::swap(match<nil_t>& other)
|
||||
{
|
||||
std::swap(len, other.len);
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_MATCH_ATTR_TRAITS_IPP)
|
||||
#define BOOST_SPIRIT_MATCH_ATTR_TRAITS_IPP
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template <typename T>
|
||||
struct match_attr_traits
|
||||
{
|
||||
typedef typename
|
||||
boost::optional<T>::reference_const_type
|
||||
const_reference;
|
||||
|
||||
// case where src *IS* convertible to T (dest)
|
||||
template <typename T2>
|
||||
static void
|
||||
convert(boost::optional<T>& dest, T2 const& src, mpl::true_)
|
||||
{
|
||||
dest.reset(src);
|
||||
}
|
||||
|
||||
// case where src *IS NOT* convertible to T (dest)
|
||||
template <typename T2>
|
||||
static void
|
||||
convert(boost::optional<T>& dest, T2 const& /*src*/, mpl::false_)
|
||||
{
|
||||
dest.reset();
|
||||
}
|
||||
|
||||
static void
|
||||
convert(boost::optional<T>& dest, nil_t/*src*/)
|
||||
{
|
||||
dest.reset();
|
||||
}
|
||||
|
||||
template <typename T2>
|
||||
static void
|
||||
convert(boost::optional<T>& dest, T2 const& src)
|
||||
{
|
||||
convert(dest, src, is_convertible<T2, T>());
|
||||
}
|
||||
|
||||
template <typename OtherMatchT>
|
||||
static void
|
||||
copy(boost::optional<T>& dest, OtherMatchT const& src)
|
||||
{
|
||||
if (src.has_valid_attribute())
|
||||
convert(dest, src.value());
|
||||
}
|
||||
|
||||
template <typename OtherMatchT>
|
||||
static void
|
||||
assign(boost::optional<T>& dest, OtherMatchT const& src)
|
||||
{
|
||||
if (src.has_valid_attribute())
|
||||
convert(dest, src.value());
|
||||
else
|
||||
dest.reset();
|
||||
}
|
||||
|
||||
// T is not reference
|
||||
template <typename ValueT>
|
||||
static void
|
||||
set_value(boost::optional<T>& dest, ValueT const& val, mpl::false_)
|
||||
{
|
||||
dest.reset(val);
|
||||
}
|
||||
|
||||
// T is a reference
|
||||
template <typename ValueT>
|
||||
static void
|
||||
set_value(boost::optional<T>& dest, ValueT const& val, mpl::true_)
|
||||
{
|
||||
dest.get() = val;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit::impl
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_PARSER_IPP)
|
||||
#define BOOST_SPIRIT_PARSER_IPP
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generic parse function implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename IteratorT, typename DerivedT>
|
||||
inline parse_info<IteratorT>
|
||||
parse(
|
||||
IteratorT const& first_
|
||||
, IteratorT const& last
|
||||
, parser<DerivedT> const& p)
|
||||
{
|
||||
IteratorT first = first_;
|
||||
scanner<IteratorT, scanner_policies<> > scan(first, last);
|
||||
match<nil_t> hit = p.derived().parse(scan);
|
||||
return parse_info<IteratorT>(
|
||||
first, hit, hit && (first == last), hit.length());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Parse function for null terminated strings implementation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT, typename DerivedT>
|
||||
inline parse_info<CharT const*>
|
||||
parse(CharT const* str, parser<DerivedT> const& p)
|
||||
{
|
||||
CharT const* last = str;
|
||||
while (*last)
|
||||
last++;
|
||||
return parse(str, last, p);
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_MATCH_HPP)
|
||||
#define BOOST_SPIRIT_MATCH_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/config.hpp>
|
||||
#include <boost/spirit/home/classic/core/nil.hpp>
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/spirit/home/classic/core/assert.hpp>
|
||||
#include <boost/spirit/home/classic/core/safe_bool.hpp>
|
||||
#include <boost/spirit/home/classic/core/impl/match_attr_traits.ipp>
|
||||
#include <boost/type_traits/add_const.hpp>
|
||||
#include <boost/type_traits/is_reference.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// match class
|
||||
//
|
||||
// The match holds the result of a parser. A match object evaluates
|
||||
// to true when a successful match is found, otherwise false. The
|
||||
// length of the match is the number of characters (or tokens) that
|
||||
// is successfully matched. This can be queried through its length()
|
||||
// member function. A negative value means that the match is
|
||||
// unsucessful.
|
||||
//
|
||||
// Each parser may have an associated attribute. This attribute is
|
||||
// also returned back to the client on a successful parse through
|
||||
// the match object. The match's value() member function returns the
|
||||
// match's attribute.
|
||||
//
|
||||
// A match attribute is valid:
|
||||
//
|
||||
// * on a successful match
|
||||
// * when its value is set through the value(val) member function
|
||||
// * if it is assigned or copied from a compatible match object
|
||||
// (e.g. match<double> from match<int>) with a valid attribute.
|
||||
//
|
||||
// The match attribute is undefined:
|
||||
//
|
||||
// * on an unsuccessful match
|
||||
// * when an attempt to copy or assign from another match object
|
||||
// with an incompatible attribute type (e.g. match<std::string>
|
||||
// from match<int>).
|
||||
//
|
||||
// The member function has_valid_attribute() can be queried to know if
|
||||
// it is safe to get the match's attribute. The attribute may be set
|
||||
// through the member function value(v) where v is the new attribute
|
||||
// value.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T = nil_t>
|
||||
class match : public safe_bool<match<T> >
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
typedef typename boost::optional<T> optional_type;
|
||||
typedef typename optional_type::argument_type ctor_param_t;
|
||||
typedef typename optional_type::reference_const_type return_t;
|
||||
typedef T attr_t;
|
||||
|
||||
match();
|
||||
explicit match(std::size_t length);
|
||||
match(std::size_t length, ctor_param_t val);
|
||||
|
||||
bool operator!() const;
|
||||
std::ptrdiff_t length() const;
|
||||
bool has_valid_attribute() const;
|
||||
return_t value() const;
|
||||
void swap(match& other);
|
||||
|
||||
template <typename T2>
|
||||
match(match<T2> const& other)
|
||||
: len(other.length()), val()
|
||||
{
|
||||
impl::match_attr_traits<T>::copy(val, other);
|
||||
}
|
||||
|
||||
template <typename T2>
|
||||
match&
|
||||
operator=(match<T2> const& other)
|
||||
{
|
||||
impl::match_attr_traits<T>::assign(val, other);
|
||||
len = other.length();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename MatchT>
|
||||
void
|
||||
concat(MatchT const& other)
|
||||
{
|
||||
BOOST_SPIRIT_ASSERT(*this && other);
|
||||
len += other.length();
|
||||
}
|
||||
|
||||
template <typename ValueT>
|
||||
void
|
||||
value(ValueT const& val_)
|
||||
{
|
||||
impl::match_attr_traits<T>::set_value(val, val_, is_reference<T>());
|
||||
}
|
||||
|
||||
bool operator_bool() const
|
||||
{
|
||||
return len >= 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::ptrdiff_t len;
|
||||
optional_type val;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// match class specialization for nil_t values
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
class match<nil_t> : public safe_bool<match<nil_t> >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef nil_t attr_t;
|
||||
typedef nil_t return_t;
|
||||
|
||||
match();
|
||||
explicit match(std::size_t length);
|
||||
match(std::size_t length, nil_t);
|
||||
|
||||
bool operator!() const;
|
||||
bool has_valid_attribute() const;
|
||||
std::ptrdiff_t length() const;
|
||||
nil_t value() const;
|
||||
void value(nil_t);
|
||||
void swap(match& other);
|
||||
|
||||
template <typename T>
|
||||
match(match<T> const& other)
|
||||
: len(other.length()) {}
|
||||
|
||||
template <typename T>
|
||||
match<>&
|
||||
operator=(match<T> const& other)
|
||||
{
|
||||
len = other.length();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
concat(match<T> const& other)
|
||||
{
|
||||
BOOST_SPIRIT_ASSERT(*this && other);
|
||||
len += other.length();
|
||||
}
|
||||
|
||||
bool operator_bool() const
|
||||
{
|
||||
return len >= 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::ptrdiff_t len;
|
||||
};
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
#include <boost/spirit/home/classic/core/impl/match.ipp>
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2003 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_NIL_HPP)
|
||||
#define BOOST_SPIRIT_NIL_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
struct nil_t {};
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2003 Joel de Guzman
|
||||
Copyright (c) 2002-2003 Martin Wille
|
||||
Copyright (c) 2003 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_GRAMMAR_HPP)
|
||||
#define BOOST_SPIRIT_GRAMMAR_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if defined(BOOST_SPIRIT_THREADSAFE) && defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
|
||||
#undef BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/non_terminal/parser_context.hpp>
|
||||
#include <boost/spirit/home/classic/core/non_terminal/impl/grammar.ipp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// grammar class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename DerivedT, typename ContextT = parser_context<> >
|
||||
struct grammar
|
||||
: public parser<DerivedT>
|
||||
, public ContextT::base_t
|
||||
, public context_aux<ContextT, DerivedT>
|
||||
BOOST_SPIRIT_GRAMMAR_ID
|
||||
{
|
||||
typedef grammar<DerivedT, ContextT> self_t;
|
||||
typedef DerivedT const& embed_t;
|
||||
typedef typename ContextT::context_linker_t context_t;
|
||||
typedef typename context_t::attr_t attr_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, attr_t>::type type;
|
||||
};
|
||||
|
||||
grammar() {}
|
||||
~grammar() { impl::grammar_destruct(this); }
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse_main(ScannerT const& scan) const
|
||||
{ return impl::grammar_parser_parse<0>(this, scan); }
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
typedef parser_scanner_linker<ScannerT> scanner_t;
|
||||
BOOST_SPIRIT_CONTEXT_PARSE(scan, *this, scanner_t, context_t, result_t)
|
||||
}
|
||||
|
||||
template <int N>
|
||||
impl::entry_grammar<DerivedT, N, ContextT>
|
||||
use_parser() const
|
||||
{ return impl::entry_grammar<DerivedT, N, ContextT>( this->derived()); }
|
||||
|
||||
BOOST_SPIRIT_GRAMMAR_STATE
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#undef BOOST_SPIRIT_GRAMMAR_ID
|
||||
#undef BOOST_SPIRIT_GRAMMAR_ACCESS
|
||||
#undef BOOST_SPIRIT_GRAMMAR_STATE
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,407 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2003 Joel de Guzman
|
||||
Copyright (c) 2002-2003 Martin Wille
|
||||
Copyright (c) 2003 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined BOOST_SPIRIT_GRAMMAR_IPP
|
||||
#define BOOST_SPIRIT_GRAMMAR_IPP
|
||||
|
||||
#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
|
||||
#include <boost/spirit/home/classic/core/non_terminal/impl/object_with_id.ipp>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <memory> // for std::auto_ptr
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
||||
#include <boost/spirit/home/classic/core/non_terminal/impl/static.hpp>
|
||||
#include <boost/thread/tss.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
template <typename DerivedT, typename ContextT>
|
||||
struct grammar;
|
||||
|
||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
||||
|
||||
BOOST_SPIRIT_DEPENDENT_TEMPLATE_WRAPPER(grammar_definition_wrapper, definition);
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename GrammarT, typename ScannerT>
|
||||
struct grammar_definition
|
||||
{
|
||||
typedef typename impl::grammar_definition_wrapper<GrammarT>
|
||||
::template result_<ScannerT>::param_t type;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename GrammarT, typename ScannerT>
|
||||
struct grammar_definition
|
||||
{
|
||||
typedef typename GrammarT::template definition<ScannerT> type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
namespace impl
|
||||
{
|
||||
|
||||
#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
|
||||
struct grammar_tag {};
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename GrammarT>
|
||||
struct grammar_helper_base
|
||||
{
|
||||
virtual int undefine(GrammarT *) = 0;
|
||||
virtual ~grammar_helper_base() {}
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename GrammarT>
|
||||
struct grammar_helper_list
|
||||
{
|
||||
typedef GrammarT grammar_t;
|
||||
typedef grammar_helper_base<GrammarT> helper_t;
|
||||
typedef std::vector<helper_t*> vector_t;
|
||||
|
||||
grammar_helper_list() {}
|
||||
grammar_helper_list(grammar_helper_list const& /*x*/)
|
||||
{ // Does _not_ copy the helpers member !
|
||||
}
|
||||
|
||||
grammar_helper_list& operator=(grammar_helper_list const& x)
|
||||
{ // Does _not_ copy the helpers member !
|
||||
return *this;
|
||||
}
|
||||
|
||||
void push_back(helper_t *helper)
|
||||
{ helpers.push_back(helper); }
|
||||
|
||||
void pop_back()
|
||||
{ helpers.pop_back(); }
|
||||
|
||||
typename vector_t::size_type
|
||||
size() const
|
||||
{ return helpers.size(); }
|
||||
|
||||
typename vector_t::reverse_iterator
|
||||
rbegin()
|
||||
{ return helpers.rbegin(); }
|
||||
|
||||
typename vector_t::reverse_iterator
|
||||
rend()
|
||||
{ return helpers.rend(); }
|
||||
|
||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
||||
boost::mutex & mutex()
|
||||
{ return m; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
vector_t helpers;
|
||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
||||
boost::mutex m;
|
||||
#endif
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
struct grammartract_helper_list;
|
||||
|
||||
#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) \
|
||||
&& (!defined(__GNUC__) || (__GNUC__ > 2))
|
||||
|
||||
struct grammartract_helper_list
|
||||
{
|
||||
template<typename GrammarT>
|
||||
static grammar_helper_list<GrammarT>&
|
||||
do_(GrammarT const* g)
|
||||
{
|
||||
return g->helpers;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename GrammarT, typename DerivedT, typename ScannerT>
|
||||
struct grammar_helper : private grammar_helper_base<GrammarT>
|
||||
{
|
||||
typedef GrammarT grammar_t;
|
||||
typedef ScannerT scanner_t;
|
||||
typedef DerivedT derived_t;
|
||||
typedef typename grammar_definition<DerivedT, ScannerT>::type definition_t;
|
||||
|
||||
typedef grammar_helper<grammar_t, derived_t, scanner_t> helper_t;
|
||||
typedef boost::shared_ptr<helper_t> helper_ptr_t;
|
||||
typedef boost::weak_ptr<helper_t> helper_weak_ptr_t;
|
||||
|
||||
grammar_helper*
|
||||
this_() { return this; }
|
||||
|
||||
grammar_helper(helper_weak_ptr_t& p)
|
||||
: definitions_cnt(0)
|
||||
, self(this_())
|
||||
{ p = self; }
|
||||
|
||||
definition_t&
|
||||
define(grammar_t const* target_grammar)
|
||||
{
|
||||
grammar_helper_list<GrammarT> &helpers =
|
||||
#if !defined(__GNUC__) || (__GNUC__ > 2)
|
||||
grammartract_helper_list::do_(target_grammar);
|
||||
#else
|
||||
target_grammar->helpers;
|
||||
#endif
|
||||
typename grammar_t::object_id id = target_grammar->get_object_id();
|
||||
|
||||
if (definitions.size()<=id)
|
||||
definitions.resize(id*3/2+1);
|
||||
if (definitions[id]!=0)
|
||||
return *definitions[id];
|
||||
|
||||
std::auto_ptr<definition_t>
|
||||
result(new definition_t(target_grammar->derived()));
|
||||
|
||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
||||
boost::mutex::scoped_lock lock(helpers.mutex());
|
||||
#endif
|
||||
helpers.push_back(this);
|
||||
|
||||
++definitions_cnt;
|
||||
definitions[id] = result.get();
|
||||
return *(result.release());
|
||||
}
|
||||
|
||||
int
|
||||
undefine(grammar_t* target_grammar)
|
||||
{
|
||||
typename grammar_t::object_id id = target_grammar->get_object_id();
|
||||
|
||||
if (definitions.size()<=id)
|
||||
return 0;
|
||||
delete definitions[id];
|
||||
definitions[id] = 0;
|
||||
if (--definitions_cnt==0)
|
||||
self.reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::vector<definition_t*> definitions;
|
||||
unsigned long definitions_cnt;
|
||||
helper_ptr_t self;
|
||||
};
|
||||
|
||||
#endif /* defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) */
|
||||
|
||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
||||
class get_definition_static_data_tag
|
||||
{
|
||||
template<typename DerivedT, typename ContextT, typename ScannerT>
|
||||
friend typename DerivedT::template definition<ScannerT> &
|
||||
get_definition(grammar<DerivedT, ContextT> const* self);
|
||||
|
||||
get_definition_static_data_tag() {}
|
||||
};
|
||||
#endif
|
||||
|
||||
template<typename DerivedT, typename ContextT, typename ScannerT>
|
||||
inline typename DerivedT::template definition<ScannerT> &
|
||||
get_definition(grammar<DerivedT, ContextT> const* self)
|
||||
{
|
||||
#if defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
|
||||
|
||||
typedef typename DerivedT::template definition<ScannerT> definition_t;
|
||||
static definition_t def(self->derived());
|
||||
return def;
|
||||
#else
|
||||
typedef grammar<DerivedT, ContextT> self_t;
|
||||
typedef impl::grammar_helper<self_t, DerivedT, ScannerT> helper_t;
|
||||
typedef typename helper_t::helper_weak_ptr_t ptr_t;
|
||||
|
||||
# ifdef BOOST_SPIRIT_THREADSAFE
|
||||
boost::thread_specific_ptr<ptr_t> & tld_helper
|
||||
= static_<boost::thread_specific_ptr<ptr_t>,
|
||||
get_definition_static_data_tag>(get_definition_static_data_tag());
|
||||
|
||||
if (!tld_helper.get())
|
||||
tld_helper.reset(new ptr_t);
|
||||
ptr_t &helper = *tld_helper;
|
||||
# else
|
||||
static ptr_t helper;
|
||||
# endif
|
||||
if (helper.expired())
|
||||
new helper_t(helper);
|
||||
return helper.lock()->define(self);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
template <int N>
|
||||
struct call_helper {
|
||||
|
||||
template <typename RT, typename DefinitionT, typename ScannerT>
|
||||
static void
|
||||
do_ (RT &result, DefinitionT &def, ScannerT const &scan)
|
||||
{
|
||||
result = def.template get_start_parser<N>()->parse(scan);
|
||||
}
|
||||
};
|
||||
#else
|
||||
// The grammar_def stuff isn't supported for compilers, which do not
|
||||
// support partial template specialization
|
||||
template <int N> struct call_helper;
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct call_helper<0> {
|
||||
|
||||
template <typename RT, typename DefinitionT, typename ScannerT>
|
||||
static void
|
||||
do_ (RT &result, DefinitionT &def, ScannerT const &scan)
|
||||
{
|
||||
result = def.start().parse(scan);
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
template<int N, typename DerivedT, typename ContextT, typename ScannerT>
|
||||
inline typename parser_result<grammar<DerivedT, ContextT>, ScannerT>::type
|
||||
grammar_parser_parse(
|
||||
grammar<DerivedT, ContextT> const* self,
|
||||
ScannerT const &scan)
|
||||
{
|
||||
typedef
|
||||
typename parser_result<grammar<DerivedT, ContextT>, ScannerT>::type
|
||||
result_t;
|
||||
typedef typename DerivedT::template definition<ScannerT> definition_t;
|
||||
|
||||
result_t result;
|
||||
definition_t &def = get_definition<DerivedT, ContextT, ScannerT>(self);
|
||||
|
||||
call_helper<N>::do_(result, def, scan);
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template<typename GrammarT>
|
||||
inline void
|
||||
grammar_destruct(GrammarT* self)
|
||||
{
|
||||
#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
|
||||
typedef impl::grammar_helper_base<GrammarT> helper_base_t;
|
||||
typedef grammar_helper_list<GrammarT> helper_list_t;
|
||||
typedef typename helper_list_t::vector_t::reverse_iterator iterator_t;
|
||||
|
||||
helper_list_t& helpers =
|
||||
# if !defined(__GNUC__) || (__GNUC__ > 2)
|
||||
grammartract_helper_list::do_(self);
|
||||
# else
|
||||
self->helpers;
|
||||
# endif
|
||||
|
||||
# if (defined(BOOST_MSVC) && (BOOST_MSVC < 1300)) \
|
||||
|| defined(BOOST_INTEL_CXX_VERSION)
|
||||
for (iterator_t i = helpers.rbegin(); i != helpers.rend(); ++i)
|
||||
(*i)->undefine(self);
|
||||
# else
|
||||
std::for_each(helpers.rbegin(), helpers.rend(),
|
||||
std::bind2nd(std::mem_fun(&helper_base_t::undefine), self));
|
||||
# endif
|
||||
|
||||
#else
|
||||
(void)self;
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// entry_grammar class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename DerivedT, int N, typename ContextT>
|
||||
class entry_grammar
|
||||
: public parser<entry_grammar<DerivedT, N, ContextT> >
|
||||
{
|
||||
|
||||
public:
|
||||
typedef entry_grammar<DerivedT, N, ContextT> self_t;
|
||||
typedef self_t embed_t;
|
||||
typedef typename ContextT::context_linker_t context_t;
|
||||
typedef typename context_t::attr_t attr_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, attr_t>::type type;
|
||||
};
|
||||
|
||||
entry_grammar(DerivedT const &p) : target_grammar(p) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse_main(ScannerT const& scan) const
|
||||
{ return impl::grammar_parser_parse<N>(&target_grammar, scan); }
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
typedef parser_scanner_linker<ScannerT> scanner_t;
|
||||
BOOST_SPIRIT_CONTEXT_PARSE(scan, target_grammar, scanner_t,
|
||||
context_t, result_t)
|
||||
}
|
||||
|
||||
private:
|
||||
DerivedT const &target_grammar;
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
///////////////////////////////////////
|
||||
#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
|
||||
#define BOOST_SPIRIT_GRAMMAR_ID , public impl::object_with_id<impl::grammar_tag>
|
||||
#else
|
||||
#define BOOST_SPIRIT_GRAMMAR_ID
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////
|
||||
#if !defined(__GNUC__) || (__GNUC__ > 2)
|
||||
#define BOOST_SPIRIT_GRAMMAR_ACCESS private:
|
||||
#else
|
||||
#define BOOST_SPIRIT_GRAMMAR_ACCESS
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////
|
||||
#if !defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
|
||||
#define BOOST_SPIRIT_GRAMMAR_STATE \
|
||||
BOOST_SPIRIT_GRAMMAR_ACCESS \
|
||||
friend struct impl::grammartract_helper_list; \
|
||||
mutable impl::grammar_helper_list<self_t> helpers;
|
||||
#else
|
||||
#define BOOST_SPIRIT_GRAMMAR_STATE
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,191 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2002-2003 Joel de Guzman
|
||||
Copyright (c) 2002-2003 Martin Wille
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined BOOST_SPIRIT_OBJECT_WITH_ID_IPP
|
||||
#define BOOST_SPIRIT_OBJECT_WITH_ID_IPP
|
||||
|
||||
#include <vector>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/once.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
namespace impl {
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename IdT = std::size_t>
|
||||
struct object_with_id_base_supply
|
||||
{
|
||||
typedef IdT object_id;
|
||||
typedef std::vector<object_id> id_vector;
|
||||
|
||||
object_with_id_base_supply() : max_id(object_id()) {}
|
||||
|
||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
||||
boost::mutex mutex;
|
||||
#endif
|
||||
object_id max_id;
|
||||
id_vector free_ids;
|
||||
|
||||
object_id acquire();
|
||||
void release(object_id);
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename TagT, typename IdT = std::size_t>
|
||||
struct object_with_id_base
|
||||
{
|
||||
typedef TagT tag_t;
|
||||
typedef IdT object_id;
|
||||
|
||||
protected:
|
||||
|
||||
object_id acquire_object_id();
|
||||
void release_object_id(object_id);
|
||||
|
||||
private:
|
||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
||||
static boost::mutex &mutex_instance();
|
||||
static void mutex_init();
|
||||
#endif
|
||||
|
||||
boost::shared_ptr<object_with_id_base_supply<IdT> > id_supply;
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
template<class TagT, typename IdT = std::size_t>
|
||||
struct object_with_id : private object_with_id_base<TagT, IdT>
|
||||
{
|
||||
typedef object_with_id<TagT, IdT> self_t;
|
||||
typedef object_with_id_base<TagT, IdT> base_t;
|
||||
typedef IdT object_id;
|
||||
|
||||
object_with_id() : id(base_t::acquire_object_id()) {}
|
||||
object_with_id(self_t const &other)
|
||||
: base_t(other)
|
||||
, id(base_t::acquire_object_id())
|
||||
{} // don't copy id
|
||||
self_t &operator = (self_t const &other)
|
||||
{ // don't assign id
|
||||
base_t::operator=(other);
|
||||
return *this;
|
||||
}
|
||||
~object_with_id() { base_t::release_object_id(id); }
|
||||
object_id get_object_id() const { return id; }
|
||||
|
||||
private:
|
||||
|
||||
object_id const id;
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename IdT>
|
||||
inline IdT
|
||||
object_with_id_base_supply<IdT>::acquire()
|
||||
{
|
||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
||||
boost::mutex::scoped_lock lock(mutex);
|
||||
#endif
|
||||
if (free_ids.size())
|
||||
{
|
||||
object_id id = *free_ids.rbegin();
|
||||
free_ids.pop_back();
|
||||
return id;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (free_ids.capacity()<=max_id)
|
||||
free_ids.reserve(max_id*3/2+1);
|
||||
return ++max_id;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename IdT>
|
||||
inline void
|
||||
object_with_id_base_supply<IdT>::release(IdT id)
|
||||
{
|
||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
||||
boost::mutex::scoped_lock lock(mutex);
|
||||
#endif
|
||||
if (max_id == id)
|
||||
max_id--;
|
||||
else
|
||||
free_ids.push_back(id); // doesn't throw
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename TagT, typename IdT>
|
||||
inline IdT
|
||||
object_with_id_base<TagT, IdT>::acquire_object_id()
|
||||
{
|
||||
{
|
||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
||||
static boost::once_flag been_here = BOOST_ONCE_INIT;
|
||||
boost::call_once(been_here, mutex_init);
|
||||
boost::mutex &mutex = mutex_instance();
|
||||
boost::mutex::scoped_lock lock(mutex);
|
||||
#endif
|
||||
static boost::shared_ptr<object_with_id_base_supply<IdT> >
|
||||
static_supply;
|
||||
|
||||
if (!static_supply.get())
|
||||
static_supply.reset(new object_with_id_base_supply<IdT>());
|
||||
id_supply = static_supply;
|
||||
}
|
||||
|
||||
return id_supply->acquire();
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename TagT, typename IdT>
|
||||
inline void
|
||||
object_with_id_base<TagT, IdT>::release_object_id(IdT id)
|
||||
{
|
||||
id_supply->release(id);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
||||
template <typename TagT, typename IdT>
|
||||
inline boost::mutex &
|
||||
object_with_id_base<TagT, IdT>::mutex_instance()
|
||||
{
|
||||
static boost::mutex mutex;
|
||||
return mutex;
|
||||
}
|
||||
#endif
|
||||
|
||||
//////////////////////////////////
|
||||
#ifdef BOOST_SPIRIT_THREADSAFE
|
||||
template <typename TagT, typename IdT>
|
||||
inline void
|
||||
object_with_id_base<TagT, IdT>::mutex_init()
|
||||
{
|
||||
mutex_instance();
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace impl
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,420 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_RULE_IPP)
|
||||
#define BOOST_SPIRIT_RULE_IPP
|
||||
|
||||
#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
|
||||
#include <boost/preprocessor/repeat.hpp>
|
||||
#include <boost/preprocessor/repeat_from_to.hpp>
|
||||
#include <boost/preprocessor/enum_params.hpp>
|
||||
#include <boost/preprocessor/enum_params_with_defaults.hpp>
|
||||
#include <boost/preprocessor/facilities/intercept.hpp>
|
||||
#include <boost/preprocessor/inc.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/scanner/scanner.hpp>
|
||||
#include <boost/spirit/home/classic/core/non_terminal/parser_context.hpp>
|
||||
#include <boost/spirit/home/classic/core/non_terminal/parser_id.hpp>
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
|
||||
|
||||
template <
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(
|
||||
BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT,
|
||||
typename ScannerT, = mpl::void_ BOOST_PP_INTERCEPT
|
||||
)
|
||||
>
|
||||
struct scanner_list;
|
||||
|
||||
#endif // BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace impl
|
||||
{
|
||||
template <typename BaseT, typename DefaultT
|
||||
, typename T0, typename T1, typename T2>
|
||||
struct get_param
|
||||
{
|
||||
typedef typename mpl::if_<
|
||||
is_base_and_derived<BaseT, T0>
|
||||
, T0
|
||||
, typename mpl::if_<
|
||||
is_base_and_derived<BaseT, T1>
|
||||
, T1
|
||||
, typename mpl::if_<
|
||||
is_base_and_derived<BaseT, T2>
|
||||
, T2
|
||||
, DefaultT
|
||||
>::type
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename T0, typename T1, typename T2>
|
||||
struct get_context
|
||||
{
|
||||
typedef typename get_param<
|
||||
parser_context_base, parser_context<>, T0, T1, T2>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename T0, typename T1, typename T2>
|
||||
struct get_tag
|
||||
{
|
||||
typedef typename get_param<
|
||||
parser_tag_base, parser_address_tag, T0, T1, T2>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename T0, typename T1, typename T2>
|
||||
struct get_scanner
|
||||
{
|
||||
typedef typename get_param<
|
||||
scanner_base, scanner<>, T0, T1, T2>::type
|
||||
type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// rule_base class
|
||||
//
|
||||
// The rule_base class implements the basic plumbing for rules
|
||||
// minus the storage mechanism. It is up to the derived class
|
||||
// to actually store the definition somewhere. The rule_base
|
||||
// class assumes that the derived class provides a get() function
|
||||
// that will return a pointer to a parser. The get() function
|
||||
// may return NULL. See rule below for details.
|
||||
//
|
||||
// <<< For framework use only. Not for public consumption. >>>
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename DerivedT // derived class
|
||||
, typename EmbedT // how derived class is embedded
|
||||
, typename T0 = nil_t // see rule class
|
||||
, typename T1 = nil_t // see rule class
|
||||
, typename T2 = nil_t // see rule class
|
||||
>
|
||||
class rule_base; // forward declaration
|
||||
|
||||
class rule_base_access
|
||||
{
|
||||
#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \
|
||||
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
public: // YUCK!
|
||||
#else
|
||||
template <
|
||||
typename DerivedT
|
||||
, typename EmbedT
|
||||
, typename T0
|
||||
, typename T1
|
||||
, typename T2
|
||||
>
|
||||
friend class rule_base;
|
||||
#endif
|
||||
template <typename RuleT>
|
||||
static typename RuleT::abstract_parser_t*
|
||||
get(RuleT const& r)
|
||||
{
|
||||
return r.get();
|
||||
}
|
||||
};
|
||||
|
||||
template <
|
||||
typename DerivedT // derived class
|
||||
, typename EmbedT // how derived class is embedded
|
||||
, typename T0 // see rule class
|
||||
, typename T1 // see rule class
|
||||
, typename T2 // see rule class
|
||||
>
|
||||
class rule_base
|
||||
: public parser<DerivedT>
|
||||
, public impl::get_context<T0, T1, T2>::type::base_t
|
||||
, public context_aux<
|
||||
typename impl::get_context<T0, T1, T2>::type, DerivedT>
|
||||
, public impl::get_tag<T0, T1, T2>::type
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename impl::get_scanner<T0, T1, T2>::type scanner_t;
|
||||
typedef typename impl::get_context<T0, T1, T2>::type context_t;
|
||||
typedef typename impl::get_tag<T0, T1, T2>::type tag_t;
|
||||
|
||||
typedef EmbedT embed_t;
|
||||
typedef typename context_t::context_linker_t linked_context_t;
|
||||
typedef typename linked_context_t::attr_t attr_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, attr_t>::type type;
|
||||
};
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<DerivedT, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef parser_scanner_linker<ScannerT> linked_scanner_t;
|
||||
typedef typename parser_result<DerivedT, ScannerT>::type result_t;
|
||||
BOOST_SPIRIT_CONTEXT_PARSE(
|
||||
scan, *this, linked_scanner_t, linked_context_t, result_t);
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<DerivedT, ScannerT>::type
|
||||
parse_main(ScannerT const& scan) const
|
||||
{
|
||||
typename parser_result<DerivedT, ScannerT>::type hit;
|
||||
|
||||
// MWCW 8.3 needs this cast to be done through a pointer,
|
||||
// not a reference. Otherwise, it will silently construct
|
||||
// a temporary, causing an infinite runtime recursion.
|
||||
DerivedT const* derived_this = static_cast<DerivedT const*>(this);
|
||||
|
||||
if (rule_base_access::get(*derived_this))
|
||||
{
|
||||
typename ScannerT::iterator_t s(scan.first);
|
||||
hit = rule_base_access::get(*derived_this)
|
||||
->do_parse_virtual(scan);
|
||||
scan.group_match(hit, this->id(), s, scan.first);
|
||||
}
|
||||
else
|
||||
{
|
||||
hit = scan.no_match();
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// abstract_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename ScannerT, typename AttrT>
|
||||
struct abstract_parser
|
||||
{
|
||||
abstract_parser() {}
|
||||
virtual ~abstract_parser() {}
|
||||
|
||||
virtual typename match_result<ScannerT, AttrT>::type
|
||||
do_parse_virtual(ScannerT const& scan) const = 0;
|
||||
|
||||
virtual abstract_parser*
|
||||
clone() const = 0;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// concrete_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
template <typename ParserT, typename ScannerT, typename AttrT>
|
||||
struct concrete_parser : abstract_parser<ScannerT, AttrT>
|
||||
{
|
||||
concrete_parser(ParserT const& p_) : p(p_) {}
|
||||
virtual ~concrete_parser() {}
|
||||
|
||||
virtual typename match_result<ScannerT, AttrT>::type
|
||||
do_parse_virtual(ScannerT const& scan) const
|
||||
{
|
||||
return p.parse(scan);
|
||||
}
|
||||
|
||||
virtual abstract_parser<ScannerT, AttrT>*
|
||||
clone() const
|
||||
{
|
||||
return new concrete_parser(p);
|
||||
}
|
||||
|
||||
typename ParserT::embed_t p;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This generates partial specializations for the class
|
||||
//
|
||||
// abstract_parser
|
||||
//
|
||||
// with an increasing number of different ScannerT template parameters
|
||||
// and corresponding do_parse_virtual function declarations for each
|
||||
// of the different required scanner types:
|
||||
//
|
||||
// template <typename ScannerT0, ..., typename AttrT>
|
||||
// struct abstract_parser<scanner_list<ScannerT0, ...>, AttrT>
|
||||
// {
|
||||
// abstract_parser() {}
|
||||
// virtual ~abstract_parser() {}
|
||||
//
|
||||
// virtual typename match_result<ScannerT0, AttrT>::type
|
||||
// do_parse_virtual(ScannerT0 const &scan) const = 0;
|
||||
//
|
||||
// virtual abstract_parser*
|
||||
// clone() const = 0;
|
||||
//
|
||||
// ...
|
||||
// };
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_SPIRIT_RULE_ENUM_DOPARSE_A(z, N, _) \
|
||||
virtual typename match_result< \
|
||||
BOOST_PP_CAT(ScannerT, N), AttrT \
|
||||
>::type \
|
||||
do_parse_virtual( \
|
||||
BOOST_PP_CAT(ScannerT, N) const& scan) const = 0; \
|
||||
|
||||
#define BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS(z, N, _) \
|
||||
template < \
|
||||
BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename ScannerT), \
|
||||
typename AttrT \
|
||||
> \
|
||||
struct abstract_parser< \
|
||||
scanner_list< \
|
||||
BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \
|
||||
>, \
|
||||
AttrT \
|
||||
> \
|
||||
{ \
|
||||
abstract_parser() {} \
|
||||
virtual ~abstract_parser() {} \
|
||||
\
|
||||
BOOST_PP_REPEAT_ ## z( \
|
||||
BOOST_PP_INC(N), BOOST_SPIRIT_RULE_ENUM_DOPARSE_A, _) \
|
||||
\
|
||||
virtual abstract_parser* \
|
||||
clone() const = 0; \
|
||||
}; \
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT,
|
||||
BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS, _)
|
||||
|
||||
#undef BOOST_SPIRIT_RULE_ENUM_DOPARSE_A
|
||||
#undef BOOST_SPIRIT_ENUM_ABSTRACT_PARSERS
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This generates partial specializations for the class
|
||||
//
|
||||
// concrete_parser
|
||||
//
|
||||
// with an increasing number of different ScannerT template parameters
|
||||
// and corresponding do_parse_virtual function declarations for each
|
||||
// of the different required scanner types:
|
||||
//
|
||||
// template <
|
||||
// typename ParserT, typename ScannerT0, ..., typename AttrT
|
||||
// >
|
||||
// struct concrete_parser<
|
||||
// ParserT, scanner_list<ScannerT0, ...>, AttrT
|
||||
// >
|
||||
// : public abstract_parser<scanner_list<ScannerT0, ...>, AttrT>
|
||||
// {
|
||||
// concrete_parser(ParserT const& p_) : p(p_) {}
|
||||
// virtual ~concrete_parser() {}
|
||||
//
|
||||
// virtual typename match_result<ScannerT0, AttrT>::type
|
||||
// do_parse_virtual(ScannerT0 const &scan) const
|
||||
// { return p.parse(scan); }
|
||||
//
|
||||
// virtual abstract_parser<scanner_list<ScannerT0, ...>, AttrT>*
|
||||
// clone() const
|
||||
// {
|
||||
// return new concrete_parser(p);
|
||||
// }
|
||||
//
|
||||
// ...
|
||||
//
|
||||
// typename ParserT::embed_t p;
|
||||
// };
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_SPIRIT_RULE_ENUM_DOPARSE_C(z, N, _) \
|
||||
virtual typename match_result< \
|
||||
BOOST_PP_CAT(ScannerT, N), AttrT \
|
||||
>::type \
|
||||
do_parse_virtual( \
|
||||
BOOST_PP_CAT(ScannerT, N) const& scan) const \
|
||||
{ return p.parse(scan); } \
|
||||
|
||||
#define BOOST_SPIRIT_ENUM_CONCRETE_PARSERS(z, N, _) \
|
||||
template < \
|
||||
typename ParserT, \
|
||||
BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename ScannerT), \
|
||||
typename AttrT \
|
||||
> \
|
||||
struct concrete_parser< \
|
||||
ParserT, \
|
||||
scanner_list< \
|
||||
BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \
|
||||
>, \
|
||||
AttrT \
|
||||
> \
|
||||
: abstract_parser< \
|
||||
scanner_list< \
|
||||
BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \
|
||||
>, \
|
||||
AttrT \
|
||||
> \
|
||||
{ \
|
||||
concrete_parser(ParserT const& p_) : p(p_) {} \
|
||||
virtual ~concrete_parser() {} \
|
||||
\
|
||||
BOOST_PP_REPEAT_ ## z( \
|
||||
BOOST_PP_INC(N), BOOST_SPIRIT_RULE_ENUM_DOPARSE_C, _) \
|
||||
\
|
||||
virtual abstract_parser< \
|
||||
scanner_list< \
|
||||
BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), ScannerT) \
|
||||
>, \
|
||||
AttrT \
|
||||
>* \
|
||||
clone() const \
|
||||
{ \
|
||||
return new concrete_parser(p); \
|
||||
} \
|
||||
\
|
||||
typename ParserT::embed_t p; \
|
||||
}; \
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT,
|
||||
BOOST_SPIRIT_ENUM_CONCRETE_PARSERS, _)
|
||||
|
||||
#undef BOOST_SPIRIT_ENUM_CONCRETE_PARSERS
|
||||
#undef BOOST_SPIRIT_RULE_ENUM_DOPARSE_C
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
|
||||
|
||||
} // namespace impl
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,120 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2006 Joao Abecasis
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_STATIC_HPP)
|
||||
#define BOOST_SPIRIT_STATIC_HPP
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <boost/aligned_storage.hpp>
|
||||
|
||||
#include <boost/type_traits/add_pointer.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
|
||||
#include <boost/thread/once.hpp>
|
||||
|
||||
#include <memory> // for placement new
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
//
|
||||
// Provides thread-safe initialization of a single static instance of T.
|
||||
//
|
||||
// This instance is guaranteed to be constructed on static storage in a
|
||||
// thread-safe manner, on the first call to the constructor of static_.
|
||||
//
|
||||
// Requirements:
|
||||
// T is default constructible
|
||||
// (There's an alternate implementation that relaxes this
|
||||
// requirement -- Joao Abecasis)
|
||||
// T::T() MUST not throw!
|
||||
// this is a requirement of boost::call_once.
|
||||
//
|
||||
template <class T, class Tag>
|
||||
struct static_
|
||||
: boost::noncopyable
|
||||
{
|
||||
private:
|
||||
|
||||
struct destructor
|
||||
{
|
||||
~destructor()
|
||||
{
|
||||
static_::get_address()->~value_type();
|
||||
}
|
||||
};
|
||||
|
||||
struct default_ctor
|
||||
{
|
||||
static void construct()
|
||||
{
|
||||
::new (static_::get_address()) value_type();
|
||||
static destructor d;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
typedef typename boost::call_traits<T>::reference reference;
|
||||
typedef typename boost::call_traits<T>::const_reference const_reference;
|
||||
|
||||
static_(Tag = Tag())
|
||||
{
|
||||
boost::call_once(&default_ctor::construct, constructed_);
|
||||
}
|
||||
|
||||
operator reference()
|
||||
{
|
||||
return this->get();
|
||||
}
|
||||
|
||||
operator const_reference() const
|
||||
{
|
||||
return this->get();
|
||||
}
|
||||
|
||||
reference get()
|
||||
{
|
||||
return *this->get_address();
|
||||
}
|
||||
|
||||
const_reference get() const
|
||||
{
|
||||
return *this->get_address();
|
||||
}
|
||||
|
||||
private:
|
||||
typedef typename boost::add_pointer<value_type>::type pointer;
|
||||
|
||||
static pointer get_address()
|
||||
{
|
||||
return static_cast<pointer>(data_.address());
|
||||
}
|
||||
|
||||
typedef boost::aligned_storage<sizeof(value_type),
|
||||
boost::alignment_of<value_type>::value> storage_type;
|
||||
|
||||
static storage_type data_;
|
||||
static once_flag constructed_;
|
||||
};
|
||||
|
||||
template <class T, class Tag>
|
||||
typename static_<T, Tag>::storage_type static_<T, Tag>::data_;
|
||||
|
||||
template <class T, class Tag>
|
||||
once_flag static_<T, Tag>::constructed_ = BOOST_ONCE_INIT;
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif // include guard
|
||||
@@ -0,0 +1,211 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2002-2003 Joel de Guzman
|
||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_SUBRULE_IPP)
|
||||
#define BOOST_SPIRIT_SUBRULE_IPP
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
template <typename FirstT, typename RestT>
|
||||
struct subrule_list;
|
||||
|
||||
template <int ID, typename DefT, typename ContextT>
|
||||
struct subrule_parser;
|
||||
|
||||
namespace impl {
|
||||
|
||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
template <int N, typename ListT>
|
||||
struct get_subrule;
|
||||
|
||||
template <int N, typename ListT>
|
||||
struct get_subrule_chooser
|
||||
{
|
||||
static ListT t();
|
||||
static char test(nil_t);
|
||||
static int test(...);
|
||||
|
||||
// Set value to
|
||||
// 0: ListT is empty
|
||||
// 1: ListT's first item has same ID
|
||||
// 2: ListT's first item has a different ID
|
||||
|
||||
enum
|
||||
{
|
||||
id = ListT::first_t::id,
|
||||
is_same_id = N == id,
|
||||
is_nil_t = sizeof(char) == sizeof(test(t())),
|
||||
value = is_nil_t ? 0 : (is_same_id ? 1 : 2)
|
||||
};
|
||||
};
|
||||
|
||||
template <int N>
|
||||
struct subrule_chooser;
|
||||
|
||||
template <>
|
||||
struct subrule_chooser<0>
|
||||
{
|
||||
// First case. ListT is empty
|
||||
|
||||
template <int N, typename ListT>
|
||||
struct result
|
||||
{ typedef nil_t type; };
|
||||
};
|
||||
|
||||
template <>
|
||||
struct subrule_chooser<1>
|
||||
{
|
||||
// Second case. ListT is non-empty and the list's
|
||||
// first item has the ID we are looking for.
|
||||
|
||||
template <int N, typename ListT>
|
||||
struct result
|
||||
{ typedef typename ListT::first_t::def_t type; };
|
||||
};
|
||||
|
||||
template <>
|
||||
struct subrule_chooser<2>
|
||||
{
|
||||
// Third case. ListT is non-empty but the list's
|
||||
// first item does not have the ID we are looking for.
|
||||
|
||||
template <int N, typename ListT>
|
||||
struct result
|
||||
{ typedef typename get_subrule<N, ListT::rest_t>::type type; };
|
||||
};
|
||||
|
||||
template <int N, typename ListT>
|
||||
struct get_subrule
|
||||
{
|
||||
enum { n = get_subrule_chooser<N, ListT>::value };
|
||||
typedef typename subrule_chooser<n>::template
|
||||
result<N, ListT>::type type;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template <int N, typename ListT>
|
||||
struct get_subrule
|
||||
{
|
||||
// First case. ListT is non-empty but the list's
|
||||
// first item does not have the ID we are looking for.
|
||||
|
||||
typedef typename get_subrule<N, typename ListT::rest_t>::type type;
|
||||
};
|
||||
|
||||
template <int ID, typename DefT, typename ContextT, typename RestT>
|
||||
struct get_subrule<
|
||||
ID,
|
||||
subrule_list<
|
||||
subrule_parser<ID, DefT, ContextT>,
|
||||
RestT> >
|
||||
{
|
||||
// Second case. ListT is non-empty and the list's
|
||||
// first item has the ID we are looking for.
|
||||
|
||||
typedef DefT type;
|
||||
};
|
||||
|
||||
template <int ID>
|
||||
struct get_subrule<ID, nil_t>
|
||||
{
|
||||
// Third case. ListT is empty
|
||||
typedef nil_t type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct get_result_t {
|
||||
|
||||
// If the result type dictated by the context is nil_t (no closures
|
||||
// present), then the whole subrule_parser return type is equal to
|
||||
// the return type of the right hand side of this subrule_parser,
|
||||
// otherwise it is equal to the dictated return value.
|
||||
|
||||
typedef typename mpl::if_<
|
||||
boost::is_same<T1, nil_t>, T2, T1
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <int ID, typename ScannerT, typename ContextResultT>
|
||||
struct get_subrule_result
|
||||
{
|
||||
typedef typename
|
||||
impl::get_subrule<ID, typename ScannerT::list_t>::type
|
||||
parser_t;
|
||||
|
||||
typedef typename parser_result<parser_t, ScannerT>::type
|
||||
def_result_t;
|
||||
|
||||
typedef typename match_result<ScannerT, ContextResultT>::type
|
||||
context_result_t;
|
||||
|
||||
typedef typename get_result_t<context_result_t, def_result_t>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename DefT, typename ScannerT, typename ContextResultT>
|
||||
struct get_subrule_parser_result
|
||||
{
|
||||
typedef typename parser_result<DefT, ScannerT>::type
|
||||
def_result_t;
|
||||
|
||||
typedef typename match_result<ScannerT, ContextResultT>::type
|
||||
context_result_t;
|
||||
|
||||
typedef typename get_result_t<context_result_t, def_result_t>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename SubruleT, int ID>
|
||||
struct same_subrule_id
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = (SubruleT::id == ID));
|
||||
};
|
||||
|
||||
template <typename RT, typename ScannerT, int ID>
|
||||
struct parse_subrule
|
||||
{
|
||||
template <typename ListT>
|
||||
static void
|
||||
do_parse(RT& r, ScannerT const& scan, ListT const& list, mpl::true_)
|
||||
{
|
||||
r = list.first.rhs.parse(scan);
|
||||
}
|
||||
|
||||
template <typename ListT>
|
||||
static void
|
||||
do_parse(RT& r, ScannerT const& scan, ListT const& list, mpl::false_)
|
||||
{
|
||||
typedef typename ListT::rest_t::first_t subrule_t;
|
||||
mpl::bool_<same_subrule_id<subrule_t, ID>::value> same_id;
|
||||
do_parse(r, scan, list.rest, same_id);
|
||||
}
|
||||
|
||||
static void
|
||||
do_(RT& r, ScannerT const& scan)
|
||||
{
|
||||
typedef typename ScannerT::list_t::first_t subrule_t;
|
||||
mpl::bool_<same_subrule_id<subrule_t, ID>::value> same_id;
|
||||
do_parse(r, scan, scan.list, same_id);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit::impl
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2002-2003 Joel de Guzman
|
||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_PARSER_CONTEXT_HPP)
|
||||
#define BOOST_SPIRIT_PARSER_CONTEXT_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost
|
||||
{
|
||||
namespace spirit
|
||||
{
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// default_parser_context_base class { default context base }
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct default_parser_context_base
|
||||
{
|
||||
template <typename DerivedT>
|
||||
struct aux {};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// parser_context_base class { base class of all context classes }
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct parser_context_base {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// parser_context class { default context }
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct nil_t;
|
||||
template<typename ContextT> struct parser_context_linker;
|
||||
|
||||
template<typename AttrT = nil_t>
|
||||
struct parser_context : parser_context_base
|
||||
{
|
||||
typedef AttrT attr_t;
|
||||
typedef default_parser_context_base base_t;
|
||||
typedef parser_context_linker<parser_context<AttrT> > context_linker_t;
|
||||
|
||||
template <typename ParserT>
|
||||
parser_context(ParserT const&) {}
|
||||
|
||||
template <typename ParserT, typename ScannerT>
|
||||
void
|
||||
pre_parse(ParserT const&, ScannerT const&) {}
|
||||
|
||||
template <typename ResultT, typename ParserT, typename ScannerT>
|
||||
ResultT&
|
||||
post_parse(ResultT& hit, ParserT const&, ScannerT const&)
|
||||
{ return hit; }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// context_aux class
|
||||
//
|
||||
// context_aux<ContextT, DerivedT> is a class derived from the
|
||||
// ContextT's nested base_t::base<DerivedT> template class. (see
|
||||
// default_parser_context_base::aux for an example).
|
||||
//
|
||||
// Basically, this class provides ContextT dependent optional
|
||||
// functionality to the derived class DerivedT through the CRTP
|
||||
// idiom (Curiously recurring template pattern).
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename ContextT, typename DerivedT>
|
||||
struct context_aux : public ContextT::base_t::template aux<DerivedT> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// parser_scanner_linker and parser_scanner_linker classes
|
||||
// { helper templates for the rule extensibility }
|
||||
//
|
||||
// This classes can be 'overloaded' (defined elsewhere), to plug
|
||||
// in additional functionality into the non-terminal parsing process.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED)
|
||||
#define BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED
|
||||
|
||||
template<typename ScannerT>
|
||||
struct parser_scanner_linker : public ScannerT
|
||||
{
|
||||
parser_scanner_linker(ScannerT const scan_) : ScannerT(scan_) {}
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED)
|
||||
|
||||
//////////////////////////////////
|
||||
#if !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED)
|
||||
#define BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED
|
||||
|
||||
template<typename ContextT>
|
||||
struct parser_context_linker : public ContextT
|
||||
{
|
||||
template <typename ParserT>
|
||||
parser_context_linker(ParserT const& p)
|
||||
: ContextT(p) {}
|
||||
|
||||
template <typename ParserT, typename ScannerT>
|
||||
void pre_parse(ParserT const& p, ScannerT const& scan)
|
||||
{ ContextT::pre_parse(p, scan); }
|
||||
|
||||
template <typename ResultT, typename ParserT, typename ScannerT>
|
||||
ResultT&
|
||||
post_parse(ResultT& hit, ParserT const& p, ScannerT const& scan)
|
||||
{ return ContextT::post_parse(hit, p, scan); }
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BOOST_SPIRIT_CONTEXT_PARSE helper macro
|
||||
//
|
||||
// The original implementation uses a template class. However, we
|
||||
// need to lessen the template instantiation depth to help inferior
|
||||
// compilers that sometimes choke on deep template instantiations.
|
||||
// The objective is to avoid code redundancy. A macro, in this case
|
||||
// is an obvious solution. Sigh!
|
||||
//
|
||||
// WARNING: INTERNAL USE ONLY. NOT FOR PUBLIC CONSUMPTION.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_SPIRIT_CONTEXT_PARSE(scan, this_, scanner_t, context_t, result_t) \
|
||||
scanner_t scan_wrap(scan); \
|
||||
context_t context_wrap(this_); \
|
||||
context_wrap.pre_parse(this_, scan_wrap); \
|
||||
result_t hit = parse_main(scan); \
|
||||
return context_wrap.post_parse(hit, this_, scan_wrap);
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
} // namespace spirit
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,122 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2003 Joel de Guzman
|
||||
Copyright (c) 2001 Daniel Nuffer
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_PARSER_ID_HPP)
|
||||
#define BOOST_SPIRIT_PARSER_ID_HPP
|
||||
|
||||
#if defined(BOOST_SPIRIT_DEBUG)
|
||||
# include <ostream>
|
||||
#endif
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// parser_id class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
class parser_id
|
||||
{
|
||||
public:
|
||||
parser_id() : p(0) {}
|
||||
explicit parser_id(void const* prule) : p(prule) {}
|
||||
parser_id(std::size_t l_) : l(l_) {}
|
||||
|
||||
bool operator==(parser_id const& x) const { return p == x.p; }
|
||||
bool operator!=(parser_id const& x) const { return !(*this == x); }
|
||||
bool operator<(parser_id const& x) const { return p < x.p; }
|
||||
std::size_t to_long() const { return l; }
|
||||
|
||||
private:
|
||||
|
||||
union
|
||||
{
|
||||
void const* p;
|
||||
std::size_t l;
|
||||
};
|
||||
};
|
||||
|
||||
#if defined(BOOST_SPIRIT_DEBUG)
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, parser_id const& rid)
|
||||
{
|
||||
out << (unsigned int)rid.to_long();
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// parser_tag_base class: base class of all parser tags
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct parser_tag_base {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// parser_address_tag class: tags a parser with its address
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct parser_address_tag : parser_tag_base
|
||||
{
|
||||
parser_id id() const
|
||||
{ return parser_id(reinterpret_cast<std::size_t>(this)); }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// parser_tag class: tags a parser with an integer ID
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <int N>
|
||||
struct parser_tag : parser_tag_base
|
||||
{
|
||||
static parser_id id()
|
||||
{ return parser_id(std::size_t(N)); }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// dynamic_parser_tag class: tags a parser with a dynamically changeable
|
||||
// integer ID
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
class dynamic_parser_tag : public parser_tag_base
|
||||
{
|
||||
public:
|
||||
|
||||
dynamic_parser_tag()
|
||||
: tag(std::size_t(0)) {}
|
||||
|
||||
parser_id
|
||||
id() const
|
||||
{
|
||||
return
|
||||
tag.to_long()
|
||||
? tag
|
||||
: parser_id(reinterpret_cast<std::size_t>(this));
|
||||
}
|
||||
|
||||
void set_id(parser_id id_) { tag = id_; }
|
||||
|
||||
private:
|
||||
|
||||
parser_id tag;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_RULE_HPP)
|
||||
#define BOOST_SPIRIT_RULE_HPP
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Spirit predefined maximum number of simultaneously usable different
|
||||
// scanner types.
|
||||
//
|
||||
// This limit defines the maximum number of of possible different scanner
|
||||
// types for which a specific rule<> may be used. If this isn't defined, a
|
||||
// rule<> may be used with one scanner type only (multiple scanner support
|
||||
// is disabled).
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT)
|
||||
# define BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT 1
|
||||
#endif
|
||||
|
||||
// Ensure a meaningful maximum number of simultaneously usable scanner types
|
||||
BOOST_STATIC_ASSERT(BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 0);
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/non_terminal/impl/rule.ipp>
|
||||
|
||||
#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
|
||||
# include <boost/preprocessor/enum_params.hpp>
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// scanner_list (a fake scanner)
|
||||
//
|
||||
// Typically, rules are tied to a specific scanner type and
|
||||
// a particular rule cannot be used with anything else. Sometimes
|
||||
// there's a need for rules that can accept more than one scanner
|
||||
// type. The scanner_list<S0, ...SN> can be used as a template
|
||||
// parameter to the rule class to specify up to the number of
|
||||
// scanner types defined by the BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT
|
||||
// constant. Example:
|
||||
//
|
||||
// rule<scanner_list<ScannerT0, ScannerT1> > r;
|
||||
//
|
||||
// *** This feature is available only to compilers that support
|
||||
// partial template specialization. ***
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
BOOST_PP_ENUM_PARAMS(
|
||||
BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT,
|
||||
typename ScannerT
|
||||
)
|
||||
>
|
||||
struct scanner_list : scanner_base {};
|
||||
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// rule class
|
||||
//
|
||||
// The rule is a polymorphic parser that acts as a named place-
|
||||
// holder capturing the behavior of an EBNF expression assigned to
|
||||
// it.
|
||||
//
|
||||
// The rule is a template class parameterized by:
|
||||
//
|
||||
// 1) scanner (scanner_t, see scanner.hpp),
|
||||
// 2) the rule's context (context_t, see parser_context.hpp)
|
||||
// 3) an arbitrary tag (tag_t, see parser_id.hpp) that allows
|
||||
// a rule to be tagged for identification.
|
||||
//
|
||||
// These template parameters may be specified in any order. The
|
||||
// scanner will default to scanner<> when it is not specified.
|
||||
// The context will default to parser_context when not specified.
|
||||
// The tag will default to parser_address_tag when not specified.
|
||||
//
|
||||
// The definition of the rule (its right hand side, RHS) held by
|
||||
// the rule through a scoped_ptr. When a rule is seen in the RHS
|
||||
// of an assignment or copy construction EBNF expression, the rule
|
||||
// is held by the LHS rule by reference.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename T0 = nil_t
|
||||
, typename T1 = nil_t
|
||||
, typename T2 = nil_t
|
||||
>
|
||||
class rule
|
||||
: public impl::rule_base<
|
||||
rule<T0, T1, T2>
|
||||
, rule<T0, T1, T2> const&
|
||||
, T0, T1, T2>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef rule<T0, T1, T2> self_t;
|
||||
typedef impl::rule_base<
|
||||
self_t
|
||||
, self_t const&
|
||||
, T0, T1, T2>
|
||||
base_t;
|
||||
|
||||
typedef typename base_t::scanner_t scanner_t;
|
||||
typedef typename base_t::attr_t attr_t;
|
||||
typedef impl::abstract_parser<scanner_t, attr_t> abstract_parser_t;
|
||||
|
||||
rule() : ptr() {}
|
||||
~rule() {}
|
||||
|
||||
rule(rule const& r)
|
||||
: ptr(new impl::concrete_parser<rule, scanner_t, attr_t>(r)) {}
|
||||
|
||||
template <typename ParserT>
|
||||
rule(ParserT const& p)
|
||||
: ptr(new impl::concrete_parser<ParserT, scanner_t, attr_t>(p)) {}
|
||||
|
||||
template <typename ParserT>
|
||||
rule& operator=(ParserT const& p)
|
||||
{
|
||||
ptr.reset(new impl::concrete_parser<ParserT, scanner_t, attr_t>(p));
|
||||
return *this;
|
||||
}
|
||||
|
||||
rule& operator=(rule const& r)
|
||||
{
|
||||
ptr.reset(new impl::concrete_parser<rule, scanner_t, attr_t>(r));
|
||||
return *this;
|
||||
}
|
||||
|
||||
rule<T0, T1, T2>
|
||||
copy() const
|
||||
{
|
||||
return rule<T0, T1, T2>(ptr.get() ? ptr->clone() : 0);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class impl::rule_base_access;
|
||||
|
||||
abstract_parser_t*
|
||||
get() const
|
||||
{
|
||||
return ptr.get();
|
||||
}
|
||||
|
||||
rule(abstract_parser_t* ptr_)
|
||||
: ptr(ptr_) {}
|
||||
|
||||
rule(abstract_parser_t const* ptr_)
|
||||
: ptr(ptr_) {}
|
||||
|
||||
scoped_ptr<abstract_parser_t> ptr;
|
||||
};
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,300 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2002-2003 Joel de Guzman
|
||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_SUBRULE_HPP)
|
||||
#define BOOST_SPIRIT_SUBRULE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/non_terminal/parser_context.hpp>
|
||||
|
||||
#include <boost/spirit/home/classic/core/non_terminal/subrule_fwd.hpp>
|
||||
#include <boost/spirit/home/classic/core/non_terminal/impl/subrule.ipp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// subrules_scanner class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename ScannerT, typename ListT>
|
||||
struct subrules_scanner : public ScannerT
|
||||
{
|
||||
typedef ScannerT scanner_t;
|
||||
typedef ListT list_t;
|
||||
typedef subrules_scanner<ScannerT, ListT> self_t;
|
||||
|
||||
subrules_scanner(ScannerT const& scan, ListT const& list_)
|
||||
: ScannerT(scan), list(list_) {}
|
||||
|
||||
template <typename PoliciesT>
|
||||
struct rebind_policies
|
||||
{
|
||||
typedef typename rebind_scanner_policies<ScannerT, PoliciesT>::type
|
||||
rebind_scanner;
|
||||
typedef subrules_scanner<rebind_scanner, ListT> type;
|
||||
};
|
||||
|
||||
template <typename PoliciesT>
|
||||
subrules_scanner<
|
||||
typename rebind_scanner_policies<ScannerT, PoliciesT>::type,
|
||||
ListT>
|
||||
change_policies(PoliciesT const& policies) const
|
||||
{
|
||||
typedef subrules_scanner<
|
||||
BOOST_DEDUCED_TYPENAME
|
||||
rebind_scanner_policies<ScannerT, PoliciesT>::type,
|
||||
ListT>
|
||||
subrules_scanner_t;
|
||||
|
||||
return subrules_scanner_t(
|
||||
ScannerT::change_policies(policies),
|
||||
list);
|
||||
}
|
||||
|
||||
template <typename IteratorT>
|
||||
struct rebind_iterator
|
||||
{
|
||||
typedef typename rebind_scanner_iterator<ScannerT, IteratorT>::type
|
||||
rebind_scanner;
|
||||
typedef subrules_scanner<rebind_scanner, ListT> type;
|
||||
};
|
||||
|
||||
template <typename IteratorT>
|
||||
subrules_scanner<
|
||||
typename rebind_scanner_iterator<ScannerT, IteratorT>::type,
|
||||
ListT>
|
||||
change_iterator(IteratorT const& first, IteratorT const &last) const
|
||||
{
|
||||
typedef subrules_scanner<
|
||||
BOOST_DEDUCED_TYPENAME
|
||||
rebind_scanner_iterator<ScannerT, IteratorT>::type,
|
||||
ListT>
|
||||
subrules_scanner_t;
|
||||
|
||||
return subrules_scanner_t(
|
||||
ScannerT::change_iterator(first, last),
|
||||
list);
|
||||
}
|
||||
|
||||
ListT const& list;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// subrule_scanner type computer class
|
||||
//
|
||||
// This computer ensures that the scanner will not be recursively
|
||||
// instantiated if it's not needed.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename ScannerT, typename ListT>
|
||||
struct subrules_scanner_finder
|
||||
{
|
||||
typedef subrules_scanner<ScannerT, ListT> type;
|
||||
};
|
||||
|
||||
template <typename ScannerT, typename ListT>
|
||||
struct subrules_scanner_finder<subrules_scanner<ScannerT, ListT>, ListT>
|
||||
{
|
||||
typedef subrules_scanner<ScannerT, ListT> type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// subrule_list class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename FirstT, typename RestT>
|
||||
struct subrule_list : public parser<subrule_list<FirstT, RestT> >
|
||||
{
|
||||
typedef subrule_list<FirstT, RestT> self_t;
|
||||
typedef FirstT first_t;
|
||||
typedef RestT rest_t;
|
||||
|
||||
subrule_list(FirstT const& first_, RestT const& rest_)
|
||||
: first(first_), rest(rest_) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename parser_result<FirstT, ScannerT>::type type;
|
||||
};
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename subrules_scanner_finder<ScannerT, self_t>::type
|
||||
subrules_scanner_t;
|
||||
subrules_scanner_t g_arg(scan, *this);
|
||||
return first.start.parse(g_arg);
|
||||
}
|
||||
|
||||
template <int ID, typename DefT, typename ContextT>
|
||||
subrule_list<
|
||||
FirstT,
|
||||
subrule_list<
|
||||
subrule_parser<ID, DefT, ContextT>,
|
||||
RestT> >
|
||||
operator,(subrule_parser<ID, DefT, ContextT> const& rhs_)
|
||||
{
|
||||
return subrule_list<
|
||||
FirstT,
|
||||
subrule_list<
|
||||
subrule_parser<ID, DefT, ContextT>,
|
||||
RestT> >(
|
||||
first,
|
||||
subrule_list<
|
||||
subrule_parser<ID, DefT, ContextT>,
|
||||
RestT>(rhs_, rest));
|
||||
}
|
||||
|
||||
FirstT first;
|
||||
RestT rest;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// subrule_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <int ID, typename DefT, typename ContextT>
|
||||
struct subrule_parser
|
||||
: public parser<subrule_parser<ID, DefT, ContextT> >
|
||||
{
|
||||
typedef subrule_parser<ID, DefT, ContextT> self_t;
|
||||
typedef subrule<ID, ContextT> subrule_t;
|
||||
typedef DefT def_t;
|
||||
|
||||
BOOST_STATIC_CONSTANT(int, id = ID);
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename
|
||||
impl::get_subrule_parser_result<
|
||||
DefT, ScannerT, typename subrule_t::attr_t>::type type;
|
||||
};
|
||||
|
||||
subrule_parser(subrule_t const& start_, DefT const& rhs_)
|
||||
: rhs(rhs_), start(start_) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
// This will only be called when parsing single subrules.
|
||||
typedef subrule_list<self_t, nil_t> list_t;
|
||||
typedef subrules_scanner<ScannerT, list_t> scanner_t;
|
||||
|
||||
list_t list(*this, nil_t());
|
||||
scanner_t g_arg(scan, list);
|
||||
return start.parse(g_arg);
|
||||
}
|
||||
|
||||
template <int ID2, typename DefT2, typename ContextT2>
|
||||
inline subrule_list<
|
||||
self_t,
|
||||
subrule_list<
|
||||
subrule_parser<ID2, DefT2, ContextT2>,
|
||||
nil_t> >
|
||||
operator,(subrule_parser<ID2, DefT2, ContextT2> const& rhs) const
|
||||
{
|
||||
return subrule_list<
|
||||
self_t,
|
||||
subrule_list<
|
||||
subrule_parser<ID2, DefT2, ContextT2>,
|
||||
nil_t> >(
|
||||
*this,
|
||||
subrule_list<
|
||||
subrule_parser<ID2, DefT2, ContextT2>, nil_t>(
|
||||
rhs, nil_t()));
|
||||
}
|
||||
|
||||
typename DefT::embed_t rhs;
|
||||
subrule_t const& start;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// subrule class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <int ID, typename ContextT>
|
||||
struct subrule
|
||||
: public parser<subrule<ID, ContextT> >
|
||||
, public ContextT::base_t
|
||||
, public context_aux<ContextT, subrule<ID, ContextT> >
|
||||
{
|
||||
typedef subrule<ID, ContextT> self_t;
|
||||
typedef subrule<ID, ContextT> const& embed_t;
|
||||
|
||||
typedef typename ContextT::context_linker_t context_t;
|
||||
typedef typename context_t::attr_t attr_t;
|
||||
|
||||
BOOST_STATIC_CONSTANT(int, id = ID);
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename
|
||||
impl::get_subrule_result<ID, ScannerT, attr_t>::type type;
|
||||
};
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse_main(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
result_t result_;
|
||||
impl::parse_subrule<result_t, ScannerT, ID>::
|
||||
do_(result_, scan);
|
||||
return result_;
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
typedef parser_scanner_linker<ScannerT> scanner_t;
|
||||
BOOST_SPIRIT_CONTEXT_PARSE(
|
||||
scan, *this, scanner_t, context_t, result_t);
|
||||
}
|
||||
|
||||
template <typename DefT>
|
||||
subrule_parser<ID, DefT, ContextT>
|
||||
operator=(parser<DefT> const& rhs) const
|
||||
{
|
||||
return subrule_parser<ID, DefT, ContextT>(*this, rhs.derived());
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// assignment of subrules is not allowed. Use subrules
|
||||
// with identical IDs if you want to have aliases.
|
||||
|
||||
subrule& operator=(subrule const&);
|
||||
|
||||
template <int ID2, typename ContextT2>
|
||||
subrule& operator=(subrule<ID2, ContextT2> const&);
|
||||
};
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2006 Tobias Schwinger
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_SUBRULE_FWD_HPP)
|
||||
#define BOOST_SPIRIT_SUBRULE_FWD_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/non_terminal/parser_context.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
template <int ID, typename ContextT = parser_context<> >
|
||||
struct subrule;
|
||||
|
||||
template <int ID, typename DefT, typename ContextT = parser_context<> >
|
||||
struct subrule_parser;
|
||||
|
||||
template <typename ScannerT, typename ListT>
|
||||
struct subrules_scanner;
|
||||
|
||||
template <typename FirstT, typename RestT>
|
||||
struct subrule_list;
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_PARSER_HPP)
|
||||
#define BOOST_SPIRIT_PARSER_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/scanner/scanner.hpp>
|
||||
#include <boost/spirit/home/classic/core/nil.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
template <typename ParserT, typename ActionT>
|
||||
class action; // forward declaration
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Parser categories
|
||||
//
|
||||
// Helper template classes to distinguish different types of
|
||||
// parsers. The following categories are the most generic. More
|
||||
// specific types may inherit from these. Each parser has a typedef
|
||||
// parser_category_t that defines its category. By default, if one
|
||||
// is not specified, it will inherit from the base parser class
|
||||
// which typedefs its parser_category_t as plain_parser_category.
|
||||
//
|
||||
// - plain parser has nothing special
|
||||
// - binary parser has subject a and b (e.g. alternative)
|
||||
// - unary parser has single subject (e.g. kleene star)
|
||||
// - action parser has an attached action parser
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct plain_parser_category {};
|
||||
struct binary_parser_category : plain_parser_category {};
|
||||
struct unary_parser_category : plain_parser_category {};
|
||||
struct action_parser_category : unary_parser_category {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// parser_result metafunction
|
||||
//
|
||||
// Given a scanner type ScannerT and a parser type ParserT, the
|
||||
// parser_result metafunction provides the actual result of the
|
||||
// parser.
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// typename parser_result<ParserT, ScannerT>::type
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename ParserT, typename ScannerT>
|
||||
struct parser_result
|
||||
{
|
||||
typedef typename boost::remove_reference<ParserT>::type parser_type;
|
||||
typedef typename parser_type::template result<ScannerT>::type type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// parser class
|
||||
//
|
||||
// This class is a protocol base class for all parsers. This is
|
||||
// essentially an interface contract. The parser class does not
|
||||
// really know how to parse anything but instead relies on the
|
||||
// template parameter DerivedT (which obviously is assumed to be a
|
||||
// subclass) to do the actual parsing.
|
||||
//
|
||||
// Concrete sub-classes inheriting from parser must have a
|
||||
// corresponding member function parse(...) compatible with the
|
||||
// conceptual Interface:
|
||||
//
|
||||
// template <typename ScannerT>
|
||||
// RT parse(ScannerT const& scan) const;
|
||||
//
|
||||
// where RT is the desired return type of the parser and ScannerT
|
||||
// scan is the scanner (see scanner.hpp).
|
||||
//
|
||||
// Concrete sub-classes inheriting from parser in most cases need to
|
||||
// have a nested meta-function result that returns the result type
|
||||
// of the parser's parse member function, given a scanner type. The
|
||||
// meta-function has the form:
|
||||
//
|
||||
// template <typename ScannerT>
|
||||
// struct result
|
||||
// {
|
||||
// typedef RT type;
|
||||
// };
|
||||
//
|
||||
// where RT is the desired return type of the parser. This is
|
||||
// usually, but not always, dependent on the template parameter
|
||||
// ScannerT. If a parser does not supply a result metafunction, a
|
||||
// default is provided by the base parser class.
|
||||
//
|
||||
// The parser's derived() member function returns a reference to the
|
||||
// parser as its derived object.
|
||||
//
|
||||
// An operator[] is provided. The operator returns a semantic action
|
||||
// handler (see actions.hpp).
|
||||
//
|
||||
// Each parser has a typedef embed_t. This typedef specifies how a
|
||||
// parser is embedded in a composite (see composite.hpp). By
|
||||
// default, if one is not specified, the parser will be embedded by
|
||||
// value. That is, a copy of the parser is placed as a member
|
||||
// variable of the composite. Most parsers are embedded by value. In
|
||||
// certain situations however, this is not desirable or possible.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename DerivedT>
|
||||
struct parser
|
||||
{
|
||||
typedef DerivedT embed_t;
|
||||
typedef DerivedT derived_t;
|
||||
typedef plain_parser_category parser_category_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, nil_t>::type type;
|
||||
};
|
||||
|
||||
DerivedT& derived()
|
||||
{
|
||||
return *static_cast<DerivedT*>(this);
|
||||
}
|
||||
|
||||
DerivedT const& derived() const
|
||||
{
|
||||
return *static_cast<DerivedT const*>(this);
|
||||
}
|
||||
|
||||
template <typename ActionT>
|
||||
action<DerivedT, ActionT>
|
||||
operator[](ActionT const& actor) const
|
||||
{
|
||||
return action<DerivedT, ActionT>(derived(), actor);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// parse_info
|
||||
//
|
||||
// Results returned by the free parse functions:
|
||||
//
|
||||
// stop: points to the final parse position (i.e parsing
|
||||
// processed the input up to this point).
|
||||
//
|
||||
// hit: true if parsing is successful. This may be full:
|
||||
// the parser consumed all the input, or partial:
|
||||
// the parser consumed only a portion of the input.
|
||||
//
|
||||
// full: true when we have a full hit (i.e the parser
|
||||
// consumed all the input.
|
||||
//
|
||||
// length: The number of characters consumed by the parser.
|
||||
// This is valid only if we have a successful hit
|
||||
// (either partial or full).
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename IteratorT = char const*>
|
||||
struct parse_info
|
||||
{
|
||||
IteratorT stop;
|
||||
bool hit;
|
||||
bool full;
|
||||
std::size_t length;
|
||||
|
||||
parse_info(
|
||||
IteratorT const& stop_ = IteratorT(),
|
||||
bool hit_ = false,
|
||||
bool full_ = false,
|
||||
std::size_t length_ = 0)
|
||||
: stop(stop_)
|
||||
, hit(hit_)
|
||||
, full(full_)
|
||||
, length(length_) {}
|
||||
|
||||
template <typename ParseInfoT>
|
||||
parse_info(ParseInfoT const& pi)
|
||||
: stop(pi.stop)
|
||||
, hit(pi.hit)
|
||||
, full(pi.full)
|
||||
, length(pi.length) {}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generic parse function
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename IteratorT, typename DerivedT>
|
||||
parse_info<IteratorT>
|
||||
parse(
|
||||
IteratorT const& first,
|
||||
IteratorT const& last,
|
||||
parser<DerivedT> const& p);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Parse function for null terminated strings
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT, typename DerivedT>
|
||||
parse_info<CharT const*>
|
||||
parse(
|
||||
CharT const* str,
|
||||
parser<DerivedT> const& p);
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/classic/core/impl/parser.ipp>
|
||||
@@ -0,0 +1,478 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001-2003 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_NUMERICS_IPP
|
||||
#define BOOST_SPIRIT_NUMERICS_IPP
|
||||
|
||||
#include <boost/config/no_tr1/cmath.hpp>
|
||||
#include <limits>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
struct sign_parser; // forward declaration only
|
||||
|
||||
namespace impl
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Extract the prefix sign (- or +)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename ScannerT>
|
||||
bool
|
||||
extract_sign(ScannerT const& scan, std::size_t& count)
|
||||
{
|
||||
// Extract the sign
|
||||
count = 0;
|
||||
bool neg = *scan == '-';
|
||||
if (neg || (*scan == '+'))
|
||||
{
|
||||
++scan;
|
||||
++count;
|
||||
return neg;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Traits class for radix specific number conversion
|
||||
//
|
||||
// Convert a digit from character representation, ch, to binary
|
||||
// representation, returned in val.
|
||||
// Returns whether the conversion was successful.
|
||||
//
|
||||
// template<typename CharT> static bool digit(CharT ch, T& val);
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template<const int Radix>
|
||||
struct radix_traits;
|
||||
|
||||
////////////////////////////////// Binary
|
||||
template<>
|
||||
struct radix_traits<2>
|
||||
{
|
||||
template<typename CharT, typename T>
|
||||
static bool digit(CharT ch, T& val)
|
||||
{
|
||||
val = ch - '0';
|
||||
return ('0' == ch || '1' == ch);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////// Octal
|
||||
template<>
|
||||
struct radix_traits<8>
|
||||
{
|
||||
template<typename CharT, typename T>
|
||||
static bool digit(CharT ch, T& val)
|
||||
{
|
||||
val = ch - '0';
|
||||
return ('0' <= ch && ch <= '7');
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////// Decimal
|
||||
template<>
|
||||
struct radix_traits<10>
|
||||
{
|
||||
template<typename CharT, typename T>
|
||||
static bool digit(CharT ch, T& val)
|
||||
{
|
||||
val = ch - '0';
|
||||
return impl::isdigit_(ch);
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////// Hexadecimal
|
||||
template<>
|
||||
struct radix_traits<16>
|
||||
{
|
||||
template<typename CharT, typename T>
|
||||
static bool digit(CharT ch, T& val)
|
||||
{
|
||||
if (radix_traits<10>::digit(ch, val))
|
||||
return true;
|
||||
|
||||
CharT lc = impl::tolower_(ch);
|
||||
if ('a' <= lc && lc <= 'f')
|
||||
{
|
||||
val = lc - 'a' + 10;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Helper templates for encapsulation of radix specific
|
||||
// conversion of an input string to an integral value.
|
||||
//
|
||||
// main entry point:
|
||||
//
|
||||
// extract_int<Radix, MinDigits, MaxDigits, Accumulate>
|
||||
// ::f(first, last, n, count);
|
||||
//
|
||||
// The template parameter Radix represents the radix of the
|
||||
// number contained in the parsed string. The template
|
||||
// parameter MinDigits specifies the minimum digits to
|
||||
// accept. The template parameter MaxDigits specifies the
|
||||
// maximum digits to parse. A -1 value for MaxDigits will
|
||||
// make it parse an arbitrarilly large number as long as the
|
||||
// numeric type can hold it. Accumulate is either
|
||||
// positive_accumulate<Radix> (default) for parsing positive
|
||||
// numbers or negative_accumulate<Radix> otherwise.
|
||||
// Checking is only performed when std::numeric_limits<T>::
|
||||
// is_specialized is true. Otherwise, there's no way to
|
||||
// do the check.
|
||||
//
|
||||
// scan.first and scan.last are iterators as usual (i.e.
|
||||
// first is mutable and is moved forward when a match is
|
||||
// found), n is a variable that holds the number (passed by
|
||||
// reference). The number of parsed characters is added to
|
||||
// count (also passed by reference)
|
||||
//
|
||||
// NOTE:
|
||||
// Returns a non-match, if the number to parse
|
||||
// overflows (or underflows) the used type.
|
||||
//
|
||||
// BEWARE:
|
||||
// the parameters 'n' and 'count' should be properly
|
||||
// initialized before calling this function.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127) //conditional expression is constant
|
||||
#endif
|
||||
|
||||
template <typename T, int Radix>
|
||||
struct positive_accumulate
|
||||
{
|
||||
// Use this accumulator if number is positive
|
||||
static bool add(T& n, T digit)
|
||||
{
|
||||
if (std::numeric_limits<T>::is_specialized)
|
||||
{
|
||||
static T const max = (std::numeric_limits<T>::max)();
|
||||
static T const max_div_radix = max/Radix;
|
||||
|
||||
if (n > max_div_radix)
|
||||
return false;
|
||||
n *= Radix;
|
||||
|
||||
if (n > max - digit)
|
||||
return false;
|
||||
n += digit;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
n *= Radix;
|
||||
n += digit;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, int Radix>
|
||||
struct negative_accumulate
|
||||
{
|
||||
// Use this accumulator if number is negative
|
||||
static bool add(T& n, T digit)
|
||||
{
|
||||
if (std::numeric_limits<T>::is_specialized)
|
||||
{
|
||||
typedef std::numeric_limits<T> num_limits;
|
||||
static T const min =
|
||||
(!num_limits::is_integer && num_limits::is_signed && num_limits::has_denorm) ?
|
||||
-(num_limits::max)() : (num_limits::min)();
|
||||
static T const min_div_radix = min/Radix;
|
||||
|
||||
if (n < min_div_radix)
|
||||
return false;
|
||||
n *= Radix;
|
||||
|
||||
if (n < min + digit)
|
||||
return false;
|
||||
n -= digit;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
n *= Radix;
|
||||
n -= digit;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <int MaxDigits>
|
||||
inline bool allow_more_digits(std::size_t i)
|
||||
{
|
||||
return i < MaxDigits;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool allow_more_digits<-1>(std::size_t)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template <
|
||||
int Radix, unsigned MinDigits, int MaxDigits,
|
||||
typename Accumulate
|
||||
>
|
||||
struct extract_int
|
||||
{
|
||||
template <typename ScannerT, typename T>
|
||||
static bool
|
||||
f(ScannerT& scan, T& n, std::size_t& count)
|
||||
{
|
||||
std::size_t i = 0;
|
||||
T digit;
|
||||
while( allow_more_digits<MaxDigits>(i) && !scan.at_end() &&
|
||||
radix_traits<Radix>::digit(*scan, digit) )
|
||||
{
|
||||
if (!Accumulate::add(n, digit))
|
||||
return false; // Overflow
|
||||
++i, ++scan, ++count;
|
||||
}
|
||||
return i >= MinDigits;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uint_parser_impl class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename T = unsigned,
|
||||
int Radix = 10,
|
||||
unsigned MinDigits = 1,
|
||||
int MaxDigits = -1
|
||||
>
|
||||
struct uint_parser_impl
|
||||
: parser<uint_parser_impl<T, Radix, MinDigits, MaxDigits> >
|
||||
{
|
||||
typedef uint_parser_impl<T, Radix, MinDigits, MaxDigits> self_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, T>::type type;
|
||||
};
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
if (!scan.at_end())
|
||||
{
|
||||
T n = 0;
|
||||
std::size_t count = 0;
|
||||
typename ScannerT::iterator_t save = scan.first;
|
||||
if (extract_int<Radix, MinDigits, MaxDigits,
|
||||
positive_accumulate<T, Radix> >::f(scan, n, count))
|
||||
{
|
||||
return scan.create_match(count, n, save, scan.first);
|
||||
}
|
||||
// return no-match if number overflows
|
||||
}
|
||||
return scan.no_match();
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// int_parser_impl class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename T = unsigned,
|
||||
int Radix = 10,
|
||||
unsigned MinDigits = 1,
|
||||
int MaxDigits = -1
|
||||
>
|
||||
struct int_parser_impl
|
||||
: parser<int_parser_impl<T, Radix, MinDigits, MaxDigits> >
|
||||
{
|
||||
typedef int_parser_impl<T, Radix, MinDigits, MaxDigits> self_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, T>::type type;
|
||||
};
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef extract_int<Radix, MinDigits, MaxDigits,
|
||||
negative_accumulate<T, Radix> > extract_int_neg_t;
|
||||
typedef extract_int<Radix, MinDigits, MaxDigits,
|
||||
positive_accumulate<T, Radix> > extract_int_pos_t;
|
||||
|
||||
if (!scan.at_end())
|
||||
{
|
||||
T n = 0;
|
||||
std::size_t count = 0;
|
||||
typename ScannerT::iterator_t save = scan.first;
|
||||
|
||||
bool hit = impl::extract_sign(scan, count);
|
||||
|
||||
if (hit)
|
||||
hit = extract_int_neg_t::f(scan, n, count);
|
||||
else
|
||||
hit = extract_int_pos_t::f(scan, n, count);
|
||||
|
||||
if (hit)
|
||||
return scan.create_match(count, n, save, scan.first);
|
||||
else
|
||||
scan.first = save;
|
||||
// return no-match if number overflows or underflows
|
||||
}
|
||||
return scan.no_match();
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// real_parser_impl class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename RT, typename T, typename RealPoliciesT>
|
||||
struct real_parser_impl
|
||||
{
|
||||
typedef real_parser_impl<RT, T, RealPoliciesT> self_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
RT parse_main(ScannerT const& scan) const
|
||||
{
|
||||
if (scan.at_end())
|
||||
return scan.no_match();
|
||||
typename ScannerT::iterator_t save = scan.first;
|
||||
|
||||
typedef typename parser_result<sign_parser, ScannerT>::type
|
||||
sign_match_t;
|
||||
typedef typename parser_result<chlit<>, ScannerT>::type
|
||||
exp_match_t;
|
||||
|
||||
sign_match_t sign_match = RealPoliciesT::parse_sign(scan);
|
||||
std::size_t count = sign_match ? sign_match.length() : 0;
|
||||
bool neg = sign_match.has_valid_attribute() ?
|
||||
sign_match.value() : false;
|
||||
|
||||
RT n_match = RealPoliciesT::parse_n(scan);
|
||||
T n = n_match.has_valid_attribute() ?
|
||||
n_match.value() : T(0);
|
||||
bool got_a_number = n_match;
|
||||
exp_match_t e_hit;
|
||||
|
||||
if (!got_a_number && !RealPoliciesT::allow_leading_dot)
|
||||
return scan.no_match();
|
||||
else
|
||||
count += n_match.length();
|
||||
|
||||
if (neg)
|
||||
n = -n;
|
||||
|
||||
if (RealPoliciesT::parse_dot(scan))
|
||||
{
|
||||
// We got the decimal point. Now we will try to parse
|
||||
// the fraction if it is there. If not, it defaults
|
||||
// to zero (0) only if we already got a number.
|
||||
|
||||
if (RT hit = RealPoliciesT::parse_frac_n(scan))
|
||||
{
|
||||
#if !defined(BOOST_NO_STDC_NAMESPACE)
|
||||
using namespace std; // allow for ADL to find pow()
|
||||
#endif
|
||||
hit.value(hit.value()
|
||||
* pow(T(10), T(-hit.length())));
|
||||
if (neg)
|
||||
n -= hit.value();
|
||||
else
|
||||
n += hit.value();
|
||||
count += hit.length() + 1;
|
||||
|
||||
}
|
||||
|
||||
else if (!got_a_number ||
|
||||
!RealPoliciesT::allow_trailing_dot)
|
||||
return scan.no_match();
|
||||
|
||||
e_hit = RealPoliciesT::parse_exp(scan);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have reached a point where we
|
||||
// still haven't seen a number at all.
|
||||
// We return early with a no-match.
|
||||
if (!got_a_number)
|
||||
return scan.no_match();
|
||||
|
||||
// If we must expect a dot and we didn't see
|
||||
// an exponent, return early with a no-match.
|
||||
e_hit = RealPoliciesT::parse_exp(scan);
|
||||
if (RealPoliciesT::expect_dot && !e_hit)
|
||||
return scan.no_match();
|
||||
}
|
||||
|
||||
if (e_hit)
|
||||
{
|
||||
// We got the exponent prefix. Now we will try to parse the
|
||||
// actual exponent. It is an error if it is not there.
|
||||
if (RT e_n_hit = RealPoliciesT::parse_exp_n(scan))
|
||||
{
|
||||
#if !defined(BOOST_NO_STDC_NAMESPACE)
|
||||
using namespace std; // allow for ADL to find pow()
|
||||
#endif
|
||||
n *= pow(T(10), T(e_n_hit.value()));
|
||||
count += e_n_hit.length() + e_hit.length();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Oops, no exponent, return a no-match
|
||||
return scan.no_match();
|
||||
}
|
||||
}
|
||||
|
||||
return scan.create_match(count, n, save, scan.first);
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
static RT parse(ScannerT const& scan)
|
||||
{
|
||||
static self_t this_;
|
||||
return impl::implicit_lexeme_parse<RT>(this_, scan, scan);
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace impl
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,476 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2003 Martin Wille
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_PRIMITIVES_IPP)
|
||||
#define BOOST_SPIRIT_PRIMITIVES_IPP
|
||||
|
||||
// This should eventually go to a config file.
|
||||
#if defined(__GNUC__) && (__GNUC__ < 3) && !defined(_STLPORT_VERSION)
|
||||
# ifndef BOOST_SPIRIT_NO_CHAR_TRAITS
|
||||
# define BOOST_SPIRIT_NO_CHAR_TRAITS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <cctype>
|
||||
#if !defined(BOOST_NO_CWCTYPE)
|
||||
#include <cwctype>
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_SPIRIT_NO_CHAR_TRAITS
|
||||
# include <string> // char_traits
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning (push)
|
||||
# pragma warning(disable:4800)
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
template <typename DrivedT> struct char_parser;
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template <typename IteratorT>
|
||||
inline IteratorT
|
||||
get_last(IteratorT first)
|
||||
{
|
||||
while (*first)
|
||||
first++;
|
||||
return first;
|
||||
}
|
||||
|
||||
template<
|
||||
typename RT,
|
||||
typename IteratorT,
|
||||
typename ScannerT>
|
||||
inline RT
|
||||
string_parser_parse(
|
||||
IteratorT str_first,
|
||||
IteratorT str_last,
|
||||
ScannerT& scan)
|
||||
{
|
||||
typedef typename ScannerT::iterator_t iterator_t;
|
||||
iterator_t saved = scan.first;
|
||||
std::size_t slen = str_last - str_first;
|
||||
|
||||
while (str_first != str_last)
|
||||
{
|
||||
if (scan.at_end() || (*str_first != *scan))
|
||||
return scan.no_match();
|
||||
++str_first;
|
||||
++scan;
|
||||
}
|
||||
|
||||
return scan.create_match(slen, nil_t(), saved, scan.first);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Conversion from char_type to int_type
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_SPIRIT_NO_CHAR_TRAITS
|
||||
# define BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE std
|
||||
#else
|
||||
|
||||
template <typename CharT>
|
||||
struct char_traits
|
||||
{
|
||||
typedef CharT int_type;
|
||||
typedef CharT char_type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct char_traits<char>
|
||||
{
|
||||
typedef int int_type;
|
||||
typedef char char_type;
|
||||
|
||||
static char_type
|
||||
to_char_type(int_type c)
|
||||
{
|
||||
return static_cast<char_type>(c);
|
||||
}
|
||||
|
||||
static int
|
||||
to_int_type(char c)
|
||||
{
|
||||
return static_cast<unsigned char>(c);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct char_traits<unsigned char>
|
||||
{
|
||||
typedef int int_type;
|
||||
typedef unsigned char char_type;
|
||||
|
||||
static char_type
|
||||
to_char_type(int_type c)
|
||||
{
|
||||
return static_cast<char_type>(c);
|
||||
}
|
||||
|
||||
static int
|
||||
to_int_type(unsigned char c)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
# define BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE impl
|
||||
# ifndef BOOST_NO_CWCTYPE
|
||||
|
||||
template<>
|
||||
struct char_traits<wchar_t>
|
||||
{
|
||||
typedef wint_t int_type;
|
||||
typedef wchar_t char_type;
|
||||
|
||||
static char_type
|
||||
to_char_type(int_type c)
|
||||
{
|
||||
return static_cast<char_type>(c);
|
||||
}
|
||||
|
||||
static wint_t
|
||||
to_int_type(wchar_t c)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
# endif
|
||||
#endif // BOOST_SPIRIT_NO_CHAR_TRAITS
|
||||
|
||||
// Use char_traits for char and wchar_t only, as these are the only
|
||||
// specializations provided in the standard. Other types are on their
|
||||
// own.
|
||||
//
|
||||
// For UDT, one may override:
|
||||
//
|
||||
// isalnum
|
||||
// isalpha
|
||||
// iscntrl
|
||||
// isdigit
|
||||
// isgraph
|
||||
// islower
|
||||
// isprint
|
||||
// ispunct
|
||||
// isspace
|
||||
// isupper
|
||||
// isxdigit
|
||||
// isblank
|
||||
// isupper
|
||||
// tolower
|
||||
// toupper
|
||||
//
|
||||
// in a namespace suitable for Argument Dependent lookup or in
|
||||
// namespace std (disallowed by the standard).
|
||||
|
||||
template <typename CharT>
|
||||
struct char_type_char_traits_helper
|
||||
{
|
||||
typedef CharT char_type;
|
||||
typedef typename BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE
|
||||
::char_traits<CharT>::int_type int_type;
|
||||
|
||||
static int_type to_int_type(CharT c)
|
||||
{
|
||||
return BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE
|
||||
::char_traits<CharT>::to_int_type(c);
|
||||
}
|
||||
|
||||
static char_type to_char_type(int_type i)
|
||||
{
|
||||
return BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE
|
||||
::char_traits<CharT>::to_char_type(i);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
struct char_traits_helper
|
||||
{
|
||||
typedef CharT char_type;
|
||||
typedef CharT int_type;
|
||||
|
||||
static CharT & to_int_type(CharT & c)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
|
||||
static CharT & to_char_type(CharT & c)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct char_traits_helper<char>
|
||||
: char_type_char_traits_helper<char>
|
||||
{
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CWCTYPE)
|
||||
|
||||
template <>
|
||||
struct char_traits_helper<wchar_t>
|
||||
: char_type_char_traits_helper<wchar_t>
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <typename CharT>
|
||||
inline typename char_traits_helper<CharT>::int_type
|
||||
to_int_type(CharT c)
|
||||
{
|
||||
return char_traits_helper<CharT>::to_int_type(c);
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline CharT
|
||||
to_char_type(typename char_traits_helper<CharT>::int_type c)
|
||||
{
|
||||
return char_traits_helper<CharT>::to_char_type(c);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Convenience functions
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
isalnum_(CharT c)
|
||||
{
|
||||
using namespace std;
|
||||
return isalnum(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
isalpha_(CharT c)
|
||||
{
|
||||
using namespace std;
|
||||
return isalpha(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
iscntrl_(CharT c)
|
||||
{
|
||||
using namespace std;
|
||||
return iscntrl(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
isdigit_(CharT c)
|
||||
{
|
||||
using namespace std;
|
||||
return isdigit(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
isgraph_(CharT c)
|
||||
{
|
||||
using namespace std;
|
||||
return isgraph(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
islower_(CharT c)
|
||||
{
|
||||
using namespace std;
|
||||
return islower(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
isprint_(CharT c)
|
||||
{
|
||||
using namespace std;
|
||||
return isprint(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
ispunct_(CharT c)
|
||||
{
|
||||
using namespace std;
|
||||
return ispunct(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
isspace_(CharT c)
|
||||
{
|
||||
using namespace std;
|
||||
return isspace(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
isupper_(CharT c)
|
||||
{
|
||||
using namespace std;
|
||||
return isupper(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
isxdigit_(CharT c)
|
||||
{
|
||||
using namespace std;
|
||||
return isxdigit(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline bool
|
||||
isblank_(CharT c)
|
||||
{
|
||||
return (c == ' ' || c == '\t');
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline CharT
|
||||
tolower_(CharT c)
|
||||
{
|
||||
using namespace std;
|
||||
return to_char_type<CharT>(tolower(to_int_type(c)));
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline CharT
|
||||
toupper_(CharT c)
|
||||
{
|
||||
using namespace std;
|
||||
return to_char_type<CharT>(toupper(to_int_type(c)));
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CWCTYPE)
|
||||
|
||||
inline bool
|
||||
isalnum_(wchar_t c)
|
||||
{
|
||||
using namespace std;
|
||||
return iswalnum(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isalpha_(wchar_t c)
|
||||
{
|
||||
using namespace std;
|
||||
return iswalpha(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
iscntrl_(wchar_t c)
|
||||
{
|
||||
using namespace std;
|
||||
return iswcntrl(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isdigit_(wchar_t c)
|
||||
{
|
||||
using namespace std;
|
||||
return iswdigit(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isgraph_(wchar_t c)
|
||||
{
|
||||
using namespace std;
|
||||
return iswgraph(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
islower_(wchar_t c)
|
||||
{
|
||||
using namespace std;
|
||||
return iswlower(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isprint_(wchar_t c)
|
||||
{
|
||||
using namespace std;
|
||||
return iswprint(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ispunct_(wchar_t c)
|
||||
{
|
||||
using namespace std;
|
||||
return iswpunct(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isspace_(wchar_t c)
|
||||
{
|
||||
using namespace std;
|
||||
return iswspace(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isupper_(wchar_t c)
|
||||
{
|
||||
using namespace std;
|
||||
return iswupper(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isxdigit_(wchar_t c)
|
||||
{
|
||||
using namespace std;
|
||||
return iswxdigit(to_int_type(c)) ? true : false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isblank_(wchar_t c)
|
||||
{
|
||||
return (c == L' ' || c == L'\t');
|
||||
}
|
||||
|
||||
inline wchar_t
|
||||
tolower_(wchar_t c)
|
||||
{
|
||||
using namespace std;
|
||||
return to_char_type<wchar_t>(towlower(to_int_type(c)));
|
||||
}
|
||||
|
||||
inline wchar_t
|
||||
toupper_(wchar_t c)
|
||||
{
|
||||
using namespace std;
|
||||
return to_char_type<wchar_t>(towupper(to_int_type(c)));
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_NO_CWCTYPE)
|
||||
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit::impl
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,289 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2001-2003 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_NUMERICS_HPP
|
||||
#define BOOST_SPIRIT_NUMERICS_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/directives.hpp>
|
||||
|
||||
#include <boost/spirit/home/classic/core/primitives/numerics_fwd.hpp>
|
||||
#include <boost/spirit/home/classic/core/primitives/impl/numerics.ipp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uint_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename T,
|
||||
int Radix,
|
||||
unsigned MinDigits,
|
||||
int MaxDigits
|
||||
>
|
||||
struct uint_parser : parser<uint_parser<T, Radix, MinDigits, MaxDigits> >
|
||||
{
|
||||
typedef uint_parser<T, Radix, MinDigits, MaxDigits> self_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, T>::type type;
|
||||
};
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef impl::uint_parser_impl<T, Radix, MinDigits, MaxDigits> impl_t;
|
||||
typedef typename parser_result<impl_t, ScannerT>::type result_t;
|
||||
return impl::contiguous_parser_parse<result_t>(impl_t(), scan, scan);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// int_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename T,
|
||||
int Radix,
|
||||
unsigned MinDigits,
|
||||
int MaxDigits
|
||||
>
|
||||
struct int_parser : parser<int_parser<T, Radix, MinDigits, MaxDigits> >
|
||||
{
|
||||
typedef int_parser<T, Radix, MinDigits, MaxDigits> self_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, T>::type type;
|
||||
};
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef impl::int_parser_impl<T, Radix, MinDigits, MaxDigits> impl_t;
|
||||
typedef typename parser_result<impl_t, ScannerT>::type result_t;
|
||||
return impl::contiguous_parser_parse<result_t>(impl_t(), scan, scan);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uint_parser/int_parser instantiations
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
int_parser<int> const
|
||||
int_p = int_parser<int>();
|
||||
|
||||
uint_parser<unsigned> const
|
||||
uint_p = uint_parser<unsigned>();
|
||||
|
||||
uint_parser<unsigned, 2> const
|
||||
bin_p = uint_parser<unsigned, 2>();
|
||||
|
||||
uint_parser<unsigned, 8> const
|
||||
oct_p = uint_parser<unsigned, 8>();
|
||||
|
||||
uint_parser<unsigned, 16> const
|
||||
hex_p = uint_parser<unsigned, 16>();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// sign_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace impl
|
||||
{
|
||||
// Utility to extract the prefix sign ('-' | '+')
|
||||
template <typename ScannerT>
|
||||
bool extract_sign(ScannerT const& scan, std::size_t& count);
|
||||
}
|
||||
|
||||
struct sign_parser : public parser<sign_parser>
|
||||
{
|
||||
typedef sign_parser self_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, bool>::type type;
|
||||
};
|
||||
|
||||
sign_parser() {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
if (!scan.at_end())
|
||||
{
|
||||
std::size_t length;
|
||||
typename ScannerT::iterator_t save(scan.first);
|
||||
bool neg = impl::extract_sign(scan, length);
|
||||
if (length)
|
||||
return scan.create_match(1, neg, save, scan.first);
|
||||
}
|
||||
return scan.no_match();
|
||||
}
|
||||
};
|
||||
|
||||
sign_parser const sign_p = sign_parser();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// default real number policies
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct ureal_parser_policies
|
||||
{
|
||||
// trailing dot policy suggested suggested by Gustavo Guerra
|
||||
BOOST_STATIC_CONSTANT(bool, allow_leading_dot = true);
|
||||
BOOST_STATIC_CONSTANT(bool, allow_trailing_dot = true);
|
||||
BOOST_STATIC_CONSTANT(bool, expect_dot = false);
|
||||
|
||||
typedef uint_parser<T, 10, 1, -1> uint_parser_t;
|
||||
typedef int_parser<T, 10, 1, -1> int_parser_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
static typename match_result<ScannerT, nil_t>::type
|
||||
parse_sign(ScannerT& scan)
|
||||
{
|
||||
return scan.no_match();
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
static typename parser_result<uint_parser_t, ScannerT>::type
|
||||
parse_n(ScannerT& scan)
|
||||
{
|
||||
return uint_parser_t().parse(scan);
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
static typename parser_result<chlit<>, ScannerT>::type
|
||||
parse_dot(ScannerT& scan)
|
||||
{
|
||||
return ch_p('.').parse(scan);
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
static typename parser_result<uint_parser_t, ScannerT>::type
|
||||
parse_frac_n(ScannerT& scan)
|
||||
{
|
||||
return uint_parser_t().parse(scan);
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
static typename parser_result<chlit<>, ScannerT>::type
|
||||
parse_exp(ScannerT& scan)
|
||||
{
|
||||
return as_lower_d['e'].parse(scan);
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
static typename parser_result<int_parser_t, ScannerT>::type
|
||||
parse_exp_n(ScannerT& scan)
|
||||
{
|
||||
return int_parser_t().parse(scan);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct real_parser_policies : public ureal_parser_policies<T>
|
||||
{
|
||||
template <typename ScannerT>
|
||||
static typename parser_result<sign_parser, ScannerT>::type
|
||||
parse_sign(ScannerT& scan)
|
||||
{
|
||||
return sign_p.parse(scan);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// real_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename T,
|
||||
typename RealPoliciesT
|
||||
>
|
||||
struct real_parser
|
||||
: public parser<real_parser<T, RealPoliciesT> >
|
||||
{
|
||||
typedef real_parser<T, RealPoliciesT> self_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, T>::type type;
|
||||
};
|
||||
|
||||
real_parser() {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
return impl::real_parser_impl<result_t, T, RealPoliciesT>::parse(scan);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// real_parser instantiations
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
real_parser<double, ureal_parser_policies<double> > const
|
||||
ureal_p = real_parser<double, ureal_parser_policies<double> >();
|
||||
|
||||
real_parser<double, real_parser_policies<double> > const
|
||||
real_p = real_parser<double, real_parser_policies<double> >();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// strict reals (do not allow plain integers (no decimal point))
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct strict_ureal_parser_policies : public ureal_parser_policies<T>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, expect_dot = true);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct strict_real_parser_policies : public real_parser_policies<T>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, expect_dot = true);
|
||||
};
|
||||
|
||||
real_parser<double, strict_ureal_parser_policies<double> > const
|
||||
strict_ureal_p
|
||||
= real_parser<double, strict_ureal_parser_policies<double> >();
|
||||
|
||||
real_parser<double, strict_real_parser_policies<double> > const
|
||||
strict_real_p
|
||||
= real_parser<double, strict_real_parser_policies<double> >();
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,88 @@
|
||||
/*=============================================================================
|
||||
Copyright (C) 2006 Tobias Schwinger
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_NUMERICS_FWD_HPP)
|
||||
# define BOOST_SPIRIT_NUMERICS_FWD_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uint_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename T = unsigned,
|
||||
int Radix = 10,
|
||||
unsigned MinDigits = 1,
|
||||
int MaxDigits = -1
|
||||
>
|
||||
struct uint_parser;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// int_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename T = unsigned,
|
||||
int Radix = 10,
|
||||
unsigned MinDigits = 1,
|
||||
int MaxDigits = -1
|
||||
>
|
||||
struct int_parser;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// sign_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct sign_parser;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// default real number policies
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct ureal_parser_policies;
|
||||
|
||||
template <typename T>
|
||||
struct real_parser_policies;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// real_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename T = double,
|
||||
typename RealPoliciesT = ureal_parser_policies<T>
|
||||
>
|
||||
struct real_parser;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// strict reals (do not allow plain integers (no decimal point))
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct strict_ureal_parser_policies;
|
||||
|
||||
template <typename T>
|
||||
struct strict_real_parser_policies;
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,654 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
Copyright (c) 2003 Martin Wille
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_PRIMITIVES_HPP)
|
||||
#define BOOST_SPIRIT_PRIMITIVES_HPP
|
||||
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/assert.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/impl/directives.ipp>
|
||||
#include <boost/spirit/home/classic/core/primitives/impl/primitives.ipp>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning (push)
|
||||
#pragma warning(disable : 4512)
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// char_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename DerivedT>
|
||||
struct char_parser : public parser<DerivedT>
|
||||
{
|
||||
typedef DerivedT self_t;
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<
|
||||
ScannerT,
|
||||
typename ScannerT::value_t
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
typedef typename ScannerT::value_t value_t;
|
||||
typedef typename ScannerT::iterator_t iterator_t;
|
||||
|
||||
if (!scan.at_end())
|
||||
{
|
||||
value_t ch = *scan;
|
||||
if (this->derived().test(ch))
|
||||
{
|
||||
iterator_t save(scan.first);
|
||||
++scan.first;
|
||||
return scan.create_match(1, ch, save, scan.first);
|
||||
}
|
||||
}
|
||||
return scan.no_match();
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// negation of char_parsers
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename PositiveT>
|
||||
struct negated_char_parser
|
||||
: public char_parser<negated_char_parser<PositiveT> >
|
||||
{
|
||||
typedef negated_char_parser<PositiveT> self_t;
|
||||
typedef PositiveT positive_t;
|
||||
|
||||
negated_char_parser(positive_t const& p)
|
||||
: positive(p.derived()) {}
|
||||
|
||||
template <typename T>
|
||||
bool test(T ch) const
|
||||
{
|
||||
return !positive.test(ch);
|
||||
}
|
||||
|
||||
positive_t const positive;
|
||||
};
|
||||
|
||||
template <typename ParserT>
|
||||
inline negated_char_parser<ParserT>
|
||||
operator~(char_parser<ParserT> const& p)
|
||||
{
|
||||
return negated_char_parser<ParserT>(p.derived());
|
||||
}
|
||||
|
||||
template <typename ParserT>
|
||||
inline ParserT
|
||||
operator~(negated_char_parser<ParserT> const& n)
|
||||
{
|
||||
return n.positive;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// chlit class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT = char>
|
||||
struct chlit : public char_parser<chlit<CharT> >
|
||||
{
|
||||
chlit(CharT ch_)
|
||||
: ch(ch_) {}
|
||||
|
||||
template <typename T>
|
||||
bool test(T ch_) const
|
||||
{
|
||||
return ch_ == ch;
|
||||
}
|
||||
|
||||
CharT ch;
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
inline chlit<CharT>
|
||||
ch_p(CharT ch)
|
||||
{
|
||||
return chlit<CharT>(ch);
|
||||
}
|
||||
|
||||
// This should take care of ch_p("a") "bugs"
|
||||
template <typename CharT, std::size_t N>
|
||||
inline chlit<CharT>
|
||||
ch_p(CharT const (& str)[N])
|
||||
{
|
||||
// ch_p's argument should be a single character or a null-terminated
|
||||
// string with a single character
|
||||
BOOST_STATIC_ASSERT(N < 3);
|
||||
return chlit<CharT>(str[0]);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// range class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT = char>
|
||||
struct range : public char_parser<range<CharT> >
|
||||
{
|
||||
range(CharT first_, CharT last_)
|
||||
: first(first_), last(last_)
|
||||
{
|
||||
BOOST_SPIRIT_ASSERT(!(last < first));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool test(T ch) const
|
||||
{
|
||||
return !(CharT(ch) < first) && !(last < CharT(ch));
|
||||
}
|
||||
|
||||
CharT first;
|
||||
CharT last;
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
inline range<CharT>
|
||||
range_p(CharT first, CharT last)
|
||||
{
|
||||
return range<CharT>(first, last);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// chseq class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename IteratorT = char const*>
|
||||
class chseq : public parser<chseq<IteratorT> >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef chseq<IteratorT> self_t;
|
||||
|
||||
chseq(IteratorT first_, IteratorT last_)
|
||||
: first(first_), last(last_) {}
|
||||
|
||||
chseq(IteratorT first_)
|
||||
: first(first_), last(impl::get_last(first_)) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename boost::unwrap_reference<IteratorT>::type striter_t;
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
return impl::string_parser_parse<result_t>(
|
||||
striter_t(first),
|
||||
striter_t(last),
|
||||
scan);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
IteratorT first;
|
||||
IteratorT last;
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
inline chseq<CharT const*>
|
||||
chseq_p(CharT const* str)
|
||||
{
|
||||
return chseq<CharT const*>(str);
|
||||
}
|
||||
|
||||
template <typename IteratorT>
|
||||
inline chseq<IteratorT>
|
||||
chseq_p(IteratorT first, IteratorT last)
|
||||
{
|
||||
return chseq<IteratorT>(first, last);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// strlit class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename IteratorT = char const*>
|
||||
class strlit : public parser<strlit<IteratorT> >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef strlit<IteratorT> self_t;
|
||||
|
||||
strlit(IteratorT first, IteratorT last)
|
||||
: seq(first, last) {}
|
||||
|
||||
strlit(IteratorT first)
|
||||
: seq(first) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
return impl::contiguous_parser_parse<result_t>
|
||||
(seq, scan, scan);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
chseq<IteratorT> seq;
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
inline strlit<CharT const*>
|
||||
str_p(CharT const* str)
|
||||
{
|
||||
return strlit<CharT const*>(str);
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline strlit<CharT *>
|
||||
str_p(CharT * str)
|
||||
{
|
||||
return strlit<CharT *>(str);
|
||||
}
|
||||
|
||||
template <typename IteratorT>
|
||||
inline strlit<IteratorT>
|
||||
str_p(IteratorT first, IteratorT last)
|
||||
{
|
||||
return strlit<IteratorT>(first, last);
|
||||
}
|
||||
|
||||
// This should take care of str_p('a') "bugs"
|
||||
template <typename CharT>
|
||||
inline chlit<CharT>
|
||||
str_p(CharT ch)
|
||||
{
|
||||
return chlit<CharT>(ch);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// nothing_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct nothing_parser : public parser<nothing_parser>
|
||||
{
|
||||
typedef nothing_parser self_t;
|
||||
|
||||
nothing_parser() {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
return scan.no_match();
|
||||
}
|
||||
};
|
||||
|
||||
nothing_parser const nothing_p = nothing_parser();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// anychar_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct anychar_parser : public char_parser<anychar_parser>
|
||||
{
|
||||
typedef anychar_parser self_t;
|
||||
|
||||
anychar_parser() {}
|
||||
|
||||
template <typename CharT>
|
||||
bool test(CharT) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
anychar_parser const anychar_p = anychar_parser();
|
||||
|
||||
inline nothing_parser
|
||||
operator~(anychar_parser)
|
||||
{
|
||||
return nothing_p;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// alnum_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct alnum_parser : public char_parser<alnum_parser>
|
||||
{
|
||||
typedef alnum_parser self_t;
|
||||
|
||||
alnum_parser() {}
|
||||
|
||||
template <typename CharT>
|
||||
bool test(CharT ch) const
|
||||
{
|
||||
return impl::isalnum_(ch);
|
||||
}
|
||||
};
|
||||
|
||||
alnum_parser const alnum_p = alnum_parser();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// alpha_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct alpha_parser : public char_parser<alpha_parser>
|
||||
{
|
||||
typedef alpha_parser self_t;
|
||||
|
||||
alpha_parser() {}
|
||||
|
||||
template <typename CharT>
|
||||
bool test(CharT ch) const
|
||||
{
|
||||
return impl::isalpha_(ch);
|
||||
}
|
||||
};
|
||||
|
||||
alpha_parser const alpha_p = alpha_parser();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// cntrl_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct cntrl_parser : public char_parser<cntrl_parser>
|
||||
{
|
||||
typedef cntrl_parser self_t;
|
||||
|
||||
cntrl_parser() {}
|
||||
|
||||
template <typename CharT>
|
||||
bool test(CharT ch) const
|
||||
{
|
||||
return impl::iscntrl_(ch);
|
||||
}
|
||||
};
|
||||
|
||||
cntrl_parser const cntrl_p = cntrl_parser();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// digit_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct digit_parser : public char_parser<digit_parser>
|
||||
{
|
||||
typedef digit_parser self_t;
|
||||
|
||||
digit_parser() {}
|
||||
|
||||
template <typename CharT>
|
||||
bool test(CharT ch) const
|
||||
{
|
||||
return impl::isdigit_(ch);
|
||||
}
|
||||
};
|
||||
|
||||
digit_parser const digit_p = digit_parser();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// graph_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct graph_parser : public char_parser<graph_parser>
|
||||
{
|
||||
typedef graph_parser self_t;
|
||||
|
||||
graph_parser() {}
|
||||
|
||||
template <typename CharT>
|
||||
bool test(CharT ch) const
|
||||
{
|
||||
return impl::isgraph_(ch);
|
||||
}
|
||||
};
|
||||
|
||||
graph_parser const graph_p = graph_parser();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// lower_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct lower_parser : public char_parser<lower_parser>
|
||||
{
|
||||
typedef lower_parser self_t;
|
||||
|
||||
lower_parser() {}
|
||||
|
||||
template <typename CharT>
|
||||
bool test(CharT ch) const
|
||||
{
|
||||
return impl::islower_(ch);
|
||||
}
|
||||
};
|
||||
|
||||
lower_parser const lower_p = lower_parser();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// print_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct print_parser : public char_parser<print_parser>
|
||||
{
|
||||
typedef print_parser self_t;
|
||||
|
||||
print_parser() {}
|
||||
|
||||
template <typename CharT>
|
||||
bool test(CharT ch) const
|
||||
{
|
||||
return impl::isprint_(ch);
|
||||
}
|
||||
};
|
||||
|
||||
print_parser const print_p = print_parser();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// punct_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct punct_parser : public char_parser<punct_parser>
|
||||
{
|
||||
typedef punct_parser self_t;
|
||||
|
||||
punct_parser() {}
|
||||
|
||||
template <typename CharT>
|
||||
bool test(CharT ch) const
|
||||
{
|
||||
return impl::ispunct_(ch);
|
||||
}
|
||||
};
|
||||
|
||||
punct_parser const punct_p = punct_parser();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// blank_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct blank_parser : public char_parser<blank_parser>
|
||||
{
|
||||
typedef blank_parser self_t;
|
||||
|
||||
blank_parser() {}
|
||||
|
||||
template <typename CharT>
|
||||
bool test(CharT ch) const
|
||||
{
|
||||
return impl::isblank_(ch);
|
||||
}
|
||||
};
|
||||
|
||||
blank_parser const blank_p = blank_parser();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// space_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct space_parser : public char_parser<space_parser>
|
||||
{
|
||||
typedef space_parser self_t;
|
||||
|
||||
space_parser() {}
|
||||
|
||||
template <typename CharT>
|
||||
bool test(CharT ch) const
|
||||
{
|
||||
return impl::isspace_(ch);
|
||||
}
|
||||
};
|
||||
|
||||
space_parser const space_p = space_parser();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// upper_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct upper_parser : public char_parser<upper_parser>
|
||||
{
|
||||
typedef upper_parser self_t;
|
||||
|
||||
upper_parser() {}
|
||||
|
||||
template <typename CharT>
|
||||
bool test(CharT ch) const
|
||||
{
|
||||
return impl::isupper_(ch);
|
||||
}
|
||||
};
|
||||
|
||||
upper_parser const upper_p = upper_parser();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// xdigit_parser class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct xdigit_parser : public char_parser<xdigit_parser>
|
||||
{
|
||||
typedef xdigit_parser self_t;
|
||||
|
||||
xdigit_parser() {}
|
||||
|
||||
template <typename CharT>
|
||||
bool test(CharT ch) const
|
||||
{
|
||||
return impl::isxdigit_(ch);
|
||||
}
|
||||
};
|
||||
|
||||
xdigit_parser const xdigit_p = xdigit_parser();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// eol_parser class (contributed by Martin Wille)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct eol_parser : public parser<eol_parser>
|
||||
{
|
||||
typedef eol_parser self_t;
|
||||
|
||||
eol_parser() {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typename ScannerT::iterator_t save = scan.first;
|
||||
std::size_t len = 0;
|
||||
|
||||
if (!scan.at_end() && *scan == '\r') // CR
|
||||
{
|
||||
++scan.first;
|
||||
++len;
|
||||
}
|
||||
|
||||
// Don't call skipper here
|
||||
if (scan.first != scan.last && *scan == '\n') // LF
|
||||
{
|
||||
++scan.first;
|
||||
++len;
|
||||
}
|
||||
|
||||
if (len)
|
||||
return scan.create_match(len, nil_t(), save, scan.first);
|
||||
return scan.no_match();
|
||||
}
|
||||
};
|
||||
|
||||
eol_parser const eol_p = eol_parser();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// end_parser class (suggested by Markus Schoepflin)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct end_parser : public parser<end_parser>
|
||||
{
|
||||
typedef end_parser self_t;
|
||||
|
||||
end_parser() {}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
if (scan.at_end())
|
||||
return scan.empty_match();
|
||||
return scan.no_match();
|
||||
}
|
||||
};
|
||||
|
||||
end_parser const end_p = end_parser();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// the pizza_p parser :-)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
inline strlit<char const*> const
|
||||
pizza_p(char const* your_favorite_pizza)
|
||||
{
|
||||
return your_favorite_pizza;
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,64 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_SAFE_BOOL_HPP)
|
||||
#define BOOST_SPIRIT_SAFE_BOOL_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template <typename T>
|
||||
struct no_base {};
|
||||
|
||||
template <typename T>
|
||||
struct safe_bool_impl
|
||||
{
|
||||
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
|
||||
void stub(T*) {};
|
||||
typedef void (safe_bool_impl::*type)(T*);
|
||||
#else
|
||||
typedef T* TP; // workaround to make parsing easier
|
||||
TP stub;
|
||||
typedef TP safe_bool_impl::*type;
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
template <typename DerivedT, typename BaseT = impl::no_base<DerivedT> >
|
||||
struct safe_bool : BaseT
|
||||
{
|
||||
private:
|
||||
typedef impl::safe_bool_impl<DerivedT> impl_t;
|
||||
typedef typename impl_t::type bool_type;
|
||||
|
||||
public:
|
||||
operator bool_type() const
|
||||
{
|
||||
return static_cast<const DerivedT*>(this)->operator_bool() ?
|
||||
&impl_t::stub : 0;
|
||||
}
|
||||
|
||||
operator bool_type()
|
||||
{
|
||||
return static_cast<DerivedT*>(this)->operator_bool() ?
|
||||
&impl_t::stub : 0;
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_SKIPPER_IPP)
|
||||
#define BOOST_SPIRIT_SKIPPER_IPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
struct space_parser;
|
||||
template <typename BaseT>
|
||||
struct no_skipper_iteration_policy;
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template <typename ST, typename ScannerT, typename BaseT>
|
||||
inline void
|
||||
skipper_skip(
|
||||
ST const& s,
|
||||
ScannerT const& scan,
|
||||
skipper_iteration_policy<BaseT> const&)
|
||||
{
|
||||
typedef scanner_policies<
|
||||
no_skipper_iteration_policy<
|
||||
BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>,
|
||||
BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t,
|
||||
BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t
|
||||
> policies_t;
|
||||
|
||||
scanner<BOOST_DEDUCED_TYPENAME ScannerT::iterator_t, policies_t>
|
||||
scan2(scan.first, scan.last, policies_t(scan));
|
||||
typedef typename ScannerT::iterator_t iterator_t;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
iterator_t save = scan.first;
|
||||
if (!s.parse(scan2))
|
||||
{
|
||||
scan.first = save;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ST, typename ScannerT, typename BaseT>
|
||||
inline void
|
||||
skipper_skip(
|
||||
ST const& s,
|
||||
ScannerT const& scan,
|
||||
no_skipper_iteration_policy<BaseT> const&)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
typedef typename ScannerT::iterator_t iterator_t;
|
||||
iterator_t save = scan.first;
|
||||
if (!s.parse(scan))
|
||||
{
|
||||
scan.first = save;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ST, typename ScannerT>
|
||||
inline void
|
||||
skipper_skip(
|
||||
ST const& s,
|
||||
ScannerT const& scan,
|
||||
iteration_policy const&)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
typedef typename ScannerT::iterator_t iterator_t;
|
||||
iterator_t save = scan.first;
|
||||
if (!s.parse(scan))
|
||||
{
|
||||
scan.first = save;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename SkipT>
|
||||
struct phrase_parser
|
||||
{
|
||||
template <typename IteratorT, typename ParserT>
|
||||
static parse_info<IteratorT>
|
||||
parse(
|
||||
IteratorT const& first_,
|
||||
IteratorT const& last,
|
||||
ParserT const& p,
|
||||
SkipT const& skip)
|
||||
{
|
||||
typedef skip_parser_iteration_policy<SkipT> iter_policy_t;
|
||||
typedef scanner_policies<iter_policy_t> scanner_policies_t;
|
||||
typedef scanner<IteratorT, scanner_policies_t> scanner_t;
|
||||
|
||||
iter_policy_t iter_policy(skip);
|
||||
scanner_policies_t policies(iter_policy);
|
||||
IteratorT first = first_;
|
||||
scanner_t scan(first, last, policies);
|
||||
match<nil_t> hit = p.parse(scan);
|
||||
return parse_info<IteratorT>(
|
||||
first, hit, hit && (first == last),
|
||||
hit.length());
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct phrase_parser<space_parser>
|
||||
{
|
||||
template <typename IteratorT, typename ParserT>
|
||||
static parse_info<IteratorT>
|
||||
parse(
|
||||
IteratorT const& first_,
|
||||
IteratorT const& last,
|
||||
ParserT const& p,
|
||||
space_parser const&)
|
||||
{
|
||||
typedef skipper_iteration_policy<> iter_policy_t;
|
||||
typedef scanner_policies<iter_policy_t> scanner_policies_t;
|
||||
typedef scanner<IteratorT, scanner_policies_t> scanner_t;
|
||||
|
||||
IteratorT first = first_;
|
||||
scanner_t scan(first, last);
|
||||
match<nil_t> hit = p.parse(scan);
|
||||
return parse_info<IteratorT>(
|
||||
first, hit, hit && (first == last),
|
||||
hit.length());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Free parse functions using the skippers
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename IteratorT, typename ParserT, typename SkipT>
|
||||
inline parse_info<IteratorT>
|
||||
parse(
|
||||
IteratorT const& first,
|
||||
IteratorT const& last,
|
||||
parser<ParserT> const& p,
|
||||
parser<SkipT> const& skip)
|
||||
{
|
||||
return impl::phrase_parser<SkipT>::
|
||||
parse(first, last, p.derived(), skip.derived());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Parse function for null terminated strings using the skippers
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT, typename ParserT, typename SkipT>
|
||||
inline parse_info<CharT const*>
|
||||
parse(
|
||||
CharT const* str,
|
||||
parser<ParserT> const& p,
|
||||
parser<SkipT> const& skip)
|
||||
{
|
||||
CharT const* last = str;
|
||||
while (*last)
|
||||
last++;
|
||||
return parse(str, last, p, skip);
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,329 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2002 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_SCANNER_HPP)
|
||||
#define BOOST_SPIRIT_SCANNER_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/match.hpp>
|
||||
#include <boost/spirit/home/classic/core/non_terminal/parser_id.hpp>
|
||||
#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
|
||||
|
||||
#include <boost/spirit/home/classic/core/scanner/scanner_fwd.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// iteration_policy class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct iteration_policy
|
||||
{
|
||||
template <typename ScannerT>
|
||||
void
|
||||
advance(ScannerT const& scan) const
|
||||
{
|
||||
++scan.first;
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
bool at_end(ScannerT const& scan) const
|
||||
{
|
||||
return scan.first == scan.last;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T filter(T ch) const
|
||||
{
|
||||
return ch;
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename ScannerT::ref_t
|
||||
get(ScannerT const& scan) const
|
||||
{
|
||||
return *scan.first;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// match_policy class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct match_policy
|
||||
{
|
||||
template <typename T>
|
||||
struct result { typedef match<T> type; };
|
||||
|
||||
const match<nil_t>
|
||||
no_match() const
|
||||
{
|
||||
return match<nil_t>();
|
||||
}
|
||||
|
||||
const match<nil_t>
|
||||
empty_match() const
|
||||
{
|
||||
return match<nil_t>(0, nil_t());
|
||||
}
|
||||
|
||||
template <typename AttrT, typename IteratorT>
|
||||
match<AttrT>
|
||||
create_match(
|
||||
std::size_t length,
|
||||
AttrT const& val,
|
||||
IteratorT const& /*first*/,
|
||||
IteratorT const& /*last*/) const
|
||||
{
|
||||
return match<AttrT>(length, val);
|
||||
}
|
||||
|
||||
template <typename MatchT, typename IteratorT>
|
||||
void group_match(
|
||||
MatchT& /*m*/,
|
||||
parser_id const& /*id*/,
|
||||
IteratorT const& /*first*/,
|
||||
IteratorT const& /*last*/) const {}
|
||||
|
||||
template <typename Match1T, typename Match2T>
|
||||
void concat_match(Match1T& l, Match2T const& r) const
|
||||
{
|
||||
l.concat(r);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// match_result class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename MatchPolicyT, typename T>
|
||||
struct match_result
|
||||
{
|
||||
typedef typename MatchPolicyT::template result<T>::type type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// action_policy class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename AttrT>
|
||||
struct attributed_action_policy
|
||||
{
|
||||
template <typename ActorT, typename IteratorT>
|
||||
static void
|
||||
call(
|
||||
ActorT const& actor,
|
||||
AttrT& val,
|
||||
IteratorT const&,
|
||||
IteratorT const&)
|
||||
{
|
||||
actor(val);
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
template <>
|
||||
struct attributed_action_policy<nil_t>
|
||||
{
|
||||
template <typename ActorT, typename IteratorT>
|
||||
static void
|
||||
call(
|
||||
ActorT const& actor,
|
||||
nil_t,
|
||||
IteratorT const& first,
|
||||
IteratorT const& last)
|
||||
{
|
||||
actor(first, last);
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
struct action_policy
|
||||
{
|
||||
template <typename ActorT, typename AttrT, typename IteratorT>
|
||||
void
|
||||
do_action(
|
||||
ActorT const& actor,
|
||||
AttrT& val,
|
||||
IteratorT const& first,
|
||||
IteratorT const& last) const
|
||||
{
|
||||
attributed_action_policy<AttrT>::call(actor, val, first, last);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// scanner_policies class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename IterationPolicyT,
|
||||
typename MatchPolicyT,
|
||||
typename ActionPolicyT>
|
||||
struct scanner_policies :
|
||||
public IterationPolicyT,
|
||||
public MatchPolicyT,
|
||||
public ActionPolicyT
|
||||
{
|
||||
typedef IterationPolicyT iteration_policy_t;
|
||||
typedef MatchPolicyT match_policy_t;
|
||||
typedef ActionPolicyT action_policy_t;
|
||||
|
||||
scanner_policies(
|
||||
IterationPolicyT const& i_policy = IterationPolicyT(),
|
||||
MatchPolicyT const& m_policy = MatchPolicyT(),
|
||||
ActionPolicyT const& a_policy = ActionPolicyT())
|
||||
: IterationPolicyT(i_policy)
|
||||
, MatchPolicyT(m_policy)
|
||||
, ActionPolicyT(a_policy) {}
|
||||
|
||||
template <typename ScannerPoliciesT>
|
||||
scanner_policies(ScannerPoliciesT const& policies)
|
||||
: IterationPolicyT(policies)
|
||||
, MatchPolicyT(policies)
|
||||
, ActionPolicyT(policies) {}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// scanner_policies_base class: the base class of all scanners
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct scanner_base {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// scanner class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename IteratorT,
|
||||
typename PoliciesT>
|
||||
class scanner : public PoliciesT, public scanner_base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef IteratorT iterator_t;
|
||||
typedef PoliciesT policies_t;
|
||||
|
||||
typedef typename boost::detail::
|
||||
iterator_traits<IteratorT>::value_type value_t;
|
||||
typedef typename boost::detail::
|
||||
iterator_traits<IteratorT>::reference ref_t;
|
||||
typedef typename boost::
|
||||
call_traits<IteratorT>::param_type iter_param_t;
|
||||
|
||||
scanner(
|
||||
IteratorT& first_,
|
||||
iter_param_t last_,
|
||||
PoliciesT const& policies = PoliciesT())
|
||||
: PoliciesT(policies), first(first_), last(last_)
|
||||
{
|
||||
at_end();
|
||||
}
|
||||
|
||||
scanner(scanner const& other)
|
||||
: PoliciesT(other), first(other.first), last(other.last) {}
|
||||
|
||||
scanner(scanner const& other, IteratorT& first_)
|
||||
: PoliciesT(other), first(first_), last(other.last) {}
|
||||
|
||||
template <typename PoliciesT1>
|
||||
scanner(scanner<IteratorT, PoliciesT1> const& other)
|
||||
: PoliciesT(other), first(other.first), last(other.last) {}
|
||||
|
||||
bool
|
||||
at_end() const
|
||||
{
|
||||
typedef typename PoliciesT::iteration_policy_t iteration_policy_type;
|
||||
return iteration_policy_type::at_end(*this);
|
||||
}
|
||||
|
||||
value_t
|
||||
operator*() const
|
||||
{
|
||||
typedef typename PoliciesT::iteration_policy_t iteration_policy_type;
|
||||
return iteration_policy_type::filter(iteration_policy_type::get(*this));
|
||||
}
|
||||
|
||||
scanner const&
|
||||
operator++() const
|
||||
{
|
||||
typedef typename PoliciesT::iteration_policy_t iteration_policy_type;
|
||||
iteration_policy_type::advance(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename PoliciesT2>
|
||||
struct rebind_policies
|
||||
{
|
||||
typedef scanner<IteratorT, PoliciesT2> type;
|
||||
};
|
||||
|
||||
template <typename PoliciesT2>
|
||||
scanner<IteratorT, PoliciesT2>
|
||||
change_policies(PoliciesT2 const& policies) const
|
||||
{
|
||||
return scanner<IteratorT, PoliciesT2>(first, last, policies);
|
||||
}
|
||||
|
||||
template <typename IteratorT2>
|
||||
struct rebind_iterator
|
||||
{
|
||||
typedef scanner<IteratorT2, PoliciesT> type;
|
||||
};
|
||||
|
||||
template <typename IteratorT2>
|
||||
scanner<IteratorT2, PoliciesT>
|
||||
change_iterator(IteratorT2 const& first_, IteratorT2 const &last_) const
|
||||
{
|
||||
return scanner<IteratorT2, PoliciesT>(first_, last_, *this);
|
||||
}
|
||||
|
||||
IteratorT& first;
|
||||
IteratorT const last;
|
||||
|
||||
private:
|
||||
|
||||
scanner&
|
||||
operator=(scanner const& other);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// rebind_scanner_policies class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename ScannerT, typename PoliciesT>
|
||||
struct rebind_scanner_policies
|
||||
{
|
||||
typedef typename ScannerT::template
|
||||
rebind_policies<PoliciesT>::type type;
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
template <typename ScannerT, typename IteratorT>
|
||||
struct rebind_scanner_iterator
|
||||
{
|
||||
typedef typename ScannerT::template
|
||||
rebind_iterator<IteratorT>::type type;
|
||||
};
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,52 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2006 Tobias Schwinger
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_SCANNER_FWD_HPP)
|
||||
#define BOOST_SPIRIT_SCANNER_FWD_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// policy classes
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct iteration_policy;
|
||||
struct action_policy;
|
||||
struct match_policy;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// scanner_policies class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename IterationPolicyT = iteration_policy,
|
||||
typename MatchPolicyT = match_policy,
|
||||
typename ActionPolicyT = action_policy>
|
||||
struct scanner_policies;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// scanner class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename IteratorT = char const*,
|
||||
typename PoliciesT = scanner_policies<> >
|
||||
class scanner;
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_SKIPPER_HPP)
|
||||
#define BOOST_SPIRIT_SKIPPER_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <cctype>
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/scanner/scanner.hpp>
|
||||
#include <boost/spirit/home/classic/core/primitives/impl/primitives.ipp>
|
||||
|
||||
#include <boost/spirit/home/classic/core/scanner/skipper_fwd.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// skipper_iteration_policy class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename BaseT>
|
||||
struct skipper_iteration_policy : public BaseT
|
||||
{
|
||||
typedef BaseT base_t;
|
||||
|
||||
skipper_iteration_policy()
|
||||
: BaseT() {}
|
||||
|
||||
template <typename PolicyT>
|
||||
skipper_iteration_policy(PolicyT const& other)
|
||||
: BaseT(other) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
void
|
||||
advance(ScannerT const& scan) const
|
||||
{
|
||||
BaseT::advance(scan);
|
||||
scan.skip(scan);
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
bool
|
||||
at_end(ScannerT const& scan) const
|
||||
{
|
||||
scan.skip(scan);
|
||||
return BaseT::at_end(scan);
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
void
|
||||
skip(ScannerT const& scan) const
|
||||
{
|
||||
while (!BaseT::at_end(scan) && impl::isspace_(BaseT::get(scan)))
|
||||
BaseT::advance(scan);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// no_skipper_iteration_policy class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename BaseT>
|
||||
struct no_skipper_iteration_policy : public BaseT
|
||||
{
|
||||
typedef BaseT base_t;
|
||||
|
||||
no_skipper_iteration_policy()
|
||||
: BaseT() {}
|
||||
|
||||
template <typename PolicyT>
|
||||
no_skipper_iteration_policy(PolicyT const& other)
|
||||
: BaseT(other) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
void
|
||||
skip(ScannerT const& /*scan*/) const {}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// skip_parser_iteration_policy class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace impl
|
||||
{
|
||||
template <typename ST, typename ScannerT, typename BaseT>
|
||||
void
|
||||
skipper_skip(
|
||||
ST const& s,
|
||||
ScannerT const& scan,
|
||||
skipper_iteration_policy<BaseT> const&);
|
||||
|
||||
template <typename ST, typename ScannerT, typename BaseT>
|
||||
void
|
||||
skipper_skip(
|
||||
ST const& s,
|
||||
ScannerT const& scan,
|
||||
no_skipper_iteration_policy<BaseT> const&);
|
||||
|
||||
template <typename ST, typename ScannerT>
|
||||
void
|
||||
skipper_skip(
|
||||
ST const& s,
|
||||
ScannerT const& scan,
|
||||
iteration_policy const&);
|
||||
}
|
||||
|
||||
template <typename ParserT, typename BaseT>
|
||||
class skip_parser_iteration_policy : public skipper_iteration_policy<BaseT>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef skipper_iteration_policy<BaseT> base_t;
|
||||
|
||||
skip_parser_iteration_policy(
|
||||
ParserT const& skip_parser,
|
||||
base_t const& base = base_t())
|
||||
: base_t(base), subject(skip_parser) {}
|
||||
|
||||
template <typename PolicyT>
|
||||
skip_parser_iteration_policy(PolicyT const& other)
|
||||
: base_t(other), subject(other.skipper()) {}
|
||||
|
||||
template <typename ScannerT>
|
||||
void
|
||||
skip(ScannerT const& scan) const
|
||||
{
|
||||
impl::skipper_skip(subject, scan, scan);
|
||||
}
|
||||
|
||||
ParserT const&
|
||||
skipper() const
|
||||
{
|
||||
return subject;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
ParserT const& subject;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Free parse functions using the skippers
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename IteratorT, typename ParserT, typename SkipT>
|
||||
parse_info<IteratorT>
|
||||
parse(
|
||||
IteratorT const& first,
|
||||
IteratorT const& last,
|
||||
parser<ParserT> const& p,
|
||||
parser<SkipT> const& skip);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Parse function for null terminated strings using the skippers
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharT, typename ParserT, typename SkipT>
|
||||
parse_info<CharT const*>
|
||||
parse(
|
||||
CharT const* str,
|
||||
parser<ParserT> const& p,
|
||||
parser<SkipT> const& skip);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// phrase_scanner_t and wide_phrase_scanner_t
|
||||
//
|
||||
// The most common scanners. Use these typedefs when you need
|
||||
// a scanner that skips white spaces.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
typedef skipper_iteration_policy<> iter_policy_t;
|
||||
typedef scanner_policies<iter_policy_t> scanner_policies_t;
|
||||
typedef scanner<char const*, scanner_policies_t> phrase_scanner_t;
|
||||
typedef scanner<wchar_t const*, scanner_policies_t> wide_phrase_scanner_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#include <boost/spirit/home/classic/core/scanner/impl/skipper.ipp>
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2006 Tobias Schwinger
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_SKIPPER_FWD_HPP)
|
||||
#define BOOST_SPIRIT_SKIPPER_FWD_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/scanner/scanner_fwd.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
template <typename BaseT = iteration_policy>
|
||||
struct skipper_iteration_policy;
|
||||
|
||||
template <typename BaseT = iteration_policy>
|
||||
struct no_skipper_iteration_policy;
|
||||
|
||||
template <typename ParserT, typename BaseT = iteration_policy>
|
||||
class skip_parser_iteration_policy;
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,343 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2006 Tobias Schwinger
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_CORE_TYPEOF_HPP)
|
||||
#define BOOST_SPIRIT_CORE_TYPEOF_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/nil.hpp>
|
||||
#include <boost/spirit/home/classic/core/primitives/numerics_fwd.hpp>
|
||||
#include <boost/spirit/home/classic/core/scanner/scanner_fwd.hpp>
|
||||
#include <boost/spirit/home/classic/core/scanner/skipper_fwd.hpp>
|
||||
#include <boost/spirit/home/classic/core/non_terminal/subrule_fwd.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
// parser.hpp
|
||||
template <typename IteratorT> struct parse_info;
|
||||
struct plain_parser_category;
|
||||
struct binary_parser_category;
|
||||
struct unary_parser_category;
|
||||
struct action_parser_category;
|
||||
|
||||
// match.hpp
|
||||
template<typename T> class match;
|
||||
|
||||
// primitives/primitives.hpp
|
||||
template<class ParserT> struct negated_char_parser;
|
||||
template<typename CharT> struct chlit;
|
||||
template<typename CharT> struct range;
|
||||
template<typename IteratorT> class chseq;
|
||||
template<typename IteratorT> class strlit;
|
||||
struct nothing_parser;
|
||||
struct anychar_parser;
|
||||
struct alnum_parser;
|
||||
struct alpha_parser;
|
||||
struct cntrl_parser;
|
||||
struct digit_parser;
|
||||
struct xdigit_parser;
|
||||
struct graph_parser;
|
||||
struct upper_parser;
|
||||
struct lower_parser;
|
||||
struct print_parser;
|
||||
struct punct_parser;
|
||||
struct blank_parser;
|
||||
struct space_parser;
|
||||
struct eol_parser;
|
||||
struct end_parser;
|
||||
|
||||
// non_terminal/parser_context.hpp
|
||||
template<typename T> struct parser_context;
|
||||
|
||||
// non_terminal/parser_id.hpp
|
||||
class parser_id;
|
||||
template<int N> struct parser_tag;
|
||||
class dynamic_parser_tag;
|
||||
struct parser_address_tag;
|
||||
|
||||
// non_terminal/rule.hpp
|
||||
template<typename T0, typename T1, typename T2> class rule;
|
||||
|
||||
// non_terminal/grammar.hpp
|
||||
template<class DerivedT, typename ContextT> struct grammar;
|
||||
|
||||
// composite.hpp
|
||||
template<class ParserT, typename ActionT> class action;
|
||||
template<class A, class B> struct alternative;
|
||||
template<class A, class B> struct difference;
|
||||
template<class A, class B> struct exclusive_or;
|
||||
template<class A, class B> struct intersection;
|
||||
template<class a, class b> struct sequence;
|
||||
template<class A, class B> struct sequential_or;
|
||||
template<class S> struct kleene_star;
|
||||
template<class S> struct positive;
|
||||
template<class S> struct optional;
|
||||
// composite/directives.hpp
|
||||
template<class ParserT> struct contiguous;
|
||||
template<class ParserT> struct inhibit_case;
|
||||
template<class BaseT> struct inhibit_case_iteration_policy;
|
||||
template<class A, class B> struct longest_alternative;
|
||||
template<class A, class B> struct shortest_alternative;
|
||||
template<class ParserT, typename BoundsT> struct min_bounded;
|
||||
template<class ParserT, typename BoundsT> struct max_bounded;
|
||||
template<class ParserT, typename BoundsT> struct bounded;
|
||||
// composite/no_actions.hpp
|
||||
template<class Parser> struct no_actions_parser;
|
||||
template<class Base> struct no_actions_action_policy;
|
||||
// composite/epsilon.hpp
|
||||
struct epsilon_parser;
|
||||
template<typename CondT, bool positive> struct condition_parser;
|
||||
template<typename SubjectT> struct empty_match_parser;
|
||||
template<typename SubjectT> struct negated_empty_match_parser;
|
||||
|
||||
// deprecated assign/push_back actor -- they live somewhere else, now
|
||||
struct assign_action;
|
||||
struct push_back_action;
|
||||
template<typename T, typename ActionT> class ref_value_actor;
|
||||
template<typename T, typename ValueT, typename ActionT>
|
||||
class ref_const_ref_actor;
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
|
||||
|
||||
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
|
||||
|
||||
|
||||
// parser.hpp
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::parse_info,1)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::plain_parser_category)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::binary_parser_category)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::unary_parser_category)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::action_parser_category)
|
||||
|
||||
|
||||
// nil.hpp (included directly)
|
||||
|
||||
#if !defined(BOOST_SPIRIT_NIL_T_TYPEOF_REGISTERED)
|
||||
// registration guard to decouple the iterators from the core
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::nil_t)
|
||||
# define BOOST_SPIRIT_NIL_T_TYPEOF_REGISTERED
|
||||
#endif
|
||||
|
||||
// match.hpp
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::match, 1)
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::match<BOOST_SPIRIT_CLASSIC_NS::nil_t>)
|
||||
|
||||
|
||||
// primitives/primitives.hpp
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::negated_char_parser, 1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::chlit, 1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::range, 1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::chseq, 1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::strlit, 1)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::nothing_parser)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::anychar_parser)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::alnum_parser)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::alpha_parser)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::cntrl_parser)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::digit_parser)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::xdigit_parser)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::graph_parser)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::upper_parser)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::lower_parser)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::print_parser)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::punct_parser)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::blank_parser)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::space_parser)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::eol_parser)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::end_parser)
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::chlit<char>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::chlit<wchar_t>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::range<char>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::range<wchar_t>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::chseq<char const *>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::chseq<wchar_t const *>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::strlit<char const *>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::strlit<wchar_t const *>)
|
||||
|
||||
|
||||
// primitives/numerics.hpp (has forward header)
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::int_parser, (class)(int)(unsigned)(int))
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::uint_parser, (class)(int)(unsigned)(int))
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::sign_parser)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::real_parser, 2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::real_parser_policies, 1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::ureal_parser_policies, 1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::strict_real_parser_policies, 1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::strict_ureal_parser_policies, 1)
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::int_parser, (class)(int))
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::uint_parser, (class)(int))
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::int_parser<boost::int32_t>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::uint_parser<boost::uint32_t>)
|
||||
#if !defined(BOOST_NO_INT64_T)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::int_parser<boost::int64_t>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::uint_parser<boost::uint64_t>)
|
||||
#endif
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::real_parser_policies<float>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::real_parser_policies<double>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::ureal_parser_policies<float>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::ureal_parser_policies<double>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::strict_real_parser_policies<float>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::strict_real_parser_policies<double>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::strict_ureal_parser_policies<float>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::strict_ureal_parser_policies<double>)
|
||||
|
||||
|
||||
// scanner/scanner.hpp (has forward header)
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::scanner,2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::scanner_policies,3)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::iteration_policy)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::action_policy)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::match_policy)
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::scanner,1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::scanner_policies,2)
|
||||
|
||||
|
||||
// scanner/skipper.hpp (has forward header)
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::skipper_iteration_policy,1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::no_skipper_iteration_policy,1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::skip_parser_iteration_policy,2)
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::skipper_iteration_policy<>)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::skip_parser_iteration_policy,1)
|
||||
|
||||
|
||||
// non_terminal/parser_context.hpp
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::parser_context,1)
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::parser_context<BOOST_SPIRIT_CLASSIC_NS::nil_t>)
|
||||
|
||||
|
||||
// non_terminal/parser_id.hpp
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::parser_id)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::parser_tag, (int))
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::dynamic_parser_tag)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::parser_address_tag)
|
||||
|
||||
|
||||
// non_terminal/subrule.hpp (has forward header)
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::subrule,(int)(class))
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::subrule_parser,(int)(class)(class))
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::subrule_list,2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::subrules_scanner,2)
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::subrule,(int))
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::subrule_parser,(int)(class))
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::subrule<0>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::subrule<1>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::subrule<2>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::subrule<3>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::subrule<4>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::subrule<5>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::subrule<6>)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::subrule<7>)
|
||||
|
||||
|
||||
// non_terminal/rule.hpp
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::rule,3)
|
||||
#if BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT > 1
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::scanner_list,1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::scanner_list,BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT)
|
||||
#endif
|
||||
|
||||
|
||||
// non_terminal/grammar.hpp
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::grammar,2)
|
||||
|
||||
|
||||
// composite.hpp
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::action, 2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::alternative, 2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::difference, 2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::exclusive_or, 2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::intersection, 2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::sequence, 2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::sequential_or, 2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::kleene_star, 1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::positive, 1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::optional, 1)
|
||||
|
||||
|
||||
// composite/directives.hpp
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::contiguous, 1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::inhibit_case, 1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::inhibit_case_iteration_policy,1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::longest_alternative, 2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::shortest_alternative, 2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::min_bounded, 2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::max_bounded, 2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::bounded, 2)
|
||||
|
||||
|
||||
// composite/no_actions.hpp
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::no_actions_parser, 1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::no_actions_action_policy, 1)
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::no_actions_action_policy<BOOST_SPIRIT_CLASSIC_NS::action_policy>)
|
||||
|
||||
|
||||
// composite/epsilon.hpp
|
||||
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::epsilon_parser)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::condition_parser, (class)(bool))
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::empty_match_parser, 1)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::negated_empty_match_parser, 1)
|
||||
|
||||
|
||||
#if !defined(BOOST_SPIRIT_ACTOR_TYPEOF_HPP)
|
||||
// deprecated assign/push_back actor -- they live somewhere else, now
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::ref_value_actor,2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::ref_const_ref_actor,3)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::assign_action)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::push_back_action)
|
||||
#endif
|
||||
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400)) && BOOST_MSVC >= 1400
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
nil_t & operator* (nil_t);
|
||||
nil_t & operator+ (nil_t);
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
} } // namespace ::BOOST_SPIRIT_CLASSIC_NS
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2003 Joel de Guzman
|
||||
Copyright (c) 2002-2003 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_MAIN_HPP)
|
||||
#define BOOST_SPIRIT_DEBUG_MAIN_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#if defined(BOOST_SPIRIT_DEBUG)
|
||||
|
||||
#include <boost/spirit/home/classic/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_CLASSIC_NS::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_CLASSIC_NS::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_CLASSIC_NS::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_CLASSIC_NS::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_CLASSIC_NS::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_CLASSIC_NS::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_CLASSIC_NS::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_CLASSIC_NS::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_CLASSIC_NS::impl::get_node_registry(). \
|
||||
register_node(&r, (n), (t))
|
||||
#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME)
|
||||
|
||||
//////////////////////////////////
|
||||
#include <boost/spirit/home/classic/debug/debug_node.hpp>
|
||||
|
||||
#else
|
||||
//////////////////////////////////
|
||||
#include <boost/spirit/home/classic/debug/minimal.hpp>
|
||||
|
||||
#endif // BOOST_SPIRIT_DEBUG
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2002-2003 Joel de Guzman
|
||||
Copyright (c) 2002 Juan Carlos Arevalo-Baeza
|
||||
Copyright (c) 2002-2003 Martin Wille
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_DYNAMIC_HPP
|
||||
#define BOOST_SPIRIT_DYNAMIC_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/version.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Master header for Spirit.Dynamic
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/spirit/home/classic/dynamic/if.hpp>
|
||||
#include <boost/spirit/home/classic/dynamic/for.hpp>
|
||||
#include <boost/spirit/home/classic/dynamic/while.hpp>
|
||||
#include <boost/spirit/home/classic/dynamic/lazy.hpp>
|
||||
#include <boost/spirit/home/classic/dynamic/stored_rule.hpp>
|
||||
#include <boost/spirit/home/classic/dynamic/rule_alias.hpp>
|
||||
#include <boost/spirit/home/classic/dynamic/select.hpp>
|
||||
#include <boost/spirit/home/classic/dynamic/switch.hpp>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#endif // BOOST_SPIRIT_DYNAMIC_HPP
|
||||
@@ -0,0 +1,187 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2002-2003 Joel de Guzman
|
||||
Copyright (c) 2002-2003 Martin Wille
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_FOR_HPP
|
||||
#define BOOST_SPIRIT_FOR_HPP
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/dynamic/impl/conditions.ipp>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
namespace impl
|
||||
{
|
||||
|
||||
template <typename FuncT>
|
||||
struct for_functor
|
||||
{
|
||||
typedef typename boost::call_traits<FuncT>::param_type param_t;
|
||||
|
||||
for_functor(param_t f) : func(f) {}
|
||||
for_functor() {}
|
||||
FuncT func;
|
||||
};
|
||||
|
||||
template <typename InitF>
|
||||
struct for_init_functor : for_functor<InitF>
|
||||
{
|
||||
typedef for_functor<InitF> base_t;
|
||||
typedef typename base_t::param_t param_t;
|
||||
|
||||
for_init_functor(param_t f) : base_t(f) {}
|
||||
for_init_functor() : base_t() {}
|
||||
void init() const { /*return*/ this->func(); }
|
||||
};
|
||||
|
||||
template <typename StepF>
|
||||
struct for_step_functor : for_functor<StepF>
|
||||
{
|
||||
typedef for_functor<StepF> base_t;
|
||||
typedef typename base_t::param_t param_t;
|
||||
|
||||
for_step_functor(param_t f) : base_t(f) {}
|
||||
for_step_functor() : base_t() {}
|
||||
void step() const { /*return*/ this->func(); }
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
// for_parser
|
||||
template
|
||||
<
|
||||
typename InitF, typename CondT, typename StepF,
|
||||
typename ParsableT
|
||||
>
|
||||
struct for_parser
|
||||
: private for_init_functor<InitF>
|
||||
, private for_step_functor<StepF>
|
||||
, private condition_evaluator<typename as_parser<CondT>::type>
|
||||
, public unary
|
||||
<
|
||||
typename as_parser<ParsableT>::type,
|
||||
parser< for_parser<InitF, CondT, StepF, ParsableT> >
|
||||
>
|
||||
{
|
||||
typedef for_parser<InitF, CondT, StepF, ParsableT> self_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 as_parser<ParsableT> as_parser_t;
|
||||
typedef typename as_parser_t::type parser_t;
|
||||
typedef unary< parser_t, parser< self_t > > base_t;
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
// constructor, saves init, condition and step functors
|
||||
// for later use the parse member function
|
||||
for_parser
|
||||
(
|
||||
InitF const &i, CondT const &c, StepF const &s,
|
||||
ParsableT const &p
|
||||
)
|
||||
: for_init_functor<InitF>(i)
|
||||
, for_step_functor<StepF>(s)
|
||||
, eval_t(cond_as_parser_t::convert(c))
|
||||
, base_t(as_parser_t::convert(p))
|
||||
{ }
|
||||
|
||||
for_parser()
|
||||
: for_init_functor<InitF>()
|
||||
, for_step_functor<StepF>()
|
||||
, eval_t()
|
||||
, base_t()
|
||||
{}
|
||||
|
||||
//////////////////////////////
|
||||
// parse member function
|
||||
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 parser_result<parser_t, ScannerT>::type
|
||||
body_result_t;
|
||||
|
||||
typename ScannerT::iterator_t save(scan.first);
|
||||
|
||||
std::size_t length = 0;
|
||||
int eval_length = 0;
|
||||
|
||||
this->init();
|
||||
while ((eval_length = this->evaluate(scan))>=0)
|
||||
{
|
||||
length += eval_length;
|
||||
body_result_t tmp(this->subject().parse(scan));
|
||||
if (tmp)
|
||||
{
|
||||
length+=tmp.length();
|
||||
}
|
||||
else
|
||||
{
|
||||
return scan.no_match();
|
||||
}
|
||||
this->step();
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NS::nil_t attr;
|
||||
return scan.create_match
|
||||
(length, attr, save, scan.first);
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
// for_parser_gen generates takes the body parser in brackets
|
||||
// and returns the for_parser
|
||||
template <typename InitF, typename CondT, typename StepF>
|
||||
struct for_parser_gen
|
||||
{
|
||||
for_parser_gen(InitF const &i, CondT const &c, StepF const &s)
|
||||
: init(i)
|
||||
, condition(c)
|
||||
, step(s)
|
||||
{}
|
||||
|
||||
template <typename ParsableT>
|
||||
for_parser<InitF, CondT, StepF, ParsableT>
|
||||
operator[](ParsableT const &p) const
|
||||
{
|
||||
return for_parser<InitF, CondT, StepF, ParsableT>
|
||||
(init, condition, step, p);
|
||||
}
|
||||
|
||||
InitF const &init;
|
||||
CondT const &condition;
|
||||
StepF const &step;
|
||||
};
|
||||
} // namespace impl
|
||||
|
||||
//////////////////////////////
|
||||
// for_p, returns for-parser generator
|
||||
// Usage: spirit::for_p(init-ftor, condition, step-ftor)[body]
|
||||
template
|
||||
<
|
||||
typename InitF, typename ConditionT, typename StepF
|
||||
>
|
||||
impl::for_parser_gen<InitF, ConditionT, StepF>
|
||||
for_p(InitF const &init_f, ConditionT const &condition, StepF const &step_f)
|
||||
{
|
||||
return impl::for_parser_gen<InitF, ConditionT, StepF>
|
||||
(init_f, condition, step_f);
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif // BOOST_SPIRIT_FOR_HPP
|
||||
@@ -0,0 +1,229 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2002-2003 Joel de Guzman
|
||||
Copyright (c) 2002 Juan Carlos Arevalo-Baeza
|
||||
Copyright (c) 2002-2003 Martin Wille
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_IF_HPP
|
||||
#define BOOST_SPIRIT_IF_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/dynamic/impl/conditions.ipp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
namespace impl {
|
||||
|
||||
//////////////////////////////////
|
||||
// if-else-parser, holds two alternative parsers and a conditional functor
|
||||
// that selects between them.
|
||||
template <typename ParsableTrueT, typename ParsableFalseT, typename CondT>
|
||||
struct if_else_parser
|
||||
: public condition_evaluator<typename as_parser<CondT>::type>
|
||||
, public binary
|
||||
<
|
||||
typename as_parser<ParsableTrueT>::type,
|
||||
typename as_parser<ParsableFalseT>::type,
|
||||
parser< if_else_parser<ParsableTrueT, ParsableFalseT, CondT> >
|
||||
>
|
||||
{
|
||||
typedef if_else_parser<ParsableTrueT, ParsableFalseT, CondT> self_t;
|
||||
|
||||
typedef as_parser<ParsableTrueT> as_parser_true_t;
|
||||
typedef as_parser<ParsableFalseT> as_parser_false_t;
|
||||
typedef typename as_parser_true_t::type parser_true_t;
|
||||
typedef typename as_parser_false_t::type parser_false_t;
|
||||
typedef as_parser<CondT> cond_as_parser_t;
|
||||
typedef typename cond_as_parser_t::type condition_t;
|
||||
|
||||
typedef binary<parser_true_t, parser_false_t, parser<self_t> > base_t;
|
||||
typedef condition_evaluator<condition_t> eval_t;
|
||||
|
||||
if_else_parser
|
||||
(
|
||||
ParsableTrueT const& p_true,
|
||||
ParsableFalseT const& p_false,
|
||||
CondT const& cond_
|
||||
)
|
||||
: eval_t(cond_as_parser_t::convert(cond_))
|
||||
, base_t
|
||||
(
|
||||
as_parser_true_t::convert(p_true),
|
||||
as_parser_false_t::convert(p_false)
|
||||
)
|
||||
{ }
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, nil_t>::type type;
|
||||
};
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result
|
||||
<parser_true_t, ScannerT>::type then_result_t;
|
||||
typedef typename parser_result
|
||||
<parser_false_t, ScannerT>::type else_result_t;
|
||||
|
||||
typename ScannerT::iterator_t const save(scan.first);
|
||||
|
||||
std::ptrdiff_t length = this->evaluate(scan);
|
||||
if (length >= 0)
|
||||
{
|
||||
then_result_t then_result(this->left().parse(scan));
|
||||
if (then_result)
|
||||
{
|
||||
length += then_result.length();
|
||||
return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
else_result_t else_result(this->right().parse(scan));
|
||||
if (else_result)
|
||||
{
|
||||
length = else_result.length();
|
||||
return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
|
||||
}
|
||||
}
|
||||
return scan.no_match();
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
// if-else-parser generator, takes the false-parser in brackets
|
||||
// and returns the if-else-parser.
|
||||
template <typename ParsableTrueT, typename CondT>
|
||||
struct if_else_parser_gen
|
||||
{
|
||||
if_else_parser_gen(ParsableTrueT const& p_true_, CondT const& cond_)
|
||||
: p_true(p_true_)
|
||||
, cond(cond_) {}
|
||||
|
||||
template <typename ParsableFalseT>
|
||||
if_else_parser
|
||||
<
|
||||
ParsableTrueT,
|
||||
ParsableFalseT,
|
||||
CondT
|
||||
>
|
||||
operator[](ParsableFalseT const& p_false) const
|
||||
{
|
||||
return if_else_parser<ParsableTrueT, ParsableFalseT, CondT>
|
||||
(
|
||||
p_true,
|
||||
p_false,
|
||||
cond
|
||||
);
|
||||
}
|
||||
|
||||
ParsableTrueT const &p_true;
|
||||
CondT const &cond;
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
// if-parser, conditionally runs a parser is a functor condition is true.
|
||||
// If the condition is fales, it fails the parse.
|
||||
// It can optionally become an if-else-parser through the member else_p.
|
||||
template <typename ParsableT, typename CondT>
|
||||
struct if_parser
|
||||
: public condition_evaluator<typename as_parser<CondT>::type>
|
||||
, public unary
|
||||
<
|
||||
typename as_parser<ParsableT>::type,
|
||||
parser<if_parser<ParsableT, CondT> > >
|
||||
{
|
||||
typedef if_parser<ParsableT, CondT> self_t;
|
||||
typedef as_parser<ParsableT> as_parser_t;
|
||||
typedef typename as_parser_t::type parser_t;
|
||||
|
||||
typedef as_parser<CondT> cond_as_parser_t;
|
||||
typedef typename cond_as_parser_t::type condition_t;
|
||||
typedef condition_evaluator<condition_t> eval_t;
|
||||
typedef unary<parser_t, parser<self_t> > base_t;
|
||||
|
||||
if_parser(ParsableT const& p, CondT const& cond_)
|
||||
: eval_t(cond_as_parser_t::convert(cond_))
|
||||
, base_t(as_parser_t::convert(p))
|
||||
, else_p(p, cond_)
|
||||
{}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, nil_t>::type type;
|
||||
};
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<parser_t, ScannerT>::type t_result_t;
|
||||
typename ScannerT::iterator_t const save(scan.first);
|
||||
|
||||
std::ptrdiff_t length = this->evaluate(scan);
|
||||
if (length >= 0)
|
||||
{
|
||||
t_result_t then_result(this->subject().parse(scan));
|
||||
if (then_result)
|
||||
{
|
||||
length += then_result.length();
|
||||
return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
|
||||
}
|
||||
return scan.no_match();
|
||||
}
|
||||
return scan.empty_match();
|
||||
}
|
||||
|
||||
if_else_parser_gen<ParsableT, CondT> else_p;
|
||||
};
|
||||
|
||||
//////////////////////////////////
|
||||
// if-parser generator, takes the true-parser in brackets and returns the
|
||||
// if-parser.
|
||||
template <typename CondT>
|
||||
struct if_parser_gen
|
||||
{
|
||||
if_parser_gen(CondT const& cond_) : cond(cond_) {}
|
||||
|
||||
template <typename ParsableT>
|
||||
if_parser
|
||||
<
|
||||
ParsableT,
|
||||
CondT
|
||||
>
|
||||
operator[](ParsableT const& subject) const
|
||||
{
|
||||
return if_parser<ParsableT, CondT>(subject, cond);
|
||||
}
|
||||
|
||||
CondT const &cond;
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
//////////////////////////////////
|
||||
// if_p function, returns "if" parser generator
|
||||
|
||||
template <typename CondT>
|
||||
impl::if_parser_gen<CondT>
|
||||
if_p(CondT const& cond)
|
||||
{
|
||||
return impl::if_parser_gen<CondT>(cond);
|
||||
}
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif // BOOST_SPIRIT_IF_HPP
|
||||
@@ -0,0 +1,104 @@
|
||||
/*=============================================================================
|
||||
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/home/classic/meta/parser_traits.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/epsilon.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
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
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,120 @@
|
||||
/*=============================================================================
|
||||
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_SELECT_IPP
|
||||
#define BOOST_SPIRIT_SELECT_IPP
|
||||
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/meta/as_parser.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace impl {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename ParserT>
|
||||
struct as_embedded_parser : public as_parser<ParserT>
|
||||
{
|
||||
typedef typename as_parser<ParserT>::type::derived_t::embed_t type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// no implementation here to catch unknown BehaviourT template arguments
|
||||
template <typename ResultT, typename BehaviourT>
|
||||
struct select_match_gen;
|
||||
|
||||
// implementation for the select_default_no_fail behaviour
|
||||
template <typename ResultT>
|
||||
struct select_match_gen<ResultT, select_default_no_fail> {
|
||||
|
||||
template <typename ScannerT>
|
||||
static ResultT
|
||||
do_ (ScannerT const &scan)
|
||||
{
|
||||
return scan.create_match(0, -1, scan.first, scan.first);
|
||||
}
|
||||
};
|
||||
|
||||
// implementation for the select_default_fail behaviour
|
||||
template <typename ResultT>
|
||||
struct select_match_gen<ResultT, select_default_fail> {
|
||||
|
||||
template <typename ScannerT>
|
||||
static ResultT
|
||||
do_ (ScannerT const &scan)
|
||||
{
|
||||
return scan.no_match();
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <int N, typename ResultT, typename TupleT, typename BehaviourT>
|
||||
struct parse_tuple_element {
|
||||
|
||||
BOOST_STATIC_CONSTANT(int, index = (TupleT::length - N));
|
||||
|
||||
template <typename ScannerT>
|
||||
static ResultT
|
||||
do_(TupleT const &t, ScannerT const &scan)
|
||||
{
|
||||
typedef typename ::phoenix::tuple_element<index, TupleT>::type parser_t;
|
||||
typedef typename ScannerT::iterator_t iterator_t;
|
||||
typedef typename parser_result<parser_t, ScannerT>::type result_t;
|
||||
|
||||
iterator_t save(scan.first);
|
||||
result_t result(t[::phoenix::tuple_index<index>()].parse(scan));
|
||||
|
||||
if (result) {
|
||||
return scan.create_match(result.length(), TupleT::length - N,
|
||||
save, scan.first);
|
||||
}
|
||||
scan.first = save; // reset the input stream
|
||||
return parse_tuple_element<N-1, ResultT, TupleT, BehaviourT>::
|
||||
do_(t, scan);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ResultT, typename TupleT, typename BehaviourT>
|
||||
struct parse_tuple_element<1, ResultT, TupleT, BehaviourT> {
|
||||
|
||||
BOOST_STATIC_CONSTANT(int, index = (TupleT::length - 1));
|
||||
|
||||
template <typename ScannerT>
|
||||
static ResultT
|
||||
do_(TupleT const &t, ScannerT const &scan)
|
||||
{
|
||||
typedef typename ::phoenix::tuple_element<index, TupleT>::type parser_t;
|
||||
typedef typename ScannerT::iterator_t iterator_t;
|
||||
typedef typename parser_result<parser_t, ScannerT>::type result_t;
|
||||
|
||||
iterator_t save(scan.first);
|
||||
result_t result(t[::phoenix::tuple_index<index>()].parse(scan));
|
||||
|
||||
if (result) {
|
||||
return scan.create_match(result.length(), TupleT::length - 1,
|
||||
save, scan.first);
|
||||
}
|
||||
scan.first = save; // reset the input stream
|
||||
return select_match_gen<ResultT, BehaviourT>::do_(scan);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace impl
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif // BOOST_SPIRIT_SELECT_IPP
|
||||
@@ -0,0 +1,574 @@
|
||||
/*=============================================================================
|
||||
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_SWITCH_IPP
|
||||
#define BOOST_SPIRIT_SWITCH_IPP
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/inc.hpp>
|
||||
#include <boost/preprocessor/repeat.hpp>
|
||||
#include <boost/preprocessor/repeat_from_to.hpp>
|
||||
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/composite.hpp>
|
||||
#include <boost/spirit/home/classic/meta/as_parser.hpp>
|
||||
|
||||
#include <boost/spirit/home/classic/phoenix/actor.hpp>
|
||||
#include <boost/spirit/home/classic/phoenix/tuples.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
// forward declaration
|
||||
template <int N, typename ParserT, bool IsDefault> struct case_parser;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace impl {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// parse helper functions
|
||||
template <typename ParserT, typename ScannerT>
|
||||
inline typename parser_result<ParserT, ScannerT>::type
|
||||
delegate_parse(ParserT const &p, ScannerT const &scan,
|
||||
typename ScannerT::iterator_t const save)
|
||||
{
|
||||
typedef typename parser_result<ParserT, ScannerT>::type result_t;
|
||||
|
||||
result_t result (p.subject().parse(scan));
|
||||
if (!result)
|
||||
scan.first = save;
|
||||
return result;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// General default case handling (no default_p case branch given).
|
||||
// First try to match the current parser node (if the condition value is
|
||||
// matched) and, if that fails, return a no_match
|
||||
template <int N, bool IsDefault, bool HasDefault>
|
||||
struct default_delegate_parse {
|
||||
|
||||
template <
|
||||
typename ParserT, typename DefaultT,
|
||||
typename ValueT, typename ScannerT
|
||||
>
|
||||
static typename parser_result<ParserT, ScannerT>::type
|
||||
parse (ValueT const &value, ParserT const &p, DefaultT const &,
|
||||
ScannerT const &scan, typename ScannerT::iterator_t const save)
|
||||
{
|
||||
if (value == N)
|
||||
return delegate_parse(p, scan, save);
|
||||
return scan.no_match();
|
||||
}
|
||||
};
|
||||
|
||||
// The current case parser node is the default parser.
|
||||
// Ignore the given case value and try to match the given default parser.
|
||||
template <int N, bool HasDefault>
|
||||
struct default_delegate_parse<N, true, HasDefault> {
|
||||
|
||||
template <
|
||||
typename ParserT, typename DefaultT,
|
||||
typename ValueT, typename ScannerT
|
||||
>
|
||||
static typename parser_result<ParserT, ScannerT>::type
|
||||
parse (ValueT const& /*value*/, ParserT const &, DefaultT const &d,
|
||||
ScannerT const &scan, typename ScannerT::iterator_t const save)
|
||||
{
|
||||
// Since there is a default_p case branch defined, the corresponding
|
||||
// parser shouldn't be the nothing_parser
|
||||
BOOST_STATIC_ASSERT((!boost::is_same<DefaultT, nothing_parser>::value));
|
||||
return delegate_parse(d, scan, save);
|
||||
}
|
||||
};
|
||||
|
||||
// The current case parser node is not the default parser, but there is a
|
||||
// default_p branch given inside the switch_p parser.
|
||||
// First try to match the current parser node (if the condition value is
|
||||
// matched) and, if that fails, match the given default_p parser.
|
||||
template <int N>
|
||||
struct default_delegate_parse<N, false, true> {
|
||||
|
||||
template <
|
||||
typename ParserT, typename DefaultT,
|
||||
typename ValueT, typename ScannerT
|
||||
>
|
||||
static typename parser_result<ParserT, ScannerT>::type
|
||||
parse (ValueT const &value, ParserT const &p, DefaultT const &d,
|
||||
ScannerT const &scan, typename ScannerT::iterator_t const save)
|
||||
{
|
||||
// Since there is a default_p case branch defined, the corresponding
|
||||
// parser shouldn't be the nothing_parser
|
||||
BOOST_STATIC_ASSERT((!boost::is_same<DefaultT, nothing_parser>::value));
|
||||
if (value == N)
|
||||
return delegate_parse(p, scan, save);
|
||||
|
||||
return delegate_parse(d, scan, save);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Look through the case parser chain to test, if there is a default case
|
||||
// branch defined (returned by 'value').
|
||||
template <typename CaseT, bool IsSimple = CaseT::is_simple>
|
||||
struct default_case;
|
||||
|
||||
////////////////////////////////////////
|
||||
template <typename ResultT, bool IsDefault>
|
||||
struct get_default_parser {
|
||||
|
||||
template <typename ParserT>
|
||||
static ResultT
|
||||
get(parser<ParserT> const &p)
|
||||
{
|
||||
return default_case<typename ParserT::derived_t::left_t>::
|
||||
get(p.derived().left());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ResultT>
|
||||
struct get_default_parser<ResultT, true> {
|
||||
|
||||
template <typename ParserT>
|
||||
static ResultT
|
||||
get(parser<ParserT> const &p) { return p.derived().right(); }
|
||||
};
|
||||
|
||||
////////////////////////////////////////
|
||||
template <typename CaseT, bool IsSimple>
|
||||
struct default_case {
|
||||
|
||||
// The 'value' constant is true, if the current case_parser or one of its
|
||||
// left siblings is a default_p generated case_parser.
|
||||
BOOST_STATIC_CONSTANT(bool, value =
|
||||
(CaseT::is_default || default_case<typename CaseT::left_t>::value));
|
||||
|
||||
// The 'is_epsilon' constant is true, if the current case_parser or one of
|
||||
// its left siblings is a default_p generated parser with an attached
|
||||
// epsilon_p (this is generated by the plain default_p).
|
||||
BOOST_STATIC_CONSTANT(bool, is_epsilon = (
|
||||
(CaseT::is_default && CaseT::is_epsilon) ||
|
||||
default_case<typename CaseT::left_t>::is_epsilon
|
||||
));
|
||||
|
||||
// The computed 'type' represents the type of the default case branch
|
||||
// parser (if there is one) or nothing_parser (if there isn't any default
|
||||
// case branch).
|
||||
typedef typename boost::mpl::if_c<
|
||||
CaseT::is_default, typename CaseT::right_embed_t,
|
||||
typename default_case<typename CaseT::left_t>::type
|
||||
>::type type;
|
||||
|
||||
// The get function returns the parser attached to the default case branch
|
||||
// (if there is one) or an instance of a nothing_parser (if there isn't
|
||||
// any default case branch).
|
||||
template <typename ParserT>
|
||||
static type
|
||||
get(parser<ParserT> const &p)
|
||||
{ return get_default_parser<type, CaseT::is_default>::get(p); }
|
||||
};
|
||||
|
||||
////////////////////////////////////////
|
||||
template <typename ResultT, bool IsDefault>
|
||||
struct get_default_parser_simple {
|
||||
|
||||
template <typename ParserT>
|
||||
static ResultT
|
||||
get(parser<ParserT> const &p) { return p.derived(); }
|
||||
};
|
||||
|
||||
template <typename ResultT>
|
||||
struct get_default_parser_simple<ResultT, false> {
|
||||
|
||||
template <typename ParserT>
|
||||
static nothing_parser
|
||||
get(parser<ParserT> const &) { return nothing_p; }
|
||||
};
|
||||
|
||||
////////////////////////////////////////
|
||||
// Specialization of the default_case template for the last (leftmost) element
|
||||
// of the case parser chain.
|
||||
template <typename CaseT>
|
||||
struct default_case<CaseT, true> {
|
||||
|
||||
// The 'value' and 'is_epsilon' constant, the 'type' type and the function
|
||||
// 'get' are described above.
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, value = CaseT::is_default);
|
||||
BOOST_STATIC_CONSTANT(bool, is_epsilon = (
|
||||
CaseT::is_default && CaseT::is_epsilon
|
||||
));
|
||||
|
||||
typedef typename boost::mpl::if_c<
|
||||
CaseT::is_default, CaseT, nothing_parser
|
||||
>::type type;
|
||||
|
||||
template <typename ParserT>
|
||||
static type
|
||||
get(parser<ParserT> const &p)
|
||||
{ return get_default_parser_simple<type, value>::get(p); }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// The case_chain template calculates recursivly the depth of the left
|
||||
// subchain of the given case branch node.
|
||||
template <typename CaseT, bool IsSimple = CaseT::is_simple>
|
||||
struct case_chain {
|
||||
|
||||
BOOST_STATIC_CONSTANT(int, depth = (
|
||||
case_chain<typename CaseT::left_t>::depth + 1
|
||||
));
|
||||
};
|
||||
|
||||
template <typename CaseT>
|
||||
struct case_chain<CaseT, true> {
|
||||
|
||||
BOOST_STATIC_CONSTANT(int, depth = 0);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// The chain_parser template is used to extract the type and the instance of
|
||||
// a left or a right parser, burried arbitrary deep inside the case parser
|
||||
// chain.
|
||||
template <int Depth, typename CaseT>
|
||||
struct chain_parser {
|
||||
|
||||
typedef typename CaseT::left_t our_left_t;
|
||||
|
||||
typedef typename chain_parser<Depth-1, our_left_t>::left_t left_t;
|
||||
typedef typename chain_parser<Depth-1, our_left_t>::right_t right_t;
|
||||
|
||||
static left_t
|
||||
left(CaseT const &p)
|
||||
{ return chain_parser<Depth-1, our_left_t>::left(p.left()); }
|
||||
|
||||
static right_t
|
||||
right(CaseT const &p)
|
||||
{ return chain_parser<Depth-1, our_left_t>::right(p.left()); }
|
||||
};
|
||||
|
||||
template <typename CaseT>
|
||||
struct chain_parser<1, CaseT> {
|
||||
|
||||
typedef typename CaseT::left_t left_t;
|
||||
typedef typename CaseT::right_t right_t;
|
||||
|
||||
static left_t left(CaseT const &p) { return p.left(); }
|
||||
static right_t right(CaseT const &p) { return p.right(); }
|
||||
};
|
||||
|
||||
template <typename CaseT>
|
||||
struct chain_parser<0, CaseT>; // shouldn't be instantiated
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Type computing meta function for calculating the type of the return value
|
||||
// of the used conditional switch expression
|
||||
template <typename TargetT, typename ScannerT>
|
||||
struct condition_result {
|
||||
|
||||
typedef typename TargetT::template result<ScannerT>::type type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename LeftT, typename RightT, bool IsDefault>
|
||||
struct compound_case_parser
|
||||
: public binary<LeftT, RightT,
|
||||
parser<compound_case_parser<LeftT, RightT, IsDefault> > >
|
||||
{
|
||||
typedef compound_case_parser<LeftT, RightT, IsDefault> self_t;
|
||||
typedef binary_parser_category parser_category_t;
|
||||
typedef binary<LeftT, RightT, parser<self_t> > base_t;
|
||||
|
||||
BOOST_STATIC_CONSTANT(int, value = RightT::value);
|
||||
BOOST_STATIC_CONSTANT(bool, is_default = IsDefault);
|
||||
BOOST_STATIC_CONSTANT(bool, is_simple = false);
|
||||
BOOST_STATIC_CONSTANT(bool, is_epsilon = (
|
||||
is_default &&
|
||||
boost::is_same<typename RightT::subject_t, epsilon_parser>::value
|
||||
));
|
||||
|
||||
compound_case_parser(parser<LeftT> const &lhs, parser<RightT> const &rhs)
|
||||
: base_t(lhs.derived(), rhs.derived())
|
||||
{}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, nil_t>::type type;
|
||||
};
|
||||
|
||||
template <typename ScannerT, typename CondT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan, CondT const &cond) const;
|
||||
|
||||
template <int N1, typename ParserT1, bool IsDefault1>
|
||||
compound_case_parser<
|
||||
self_t, case_parser<N1, ParserT1, IsDefault1>, IsDefault1
|
||||
>
|
||||
operator, (case_parser<N1, ParserT1, IsDefault1> const &p) const
|
||||
{
|
||||
// If the following compile time assertion fires, you've probably used
|
||||
// more than one default_p case inside the switch_p parser construct.
|
||||
BOOST_STATIC_ASSERT(!default_case<self_t>::value || !IsDefault1);
|
||||
|
||||
// If this compile time assertion fires, you've probably want to use
|
||||
// more case_p/default_p case branches, than possible.
|
||||
BOOST_STATIC_ASSERT(
|
||||
case_chain<self_t>::depth < BOOST_SPIRIT_SWITCH_CASE_LIMIT
|
||||
);
|
||||
|
||||
typedef case_parser<N1, ParserT1, IsDefault1> right_t;
|
||||
return compound_case_parser<self_t, right_t, IsDefault1>(*this, p);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// The parse_switch::do_ functions dispatch to the correct parser, which is
|
||||
// selected through the given conditional switch value.
|
||||
template <int Value, int Depth, bool IsDefault>
|
||||
struct parse_switch;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The following generates a couple of parse_switch template specializations
|
||||
// with an increasing number of handled case branches (for 1..N).
|
||||
//
|
||||
// template <int Value, bool IsDefault>
|
||||
// struct parse_switch<Value, N, IsDefault> {
|
||||
//
|
||||
// template <typename ParserT, typename ScannerT>
|
||||
// static typename parser_result<ParserT, ScannerT>::type
|
||||
// do_(ParserT const &p, ScannerT const &scan, long cond_value,
|
||||
// typename ScannerT::iterator_t const &save)
|
||||
// {
|
||||
// typedef ParserT left_t0;
|
||||
// typedef typename left_t0::left left_t1;
|
||||
// ...
|
||||
//
|
||||
// switch (cond_value) {
|
||||
// case left_tN::value:
|
||||
// return delegate_parse(chain_parser<
|
||||
// case_chain<ParserT>::depth, ParserT
|
||||
// >::left(p), scan, save);
|
||||
// ...
|
||||
// case left_t1::value:
|
||||
// return delegate_parse(chain_parser<
|
||||
// 1, left_t1
|
||||
// >::right(p.left()), scan, save);
|
||||
//
|
||||
// case left_t0::value:
|
||||
// default:
|
||||
// typedef default_case<ParserT> default_t;
|
||||
// typedef default_delegate_parse<
|
||||
// Value, IsDefault, default_t::value>
|
||||
// default_parse_t;
|
||||
//
|
||||
// return default_parse_t::parse(cond_value, p.right(),
|
||||
// default_t::get(p), scan, save);
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS(z, N, _) \
|
||||
typedef typename BOOST_PP_CAT(left_t, N)::left_t \
|
||||
BOOST_PP_CAT(left_t, BOOST_PP_INC(N)); \
|
||||
/**/
|
||||
|
||||
#define BOOST_SPIRIT_PARSE_SWITCH_CASES(z, N, _) \
|
||||
case (long)(BOOST_PP_CAT(left_t, N)::value): \
|
||||
return delegate_parse(chain_parser<N, left_t1>::right(p.left()), \
|
||||
scan, save); \
|
||||
/**/
|
||||
|
||||
#define BOOST_SPIRIT_PARSE_SWITCHES(z, N, _) \
|
||||
template <int Value, bool IsDefault> \
|
||||
struct parse_switch<Value, BOOST_PP_INC(N), IsDefault> { \
|
||||
\
|
||||
template <typename ParserT, typename ScannerT> \
|
||||
static typename parser_result<ParserT, ScannerT>::type \
|
||||
do_(ParserT const &p, ScannerT const &scan, long cond_value, \
|
||||
typename ScannerT::iterator_t const &save) \
|
||||
{ \
|
||||
typedef ParserT left_t0; \
|
||||
BOOST_PP_REPEAT_FROM_TO_ ## z(0, BOOST_PP_INC(N), \
|
||||
BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS, _) \
|
||||
\
|
||||
switch (cond_value) { \
|
||||
case (long)(BOOST_PP_CAT(left_t, BOOST_PP_INC(N))::value): \
|
||||
return delegate_parse( \
|
||||
chain_parser< \
|
||||
case_chain<ParserT>::depth, ParserT \
|
||||
>::left(p), scan, save); \
|
||||
\
|
||||
BOOST_PP_REPEAT_FROM_TO_ ## z(1, BOOST_PP_INC(N), \
|
||||
BOOST_SPIRIT_PARSE_SWITCH_CASES, _) \
|
||||
\
|
||||
case (long)(left_t0::value): \
|
||||
default: \
|
||||
typedef default_case<ParserT> default_t; \
|
||||
typedef \
|
||||
default_delegate_parse<Value, IsDefault, default_t::value> \
|
||||
default_parse_t; \
|
||||
\
|
||||
return default_parse_t::parse(cond_value, p.right(), \
|
||||
default_t::get(p), scan, save); \
|
||||
} \
|
||||
} \
|
||||
}; \
|
||||
/**/
|
||||
|
||||
BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_SPIRIT_SWITCH_CASE_LIMIT),
|
||||
BOOST_SPIRIT_PARSE_SWITCHES, _)
|
||||
|
||||
#undef BOOST_SPIRIT_PARSE_SWITCH_TYPEDEFS
|
||||
#undef BOOST_SPIRIT_PARSE_SWITCH_CASES
|
||||
#undef BOOST_SPIRIT_PARSE_SWITCHES
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename LeftT, typename RightT, bool IsDefault>
|
||||
template <typename ScannerT, typename CondT>
|
||||
inline typename parser_result<
|
||||
compound_case_parser<LeftT, RightT, IsDefault>, ScannerT
|
||||
>::type
|
||||
compound_case_parser<LeftT, RightT, IsDefault>::
|
||||
parse(ScannerT const& scan, CondT const &cond) const
|
||||
{
|
||||
scan.at_end(); // allow skipper to take effect
|
||||
return parse_switch<value, case_chain<self_t>::depth, is_default>::
|
||||
do_(*this, scan, cond(scan), scan.first);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// The switch condition is to be evaluated from a parser result value.
|
||||
template <typename ParserT>
|
||||
struct cond_functor {
|
||||
|
||||
typedef cond_functor<ParserT> self_t;
|
||||
|
||||
cond_functor(ParserT const &p_)
|
||||
: p(p_)
|
||||
{}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename parser_result<ParserT, ScannerT>::type::attr_t type;
|
||||
};
|
||||
|
||||
template <typename ScannerT>
|
||||
typename condition_result<self_t, ScannerT>::type
|
||||
operator()(ScannerT const &scan) const
|
||||
{
|
||||
typedef typename parser_result<ParserT, ScannerT>::type result_t;
|
||||
typedef typename result_t::attr_t attr_t;
|
||||
|
||||
result_t result(p.parse(scan));
|
||||
return !result ? attr_t() : result.value();
|
||||
}
|
||||
|
||||
typename ParserT::embed_t p;
|
||||
};
|
||||
|
||||
template <typename ParserT>
|
||||
struct make_cond_functor {
|
||||
|
||||
typedef as_parser<ParserT> as_parser_t;
|
||||
|
||||
static cond_functor<typename as_parser_t::type>
|
||||
do_(ParserT const &cond)
|
||||
{
|
||||
return cond_functor<typename as_parser_t::type>(
|
||||
as_parser_t::convert(cond));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// The switch condition is to be evaluated from a phoenix actor
|
||||
template <typename ActorT>
|
||||
struct cond_actor {
|
||||
|
||||
typedef cond_actor<ActorT> self_t;
|
||||
|
||||
cond_actor(ActorT const &actor_)
|
||||
: actor(actor_)
|
||||
{}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename ::phoenix::actor_result<ActorT, ::phoenix::tuple<> >::type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename ScannerT>
|
||||
typename condition_result<self_t, ScannerT>::type
|
||||
operator()(ScannerT const& /*scan*/) const
|
||||
{
|
||||
return actor();
|
||||
}
|
||||
|
||||
ActorT const &actor;
|
||||
};
|
||||
|
||||
template <typename ActorT>
|
||||
struct make_cond_functor< ::phoenix::actor<ActorT> > {
|
||||
|
||||
static cond_actor< ::phoenix::actor<ActorT> >
|
||||
do_(::phoenix::actor<ActorT> const &actor)
|
||||
{
|
||||
return cond_actor< ::phoenix::actor<ActorT> >(actor);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// The switch condition is to be taken directly from the input stream
|
||||
struct get_next_token_cond {
|
||||
|
||||
typedef get_next_token_cond self_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename ScannerT::value_t type;
|
||||
};
|
||||
|
||||
template <typename ScannerT>
|
||||
typename condition_result<self_t, ScannerT>::type
|
||||
operator()(ScannerT const &scan) const
|
||||
{
|
||||
typename ScannerT::value_t val(*scan);
|
||||
++scan.first;
|
||||
return val;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct make_cond_functor<get_next_token_cond> {
|
||||
|
||||
static get_next_token_cond
|
||||
do_(get_next_token_cond const &cond)
|
||||
{
|
||||
return cond;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace impl
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif // BOOST_SPIRIT_SWITCH_IPP
|
||||
@@ -0,0 +1,66 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Joel de Guzman
|
||||
Copyright (c) 2003 Vaclav Vesely
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_LAZY_HPP
|
||||
#define BOOST_SPIRIT_LAZY_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/phoenix/actor.hpp>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// lazy_parser, holds phoenix actor which returns a spirit parser.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class ActorT>
|
||||
struct lazy_parser : parser<lazy_parser<ActorT> >
|
||||
{
|
||||
typedef lazy_parser<ActorT> self_t;
|
||||
typedef typename ::phoenix::actor_result<
|
||||
ActorT, ::phoenix::tuple<> >::plain_type actor_result_t;
|
||||
|
||||
template<typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename
|
||||
parser_result<actor_result_t, ScannerT>::type
|
||||
type;
|
||||
};
|
||||
|
||||
lazy_parser(ActorT const& actor_)
|
||||
: actor(actor_) {}
|
||||
|
||||
template<typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{ return actor().parse(scan); }
|
||||
|
||||
ActorT actor;
|
||||
};
|
||||
|
||||
//////////////////////////////
|
||||
// lazy_p, returns lazy_parser
|
||||
// Usage: lazy_p(actor)
|
||||
template<class ActorT>
|
||||
lazy_parser<ActorT> lazy_p(ActorT const& actor)
|
||||
{ return lazy_parser<ActorT>(actor); }
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif // BOOST_SPIRIT_LAZY_HPP
|
||||
@@ -0,0 +1,76 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_RULE_ALIAS_HPP)
|
||||
#define BOOST_SPIRIT_RULE_ALIAS_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// rule_alias class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename ParserT>
|
||||
class rule_alias :
|
||||
public parser<rule_alias<ParserT> >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef rule_alias<ParserT> self_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename parser_result<ParserT, ScannerT>::type type;
|
||||
};
|
||||
|
||||
rule_alias()
|
||||
: ptr(0) {}
|
||||
|
||||
rule_alias(ParserT const& p)
|
||||
: ptr(&p) {}
|
||||
|
||||
rule_alias&
|
||||
operator=(ParserT const& p)
|
||||
{
|
||||
ptr = &p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<ParserT, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
if (ptr)
|
||||
return ptr->parse(scan);
|
||||
else
|
||||
return scan.no_match();
|
||||
}
|
||||
|
||||
ParserT const&
|
||||
get() const
|
||||
{
|
||||
BOOST_ASSERT(ptr != 0);
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
ParserT const* ptr; // hold it by pointer
|
||||
};
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,245 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_SELECT_HPP
|
||||
#define BOOST_SPIRIT_SELECT_HPP
|
||||
|
||||
#include <boost/preprocessor/repeat.hpp>
|
||||
#include <boost/preprocessor/enum.hpp>
|
||||
#include <boost/preprocessor/enum_params.hpp>
|
||||
#include <boost/preprocessor/enum_params_with_defaults.hpp>
|
||||
#include <boost/preprocessor/inc.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/facilities/intercept.hpp>
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
|
||||
#include <boost/spirit/home/classic/phoenix/tuples.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Spirit predefined maximum number of possible embedded select_p parsers.
|
||||
// It should NOT be greater than PHOENIX_LIMIT!
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(BOOST_SPIRIT_SELECT_LIMIT)
|
||||
#define BOOST_SPIRIT_SELECT_LIMIT PHOENIX_LIMIT
|
||||
#endif // !defined(BOOST_SPIRIT_SELECT_LIMIT)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ensure BOOST_SPIRIT_SELECT_LIMIT <= PHOENIX_LIMIT and
|
||||
// BOOST_SPIRIT_SELECT_LIMIT > 0
|
||||
// BOOST_SPIRIT_SELECT_LIMIT <= 15
|
||||
//
|
||||
// [Pushed this down a little to make CW happy with BOOST_STATIC_ASSERT]
|
||||
// [Otherwise, it complains: 'boost_static_assert_test_42' redefined]
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_STATIC_ASSERT(BOOST_SPIRIT_SELECT_LIMIT <= PHOENIX_LIMIT);
|
||||
BOOST_STATIC_ASSERT(BOOST_SPIRIT_SELECT_LIMIT > 0);
|
||||
BOOST_STATIC_ASSERT(BOOST_SPIRIT_SELECT_LIMIT <= 15);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculate the required amount of tuple members rounded up to the nearest
|
||||
// integer dividable by 3
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if BOOST_SPIRIT_SELECT_LIMIT > 12
|
||||
#define BOOST_SPIRIT_SELECT_LIMIT_A 15
|
||||
#elif BOOST_SPIRIT_SELECT_LIMIT > 9
|
||||
#define BOOST_SPIRIT_SELECT_LIMIT_A 12
|
||||
#elif BOOST_SPIRIT_SELECT_LIMIT > 6
|
||||
#define BOOST_SPIRIT_SELECT_LIMIT_A 9
|
||||
#elif BOOST_SPIRIT_SELECT_LIMIT > 3
|
||||
#define BOOST_SPIRIT_SELECT_LIMIT_A 6
|
||||
#else
|
||||
#define BOOST_SPIRIT_SELECT_LIMIT_A 3
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The select_default_no_fail and select_default_fail structs are used to
|
||||
// distinguish two different behaviours for the select_parser in case that not
|
||||
// any of the given sub-parsers match.
|
||||
//
|
||||
// If the select_parser is used with the select_default_no_fail behaviour,
|
||||
// then in case of no matching sub-parser the whole select_parser returns an
|
||||
// empty match and the value -1.
|
||||
//
|
||||
// If the select_parser is used with the select_default_fail behaviour, then
|
||||
// in case of no matching sub-parser the whole select_parser fails to match at
|
||||
// all.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct select_default_no_fail {};
|
||||
struct select_default_fail {};
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/spirit/home/classic/dynamic/impl/select.ipp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename TupleT, typename BehaviourT, typename T>
|
||||
struct select_parser
|
||||
: public parser<select_parser<TupleT, BehaviourT, T> >
|
||||
{
|
||||
typedef select_parser<TupleT, BehaviourT, T> self_t;
|
||||
|
||||
select_parser(TupleT const &t_)
|
||||
: t(t_)
|
||||
{}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, T>::type type;
|
||||
};
|
||||
|
||||
template <typename ScannerT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
typedef typename parser_result<self_t, ScannerT>::type result_t;
|
||||
|
||||
if (!scan.at_end()) {
|
||||
return impl::parse_tuple_element<
|
||||
TupleT::length, result_t, TupleT, BehaviourT>::do_(t, scan);
|
||||
}
|
||||
return impl::select_match_gen<result_t, BehaviourT>::do_(scan);
|
||||
}
|
||||
|
||||
TupleT const t;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename BehaviourT, typename T = int>
|
||||
struct select_parser_gen {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// This generates different select_parser_gen::operator()() functions with
|
||||
// an increasing number of parser parameters:
|
||||
//
|
||||
// template <typename ParserT0, ...>
|
||||
// select_parser<
|
||||
// ::phoenix::tuple<
|
||||
// typename impl::as_embedded_parser<ParserT0>::type,
|
||||
// ...
|
||||
// >,
|
||||
// BehaviourT,
|
||||
// T
|
||||
// >
|
||||
// operator()(ParserT0 const &p0, ...) const
|
||||
// {
|
||||
// typedef impl::as_embedded_parser<ParserT0> parser_t0;
|
||||
// ...
|
||||
//
|
||||
// typedef ::phoenix::tuple<
|
||||
// parser_t0::type,
|
||||
// ...
|
||||
// > tuple_t;
|
||||
// typedef select_parser<tuple_t, BehaviourT, T> result_t;
|
||||
//
|
||||
// return result_t(tuple_t(
|
||||
// parser_t0::convert(p0),
|
||||
// ...
|
||||
// ));
|
||||
// }
|
||||
//
|
||||
// The number of generated functions depends on the maximum tuple member
|
||||
// limit defined by the PHOENIX_LIMIT pp constant.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_SPIRIT_SELECT_EMBEDDED(z, N, _) \
|
||||
typename impl::as_embedded_parser<BOOST_PP_CAT(ParserT, N)>::type \
|
||||
/**/
|
||||
#define BOOST_SPIRIT_SELECT_EMBEDDED_TYPEDEF(z, N, _) \
|
||||
typedef impl::as_embedded_parser<BOOST_PP_CAT(ParserT, N)> \
|
||||
BOOST_PP_CAT(parser_t, N); \
|
||||
/**/
|
||||
#define BOOST_SPIRIT_SELECT_CONVERT(z, N, _) \
|
||||
BOOST_PP_CAT(parser_t, N)::convert(BOOST_PP_CAT(p, N)) \
|
||||
/**/
|
||||
|
||||
#define BOOST_SPIRIT_SELECT_PARSER(z, N, _) \
|
||||
template < \
|
||||
BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename ParserT) \
|
||||
> \
|
||||
select_parser< \
|
||||
::phoenix::tuple< \
|
||||
BOOST_PP_ENUM_ ## z(BOOST_PP_INC(N), \
|
||||
BOOST_SPIRIT_SELECT_EMBEDDED, _) \
|
||||
>, \
|
||||
BehaviourT, \
|
||||
T \
|
||||
> \
|
||||
operator()( \
|
||||
BOOST_PP_ENUM_BINARY_PARAMS_Z(z, BOOST_PP_INC(N), \
|
||||
ParserT, const &p) \
|
||||
) const \
|
||||
{ \
|
||||
BOOST_PP_REPEAT_ ## z(BOOST_PP_INC(N), \
|
||||
BOOST_SPIRIT_SELECT_EMBEDDED_TYPEDEF, _) \
|
||||
\
|
||||
typedef ::phoenix::tuple< \
|
||||
BOOST_PP_ENUM_BINARY_PARAMS_Z(z, BOOST_PP_INC(N), \
|
||||
typename parser_t, ::type BOOST_PP_INTERCEPT) \
|
||||
> tuple_t; \
|
||||
typedef select_parser<tuple_t, BehaviourT, T> result_t; \
|
||||
\
|
||||
return result_t(tuple_t( \
|
||||
BOOST_PP_ENUM_ ## z(BOOST_PP_INC(N), \
|
||||
BOOST_SPIRIT_SELECT_CONVERT, _) \
|
||||
)); \
|
||||
} \
|
||||
/**/
|
||||
|
||||
BOOST_PP_REPEAT(BOOST_SPIRIT_SELECT_LIMIT_A,
|
||||
BOOST_SPIRIT_SELECT_PARSER, _)
|
||||
|
||||
#undef BOOST_SPIRIT_SELECT_PARSER
|
||||
#undef BOOST_SPIRIT_SELECT_CONVERT
|
||||
#undef BOOST_SPIRIT_SELECT_EMBEDDED_TYPEDEF
|
||||
#undef BOOST_SPIRIT_SELECT_EMBEDDED
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Predefined parser generator helper objects
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
select_parser_gen<select_default_no_fail> const select_p =
|
||||
select_parser_gen<select_default_no_fail>();
|
||||
|
||||
select_parser_gen<select_default_fail> const select_fail_p =
|
||||
select_parser_gen<select_default_fail>();
|
||||
|
||||
#undef BOOST_SPIRIT_SELECT_LIMIT_A
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif // BOOST_SPIRIT_SELECT_HPP
|
||||
@@ -0,0 +1,127 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 1998-2003 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_STORED_RULE_HPP)
|
||||
#define BOOST_SPIRIT_STORED_RULE_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/non_terminal/impl/rule.ipp>
|
||||
#include <boost/spirit/home/classic/dynamic/rule_alias.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <boost/spirit/home/classic/dynamic/stored_rule_fwd.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// stored_rule class
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename T0
|
||||
, typename T1
|
||||
, typename T2
|
||||
, bool EmbedByValue
|
||||
>
|
||||
class stored_rule
|
||||
: public impl::rule_base<
|
||||
stored_rule<T0, T1, T2, EmbedByValue>
|
||||
, typename mpl::if_c<
|
||||
EmbedByValue
|
||||
, stored_rule<T0, T1, T2, true>
|
||||
, stored_rule<T0, T1, T2> const&>::type
|
||||
, T0, T1, T2>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef stored_rule<T0, T1, T2, EmbedByValue> self_t;
|
||||
typedef impl::rule_base<
|
||||
self_t
|
||||
, typename mpl::if_c<
|
||||
EmbedByValue
|
||||
, stored_rule<T0, T1, T2, true>
|
||||
, self_t const&>::type
|
||||
, T0, T1, T2>
|
||||
base_t;
|
||||
|
||||
typedef typename base_t::scanner_t scanner_t;
|
||||
typedef typename base_t::attr_t attr_t;
|
||||
typedef impl::abstract_parser<scanner_t, attr_t> abstract_parser_t;
|
||||
typedef rule_alias<self_t> alias_t;
|
||||
|
||||
stored_rule() : ptr() {}
|
||||
~stored_rule() {}
|
||||
|
||||
stored_rule(stored_rule const& r)
|
||||
: ptr(r.ptr) {}
|
||||
|
||||
template <typename ParserT>
|
||||
stored_rule(ParserT const& p)
|
||||
: ptr(new impl::concrete_parser<ParserT, scanner_t, attr_t>(p)) {}
|
||||
|
||||
template <typename ParserT>
|
||||
stored_rule& operator=(ParserT const& p)
|
||||
{
|
||||
ptr.reset(new impl::concrete_parser<ParserT, scanner_t, attr_t>(p));
|
||||
return *this;
|
||||
}
|
||||
|
||||
stored_rule& operator=(stored_rule const& r)
|
||||
{
|
||||
// If this is placed above the templatized assignment
|
||||
// operator, VC6 incorrectly complains ambiguity with
|
||||
// r1 = r2, where r1 and r2 are both rules.
|
||||
ptr = r.ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
stored_rule<T0, T1, T2, true>
|
||||
copy() const
|
||||
{
|
||||
return stored_rule<T0, T1, T2, true>(ptr);
|
||||
}
|
||||
|
||||
alias_t
|
||||
alias() const
|
||||
{
|
||||
return alias_t(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
friend class impl::rule_base_access;
|
||||
friend class stored_rule<T0, T1, T2, !EmbedByValue>;
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
||||
public:
|
||||
#endif
|
||||
abstract_parser_t*
|
||||
get() const
|
||||
{
|
||||
return ptr.get();
|
||||
}
|
||||
#if defined(__GNUC__) && (__GNUC__ < 3)
|
||||
private:
|
||||
#endif
|
||||
|
||||
stored_rule(shared_ptr<abstract_parser_t> const& ptr)
|
||||
: ptr(ptr) {}
|
||||
|
||||
shared_ptr<abstract_parser_t> ptr;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2006 Tobias Schwinger
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_STORED_RULE_FWD_HPP)
|
||||
#define BOOST_SPIRIT_STORED_RULE_FWD_HPP
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/nil.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
template <
|
||||
typename T0 = nil_t
|
||||
, typename T1 = nil_t
|
||||
, typename T2 = nil_t
|
||||
, bool EmbedByValue = false
|
||||
>
|
||||
class stored_rule;
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2003 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_SWITCH_HPP
|
||||
#define BOOST_SPIRIT_SWITCH_HPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The default_p parser generator template uses the following magic number
|
||||
// as the corresponding case label value inside the generated switch()
|
||||
// statements. If this number conflicts with your code, please pick a
|
||||
// different one.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(BOOST_SPIRIT_DEFAULTCASE_MAGIC)
|
||||
#define BOOST_SPIRIT_DEFAULTCASE_MAGIC 0x15F97A7
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Spirit predefined maximum number of possible case_p/default_p case branch
|
||||
// parsers.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(BOOST_SPIRIT_SWITCH_CASE_LIMIT)
|
||||
#define BOOST_SPIRIT_SWITCH_CASE_LIMIT 3
|
||||
#endif // !defined(BOOST_SPIRIT_SWITCH_CASE_LIMIT)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Ensure BOOST_SPIRIT_SELECT_LIMIT > 0
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_STATIC_ASSERT(BOOST_SPIRIT_SWITCH_CASE_LIMIT > 0);
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/config.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/spirit/home/classic/core/parser.hpp>
|
||||
#include <boost/spirit/home/classic/core/composite/epsilon.hpp>
|
||||
#include <boost/spirit/home/classic/dynamic/impl/switch.ipp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The switch_parser allows to build switch like parsing constructs, which
|
||||
// will have much better perfomance as comparable straight solutions.
|
||||
//
|
||||
// Input stream driven syntax:
|
||||
//
|
||||
// switch_p
|
||||
// [
|
||||
// case_p<'a'>
|
||||
// (...parser to use, if the next character is 'a'...),
|
||||
// case_p<'b'>
|
||||
// (...parser to use, if the next character is 'b'...),
|
||||
// default_p
|
||||
// (...parser to use, if nothing was matched before...)
|
||||
// ]
|
||||
//
|
||||
// General syntax:
|
||||
//
|
||||
// switch_p(...lazy expression returning the switch condition value...)
|
||||
// [
|
||||
// case_p<1>
|
||||
// (...parser to use, if the switch condition value is 1...),
|
||||
// case_p<2>
|
||||
// (...parser to use, if the switch condition value is 2...),
|
||||
// default_p
|
||||
// (...parser to use, if nothing was matched before...)
|
||||
// ]
|
||||
//
|
||||
// The maximum number of possible case_p branches is defined by the p constant
|
||||
// BOOST_SPIRIT_SWITCH_CASE_LIMIT (this value defaults to 3 if not otherwise
|
||||
// defined).
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CaseT, typename CondT = impl::get_next_token_cond>
|
||||
struct switch_parser
|
||||
: public unary<CaseT, parser<switch_parser<CaseT, CondT> > >
|
||||
{
|
||||
typedef switch_parser<CaseT, CondT> self_t;
|
||||
typedef unary_parser_category parser_category_t;
|
||||
typedef unary<CaseT, parser<self_t> > base_t;
|
||||
|
||||
switch_parser(CaseT const &case_)
|
||||
: base_t(case_), cond(CondT())
|
||||
{}
|
||||
|
||||
switch_parser(CaseT const &case_, CondT const &cond_)
|
||||
: base_t(case_), cond(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
|
||||
{
|
||||
return this->subject().parse(scan,
|
||||
impl::make_cond_functor<CondT>::do_(cond));
|
||||
}
|
||||
|
||||
CondT cond;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename CondT>
|
||||
struct switch_cond_parser
|
||||
{
|
||||
switch_cond_parser(CondT const &cond_)
|
||||
: cond(cond_)
|
||||
{}
|
||||
|
||||
template <typename ParserT>
|
||||
switch_parser<ParserT, CondT>
|
||||
operator[](parser<ParserT> const &p) const
|
||||
{
|
||||
return switch_parser<ParserT, CondT>(p.derived(), cond);
|
||||
}
|
||||
|
||||
CondT const &cond;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <int N, typename ParserT, bool IsDefault>
|
||||
struct case_parser
|
||||
: public unary<ParserT, parser<case_parser<N, ParserT, IsDefault> > >
|
||||
{
|
||||
typedef case_parser<N, ParserT, IsDefault> self_t;
|
||||
typedef unary_parser_category parser_category_t;
|
||||
typedef unary<ParserT, parser<self_t> > base_t;
|
||||
|
||||
typedef typename base_t::subject_t self_subject_t;
|
||||
|
||||
BOOST_STATIC_CONSTANT(int, value = N);
|
||||
BOOST_STATIC_CONSTANT(bool, is_default = IsDefault);
|
||||
BOOST_STATIC_CONSTANT(bool, is_simple = true);
|
||||
BOOST_STATIC_CONSTANT(bool, is_epsilon = (
|
||||
is_default && boost::is_same<self_subject_t, epsilon_parser>::value
|
||||
));
|
||||
|
||||
case_parser(parser<ParserT> const &p)
|
||||
: base_t(p.derived())
|
||||
{}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct result
|
||||
{
|
||||
typedef typename match_result<ScannerT, nil_t>::type type;
|
||||
};
|
||||
|
||||
template <typename ScannerT, typename CondT>
|
||||
typename parser_result<self_t, ScannerT>::type
|
||||
parse(ScannerT const& scan, CondT const &cond) const
|
||||
{
|
||||
typedef impl::default_case<self_t> default_t;
|
||||
|
||||
if (!scan.at_end()) {
|
||||
typedef impl::default_delegate_parse<
|
||||
value, is_default, default_t::value> default_parse_t;
|
||||
|
||||
typename ScannerT::iterator_t const save(scan.first);
|
||||
return default_parse_t::parse(cond(scan), *this,
|
||||
*this, scan, save);
|
||||
}
|
||||
|
||||
return default_t::is_epsilon ? scan.empty_match() : scan.no_match();
|
||||
}
|
||||
|
||||
template <int N1, typename ParserT1, bool IsDefault1>
|
||||
impl::compound_case_parser<
|
||||
self_t, case_parser<N1, ParserT1, IsDefault1>, IsDefault1
|
||||
>
|
||||
operator, (case_parser<N1, ParserT1, IsDefault1> const &p) const
|
||||
{
|
||||
// If the following compile time assertion fires, you've probably used
|
||||
// more than one default_p case inside the switch_p parser construct.
|
||||
BOOST_STATIC_ASSERT(!is_default || !IsDefault1);
|
||||
|
||||
typedef case_parser<N1, ParserT1, IsDefault1> right_t;
|
||||
return impl::compound_case_parser<self_t, right_t, IsDefault1>(*this, p);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct switch_parser_gen {
|
||||
|
||||
// This generates a switch parser, which is driven by the condition value
|
||||
// returned by the lazy parameter expression 'cond'. This may be a parser,
|
||||
// which result is used or a phoenix actor, which will be dereferenced to
|
||||
// obtain the switch condition value.
|
||||
template <typename CondT>
|
||||
switch_cond_parser<CondT>
|
||||
operator()(CondT const &cond) const
|
||||
{
|
||||
return switch_cond_parser<CondT>(cond);
|
||||
}
|
||||
|
||||
// This generates a switch parser, which is driven by the next character/token
|
||||
// found in the input stream.
|
||||
template <typename CaseT>
|
||||
switch_parser<CaseT>
|
||||
operator[](parser<CaseT> const &p) const
|
||||
{
|
||||
return switch_parser<CaseT>(p.derived());
|
||||
}
|
||||
};
|
||||
|
||||
switch_parser_gen const switch_p = switch_parser_gen();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <int N, typename ParserT>
|
||||
inline case_parser<N, ParserT, false>
|
||||
case_p(parser<ParserT> const &p)
|
||||
{
|
||||
return case_parser<N, ParserT, false>(p);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct default_parser_gen
|
||||
: public case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, epsilon_parser, true>
|
||||
{
|
||||
default_parser_gen()
|
||||
: case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, epsilon_parser, true>
|
||||
(epsilon_p)
|
||||
{}
|
||||
|
||||
template <typename ParserT>
|
||||
case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, ParserT, true>
|
||||
operator()(parser<ParserT> const &p) const
|
||||
{
|
||||
return case_parser<BOOST_SPIRIT_DEFAULTCASE_MAGIC, ParserT, true>(p);
|
||||
}
|
||||
};
|
||||
|
||||
default_parser_gen const default_p = default_parser_gen();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
#endif // BOOST_SPIRIT_SWITCH_HPP
|
||||
@@ -0,0 +1,89 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2006 Tobias Schwinger
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_DYNAMIC_TYPEOF_HPP)
|
||||
#define BOOST_SPIRIT_DYNAMIC_TYPEOF_HPP
|
||||
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
#include <boost/spirit/home/classic/namespace.hpp>
|
||||
#include <boost/spirit/home/classic/core/typeof.hpp>
|
||||
|
||||
#include <boost/spirit/home/classic/dynamic/stored_rule_fwd.hpp>
|
||||
|
||||
namespace boost { namespace spirit {
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
|
||||
|
||||
// if.hpp
|
||||
template <class ParsableT, typename CondT> struct if_parser;
|
||||
template <class ParsableTrueT, class ParsableFalseT, typename CondT>
|
||||
struct if_else_parser;
|
||||
|
||||
// for.hpp
|
||||
namespace impl {
|
||||
template<typename InitF, typename CondT, typename StepF, class ParsableT>
|
||||
struct for_parser;
|
||||
}
|
||||
|
||||
// while.hpp
|
||||
template<typename ParsableT, typename CondT, bool is_do_parser>
|
||||
struct while_parser;
|
||||
|
||||
// lazy.hpp
|
||||
template<typename ActorT> struct lazy_parser;
|
||||
|
||||
// rule_alias.hpp
|
||||
template <typename ParserT> class rule_alias;
|
||||
|
||||
// switch.hpp
|
||||
template <typename CaseT, typename CondT> struct switch_parser;
|
||||
template <int N, class ParserT, bool IsDefault> struct case_parser;
|
||||
|
||||
// select.hpp
|
||||
template <typename TupleT, typename BehaviourT, typename T>
|
||||
struct select_parser;
|
||||
|
||||
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
|
||||
|
||||
}} // namespace BOOST_SPIRIT_CLASSIC_NS
|
||||
|
||||
|
||||
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
|
||||
|
||||
// if.hpp
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::if_parser,2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::if_else_parser,3)
|
||||
|
||||
// for.hpp
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::impl::for_parser,4)
|
||||
|
||||
// while.hpp
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::while_parser,(class)(class)(bool))
|
||||
|
||||
// lazy.hpp
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::lazy_parser,1)
|
||||
|
||||
// stored_rule.hpp (has forward header)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::stored_rule,(typename)(typename)(typename)(bool))
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::stored_rule,3)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::stored_rule,2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::stored_rule,1)
|
||||
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::stored_rule<>)
|
||||
|
||||
// rule_alias.hpp
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::rule_alias,1)
|
||||
|
||||
// switch.hpp
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::switch_parser,2)
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::case_parser,(int)(class)(bool))
|
||||
|
||||
// select.hpp
|
||||
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::select_parser,3)
|
||||
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user