201007c533
[SVN r73578]
145 lines
5.1 KiB
C++
145 lines
5.1 KiB
C++
/*=============================================================================
|
|
Copyright (c) 2001-2011 Hartmut Kaiser
|
|
Copyright (c) 2001-2011 Joel de Guzman
|
|
|
|
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_CONJURE_LEXER_HPP)
|
|
#define BOOST_SPIRIT_CONJURE_LEXER_HPP
|
|
|
|
#include <boost/spirit/include/lex_lexertl.hpp>
|
|
#include <boost/spirit/include/lex_lexertl_position_token.hpp>
|
|
|
|
#include "config.hpp"
|
|
#include "ids.hpp"
|
|
|
|
#if CONJURE_LEXER_STATIC_TABLES != 0
|
|
#include <boost/spirit/include/lex_static_lexertl.hpp>
|
|
#include "conjure_static_lexer.hpp"
|
|
#elif CONJURE_LEXER_STATIC_SWITCH != 0
|
|
#include <boost/spirit/include/lex_static_lexertl.hpp>
|
|
#include "conjure_static_switch_lexer.hpp"
|
|
#endif
|
|
#include <boost/assert.hpp>
|
|
|
|
namespace client { namespace lexer
|
|
{
|
|
namespace lex = boost::spirit::lex;
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
namespace detail
|
|
{
|
|
namespace lex = boost::spirit::lex;
|
|
|
|
template <typename BaseIterator>
|
|
struct get_lexer_type
|
|
{
|
|
// Our token needs to be able to carry several token values:
|
|
// std::string, unsigned int, and bool
|
|
typedef boost::mpl::vector<std::string, unsigned int, bool>
|
|
token_value_types;
|
|
|
|
// Using the position_token class as the token type to be returned
|
|
// from the lexer iterators allows to retain positional information
|
|
// as every token instance stores an iterator pair pointing to the
|
|
// matched input sequence.
|
|
typedef lex::lexertl::position_token<
|
|
BaseIterator, token_value_types, boost::mpl::false_
|
|
> token_type;
|
|
|
|
#if CONJURE_LEXER_DYNAMIC_TABLES != 0
|
|
// use the lexer based on runtime generated DFA tables
|
|
typedef lex::lexertl::actor_lexer<token_type> type;
|
|
#elif CONJURE_LEXER_STATIC_TABLES != 0
|
|
// use the lexer based on pre-generated static DFA tables
|
|
typedef lex::lexertl::static_actor_lexer<
|
|
token_type
|
|
, boost::spirit::lex::lexertl::static_::lexer_conjure_static
|
|
> type;
|
|
#elif CONJURE_LEXER_STATIC_SWITCH != 0
|
|
// use the lexer based on pre-generated static code
|
|
typedef lex::lexertl::static_actor_lexer<
|
|
token_type
|
|
, boost::spirit::lex::lexertl::static_::lexer_conjure_static_switch
|
|
> type;
|
|
#else
|
|
#error "Configuration problem: please select exactly one type of lexer to build"
|
|
#endif
|
|
};
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
template <typename BaseIterator>
|
|
struct conjure_tokens
|
|
: lex::lexer<typename detail::get_lexer_type<BaseIterator>::type>
|
|
{
|
|
private:
|
|
// get the type of any qi::raw_token(...) and qi::token(...) constructs
|
|
typedef typename boost::spirit::result_of::terminal<
|
|
boost::spirit::tag::raw_token(token_ids::type)
|
|
>::type raw_token_spec;
|
|
|
|
typedef typename boost::spirit::result_of::terminal<
|
|
boost::spirit::tag::token(token_ids::type)
|
|
>::type token_spec;
|
|
|
|
typedef std::map<std::string, token_ids::type> keyword_map_type;
|
|
|
|
protected:
|
|
// add a keyword to the mapping table
|
|
bool add_(std::string const& keyword, int id = token_ids::invalid);
|
|
|
|
struct keyword_adder
|
|
{
|
|
conjure_tokens& l;
|
|
keyword_adder(conjure_tokens& l) : l(l) {}
|
|
keyword_adder& operator()(
|
|
std::string const& keyword, int id = token_ids::invalid)
|
|
{
|
|
l.add_(keyword, id);
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
friend struct keyword_adder;
|
|
keyword_adder add;
|
|
|
|
public:
|
|
typedef BaseIterator base_iterator_type;
|
|
|
|
conjure_tokens();
|
|
|
|
// extract a raw_token(id) for the given registered keyword
|
|
raw_token_spec operator()(std::string const& kwd) const
|
|
{
|
|
namespace qi = boost::spirit::qi;
|
|
qi::raw_token_type raw_token;
|
|
|
|
typename keyword_map_type::const_iterator it = keywords_.find(kwd);
|
|
BOOST_ASSERT(it != keywords_.end());
|
|
return raw_token((it != keywords_.end()) ? (*it).second : token_ids::invalid);
|
|
}
|
|
|
|
// extract a token(id) for the given registered keyword
|
|
token_spec token(std::string const& kwd) const
|
|
{
|
|
namespace qi = boost::spirit::qi;
|
|
qi::token_type token;
|
|
|
|
typename keyword_map_type::const_iterator it = keywords_.find(kwd);
|
|
BOOST_ASSERT(it != keywords_.end());
|
|
return token((it != keywords_.end()) ? (*it).second : token_ids::invalid);
|
|
}
|
|
|
|
lex::token_def<std::string> identifier;
|
|
lex::token_def<unsigned int> lit_uint;
|
|
lex::token_def<bool> true_or_false;
|
|
keyword_map_type keywords_;
|
|
};
|
|
}}
|
|
|
|
#endif
|
|
|
|
|