2
0
mirror of https://github.com/boostorg/wave.git synced 2026-01-19 04:42:16 +00:00

Wave: Started to fox examples

[SVN r49301]
This commit is contained in:
Hartmut Kaiser
2008-10-13 01:03:32 +00:00
parent 506a7a612b
commit 6bc791d255
6 changed files with 109 additions and 70 deletions

View File

@@ -670,7 +670,7 @@ public:
}
break;
}
result = token_type(id, token_val, pos);
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
return guards.detect_guard(result);
@@ -678,13 +678,13 @@ public:
return result;
#endif
}
// skip the T_CONTLINE token
} while (true);
}
return result = token_type(); // return T_EOI
}
void set_position(PositionT const &pos)
{
// set position has to change the file name and line number only

View File

@@ -64,7 +64,7 @@ public:
typedef lex_input_interface<TokenT>* shared;
BOOST_WAVE_EOF_PREFIX result_type const eof;
template <typename MultiPass>
static result_type& get_next(MultiPass& mp, result_type& result)
{
@@ -84,14 +84,14 @@ public:
{
mp.shared->ftor->set_position(pos);
}
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
template <typename MultiPass>
static bool has_include_guards(MultiPass& mp, std::string& guard_name)
{
return mp.shared->ftor->has_include_guards(guard_name);
}
#endif
#endif
private:
boost::shared_ptr<lex_input_interface<TokenT> > functor_ptr;
@@ -149,7 +149,7 @@ struct make_multi_pass
typedef boost::spirit::multi_pass_policies::no_check check_policy;
#endif
typedef boost::spirit::multi_pass_policies::split_std_deque storage_policy;
typedef boost::spirit::multi_pass_policies::default_policy<
ownership_policy, check_policy, input_policy, storage_policy>
policy_type;
@@ -169,13 +169,13 @@ class slex_iterator
typedef typename input_policy_type::unique unique_functor_type;
typedef typename input_policy_type::shared shared_functor_type;
public:
typedef TokenT token_type;
slex_iterator()
{}
template <typename IteratorT>
slex_iterator(IteratorT const &first, IteratorT const &last,
typename TokenT::position_type const &pos,
@@ -192,22 +192,22 @@ public:
void set_position(typename TokenT::position_type const &pos)
{
typedef typename token_type::position_type position_type;
// set the new position in the current token
token_type const& currtoken = base_type::get_input();
token_type& currtoken = this->base_type::dereference(*this);
position_type currpos = currtoken.get_position();
currpos.set_file(pos.get_file());
currpos.set_line(pos.get_line());
base_type::get_input().set_position(currpos);
currtoken.set_position(currpos);
// set the new position for future tokens as well
if (token_type::string_type::npos !=
currtoken.get_value().find_first_of('\n'))
{
currpos.set_line(pos.get_line() + 1);
}
unique_functor_type::get_functor().set_position(currpos);
unique_functor_type::set_position(*this, currpos);
}
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
@@ -216,9 +216,9 @@ public:
// completely
bool has_include_guards(std::string& guard_name) const
{
return unique_functor_type::has_include_guards(guard_name);
return unique_functor_type::has_include_guards(*this, guard_name);
}
#endif
#endif
};
///////////////////////////////////////////////////////////////////////////////

View File

@@ -602,9 +602,8 @@ public:
~lexertl_functor() {}
// get the next token from the input stream
token_type get()
token_type& get(token_type& result)
{
token_type token;
if (lexer_.is_initialized() && !at_eof) {
do {
// generate and return the next token
@@ -710,18 +709,19 @@ public:
}
break;
}
result = token_type(id, token_val, pos);
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
return guards.detect_guard(token_type(id, token_val, pos));
return guards.detect_guard(result);
#else
return token_type(id, token_val, pos);
return result;
#endif
}
} while (true); // skip the T_CONTLINE token
}
return token; // return T_EOI
return result = token_type(); // return T_EOI
}
void set_position(Position const &pos)
{
// set position has to change the file name and line number only

View File

@@ -17,7 +17,7 @@
#include <boost/assert.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/spirit/include/classic_multi_pass.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
#include <boost/wave/language_support.hpp>
#include <boost/wave/util/file_position.hpp>
@@ -47,14 +47,11 @@ namespace impl {
template <typename TokenT>
class iterator_functor_shim
{
typedef typename TokenT::position_type position_type;
public:
template <typename IteratorT>
iterator_functor_shim(IteratorT const &first, IteratorT const &last,
typename TokenT::position_type const &pos,
wave::language_support language)
: functor_ptr(lexertl_input_interface<TokenT>
::new_lexer(first, last, pos, language))
#if 0 != __DECCXX_VER || defined(__PGI)
iterator_functor_shim()
#if /*0 != __DECCXX_VER || */defined(__PGI)
, eof()
#endif // 0 != __DECCXX_VER
{}
@@ -62,27 +59,38 @@ public:
// interface to the boost::spirit::classic::multi_pass_policies::functor_input
// policy
typedef TokenT result_type;
typedef iterator_functor_shim unique;
typedef lex_input_interface<TokenT>* shared;
BOOST_WAVE_EOF_PREFIX result_type const eof;
result_type operator()()
template <typename MultiPass>
static result_type& get_next(MultiPass& mp, result_type& result)
{
BOOST_ASSERT(0 != functor_ptr.get());
return functor_ptr->get();
return mp.shared->ftor->get(result);
}
void set_position(typename TokenT::position_type const &pos)
// this will be called whenever the last reference to a multi_pass will
// be released
template <typename MultiPass>
static void destroy(MultiPass& mp)
{
delete mp.shared->ftor;
}
template <typename MultiPass>
static void set_position(MultiPass& mp, position_type const &pos)
{
BOOST_ASSERT(0 != functor_ptr.get());
functor_ptr->set_position(pos);
mp.shared->ftor->set_position(pos);
}
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
bool has_include_guards(std::string& guard_name) const
template <typename MultiPass>
static bool has_include_guards(MultiPass& mp, std::string& guard_name)
{
BOOST_ASSERT(0 != functor_ptr.get());
return functor_ptr->has_include_guards(guard_name);
return mp.shared->ftor->has_include_guards(guard_name);
}
#endif
#endif
private:
boost::shared_ptr<lex_input_interface<TokenT> > functor_ptr;
@@ -121,31 +129,62 @@ typename iterator_functor_shim<TokenT>::result_type const
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Divide the given functor type into its components (unique and shared)
// and build a std::pair from these parts
template <typename FunctorData>
struct make_multi_pass
{
typedef
std::pair<typename FunctorData::unique, typename FunctorData::shared>
functor_data_type;
typedef typename FunctorData::result_type result_type;
typedef boost::spirit::multi_pass_policies::split_functor_input input_policy;
typedef boost::spirit::multi_pass_policies::ref_counted ownership_policy;
#if defined(BOOST_WAVE_DEBUG)
typedef boost::spirit::multi_pass_policies::buf_id_check check_policy;
#else
typedef boost::spirit::multi_pass_policies::no_check check_policy;
#endif
typedef boost::spirit::multi_pass_policies::split_std_deque storage_policy;
typedef boost::spirit::multi_pass_policies::default_policy<
ownership_policy, check_policy, input_policy, storage_policy>
policy_type;
typedef boost::spirit::multi_pass<functor_data_type, policy_type> type;
};
template <typename TokenT>
class lex_iterator
: public boost::spirit::classic::multi_pass<
impl::iterator_functor_shim<TokenT>,
boost::wave::util::functor_input
>
: public make_multi_pass<impl::iterator_functor_shim<TokenT> >::type
{
typedef impl::iterator_functor_shim<TokenT> input_policy_type;
typedef
boost::spirit::classic::multi_pass<input_policy_type,
boost::wave::util::functor_input>
base_type;
typedef lex_iterator<TokenT> self_type;
typedef typename make_multi_pass<input_policy_type>::type base_type;
typedef typename make_multi_pass<input_policy_type>::functor_data_type
functor_data_type;
typedef typename input_policy_type::unique unique_functor_type;
typedef typename input_policy_type::shared shared_functor_type;
public:
typedef TokenT token_type;
lex_iterator()
{}
template <typename IteratorT>
lex_iterator(IteratorT const &first, IteratorT const &last,
typename TokenT::position_type const &pos,
boost::wave::language_support language)
: base_type(input_policy_type(first, last, pos, language))
: base_type(
functor_data_type(
unique_functor_type(),
lexertl_input_interface<TokenT>
::new_lexer(first, last, pos, language)
)
)
{}
void set_position(typename TokenT::position_type const &pos)
@@ -153,7 +192,7 @@ public:
typedef typename TokenT::position_type position_type;
// set the new position in the current token
token_type& currtoken = base_type::get_input();
token_type& currtoken = this->base_type::dereference(*this);
position_type currpos = currtoken.get_position();
currpos.set_file(pos.get_file());
@@ -166,18 +205,18 @@ public:
{
currpos.set_line(pos.get_line() + 1);
}
base_type::get_functor().set_position(currpos);
unique_functor_type::set_position(*this, currpos);
}
#if BOOST_WAVE_SUPPORT_PRAGMA_ONCE != 0
// Return, whether the current file has include guards. This function
// returns meaningful results only if the file was scanned completely.
// For now we always return false, but this can be fixed easily later on.
bool has_include_guards(std::string& guard_name) const
{
return base_type::get_functor().has_include_guards(guard_name);
return base_type::get_functor().has_include_guards(*this, guard_name);
}
#endif
#endif
};
///////////////////////////////////////////////////////////////////////////////

View File

@@ -15,7 +15,7 @@
// provided in the preprocess_pragma_output_hooks policy class. This
// #pragma preprocesses the provided arguments in the current context.
#pragma wave pp ( \
"#define A() \"some text\" and more\n" \
"#define A() \"some text\" and more\n" \
"#define B() 1.0\n" \
) \
/**/

View File

@@ -65,13 +65,13 @@ boost::wave::util::file_position_type current_position;
typedef boost::wave::context<std::string::iterator, lex_iterator_type>
context_type;
// The preprocessor iterator shouldn't be constructed directly. It is
// to be generated through a wave::context<> object. This wave:context<>
// object is to be used additionally to initialize and define different
// parameters of the actual preprocessing (not done here).
// The preprocessor iterator shouldn't be constructed directly. It is
// to be generated through a wave::context<> object. This wave:context<>
// object is to be used additionally to initialize and define different
// parameters of the actual preprocessing (not done here).
//
// The preprocessing of the input stream is done on the fly behind the
// scenes during iteration over the context_type::iterator_type stream.
// The preprocessing of the input stream is done on the fly behind the
// scenes during iteration over the context_type::iterator_type stream.
context_type ctx (instring.begin(), instring.end(), argv[1]);
// Get the preprocessor iterators and use them to generate