escape_char.ipp

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

IPP
225
字号
/*=============================================================================    Copyright (c) 2001-2003 Daniel Nuffer    Copyright (c) 2002-2003 Hartmut Kaiser    http://spirit.sourceforge.net/    Use, modification and distribution is subject to 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_SPIRIT_ESCAPE_CHAR_IPP#define BOOST_SPIRIT_ESCAPE_CHAR_IPP#include <boost/spirit/home/classic/core/parser.hpp>#include <boost/spirit/home/classic/core/primitives/numerics.hpp>#include <boost/spirit/home/classic/core/composite/difference.hpp>#include <boost/spirit/home/classic/core/composite/sequence.hpp>///////////////////////////////////////////////////////////////////////////////namespace boost { namespace spirit {BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN///////////////////////////////////////////////////////////////////////////////////  escape_char_parser class/////////////////////////////////////////////////////////////////////////////////const unsigned long c_escapes = 1;const unsigned long lex_escapes = c_escapes << 1;//////////////////////////////////namespace impl {    //////////////////////////////////#if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310))#pragma warning(push)#pragma warning(disable:4127)#endif    template <unsigned long Flags, typename CharT>    struct escape_char_action_parse {        template <typename ParserT, typename ScannerT>        static typename parser_result<ParserT, ScannerT>::type        parse(ScannerT const& scan, ParserT const &p)        {            // Actually decode the escape char.            typedef CharT char_t;            typedef typename ScannerT::iterator_t iterator_t;            typedef typename parser_result<ParserT, ScannerT>::type result_t;            if (scan.first != scan.last) {                iterator_t save = scan.first;                if (result_t hit = p.subject().parse(scan)) {                    char_t unescaped;                    scan.first = save;                    if (*scan.first == '\\') {                        ++scan.first;                        switch (*scan.first) {                        case 'b':   unescaped = '\b';   ++scan.first; break;                        case 't':   unescaped = '\t';   ++scan.first; break;                        case 'n':   unescaped = '\n';   ++scan.first; break;                        case 'f':   unescaped = '\f';   ++scan.first; break;                        case 'r':   unescaped = '\r';   ++scan.first; break;                        case '"':   unescaped = '"';    ++scan.first; break;                        case '\'':  unescaped = '\'';   ++scan.first; break;                        case '\\':  unescaped = '\\';   ++scan.first; break;                        case 'x': case 'X':                            {                                char_t hex = 0;                                char_t const lim =                                    (std::numeric_limits<char_t>::max)() >> 4;                                ++scan.first;                                while (scan.first != scan.last)                                {                                    char_t c = *scan.first;                                    if (hex > lim && impl::isxdigit_(c))                                    {                                        // overflow detected                                        scan.first = save;                                        return scan.no_match();                                    }                                    if (impl::isdigit_(c))                                    {                                        hex <<= 4;                                        hex |= c - '0';                                        ++scan.first;                                    }                                    else if (impl::isxdigit_(c))                                    {                                        hex <<= 4;                                        c = impl::toupper_(c);                                        hex |= c - 'A' + 0xA;                                        ++scan.first;                                    }                                    else                                    {                                        break; // reached the end of the number                                    }                                }                                unescaped = hex;                            }                            break;                        case '0': case '1': case '2': case '3':                        case '4': case '5': case '6': case '7':                            {                                char_t oct = 0;                                char_t const lim =                                    (std::numeric_limits<char_t>::max)() >> 3;                                while (scan.first != scan.last)                                {                                    char_t c = *scan.first;                                    if (oct > lim && (c >= '0' && c <= '7'))                                    {                                        // overflow detected                                        scan.first = save;                                        return scan.no_match();                                    }                                    if (c >= '0' && c <= '7')                                    {                                        oct <<= 3;                                        oct |= c - '0';                                        ++scan.first;                                    }                                    else                                    {                                        break; // reached end of digits                                    }                                }                                unescaped = oct;                            }                            break;                        default:                            if (Flags & c_escapes)                            {                                // illegal C escape sequence                                scan.first = save;                                return scan.no_match();                            }                            else                            {                                unescaped = *scan.first;                                ++scan.first;                            }                            break;                        }                    }                    else {                        unescaped = *scan.first;                        ++scan.first;                    }                    scan.do_action(p.predicate(), unescaped, save, scan.first);                    return hit;                }            }            return scan.no_match(); // overflow detected        }    };#if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310))#pragma warning(pop)#endif    //////////////////////////////////    template <typename CharT>    struct escape_char_parse {        template <typename ScannerT, typename ParserT>        static typename parser_result<ParserT, ScannerT>::type        parse(ScannerT const &scan, ParserT const &/*p*/)        {            typedef                uint_parser<CharT, 8, 1,                    std::numeric_limits<CharT>::digits / 3 + 1                >                oct_parser_t;            typedef                uint_parser<CharT, 16, 1,                    std::numeric_limits<CharT>::digits / 4 + 1                >                hex_parser_t;            typedef alternative<difference<anychar_parser, chlit<CharT> >,                sequence<chlit<CharT>, alternative<alternative<oct_parser_t,                sequence<inhibit_case<chlit<CharT> >, hex_parser_t > >,                difference<difference<anychar_parser,                inhibit_case<chlit<CharT> > >, oct_parser_t > > > >                parser_t;            static parser_t p =                ( (anychar_p - chlit<CharT>(CharT('\\')))                | (chlit<CharT>(CharT('\\')) >>                    (  oct_parser_t()                     | as_lower_d[chlit<CharT>(CharT('x'))] >> hex_parser_t()                     | (anychar_p - as_lower_d[chlit<CharT>(CharT('x'))] - oct_parser_t())                    )                ));            BOOST_SPIRIT_DEBUG_TRACE_NODE(p,                (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_ESCAPE_CHAR) != 0);            return p.parse(scan);        }    };///////////////////////////////////////////////////////////////////////////////} // namespace impl///////////////////////////////////////////////////////////////////////////////BOOST_SPIRIT_CLASSIC_NAMESPACE_END}} // namespace boost::spirit#endif

⌨️ 快捷键说明

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