1
0
mirror of https://git.suyu.dev/suyu/suyu synced 2025-09-18 12:08:00 -05:00

Initial commit

This commit is contained in:
Crimson-Hawk
2024-03-05 16:42:40 +08:00
commit f1e4595ebf
39576 changed files with 7006612 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
/*=============================================================================
Copyright (c) 2001-2008 Joel de Guzman
Copyright (c) 2001-2008 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_DEPRECATED_INCLUDE_SPIRIT
#define BOOST_SPIRIT_DEPRECATED_INCLUDE_SPIRIT
#include <boost/version.hpp>
#if BOOST_VERSION >= 103800
#if defined(_MSC_VER) || defined(__BORLANDC__) && !defined(__clang__) || defined(__DMC__)
# pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic.hpp")
#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__) || defined(__BORLANDC__)
# warning "This header is deprecated. Please use: boost/spirit/include/classic.hpp"
#endif
#endif
#if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
#define BOOST_SPIRIT_USE_OLD_NAMESPACE
#endif
#include <boost/spirit/include/classic.hpp>
#endif

View File

@@ -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

View File

@@ -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 directly 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

View File

@@ -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 assignment 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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,36 @@
/*=============================================================================
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
///////////////////////////////////////////////////////////////////////////////
//
// 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)
#include <boost/throw_exception.hpp>
#define BOOST_SPIRIT_ASSERT_AUX(f, l, x) BOOST_SPIRIT_ASSERT_AUX2(f, l, x)
#define BOOST_SPIRIT_ASSERT_AUX2(f, l, x) \
( (x) ? (void)0 : boost::throw_exception( \
BOOST_SPIRIT_ASSERT_EXCEPTION(f "(" #l "): " #x)) )
#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

View File

@@ -0,0 +1,137 @@
/*=============================================================================
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>
#include <boost/core/ignore_unused.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;
ignore_unused(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

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View File

@@ -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

View File

@@ -0,0 +1,285 @@
/*=============================================================================
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>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4800) // forcing value to bool 'true' or 'false'
#endif
////////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
//
// condition_parser class
//
// handles expressions 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 expression 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
#ifdef BOOST_MSVC
# pragma warning (pop)
#endif
#endif

View File

@@ -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>

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,210 @@
/*=============================================================================
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);
}
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()));
}
};
}
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace boost::spirit
#endif

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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)

View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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(BOOST_BORLANDC) && (BOOST_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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,195 @@
/*=============================================================================
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/add_reference.hpp>
#include <boost/type_traits/conditional.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
// unsuccessful.
//
// 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> >
{
typedef typename
conditional<
is_reference<T>::value
, T
, typename add_reference<
typename add_const<T>::type
>::type
>::type attr_ref_t;
public:
typedef typename boost::optional<T> optional_type;
typedef attr_ref_t ctor_param_t;
typedef attr_ref_t 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>

View File

@@ -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

View File

@@ -0,0 +1,84 @@
/*=============================================================================
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_STATE
#endif

View File

@@ -0,0 +1,365 @@
/*=============================================================================
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 <boost/move/unique_ptr.hpp>
#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>
#include <boost/thread/lock_types.hpp>
#endif
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
template <typename DerivedT, typename ContextT>
struct grammar;
//////////////////////////////////
template <typename GrammarT, typename ScannerT>
struct grammar_definition
{
typedef typename GrammarT::template definition<ScannerT> type;
};
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)
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 =
grammartract_helper_list::do_(target_grammar);
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];
boost::movelib::unique_ptr<definition_t>
result(new definition_t(target_grammar->derived()));
#ifdef BOOST_SPIRIT_THREADSAFE
boost::unique_lock<boost::mutex> lock(helpers.mutex());
#endif
helpers.push_back(this);
++definitions_cnt;
definitions[id] = result.get();
return *(result.release());
}
int
undefine(grammar_t* target_grammar) BOOST_OVERRIDE
{
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
}
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);
}
};
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 grammar_helper_list<GrammarT> helper_list_t;
helper_list_t& helpers =
grammartract_helper_list::do_(self);
typedef typename helper_list_t::vector_t::reverse_iterator iterator_t;
for (iterator_t i = helpers.rbegin(); i != helpers.rend(); ++i)
(*i)->undefine(self);
#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(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE)
#define BOOST_SPIRIT_GRAMMAR_STATE \
private: \
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

View File

@@ -0,0 +1,196 @@
/*=============================================================================
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/lock_types.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::unique_lock<boost::mutex> lock(mutex);
#endif
if (!free_ids.empty())
{
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::unique_lock<boost::mutex> 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
#ifndef BOOST_THREAD_PROVIDES_ONCE_CXX11
static boost::once_flag been_here = BOOST_ONCE_INIT;
#else
static boost::once_flag been_here;
#endif
boost::call_once(been_here, mutex_init);
boost::mutex &mutex = mutex_instance();
boost::unique_lock<boost::mutex> 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

View File

@@ -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>
#include <boost/mpl/if.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)
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_) {}
~concrete_parser() BOOST_OVERRIDE {}
typename match_result<ScannerT, AttrT>::type
do_parse_virtual(ScannerT const& scan) const BOOST_OVERRIDE
{
return p.parse(scan);
}
abstract_parser<ScannerT, AttrT>*
clone() const BOOST_OVERRIDE
{
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

View File

@@ -0,0 +1,124 @@
/*=============================================================================
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>
#ifndef BOOST_THREAD_PROVIDES_ONCE_CXX11
once_flag static_<T, Tag>::constructed_ = BOOST_ONCE_INIT;
#else
once_flag static_<T, Tag>::constructed_;
#endif
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif // include guard

View File

@@ -0,0 +1,142 @@
/*=============================================================================
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
#include <boost/mpl/if.hpp>
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 {
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;
};
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

View File

@@ -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

View File

@@ -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

View File

@@ -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 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

View File

@@ -0,0 +1,303 @@
/*=============================================================================
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/mpl/if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/type_traits/is_same.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

View File

@@ -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

View File

@@ -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>

View File

@@ -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

View File

@@ -0,0 +1,396 @@
/*=============================================================================
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
#include <cctype>
#if !defined(BOOST_NO_CWCTYPE)
#include <cwctype>
#endif
#include <string> // char_traits
#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
//
///////////////////////////////////////////////////////////////////////////
// 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 std::char_traits<CharT>::int_type int_type;
static int_type to_int_type(CharT c)
{
return std::char_traits<CharT>::to_int_type(c);
}
static char_type to_char_type(int_type i)
{
return std::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)));
}
inline bool
isblank_(bool)
{
return false;
}
#endif // !defined(BOOST_NO_CWCTYPE)
}
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace boost::spirit::impl
#ifdef BOOST_MSVC
#pragma warning (pop)
#endif
#endif

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,666 @@
/*=============================================================================
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 ScannerT::value_t value_t;
typedef typename ScannerT::iterator_t iterator_t;
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;
if (!scan.at_end())
{
value_t ch = *scan;
if (this->derived().test(ch))
{
iterator_t save(scan.first);
++scan.change_policies(policies_t(scan));
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
{
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;
typename ScannerT::iterator_t save = scan.first;
std::size_t len = 0;
if (!scan.at_end() && *scan == '\r') // CR
{
++scan.change_policies(policies_t(scan));
++len;
}
// Don't call skipper here
if (scan.first != scan.last && *scan == '\n') // LF
{
++scan.change_policies(policies_t(scan));
++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

View File

@@ -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

View File

@@ -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> it_policy_t;
typedef scanner_policies<it_policy_t> scan_policies_t;
typedef scanner<IteratorT, scan_policies_t> scanner_t;
it_policy_t iter_policy(skip);
scan_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<> it_policy_t;
typedef scanner_policies<it_policy_t> scan_policies_t;
typedef scanner<IteratorT, scan_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

View File

@@ -0,0 +1,328 @@
/*=============================================================================
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/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 std::
iterator_traits<IteratorT>::value_type value_t;
typedef typename std::
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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,319 @@
/*=============================================================================
Copyright (c) 2001-2003 Joel de Guzman
Copyright (c) 2002-2003 Hartmut Kaiser
Copyright (c) 2003 Gustavo Guerra
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_NODE_HPP)
#define BOOST_SPIRIT_DEBUG_NODE_HPP
#if !defined(BOOST_SPIRIT_DEBUG_MAIN_HPP)
#error "You must include boost/spirit/debug.hpp, not boost/spirit/debug/debug_node.hpp"
#endif
#if defined(BOOST_SPIRIT_DEBUG)
#include <string>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/primitives/primitives.hpp> // for iscntrl_
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
//
// Debug helper classes for rules, which ensure maximum non-intrusiveness of
// the Spirit debug support
//
///////////////////////////////////////////////////////////////////////////////
namespace impl {
struct token_printer_aux_for_chars
{
template<typename CharT>
static void print(std::ostream& o, CharT c)
{
if (c == static_cast<CharT>('\a'))
o << "\\a";
else if (c == static_cast<CharT>('\b'))
o << "\\b";
else if (c == static_cast<CharT>('\f'))
o << "\\f";
else if (c == static_cast<CharT>('\n'))
o << "\\n";
else if (c == static_cast<CharT>('\r'))
o << "\\r";
else if (c == static_cast<CharT>('\t'))
o << "\\t";
else if (c == static_cast<CharT>('\v'))
o << "\\v";
else if (iscntrl_(c))
o << "\\" << static_cast<int>(c);
else
o << static_cast<char>(c);
}
};
// for token types where the comparison with char constants wouldn't work
struct token_printer_aux_for_other_types
{
template<typename CharT>
static void print(std::ostream& o, CharT c)
{
o << c;
}
};
template <typename CharT>
struct token_printer_aux
: mpl::if_<
mpl::and_<
is_convertible<CharT, char>,
is_convertible<char, CharT> >,
token_printer_aux_for_chars,
token_printer_aux_for_other_types
>::type
{
};
template<typename CharT>
inline void token_printer(std::ostream& o, CharT c)
{
#if !defined(BOOST_SPIRIT_DEBUG_TOKEN_PRINTER)
token_printer_aux<CharT>::print(o, c);
#else
BOOST_SPIRIT_DEBUG_TOKEN_PRINTER(o, c);
#endif
}
///////////////////////////////////////////////////////////////////////////////
//
// Dump infos about the parsing state of a rule
//
///////////////////////////////////////////////////////////////////////////////
#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES
template <typename IteratorT>
inline void
print_node_info(bool hit, int level, bool close, std::string const& name,
IteratorT first, IteratorT last)
{
if (!name.empty())
{
for (int i = 0; i < level; ++i)
BOOST_SPIRIT_DEBUG_OUT << " ";
if (close)
{
if (hit)
BOOST_SPIRIT_DEBUG_OUT << "/";
else
BOOST_SPIRIT_DEBUG_OUT << "#";
}
BOOST_SPIRIT_DEBUG_OUT << name << ":\t\"";
IteratorT iter = first;
IteratorT ilast = last;
for (int j = 0; j < BOOST_SPIRIT_DEBUG_PRINT_SOME; ++j)
{
if (iter == ilast)
break;
token_printer(BOOST_SPIRIT_DEBUG_OUT, *iter);
++iter;
}
BOOST_SPIRIT_DEBUG_OUT << "\"\n";
}
}
#endif // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES
#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES
template <typename ResultT>
inline ResultT &
print_closure_info(ResultT &hit, int level, std::string const& name)
{
if (!name.empty())
{
for (int i = 0; i < level-1; ++i)
BOOST_SPIRIT_DEBUG_OUT << " ";
// for now, print out the return value only
BOOST_SPIRIT_DEBUG_OUT << "^" << name << ":\t";
if (hit.has_valid_attribute())
BOOST_SPIRIT_DEBUG_OUT << hit.value();
else
BOOST_SPIRIT_DEBUG_OUT << "undefined attribute";
BOOST_SPIRIT_DEBUG_OUT << "\n";
}
return hit;
}
#endif // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES
}
///////////////////////////////////////////////////////////////////////////////
//
// Implementation note: The parser_context_linker, parser_scanner_linker and
// closure_context_linker classes are wrapped by a PP constant to allow
// redefinition of this classes outside of Spirit
//
///////////////////////////////////////////////////////////////////////////////
#if !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED)
#define BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED
///////////////////////////////////////////////////////////////////////////
//
// parser_context_linker is a debug wrapper for the ContextT template
// parameter of the rule<>, subrule<> and the grammar<> classes
//
///////////////////////////////////////////////////////////////////////////
template<typename ContextT>
struct parser_context_linker : public ContextT
{
typedef ContextT base_t;
template <typename ParserT>
parser_context_linker(ParserT const& p)
: ContextT(p) {}
template <typename ParserT, typename ScannerT>
void pre_parse(ParserT const& p, ScannerT &scan)
{
this->base_t::pre_parse(p, scan);
#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES
if (trace_parser(p.derived())) {
impl::print_node_info(
false,
scan.get_level(),
false,
parser_name(p.derived()),
scan.first,
scan.last);
}
scan.get_level()++;
#endif // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES
}
template <typename ResultT, typename ParserT, typename ScannerT>
ResultT& post_parse(ResultT& hit, ParserT const& p, ScannerT &scan)
{
#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES
--scan.get_level();
if (trace_parser(p.derived())) {
impl::print_node_info(
hit,
scan.get_level(),
true,
parser_name(p.derived()),
scan.first,
scan.last);
}
#endif // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_NODES
return this->base_t::post_parse(hit, p, scan);
}
};
#endif // !defined(BOOST_SPIRIT_PARSER_CONTEXT_LINKER_DEFINED)
#if !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED)
#define BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED
///////////////////////////////////////////////////////////////////////////////
// This class is to avoid linker problems and to ensure a real singleton
// 'level' variable
struct debug_support
{
int& get_level()
{
static int level = 0;
return level;
}
};
template<typename ScannerT>
struct parser_scanner_linker : public ScannerT
{
parser_scanner_linker(ScannerT const &scan_) : ScannerT(scan_)
{}
int &get_level()
{ return debug.get_level(); }
private: debug_support debug;
};
#endif // !defined(BOOST_SPIRIT_PARSER_SCANNER_LINKER_DEFINED)
#if !defined(BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED)
#define BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED
///////////////////////////////////////////////////////////////////////////
//
// closure_context_linker is a debug wrapper for the closure template
// parameter of the rule<>, subrule<> and grammar classes
//
///////////////////////////////////////////////////////////////////////////
template<typename ContextT>
struct closure_context_linker : public parser_context_linker<ContextT>
{
typedef parser_context_linker<ContextT> base_t;
template <typename ParserT>
closure_context_linker(ParserT const& p)
: parser_context_linker<ContextT>(p) {}
template <typename ParserT, typename ScannerT>
void pre_parse(ParserT const& p, ScannerT &scan)
{ this->base_t::pre_parse(p, scan); }
template <typename ResultT, typename ParserT, typename ScannerT>
ResultT&
post_parse(ResultT& hit, ParserT const& p, ScannerT &scan)
{
#if BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES
if (hit && trace_parser(p.derived())) {
// for now, print out the return value only
return impl::print_closure_info(
this->base_t::post_parse(hit, p, scan),
scan.get_level(),
parser_name(p.derived())
);
}
#endif // BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES
return this->base_t::post_parse(hit, p, scan);
}
};
#endif // !defined(BOOST_SPIRIT_CLOSURE_CONTEXT_LINKER_DEFINED)
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif // defined(BOOST_SPIRIT_DEBUG)
#endif // !defined(BOOST_SPIRIT_DEBUG_NODE_HPP)

View File

@@ -0,0 +1,555 @@
/*=============================================================================
Copyright (c) 2001-2003 Joel de Guzman
Copyright (c) 2002-2003 Hartmut Kaiser
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_PARSER_NAMES_IPP)
#define BOOST_SPIRIT_PARSER_NAMES_IPP
#if defined(BOOST_SPIRIT_DEBUG)
#include <string>
#include <iostream>
#include <map>
#include <boost/config.hpp>
#ifdef BOOST_NO_STRINGSTREAM
#include <strstream>
#define BOOST_SPIRIT_SSTREAM std::strstream
std::string BOOST_SPIRIT_GETSTRING(std::strstream& ss)
{
ss << ends;
std::string rval = ss.str();
ss.freeze(false);
return rval;
}
#else
#include <sstream>
#define BOOST_SPIRIT_GETSTRING(ss) ss.str()
#define BOOST_SPIRIT_SSTREAM std::stringstream
#endif
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
// from actions.hpp
template <typename ParserT, typename ActionT>
inline std::string
parser_name(action<ParserT, ActionT> const& p)
{
return std::string("action")
+ std::string("[")
+ parser_name(p.subject())
+ std::string("]");
}
///////////////////////////////////////////////////////////////////////////////
// from directives.hpp
template <typename ParserT>
inline std::string
parser_name(contiguous<ParserT> const& p)
{
return std::string("contiguous")
+ std::string("[")
+ parser_name(p.subject())
+ std::string("]");
}
template <typename ParserT>
inline std::string
parser_name(inhibit_case<ParserT> const& p)
{
return std::string("inhibit_case")
+ std::string("[")
+ parser_name(p.subject())
+ std::string("]");
}
template <typename A, typename B>
inline std::string
parser_name(longest_alternative<A, B> const& p)
{
return std::string("longest_alternative")
+ std::string("[")
+ parser_name(p.left()) + std::string(", ") + parser_name(p.right())
+ std::string("]");
}
template <typename A, typename B>
inline std::string
parser_name(shortest_alternative<A, B> const& p)
{
return std::string("shortest_alternative")
+ std::string("[")
+ parser_name(p.left()) + std::string(", ") + parser_name(p.right())
+ std::string("]");
}
///////////////////////////////////////////////////////////////////////////////
// from numerics.hpp
template <typename T, int Radix, unsigned MinDigits, int MaxDigits>
inline std::string
parser_name(uint_parser<T, Radix, MinDigits, MaxDigits> const& /*p*/)
{
BOOST_SPIRIT_SSTREAM stream;
stream << Radix << ", " << MinDigits << ", " << MaxDigits;
return std::string("uint_parser<")
+ BOOST_SPIRIT_GETSTRING(stream)
+ std::string(">");
}
template <typename T, int Radix, unsigned MinDigits, int MaxDigits>
inline std::string
parser_name(int_parser<T, Radix, MinDigits, MaxDigits> const& /*p*/)
{
BOOST_SPIRIT_SSTREAM stream;
stream << Radix << ", " << MinDigits << ", " << MaxDigits;
return std::string("int_parser<")
+ BOOST_SPIRIT_GETSTRING(stream)
+ std::string(">");
}
template <typename T, typename RealPoliciesT>
inline std::string
parser_name(real_parser<T, RealPoliciesT> const& /*p*/)
{
return std::string("real_parser");
}
///////////////////////////////////////////////////////////////////////////////
// from operators.hpp
template <typename A, typename B>
inline std::string
parser_name(sequence<A, B> const& p)
{
return std::string("sequence")
+ std::string("[")
+ parser_name(p.left()) + std::string(", ") + parser_name(p.right())
+ std::string("]");
}
template <typename A, typename B>
inline std::string
parser_name(sequential_or<A, B> const& p)
{
return std::string("sequential_or")
+ std::string("[")
+ parser_name(p.left()) + std::string(", ") + parser_name(p.right())
+ std::string("]");
}
template <typename A, typename B>
inline std::string
parser_name(alternative<A, B> const& p)
{
return std::string("alternative")
+ std::string("[")
+ parser_name(p.left()) + std::string(", ") + parser_name(p.right())
+ std::string("]");
}
template <typename A, typename B>
inline std::string
parser_name(intersection<A, B> const& p)
{
return std::string("intersection")
+ std::string("[")
+ parser_name(p.left()) + std::string(", ") + parser_name(p.right())
+ std::string("]");
}
template <typename A, typename B>
inline std::string
parser_name(difference<A, B> const& p)
{
return std::string("difference")
+ std::string("[")
+ parser_name(p.left()) + std::string(", ") + parser_name(p.right())
+ std::string("]");
}
template <typename A, typename B>
inline std::string
parser_name(exclusive_or<A, B> const& p)
{
return std::string("exclusive_or")
+ std::string("[")
+ parser_name(p.left()) + std::string(", ") + parser_name(p.right())
+ std::string("]");
}
template <typename S>
inline std::string
parser_name(optional<S> const& p)
{
return std::string("optional")
+ std::string("[")
+ parser_name(p.subject())
+ std::string("]");
}
template <typename S>
inline std::string
parser_name(kleene_star<S> const& p)
{
return std::string("kleene_star")
+ std::string("[")
+ parser_name(p.subject())
+ std::string("]");
}
template <typename S>
inline std::string
parser_name(positive<S> const& p)
{
return std::string("positive")
+ std::string("[")
+ parser_name(p.subject())
+ std::string("]");
}
///////////////////////////////////////////////////////////////////////////////
// from parser.hpp
template <typename DerivedT>
inline std::string
parser_name(parser<DerivedT> const& /*p*/)
{
return std::string("parser");
}
///////////////////////////////////////////////////////////////////////////////
// from primitives.hpp
template <typename DerivedT>
inline std::string
parser_name(char_parser<DerivedT> const &/*p*/)
{
return std::string("char_parser");
}
template <typename CharT>
inline std::string
parser_name(chlit<CharT> const &p)
{
return std::string("chlit(\'")
+ std::string(1, p.ch)
+ std::string("\')");
}
template <typename CharT>
inline std::string
parser_name(range<CharT> const &p)
{
return std::string("range(")
+ std::string(1, p.first) + std::string(", ") + std::string(1, p.last)
+ std::string(")");
}
template <typename IteratorT>
inline std::string
parser_name(chseq<IteratorT> const &p)
{
return std::string("chseq(\"")
+ std::string(p.first, p.last)
+ std::string("\")");
}
template <typename IteratorT>
inline std::string
parser_name(strlit<IteratorT> const &p)
{
return std::string("strlit(\"")
+ std::string(p.seq.first, p.seq.last)
+ std::string("\")");
}
inline std::string
parser_name(nothing_parser const&)
{
return std::string("nothing");
}
inline std::string
parser_name(epsilon_parser const&)
{
return std::string("epsilon");
}
inline std::string
parser_name(anychar_parser const&)
{
return std::string("anychar");
}
inline std::string
parser_name(alnum_parser const&)
{
return std::string("alnum");
}
inline std::string
parser_name(alpha_parser const&)
{
return std::string("alpha");
}
inline std::string
parser_name(cntrl_parser const&)
{
return std::string("cntrl");
}
inline std::string
parser_name(digit_parser const&)
{
return std::string("digit");
}
inline std::string
parser_name(graph_parser const&)
{
return std::string("graph");
}
inline std::string
parser_name(lower_parser const&)
{
return std::string("lower");
}
inline std::string
parser_name(print_parser const&)
{
return std::string("print");
}
inline std::string
parser_name(punct_parser const&)
{
return std::string("punct");
}
inline std::string
parser_name(blank_parser const&)
{
return std::string("blank");
}
inline std::string
parser_name(space_parser const&)
{
return std::string("space");
}
inline std::string
parser_name(upper_parser const&)
{
return std::string("upper");
}
inline std::string
parser_name(xdigit_parser const&)
{
return std::string("xdigit");
}
inline std::string
parser_name(eol_parser const&)
{
return std::string("eol");
}
inline std::string
parser_name(end_parser const&)
{
return std::string("end");
}
///////////////////////////////////////////////////////////////////////////////
// from rule.hpp
namespace impl {
struct node_registry
{
typedef std::pair<std::string, bool> rule_info;
typedef std::map<void const *, rule_info> rule_infos;
std::string find_node(void const *r)
{
rule_infos::const_iterator cit = infos.find(r);
if (cit != infos.end())
return (*cit).second.first;
return std::string("<unknown>");
}
bool trace_node(void const *r)
{
rule_infos::const_iterator cit = infos.find(r);
if (cit != infos.end())
return (*cit).second.second;
return BOOST_SPIRIT_DEBUG_TRACENODE;
}
bool register_node(void const *r, char const *name_to_register,
bool trace_node)
{
if (infos.find(r) != infos.end())
return false;
return infos.insert(rule_infos::value_type(r,
rule_info(std::string(name_to_register), trace_node))
).second;
}
bool unregister_node(void const *r)
{
if (infos.find(r) == infos.end())
return false;
return (1 == infos.erase(r));
}
private:
rule_infos infos;
};
inline node_registry &
get_node_registry()
{
static node_registry node_infos;
return node_infos;
}
} // namespace impl
template<
typename DerivedT, typename EmbedT,
typename T0, typename T1, typename T2
>
inline std::string
parser_name(impl::rule_base<DerivedT, EmbedT, T0, T1, T2> const& p)
{
return std::string("rule_base")
+ std::string("(")
+ impl::get_node_registry().find_node(&p)
+ std::string(")");
}
template<typename T0, typename T1, typename T2>
inline std::string
parser_name(rule<T0, T1, T2> const& p)
{
return std::string("rule")
+ std::string("(")
+ impl::get_node_registry().find_node(&p)
+ std::string(")");
}
///////////////////////////////////////////////////////////////////////////////
// from subrule.hpp
template <typename FirstT, typename RestT>
inline std::string
parser_name(subrule_list<FirstT, RestT> const &p)
{
return std::string("subrule_list")
+ std::string("(")
+ impl::get_node_registry().find_node(&p)
+ std::string(")");
}
template <int ID, typename DefT, typename ContextT>
inline std::string
parser_name(subrule_parser<ID, DefT, ContextT> const &p)
{
return std::string("subrule_parser")
+ std::string("(")
+ impl::get_node_registry().find_node(&p)
+ std::string(")");
}
template <int ID, typename ContextT>
inline std::string
parser_name(subrule<ID, ContextT> const &p)
{
BOOST_SPIRIT_SSTREAM stream;
stream << ID;
return std::string("subrule<")
+ BOOST_SPIRIT_GETSTRING(stream)
+ std::string(">(")
+ impl::get_node_registry().find_node(&p)
+ std::string(")");
}
///////////////////////////////////////////////////////////////////////////////
// from grammar.hpp
template <typename DerivedT, typename ContextT>
inline std::string
parser_name(grammar<DerivedT, ContextT> const& p)
{
return std::string("grammar")
+ std::string("(")
+ impl::get_node_registry().find_node(&p)
+ std::string(")");
}
///////////////////////////////////////////////////////////////////////////////
// decide, if a node is to be traced or not
template<
typename DerivedT, typename EmbedT,
typename T0, typename T1, typename T2
>
inline bool
trace_parser(impl::rule_base<DerivedT, EmbedT, T0, T1, T2>
const& p)
{
return impl::get_node_registry().trace_node(&p);
}
template<typename T0, typename T1, typename T2>
inline bool
trace_parser(rule<T0, T1, T2> const& p)
{
return impl::get_node_registry().trace_node(&p);
}
template <typename DerivedT, typename ContextT>
inline bool
trace_parser(grammar<DerivedT, ContextT> const& p)
{
return impl::get_node_registry().trace_node(&p);
}
template <typename DerivedT, int N, typename ContextT>
inline bool
trace_parser(impl::entry_grammar<DerivedT, N, ContextT> const& p)
{
return impl::get_node_registry().trace_node(&p);
}
template <int ID, typename ContextT>
bool
trace_parser(subrule<ID, ContextT> const& p)
{
return impl::get_node_registry().trace_node(&p);
}
template <typename ParserT, typename ActorTupleT>
bool
trace_parser(init_closure_parser<ParserT, ActorTupleT> const& p)
{
return impl::get_node_registry().trace_node(&p);
}
///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace boost::spirit
#undef BOOST_SPIRIT_SSTREAM
#undef BOOST_SPIRIT_GETSTRING
#endif // defined(BOOST_SPIRIT_DEBUG)
#endif // !defined(BOOST_SPIRIT_PARSER_NAMES_IPP)

View File

@@ -0,0 +1,81 @@
/*=============================================================================
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_MINIMAL_DEBUG_HPP)
#define BOOST_SPIRIT_MINIMAL_DEBUG_HPP
#if !defined(BOOST_SPIRIT_DEBUG_MAIN_HPP)
#error "You must include boost/spirit/debug.hpp, not boost/spirit/debug/minimal.hpp"
#endif
///////////////////////////////////////////////////////////////////////////////
//
// Minimum debugging tools support
//
///////////////////////////////////////////////////////////////////////////////
#if !defined(BOOST_SPIRIT_DEBUG_OUT)
#define BOOST_SPIRIT_DEBUG_OUT std::cout
#endif
///////////////////////////////////////////////////////////////////////////
//
// BOOST_SPIRIT_DEBUG_FLAGS controls the level of diagnostics printed
//
///////////////////////////////////////////////////////////////////////////
#if !defined(BOOST_SPIRIT_DEBUG_FLAGS_NONE)
#define BOOST_SPIRIT_DEBUG_FLAGS_NONE 0x0000 // no diagnostics at all
#endif
#if !defined(BOOST_SPIRIT_DEBUG_FLAGS_MAX)
#define BOOST_SPIRIT_DEBUG_FLAGS_MAX 0xFFFF // print maximal diagnostics
#endif
#if !defined(BOOST_SPIRIT_DEBUG_FLAGS)
#define BOOST_SPIRIT_DEBUG_FLAGS BOOST_SPIRIT_DEBUG_FLAGS_MAX
#endif
#if !defined(BOOST_SPIRIT_DEBUG_PRINT_SOME)
#define BOOST_SPIRIT_DEBUG_PRINT_SOME 20
#endif
#if !defined(BOOST_SPIRIT_DEBUG_RULE)
#define BOOST_SPIRIT_DEBUG_RULE(r)
#endif // !defined(BOOST_SPIRIT_DEBUG_RULE)
#if !defined(BOOST_SPIRIT_DEBUG_NODE)
#define BOOST_SPIRIT_DEBUG_NODE(r)
#endif // !defined(BOOST_SPIRIT_DEBUG_NODE)
#if !defined(BOOST_SPIRIT_DEBUG_GRAMMAR)
#define BOOST_SPIRIT_DEBUG_GRAMMAR(r)
#endif // !defined(BOOST_SPIRIT_DEBUG_GRAMMAR)
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_RULE)
#define BOOST_SPIRIT_DEBUG_TRACE_RULE(r, t)
#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_RULE)
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE)
#define BOOST_SPIRIT_DEBUG_TRACE_NODE(r, t)
#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE)
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR)
#define BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR(r, t)
#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR)
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME)
#define BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME(r, n, t)
#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME)
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME)
#define BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME(r, n, t)
#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME)
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME)
#define BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(r, n, t)
#endif // !defined(BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME)
#endif // !defined(BOOST_SPIRIT_MINIMAL_DEBUG_HPP)

View File

@@ -0,0 +1,254 @@
/*=============================================================================
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_PARSER_NAMES_HPP)
#define BOOST_SPIRIT_PARSER_NAMES_HPP
#if defined(BOOST_SPIRIT_DEBUG)
//////////////////////////////////
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core.hpp>
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
//
// Declaration of helper functions, which return the name of a concrete
// parser instance. The functions are specialized on the parser types. The
// functions declared in this file are for the predefined parser types from
// the Spirit core library only, so additional functions might be provided as
// needed.
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// from actions.hpp
template <typename ParserT, typename ActionT>
std::string
parser_name(action<ParserT, ActionT> const& p);
///////////////////////////////////////////////////////////////////////////////
// from directives.hpp
template <typename ParserT>
std::string
parser_name(contiguous<ParserT> const& p);
template <typename ParserT>
std::string
parser_name(inhibit_case<ParserT> const& p);
template <typename A, typename B>
std::string
parser_name(longest_alternative<A, B> const& p);
template <typename A, typename B>
std::string
parser_name(shortest_alternative<A, B> const& p);
///////////////////////////////////////////////////////////////////////////////
// from grammar.hpp
template <typename DerivedT, typename ContextT>
std::string
parser_name(grammar<DerivedT, ContextT> const& p);
///////////////////////////////////////////////////////////////////////////////
// from numerics.hpp
template <typename T, int Radix, unsigned MinDigits, int MaxDigits>
std::string
parser_name(uint_parser<T, Radix, MinDigits, MaxDigits> const& p);
template <typename T, int Radix, unsigned MinDigits, int MaxDigits>
std::string
parser_name(int_parser<T, Radix, MinDigits, MaxDigits> const& p);
template <typename T, typename RealPoliciesT>
std::string
parser_name(real_parser<T, RealPoliciesT> const& p);
///////////////////////////////////////////////////////////////////////////////
// from operators.hpp
template <typename A, typename B>
std::string
parser_name(sequence<A, B> const& p);
template <typename A, typename B>
std::string
parser_name(sequential_or<A, B> const& p);
template <typename A, typename B>
std::string
parser_name(alternative<A, B> const& p);
template <typename A, typename B>
std::string
parser_name(intersection<A, B> const& p);
template <typename A, typename B>
std::string
parser_name(difference<A, B> const& p);
template <typename A, typename B>
std::string
parser_name(exclusive_or<A, B> const& p);
template <typename S>
std::string
parser_name(optional<S> const& p);
template <typename S>
std::string
parser_name(kleene_star<S> const& p);
template <typename S>
std::string
parser_name(positive<S> const& p);
///////////////////////////////////////////////////////////////////////////////
// from parser.hpp
template <typename DerivedT>
std::string
parser_name(parser<DerivedT> const& p);
///////////////////////////////////////////////////////////////////////////////
// from primitives.hpp
template <typename DerivedT>
std::string
parser_name(char_parser<DerivedT> const &p);
template <typename CharT>
std::string
parser_name(chlit<CharT> const &p);
template <typename CharT>
std::string
parser_name(range<CharT> const &p);
template <typename IteratorT>
std::string
parser_name(chseq<IteratorT> const &p);
template <typename IteratorT>
std::string
parser_name(strlit<IteratorT> const &p);
std::string
parser_name(nothing_parser const &p);
std::string
parser_name(epsilon_parser const &p);
std::string
parser_name(anychar_parser const &p);
std::string
parser_name(alnum_parser const &p);
std::string
parser_name(alpha_parser const &p);
std::string
parser_name(cntrl_parser const &p);
std::string
parser_name(digit_parser const &p);
std::string
parser_name(graph_parser const &p);
std::string
parser_name(lower_parser const &p);
std::string
parser_name(print_parser const &p);
std::string
parser_name(punct_parser const &p);
std::string
parser_name(blank_parser const &p);
std::string
parser_name(space_parser const &p);
std::string
parser_name(upper_parser const &p);
std::string
parser_name(xdigit_parser const &p);
std::string
parser_name(eol_parser const &p);
std::string
parser_name(end_parser const &p);
///////////////////////////////////////////////////////////////////////////////
// from rule.hpp
template<typename T0, typename T1, typename T2>
std::string
parser_name(rule<T0, T1, T2> const& p);
///////////////////////////////////////////////////////////////////////////////
// from subrule.hpp
template <typename FirstT, typename RestT>
std::string
parser_name(subrule_list<FirstT, RestT> const &p);
template <int ID, typename DefT, typename ContextT>
std::string
parser_name(subrule_parser<ID, DefT, ContextT> const &p);
template <int ID, typename ContextT>
std::string
parser_name(subrule<ID, ContextT> const &p);
///////////////////////////////////////////////////////////////////////////////
// from chset.hpp
///////////////////////////////////////////////////////////////////////////////
//
// Decide, if a node is to be traced or not
//
///////////////////////////////////////////////////////////////////////////////
template<
typename DerivedT, typename EmbedT,
typename T0, typename T1, typename T2
>
bool
trace_parser(impl::rule_base<DerivedT, EmbedT, T0, T1, T2>
const& p);
template <typename DerivedT, typename ContextT>
bool
trace_parser(grammar<DerivedT, ContextT> const& p);
template <int ID, typename ContextT>
bool
trace_parser(subrule<ID, ContextT> const& p);
template <typename ParserT, typename ActorTupleT>
struct init_closure_parser;
template <typename ParserT, typename ActorTupleT>
bool
trace_parser(init_closure_parser<ParserT, ActorTupleT> const& p);
///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
//////////////////////////////////
#include <boost/spirit/home/classic/debug/impl/parser_names.ipp>
#endif // defined(BOOST_SPIRIT_DEBUG)
#endif // !defined(BOOST_SPIRIT_PARSER_NAMES_HPP)

View File

@@ -0,0 +1,37 @@
/*=============================================================================
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_DEBUG_TYPEOF_HPP)
#define BOOST_SPIRIT_DEBUG_TYPEOF_HPP
#include <boost/typeof/typeof.hpp>
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/typeof.hpp>
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
// debug_node.hpp
template<typename ContextT> struct parser_context_linker;
template<typename ScannerT> struct scanner_context_linker;
template<typename ContextT> struct closure_context_linker;
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
// debug_node.hpp
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::parser_context_linker,1)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::scanner_context_linker,1)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::closure_context_linker,1)
#endif

View File

@@ -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

View File

@@ -0,0 +1,185 @@
/*=============================================================================
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<parser_t, ScannerT>::type
body_result_t;
typename ScannerT::iterator_t save(scan.first);
std::size_t length = 0;
std::ptrdiff_t 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

View File

@@ -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 false, 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

View File

@@ -0,0 +1,97 @@
/*=============================================================================
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;
};
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

View File

@@ -0,0 +1,122 @@
/*=============================================================================
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);
::phoenix::tuple_index<index> const idx;
result_t result(t[idx].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);
::phoenix::tuple_index<index> const idx;
result_t result(t[idx].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

View File

@@ -0,0 +1,575 @@
/*=============================================================================
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/core/ignore_unused.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 recursively 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, buried 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> rhs_t;
return compound_case_parser<self_t, rhs_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
{
ignore_unused(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

View File

@@ -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

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