1 /*=============================================================================
2     Copyright (c) 2001-2011 Joel de Guzman
3 
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 =============================================================================*/
7 #ifndef BOOST_SPIRIT_QI_DIRECTIVE_LEXEME_HPP
8 #define BOOST_SPIRIT_QI_DIRECTIVE_LEXEME_HPP
9 
10 #if defined(_MSC_VER)
11 #pragma once
12 #endif
13 
14 #include <boost/spirit/home/qi/meta_compiler.hpp>
15 #include <boost/spirit/home/qi/skip_over.hpp>
16 #include <boost/spirit/home/qi/parser.hpp>
17 #include <boost/spirit/home/qi/detail/unused_skipper.hpp>
18 #include <boost/spirit/home/support/unused.hpp>
19 #include <boost/spirit/home/support/common_terminals.hpp>
20 #include <boost/spirit/home/qi/detail/attributes.hpp>
21 #include <boost/spirit/home/support/info.hpp>
22 #include <boost/spirit/home/support/handles_container.hpp>
23 #include <boost/utility/enable_if.hpp>
24 
25 namespace boost { namespace spirit
26 {
27     ///////////////////////////////////////////////////////////////////////////
28     // Enablers
29     ///////////////////////////////////////////////////////////////////////////
30     template <>
31     struct use_directive<qi::domain, tag::lexeme> // enables lexeme
32       : mpl::true_ {};
33 }}
34 
35 namespace boost { namespace spirit { namespace qi
36 {
37 #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
38     using spirit::lexeme;
39 #endif
40     using spirit::lexeme_type;
41 
42     template <typename Subject>
43     struct lexeme_directive : unary_parser<lexeme_directive<Subject> >
44     {
45         typedef Subject subject_type;
lexeme_directiveboost::spirit::qi::lexeme_directive46         lexeme_directive(Subject const& subject_)
47           : subject(subject_) {}
48 
49         template <typename Context, typename Iterator>
50         struct attribute
51         {
52             typedef typename
53                 traits::attribute_of<subject_type, Context, Iterator>::type
54             type;
55         };
56 
57         template <typename Iterator, typename Context
58           , typename Skipper, typename Attribute>
59         typename disable_if<detail::is_unused_skipper<Skipper>, bool>::type
parseboost::spirit::qi::lexeme_directive60         parse(Iterator& first, Iterator const& last
61           , Context& context, Skipper const& skipper
62           , Attribute& attr_) const
63         {
64             qi::skip_over(first, last, skipper);
65             return subject.parse(first, last, context
66               , detail::unused_skipper<Skipper>(skipper), attr_);
67         }
68         template <typename Iterator, typename Context
69           , typename Skipper, typename Attribute>
70         typename enable_if<detail::is_unused_skipper<Skipper>, bool>::type
parseboost::spirit::qi::lexeme_directive71         parse(Iterator& first, Iterator const& last
72           , Context& context, Skipper const& skipper
73           , Attribute& attr_) const
74         {
75             //  no need to pre-skip if skipper is unused
76             //- qi::skip_over(first, last, skipper);
77             return subject.parse(first, last, context
78               , skipper, attr_);
79         }
80 
81         template <typename Context>
whatboost::spirit::qi::lexeme_directive82         info what(Context& context) const
83         {
84             return info("lexeme", subject.what(context));
85 
86         }
87 
88         Subject subject;
89     };
90 
91     ///////////////////////////////////////////////////////////////////////////
92     // Parser generators: make_xxx function (objects)
93     ///////////////////////////////////////////////////////////////////////////
94     template <typename Subject, typename Modifiers>
95     struct make_directive<tag::lexeme, Subject, Modifiers>
96     {
97         typedef lexeme_directive<Subject> result_type;
operator ()boost::spirit::qi::make_directive98         result_type operator()(unused_type, Subject const& subject, unused_type) const
99         {
100             return result_type(subject);
101         }
102     };
103 }}}
104 
105 namespace boost { namespace spirit { namespace traits
106 {
107     ///////////////////////////////////////////////////////////////////////////
108     template <typename Subject>
109     struct has_semantic_action<qi::lexeme_directive<Subject> >
110       : unary_has_semantic_action<Subject> {};
111 
112     ///////////////////////////////////////////////////////////////////////////
113     template <typename Subject, typename Attribute, typename Context
114         , typename Iterator>
115     struct handles_container<qi::lexeme_directive<Subject>, Attribute
116         , Context, Iterator>
117       : unary_handles_container<Subject, Attribute, Context, Iterator> {};
118 }}}
119 
120 #endif
121