📄 lexer.hpp
字号:
// Copyright (c) 2001-2008 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(BOOST_SPIRIT_LEX_LEXER_MAR_13_2007_0145PM)#define BOOST_SPIRIT_LEX_LEXER_MAR_13_2007_0145PM#if defined(_MSC_VER) && (_MSC_VER >= 1020)#pragma once // MS compatible compilers support #pragma once#endif#include <boost/spirit/home/support/safe_bool.hpp>#include <boost/spirit/home/lex/lexer/lexer_fwd.hpp>#include <boost/spirit/home/lex/lexer/terminal_holder.hpp>#include <boost/spirit/home/lex/lexer/token_def.hpp>#include <boost/noncopyable.hpp>#include <boost/detail/iterator.hpp>#include <boost/fusion/include/vector.hpp>#include <boost/assert.hpp>#include <boost/mpl/assert.hpp>#include <string>#include <boost/range/iterator_range.hpp>namespace boost { namespace spirit { namespace lex{ namespace detail { /////////////////////////////////////////////////////////////////////// template <typename LexerDef> struct lexer_def_ : public proto::extends< typename make_terminal_holder< lexer_def_<LexerDef> const*, lexer_def_<LexerDef> >::type, lexer_def_<LexerDef> > { private: // avoid warnings about using 'this' in constructor lexer_def_& this_() { return *this; } // initialize proto base class typedef terminal_holder<lexer_def_ const*, lexer_def_> terminal_holder_; typedef typename proto::terminal<terminal_holder_>::type tag; typedef proto::extends<tag, lexer_def_> base_type; typedef typename LexerDef::id_type id_type; tag make_tag() const { tag xpr = {{ this }}; return xpr; } typedef typename LexerDef::char_type char_type; typedef typename LexerDef::string_type string_type; public: // Qi interface: metafunction calculating parser return type template <typename Component, typename Context, typename Iterator> struct attribute { // the return value of a token set contains the matched token // id, and the corresponding pair of iterators typedef typename Iterator::base_iterator_type iterator_type; typedef fusion::vector<id_type, iterator_range<iterator_type> > type; }; private: // Qi interface: parse functionality template <typename Iterator, typename Context, typename Skipper, typename Attribute> bool parse(Iterator& first, Iterator const& last, Context& context, Skipper const& skipper, Attribute& attr) const { qi::skip(first, last, skipper); // always do a pre-skip if (first != last) { typedef typename boost::detail::iterator_traits<Iterator>::value_type token_type; token_type &t = *first; if (token_is_valid(t)) { // any of the token definitions matched qi::detail::assign_to(t, attr); ++first; return true; } } return false; } friend struct terminal_director; static std::string what() { return "lexer"; } // allow to use the lexer.self.add("regex1", id1)("regex2", id2); // syntax struct adder { adder(lexer_def_& def_) : def(def_) {} adder const& operator()(char_type c, id_type token_id = 0) const { if (0 == token_id) token_id = static_cast<id_type>(c); def.def.add_token (def.state.c_str(), lex::detail::escape(c), token_id); return *this; } adder const& operator()(string_type const& s, id_type token_id = id_type()) const { if (0 == token_id) token_id = next_id<id_type>::get(); def.def.add_token (def.state.c_str(), s, token_id); return *this; } template <typename Attribute> adder const& operator()(token_def<Attribute, char_type, id_type>& tokdef, id_type token_id = id_type()) const { // make sure we have a token id if (0 == token_id) { if (0 == tokdef.id()) { token_id = next_id<id_type>::get(); tokdef.id(token_id); } else { token_id = tokdef.id(); } } else { // the following assertion makes sure, that the token_def // instance has not been assigned a different id earlier BOOST_ASSERT(0 == tokdef.id() || token_id == tokdef.id()); tokdef.id(token_id); } def.define(tokdef); return *this; } template <typename TokenSet> adder const& operator()(token_set<TokenSet>& tokset) const { def.define(tokset); return *this; } lexer_def_& def; }; friend struct adder; // allow to use lexer.self.add_pattern("pattern1", "regex1")(...); // syntax struct pattern_adder { pattern_adder(lexer_def_& def_) : def(def_) {} pattern_adder const& operator()(string_type const& p, string_type const& s) const { def.def.add_pattern (def.state.c_str(), p, s); return *this; } lexer_def_& def; }; friend struct pattern_adder; public: /////////////////////////////////////////////////////////////////// template <typename Expr> void define(Expr const& xpr) { typedef typename result_of::as_component<lex::domain, Expr>::type component; typedef typename component::director director; component c = spirit::as_component(lex::domain(), xpr); director::collect(c, def, state); } lexer_def_(LexerDef& def_, string_type const& state_) : base_type(make_tag()), add(this_()), add_pattern(this_()), def(def_), state(state_) { } // allow to switch states lexer_def_ operator()(char_type const* state) const { return lexer_def_(def, state); } lexer_def_ operator()(string_type const& state) const { return lexer_def_(def, state); } // allow to assign a token definition expression template <typename Expr> lexer_def_& operator= (Expr const& xpr) { typedef spirit::traits::is_component<lex::domain, Expr> is_component; // report invalid expression error as early as possible BOOST_MPL_ASSERT_MSG( is_component::value, xpr_is_not_convertible_to_a_token_definition, ()); def.clear(state.c_str()); define(xpr); return *this; } adder add; pattern_adder add_pattern; private: LexerDef& def; string_type state; }; // allow to assign a token definition expression template <typename LexerDef, typename Expr> inline lexer_def_<LexerDef>& operator+= (lexer_def_<LexerDef>& lexdef, Expr& xpr) { typedef spirit::traits::is_component<lex::domain, Expr> is_component; // report invalid expression error as early as possible BOOST_MPL_ASSERT_MSG( is_component::value, xpr_is_not_convertible_to_a_token_definition, ()); lexdef.define(xpr); return lexdef; } template <typename LexerDef, typename Expr> inline lexer_def_<LexerDef>& operator+= (lexer_def_<LexerDef>& lexdef, Expr const& xpr) { typedef spirit::traits::is_component<lex::domain, Expr> is_component; // report invalid expression error as early as possible BOOST_MPL_ASSERT_MSG( is_component::value, xpr_is_not_convertible_to_a_token_definition, ()); lexdef.define(xpr); return lexdef; } } /////////////////////////////////////////////////////////////////////////// // This represents a lexer definition (helper for token and token set // definitions /////////////////////////////////////////////////////////////////////////// template <typename Lexer> class lexer_def : private noncopyable, public Lexer { private: typedef lexer_def self_type; // avoid warnings about using 'this' in constructor lexer_def& this_() { return *this; } public: typedef Lexer lexer_type; typedef typename Lexer::id_type id_type; typedef detail::lexer_def_<self_type> token_set; typedef typename Lexer::char_type char_type; typedef std::basic_string<char_type> string_type; lexer_def() : self(this_(), Lexer::initial_state()) { } token_set self; // allow for easy token definition // this is just a dummy implementation to allow to use lexer_def // directly, without having to derive a separate class void def(token_set& /*self*/) {} }; /////////////////////////////////////////////////////////////////////////// // This represents a lexer object /////////////////////////////////////////////////////////////////////////// template <typename Definition> class lexer : public safe_bool<lexer<Definition> > { public: // operator_bool() is needed for the safe_bool base class bool operator_bool() const { return token_def; } typedef typename Definition::lexer_type lexer_type; typedef typename Definition::char_type char_type; typedef typename Definition::iterator_type iterator_type; typedef typename Definition::id_type id_type; lexer(Definition& token_def_) : token_def(token_def_) { // call initialization routine supplied by the target lexer token_def.def(token_def.self); } // access iterator interface template <typename Iterator> iterator_type begin(Iterator& first, Iterator const& last) const { return token_def.begin(first, last); } iterator_type end() const { return token_def.end(); } std::size_t map_state(char_type const* state) { return token_def.add_state(state); } Definition& get_definition() { return token_def; } Definition const& get_definition() const { return token_def; } private: Definition& token_def; }; /////////////////////////////////////////////////////////////////////////// // Metafunction returning the iterator type of the lexer given the token // definition type. /////////////////////////////////////////////////////////////////////////// template <typename Definition> struct lexer_iterator { typedef typename lexer<Definition>::iterator_type type; }; /////////////////////////////////////////////////////////////////////////// // Generator function helping to construct a proper lexer object // instance /////////////////////////////////////////////////////////////////////////// template <typename Definition> inline lexer<Definition> make_lexer(Definition& def) { return lexer<Definition>(def); } }}}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -