Added boost header
This commit is contained in:
354
test/external/boost/wave/grammars/cpp_chlit_grammar.hpp
vendored
Normal file
354
test/external/boost/wave/grammars/cpp_chlit_grammar.hpp
vendored
Normal file
@@ -0,0 +1,354 @@
|
||||
/*=============================================================================
|
||||
Boost.Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://www.boost.org/
|
||||
|
||||
Copyright (c) 2001-2011 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)
|
||||
185
test/external/boost/wave/grammars/cpp_defined_grammar.hpp
vendored
Normal file
185
test/external/boost/wave/grammars/cpp_defined_grammar.hpp
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
/*=============================================================================
|
||||
Boost.Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://www.boost.org/
|
||||
|
||||
Copyright (c) 2001-2011 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_DEFINED_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED)
|
||||
#define CPP_DEFINED_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/spirit/include/classic_core.hpp>
|
||||
#include <boost/spirit/include/classic_closure.hpp>
|
||||
#include <boost/spirit/include/classic_assign_actor.hpp>
|
||||
#include <boost/spirit/include/classic_push_back_actor.hpp>
|
||||
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
#include <boost/wave/util/pattern_parser.hpp>
|
||||
#include <boost/wave/grammars/cpp_defined_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
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// define, whether the rule's should generate some debug output
|
||||
#define TRACE_CPP_DEFINED_GRAMMAR \
|
||||
bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_DEFINED_GRAMMAR) \
|
||||
/**/
|
||||
|
||||
template <typename ContainerT>
|
||||
struct defined_grammar :
|
||||
public boost::spirit::classic::grammar<defined_grammar<ContainerT> >
|
||||
{
|
||||
defined_grammar(ContainerT &result_seq_)
|
||||
: result_seq(result_seq_)
|
||||
{
|
||||
BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "defined_grammar",
|
||||
TRACE_CPP_DEFINED_GRAMMAR);
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct definition
|
||||
{
|
||||
typedef boost::spirit::classic::rule<ScannerT> rule_t;
|
||||
|
||||
rule_t defined_op;
|
||||
rule_t identifier;
|
||||
|
||||
definition(defined_grammar const &self)
|
||||
{
|
||||
using namespace boost::spirit::classic;
|
||||
using namespace boost::wave;
|
||||
using namespace boost::wave::util;
|
||||
|
||||
defined_op // parens not required, see C++ standard 16.1.1
|
||||
= ch_p(T_IDENTIFIER) // token contains 'defined'
|
||||
>> (
|
||||
( ch_p(T_LEFTPAREN)
|
||||
>> identifier
|
||||
>> ch_p(T_RIGHTPAREN)
|
||||
)
|
||||
| identifier
|
||||
)
|
||||
;
|
||||
|
||||
identifier
|
||||
= ch_p(T_IDENTIFIER)
|
||||
[
|
||||
spirit_append_actor(self.result_seq)
|
||||
]
|
||||
| pattern_p(KeywordTokenType, TokenTypeMask|PPTokenFlag)
|
||||
[
|
||||
spirit_append_actor(self.result_seq)
|
||||
]
|
||||
| pattern_p(OperatorTokenType|AltExtTokenType,
|
||||
ExtTokenTypeMask|PPTokenFlag)
|
||||
[
|
||||
spirit_append_actor(self.result_seq)
|
||||
]
|
||||
| pattern_p(BoolLiteralTokenType, TokenTypeMask|PPTokenFlag)
|
||||
[
|
||||
spirit_append_actor(self.result_seq)
|
||||
]
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(defined_op, TRACE_CPP_DEFINED_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(identifier, TRACE_CPP_DEFINED_GRAMMAR);
|
||||
}
|
||||
|
||||
// start rule of this grammar
|
||||
rule_t const& start() const
|
||||
{ return defined_op; }
|
||||
};
|
||||
|
||||
ContainerT &result_seq;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#undef TRACE_CPP_DEFINED_GRAMMAR
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The following parse function is defined here, to allow the separation of
|
||||
// the compilation of the defined_grammar from the function
|
||||
// using it.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
||||
#define BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
|
||||
#else
|
||||
#define BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE inline
|
||||
#endif
|
||||
|
||||
// The parse_operator_define function is instantiated manually twice to
|
||||
// simplify the explicit specialization of this template. This way the user
|
||||
// has only to specify one template parameter (the lexer type) to correctly
|
||||
// formulate the required explicit specialization.
|
||||
// This results in no code overhead, because otherwise the function would be
|
||||
// generated by the compiler twice anyway.
|
||||
|
||||
template <typename LexIteratorT>
|
||||
BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
|
||||
boost::spirit::classic::parse_info<
|
||||
typename defined_grammar_gen<LexIteratorT>::iterator1_type
|
||||
>
|
||||
defined_grammar_gen<LexIteratorT>::parse_operator_defined (
|
||||
iterator1_type const &first, iterator1_type const &last,
|
||||
token_sequence_type &found_qualified_name)
|
||||
{
|
||||
using namespace boost::spirit::classic;
|
||||
using namespace boost::wave;
|
||||
|
||||
defined_grammar<token_sequence_type> g(found_qualified_name);
|
||||
return boost::spirit::classic::parse (
|
||||
first, last, g, ch_p(T_SPACE) | ch_p(T_CCOMMENT));
|
||||
}
|
||||
|
||||
template <typename LexIteratorT>
|
||||
BOOST_WAVE_DEFINED_GRAMMAR_GEN_INLINE
|
||||
boost::spirit::classic::parse_info<
|
||||
typename defined_grammar_gen<LexIteratorT>::iterator2_type
|
||||
>
|
||||
defined_grammar_gen<LexIteratorT>::parse_operator_defined (
|
||||
iterator2_type const &first, iterator2_type const &last,
|
||||
token_sequence_type &found_qualified_name)
|
||||
{
|
||||
using namespace boost::spirit::classic;
|
||||
using namespace boost::wave;
|
||||
|
||||
defined_grammar<token_sequence_type> g(found_qualified_name);
|
||||
return boost::spirit::classic::parse (
|
||||
first, last, g, ch_p(T_SPACE) | ch_p(T_CCOMMENT));
|
||||
}
|
||||
|
||||
#undef BOOST_WAVE_DEFINED_GRAMMAR_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_DEFINED_GRAMMAR_HPP_F48287B2_DC67_40A8_B4A1_800EFBD67869_INCLUDED)
|
||||
85
test/external/boost/wave/grammars/cpp_defined_grammar_gen.hpp
vendored
Normal file
85
test/external/boost/wave/grammars/cpp_defined_grammar_gen.hpp
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
/*=============================================================================
|
||||
Boost.Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://www.boost.org/
|
||||
|
||||
Copyright (c) 2001-2011 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_DEFINED_GRAMMAR_GEN_HPP_825BE9F5_98A3_400D_A97C_AD76B3B08632_INCLUDED)
|
||||
#define CPP_DEFINED_GRAMMAR_GEN_HPP_825BE9F5_98A3_400D_A97C_AD76B3B08632_INCLUDED
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
|
||||
#include <list>
|
||||
|
||||
#include <boost/spirit/include/classic_parser.hpp>
|
||||
#include <boost/pool/pool_alloc.hpp>
|
||||
|
||||
#include <boost/wave/util/unput_queue_iterator.hpp>
|
||||
|
||||
// this must occur after all of the includes and before any code appears
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
#include BOOST_ABI_PREFIX
|
||||
#endif
|
||||
|
||||
// suppress warnings about dependent classes not being exported from the dll
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4251 4231 4660)
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
template <typename LexIteratorT>
|
||||
struct BOOST_WAVE_DECL defined_grammar_gen
|
||||
{
|
||||
typedef typename LexIteratorT::token_type token_type;
|
||||
typedef std::list<token_type, boost::fast_pool_allocator<token_type> >
|
||||
token_sequence_type;
|
||||
|
||||
// The parse_operator_defined function is instantiated manually twice to
|
||||
// simplify the explicit specialization of this template. This way the user
|
||||
// has only to specify one template parameter (the lexer iterator type) to
|
||||
// correctly formulate the required explicit specialization.
|
||||
// This results in no code overhead, because otherwise the function would be
|
||||
// generated by the compiler twice anyway.
|
||||
|
||||
typedef boost::wave::util::unput_queue_iterator<
|
||||
typename token_sequence_type::iterator, token_type, token_sequence_type>
|
||||
iterator1_type;
|
||||
|
||||
typedef boost::wave::util::unput_queue_iterator<
|
||||
LexIteratorT, token_type, token_sequence_type>
|
||||
iterator2_type;
|
||||
|
||||
// parse the operator defined and return the found qualified name
|
||||
static boost::spirit::classic::parse_info<iterator1_type>
|
||||
parse_operator_defined (iterator1_type const &first,
|
||||
iterator1_type const &last, token_sequence_type &found_qualified_name);
|
||||
|
||||
static boost::spirit::classic::parse_info<iterator2_type>
|
||||
parse_operator_defined (iterator2_type const &first,
|
||||
iterator2_type const &last, token_sequence_type &found_qualified_name);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace grammars
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
// the suffix header occurs after all of the code
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
#include BOOST_ABI_SUFFIX
|
||||
#endif
|
||||
|
||||
#endif // !defined(CPP_DEFINED_GRAMMAR_GEN_HPP_825BE9F5_98A3_400D_A97C_AD76B3B08632_INCLUDED)
|
||||
870
test/external/boost/wave/grammars/cpp_expression_grammar.hpp
vendored
Normal file
870
test/external/boost/wave/grammars/cpp_expression_grammar.hpp
vendored
Normal file
@@ -0,0 +1,870 @@
|
||||
/*=============================================================================
|
||||
Boost.Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://www.boost.org/
|
||||
|
||||
Copyright (c) 2001-2011 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_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED)
|
||||
#define CPP_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
|
||||
#include <boost/assert.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_functions.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_casts.hpp>
|
||||
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
|
||||
#include <boost/wave/cpp_exceptions.hpp>
|
||||
#include <boost/wave/grammars/cpp_expression_grammar_gen.hpp>
|
||||
#include <boost/wave/grammars/cpp_literal_grammar_gen.hpp>
|
||||
#include <boost/wave/grammars/cpp_expression_value.hpp>
|
||||
#include <boost/wave/util/pattern_parser.hpp>
|
||||
#include <boost/wave/util/macro_helpers.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
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Encapsulation of the grammar for evaluation of constant preprocessor
|
||||
// expressions
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
namespace closures {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// define the closure type used throughout the C++ expression grammar
|
||||
//
|
||||
// Throughout this grammar all literal tokens are stored into a
|
||||
// closure_value variables, which converts the types appropriately, where
|
||||
// required.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct cpp_expr_closure
|
||||
: boost::spirit::classic::closure<cpp_expr_closure, closure_value>
|
||||
{
|
||||
member1 val;
|
||||
};
|
||||
|
||||
} // namespace closures
|
||||
|
||||
namespace impl {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// convert the given token value (integer literal) to a unsigned long
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct convert_intlit {
|
||||
|
||||
template <typename ArgT>
|
||||
struct result {
|
||||
|
||||
typedef boost::wave::grammars::closures::closure_value type;
|
||||
};
|
||||
|
||||
template <typename TokenT>
|
||||
boost::wave::grammars::closures::closure_value
|
||||
operator()(TokenT const &token) const
|
||||
{
|
||||
typedef boost::wave::grammars::closures::closure_value return_type;
|
||||
bool is_unsigned = false;
|
||||
uint_literal_type ul = intlit_grammar_gen<TokenT>::evaluate(token,
|
||||
is_unsigned);
|
||||
|
||||
return is_unsigned ?
|
||||
return_type(ul) : return_type(static_cast<int_literal_type>(ul));
|
||||
}
|
||||
};
|
||||
phoenix::function<convert_intlit> const as_intlit;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Convert the given token value (character literal) to a unsigned int
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct convert_chlit {
|
||||
|
||||
template <typename ArgT>
|
||||
struct result {
|
||||
|
||||
typedef boost::wave::grammars::closures::closure_value type;
|
||||
};
|
||||
|
||||
template <typename TokenT>
|
||||
boost::wave::grammars::closures::closure_value
|
||||
operator()(TokenT const &token) const
|
||||
{
|
||||
typedef boost::wave::grammars::closures::closure_value return_type;
|
||||
value_error status = error_noerror;
|
||||
|
||||
// If the literal is a wchar_t and wchar_t is represented by a
|
||||
// signed integral type, then the created value will be signed as
|
||||
// well, otherwise we assume unsigned values.
|
||||
#if BOOST_WAVE_WCHAR_T_SIGNEDNESS == BOOST_WAVE_WCHAR_T_AUTOSELECT
|
||||
if ('L' == token.get_value()[0] && std::numeric_limits<wchar_t>::is_signed)
|
||||
{
|
||||
int value = chlit_grammar_gen<int, TokenT>::evaluate(token, status);
|
||||
return return_type(value, status);
|
||||
}
|
||||
#elif BOOST_WAVE_WCHAR_T_SIGNEDNESS == BOOST_WAVE_WCHAR_T_FORCE_SIGNED
|
||||
if ('L' == token.get_value()[0])
|
||||
{
|
||||
int value = chlit_grammar_gen<int, TokenT>::evaluate(token, status);
|
||||
return return_type(value, status);
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int value = chlit_grammar_gen<unsigned int, TokenT>::evaluate(token, status);
|
||||
return return_type(value, status);
|
||||
}
|
||||
};
|
||||
phoenix::function<convert_chlit> const as_chlit;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Handle the ?: operator with correct type and error propagation
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
struct operator_questionmark {
|
||||
|
||||
template <typename CondT, typename Arg1T, typename Arg2T>
|
||||
struct result {
|
||||
|
||||
typedef boost::wave::grammars::closures::closure_value type;
|
||||
};
|
||||
|
||||
template <typename CondT, typename Arg1T, typename Arg2T>
|
||||
boost::wave::grammars::closures::closure_value
|
||||
operator()(CondT const &cond, Arg1T &val1, Arg2T const &val2) const
|
||||
{
|
||||
return val1.handle_questionmark(cond, val2);
|
||||
}
|
||||
};
|
||||
phoenix::function<operator_questionmark> const questionmark;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Handle type conversion conserving error conditions
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct operator_to_bool {
|
||||
|
||||
template <typename ArgT>
|
||||
struct result {
|
||||
|
||||
typedef boost::wave::grammars::closures::closure_value type;
|
||||
};
|
||||
|
||||
template <typename ArgT>
|
||||
boost::wave::grammars::closures::closure_value
|
||||
operator()(ArgT &val) const
|
||||
{
|
||||
typedef boost::wave::grammars::closures::closure_value return_type;
|
||||
return return_type(
|
||||
boost::wave::grammars::closures::as_bool(val), val.is_valid());
|
||||
}
|
||||
};
|
||||
phoenix::function<operator_to_bool> const to_bool;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Handle explicit type conversion
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct operator_as_bool {
|
||||
|
||||
template <typename ArgT>
|
||||
struct result {
|
||||
|
||||
typedef bool type;
|
||||
};
|
||||
|
||||
template <typename ArgT>
|
||||
bool
|
||||
operator()(ArgT &val) const
|
||||
{
|
||||
return boost::wave::grammars::closures::as_bool(val);
|
||||
}
|
||||
};
|
||||
phoenix::function<operator_as_bool> const as_bool;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Handle closure value operators with proper error propagation
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_WAVE_BINARYOP(op, optok) \
|
||||
struct operator_binary_ ## op { \
|
||||
\
|
||||
template <typename Arg1T, typename Arg2T> \
|
||||
struct result { \
|
||||
\
|
||||
typedef boost::wave::grammars::closures::closure_value type; \
|
||||
}; \
|
||||
\
|
||||
template <typename Arg1T, typename Arg2T> \
|
||||
boost::wave::grammars::closures::closure_value \
|
||||
operator()(Arg1T &val1, Arg2T &val2) const \
|
||||
{ \
|
||||
return val1 optok val2; \
|
||||
} \
|
||||
}; \
|
||||
phoenix::function<operator_binary_ ## op> const binary_ ## op \
|
||||
/**/
|
||||
|
||||
BOOST_WAVE_BINARYOP(and, &&);
|
||||
BOOST_WAVE_BINARYOP(or, ||);
|
||||
|
||||
BOOST_WAVE_BINARYOP(bitand, &);
|
||||
BOOST_WAVE_BINARYOP(bitor, |);
|
||||
BOOST_WAVE_BINARYOP(bitxor, ^);
|
||||
|
||||
BOOST_WAVE_BINARYOP(lesseq, <=);
|
||||
BOOST_WAVE_BINARYOP(less, <);
|
||||
BOOST_WAVE_BINARYOP(greater, >);
|
||||
BOOST_WAVE_BINARYOP(greateq, >=);
|
||||
BOOST_WAVE_BINARYOP(eq, ==);
|
||||
BOOST_WAVE_BINARYOP(ne, !=);
|
||||
|
||||
#undef BOOST_WAVE_BINARYOP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_WAVE_UNARYOP(op, optok) \
|
||||
struct operator_unary_ ## op { \
|
||||
\
|
||||
template <typename ArgT> \
|
||||
struct result { \
|
||||
\
|
||||
typedef boost::wave::grammars::closures::closure_value type; \
|
||||
}; \
|
||||
\
|
||||
template <typename ArgT> \
|
||||
boost::wave::grammars::closures::closure_value \
|
||||
operator()(ArgT &val) const \
|
||||
{ \
|
||||
return optok val; \
|
||||
} \
|
||||
}; \
|
||||
phoenix::function<operator_unary_ ## op> const unary_ ## op \
|
||||
/**/
|
||||
|
||||
BOOST_WAVE_UNARYOP(neg, !);
|
||||
|
||||
#undef BOOST_WAVE_UNARYOP
|
||||
|
||||
} // namespace impl
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// define, whether the rule's should generate some debug output
|
||||
#define TRACE_CPP_EXPR_GRAMMAR \
|
||||
bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_EXPR_GRAMMAR) \
|
||||
/**/
|
||||
|
||||
struct expression_grammar :
|
||||
public boost::spirit::classic::grammar<
|
||||
expression_grammar,
|
||||
closures::cpp_expr_closure::context_t
|
||||
>
|
||||
{
|
||||
expression_grammar()
|
||||
{
|
||||
BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "expression_grammar",
|
||||
TRACE_CPP_EXPR_GRAMMAR);
|
||||
}
|
||||
|
||||
// no need for copy constructor/assignment operator
|
||||
expression_grammar(expression_grammar const&);
|
||||
expression_grammar& operator= (expression_grammar const&);
|
||||
|
||||
template <typename ScannerT>
|
||||
struct definition
|
||||
{
|
||||
typedef closures::cpp_expr_closure closure_type;
|
||||
typedef boost::spirit::classic::rule<ScannerT, closure_type::context_t> rule_t;
|
||||
typedef boost::spirit::classic::rule<ScannerT> simple_rule_t;
|
||||
|
||||
simple_rule_t pp_expression;
|
||||
|
||||
rule_t const_exp;
|
||||
rule_t logical_or_exp, logical_and_exp;
|
||||
rule_t inclusive_or_exp, exclusive_or_exp, and_exp;
|
||||
rule_t cmp_equality, cmp_relational;
|
||||
rule_t shift_exp;
|
||||
rule_t add_exp, multiply_exp;
|
||||
rule_t unary_exp, primary_exp, constant;
|
||||
|
||||
rule_t const_exp_nocalc;
|
||||
rule_t logical_or_exp_nocalc, logical_and_exp_nocalc;
|
||||
rule_t inclusive_or_exp_nocalc, exclusive_or_exp_nocalc, and_exp_nocalc;
|
||||
rule_t cmp_equality_nocalc, cmp_relational_nocalc;
|
||||
rule_t shift_exp_nocalc;
|
||||
rule_t add_exp_nocalc, multiply_exp_nocalc;
|
||||
rule_t unary_exp_nocalc, primary_exp_nocalc, constant_nocalc;
|
||||
|
||||
boost::spirit::classic::subrule<0, closure_type::context_t> const_exp_subrule;
|
||||
|
||||
definition(expression_grammar const &self)
|
||||
{
|
||||
using namespace boost::spirit::classic;
|
||||
using namespace phoenix;
|
||||
using namespace boost::wave;
|
||||
using boost::wave::util::pattern_p;
|
||||
|
||||
pp_expression
|
||||
= const_exp[self.val = arg1]
|
||||
;
|
||||
|
||||
const_exp
|
||||
= logical_or_exp[const_exp.val = arg1]
|
||||
>> !(const_exp_subrule =
|
||||
ch_p(T_QUESTION_MARK)
|
||||
>> const_exp
|
||||
[
|
||||
const_exp_subrule.val = arg1
|
||||
]
|
||||
>> ch_p(T_COLON)
|
||||
>> const_exp
|
||||
[
|
||||
const_exp_subrule.val =
|
||||
impl::questionmark(const_exp.val,
|
||||
const_exp_subrule.val, arg1)
|
||||
]
|
||||
)[const_exp.val = arg1]
|
||||
;
|
||||
|
||||
logical_or_exp
|
||||
= logical_and_exp[logical_or_exp.val = arg1]
|
||||
>> *( if_p(impl::as_bool(logical_or_exp.val))
|
||||
[
|
||||
// if one of the || operators is true, no more
|
||||
// evaluation is required
|
||||
pattern_p(T_OROR, MainTokenMask)
|
||||
>> logical_and_exp_nocalc
|
||||
[
|
||||
logical_or_exp.val =
|
||||
impl::to_bool(logical_or_exp.val)
|
||||
]
|
||||
]
|
||||
.else_p
|
||||
[
|
||||
pattern_p(T_OROR, MainTokenMask)
|
||||
>> logical_and_exp
|
||||
[
|
||||
logical_or_exp.val =
|
||||
impl::binary_or(logical_or_exp.val, arg1)
|
||||
]
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
logical_and_exp
|
||||
= inclusive_or_exp[logical_and_exp.val = arg1]
|
||||
>> *( if_p(impl::as_bool(logical_and_exp.val))
|
||||
[
|
||||
pattern_p(T_ANDAND, MainTokenMask)
|
||||
>> inclusive_or_exp
|
||||
[
|
||||
logical_and_exp.val =
|
||||
impl::binary_and(logical_and_exp.val, arg1)
|
||||
]
|
||||
]
|
||||
.else_p
|
||||
[
|
||||
// if one of the && operators is false, no more
|
||||
// evaluation is required
|
||||
pattern_p(T_ANDAND, MainTokenMask)
|
||||
>> inclusive_or_exp_nocalc
|
||||
[
|
||||
logical_and_exp.val =
|
||||
impl::to_bool(logical_and_exp.val)
|
||||
]
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
inclusive_or_exp
|
||||
= exclusive_or_exp[inclusive_or_exp.val = arg1]
|
||||
>> *( pattern_p(T_OR, MainTokenMask)
|
||||
>> exclusive_or_exp
|
||||
[
|
||||
inclusive_or_exp.val =
|
||||
impl::binary_bitor(inclusive_or_exp.val, arg1)
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
exclusive_or_exp
|
||||
= and_exp[exclusive_or_exp.val = arg1]
|
||||
>> *( pattern_p(T_XOR, MainTokenMask)
|
||||
>> and_exp
|
||||
[
|
||||
exclusive_or_exp.val =
|
||||
impl::binary_bitxor(exclusive_or_exp.val, arg1)
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
and_exp
|
||||
= cmp_equality[and_exp.val = arg1]
|
||||
>> *( pattern_p(T_AND, MainTokenMask)
|
||||
>> cmp_equality
|
||||
[
|
||||
and_exp.val =
|
||||
impl::binary_bitand(and_exp.val, arg1)
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
cmp_equality
|
||||
= cmp_relational[cmp_equality.val = arg1]
|
||||
>> *( ch_p(T_EQUAL)
|
||||
>> cmp_relational
|
||||
[
|
||||
cmp_equality.val =
|
||||
impl::binary_eq(cmp_equality.val, arg1)
|
||||
]
|
||||
| pattern_p(T_NOTEQUAL, MainTokenMask)
|
||||
>> cmp_relational
|
||||
[
|
||||
cmp_equality.val =
|
||||
impl::binary_ne(cmp_equality.val, arg1)
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
cmp_relational
|
||||
= shift_exp[cmp_relational.val = arg1]
|
||||
>> *( ch_p(T_LESSEQUAL)
|
||||
>> shift_exp
|
||||
[
|
||||
cmp_relational.val =
|
||||
impl::binary_lesseq(cmp_relational.val, arg1)
|
||||
]
|
||||
| ch_p(T_GREATEREQUAL)
|
||||
>> shift_exp
|
||||
[
|
||||
cmp_relational.val =
|
||||
impl::binary_greateq(cmp_relational.val, arg1)
|
||||
]
|
||||
| ch_p(T_LESS)
|
||||
>> shift_exp
|
||||
[
|
||||
cmp_relational.val =
|
||||
impl::binary_less(cmp_relational.val, arg1)
|
||||
]
|
||||
| ch_p(T_GREATER)
|
||||
>> shift_exp
|
||||
[
|
||||
cmp_relational.val =
|
||||
impl::binary_greater(cmp_relational.val, arg1)
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
shift_exp
|
||||
= add_exp[shift_exp.val = arg1]
|
||||
>> *( ch_p(T_SHIFTLEFT)
|
||||
>> add_exp
|
||||
[
|
||||
shift_exp.val <<= arg1
|
||||
]
|
||||
| ch_p(T_SHIFTRIGHT)
|
||||
>> add_exp
|
||||
[
|
||||
shift_exp.val >>= arg1
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
add_exp
|
||||
= multiply_exp[add_exp.val = arg1]
|
||||
>> *( ch_p(T_PLUS)
|
||||
>> multiply_exp
|
||||
[
|
||||
add_exp.val += arg1
|
||||
]
|
||||
| ch_p(T_MINUS)
|
||||
>> multiply_exp
|
||||
[
|
||||
add_exp.val -= arg1
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
multiply_exp
|
||||
= unary_exp[multiply_exp.val = arg1]
|
||||
>> *( ch_p(T_STAR)
|
||||
>> unary_exp
|
||||
[
|
||||
multiply_exp.val *= arg1
|
||||
]
|
||||
| ch_p(T_DIVIDE)
|
||||
>> unary_exp
|
||||
[
|
||||
multiply_exp.val /= arg1
|
||||
]
|
||||
| ch_p(T_PERCENT)
|
||||
>> unary_exp
|
||||
[
|
||||
multiply_exp.val %= arg1
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
unary_exp
|
||||
= primary_exp[unary_exp.val = arg1]
|
||||
| ch_p(T_PLUS) >> unary_exp
|
||||
[
|
||||
unary_exp.val = arg1
|
||||
]
|
||||
| ch_p(T_MINUS) >> unary_exp
|
||||
[
|
||||
unary_exp.val = -arg1
|
||||
]
|
||||
| pattern_p(T_COMPL, MainTokenMask) >> unary_exp
|
||||
[
|
||||
unary_exp.val = ~arg1
|
||||
]
|
||||
| pattern_p(T_NOT, MainTokenMask) >> unary_exp
|
||||
[
|
||||
unary_exp.val = impl::unary_neg(arg1)
|
||||
]
|
||||
;
|
||||
|
||||
primary_exp
|
||||
= constant[primary_exp.val = arg1]
|
||||
| ch_p(T_LEFTPAREN)
|
||||
>> const_exp[primary_exp.val = arg1]
|
||||
>> ch_p(T_RIGHTPAREN)
|
||||
;
|
||||
|
||||
constant
|
||||
= ch_p(T_PP_NUMBER)
|
||||
[
|
||||
constant.val = impl::as_intlit(arg1)
|
||||
]
|
||||
| ch_p(T_INTLIT)
|
||||
[
|
||||
constant.val = impl::as_intlit(arg1)
|
||||
]
|
||||
| ch_p(T_CHARLIT)
|
||||
[
|
||||
constant.val = impl::as_chlit(arg1)
|
||||
]
|
||||
;
|
||||
|
||||
// here follows the same grammar, but without any embedded
|
||||
// calculations
|
||||
const_exp_nocalc
|
||||
= logical_or_exp_nocalc
|
||||
>> !( ch_p(T_QUESTION_MARK)
|
||||
>> const_exp_nocalc
|
||||
>> ch_p(T_COLON)
|
||||
>> const_exp_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
logical_or_exp_nocalc
|
||||
= logical_and_exp_nocalc
|
||||
>> *( pattern_p(T_OROR, MainTokenMask)
|
||||
>> logical_and_exp_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
logical_and_exp_nocalc
|
||||
= inclusive_or_exp_nocalc
|
||||
>> *( pattern_p(T_ANDAND, MainTokenMask)
|
||||
>> inclusive_or_exp_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
inclusive_or_exp_nocalc
|
||||
= exclusive_or_exp_nocalc
|
||||
>> *( pattern_p(T_OR, MainTokenMask)
|
||||
>> exclusive_or_exp_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
exclusive_or_exp_nocalc
|
||||
= and_exp_nocalc
|
||||
>> *( pattern_p(T_XOR, MainTokenMask)
|
||||
>> and_exp_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
and_exp_nocalc
|
||||
= cmp_equality_nocalc
|
||||
>> *( pattern_p(T_AND, MainTokenMask)
|
||||
>> cmp_equality_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
cmp_equality_nocalc
|
||||
= cmp_relational_nocalc
|
||||
>> *( ch_p(T_EQUAL)
|
||||
>> cmp_relational_nocalc
|
||||
| pattern_p(T_NOTEQUAL, MainTokenMask)
|
||||
>> cmp_relational_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
cmp_relational_nocalc
|
||||
= shift_exp_nocalc
|
||||
>> *( ch_p(T_LESSEQUAL)
|
||||
>> shift_exp_nocalc
|
||||
| ch_p(T_GREATEREQUAL)
|
||||
>> shift_exp_nocalc
|
||||
| ch_p(T_LESS)
|
||||
>> shift_exp_nocalc
|
||||
| ch_p(T_GREATER)
|
||||
>> shift_exp_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
shift_exp_nocalc
|
||||
= add_exp_nocalc
|
||||
>> *( ch_p(T_SHIFTLEFT)
|
||||
>> add_exp_nocalc
|
||||
| ch_p(T_SHIFTRIGHT)
|
||||
>> add_exp_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
add_exp_nocalc
|
||||
= multiply_exp_nocalc
|
||||
>> *( ch_p(T_PLUS)
|
||||
>> multiply_exp_nocalc
|
||||
| ch_p(T_MINUS)
|
||||
>> multiply_exp_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
multiply_exp_nocalc
|
||||
= unary_exp_nocalc
|
||||
>> *( ch_p(T_STAR)
|
||||
>> unary_exp_nocalc
|
||||
| ch_p(T_DIVIDE)
|
||||
>> unary_exp_nocalc
|
||||
| ch_p(T_PERCENT)
|
||||
>> unary_exp_nocalc
|
||||
)
|
||||
;
|
||||
|
||||
unary_exp_nocalc
|
||||
= primary_exp_nocalc
|
||||
| ch_p(T_PLUS) >> unary_exp_nocalc
|
||||
| ch_p(T_MINUS) >> unary_exp_nocalc
|
||||
| pattern_p(T_COMPL, MainTokenMask) >> unary_exp_nocalc
|
||||
| pattern_p(T_NOT, MainTokenMask) >> unary_exp_nocalc
|
||||
;
|
||||
|
||||
primary_exp_nocalc
|
||||
= constant_nocalc
|
||||
| ch_p(T_LEFTPAREN)
|
||||
>> const_exp_nocalc
|
||||
>> ch_p(T_RIGHTPAREN)
|
||||
;
|
||||
|
||||
constant_nocalc
|
||||
= ch_p(T_PP_NUMBER)
|
||||
| ch_p(T_INTLIT)
|
||||
| ch_p(T_CHARLIT)
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(pp_expression, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(const_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_or_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_and_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(inclusive_or_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(exclusive_or_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(and_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_equality, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_relational, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(shift_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(add_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(multiply_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(unary_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(primary_exp, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(constant, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(const_exp_subrule, TRACE_CPP_EXPR_GRAMMAR);
|
||||
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(const_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_or_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(logical_and_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(inclusive_or_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(exclusive_or_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(and_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_equality_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(cmp_relational_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(shift_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(add_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(multiply_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(unary_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(primary_exp_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(constant_nocalc, TRACE_CPP_EXPR_GRAMMAR);
|
||||
}
|
||||
|
||||
// start rule of this grammar
|
||||
simple_rule_t const& start() const
|
||||
{ return pp_expression; }
|
||||
};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#undef TRACE_CPP_EXPR_GRAMMAR
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The following function is defined here, to allow the separation of
|
||||
// the compilation of the expression_grammar from the function using it.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
||||
#define BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE
|
||||
#else
|
||||
#define BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE inline
|
||||
#endif
|
||||
|
||||
template <typename TokenT>
|
||||
BOOST_WAVE_EXPRGRAMMAR_GEN_INLINE
|
||||
bool
|
||||
expression_grammar_gen<TokenT>::evaluate(
|
||||
typename token_sequence_type::const_iterator const &first,
|
||||
typename token_sequence_type::const_iterator const &last,
|
||||
typename token_type::position_type const &act_pos,
|
||||
bool if_block_status, value_error &status)
|
||||
{
|
||||
using namespace boost::spirit::classic;
|
||||
using namespace boost::wave;
|
||||
using namespace boost::wave::grammars::closures;
|
||||
|
||||
using boost::wave::util::impl::as_string;
|
||||
|
||||
typedef typename token_sequence_type::const_iterator iterator_type;
|
||||
typedef typename token_sequence_type::value_type::string_type string_type;
|
||||
|
||||
parse_info<iterator_type> hit(first);
|
||||
closure_value result; // expression result
|
||||
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
try
|
||||
#endif
|
||||
{
|
||||
expression_grammar g; // expression grammar
|
||||
hit = parse (first, last, g[spirit_assign_actor(result)],
|
||||
ch_p(T_SPACE) | ch_p(T_CCOMMENT) | ch_p(T_CPPCOMMENT));
|
||||
|
||||
if (!hit.hit) {
|
||||
// expression is illformed
|
||||
if (if_block_status) {
|
||||
string_type expression = as_string<string_type>(first, last);
|
||||
if (0 == expression.size())
|
||||
expression = "<empty expression>";
|
||||
BOOST_WAVE_THROW(preprocess_exception, ill_formed_expression,
|
||||
expression.c_str(), act_pos);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
// as the if_block_status is false no errors will be reported
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if !defined(BOOST_NO_EXCEPTIONS)
|
||||
catch (boost::wave::preprocess_exception const& e) {
|
||||
// expression is illformed
|
||||
if (if_block_status) {
|
||||
boost::throw_exception(e);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
// as the if_block_status is false no errors will be reported
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!hit.full) {
|
||||
// The token list starts with a valid expression, but there remains
|
||||
// something. If the remainder consists out of whitespace only, the
|
||||
// expression is still valid.
|
||||
iterator_type next = hit.stop;
|
||||
|
||||
while (next != last) {
|
||||
switch (static_cast<unsigned int>(token_id(*next))) {
|
||||
case T_SPACE:
|
||||
case T_SPACE2:
|
||||
case T_CCOMMENT:
|
||||
break; // ok continue
|
||||
|
||||
case T_NEWLINE:
|
||||
case T_EOF:
|
||||
case T_CPPCOMMENT: // contains newline
|
||||
return as_bool(result); // expression is valid
|
||||
|
||||
default:
|
||||
// expression is illformed
|
||||
if (if_block_status) {
|
||||
string_type expression = as_string<string_type>(first, last);
|
||||
if (0 == expression.size())
|
||||
expression = "<empty expression>";
|
||||
BOOST_WAVE_THROW(preprocess_exception, ill_formed_expression,
|
||||
expression.c_str(), act_pos);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
// as the if_block_status is false no errors will be reported
|
||||
return false;
|
||||
}
|
||||
}
|
||||
++next;
|
||||
}
|
||||
}
|
||||
|
||||
if (error_noerror != result.is_valid()) // division or other error by zero occurred
|
||||
status = result.is_valid();
|
||||
|
||||
// token sequence is a valid expression
|
||||
return as_bool(result);
|
||||
}
|
||||
|
||||
#undef BOOST_WAVE_EXPRGRAMMAR_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_EXPRESSION_GRAMMAR_HPP_099CD1A4_A6C0_44BE_8F24_0B00F5BE5674_INCLUDED)
|
||||
75
test/external/boost/wave/grammars/cpp_expression_grammar_gen.hpp
vendored
Normal file
75
test/external/boost/wave/grammars/cpp_expression_grammar_gen.hpp
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
/*=============================================================================
|
||||
Boost.Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://www.boost.org/
|
||||
|
||||
Copyright (c) 2001-2011 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_EXPRESSION_GRAMMAR_GEN_HPP_42399258_6CDC_4101_863D_5C7D95B5A6CA_INCLUDED)
|
||||
#define CPP_EXPRESSION_GRAMMAR_GEN_HPP_42399258_6CDC_4101_863D_5C7D95B5A6CA_INCLUDED
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/cpp_iteration_context.hpp>
|
||||
#include <boost/wave/grammars/cpp_value_error.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <boost/pool/pool_alloc.hpp>
|
||||
|
||||
// this must occur after all of the includes and before any code appears
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
#include BOOST_ABI_PREFIX
|
||||
#endif
|
||||
|
||||
// suppress warnings about dependent classes not being exported from the dll
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4251 4231 4660)
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// expression_grammar_gen template class
|
||||
//
|
||||
// This template helps separating the compilation of the
|
||||
// expression_grammar class from the compilation of the main
|
||||
// pp_iterator. This is done to safe compilation time.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename TokenT>
|
||||
struct BOOST_WAVE_DECL expression_grammar_gen {
|
||||
|
||||
typedef TokenT token_type;
|
||||
typedef std::list<token_type, boost::fast_pool_allocator<token_type> >
|
||||
token_sequence_type;
|
||||
|
||||
static bool evaluate(
|
||||
typename token_sequence_type::const_iterator const &first,
|
||||
typename token_sequence_type::const_iterator const &last,
|
||||
typename token_type::position_type const &tok,
|
||||
bool if_block_status, value_error &status);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace grammars
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
// the suffix header occurs after all of the code
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
#include BOOST_ABI_SUFFIX
|
||||
#endif
|
||||
|
||||
#endif // !defined(CPP_EXPRESSION_GRAMMAR_GEN_HPP_42399258_6CDC_4101_863D_5C7D95B5A6CA_INCLUDED)
|
||||
883
test/external/boost/wave/grammars/cpp_expression_value.hpp
vendored
Normal file
883
test/external/boost/wave/grammars/cpp_expression_value.hpp
vendored
Normal file
@@ -0,0 +1,883 @@
|
||||
/*=============================================================================
|
||||
Boost.Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://www.boost.org/
|
||||
|
||||
Copyright (c) 2001-2011 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_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED)
|
||||
#define CPP_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED
|
||||
|
||||
#if defined (BOOST_SPIRIT_DEBUG)
|
||||
#include <iostream>
|
||||
#endif // defined(BOOST_SPIRIT_DEBUG)
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/grammars/cpp_value_error.hpp> // value_error
|
||||
|
||||
// this must occur after all of the includes and before any code appears
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
#include BOOST_ABI_PREFIX
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
namespace closures {
|
||||
|
||||
class closure_value;
|
||||
inline bool as_bool(closure_value const& v);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The closure_value class represents the closure type, which is used for the
|
||||
// expression grammar.
|
||||
//
|
||||
// This class was introduced to allow the expression grammar to respect
|
||||
// the numeric type of a numeric literal or expression result.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class closure_value {
|
||||
public:
|
||||
|
||||
enum value_type {
|
||||
is_int = 1,
|
||||
is_uint = 2,
|
||||
is_bool = 3
|
||||
};
|
||||
|
||||
closure_value(value_error valid_ = error_noerror)
|
||||
: type(is_int), valid(valid_)
|
||||
{ value.i = 0; }
|
||||
explicit closure_value(int i, value_error valid_ = error_noerror)
|
||||
: type(is_int), valid(valid_)
|
||||
{ value.i = i; }
|
||||
explicit closure_value(unsigned int ui, value_error valid_ = error_noerror)
|
||||
: type(is_uint), valid(valid_)
|
||||
{ value.ui = ui; }
|
||||
explicit closure_value(int_literal_type i, value_error valid_ = error_noerror)
|
||||
: type(is_int), valid(valid_)
|
||||
{ value.i = i; }
|
||||
explicit closure_value(uint_literal_type ui, value_error valid_ = error_noerror)
|
||||
: type(is_uint), valid(valid_)
|
||||
{ value.ui = ui; }
|
||||
explicit closure_value(bool b, value_error valid_ = error_noerror)
|
||||
: type(is_bool), valid(valid_)
|
||||
{ value.b = b; }
|
||||
|
||||
value_type get_type() const { return type; }
|
||||
value_error is_valid() const { return valid; }
|
||||
|
||||
// explicit conversion
|
||||
friend int_literal_type as_int(closure_value const& v)
|
||||
{
|
||||
switch (v.type) {
|
||||
case is_uint: return v.value.ui;
|
||||
case is_bool: return v.value.b ? 1 : 0;
|
||||
case is_int: break;
|
||||
}
|
||||
return v.value.i;
|
||||
}
|
||||
friend uint_literal_type as_uint(closure_value const& v)
|
||||
{
|
||||
switch (v.type) {
|
||||
case is_uint: return v.value.ui;
|
||||
case is_bool: return v.value.b ? 1 : 0;
|
||||
case is_int: break;
|
||||
}
|
||||
return v.value.i;
|
||||
}
|
||||
friend int_literal_type as_long(closure_value const& v)
|
||||
{
|
||||
switch (v.type) {
|
||||
case is_uint: return v.value.ui;
|
||||
case is_bool: return v.value.b ? 1 : 0;
|
||||
case is_int: break;
|
||||
}
|
||||
return v.value.i;
|
||||
}
|
||||
friend uint_literal_type as_ulong(closure_value const& v)
|
||||
{
|
||||
switch (v.type) {
|
||||
case is_uint: return v.value.ui;
|
||||
case is_bool: return v.value.b ? 1 : 0;
|
||||
case is_int: break;
|
||||
}
|
||||
return v.value.i;
|
||||
}
|
||||
friend bool as_bool(closure_value const& v)
|
||||
{
|
||||
switch (v.type) {
|
||||
case is_uint: return v.value.ui != 0;
|
||||
case is_bool: return v.value.b;
|
||||
case is_int: break;
|
||||
}
|
||||
return v.value.i != 0.0;
|
||||
}
|
||||
|
||||
// assignment
|
||||
closure_value &operator= (closure_value const &rhs)
|
||||
{
|
||||
switch (rhs.get_type()) {
|
||||
case is_int:
|
||||
value.i = as_long(rhs);
|
||||
type = is_int;
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
value.ui = as_ulong(rhs);
|
||||
type = is_uint;
|
||||
break;
|
||||
|
||||
case is_bool:
|
||||
value.b = as_bool(rhs);
|
||||
type = is_bool;
|
||||
break;
|
||||
}
|
||||
valid = rhs.valid;
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator= (int rhs)
|
||||
{
|
||||
type = is_int;
|
||||
value.i = rhs;
|
||||
valid = error_noerror;
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator= (unsigned int rhs)
|
||||
{
|
||||
type = is_uint;
|
||||
value.ui = rhs;
|
||||
valid = error_noerror;
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator= (int_literal_type rhs)
|
||||
{
|
||||
type = is_int;
|
||||
value.i = rhs;
|
||||
valid = error_noerror;
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator= (uint_literal_type rhs)
|
||||
{
|
||||
type = is_uint;
|
||||
value.ui = rhs;
|
||||
valid = error_noerror;
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator= (bool rhs)
|
||||
{
|
||||
type = is_bool;
|
||||
value.b = rhs;
|
||||
valid = error_noerror;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// arithmetics
|
||||
closure_value &operator+= (closure_value const &rhs)
|
||||
{
|
||||
switch (type) {
|
||||
case is_int:
|
||||
switch(rhs.type) {
|
||||
case is_bool:
|
||||
{
|
||||
int_literal_type result = value.i + as_long(rhs);
|
||||
if ((rhs.value.i > 0L && value.i > result) ||
|
||||
(rhs.value.i < 0L && value.i < result))
|
||||
{
|
||||
valid = error_integer_overflow;
|
||||
}
|
||||
else {
|
||||
value.i = result;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case is_int:
|
||||
{
|
||||
int_literal_type result = value.i + rhs.value.i;
|
||||
if ((rhs.value.i > 0L && value.i > result) ||
|
||||
(rhs.value.i < 0L && value.i < result))
|
||||
{
|
||||
valid = error_integer_overflow;
|
||||
}
|
||||
else {
|
||||
value.i = result;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
{
|
||||
uint_literal_type result = value.ui + rhs.value.ui;
|
||||
if (result < value.ui) {
|
||||
valid = error_integer_overflow;
|
||||
}
|
||||
else {
|
||||
value.ui = result;
|
||||
type = is_uint;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
{
|
||||
uint_literal_type result = value.ui + as_ulong(rhs);
|
||||
if (result < value.ui) {
|
||||
valid = error_integer_overflow;
|
||||
}
|
||||
else {
|
||||
value.ui = result;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case is_bool:
|
||||
value.i = value.b + as_bool(rhs);
|
||||
type = is_int;
|
||||
}
|
||||
valid = (value_error)(valid | rhs.valid);
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator-= (closure_value const &rhs)
|
||||
{
|
||||
switch (type) {
|
||||
case is_int:
|
||||
switch(rhs.type) {
|
||||
case is_bool:
|
||||
{
|
||||
int_literal_type result = value.i - as_long(rhs);
|
||||
if ((rhs.value.i > 0L && result > value.i) ||
|
||||
(rhs.value.i < 0L && result < value.i))
|
||||
{
|
||||
valid = error_integer_overflow;
|
||||
}
|
||||
else {
|
||||
value.i = result;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case is_int:
|
||||
{
|
||||
int_literal_type result = value.i - rhs.value.i;
|
||||
if ((rhs.value.i > 0L && result > value.i) ||
|
||||
(rhs.value.i < 0L && result < value.i))
|
||||
{
|
||||
valid = error_integer_overflow;
|
||||
}
|
||||
else {
|
||||
value.i = result;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
{
|
||||
uint_literal_type result = value.ui - rhs.value.ui;
|
||||
if (result > value.ui) {
|
||||
valid = error_integer_overflow;
|
||||
}
|
||||
else {
|
||||
value.ui = result;
|
||||
type = is_uint;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
switch(rhs.type) {
|
||||
case is_bool:
|
||||
{
|
||||
uint_literal_type result = value.ui - as_ulong(rhs);
|
||||
if (result > value.ui)
|
||||
{
|
||||
valid = error_integer_overflow;
|
||||
}
|
||||
else {
|
||||
value.ui = result;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case is_int:
|
||||
{
|
||||
uint_literal_type result = value.ui - rhs.value.i;
|
||||
if ((rhs.value.i > 0L && result > value.ui) ||
|
||||
(rhs.value.i < 0L && result < value.ui))
|
||||
{
|
||||
valid = error_integer_overflow;
|
||||
}
|
||||
else {
|
||||
value.ui = result;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
{
|
||||
uint_literal_type result = value.ui - rhs.value.ui;
|
||||
if (result > value.ui) {
|
||||
valid = error_integer_overflow;
|
||||
}
|
||||
else {
|
||||
value.ui = result;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_bool:
|
||||
value.i = value.b - as_bool(rhs);
|
||||
type = is_int;
|
||||
}
|
||||
valid = (value_error)(valid | rhs.valid);
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator*= (closure_value const &rhs)
|
||||
{
|
||||
switch (type) {
|
||||
case is_int:
|
||||
switch(rhs.type) {
|
||||
case is_bool: value.i *= as_long(rhs); break;
|
||||
case is_int:
|
||||
{
|
||||
int_literal_type result = value.i * rhs.value.i;
|
||||
if (0 != value.i && 0 != rhs.value.i &&
|
||||
(result / value.i != rhs.value.i ||
|
||||
result / rhs.value.i != value.i)
|
||||
)
|
||||
{
|
||||
valid = error_integer_overflow;
|
||||
}
|
||||
else {
|
||||
value.i = result;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
{
|
||||
uint_literal_type result = value.ui * rhs.value.ui;
|
||||
if (0 != value.ui && 0 != rhs.value.ui &&
|
||||
(result / value.ui != rhs.value.ui ||
|
||||
result / rhs.value.ui != value.ui)
|
||||
)
|
||||
{
|
||||
valid = error_integer_overflow;
|
||||
}
|
||||
else {
|
||||
value.ui = result;
|
||||
type = is_uint;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
{
|
||||
uint_literal_type rhs_val = as_ulong(rhs);
|
||||
uint_literal_type result = value.ui * rhs_val;
|
||||
if (0 != value.ui && 0 != rhs_val &&
|
||||
(result / value.ui != rhs_val ||
|
||||
result / rhs_val != value.ui)
|
||||
)
|
||||
{
|
||||
valid = error_integer_overflow;
|
||||
}
|
||||
else {
|
||||
value.ui = result;
|
||||
type = is_uint;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case is_bool:
|
||||
switch (rhs.type) {
|
||||
case is_int:
|
||||
value.i = (value.b ? 1 : 0) * rhs.value.i;
|
||||
type = is_int;
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
value.ui = (value.b ? 1 : 0) * rhs.value.ui;
|
||||
type = is_uint;
|
||||
break;
|
||||
|
||||
case is_bool:
|
||||
value.b = 0 != ((value.b ? 1 : 0) * (rhs.value.b ? 1 : 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
valid = (value_error)(valid | rhs.valid);
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator/= (closure_value const &rhs)
|
||||
{
|
||||
switch (type) {
|
||||
case is_int:
|
||||
switch(rhs.type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
if (as_long(rhs) != 0) {
|
||||
if (value.i == -value.i && -1 == rhs.value.i) {
|
||||
// LONG_MIN / -1 on two's complement
|
||||
valid = error_integer_overflow;
|
||||
}
|
||||
else {
|
||||
value.i /= as_long(rhs);
|
||||
}
|
||||
}
|
||||
else {
|
||||
valid = error_division_by_zero; // division by zero
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
if (rhs.value.ui != 0) {
|
||||
value.ui /= rhs.value.ui;
|
||||
type = is_uint;
|
||||
}
|
||||
else {
|
||||
valid = error_division_by_zero; // division by zero
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
if (as_ulong(rhs) != 0)
|
||||
value.ui /= as_ulong(rhs);
|
||||
else
|
||||
valid = error_division_by_zero; // division by zero
|
||||
break;
|
||||
|
||||
case is_bool:
|
||||
if (as_bool(rhs)) {
|
||||
switch(rhs.type) {
|
||||
case is_int:
|
||||
value.i = (value.b ? 1 : 0) / rhs.value.i;
|
||||
type = is_int;
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
value.i = (value.b ? 1 : 0) / rhs.value.ui;
|
||||
type = is_int;
|
||||
break;
|
||||
|
||||
case is_bool:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
valid = error_division_by_zero; // division by zero
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
closure_value &operator%= (closure_value const &rhs)
|
||||
{
|
||||
switch (type) {
|
||||
case is_int:
|
||||
switch(rhs.type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
if (as_long(rhs) != 0) {
|
||||
if (value.i == -value.i && -1 == rhs.value.i) {
|
||||
// LONG_MIN % -1 on two's complement
|
||||
valid = error_integer_overflow;
|
||||
}
|
||||
else {
|
||||
value.i %= as_long(rhs);
|
||||
}
|
||||
}
|
||||
else {
|
||||
valid = error_division_by_zero; // division by zero
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
if (rhs.value.ui != 0) {
|
||||
value.ui %= rhs.value.ui;
|
||||
type = is_uint;
|
||||
}
|
||||
else {
|
||||
valid = error_division_by_zero; // division by zero
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
if (as_ulong(rhs) != 0)
|
||||
value.ui %= as_ulong(rhs);
|
||||
else
|
||||
valid = error_division_by_zero; // division by zero
|
||||
break;
|
||||
|
||||
case is_bool:
|
||||
if (as_bool(rhs)) {
|
||||
switch(rhs.type) {
|
||||
case is_int:
|
||||
value.i = (value.b ? 1 : 0) % rhs.value.i;
|
||||
type = is_int;
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
value.i = (value.b ? 1 : 0) % rhs.value.ui;
|
||||
type = is_int;
|
||||
break;
|
||||
|
||||
case is_bool:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
valid = error_division_by_zero; // division by zero
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend closure_value
|
||||
operator- (closure_value const &rhs)
|
||||
{
|
||||
switch (rhs.type) {
|
||||
case is_int:
|
||||
{
|
||||
int_literal_type value = as_long(rhs);
|
||||
if (value != 0 && value == -value)
|
||||
return closure_value(-value, error_integer_overflow);
|
||||
return closure_value(-value, rhs.valid);
|
||||
}
|
||||
|
||||
case is_bool: return closure_value(-as_long(rhs), rhs.valid);
|
||||
case is_uint: break;
|
||||
}
|
||||
|
||||
int_literal_type value = as_ulong(rhs);
|
||||
if (value != 0 && value == -value)
|
||||
return closure_value(-value, error_integer_overflow);
|
||||
return closure_value(-value, rhs.valid);
|
||||
}
|
||||
friend closure_value
|
||||
operator~ (closure_value const &rhs)
|
||||
{
|
||||
return closure_value(~as_ulong(rhs), rhs.valid);
|
||||
}
|
||||
friend closure_value
|
||||
operator! (closure_value const &rhs)
|
||||
{
|
||||
switch (rhs.type) {
|
||||
case is_int: return closure_value(!as_long(rhs), rhs.valid);
|
||||
case is_bool: return closure_value(!as_bool(rhs), rhs.valid);
|
||||
case is_uint: break;
|
||||
}
|
||||
return closure_value(!as_ulong(rhs), rhs.valid);
|
||||
}
|
||||
|
||||
// comparison
|
||||
friend closure_value
|
||||
operator== (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
bool cmp = false;
|
||||
switch (lhs.type) {
|
||||
case is_int:
|
||||
switch(rhs.type) {
|
||||
case is_bool: cmp = as_bool(lhs) == rhs.value.b; break;
|
||||
case is_int: cmp = lhs.value.i == rhs.value.i; break;
|
||||
case is_uint: cmp = lhs.value.ui == rhs.value.ui; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint: cmp = lhs.value.ui == as_ulong(rhs); break;
|
||||
case is_bool: cmp = lhs.value.b == as_bool(rhs); break;
|
||||
}
|
||||
return closure_value(cmp, (value_error)(lhs.valid | rhs.valid));
|
||||
}
|
||||
friend closure_value
|
||||
operator!= (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
return closure_value(!as_bool(lhs == rhs), (value_error)(lhs.valid | rhs.valid));
|
||||
}
|
||||
friend closure_value
|
||||
operator> (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
bool cmp = false;
|
||||
switch (lhs.type) {
|
||||
case is_int:
|
||||
switch(rhs.type) {
|
||||
case is_bool: cmp = lhs.value.i > as_long(rhs); break;
|
||||
case is_int: cmp = lhs.value.i > rhs.value.i; break;
|
||||
case is_uint: cmp = lhs.value.ui > rhs.value.ui; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint: cmp = lhs.value.ui > as_ulong(rhs); break;
|
||||
case is_bool: cmp = lhs.value.b > as_bool(rhs); break;
|
||||
}
|
||||
return closure_value(cmp, (value_error)(lhs.valid | rhs.valid));
|
||||
}
|
||||
friend closure_value
|
||||
operator< (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
bool cmp = false;
|
||||
switch (lhs.type) {
|
||||
case is_int:
|
||||
switch(rhs.type) {
|
||||
case is_bool: cmp = lhs.value.i < as_long(rhs); break;
|
||||
case is_int: cmp = lhs.value.i < rhs.value.i; break;
|
||||
case is_uint: cmp = lhs.value.ui < rhs.value.ui; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint: cmp = lhs.value.ui < as_ulong(rhs); break;
|
||||
case is_bool: cmp = as_bool(lhs) < as_bool(rhs); break;
|
||||
}
|
||||
return closure_value(cmp, (value_error)(lhs.valid | rhs.valid));
|
||||
}
|
||||
friend closure_value
|
||||
operator<= (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
return closure_value(!as_bool(lhs > rhs), (value_error)(lhs.valid | rhs.valid));
|
||||
}
|
||||
friend closure_value
|
||||
operator>= (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
return closure_value(!as_bool(lhs < rhs), (value_error)(lhs.valid | rhs.valid));
|
||||
}
|
||||
|
||||
closure_value &
|
||||
operator<<= (closure_value const &rhs)
|
||||
{
|
||||
switch (type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
switch (rhs.type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
{
|
||||
int_literal_type shift_by = as_long(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
else if (shift_by < -64)
|
||||
shift_by = -64;
|
||||
value.i <<= shift_by;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
{
|
||||
uint_literal_type shift_by = as_ulong(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
value.ui <<= shift_by;
|
||||
|
||||
// Note: The usual arithmetic conversions are not performed on
|
||||
// bit shift operations.
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
switch (rhs.type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
{
|
||||
int_literal_type shift_by = as_long(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
else if (shift_by < -64)
|
||||
shift_by = -64;
|
||||
value.ui <<= shift_by;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
{
|
||||
uint_literal_type shift_by = as_ulong(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
value.ui <<= shift_by;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
valid = (value_error)(valid | rhs.valid);
|
||||
return *this;
|
||||
}
|
||||
|
||||
closure_value &
|
||||
operator>>= (closure_value const &rhs)
|
||||
{
|
||||
switch (type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
switch (rhs.type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
{
|
||||
int_literal_type shift_by = as_long(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
else if (shift_by < -64)
|
||||
shift_by = -64;
|
||||
value.i >>= shift_by;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
{
|
||||
uint_literal_type shift_by = as_ulong(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
value.ui >>= shift_by;
|
||||
|
||||
// Note: The usual arithmetic conversions are not performed on
|
||||
// bit shift operations.
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
switch (rhs.type) {
|
||||
case is_bool:
|
||||
case is_int:
|
||||
{
|
||||
int_literal_type shift_by = as_long(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
else if (shift_by < -64)
|
||||
shift_by = -64;
|
||||
value.ui >>= shift_by;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint:
|
||||
{
|
||||
uint_literal_type shift_by = as_ulong(rhs);
|
||||
|
||||
if (shift_by > 64)
|
||||
shift_by = 64;
|
||||
value.ui >>= shift_by;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
valid = (value_error)(valid | rhs.valid);
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend closure_value
|
||||
operator|| (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
bool result = as_bool(lhs) || as_bool(rhs);
|
||||
return closure_value(result, (value_error)(lhs.valid | rhs.valid));
|
||||
}
|
||||
|
||||
friend closure_value
|
||||
operator&& (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
bool result = as_bool(lhs) && as_bool(rhs);
|
||||
return closure_value(result, (value_error)(lhs.valid | rhs.valid));
|
||||
}
|
||||
|
||||
friend closure_value
|
||||
operator| (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
uint_literal_type result = as_ulong(lhs) | as_ulong(rhs);
|
||||
return closure_value(result, (value_error)(lhs.valid | rhs.valid));
|
||||
}
|
||||
|
||||
friend closure_value
|
||||
operator& (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
uint_literal_type result = as_ulong(lhs) & as_ulong(rhs);
|
||||
return closure_value(result, (value_error)(lhs.valid | rhs.valid));
|
||||
}
|
||||
|
||||
friend closure_value
|
||||
operator^ (closure_value const &lhs, closure_value const &rhs)
|
||||
{
|
||||
uint_literal_type result = as_ulong(lhs) ^ as_ulong(rhs);
|
||||
return closure_value(result, (value_error)(lhs.valid | rhs.valid));
|
||||
}
|
||||
|
||||
// handle the ?: operator
|
||||
closure_value &
|
||||
handle_questionmark(closure_value const &cond, closure_value const &val2)
|
||||
{
|
||||
switch (type) {
|
||||
case is_int:
|
||||
switch (val2.type) {
|
||||
case is_bool: value.b = as_bool(cond) ? value.b : as_bool(val2); break;
|
||||
case is_int: value.i = as_bool(cond) ? value.i : as_long(val2); break;
|
||||
case is_uint:
|
||||
value.ui = as_bool(cond) ? value.ui : as_ulong(val2);
|
||||
type = is_uint; // changing type!
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case is_uint: value.ui = as_bool(cond) ? value.ui : as_ulong(val2); break;
|
||||
case is_bool: value.b = as_bool(cond) ? value.b : as_bool(val2); break;
|
||||
}
|
||||
valid = as_bool(cond) ? valid : val2.valid;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if defined (BOOST_SPIRIT_DEBUG)
|
||||
friend std::ostream&
|
||||
operator<< (std::ostream &o, closure_value const &val)
|
||||
{
|
||||
switch (val.type) {
|
||||
case is_int: o << "int(" << as_long(val) << ")"; break;
|
||||
case is_uint: o << "unsigned int(" << as_ulong(val) << ")"; break;
|
||||
case is_bool: o << "bool(" << as_bool(val) << ")"; break;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
#endif // defined(BOOST_SPIRIT_DEBUG)
|
||||
|
||||
private:
|
||||
value_type type;
|
||||
union {
|
||||
int_literal_type i;
|
||||
uint_literal_type ui;
|
||||
bool b;
|
||||
} value;
|
||||
value_error valid;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace closures
|
||||
} // 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_EXPRESSION_VALUE_HPP_452FE66D_8754_4107_AF1E_E42255A0C18A_INCLUDED)
|
||||
765
test/external/boost/wave/grammars/cpp_grammar.hpp
vendored
Normal file
765
test/external/boost/wave/grammars/cpp_grammar.hpp
vendored
Normal file
@@ -0,0 +1,765 @@
|
||||
/*=============================================================================
|
||||
Boost.Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://www.boost.org/
|
||||
|
||||
Copyright (c) 2001-2011 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_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED)
|
||||
#define CPP_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED
|
||||
|
||||
#include <boost/spirit/include/classic_core.hpp>
|
||||
#include <boost/spirit/include/classic_parse_tree.hpp>
|
||||
#include <boost/spirit/include/classic_parse_tree_utils.hpp>
|
||||
#include <boost/spirit/include/classic_confix.hpp>
|
||||
#include <boost/spirit/include/classic_lists.hpp>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/pool/pool_alloc.hpp>
|
||||
|
||||
#if BOOST_WAVE_DUMP_PARSE_TREE != 0
|
||||
#include <map>
|
||||
#include <boost/spirit/include/classic_tree_to_xml.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
#include <boost/wave/grammars/cpp_grammar_gen.hpp>
|
||||
#include <boost/wave/util/pattern_parser.hpp>
|
||||
|
||||
#include <boost/wave/cpp_exceptions.hpp>
|
||||
|
||||
// this must occur after all of the includes and before any code appears
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
#include BOOST_ABI_PREFIX
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
namespace impl {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// store_found_eof
|
||||
//
|
||||
// The store_found_eof functor sets a given flag if the T_EOF token was
|
||||
// found during the parsing process
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct store_found_eof {
|
||||
|
||||
store_found_eof(bool &found_eof_) : found_eof(found_eof_) {}
|
||||
|
||||
template <typename TokenT>
|
||||
void operator()(TokenT const &/*token*/) const
|
||||
{
|
||||
found_eof = true;
|
||||
}
|
||||
|
||||
bool &found_eof;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// store_found_directive
|
||||
//
|
||||
// The store_found_directive functor stores the token_id of the recognized
|
||||
// pp directive
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename TokenT>
|
||||
struct store_found_directive {
|
||||
|
||||
store_found_directive(TokenT &found_directive_)
|
||||
: found_directive(found_directive_) {}
|
||||
|
||||
void operator()(TokenT const &token) const
|
||||
{
|
||||
found_directive = token;
|
||||
}
|
||||
|
||||
TokenT &found_directive;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// store_found_eoltokens
|
||||
//
|
||||
// The store_found_eoltokens functor stores the token sequence of the
|
||||
// line ending for a particular pp directive
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename ContainerT>
|
||||
struct store_found_eoltokens {
|
||||
|
||||
store_found_eoltokens(ContainerT &found_eoltokens_)
|
||||
: found_eoltokens(found_eoltokens_) {}
|
||||
|
||||
template <typename IteratorT>
|
||||
void operator()(IteratorT const &first, IteratorT const& last) const
|
||||
{
|
||||
std::copy(first, last,
|
||||
std::inserter(found_eoltokens, found_eoltokens.end()));
|
||||
}
|
||||
|
||||
ContainerT &found_eoltokens;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// flush_underlying_parser
|
||||
//
|
||||
// The flush_underlying_parser flushes the underlying
|
||||
// multi_pass_iterator during the normal parsing process. This is
|
||||
// used at certain points during the parsing process, when it is
|
||||
// clear, that no backtracking is needed anymore and the input
|
||||
// gathered so far may be discarded.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct flush_underlying_parser
|
||||
: public boost::spirit::classic::parser<flush_underlying_parser>
|
||||
{
|
||||
typedef flush_underlying_parser this_t;
|
||||
|
||||
template <typename ScannerT>
|
||||
typename boost::spirit::classic::parser_result<this_t, ScannerT>::type
|
||||
parse(ScannerT const& scan) const
|
||||
{
|
||||
scan.first.clear_queue();
|
||||
return scan.empty_match();
|
||||
}
|
||||
};
|
||||
|
||||
flush_underlying_parser const
|
||||
flush_underlying_parser_p = flush_underlying_parser();
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// define, whether the rule's should generate some debug output
|
||||
#define TRACE_CPP_GRAMMAR \
|
||||
bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR) \
|
||||
/**/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Encapsulation of the C++ preprocessor grammar.
|
||||
template <typename TokenT, typename ContainerT>
|
||||
struct cpp_grammar :
|
||||
public boost::spirit::classic::grammar<cpp_grammar<TokenT, ContainerT> >
|
||||
{
|
||||
typedef typename TokenT::position_type position_type;
|
||||
typedef cpp_grammar<TokenT, ContainerT> grammar_type;
|
||||
typedef impl::store_found_eof store_found_eof_type;
|
||||
typedef impl::store_found_directive<TokenT> store_found_directive_type;
|
||||
typedef impl::store_found_eoltokens<ContainerT> store_found_eoltokens_type;
|
||||
|
||||
template <typename ScannerT>
|
||||
struct definition
|
||||
{
|
||||
// non-parse_tree generating rule type
|
||||
typedef typename ScannerT::iteration_policy_t iteration_policy_t;
|
||||
typedef boost::spirit::classic::match_policy match_policy_t;
|
||||
typedef typename ScannerT::action_policy_t action_policy_t;
|
||||
typedef
|
||||
boost::spirit::classic::scanner_policies<
|
||||
iteration_policy_t, match_policy_t, action_policy_t>
|
||||
policies_t;
|
||||
typedef
|
||||
boost::spirit::classic::scanner<typename ScannerT::iterator_t, policies_t>
|
||||
non_tree_scanner_t;
|
||||
typedef
|
||||
boost::spirit::classic::rule<
|
||||
non_tree_scanner_t, boost::spirit::classic::dynamic_parser_tag>
|
||||
no_tree_rule_type;
|
||||
|
||||
// 'normal' (parse_tree generating) rule type
|
||||
typedef
|
||||
boost::spirit::classic::rule<
|
||||
ScannerT, boost::spirit::classic::dynamic_parser_tag>
|
||||
rule_type;
|
||||
|
||||
rule_type pp_statement, macro_include_file;
|
||||
// rule_type include_file, system_include_file;
|
||||
rule_type plain_define, macro_definition, macro_parameters;
|
||||
rule_type undefine;
|
||||
rule_type ppifdef, ppifndef, ppif, ppelif;
|
||||
// rule_type ppelse, ppendif;
|
||||
rule_type ppline;
|
||||
rule_type pperror;
|
||||
rule_type ppwarning;
|
||||
rule_type pppragma;
|
||||
rule_type illformed;
|
||||
rule_type ppqualifiedname;
|
||||
rule_type eol_tokens;
|
||||
no_tree_rule_type ppsp;
|
||||
#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
|
||||
rule_type ppregion;
|
||||
rule_type ppendregion;
|
||||
#endif
|
||||
|
||||
definition(cpp_grammar const &self)
|
||||
{
|
||||
// import the spirit and cpplexer namespaces here
|
||||
using namespace boost::spirit::classic;
|
||||
using namespace boost::wave;
|
||||
using namespace boost::wave::util;
|
||||
|
||||
// set the rule id's for later use
|
||||
pp_statement.set_id(BOOST_WAVE_PP_STATEMENT_ID);
|
||||
// include_file.set_id(BOOST_WAVE_INCLUDE_FILE_ID);
|
||||
// system_include_file.set_id(BOOST_WAVE_SYSINCLUDE_FILE_ID);
|
||||
macro_include_file.set_id(BOOST_WAVE_MACROINCLUDE_FILE_ID);
|
||||
plain_define.set_id(BOOST_WAVE_PLAIN_DEFINE_ID);
|
||||
macro_parameters.set_id(BOOST_WAVE_MACRO_PARAMETERS_ID);
|
||||
macro_definition.set_id(BOOST_WAVE_MACRO_DEFINITION_ID);
|
||||
undefine.set_id(BOOST_WAVE_UNDEFINE_ID);
|
||||
ppifdef.set_id(BOOST_WAVE_IFDEF_ID);
|
||||
ppifndef.set_id(BOOST_WAVE_IFNDEF_ID);
|
||||
ppif.set_id(BOOST_WAVE_IF_ID);
|
||||
ppelif.set_id(BOOST_WAVE_ELIF_ID);
|
||||
// ppelse.set_id(BOOST_WAVE_ELSE_ID);
|
||||
// ppendif.set_id(BOOST_WAVE_ENDIF_ID);
|
||||
ppline.set_id(BOOST_WAVE_LINE_ID);
|
||||
pperror.set_id(BOOST_WAVE_ERROR_ID);
|
||||
ppwarning.set_id(BOOST_WAVE_WARNING_ID);
|
||||
pppragma.set_id(BOOST_WAVE_PRAGMA_ID);
|
||||
illformed.set_id(BOOST_WAVE_ILLFORMED_ID);
|
||||
ppsp.set_id(BOOST_WAVE_PPSPACE_ID);
|
||||
ppqualifiedname.set_id(BOOST_WAVE_PPQUALIFIEDNAME_ID);
|
||||
#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
|
||||
ppregion.set_id(BOOST_WAVE_REGION_ID);
|
||||
ppendregion.set_id(BOOST_WAVE_ENDREGION_ID);
|
||||
#endif
|
||||
|
||||
#if BOOST_WAVE_DUMP_PARSE_TREE != 0
|
||||
self.map_rule_id_to_name.init_rule_id_to_name_map(self);
|
||||
#endif
|
||||
|
||||
// recognizes preprocessor directives only
|
||||
|
||||
// C++ standard 16.1: A preprocessing directive consists of a sequence
|
||||
// of preprocessing tokens. The first token in the sequence is #
|
||||
// preprocessing token that is either the first character in the source
|
||||
// file (optionally after white space containing no new-line
|
||||
// characters) or that follows white space containing at least one
|
||||
// new-line character. The last token in the sequence is the first
|
||||
// new-line character that follows the first token in the sequence.
|
||||
|
||||
pp_statement
|
||||
= ( plain_define
|
||||
// | include_file
|
||||
// | system_include_file
|
||||
| ppif
|
||||
| ppelif
|
||||
| ppifndef
|
||||
| ppifdef
|
||||
| undefine
|
||||
// | ppelse
|
||||
| macro_include_file
|
||||
| ppline
|
||||
| pppragma
|
||||
| pperror
|
||||
| ppwarning
|
||||
// | ppendif
|
||||
#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
|
||||
| ppregion
|
||||
| ppendregion
|
||||
#endif
|
||||
| illformed
|
||||
)
|
||||
>> eol_tokens
|
||||
[ store_found_eoltokens_type(self.found_eoltokens) ]
|
||||
// In parser debug mode it is useful not to flush the underlying stream
|
||||
// to allow its investigation in the debugger and to see the correct
|
||||
// output in the printed debug log..
|
||||
// Note: this may break the parser, though.
|
||||
#if !(defined(BOOST_SPIRIT_DEBUG) && \
|
||||
(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_CPP_GRAMMAR) \
|
||||
)
|
||||
>> impl::flush_underlying_parser_p
|
||||
#endif // !(defined(BOOST_SPIRIT_DEBUG) &&
|
||||
;
|
||||
|
||||
// // #include ...
|
||||
// include_file // include "..."
|
||||
// = ch_p(T_PP_QHEADER)
|
||||
// [ store_found_directive_type(self.found_directive) ]
|
||||
// #if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
|
||||
// | ch_p(T_PP_QHEADER_NEXT)
|
||||
// [ store_found_directive_type(self.found_directive) ]
|
||||
// #endif
|
||||
// ;
|
||||
|
||||
// system_include_file // include <...>
|
||||
// = ch_p(T_PP_HHEADER)
|
||||
// [ store_found_directive_type(self.found_directive) ]
|
||||
// #if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
|
||||
// | ch_p(T_PP_HHEADER_NEXT)
|
||||
// [ store_found_directive_type(self.found_directive) ]
|
||||
// #endif
|
||||
// ;
|
||||
|
||||
macro_include_file // include ...anything else...
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_INCLUDE)
|
||||
[ store_found_directive_type(self.found_directive) ]
|
||||
#if BOOST_WAVE_SUPPORT_INCLUDE_NEXT != 0
|
||||
| ch_p(T_PP_INCLUDE_NEXT)
|
||||
[ store_found_directive_type(self.found_directive) ]
|
||||
#endif
|
||||
]
|
||||
>> *( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
;
|
||||
|
||||
// #define FOO foo (with optional parameters)
|
||||
plain_define
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_DEFINE)
|
||||
[ store_found_directive_type(self.found_directive) ]
|
||||
>> +ppsp
|
||||
]
|
||||
>> ( ch_p(T_IDENTIFIER)
|
||||
| pattern_p(KeywordTokenType,
|
||||
TokenTypeMask|PPTokenFlag)
|
||||
| pattern_p(OperatorTokenType|AltExtTokenType,
|
||||
ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc.
|
||||
| pattern_p(BoolLiteralTokenType,
|
||||
TokenTypeMask|PPTokenFlag) // true/false
|
||||
)
|
||||
>> ( ( no_node_d[eps_p(ch_p(T_LEFTPAREN))]
|
||||
>> macro_parameters
|
||||
>> !macro_definition
|
||||
)
|
||||
| !( no_node_d[+ppsp]
|
||||
>> macro_definition
|
||||
)
|
||||
)
|
||||
;
|
||||
|
||||
// parameter list
|
||||
// normal C++ mode
|
||||
macro_parameters
|
||||
= confix_p(
|
||||
no_node_d[ch_p(T_LEFTPAREN) >> *ppsp],
|
||||
!list_p(
|
||||
( ch_p(T_IDENTIFIER)
|
||||
| pattern_p(KeywordTokenType,
|
||||
TokenTypeMask|PPTokenFlag)
|
||||
| pattern_p(OperatorTokenType|AltExtTokenType,
|
||||
ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc.
|
||||
| pattern_p(BoolLiteralTokenType,
|
||||
TokenTypeMask|PPTokenFlag) // true/false
|
||||
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
|
||||
| ch_p(T_ELLIPSIS)
|
||||
#endif
|
||||
),
|
||||
no_node_d[*ppsp >> ch_p(T_COMMA) >> *ppsp]
|
||||
),
|
||||
no_node_d[*ppsp >> ch_p(T_RIGHTPAREN)]
|
||||
)
|
||||
;
|
||||
|
||||
// macro body (anything left until eol)
|
||||
macro_definition
|
||||
= no_node_d[*ppsp]
|
||||
>> *( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
;
|
||||
|
||||
// #undef FOO
|
||||
undefine
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_UNDEF)
|
||||
[ store_found_directive_type(self.found_directive) ]
|
||||
>> +ppsp
|
||||
]
|
||||
>> ( ch_p(T_IDENTIFIER)
|
||||
| pattern_p(KeywordTokenType,
|
||||
TokenTypeMask|PPTokenFlag)
|
||||
| pattern_p(OperatorTokenType|AltExtTokenType,
|
||||
ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc.
|
||||
| pattern_p(BoolLiteralTokenType,
|
||||
TokenTypeMask|PPTokenFlag) // true/false
|
||||
)
|
||||
;
|
||||
|
||||
// #ifdef et.al.
|
||||
ppifdef
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_IFDEF)
|
||||
[ store_found_directive_type(self.found_directive) ]
|
||||
>> +ppsp
|
||||
]
|
||||
>> ppqualifiedname
|
||||
;
|
||||
|
||||
ppifndef
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_IFNDEF)
|
||||
[ store_found_directive_type(self.found_directive) ]
|
||||
>> +ppsp
|
||||
]
|
||||
>> ppqualifiedname
|
||||
;
|
||||
|
||||
ppif
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_IF)
|
||||
[ store_found_directive_type(self.found_directive) ]
|
||||
// >> *ppsp
|
||||
]
|
||||
>> +( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
;
|
||||
|
||||
// ppelse
|
||||
// = no_node_d
|
||||
// [
|
||||
// ch_p(T_PP_ELSE)
|
||||
// [ store_found_directive_type(self.found_directive) ]
|
||||
// ]
|
||||
// ;
|
||||
|
||||
ppelif
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_ELIF)
|
||||
[ store_found_directive_type(self.found_directive) ]
|
||||
// >> *ppsp
|
||||
]
|
||||
>> +( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
;
|
||||
|
||||
// ppendif
|
||||
// = no_node_d
|
||||
// [
|
||||
// ch_p(T_PP_ENDIF)
|
||||
// [ store_found_directive_type(self.found_directive) ]
|
||||
// ]
|
||||
// ;
|
||||
|
||||
// #line ...
|
||||
ppline
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_LINE)
|
||||
[ store_found_directive_type(self.found_directive) ]
|
||||
>> *ppsp
|
||||
]
|
||||
>> +( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
;
|
||||
|
||||
#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
|
||||
// #region ...
|
||||
ppregion
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_MSEXT_PP_REGION)
|
||||
[ store_found_directive_type(self.found_directive) ]
|
||||
>> +ppsp
|
||||
]
|
||||
>> ppqualifiedname
|
||||
;
|
||||
|
||||
// #endregion
|
||||
ppendregion
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_MSEXT_PP_ENDREGION)
|
||||
[ store_found_directive_type(self.found_directive) ]
|
||||
]
|
||||
;
|
||||
#endif
|
||||
|
||||
// # something else (ill formed preprocessor directive)
|
||||
illformed // for error reporting
|
||||
= no_node_d
|
||||
[
|
||||
pattern_p(T_POUND, MainTokenMask)
|
||||
>> *ppsp
|
||||
]
|
||||
>> ( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
>> no_node_d
|
||||
[
|
||||
*( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
]
|
||||
;
|
||||
|
||||
// #error
|
||||
pperror
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_ERROR)
|
||||
[ store_found_directive_type(self.found_directive) ]
|
||||
>> *ppsp
|
||||
]
|
||||
>> *( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
;
|
||||
|
||||
// #warning
|
||||
ppwarning
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_WARNING)
|
||||
[ store_found_directive_type(self.found_directive) ]
|
||||
>> *ppsp
|
||||
]
|
||||
>> *( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
;
|
||||
|
||||
// #pragma ...
|
||||
pppragma
|
||||
= no_node_d
|
||||
[
|
||||
ch_p(T_PP_PRAGMA)
|
||||
[ store_found_directive_type(self.found_directive) ]
|
||||
]
|
||||
>> *( anychar_p -
|
||||
(ch_p(T_NEWLINE) | ch_p(T_CPPCOMMENT) | ch_p(T_EOF))
|
||||
)
|
||||
;
|
||||
|
||||
ppqualifiedname
|
||||
= no_node_d[*ppsp]
|
||||
>> ( ch_p(T_IDENTIFIER)
|
||||
| pattern_p(KeywordTokenType,
|
||||
TokenTypeMask|PPTokenFlag)
|
||||
| pattern_p(OperatorTokenType|AltExtTokenType,
|
||||
ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc.
|
||||
| pattern_p(BoolLiteralTokenType,
|
||||
TokenTypeMask|PPTokenFlag) // true/false
|
||||
)
|
||||
;
|
||||
|
||||
// auxiliary helper rules
|
||||
ppsp // valid space in a line with a preprocessor directive
|
||||
= ch_p(T_SPACE) | ch_p(T_CCOMMENT)
|
||||
;
|
||||
|
||||
// end of line tokens
|
||||
eol_tokens
|
||||
= no_node_d
|
||||
[
|
||||
*( ch_p(T_SPACE)
|
||||
| ch_p(T_CCOMMENT)
|
||||
)
|
||||
>> ( ch_p(T_NEWLINE)
|
||||
| ch_p(T_CPPCOMMENT)
|
||||
| ch_p(T_EOF)
|
||||
[ store_found_eof_type(self.found_eof) ]
|
||||
)
|
||||
]
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(pp_statement, TRACE_CPP_GRAMMAR);
|
||||
// BOOST_SPIRIT_DEBUG_TRACE_RULE(include_file, TRACE_CPP_GRAMMAR);
|
||||
// BOOST_SPIRIT_DEBUG_TRACE_RULE(system_include_file, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_include_file, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(plain_define, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_definition, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_parameters, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(undefine, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppifdef, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppifndef, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppif, TRACE_CPP_GRAMMAR);
|
||||
// BOOST_SPIRIT_DEBUG_TRACE_RULE(ppelse, TRACE_CPP_GRAMMAR);
|
||||
// BOOST_SPIRIT_DEBUG_TRACE_RULE(ppelif, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppendif, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppline, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(pperror, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppwarning, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(illformed, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppsp, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppqualifiedname, TRACE_CPP_GRAMMAR);
|
||||
#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppregion, TRACE_CPP_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(ppendregion, TRACE_CPP_GRAMMAR);
|
||||
#endif
|
||||
}
|
||||
|
||||
// start rule of this grammar
|
||||
rule_type const& start() const
|
||||
{ return pp_statement; }
|
||||
};
|
||||
|
||||
bool &found_eof;
|
||||
TokenT &found_directive;
|
||||
ContainerT &found_eoltokens;
|
||||
|
||||
cpp_grammar(bool &found_eof_, TokenT &found_directive_,
|
||||
ContainerT &found_eoltokens_)
|
||||
: found_eof(found_eof_),
|
||||
found_directive(found_directive_),
|
||||
found_eoltokens(found_eoltokens_)
|
||||
{
|
||||
BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "cpp_grammar",
|
||||
TRACE_CPP_GRAMMAR);
|
||||
}
|
||||
|
||||
#if BOOST_WAVE_DUMP_PARSE_TREE != 0
|
||||
// helper function and data to get readable names of the rules known to us
|
||||
struct map_ruleid_to_name :
|
||||
public std::map<boost::spirit::classic::parser_id, std::string>
|
||||
{
|
||||
typedef std::map<boost::spirit::classic::parser_id, std::string> base_type;
|
||||
|
||||
void init_rule_id_to_name_map(cpp_grammar const &self)
|
||||
{
|
||||
struct {
|
||||
int parser_id;
|
||||
char const *rule_name;
|
||||
}
|
||||
init_ruleid_name_map[] = {
|
||||
{ BOOST_WAVE_PP_STATEMENT_ID, "pp_statement" },
|
||||
// { BOOST_WAVE_INCLUDE_FILE_ID, "include_file" },
|
||||
// { BOOST_WAVE_SYSINCLUDE_FILE_ID, "system_include_file" },
|
||||
{ BOOST_WAVE_MACROINCLUDE_FILE_ID, "macro_include_file" },
|
||||
{ BOOST_WAVE_PLAIN_DEFINE_ID, "plain_define" },
|
||||
{ BOOST_WAVE_MACRO_PARAMETERS_ID, "macro_parameters" },
|
||||
{ BOOST_WAVE_MACRO_DEFINITION_ID, "macro_definition" },
|
||||
{ BOOST_WAVE_UNDEFINE_ID, "undefine" },
|
||||
{ BOOST_WAVE_IFDEF_ID, "ppifdef" },
|
||||
{ BOOST_WAVE_IFNDEF_ID, "ppifndef" },
|
||||
{ BOOST_WAVE_IF_ID, "ppif" },
|
||||
{ BOOST_WAVE_ELIF_ID, "ppelif" },
|
||||
// { BOOST_WAVE_ELSE_ID, "ppelse" },
|
||||
// { BOOST_WAVE_ENDIF_ID, "ppendif" },
|
||||
{ BOOST_WAVE_LINE_ID, "ppline" },
|
||||
{ BOOST_WAVE_ERROR_ID, "pperror" },
|
||||
{ BOOST_WAVE_WARNING_ID, "ppwarning" },
|
||||
{ BOOST_WAVE_PRAGMA_ID, "pppragma" },
|
||||
{ BOOST_WAVE_ILLFORMED_ID, "illformed" },
|
||||
{ BOOST_WAVE_PPSPACE_ID, "ppspace" },
|
||||
{ BOOST_WAVE_PPQUALIFIEDNAME_ID, "ppqualifiedname" },
|
||||
#if BOOST_WAVE_SUPPORT_MS_EXTENSIONS != 0
|
||||
{ BOOST_WAVE_REGION_ID, "ppregion" },
|
||||
{ BOOST_WAVE_ENDREGION_ID, "ppendregion" },
|
||||
#endif
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
// initialize parser_id to rule_name map
|
||||
for (int i = 0; 0 != init_ruleid_name_map[i].parser_id; ++i)
|
||||
base_type::insert(base_type::value_type(
|
||||
boost::spirit::classic::parser_id(init_ruleid_name_map[i].parser_id),
|
||||
std::string(init_ruleid_name_map[i].rule_name))
|
||||
);
|
||||
}
|
||||
};
|
||||
mutable map_ruleid_to_name map_rule_id_to_name;
|
||||
#endif // WAVE_DUMP_PARSE_TREE != 0
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#undef TRACE_CPP_GRAMMAR
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Special parse function generating a parse tree using a given node_factory.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename NodeFactoryT, typename IteratorT, typename ParserT>
|
||||
inline boost::spirit::classic::tree_parse_info<IteratorT, NodeFactoryT>
|
||||
parsetree_parse(IteratorT const& first_, IteratorT const& last,
|
||||
boost::spirit::classic::parser<ParserT> const& p)
|
||||
{
|
||||
using namespace boost::spirit::classic;
|
||||
|
||||
typedef pt_match_policy<IteratorT, NodeFactoryT> pt_match_policy_type;
|
||||
typedef scanner_policies<iteration_policy, pt_match_policy_type>
|
||||
scanner_policies_type;
|
||||
typedef scanner<IteratorT, scanner_policies_type> scanner_type;
|
||||
|
||||
scanner_policies_type policies;
|
||||
IteratorT first = first_;
|
||||
scanner_type scan(first, last, policies);
|
||||
tree_match<IteratorT, NodeFactoryT> hit = p.derived().parse(scan);
|
||||
return tree_parse_info<IteratorT, NodeFactoryT>(
|
||||
first, hit, hit && (first == last), hit.length(), hit.trees);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The following parse function is defined here, to allow the separation of
|
||||
// the compilation of the cpp_grammar from the function using it.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
||||
#define BOOST_WAVE_GRAMMAR_GEN_INLINE
|
||||
#else
|
||||
#define BOOST_WAVE_GRAMMAR_GEN_INLINE inline
|
||||
#endif
|
||||
|
||||
template <typename LexIteratorT, typename TokenContainerT>
|
||||
BOOST_WAVE_GRAMMAR_GEN_INLINE
|
||||
boost::spirit::classic::tree_parse_info<
|
||||
LexIteratorT,
|
||||
typename cpp_grammar_gen<LexIteratorT, TokenContainerT>::node_factory_type
|
||||
>
|
||||
cpp_grammar_gen<LexIteratorT, TokenContainerT>::parse_cpp_grammar (
|
||||
LexIteratorT const &first, LexIteratorT const &last,
|
||||
position_type const &act_pos, bool &found_eof,
|
||||
token_type &found_directive, token_container_type &found_eoltokens)
|
||||
{
|
||||
using namespace boost::spirit::classic;
|
||||
using namespace boost::wave;
|
||||
|
||||
cpp_grammar<token_type, TokenContainerT> g(found_eof, found_directive, found_eoltokens);
|
||||
tree_parse_info<LexIteratorT, node_factory_type> hit =
|
||||
parsetree_parse<node_factory_type>(first, last, g);
|
||||
|
||||
#if BOOST_WAVE_DUMP_PARSE_TREE != 0
|
||||
if (hit.match) {
|
||||
tree_to_xml (BOOST_WAVE_DUMP_PARSE_TREE_OUT, hit.trees, "",
|
||||
g.map_rule_id_to_name, &token_type::get_token_id,
|
||||
&token_type::get_token_value);
|
||||
}
|
||||
#endif
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
#undef BOOST_WAVE_GRAMMAR_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_GRAMMAR_HPP_FEAEBC2E_2734_428B_A7CA_85E5A415E23E_INCLUDED)
|
||||
110
test/external/boost/wave/grammars/cpp_grammar_gen.hpp
vendored
Normal file
110
test/external/boost/wave/grammars/cpp_grammar_gen.hpp
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
/*=============================================================================
|
||||
Boost.Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://www.boost.org/
|
||||
|
||||
Copyright (c) 2001-2011 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_GRAMMAR_GEN_HPP_80CB8A59_5411_4E45_B406_62531A12FB99_INCLUDED)
|
||||
#define CPP_GRAMMAR_GEN_HPP_80CB8A59_5411_4E45_B406_62531A12FB99_INCLUDED
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/language_support.hpp>
|
||||
|
||||
#include <boost/spirit/include/classic_nil.hpp>
|
||||
#include <boost/spirit/include/classic_parse_tree.hpp>
|
||||
|
||||
#include <boost/pool/pool_alloc.hpp>
|
||||
|
||||
// this must occur after all of the includes and before any code appears
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
#include BOOST_ABI_PREFIX
|
||||
#endif
|
||||
|
||||
// suppress warnings about dependent classes not being exported from the dll
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4251 4231 4660)
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Here are the node id's of the different node of the cpp_grammar
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_WAVE_PP_STATEMENT_ID 1
|
||||
#define BOOST_WAVE_INCLUDE_FILE_ID 2
|
||||
#define BOOST_WAVE_SYSINCLUDE_FILE_ID 3
|
||||
#define BOOST_WAVE_MACROINCLUDE_FILE_ID 4
|
||||
#define BOOST_WAVE_PLAIN_DEFINE_ID 5
|
||||
#define BOOST_WAVE_MACRO_PARAMETERS_ID 6
|
||||
#define BOOST_WAVE_MACRO_DEFINITION_ID 7
|
||||
#define BOOST_WAVE_UNDEFINE_ID 8
|
||||
#define BOOST_WAVE_IFDEF_ID 9
|
||||
#define BOOST_WAVE_IFNDEF_ID 10
|
||||
#define BOOST_WAVE_IF_ID 11
|
||||
#define BOOST_WAVE_ELIF_ID 12
|
||||
#define BOOST_WAVE_ELSE_ID 13
|
||||
#define BOOST_WAVE_ENDIF_ID 14
|
||||
#define BOOST_WAVE_LINE_ID 15
|
||||
#define BOOST_WAVE_ERROR_ID 16
|
||||
#define BOOST_WAVE_WARNING_ID 17
|
||||
#define BOOST_WAVE_PRAGMA_ID 18
|
||||
#define BOOST_WAVE_ILLFORMED_ID 19
|
||||
#define BOOST_WAVE_PPSPACE_ID 20
|
||||
#define BOOST_WAVE_PPQUALIFIEDNAME_ID 21
|
||||
#define BOOST_WAVE_REGION_ID 22
|
||||
#define BOOST_WAVE_ENDREGION_ID 23
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// cpp_grammar_gen template class
|
||||
//
|
||||
// This template helps separating the compilation of the cpp_grammar
|
||||
// class from the compilation of the main pp_iterator. This is done to
|
||||
// safe compilation time.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename LexIteratorT, typename TokenContainerT>
|
||||
struct BOOST_WAVE_DECL cpp_grammar_gen
|
||||
{
|
||||
typedef LexIteratorT iterator_type;
|
||||
typedef typename LexIteratorT::token_type token_type;
|
||||
typedef TokenContainerT token_container_type;
|
||||
typedef typename token_type::position_type position_type;
|
||||
typedef boost::spirit::classic::node_val_data_factory<
|
||||
// boost::spirit::nil_t,
|
||||
// boost::pool_allocator<boost::spirit::nil_t>
|
||||
> node_factory_type;
|
||||
|
||||
// parse the cpp_grammar and return the resulting parse tree
|
||||
static boost::spirit::classic::tree_parse_info<iterator_type, node_factory_type>
|
||||
parse_cpp_grammar (iterator_type const &first, iterator_type const &last,
|
||||
position_type const &act_pos, bool &found_eof,
|
||||
token_type &found_directive, token_container_type &found_eoltokens);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace grammars
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
// the suffix header occurs after all of the code
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
#include BOOST_ABI_SUFFIX
|
||||
#endif
|
||||
|
||||
#endif // !defined(CPP_GRAMMAR_GEN_HPP_80CB8A59_5411_4E45_B406_62531A12FB99_INCLUDED)
|
||||
188
test/external/boost/wave/grammars/cpp_intlit_grammar.hpp
vendored
Normal file
188
test/external/boost/wave/grammars/cpp_intlit_grammar.hpp
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
/*=============================================================================
|
||||
Boost.Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://www.boost.org/
|
||||
|
||||
Copyright (c) 2001-2011 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_INTLIT_GRAMMAR_HPP_2E1E70B1_F15C_4132_8554_10A231B0D91C_INCLUDED)
|
||||
#define CPP_INTLIT_GRAMMAR_HPP_2E1E70B1_F15C_4132_8554_10A231B0D91C_INCLUDED
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
|
||||
#include <boost/spirit/include/classic_core.hpp>
|
||||
#include <boost/spirit/include/classic_closure.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/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 for parsing of C++ style integer literals
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace closures {
|
||||
|
||||
struct intlit_closure
|
||||
: boost::spirit::classic::closure<intlit_closure, uint_literal_type>
|
||||
{
|
||||
member1 val;
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// define, whether the rule's should generate some debug output
|
||||
#define TRACE_INTLIT_GRAMMAR \
|
||||
bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_INTLIT_GRAMMAR) \
|
||||
/**/
|
||||
|
||||
struct intlit_grammar :
|
||||
boost::spirit::classic::grammar<intlit_grammar, closures::intlit_closure::context_t>
|
||||
{
|
||||
intlit_grammar(bool &is_unsigned_) : is_unsigned(is_unsigned_)
|
||||
{
|
||||
BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this, "intlit_grammar",
|
||||
TRACE_INTLIT_GRAMMAR);
|
||||
}
|
||||
|
||||
template <typename ScannerT>
|
||||
struct definition
|
||||
{
|
||||
typedef boost::spirit::classic::rule<ScannerT> rule_t;
|
||||
|
||||
rule_t int_lit;
|
||||
boost::spirit::classic::subrule<0> sub_int_lit;
|
||||
boost::spirit::classic::subrule<1> oct_lit;
|
||||
boost::spirit::classic::subrule<2> hex_lit;
|
||||
boost::spirit::classic::subrule<3> dec_lit;
|
||||
|
||||
definition(intlit_grammar const &self)
|
||||
{
|
||||
using namespace boost::spirit::classic;
|
||||
namespace phx = phoenix;
|
||||
|
||||
|
||||
int_lit = (
|
||||
sub_int_lit =
|
||||
( ch_p('0')[self.val = 0] >> (hex_lit | oct_lit)
|
||||
| dec_lit
|
||||
)
|
||||
>> !as_lower_d[
|
||||
(ch_p('u')[phx::var(self.is_unsigned) = true] || ch_p('l'))
|
||||
| (ch_p('l') || ch_p('u')[phx::var(self.is_unsigned) = true])
|
||||
]
|
||||
,
|
||||
|
||||
hex_lit =
|
||||
(ch_p('X') | ch_p('x'))
|
||||
>> uint_parser<uint_literal_type, 16>()
|
||||
[
|
||||
self.val = phx::arg1,
|
||||
phx::var(self.is_unsigned) = true
|
||||
]
|
||||
,
|
||||
|
||||
oct_lit =
|
||||
!uint_parser<uint_literal_type, 8>()
|
||||
[
|
||||
self.val = phx::arg1,
|
||||
phx::var(self.is_unsigned) = true
|
||||
]
|
||||
,
|
||||
|
||||
dec_lit =
|
||||
uint_parser<uint_literal_type, 10>()
|
||||
[
|
||||
self.val = phx::arg1
|
||||
]
|
||||
)
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(int_lit, TRACE_INTLIT_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(sub_int_lit, TRACE_INTLIT_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(hex_lit, TRACE_INTLIT_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(oct_lit, TRACE_INTLIT_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(dec_lit, TRACE_INTLIT_GRAMMAR);
|
||||
}
|
||||
|
||||
// start rule of this grammar
|
||||
rule_t const& start() const
|
||||
{ return int_lit; }
|
||||
};
|
||||
|
||||
bool &is_unsigned;
|
||||
};
|
||||
|
||||
#undef TRACE_INTLIT_GRAMMAR
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The following function is defined here, to allow the separation of
|
||||
// the compilation of the intlit_grammar from the function using it.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
||||
#define BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE
|
||||
#else
|
||||
#define BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE inline
|
||||
#endif
|
||||
|
||||
template <typename TokenT>
|
||||
BOOST_WAVE_INTLITGRAMMAR_GEN_INLINE
|
||||
uint_literal_type
|
||||
intlit_grammar_gen<TokenT>::evaluate(TokenT const &token,
|
||||
bool &is_unsigned)
|
||||
{
|
||||
using namespace boost::spirit::classic;
|
||||
|
||||
intlit_grammar g(is_unsigned);
|
||||
uint_literal_type 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_integer_literal,
|
||||
token_val.c_str(), token.get_position());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#undef BOOST_WAVE_INTLITGRAMMAR_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_INTLIT_GRAMMAR_HPP_2E1E70B1_F15C_4132_8554_10A231B0D91C_INCLUDED)
|
||||
77
test/external/boost/wave/grammars/cpp_literal_grammar_gen.hpp
vendored
Normal file
77
test/external/boost/wave/grammars/cpp_literal_grammar_gen.hpp
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
/*=============================================================================
|
||||
Boost.Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://www.boost.org/
|
||||
|
||||
Copyright (c) 2001-2011 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_LITERAL_GRAMMAR_GEN_HPP_67794A6C_468A_4AAB_A757_DEDDB182F5A0_INCLUDED)
|
||||
#define CPP_LITERAL_GRAMMAR_GEN_HPP_67794A6C_468A_4AAB_A757_DEDDB182F5A0_INCLUDED
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/grammars/cpp_value_error.hpp>
|
||||
|
||||
// this must occur after all of the includes and before any code appears
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
#include BOOST_ABI_PREFIX
|
||||
#endif
|
||||
|
||||
// suppress warnings about dependent classes not being exported from the dll
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4251 4231 4660)
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// cpp_intlit_grammar_gen template class
|
||||
//
|
||||
// This template helps separating the compilation of the intlit_grammar
|
||||
// class from the compilation of the expression_grammar. This is done
|
||||
// to safe compilation time.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename TokenT>
|
||||
struct BOOST_WAVE_DECL intlit_grammar_gen {
|
||||
|
||||
static uint_literal_type evaluate(TokenT const &tok, bool &is_unsigned);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// cpp_chlit_grammar_gen template class
|
||||
//
|
||||
// This template helps separating the compilation of the chlit_grammar
|
||||
// class from the compilation of the expression_grammar. This is done
|
||||
// to safe compilation time.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
template <typename IntegralResult, typename TokenT>
|
||||
struct BOOST_WAVE_DECL chlit_grammar_gen {
|
||||
|
||||
static IntegralResult evaluate(TokenT const &tok, value_error& status);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace grammars
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
// the suffix header occurs after all of the code
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
#include BOOST_ABI_SUFFIX
|
||||
#endif
|
||||
|
||||
#endif // !defined(CPP_LITERAL_GRAMMAR_GEN_HPP_67794A6C_468A_4AAB_A757_DEDDB182F5A0_INCLUDED)
|
||||
80
test/external/boost/wave/grammars/cpp_predef_macros_gen.hpp
vendored
Normal file
80
test/external/boost/wave/grammars/cpp_predef_macros_gen.hpp
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/*=============================================================================
|
||||
A Standard compliant C++ preprocessor
|
||||
|
||||
http://www.boost.org/
|
||||
|
||||
Copyright (c) 2001-2011 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_PREDEF_MACROS_GEN_HPP_CADB6D2C_76A4_4988_83E1_EFFC6902B9A2_INCLUDED)
|
||||
#define CPP_PREDEF_MACROS_GEN_HPP_CADB6D2C_76A4_4988_83E1_EFFC6902B9A2_INCLUDED
|
||||
|
||||
#include <boost/spirit/include/classic_parse_tree.hpp>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
|
||||
// this must occur after all of the includes and before any code appears
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
#include BOOST_ABI_PREFIX
|
||||
#endif
|
||||
|
||||
// suppress warnings about dependent classes not being exported from the dll
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4251 4231 4660)
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Here are the node id's of the different node of the cpp_grammar
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_WAVE_PLAIN_DEFINE_ID 5
|
||||
#define BOOST_WAVE_MACRO_PARAMETERS_ID 6
|
||||
#define BOOST_WAVE_MACRO_DEFINITION_ID 7
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// predefined_macros_grammar_gen template class
|
||||
//
|
||||
// This template helps separating the compilation of the
|
||||
// predefined_macros_grammar class from the compilation of the
|
||||
// main pp_iterator. This is done to safe compilation time.
|
||||
//
|
||||
// This class helps parsing command line given macro definitions in a
|
||||
// similar way, as macros are parsed by the cpp_grammar class.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename LexIteratorT>
|
||||
struct BOOST_WAVE_DECL predefined_macros_grammar_gen
|
||||
{
|
||||
typedef LexIteratorT iterator_type;
|
||||
|
||||
// parse the cpp_grammar and return the resulting parse tree
|
||||
static boost::spirit::classic::tree_parse_info<iterator_type>
|
||||
parse_predefined_macro (iterator_type const &first, iterator_type const &last);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace grammars
|
||||
} // namespace wave
|
||||
} // namespace boost
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
// the suffix header occurs after all of the code
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
#include BOOST_ABI_SUFFIX
|
||||
#endif
|
||||
|
||||
#endif // !defined(CPP_PREDEF_MACROS_GEN_HPP_CADB6D2C_76A4_4988_83E1_EFFC6902B9A2_INCLUDED)
|
||||
178
test/external/boost/wave/grammars/cpp_predef_macros_grammar.hpp
vendored
Normal file
178
test/external/boost/wave/grammars/cpp_predef_macros_grammar.hpp
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
/*=============================================================================
|
||||
Boost.Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://www.boost.org/
|
||||
|
||||
Copyright (c) 2001-2011 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_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED)
|
||||
#define CPP_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED
|
||||
|
||||
#include <boost/spirit/include/classic_core.hpp>
|
||||
#include <boost/spirit/include/classic_parse_tree.hpp>
|
||||
#include <boost/spirit/include/classic_confix.hpp>
|
||||
#include <boost/spirit/include/classic_lists.hpp>
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
#include <boost/wave/token_ids.hpp>
|
||||
#include <boost/wave/grammars/cpp_predef_macros_gen.hpp>
|
||||
#include <boost/wave/util/pattern_parser.hpp>
|
||||
|
||||
// this must occur after all of the includes and before any code appears
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
#include BOOST_ABI_PREFIX
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// define, whether the rule's should generate some debug output
|
||||
#define TRACE_PREDEF_MACROS_GRAMMAR \
|
||||
bool(BOOST_SPIRIT_DEBUG_FLAGS_CPP & BOOST_SPIRIT_DEBUG_FLAGS_PREDEF_MACROS_GRAMMAR) \
|
||||
/**/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Encapsulation of the grammar for command line driven predefined macros.
|
||||
struct predefined_macros_grammar :
|
||||
public boost::spirit::classic::grammar<predefined_macros_grammar>
|
||||
{
|
||||
template <typename ScannerT>
|
||||
struct definition
|
||||
{
|
||||
// 'normal' (parse_tree generating) rule type
|
||||
typedef boost::spirit::classic::rule<
|
||||
ScannerT, boost::spirit::classic::dynamic_parser_tag>
|
||||
rule_type;
|
||||
|
||||
rule_type plain_define, macro_definition, macro_parameters;
|
||||
|
||||
definition(predefined_macros_grammar const &/*self*/)
|
||||
{
|
||||
// import the spirit and cpplexer namespaces here
|
||||
using namespace boost::spirit::classic;
|
||||
using namespace boost::wave;
|
||||
using namespace boost::wave::util;
|
||||
|
||||
// set the rule id's for later use
|
||||
plain_define.set_id(BOOST_WAVE_PLAIN_DEFINE_ID);
|
||||
macro_parameters.set_id(BOOST_WAVE_MACRO_PARAMETERS_ID);
|
||||
macro_definition.set_id(BOOST_WAVE_MACRO_DEFINITION_ID);
|
||||
|
||||
// recognizes command line defined macro syntax, i.e.
|
||||
// -DMACRO
|
||||
// -DMACRO=
|
||||
// -DMACRO=value
|
||||
// -DMACRO(x)
|
||||
// -DMACRO(x)=
|
||||
// -DMACRO(x)=value
|
||||
|
||||
// This grammar resembles the overall structure of the cpp_grammar to
|
||||
// make it possible to reuse the parse tree traversal code
|
||||
plain_define
|
||||
= ( ch_p(T_IDENTIFIER)
|
||||
| pattern_p(KeywordTokenType,
|
||||
TokenTypeMask|PPTokenFlag)
|
||||
| pattern_p(OperatorTokenType|AltExtTokenType,
|
||||
ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc.
|
||||
| pattern_p(BoolLiteralTokenType,
|
||||
TokenTypeMask|PPTokenFlag) // true/false
|
||||
)
|
||||
>> !macro_parameters
|
||||
>> !macro_definition
|
||||
;
|
||||
|
||||
// parameter list
|
||||
macro_parameters
|
||||
= confix_p(
|
||||
no_node_d[ch_p(T_LEFTPAREN) >> *ch_p(T_SPACE)],
|
||||
!list_p(
|
||||
( ch_p(T_IDENTIFIER)
|
||||
| pattern_p(KeywordTokenType,
|
||||
TokenTypeMask|PPTokenFlag)
|
||||
| pattern_p(OperatorTokenType|AltExtTokenType,
|
||||
ExtTokenTypeMask|PPTokenFlag) // and, bit_and etc.
|
||||
| pattern_p(BoolLiteralTokenType,
|
||||
TokenTypeMask|PPTokenFlag) // true/false
|
||||
#if BOOST_WAVE_SUPPORT_VARIADICS_PLACEMARKERS != 0
|
||||
| ch_p(T_ELLIPSIS)
|
||||
#endif
|
||||
),
|
||||
no_node_d
|
||||
[
|
||||
*ch_p(T_SPACE) >> ch_p(T_COMMA) >> *ch_p(T_SPACE)
|
||||
]
|
||||
),
|
||||
no_node_d[*ch_p(T_SPACE) >> ch_p(T_RIGHTPAREN)]
|
||||
)
|
||||
;
|
||||
|
||||
// macro body (anything left until eol)
|
||||
macro_definition
|
||||
= no_node_d[ch_p(T_ASSIGN)]
|
||||
>> *anychar_p
|
||||
;
|
||||
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(plain_define, TRACE_PREDEF_MACROS_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_definition, TRACE_PREDEF_MACROS_GRAMMAR);
|
||||
BOOST_SPIRIT_DEBUG_TRACE_RULE(macro_parameters, TRACE_PREDEF_MACROS_GRAMMAR);
|
||||
}
|
||||
|
||||
// start rule of this grammar
|
||||
rule_type const& start() const
|
||||
{ return plain_define; }
|
||||
};
|
||||
|
||||
predefined_macros_grammar()
|
||||
{
|
||||
BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME(*this,
|
||||
"predefined_macros_grammar", TRACE_PREDEF_MACROS_GRAMMAR);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#undef TRACE_PREDEF_MACROS_GRAMMAR
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The following parse function is defined here, to allow the separation of
|
||||
// the compilation of the cpp_predefined_macros_grammar from the function
|
||||
// using it.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if BOOST_WAVE_SEPARATE_GRAMMAR_INSTANTIATION != 0
|
||||
#define BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE
|
||||
#else
|
||||
#define BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE inline
|
||||
#endif
|
||||
|
||||
template <typename LexIteratorT>
|
||||
BOOST_WAVE_PREDEF_MACROS_GRAMMAR_GEN_INLINE
|
||||
boost::spirit::classic::tree_parse_info<LexIteratorT>
|
||||
predefined_macros_grammar_gen<LexIteratorT>::parse_predefined_macro (
|
||||
LexIteratorT const &first, LexIteratorT const &last)
|
||||
{
|
||||
predefined_macros_grammar g;
|
||||
return boost::spirit::classic::pt_parse (first, last, g);
|
||||
}
|
||||
|
||||
#undef BOOST_WAVE_PREDEF_MACROS_GRAMMAR_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_PREDEF_MACROS_GRAMMAR_HPP_53858C9A_C202_4D60_AD92_DC9CAE4DBB43_INCLUDED)
|
||||
51
test/external/boost/wave/grammars/cpp_value_error.hpp
vendored
Normal file
51
test/external/boost/wave/grammars/cpp_value_error.hpp
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
/*=============================================================================
|
||||
Boost.Wave: A Standard compliant C++ preprocessor library
|
||||
|
||||
http://www.boost.org/
|
||||
|
||||
Copyright (c) 2001-2011 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(BOOST_WAVE_CPP_VALUE_ERROR_INCLUDED)
|
||||
#define BOOST_WAVE_CPP_VALUE_ERROR_INCLUDED
|
||||
|
||||
#include <boost/wave/wave_config.hpp>
|
||||
|
||||
// this must occur after all of the includes and before any code appears
|
||||
#ifdef BOOST_HAS_ABI_HEADERS
|
||||
#include BOOST_ABI_PREFIX
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost {
|
||||
namespace wave {
|
||||
namespace grammars {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// value_error enum type
|
||||
//
|
||||
// This is used to encode any error occurred during the evaluation of a
|
||||
// conditional preprocessor expression
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
enum value_error {
|
||||
error_noerror = 0x0,
|
||||
error_division_by_zero = 0x1,
|
||||
error_integer_overflow = 0x2,
|
||||
error_character_overflow = 0x4
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
} // 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(BOOST_WAVE_CPP_VALUE_ERROR_INCLUDED)
|
||||
Reference in New Issue
Block a user