parser_traits.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 475 行 · 第 1/2 页

HPP
475
字号
///////////////////////////////////////////////////////////////////////////////// detail/dynamic/parser_traits.hpp////  Copyright 2008 Eric Niebler. 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)#ifndef BOOST_XPRESSIVE_DETAIL_DYNAMIC_PARSER_TRAITS_HPP_EAN_10_04_2005#define BOOST_XPRESSIVE_DETAIL_DYNAMIC_PARSER_TRAITS_HPP_EAN_10_04_2005// MS compatible compilers support #pragma once#if defined(_MSC_VER) && (_MSC_VER >= 1020)# pragma once#endif#include <string>#include <climits>#include <boost/assert.hpp>#include <boost/throw_exception.hpp>#include <boost/xpressive/regex_error.hpp>#include <boost/xpressive/regex_traits.hpp>#include <boost/xpressive/detail/detail_fwd.hpp>#include <boost/xpressive/detail/dynamic/matchable.hpp>#include <boost/xpressive/detail/dynamic/parser_enum.hpp>#include <boost/xpressive/detail/utility/literals.hpp>#include <boost/xpressive/detail/utility/algorithm.hpp>namespace boost { namespace xpressive{///////////////////////////////////////////////////////////////////////////////// compiler_traits//  this works for char and wchar_t. it must be specialized for anything else.//template<typename RegexTraits>struct compiler_traits{    typedef RegexTraits regex_traits;    typedef typename regex_traits::char_type char_type;    typedef typename regex_traits::string_type string_type;    typedef typename regex_traits::locale_type locale_type;    ///////////////////////////////////////////////////////////////////////////////    // constructor    explicit compiler_traits(RegexTraits const &traits = RegexTraits())      : traits_(traits)      , flags_(regex_constants::ECMAScript)      , space_(lookup_classname(traits_, "space"))      , alnum_(lookup_classname(traits_, "alnum"))    {    }    ///////////////////////////////////////////////////////////////////////////////    // flags    regex_constants::syntax_option_type flags() const    {        return this->flags_;    }    ///////////////////////////////////////////////////////////////////////////////    // flags    void flags(regex_constants::syntax_option_type flags)    {        this->flags_ = flags;    }    ///////////////////////////////////////////////////////////////////////////////    // traits    regex_traits &traits()    {        return this->traits_;    }    regex_traits const &traits() const    {        return this->traits_;    }    ///////////////////////////////////////////////////////////////////////////////    // imbue    locale_type imbue(locale_type const &loc)    {        locale_type oldloc = this->traits().imbue(loc);        this->space_ = lookup_classname(this->traits(), "space");        this->alnum_ = lookup_classname(this->traits(), "alnum");        return oldloc;    }    ///////////////////////////////////////////////////////////////////////////////    // getloc    locale_type getloc() const    {        return this->traits().getloc();    }    ///////////////////////////////////////////////////////////////////////////////    // get_token    //  get a token and advance the iterator    template<typename FwdIter>    regex_constants::compiler_token_type get_token(FwdIter &begin, FwdIter end)    {        using namespace regex_constants;        if(this->eat_ws_(begin, end) == end)        {            return regex_constants::token_end_of_pattern;        }        switch(*begin)        {        case BOOST_XPR_CHAR_(char_type, '\\'): return this->get_escape_token(++begin, end);        case BOOST_XPR_CHAR_(char_type, '.'): ++begin; return token_any;        case BOOST_XPR_CHAR_(char_type, '^'): ++begin; return token_assert_begin_line;        case BOOST_XPR_CHAR_(char_type, '$'): ++begin; return token_assert_end_line;        case BOOST_XPR_CHAR_(char_type, '('): ++begin; return token_group_begin;        case BOOST_XPR_CHAR_(char_type, ')'): ++begin; return token_group_end;        case BOOST_XPR_CHAR_(char_type, '|'): ++begin; return token_alternate;        case BOOST_XPR_CHAR_(char_type, '['): ++begin; return token_charset_begin;        case BOOST_XPR_CHAR_(char_type, '*'):        case BOOST_XPR_CHAR_(char_type, '+'):        case BOOST_XPR_CHAR_(char_type, '?'):            return token_invalid_quantifier;        case BOOST_XPR_CHAR_(char_type, ']'):        case BOOST_XPR_CHAR_(char_type, '{'):        default:            return token_literal;        }    }    ///////////////////////////////////////////////////////////////////////////////    // get_quant_spec    template<typename FwdIter>    bool get_quant_spec(FwdIter &begin, FwdIter end, detail::quant_spec &spec)    {        using namespace regex_constants;        FwdIter old_begin;        if(this->eat_ws_(begin, end) == end)        {            return false;        }        switch(*begin)        {        case BOOST_XPR_CHAR_(char_type, '*'):            spec.min_ = 0;            spec.max_ = (std::numeric_limits<unsigned int>::max)();            break;        case BOOST_XPR_CHAR_(char_type, '+'):            spec.min_ = 1;            spec.max_ = (std::numeric_limits<unsigned int>::max)();            break;        case BOOST_XPR_CHAR_(char_type, '?'):            spec.min_ = 0;            spec.max_ = 1;            break;        case BOOST_XPR_CHAR_(char_type, '{'):            old_begin = this->eat_ws_(++begin, end);            spec.min_ = spec.max_ = detail::toi(begin, end, this->traits());            detail::ensure            (                begin != old_begin && begin != end, error_brace, "invalid quantifier"            );            if(*begin == BOOST_XPR_CHAR_(char_type, ','))            {                old_begin = this->eat_ws_(++begin, end);                spec.max_ = detail::toi(begin, end, this->traits());                detail::ensure                (                    begin != end && BOOST_XPR_CHAR_(char_type, '}') == *begin                  , error_brace, "invalid quantifier"                );                if(begin == old_begin)                {                    spec.max_ = (std::numeric_limits<unsigned int>::max)();                }                else                {                    detail::ensure                    (                        spec.min_ <= spec.max_, error_badbrace, "invalid quantification range"                    );                }            }            else            {                detail::ensure                (                    BOOST_XPR_CHAR_(char_type, '}') == *begin, error_brace, "invalid quantifier"                );            }            break;        default:            return false;        }        spec.greedy_ = true;        if(this->eat_ws_(++begin, end) != end && BOOST_XPR_CHAR_(char_type, '?') == *begin)        {            ++begin;            spec.greedy_ = false;        }        return true;    }    ///////////////////////////////////////////////////////////////////////////    // get_group_type    template<typename FwdIter>    regex_constants::compiler_token_type get_group_type(FwdIter &begin, FwdIter end, string_type &name)    {        using namespace regex_constants;        if(this->eat_ws_(begin, end) != end && BOOST_XPR_CHAR_(char_type, '?') == *begin)        {            this->eat_ws_(++begin, end);            detail::ensure(begin != end, error_paren, "incomplete extension");            switch(*begin)            {            case BOOST_XPR_CHAR_(char_type, ':'): ++begin; return token_no_mark;            case BOOST_XPR_CHAR_(char_type, '>'): ++begin; return token_independent_sub_expression;            case BOOST_XPR_CHAR_(char_type, '#'): ++begin; return token_comment;            case BOOST_XPR_CHAR_(char_type, '='): ++begin; return token_positive_lookahead;            case BOOST_XPR_CHAR_(char_type, '!'): ++begin; return token_negative_lookahead;            case BOOST_XPR_CHAR_(char_type, 'R'): ++begin; return token_recurse;            case BOOST_XPR_CHAR_(char_type, '$'):                this->get_name_(++begin, end, name);                detail::ensure(begin != end, error_paren, "incomplete extension");                if(BOOST_XPR_CHAR_(char_type, '=') == *begin)                {                    ++begin;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?