|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r54676 - in trunk/boost/spirit/home/lex: . lexer lexer/lexertl
From: hartmut.kaiser_at_[hidden]
Date: 2009-07-05 14:50:31
Author: hkaiser
Date: 2009-07-05 14:50:29 EDT (Sun, 05 Jul 2009)
New Revision: 54676
URL: http://svn.boost.org/trac/boost/changeset/54676
Log:
Spirit: Added support for accessing the token value from a lexer semantic action
Text files modified:
trunk/boost/spirit/home/lex/argument.hpp | 41 ++++++++++++++++++++++++++++++++++++++
trunk/boost/spirit/home/lex/lexer/lexertl/functor.hpp | 22 +++++++++++++++----
trunk/boost/spirit/home/lex/lexer/lexertl/functor_data.hpp | 43 +++++++++++++++++++++++++++++----------
trunk/boost/spirit/home/lex/lexer/lexertl/lexer.hpp | 3 -
trunk/boost/spirit/home/lex/lexer/lexertl/token.hpp | 18 ++++++++++++++-
trunk/boost/spirit/home/lex/lexer/pass_flags.hpp | 7 +++--
trunk/boost/spirit/home/lex/tokenize_and_parse.hpp | 25 ++++++++++++++++++++++
7 files changed, 135 insertions(+), 24 deletions(-)
Modified: trunk/boost/spirit/home/lex/argument.hpp
==============================================================================
--- trunk/boost/spirit/home/lex/argument.hpp (original)
+++ trunk/boost/spirit/home/lex/argument.hpp 2009-07-05 14:50:29 EDT (Sun, 05 Jul 2009)
@@ -133,6 +133,43 @@
};
///////////////////////////////////////////////////////////////////////////
+ // The value_getter is used to create the _value placeholder, which is a
+ // Phoenix actor used to access or change the value of the current token.
+ //
+ // This actor is invoked whenever the placeholder '_value' is used in a
+ // lexer semantic action:
+ //
+ // lex::token_def<> identifier = "[a-zA-Z_][a-zA-Z0-9_]*";
+ // this->self = identifier
+ // [ _value = construct_<std::string>(_start, _end) ];
+ //
+ // The example shows how to use _value to set the identifier name as the
+ // token value.
+ struct value_getter
+ {
+ typedef mpl::true_ no_nullary;
+
+ template <typename Env>
+ struct result
+ {
+ typedef typename
+ remove_const<
+ typename mpl::at_c<typename Env::args_type, 4>::type
+ >::type
+ context_type;
+
+ typedef typename context_type::token_value_type& type;
+ };
+
+ template <typename Env>
+ typename result<Env>::type
+ eval(Env const& env) const
+ {
+ return fusion::at_c<4>(env.args()).value();
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
// The eoi_getter is used to create the _eoi placeholder, which is a
// Phoenix actor used to access the end of input iterator pointing to the
// end of the underlying input sequence.
@@ -184,6 +221,10 @@
// token
phoenix::actor<phoenix::argument<3> > const _tokenid = phoenix::argument<3>();
+ // '_value' may be used to access and change the token value of the current
+ // token
+ phoenix::actor<value_getter> const _value = value_getter();
+
// _state may be used to access and change the name of the current lexer
// state
phoenix::actor<state_context> const _state = state_context();
Modified: trunk/boost/spirit/home/lex/lexer/lexertl/functor.hpp
==============================================================================
--- trunk/boost/spirit/home/lex/lexer/lexertl/functor.hpp (original)
+++ trunk/boost/spirit/home/lex/lexer/lexertl/functor.hpp 2009-07-05 14:50:29 EDT (Sun, 05 Jul 2009)
@@ -58,7 +58,7 @@
//
///////////////////////////////////////////////////////////////////////////
template <typename Token
- , template <typename, typename, typename> class FunctorData
+ , template <typename, typename, typename, typename> class FunctorData
, typename Iterator = typename Token::iterator_type
, typename SupportsActors = mpl::false_
, typename SupportsState = typename Token::has_state>
@@ -73,7 +73,9 @@
// Needed by compilers not implementing the resolution to DR45. For
// reference, see
// http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#45.
- friend class FunctorData<Iterator, SupportsActors, SupportsState>;
+ typedef typename Token::token_value_type token_value_type;
+ friend class FunctorData<Iterator, SupportsActors, SupportsState
+ , token_value_type>;
// Helper template allowing to assign a value on exit
template <typename T>
@@ -110,7 +112,8 @@
// interface to the iterator_policies::split_functor_input policy
typedef Token result_type;
typedef functor unique;
- typedef FunctorData<Iterator, SupportsActors, SupportsState> shared;
+ typedef FunctorData<Iterator, SupportsActors, SupportsState
+ , token_value_type> shared;
BOOST_SPIRIT_EOF_PREFIX result_type const eof;
@@ -190,6 +193,13 @@
assign_on_exit<Iterator> on_exit(data.get_first(), end);
return result = result_type(id, state, data.get_first(), end);
}
+ else if (pass_flags::pass_use_value == pass) {
+ // return matched token using the token value as set before
+ // using data.set_value(), advancing 'data.first_' past the
+ // matched sequence
+ assign_on_exit<Iterator> on_exit(data.get_first(), end);
+ return result = result_type(id, state, data.value());
+ }
else if (pass_flags::pass_fail == pass) {
// if the data.first_ got adjusted above, revert this adjustment
if (adjusted)
@@ -199,7 +209,9 @@
return result = result_type(0);
}
- // if this token needs to be ignored, just repeat the matching
+ // if this token needs to be ignored, just repeat the matching,
+ // while starting right after the current match
+ data.get_first() = end;
} while (true);
}
@@ -238,7 +250,7 @@
// eof token
///////////////////////////////////////////////////////////////////////////
template <typename Token
- , template <typename, typename, typename> class FunctorData
+ , template <typename, typename, typename, typename> class FunctorData
, typename Iterator, typename SupportsActors, typename SupportsState>
typename functor<Token, FunctorData, Iterator, SupportsActors, SupportsState>::result_type const
functor<Token, FunctorData, Iterator, SupportsActors, SupportsState>::eof =
Modified: trunk/boost/spirit/home/lex/lexer/lexertl/functor_data.hpp
==============================================================================
--- trunk/boost/spirit/home/lex/lexer/lexertl/functor_data.hpp (original)
+++ trunk/boost/spirit/home/lex/lexer/lexertl/functor_data.hpp 2009-07-05 14:50:29 EDT (Sun, 05 Jul 2009)
@@ -23,13 +23,14 @@
namespace detail
{
///////////////////////////////////////////////////////////////////////
- template <typename Iterator, typename HasActors, typename HasState>
+ template <typename Iterator, typename HasActors, typename HasState
+ , typename TokenValue>
struct data; // no default specialization
///////////////////////////////////////////////////////////////////////
// neither supports state, nor actors
- template <typename Iterator>
- struct data<Iterator, mpl::false_, mpl::false_>
+ template <typename Iterator, typename TokenValue>
+ struct data<Iterator, mpl::false_, mpl::false_, TokenValue>
{
protected:
typedef typename
@@ -38,6 +39,7 @@
public:
typedef Iterator base_iterator_type;
+ typedef unused_type token_value_type;
typedef std::size_t state_type;
typedef char_type const* state_name_type;
typedef unused_type semantic_actions_type;
@@ -146,6 +148,8 @@
Iterator const& get_first() const { return first_; }
Iterator const& get_last() const { return last_; }
+ unused_type value() const { return unused; }
+
protected:
Iterator& first_;
Iterator last_;
@@ -156,16 +160,17 @@
///////////////////////////////////////////////////////////////////////
// doesn't support lexer semantic actions
- template <typename Iterator>
- struct data<Iterator, mpl::false_, mpl::true_>
- : data<Iterator, mpl::false_, mpl::false_>
+ template <typename Iterator, typename TokenValue>
+ struct data<Iterator, mpl::false_, mpl::true_, TokenValue>
+ : data<Iterator, mpl::false_, mpl::false_, TokenValue>
{
protected:
- typedef data<Iterator, mpl::false_, mpl::false_> base_type;
+ typedef data<Iterator, mpl::false_, mpl::false_, TokenValue> base_type;
typedef typename base_type::char_type char_type;
public:
typedef Iterator base_iterator_type;
+ typedef unused_type token_value_type;
typedef typename base_type::state_type state_type;
typedef typename base_type::state_name_type state_name_type;
typedef typename base_type::semantic_actions_type
@@ -221,22 +226,23 @@
///////////////////////////////////////////////////////////////////////
// does support lexer semantic actions, may support state
- template <typename Iterator, typename HasState>
- struct data<Iterator, mpl::true_, HasState>
- : data<Iterator, mpl::false_, HasState>
+ template <typename Iterator, typename HasState, typename TokenValue>
+ struct data<Iterator, mpl::true_, HasState, TokenValue>
+ : data<Iterator, mpl::false_, HasState, TokenValue>
{
public:
typedef semantic_actions<Iterator, HasState, data>
semantic_actions_type;
protected:
- typedef data<Iterator, mpl::false_, HasState> base_type;
+ typedef data<Iterator, mpl::false_, HasState, TokenValue> base_type;
typedef typename base_type::char_type char_type;
typedef typename semantic_actions_type::functor_wrapper_type
functor_wrapper_type;
public:
typedef Iterator base_iterator_type;
+ typedef TokenValue token_value_type;
typedef typename base_type::state_type state_type;
typedef typename base_type::state_name_type state_name_type;
@@ -310,10 +316,25 @@
has_hold_ = true;
}
+ TokenValue const& value() const
+ {
+ return value_;
+ }
+ TokenValue& value()
+ {
+ return value_;
+ }
+ template <typename Value>
+ void set_value(Value const& val)
+ {
+ value_ = val;
+ }
+
protected:
semantic_actions_type const& actions_;
Iterator hold_; // iterator needed to support lex::more()
bool has_hold_; // 'true' if hold_ is valid
+ TokenValue value_;
};
}
Modified: trunk/boost/spirit/home/lex/lexer/lexertl/lexer.hpp
==============================================================================
--- trunk/boost/spirit/home/lex/lexer/lexertl/lexer.hpp (original)
+++ trunk/boost/spirit/home/lex/lexer/lexertl/lexer.hpp 2009-07-05 14:50:29 EDT (Sun, 05 Jul 2009)
@@ -205,7 +205,7 @@
///////////////////////////////////////////////////////////////////////////
template <typename Token = token<>
, typename Iterator = typename Token::iterator_type
- , typename Functor = functor<Token, lexertl::detail::data, Iterator, mpl::false_>
+ , typename Functor = functor<Token, lexertl::detail::data, Iterator>
, typename TokenSet = lex::token_set<token_set<Token, Iterator> > >
class lexer
{
@@ -362,7 +362,6 @@
private:
// lexertl specific data
mutable boost::lexer::basic_state_machine<char_type> state_machine_;
- std::size_t unique_ids_;
boost::lexer::regex_flags flags_;
boost::lexer::basic_rules<char_type> rules_;
Modified: trunk/boost/spirit/home/lex/lexer/lexertl/token.hpp
==============================================================================
--- trunk/boost/spirit/home/lex/lexer/lexertl/token.hpp (original)
+++ trunk/boost/spirit/home/lex/lexer/lexertl/token.hpp 2009-07-05 14:50:29 EDT (Sun, 05 Jul 2009)
@@ -117,6 +117,7 @@
typedef Iterator iterator_type;
typedef mpl::false_ has_state;
typedef std::size_t id_type;
+ typedef unused_type token_value_type;
// default constructed tokens correspond to EOI tokens
token() : id_(boost::lexer::npos) {}
@@ -126,6 +127,9 @@
token(id_type id, std::size_t) : id_(id) {}
+ token(id_type id, std::size_t, token_value_type)
+ : id_(id) {}
+
token(id_type id, std::size_t, Iterator const& first
, Iterator const& last)
: id_(id)
@@ -204,6 +208,10 @@
token(id_type id, std::size_t state)
: base_type(id, boost::lexer::npos), state_(state) {}
+ token(id_type id, std::size_t state, token_value_type)
+ : base_type(id, boost::lexer::npos, unused)
+ , state_(state) {}
+
token(id_type id, std::size_t state
, Iterator const& first, Iterator const& last)
: base_type(id, boost::lexer::npos, first, last)
@@ -292,11 +300,13 @@
// from the iterator pair to the required data type is done when it is
// accessed for the first time.
typedef iterator_range<Iterator> iterpair_type;
+
+ public:
+ typedef typename base_type::id_type id_type;
typedef typename detail::token_value_type<
iterpair_type, AttributeTypes
>::type token_value_type;
- public:
typedef Iterator iterator_type;
// default constructed tokens correspond to EOI tokens
@@ -307,7 +317,11 @@
: base_type(0)
, value_(iterpair_type(iterator_type(), iterator_type())) {}
- token(std::size_t id, std::size_t state, Iterator const& first
+ token(id_type id, std::size_t state, token_value_type const& value)
+ : base_type(id, state, value)
+ , value_(value) {}
+
+ token(id_type id, std::size_t state, Iterator const& first
, Iterator const& last)
: base_type(id, state, first, last)
, value_(iterpair_type(first, last)) {}
Modified: trunk/boost/spirit/home/lex/lexer/pass_flags.hpp
==============================================================================
--- trunk/boost/spirit/home/lex/lexer/pass_flags.hpp (original)
+++ trunk/boost/spirit/home/lex/lexer/pass_flags.hpp 2009-07-05 14:50:29 EDT (Sun, 05 Jul 2009)
@@ -17,9 +17,10 @@
///////////////////////////////////////////////////////////////////////////
BOOST_SCOPED_ENUM_START(pass_flags)
{
- pass_fail = 0, // make the current match fail in retrospective
- pass_normal = 1, // continue normal token matching, that's the default
- pass_ignore = 2 // ignore the current token and start matching the next
+ pass_fail = 0, // make the current match fail in retrospective
+ pass_normal = 1, // continue normal token matching, that's the default
+ pass_ignore = 2, // ignore the current token and start matching the next
+ pass_use_value = 3 // continue normal matching but use token value as set before
};
BOOST_SCOPED_ENUM_END
Modified: trunk/boost/spirit/home/lex/tokenize_and_parse.hpp
==============================================================================
--- trunk/boost/spirit/home/lex/tokenize_and_parse.hpp (original)
+++ trunk/boost/spirit/home/lex/tokenize_and_parse.hpp 2009-07-05 14:50:29 EDT (Sun, 05 Jul 2009)
@@ -249,6 +249,29 @@
// in its 'INITIAL' state.
//
///////////////////////////////////////////////////////////////////////////
+ namespace detail
+ {
+ template <typename Token>
+ bool tokenize_callback(Token const& t, void (*f)(Token const&))
+ {
+ f(t);
+ return true;
+ }
+
+ template <typename Token, typename Eval>
+ bool tokenize_callback(Token const& t, phoenix::actor<Eval> const& f)
+ {
+ f(t);
+ return true;
+ }
+
+ template <typename Token>
+ bool tokenize_callback(Token const& t, bool (*f)(Token const&))
+ {
+ return f(t);
+ }
+ }
+
template <typename Iterator, typename Lexer, typename F>
inline bool
tokenize(Iterator& first, Iterator last, Lexer const& lex, F f
@@ -260,7 +283,7 @@
iterator_type end = lex.end();
for (/**/; iter != end; ++iter)
{
- if (!f(*iter))
+ if (!detail::tokenize_callback(*iter, f))
return false;
}
return (iter == end) ? true : false;
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk