parser.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 361 行

HPP
361
字号
////////////////////////////////////////////////////////////////////////////////// \file parser.hpp/// Contains the definition of regex_compiler, a factory for building regex objects/// from strings.////  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_HPP_EAN_10_04_2005#define BOOST_XPRESSIVE_DETAIL_DYNAMIC_PARSER_HPP_EAN_10_04_2005// MS compatible compilers support #pragma once#if defined(_MSC_VER) && (_MSC_VER >= 1020)# pragma once# pragma warning(push)# pragma warning(disable : 4127) // conditional expression is constant#endif#include <boost/assert.hpp>#include <boost/xpressive/regex_constants.hpp>#include <boost/xpressive/detail/detail_fwd.hpp>#include <boost/xpressive/detail/core/matchers.hpp>#include <boost/xpressive/detail/utility/ignore_unused.hpp>#include <boost/xpressive/detail/dynamic/dynamic.hpp>// The Regular Expression grammar, in pseudo BNF://// expression   = alternates ;//// alternates   = sequence, *('|', sequence) ;//// sequence     = quant, *(quant) ;//// quant        = atom, [*+?] ;//// atom         = literal             |//                '.'                 |//                '\' any             |//                '(' expression ')' ;//// literal      = not a meta-character ;//namespace boost { namespace xpressive { namespace detail{///////////////////////////////////////////////////////////////////////////////// make_char_xpression//template<typename BidiIter, typename Char, typename Traits>inline sequence<BidiIter> make_char_xpression(    Char ch  , regex_constants::syntax_option_type flags  , Traits const &traits){    if(0 != (regex_constants::icase_ & flags))    {        literal_matcher<Traits, mpl::true_, mpl::false_> matcher(ch, traits);        return make_dynamic<BidiIter>(matcher);    }    else    {        literal_matcher<Traits, mpl::false_, mpl::false_> matcher(ch, traits);        return make_dynamic<BidiIter>(matcher);    }}///////////////////////////////////////////////////////////////////////////////// make_any_xpression//template<typename BidiIter, typename Traits>inline sequence<BidiIter> make_any_xpression(    regex_constants::syntax_option_type flags  , Traits const &traits){    using namespace regex_constants;    typedef typename iterator_value<BidiIter>::type char_type;    typedef detail::set_matcher<Traits, mpl::int_<2> > set_matcher;    typedef literal_matcher<Traits, mpl::false_, mpl::true_> literal_matcher;    char_type const newline = traits.widen('\n');    set_matcher s;    s.set_[0] = newline;    s.set_[1] = 0;    s.inverse();    switch(((int)not_dot_newline | not_dot_null) & flags)    {    case not_dot_null:        return make_dynamic<BidiIter>(literal_matcher(char_type(0), traits));    case not_dot_newline:        return make_dynamic<BidiIter>(literal_matcher(newline, traits));    case (int)not_dot_newline | not_dot_null:        return make_dynamic<BidiIter>(s);    default:        return make_dynamic<BidiIter>(any_matcher());    }}///////////////////////////////////////////////////////////////////////////////// make_literal_xpression//template<typename BidiIter, typename Traits>inline sequence<BidiIter> make_literal_xpression(    typename Traits::string_type const &literal  , regex_constants::syntax_option_type flags  , Traits const &traits){    BOOST_ASSERT(0 != literal.size());    if(1 == literal.size())    {        return make_char_xpression<BidiIter>(literal[0], flags, traits);    }    if(0 != (regex_constants::icase_ & flags))    {        string_matcher<Traits, mpl::true_> matcher(literal, traits);        return make_dynamic<BidiIter>(matcher);    }    else    {        string_matcher<Traits, mpl::false_> matcher(literal, traits);        return make_dynamic<BidiIter>(matcher);    }}///////////////////////////////////////////////////////////////////////////////// make_backref_xpression//template<typename BidiIter, typename Traits>inline sequence<BidiIter> make_backref_xpression(    int mark_nbr  , regex_constants::syntax_option_type flags  , Traits const &traits){    if(0 != (regex_constants::icase_ & flags))    {        return make_dynamic<BidiIter>        (            mark_matcher<Traits, mpl::true_>(mark_nbr, traits)        );    }    else    {        return make_dynamic<BidiIter>        (            mark_matcher<Traits, mpl::false_>(mark_nbr, traits)        );    }}///////////////////////////////////////////////////////////////////////////////// merge_charset//template<typename Char, typename Traits>inline void merge_charset(    basic_chset<Char> &basic  , compound_charset<Traits> const &compound  , Traits const &traits){    detail::ignore_unused(traits);    if(0 != compound.posix_yes())    {        typename Traits::char_class_type mask = compound.posix_yes();        for(int i = 0; i <= UCHAR_MAX; ++i)        {            if(traits.isctype((Char)i, mask))            {                basic.set((Char)i);            }        }    }    if(!compound.posix_no().empty())    {        for(std::size_t j = 0; j < compound.posix_no().size(); ++j)        {            typename Traits::char_class_type mask = compound.posix_no()[j];            for(int i = 0; i <= UCHAR_MAX; ++i)            {                if(!traits.isctype((Char)i, mask))                {                    basic.set((Char)i);                }            }        }    }    if(compound.is_inverted())    {        basic.inverse();    }}///////////////////////////////////////////////////////////////////////////////// make_charset_xpression//template<typename BidiIter, typename Traits>inline sequence<BidiIter> make_charset_xpression(    compound_charset<Traits> &chset  , Traits const &traits  , regex_constants::syntax_option_type flags){    typedef typename Traits::char_type char_type;    bool const icase = (0 != (regex_constants::icase_ & flags));    bool const optimize = is_narrow_char<char_type>::value && 0 != (regex_constants::optimize & flags);    // don't care about compile speed -- fold eveything into a bitset<256>    if(optimize)    {        typedef basic_chset<char_type> charset_type;        charset_type charset(chset.base());        if(icase)        {            charset_matcher<Traits, mpl::true_, charset_type> matcher(charset);            merge_charset(matcher.charset_, chset, traits);            return make_dynamic<BidiIter>(matcher);        }        else        {            charset_matcher<Traits, mpl::false_, charset_type> matcher(charset);            merge_charset(matcher.charset_, chset, traits);            return make_dynamic<BidiIter>(matcher);        }    }    // special case to make [[:digit:]] fast    else if(chset.base().empty() && chset.posix_no().empty())    {        BOOST_ASSERT(0 != chset.posix_yes());        posix_charset_matcher<Traits> matcher(chset.posix_yes(), chset.is_inverted());        return make_dynamic<BidiIter>(matcher);    }    // default, slow    else    {        if(icase)        {            charset_matcher<Traits, mpl::true_> matcher(chset);            return make_dynamic<BidiIter>(matcher);        }        else        {            charset_matcher<Traits, mpl::false_> matcher(chset);            return make_dynamic<BidiIter>(matcher);        }    }}///////////////////////////////////////////////////////////////////////////////// make_posix_charset_xpression//template<typename BidiIter, typename Traits>inline sequence<BidiIter> make_posix_charset_xpression(    typename Traits::char_class_type m  , bool no  , regex_constants::syntax_option_type //flags  , Traits const & //traits){    posix_charset_matcher<Traits> charset(m, no);    return make_dynamic<BidiIter>(charset);}///////////////////////////////////////////////////////////////////////////////// make_assert_begin_line//template<typename BidiIter, typename Traits>inline sequence<BidiIter> make_assert_begin_line(    regex_constants::syntax_option_type flags  , Traits const &traits){    if(0 != (regex_constants::single_line & flags))    {        return detail::make_dynamic<BidiIter>(detail::assert_bos_matcher());    }    else    {        detail::assert_bol_matcher<Traits> matcher(traits);        return detail::make_dynamic<BidiIter>(matcher);    }}///////////////////////////////////////////////////////////////////////////////// make_assert_end_line//template<typename BidiIter, typename Traits>inline sequence<BidiIter> make_assert_end_line(    regex_constants::syntax_option_type flags  , Traits const &traits){    if(0 != (regex_constants::single_line & flags))    {        return detail::make_dynamic<BidiIter>(detail::assert_eos_matcher());    }    else    {        detail::assert_eol_matcher<Traits> matcher(traits);        return detail::make_dynamic<BidiIter>(matcher);    }}///////////////////////////////////////////////////////////////////////////////// make_assert_word//template<typename BidiIter, typename Cond, typename Traits>inline sequence<BidiIter> make_assert_word(Cond, Traits const &traits){    typedef typename iterator_value<BidiIter>::type char_type;    return detail::make_dynamic<BidiIter>    (        detail::assert_word_matcher<Cond, Traits>(traits)    );}///////////////////////////////////////////////////////////////////////////////// make_independent_end_xpression//template<typename BidiIter>inline sequence<BidiIter> make_independent_end_xpression(bool pure){    if(pure)    {        return detail::make_dynamic<BidiIter>(detail::true_matcher());    }    else    {        return detail::make_dynamic<BidiIter>(detail::independent_end_matcher());    }}}}} // namespace boost::xpressive::detail#if defined(_MSC_VER) && (_MSC_VER >= 1020)# pragma warning(pop)#endif#endif

⌨️ 快捷键说明

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