diff DEPENDENCIES/generic/include/boost/wave/grammars/cpp_chlit_grammar.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DEPENDENCIES/generic/include/boost/wave/grammars/cpp_chlit_grammar.hpp	Tue Aug 05 11:11:38 2014 +0100
@@ -0,0 +1,354 @@
+/*=============================================================================
+    Boost.Wave: A Standard compliant C++ preprocessor library
+
+    http://www.boost.org/
+
+    Copyright (c) 2001-2012 Hartmut Kaiser. 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(CPP_CHLIT_GRAMMAR_HPP_9527D349_6592_449A_A409_42A001E6C64C_INCLUDED)
+#define CPP_CHLIT_GRAMMAR_HPP_9527D349_6592_449A_A409_42A001E6C64C_INCLUDED
+
+#include <limits>     // std::numeric_limits
+#include <climits>    // CHAR_BIT
+
+#include <boost/wave/wave_config.hpp>   
+
+#include <boost/static_assert.hpp>
+#include <boost/cstdint.hpp>
+
+#include <boost/spirit/include/classic_core.hpp>
+#include <boost/spirit/include/classic_closure.hpp>
+#include <boost/spirit/include/classic_if.hpp>
+#include <boost/spirit/include/classic_assign_actor.hpp>
+#include <boost/spirit/include/classic_push_back_actor.hpp>
+
+#include <boost/spirit/include/phoenix1_operators.hpp>
+#include <boost/spirit/include/phoenix1_primitives.hpp>
+#include <boost/spirit/include/phoenix1_statements.hpp>
+#include <boost/spirit/include/phoenix1_functions.hpp>
+
+#include <boost/wave/cpp_exceptions.hpp>   
+#include <boost/wave/grammars/cpp_literal_grammar_gen.hpp>
+
+#if !defined(spirit_append_actor)
+#define spirit_append_actor(actor) boost::spirit::classic::push_back_a(actor)
+#define spirit_assign_actor(actor) boost::spirit::classic::assign_a(actor)
+#endif // !defined(spirit_append_actor)
+
+// this must occur after all of the includes and before any code appears
+#ifdef BOOST_HAS_ABI_HEADERS
+#include BOOST_ABI_PREFIX
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  Reusable grammar to parse a C++ style character literal 
+//
+///////////////////////////////////////////////////////////////////////////////
+namespace boost {
+namespace wave { 
+namespace grammars {
+
+namespace closures {
+
+    struct chlit_closure 
+    :   boost::spirit::classic::closure<chlit_closure, boost::uint32_t, bool> 
+    {
+        member1 value;
+        member2 long_lit;
+    };
+}
+
+namespace impl {
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  compose a multibyte character literal
+//
+///////////////////////////////////////////////////////////////////////////////
+    struct compose_character_literal {
+
+        template <typename A1, typename A2, typename A3, typename A4>
+        struct result 
+        { 
+            typedef void type; 
+        };
+
+        void 
+        operator()(boost::uint32_t& value, bool long_lit, bool& overflow,
+            boost::uint32_t character) const
+        { 
+            // The following assumes that wchar_t is max. 32 Bit
+            BOOST_STATIC_ASSERT(sizeof(wchar_t) <= 4);
+            
+            static boost::uint32_t masks[] = { 
+                0x000000ff, 0x0000ffff, 0x00ffffff, 0xffffffff
+            };
+            static boost::uint32_t overflow_masks[] = { 
+                0xff000000, 0xffff0000, 0xffffff00, 0xffffffff
+            };
+            
+            if (long_lit) {
+            // make sure no overflow will occur below
+                if ((value & overflow_masks[sizeof(wchar_t)-1]) != 0) {
+                    overflow |= true;
+                }
+                else {
+                // calculate the new value (avoiding a warning regarding 
+                // shifting count >= size of the type)
+                    value <<= CHAR_BIT * (sizeof(wchar_t)-1);
+                    value <<= CHAR_BIT;  
+                    value |= character & masks[sizeof(wchar_t)-1];
+                }
+            }
+            else {
+            // make sure no overflow will occur below
+                if ((value & overflow_masks[sizeof(char)-1]) != 0) {
+                    overflow |= true;
+                }
+                else {
+                // calculate the new value
+                    value <<= CHAR_BIT * sizeof(char);
+                    value |= character & masks[sizeof(char)-1];
+                }
+            }
+        }
+    };
+    phoenix::function<compose_character_literal> const compose;
+
+}   // namespace impl
+
+///////////////////////////////////////////////////////////////////////////////
+//  define, whether the rule's should generate some debug output
+#define TRACE_CHLIT_GRAMMAR \
+    bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CHLIT_GRAMMAR) \
+    /**/
+
+struct chlit_grammar :
+    public boost::spirit::classic::grammar<chlit_grammar, 
+        closures::chlit_closure::context_t>
+{
+    chlit_grammar()
+    :   overflow(false)
+    {
+        BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "chlit_grammar", 
+            TRACE_CHLIT_GRAMMAR);
+    }
+    
+    // no need for copy constructor/assignment operator
+    chlit_grammar(chlit_grammar const&);
+    chlit_grammar& operator=(chlit_grammar const&);
+    
+    template <typename ScannerT>
+    struct definition
+    {
+        typedef boost::spirit::classic::rule<
+                ScannerT, closures::chlit_closure::context_t> 
+            rule_t;
+
+        rule_t ch_lit;
+
+        definition(chlit_grammar const &self)
+        {
+            using namespace boost::spirit::classic;
+            namespace phx = phoenix;
+            
+            // special parsers for '\x..' and L'\x....'
+            typedef uint_parser<
+                        unsigned int, 16, 1, 2 * sizeof(char)
+                    > hex_char_parser_type;
+            typedef uint_parser<
+                        unsigned int, 16, 1, 2 * sizeof(wchar_t)
+                    > hex_wchar_parser_type;
+
+            // the rule for a character literal
+            ch_lit
+                =   eps_p[self.value = phx::val(0), self.long_lit = phx::val(false)]
+                    >> !ch_p('L')[self.long_lit = phx::val(true)]
+                    >>  ch_p('\'')
+                    >> +(   (
+                            ch_p('\\') 
+                            >>  (   ch_p('a')    // BEL
+                                    [
+                                        impl::compose(self.value, self.long_lit, 
+                                            phx::var(self.overflow), phx::val(0x07))
+                                    ]
+                                |   ch_p('b')    // BS
+                                    [
+                                        impl::compose(self.value, self.long_lit, 
+                                            phx::var(self.overflow), phx::val(0x08))
+                                    ]
+                                |   ch_p('t')    // HT
+                                    [
+                                        impl::compose(self.value, self.long_lit, 
+                                            phx::var(self.overflow), phx::val(0x09))
+                                    ]
+                                |   ch_p('n')    // NL
+                                    [
+                                        impl::compose(self.value, self.long_lit, 
+                                            phx::var(self.overflow), phx::val(0x0a))
+                                    ]
+                                |   ch_p('v')    // VT
+                                    [
+                                        impl::compose(self.value, self.long_lit, 
+                                            phx::var(self.overflow), phx::val(0x0b))
+                                    ]
+                                |   ch_p('f')    // FF
+                                    [
+                                        impl::compose(self.value, self.long_lit, 
+                                            phx::var(self.overflow), phx::val(0x0c))
+                                    ]
+                                |   ch_p('r')    // CR
+                                    [
+                                        impl::compose(self.value, self.long_lit, 
+                                            phx::var(self.overflow), phx::val(0x0d))
+                                    ]
+                                |   ch_p('?')
+                                    [
+                                        impl::compose(self.value, self.long_lit, 
+                                            phx::var(self.overflow), phx::val('?'))
+                                    ]
+                                |   ch_p('\'')
+                                    [
+                                        impl::compose(self.value, self.long_lit, 
+                                            phx::var(self.overflow), phx::val('\''))
+                                    ]
+                                |   ch_p('\"')
+                                    [
+                                        impl::compose(self.value, self.long_lit, 
+                                            phx::var(self.overflow), phx::val('\"'))
+                                    ]
+                                |   ch_p('\\')
+                                    [
+                                        impl::compose(self.value, self.long_lit, 
+                                            phx::var(self.overflow), phx::val('\\'))
+                                    ]
+                                |   ch_p('x') 
+                                    >>  if_p(self.long_lit) 
+                                        [
+                                            hex_wchar_parser_type()
+                                            [
+                                                impl::compose(self.value, self.long_lit, 
+                                                    phx::var(self.overflow), phx::arg1)
+                                            ]
+                                        ]
+                                        .else_p
+                                        [
+                                            hex_char_parser_type()
+                                            [
+                                                impl::compose(self.value, self.long_lit, 
+                                                    phx::var(self.overflow), phx::arg1)
+                                            ]
+                                        ]
+                                |   ch_p('u') 
+                                    >>  uint_parser<unsigned int, 16, 4, 4>()
+                                        [
+                                            impl::compose(self.value, self.long_lit, 
+                                                phx::var(self.overflow), phx::arg1)
+                                        ]
+                                |   ch_p('U')
+                                    >>  uint_parser<unsigned int, 16, 8, 8>()
+                                        [
+                                            impl::compose(self.value, self.long_lit, 
+                                                phx::var(self.overflow), phx::arg1)
+                                        ]
+                                |   uint_parser<unsigned int, 8, 1, 3>()
+                                    [
+                                        impl::compose(self.value, self.long_lit, 
+                                            phx::var(self.overflow), phx::arg1)
+                                    ]
+                                )
+                            )
+                        |   ~eps_p(ch_p('\'')) >> anychar_p
+                            [
+                                impl::compose(self.value, self.long_lit, 
+                                    phx::var(self.overflow), phx::arg1)
+                            ]
+                        )
+                    >>  ch_p('\'')
+                ;
+
+            BOOST_SPIRIT_DEBUG_TRACE_RULE(ch_lit, TRACE_CHLIT_GRAMMAR);
+        }
+
+    // start rule of this grammar
+        rule_t const& start() const
+        { return ch_lit; }
+    };
+
+    // flag signaling integer overflow during value composition
+    mutable bool overflow;
+};
+
+#undef TRACE_CHLIT_GRAMMAR
+
+///////////////////////////////////////////////////////////////////////////////
+//  
+//  The following function is defined here, to allow the separation of 
+//  the compilation of the intlit_grammap from the function using it.
+//  
+///////////////////////////////////////////////////////////////////////////////
+
+#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
+#define BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE
+#else
+#define BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE inline
+#endif 
+
+template <typename IntegralResult, typename TokenT>
+BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE 
+IntegralResult
+chlit_grammar_gen<IntegralResult, TokenT>::evaluate(TokenT const &token, value_error &status)
+{
+    using namespace boost::spirit::classic;
+    
+chlit_grammar g;
+IntegralResult result = 0;
+typename TokenT::string_type const &token_val = token.get_value();
+parse_info<typename TokenT::string_type::const_iterator> hit =
+    parse(token_val.begin(), token_val.end(), g[spirit_assign_actor(result)]);
+
+    if (!hit.hit) {
+        BOOST_WAVE_THROW(preprocess_exception, ill_formed_character_literal, 
+            token_val.c_str(), token.get_position());
+    }
+    else {
+    // range check
+        if ('L' == token_val[0]) {
+        // recognized wide character
+            if (g.overflow || 
+                result > (IntegralResult)(std::numeric_limits<wchar_t>::max)()) 
+            {
+            // out of range
+                status = error_character_overflow;
+            }
+        }
+        else {
+        // recognized narrow ('normal') character
+            if (g.overflow || 
+                result > (IntegralResult)(std::numeric_limits<unsigned char>::max)()) 
+            {
+            // out of range
+                status = error_character_overflow;
+            }
+        }
+    }
+    return result;
+}
+
+#undef BOOST_WAVE_CHLITGRAMMAR_GEN_INLINE
+
+///////////////////////////////////////////////////////////////////////////////
+}   // namespace grammars
+}   // namespace wave
+}   // namespace boost
+
+// the suffix header occurs after all of the code
+#ifdef BOOST_HAS_ABI_HEADERS
+#include BOOST_ABI_SUFFIX
+#endif
+
+#endif // !defined(CPP_CHLIT_GRAMMAR_HPP_9527D349_6592_449A_A409_42A001E6C64C_INCLUDED)