9fd423ca58
[SVN r58724]
211 lines
6.6 KiB
C++
211 lines
6.6 KiB
C++
/*=============================================================================
|
|
Boost.Wave: A Standard compliant C++ preprocessor library
|
|
|
|
A C++ lexer token definition for the real_positions example
|
|
|
|
http://www.boost.org/
|
|
|
|
Copyright (c) 2001-2010 Hartmut Kaiser. 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(REAL_POSITION_TOKEN_HPP_HK_061109_INCLUDED)
|
|
#define REAL_POSITION_TOKEN_HPP_HK_061109_INCLUDED
|
|
|
|
#include <boost/wave/wave_config.hpp>
|
|
#include <boost/wave/util/file_position.hpp>
|
|
#include <boost/wave/token_ids.hpp>
|
|
#include <boost/wave/language_support.hpp>
|
|
#include <boost/detail/atomic_count.hpp>
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
namespace impl {
|
|
|
|
template <typename StringTypeT, typename PositionT>
|
|
class token_data
|
|
{
|
|
public:
|
|
typedef StringTypeT string_type;
|
|
typedef PositionT position_type;
|
|
|
|
token_data()
|
|
: id(boost::wave::T_EOI), refcnt(1)
|
|
{}
|
|
|
|
// construct an invalid token
|
|
explicit token_data(int)
|
|
: id(T_UNKNOWN), refcnt(1)
|
|
{}
|
|
|
|
token_data(boost::wave::token_id id_, string_type const &value_,
|
|
position_type const &pos_)
|
|
: id(id_), value(value_), pos(pos_), corrected_pos(pos_), refcnt(1)
|
|
{}
|
|
|
|
token_data(token_data const& rhs)
|
|
: id(rhs.id), value(rhs.value), pos(rhs.pos),
|
|
corrected_pos(rhs.corrected_pos), refcnt(1)
|
|
{}
|
|
|
|
~token_data()
|
|
{}
|
|
|
|
std::size_t addref() { return ++refcnt; }
|
|
std::size_t release() { return --refcnt; }
|
|
std::size_t get_refcnt() const { return refcnt; }
|
|
|
|
// accessors
|
|
operator boost::wave::token_id() const { return id; }
|
|
string_type const &get_value() const { return value; }
|
|
position_type const &get_position() const { return pos; }
|
|
position_type const &get_corrected_position() const
|
|
{ return corrected_pos; }
|
|
bool is_eoi() const { id == T_EOI; }
|
|
|
|
void set_token_id (boost::wave::token_id id_) { id = id_; }
|
|
void set_value (string_type const &value_) { value = value_; }
|
|
void set_position (position_type const &pos_) { pos = pos_; }
|
|
void set_corrected_position (position_type const &pos_)
|
|
{ corrected_pos = pos_; }
|
|
|
|
friend bool operator== (token_data const& lhs, token_data const& rhs)
|
|
{
|
|
// two tokens are considered equal even if they refer to different
|
|
// positions
|
|
return (lhs.id == rhs.id && lhs.value == rhs.value) ? true : false;
|
|
}
|
|
|
|
private:
|
|
boost::wave::token_id id; // the token id
|
|
string_type value; // the text, which was parsed into this token
|
|
position_type pos; // the original file position
|
|
position_type corrected_pos; // the original file position
|
|
boost::detail::atomic_count refcnt;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
} // namespace impl
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// forward declaration of the token type
|
|
template <typename PositionT = boost::wave::util::file_position_type>
|
|
class lex_token;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// lex_token
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
template <typename PositionT>
|
|
class lex_token
|
|
{
|
|
public:
|
|
typedef BOOST_WAVE_STRINGTYPE string_type;
|
|
typedef PositionT position_type;
|
|
|
|
lex_token()
|
|
: data(new impl::token_data<string_type, position_type>())
|
|
{}
|
|
|
|
// construct an invalid token
|
|
explicit lex_token(int)
|
|
: data(new data_type(0))
|
|
{}
|
|
|
|
lex_token(lex_token const& rhs)
|
|
: data(rhs.data)
|
|
{
|
|
data->addref();
|
|
}
|
|
|
|
lex_token(boost::wave::token_id id_, string_type const &value_,
|
|
PositionT const &pos_)
|
|
: data(new impl::token_data<string_type, position_type>(id_, value_, pos_))
|
|
{}
|
|
|
|
~lex_token()
|
|
{
|
|
if (0 == data->release())
|
|
delete data;
|
|
data = 0;
|
|
}
|
|
|
|
lex_token& operator=(lex_token const& rhs)
|
|
{
|
|
if (&rhs != this) {
|
|
if (0 == data->release())
|
|
delete data;
|
|
|
|
data = rhs.data;
|
|
data->addref();
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
// accessors
|
|
operator boost::wave::token_id() const
|
|
{ return boost::wave::token_id(*data); }
|
|
string_type const &get_value() const
|
|
{ return data->get_value(); }
|
|
position_type const &get_position() const
|
|
{ return data->get_position(); }
|
|
position_type const &get_corrected_position() const
|
|
{ return data->get_corrected_position(); }
|
|
bool is_valid() const { return 0 != data && token_id(*data) != T_UNKNOWN; }
|
|
|
|
void set_token_id (boost::wave::token_id id_)
|
|
{ make_unique(); data->set_token_id(id_); }
|
|
void set_value (string_type const &value_)
|
|
{ make_unique(); data->set_value(value_); }
|
|
void set_position (position_type const &pos_)
|
|
{ make_unique(); data->set_position(pos_); }
|
|
void set_corrected_position (position_type const &pos_)
|
|
{ make_unique(); data->set_corrected_position(pos_); }
|
|
|
|
friend bool operator== (lex_token const& lhs, lex_token const& rhs)
|
|
{
|
|
return *(lhs.data) == *(rhs.data);
|
|
}
|
|
|
|
// debug support
|
|
#if BOOST_WAVE_DUMP_PARSE_TREE != 0
|
|
// access functions for the tree_to_xml functionality
|
|
static int get_token_id(lex_token const &t)
|
|
{ return token_id(t); }
|
|
static string_type get_token_value(lex_token const &t)
|
|
{ return t.get_value(); }
|
|
#endif
|
|
|
|
private:
|
|
// make a unique copy of the current object
|
|
void make_unique()
|
|
{
|
|
if (1 == data->get_refcnt())
|
|
return;
|
|
|
|
impl::token_data<string_type, position_type> *newdata =
|
|
new impl::token_data<string_type, position_type>(*data);
|
|
|
|
data->release(); // release this reference, can't get zero
|
|
data = newdata;
|
|
}
|
|
|
|
impl::token_data<string_type, position_type> *data;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// This overload is needed by the multi_pass/functor_input_policy to
|
|
// validate a token instance. It has to be defined in the same namespace
|
|
// as the token class itself to allow ADL to find it.
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
template <typename Position>
|
|
inline bool
|
|
token_is_valid(lex_token<Position> const& t)
|
|
{
|
|
return t.is_valid();
|
|
}
|
|
|
|
#endif // !defined(REAL_POSITION_TOKEN_HPP_HK_061109_INCLUDED)
|