📄 meta_grammar.hpp
字号:
/*============================================================================= Copyright (c) 2001-2007 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_META_GRAMMAR_FEB_02_2007_0925AM)#define BOOST_SPIRIT_META_GRAMMAR_FEB_02_2007_0925AM#include <boost/spirit/home/qi/domain.hpp>#include <boost/spirit/home/support/placeholders.hpp>#include <boost/spirit/home/support/meta_grammar.hpp>#include <boost/spirit/home/support/char_class.hpp>#include <boost/spirit/home/qi/char/detail/basic_chset.hpp>#include <boost/utility/enable_if.hpp>#include <boost/type_traits/is_same.hpp>#include <boost/shared_ptr.hpp>namespace boost { namespace spirit { namespace qi{ /////////////////////////////////////////////////////////////////////////// // forwards /////////////////////////////////////////////////////////////////////////// template <typename Char> struct any_char; template <typename Char> struct literal_char; struct lazy_char; template <typename Char> struct char_range; struct lazy_char_range; template <typename Positive> struct negated_char_parser; template <typename Tag> struct char_class; struct char_meta_grammar; /////////////////////////////////////////////////////////////////////////// template <typename Expr, typename Enable> struct is_valid_expr; template <typename Expr, typename Enable> struct expr_transform; /////////////////////////////////////////////////////////////////////////// // get the director of an any_char /////////////////////////////////////////////////////////////////////////// template <typename Tag> struct extract_any_char_director; template <> struct extract_any_char_director<tag::char_> { typedef any_char<char> type; }; template <> struct extract_any_char_director<tag::wchar> { typedef any_char<wchar_t> type; }; /////////////////////////////////////////////////////////////////////////// // get the director of a character literal type /////////////////////////////////////////////////////////////////////////// template <typename Tag, typename T> struct extract_literal_char_director; template <typename T> struct extract_literal_char_director<tag::char_, T> { typedef literal_char<T> type; }; template <typename T> struct extract_literal_char_director<tag::wchar, T> { typedef literal_char<wchar_t> type; }; template <typename T> struct extract_literal_char_director<tag::lit, T> { typedef literal_char<T> type; }; template <typename T> struct extract_literal_char_director<tag::wlit, T> { typedef literal_char<wchar_t> type; }; /////////////////////////////////////////////////////////////////////////// // get the director of a character range type /////////////////////////////////////////////////////////////////////////// template <typename Tag, typename T> struct extract_char_range_director; template <typename T> struct extract_char_range_director<tag::char_, T> { typedef char_range<T> type; }; template <typename T> struct extract_char_range_director<tag::wchar, T> { typedef char_range<wchar_t> type; }; /////////////////////////////////////////////////////////////////////////// // char parser meta-grammars /////////////////////////////////////////////////////////////////////////// // literals: 'x', L'x' struct basic_char_literal_meta_grammar : proto::or_< proto::terminal<char> , proto::terminal<wchar_t> > { }; // literals: 'x', L'x' and single char strings: "x", L"x" struct single_char_literal_meta_grammar : proto::or_< // plain chars: proto::terminal<char> , proto::terminal<wchar_t> // single char null terminates strings: , proto::terminal<char[2]> , proto::terminal<char(&)[2]> , proto::terminal<wchar_t[2]> , proto::terminal<wchar_t(&)[2]> > { }; // literals: 'x', L'x' struct char_literal_meta_grammar : proto::or_< meta_grammar::terminal_rule< qi::domain, char, literal_char<char> > , meta_grammar::terminal_rule< qi::domain, wchar_t, literal_char<wchar_t> > > { }; // literal strings: "hello" (defined in qi/string/meta_grammar.hpp) struct basic_string_literal_meta_grammar; // std::string(s) (defined in qi/string/meta_grammar.hpp) struct basic_std_string_meta_grammar; template <typename T> struct extract_char; // (defined in qi/string/metagrammar.hpp) template <typename Tag, typename T> struct extract_chset_director; template <typename T> struct extract_chset_director<tag::char_, T> { typedef typename extract_char<T>::type char_type; typedef char_set<char_type> type; }; template <typename T> struct extract_chset_director<tag::wchar, T> { typedef typename extract_char<T>::type char_type; typedef char_set<char_type> type; }; template <typename Char, typename Elements> struct char_set_component { typedef qi::domain domain; typedef char_set<Char> director; typedef Elements elements_type; char_set_component(Char const* definition) : ptr(new detail::basic_chset<Char>()) { Char ch = *definition++; while (ch) { Char next = *definition++; if (next == '-') { next = *definition++; if (next == 0) { ptr->set(ch); ptr->set('-'); break; } ptr->set(ch, next); } else { ptr->set(ch); } ch = next; } } template <typename CharSetClass> // no-case version char_set_component(Char const* definition, CharSetClass) : ptr(new detail::basic_chset<Char>()) { Char ch = *definition++; while (ch) { Char next = *definition++; if (next == '-') { next = *definition++; if (next == 0) { ptr->set(CharSetClass::tolower(ch)); ptr->set(CharSetClass::tolower('-')); ptr->set(CharSetClass::toupper(ch)); ptr->set(CharSetClass::toupper('-')); break; } ptr->set(CharSetClass::tolower(ch) , CharSetClass::tolower(next)); ptr->set(CharSetClass::toupper(ch) , CharSetClass::toupper(next)); } else { ptr->set(CharSetClass::tolower(ch)); ptr->set(CharSetClass::toupper(ch)); } ch = next; } } boost::shared_ptr<detail::basic_chset<Char> > ptr; }; // char_, char_('x'), char_("x"), char_(f), char_('x', 'z'), // char_(L'x'), char_(L'x', L'z'), // wchar, wchar('x'), wchar("x"), wchar('x', 'z'), // wchar(L'x'), wchar(L'x', L'z') // char_("a-z"), wchar("a-z") // [w]lit('x'), [w]lit(L'x') struct char_meta_grammar1 : proto::or_< // char_, wchar --> any_char meta_grammar::compose_empty< proto::if_< is_char_tag<proto::_arg, qi::domain>() > , qi::domain , mpl::identity<extract_any_char_director<mpl::_> > > // char_('x'), wchar(L'x'), char_("x"), wchar(L"x")--> literal_char , meta_grammar::compose_function1_eval< proto::function< proto::if_< is_char_tag<proto::_arg, qi::domain>() > , single_char_literal_meta_grammar > , qi::domain , mpl::identity<extract_literal_char_director<mpl::_, mpl::_> > > // lit("x"), wlit(L"x") --> literal_char , meta_grammar::compose_function1_eval< proto::function< proto::if_< is_lit_tag<proto::_arg, qi::domain>() > , basic_char_literal_meta_grammar > , qi::domain , mpl::identity<extract_literal_char_director<mpl::_, mpl::_> > > // char_("a-z"), char_(L"a-z"), wchar(L"a-z") --> char_set , meta_grammar::compose_function1_eval< proto::function< proto::if_< is_char_tag<proto::_arg, qi::domain>()> , proto::or_<basic_string_literal_meta_grammar, basic_std_string_meta_grammar> > , qi::domain , mpl::identity<extract_chset_director<mpl::_, mpl::_> > > // char_(F()) --> lazy_char , meta_grammar::function1_rule< qi::domain , tag::char_ , lazy_char > // char_('x', 'z'), wchar(L'x', L'z') --> char_range , meta_grammar::compose_function2_eval< proto::function< proto::if_< is_char_tag<proto::_arg, qi::domain>() > , basic_char_literal_meta_grammar , basic_char_literal_meta_grammar > , qi::domain , mpl::identity<extract_char_range_director<mpl::_, mpl::_> > > // char_(F1(), F2()) --> lazy_char_range , meta_grammar::function2_rule< qi::domain , tag::char_ , lazy_char_range > > { }; // char_classes: alnum, alpha, cntrl, ... etc. struct char_class_meta_grammar : proto::or_< // alnum, alpha, cntrl, ... etc. meta_grammar::compose_empty< proto::terminal<spirit::char_class::key<proto::_, proto::_> > , qi::domain , char_class<mpl::_> > , meta_grammar::compose_empty< proto::terminal<spirit::char_class::lower_case_tag<proto::_> > , qi::domain , char_class<mpl::_> > , meta_grammar::compose_empty< proto::terminal<spirit::char_class::upper_case_tag<proto::_> > , qi::domain , char_class<mpl::_> > > {}; // ~x (where x is a char_parser) struct negated_char_meta_grammar : meta_grammar::compose_single< proto::unary_expr< proto::tag::complement , char_meta_grammar > , qi::domain , negated_char_parser<mpl::_> > { }; // main char_meta_grammar struct char_meta_grammar : proto::or_< char_meta_grammar1 , char_class_meta_grammar , char_literal_meta_grammar , negated_char_meta_grammar > { }; /////////////////////////////////////////////////////////////////////////// // These specializations non-intrusively hooks into the RD meta-grammar. // (see qi/meta_grammar.hpp) /////////////////////////////////////////////////////////////////////////// template <typename Expr> struct is_valid_expr<Expr , typename enable_if<proto::matches<Expr, char_meta_grammar> >::type> : mpl::true_ { }; template <typename Expr> struct expr_transform<Expr , typename enable_if<proto::matches<Expr, char_meta_grammar> >::type> : mpl::identity<char_meta_grammar> { };}}}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -