📄 primitives.hpp
字号:
/*=============================================================================
Copyright (c) 1998-2003 Joel de Guzman
Copyright (c) 2003 Martin Wille
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_PRIMITIVES_HPP)
#define BOOST_SPIRIT_PRIMITIVES_HPP
#include <boost/ref.hpp>
#include <boost/spirit/core/assert.hpp>
#include <boost/spirit/core/parser.hpp>
#include <boost/spirit/core/composite/impl/directives.ipp>
#include <boost/spirit/core/primitives/impl/primitives.ipp>
namespace boost { namespace spirit {
///////////////////////////////////////////////////////////////////////////
//
// char_parser class
//
///////////////////////////////////////////////////////////////////////////
template <typename DerivedT>
struct char_parser : public parser<DerivedT>
{
typedef DerivedT self_t;
template <typename ScannerT>
struct result
{
typedef typename match_result<
ScannerT,
typename ScannerT::value_t
>::type type;
};
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
typedef typename parser_result<self_t, ScannerT>::type result_t;
typedef typename ScannerT::value_t value_t;
typedef typename ScannerT::iterator_t iterator_t;
if (!scan.at_end())
{
value_t ch = *scan;
if (this->derived().test(ch))
{
iterator_t save(scan.first);
++scan.first;
return scan.create_match(1, ch, save, scan.first);
}
}
return scan.no_match();
}
};
///////////////////////////////////////////////////////////////////////////
//
// negation of char_parsers
//
///////////////////////////////////////////////////////////////////////////
template <typename PositiveT>
struct negated_char_parser
: public char_parser<negated_char_parser<PositiveT> >
{
typedef negated_char_parser<PositiveT> self_t;
typedef PositiveT positive_t;
negated_char_parser(positive_t const& p)
: positive(p.derived()) {}
template <typename T>
bool test(T ch) const
{
return !positive.test(ch);
}
positive_t const positive;
};
template <typename ParserT>
inline negated_char_parser<ParserT>
operator~(char_parser<ParserT> const& p)
{
return negated_char_parser<ParserT>(p.derived());
}
template <typename ParserT>
inline ParserT
operator~(negated_char_parser<ParserT> const& n)
{
return n.positive;
}
///////////////////////////////////////////////////////////////////////////
//
// chlit class
//
///////////////////////////////////////////////////////////////////////////
template <typename CharT = char>
struct chlit : public char_parser<chlit<CharT> >
{
chlit(CharT ch_)
: ch(ch_) {}
template <typename T>
bool test(T ch_) const
{
return ch_ == ch;
}
CharT ch;
};
template <typename CharT>
inline chlit<CharT>
ch_p(CharT ch)
{
return chlit<CharT>(ch);
}
// This should take care of ch_p("a") "bugs"
template <typename CharT, std::size_t N>
inline chlit<CharT>
ch_p(CharT const (& str)[N])
{
// ch_p's argument should be a single character or a null-terminated
// string with a single character
BOOST_STATIC_ASSERT(N < 3);
return chlit<CharT>(str[0]);
}
///////////////////////////////////////////////////////////////////////////
//
// range class
//
///////////////////////////////////////////////////////////////////////////
template <typename CharT = char>
struct range : public char_parser<range<CharT> >
{
range(CharT first_, CharT last_)
: first(first_), last(last_)
{
BOOST_SPIRIT_ASSERT(!(last < first));
}
template <typename T>
bool test(T ch) const
{
return !(CharT(ch) < first) && !(last < CharT(ch));
}
CharT first;
CharT last;
};
template <typename CharT>
inline range<CharT>
range_p(CharT first, CharT last)
{
return range<CharT>(first, last);
}
///////////////////////////////////////////////////////////////////////////
//
// chseq class
//
///////////////////////////////////////////////////////////////////////////
template <typename IteratorT = char const*>
class chseq : public parser<chseq<IteratorT> >
{
public:
typedef chseq<IteratorT> self_t;
chseq(IteratorT first_, IteratorT last_)
: first(first_), last(last_) {}
chseq(IteratorT first_)
: first(first_), last(impl::get_last(first_)) {}
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
typedef typename boost::unwrap_reference<IteratorT>::type striter_t;
typedef typename parser_result<self_t, ScannerT>::type result_t;
return impl::string_parser_parse<result_t>(
striter_t(first),
striter_t(last),
scan);
}
private:
IteratorT first;
IteratorT last;
};
template <typename CharT>
inline chseq<CharT const*>
chseq_p(CharT const* str)
{
return chseq<CharT const*>(str);
}
template <typename IteratorT>
inline chseq<IteratorT>
chseq_p(IteratorT first, IteratorT last)
{
return chseq<IteratorT>(first, last);
}
///////////////////////////////////////////////////////////////////////////
//
// strlit class
//
///////////////////////////////////////////////////////////////////////////
template <typename IteratorT = char const*>
class strlit : public parser<strlit<IteratorT> >
{
public:
typedef strlit<IteratorT> self_t;
strlit(IteratorT first, IteratorT last)
: seq(first, last) {}
strlit(IteratorT first)
: seq(first) {}
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
typedef typename parser_result<self_t, ScannerT>::type result_t;
return impl::contiguous_parser_parse<result_t>
(seq, scan, scan);
}
private:
chseq<IteratorT> seq;
};
template <typename CharT>
inline strlit<CharT const*>
str_p(CharT const* str)
{
return strlit<CharT const*>(str);
}
template <typename CharT>
inline strlit<CharT *>
str_p(CharT * str)
{
return strlit<CharT *>(str);
}
template <typename IteratorT>
inline strlit<IteratorT>
str_p(IteratorT first, IteratorT last)
{
return strlit<IteratorT>(first, last);
}
// This should take care of str_p('a') "bugs"
template <typename CharT>
inline chlit<CharT>
str_p(CharT ch)
{
return chlit<CharT>(ch);
}
///////////////////////////////////////////////////////////////////////////
//
// nothing_parser class
//
///////////////////////////////////////////////////////////////////////////
struct nothing_parser : public parser<nothing_parser>
{
typedef nothing_parser self_t;
nothing_parser() {}
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
return scan.no_match();
}
};
nothing_parser const nothing_p = nothing_parser();
///////////////////////////////////////////////////////////////////////////
//
// anychar_parser class
//
///////////////////////////////////////////////////////////////////////////
struct anychar_parser : public char_parser<anychar_parser>
{
typedef anychar_parser self_t;
anychar_parser() {}
template <typename CharT>
bool test(CharT) const
{
return true;
}
};
anychar_parser const anychar_p = anychar_parser();
inline nothing_parser
operator~(anychar_parser)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -