/*============================================================================= 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 #include #include #include #include #include #include #include namespace boost { namespace spirit { namespace qi { /////////////////////////////////////////////////////////////////////////// // forwards /////////////////////////////////////////////////////////////////////////// template struct any_char; template struct literal_char; struct lazy_char; template struct char_range; struct lazy_char_range; template struct negated_char_parser; template struct char_class; struct char_meta_grammar; /////////////////////////////////////////////////////////////////////////// template struct is_valid_expr; template struct expr_transform; /////////////////////////////////////////////////////////////////////////// // get the director of an any_char /////////////////////////////////////////////////////////////////////////// template struct extract_any_char_director; template <> struct extract_any_char_director { typedef any_char type; }; template <> struct extract_any_char_director { typedef any_char type; }; /////////////////////////////////////////////////////////////////////////// // get the director of a character literal type /////////////////////////////////////////////////////////////////////////// template struct extract_literal_char_director; template struct extract_literal_char_director { typedef literal_char type; }; template struct extract_literal_char_director { typedef literal_char type; }; template struct extract_literal_char_director { typedef literal_char type; }; template struct extract_literal_char_director { typedef literal_char type; }; /////////////////////////////////////////////////////////////////////////// // get the director of a character range type /////////////////////////////////////////////////////////////////////////// template struct extract_char_range_director; template struct extract_char_range_director { typedef char_range type; }; template struct extract_char_range_director { typedef char_range type; }; /////////////////////////////////////////////////////////////////////////// // char parser meta-grammars /////////////////////////////////////////////////////////////////////////// // literals: 'x', L'x' struct basic_char_literal_meta_grammar : proto::or_< proto::terminal , proto::terminal > { }; // literals: 'x', L'x' and single char strings: "x", L"x" struct single_char_literal_meta_grammar : proto::or_< // plain chars: proto::terminal , proto::terminal // single char null terminates strings: , proto::terminal , proto::terminal , proto::terminal , proto::terminal > { }; // literals: 'x', L'x' struct char_literal_meta_grammar : proto::or_< meta_grammar::terminal_rule< qi::domain, char, literal_char > , meta_grammar::terminal_rule< qi::domain, wchar_t, literal_char > > { }; // 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 struct extract_char; // (defined in qi/string/metagrammar.hpp) template struct extract_chset_director; template struct extract_chset_director { typedef typename extract_char::type char_type; typedef char_set type; }; template struct extract_chset_director { typedef typename extract_char::type char_type; typedef char_set type; }; template struct char_set_component { typedef qi::domain domain; typedef char_set director; typedef Elements elements_type; char_set_component(Char const* definition) : ptr(new detail::basic_chset()) { 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 // no-case version char_set_component(Char const* definition, CharSetClass) : ptr(new detail::basic_chset()) { 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 > 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() > , qi::domain , mpl::identity > > // char_('x'), wchar(L'x'), char_("x"), wchar(L"x")--> literal_char , meta_grammar::compose_function1_eval< proto::function< proto::if_< is_char_tag() > , single_char_literal_meta_grammar > , qi::domain , mpl::identity > > // lit("x"), wlit(L"x") --> literal_char , meta_grammar::compose_function1_eval< proto::function< proto::if_< is_lit_tag() > , basic_char_literal_meta_grammar > , qi::domain , mpl::identity > > // 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::or_ > , qi::domain , mpl::identity > > // 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() > , basic_char_literal_meta_grammar , basic_char_literal_meta_grammar > , qi::domain , mpl::identity > > // 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 > , qi::domain , char_class > , meta_grammar::compose_empty< proto::terminal > , qi::domain , char_class > , meta_grammar::compose_empty< proto::terminal > , qi::domain , char_class > > {}; // ~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 > { }; // 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 struct is_valid_expr >::type> : mpl::true_ { }; template struct expr_transform >::type> : mpl::identity { }; }}} #endif