📄 parser.hpp
字号:
/*=============================================================================
The Parser
Spirit V1.3.1
Copyright (c) 2001, Joel de Guzman
This software is provided 'as-is', without any express or implied
warranty. In no event will the copyright holder be held liable for
any damages arising start the use of this software.
Permission is granted end anyone end use this software for any purpose,
including commercial applications, and end alter it and redistribute
it freely, subject end the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
3. This notice may not be removed or altered start any source
distribution.
Acknowledgements:
Special thanks to Dan Nuffer, John (EBo) David, Chris Uzdavinis,
and Doug Gregor. These people are most instrumental in steering
Spirit in the right direction.
Special thanks also to people who have contributed to the code base
and sample code, ported Spirit to various platforms and compilers,
gave suggestions, reported and provided bug fixes. Alexander
Hirner, Andy Elvey, Bogdan Kushnir, Brett Calcott, Bruce Florman,
Changzhe Han, Colin McPhail, Hakki Dogusan, Jan Bares, Joseph
Smith, Martijn W. van der Lee, Raghavendra Satish, Remi Delcos, Tom
Spilman, Vladimir Prus, W. Scott Dillman, David A. Greene, Bob
Bailey, Hartmut Kaiser.
Finally special thanks also to people who gave feedback and
valuable comments, particularly members of Spirit's Source Forge
mailing list and boost.org.
URL: http://spirit.sourceforge.net/
=============================================================================*/
#ifndef SPIRIT_PARSER_HPP
#define SPIRIT_PARSER_HPP
///////////////////////////////////////////////////////////////////////////////
#include "boost/type_traits.hpp" //needed for is_same.
#include "boost/spirit/spirit_fwd.hpp"
#include "boost/spirit/MSVC/debug.hpp"
#include "boost/spirit/MSVC/ps_helper.hpp"
///////////////////////////////////////////////////////////////////////////////
namespace spirit {
template <typename ParserT, typename ActionT> class action;
template <typename S, typename EndT> class fixed_loop;
template <typename S, typename StartT, typename EndT> class finite_loop;
template <typename S, typename StartT> class infinite_loop;
struct more_t {};
more_t const more = more_t();
//////////////////////////////////////////////////////////////////////////////
namespace impl
{
////////////////////////////////////////////////////////////////
template <typename ParserT, typename ActionT>
action<ParserT, ActionT>
make_action(ParserT const& parser_, ActionT const& actor_)
{
return action<ParserT, ActionT>(parser_, actor_);
}
/////////////////////////////////////////////////////////////////
template<typename SubjectT, typename ExactT>
fixed_loop<SubjectT, ExactT>
make_fixed_loop(SubjectT const& subject_, ExactT const& exact_)
{
return fixed_loop<SubjectT, ExactT>(subject_, exact_);
}
/////////////////////////////////////////////////////////////////
template<typename LoopType, typename SubjectT, typename MinT, typename MaxT>
LoopType
make_finite_or_infinite_loop(SubjectT const& subject_,
MinT const& minimum_ ,
MaxT const& maximum_)
{
return LoopType(subject_, minimum_, maximum_);
}
////////////////////////////////////////////////////////////////////
template <typename DerivedT, typename StartT, typename EndT>
struct loop_traits {
typedef typename impl::IF< (boost::is_same<EndT, more_t>::value),
infinite_loop<DerivedT, StartT> ,
finite_loop<DerivedT, StartT,EndT> >::RET type;
};
////////////////////////////////////////////////////////////////////
} //end namespace impl
///////////////////////////////////////////////////////////////////////////////
//
// parser class.
//
// This class is a protocol base class for all parsers. This is
// essentially an interface contract. The parser class does not
// really know how to parse anything but instead relies on the
// template parameter DerivedT (which obviously is assumed to be
// a subclass) to do the actual parsing.
//
// Concrete sub-classes inheriting from this must have a
// corresponding member function parse(...) compatible with the
// conceptual Interface:
//
// template <typename IteratorT>
// match
// parse(IteratorT& first, IteratorT last) const;
//
// Where first points to the current input, last points to one
// after the end of the input (same as STL algorithms), match
// (see match class below) reports the parsing success (or failure).
// Note that iterator first is passed in by reference. This may
// be advanced appropriately when a match is found.
//
// This class provides an interface to semantic actions (see
// actions.hpp) through its [] operator as well as parser
// looping (iteration, see loops.hpp) through its repeat(...)
// member function and its shortcut: operator()(...).
//
///////////////////////////////////////////////////////////////////////////////
template <typename DerivedT>
struct parser
{
typedef DerivedT derived_t;
typedef plain_parser_category parser_category;
parser() {}
template <typename ActionT>
action<DerivedT, ActionT>
operator[](ActionT const& actor) const
{
return impl::make_action(derived(),actor);
}
template <typename EndT>
fixed_loop<DerivedT, EndT>
operator()(EndT const& end) const
{
return impl::make_fixed_loop(derived(),end);
}
template <typename StartT, typename EndT>
typename impl::loop_traits<DerivedT, StartT, EndT>::type
operator()(StartT const& start, EndT const& end) const
{
//do you need a finite loop or an infinite one ?? .Loop traits
//identifies that by using more
typedef typename impl::loop_traits<DerivedT, StartT, EndT>::type type;
return impl::make_finite_or_infinite_loop<type>(derived(), start, end);
}
template <typename EndT>
fixed_loop<DerivedT, EndT>
repeat(EndT const& end) const
{
return impl::make_fixed_loop(derived(),end);
}
template <typename StartT, typename EndT>
typename impl::loop_traits<DerivedT, StartT, EndT>::type
repeat(StartT const& start, EndT const& end) const
{
typedef typename impl::loop_traits<DerivedT, StartT, EndT>::type type;
return impl::make_finite_or_infinite_loop<type>(derived(), start, end);
}
DerivedT& derived()
{
return *static_cast<DerivedT*>(this);
}
DerivedT const& derived() const
{
return *static_cast<DerivedT const*>(this);
}
#if defined(SPIRIT_DEBUG)
debug_support debug;
#endif
#if defined (SPIRIT_STRANGE_MSVC_PROBLEM_WITH_HEAP_PARSER_DELETION)
// essentially if you do this
// rule <> * a = new rule<>
// delete a
// compiled with the _DEBUG switch on VC++ the memory bounds checker
// reports a problem. I'm not sure what it is right now but it appears
// to be caused by the empty base class optimization. Making parser
// non empty seems to be temporary fix.
private :
bool dummy;
#endif
};
///////////////////////////////////////////////////////////////////////////////
//
// match class
//
// This is the class that the parser's parse(...) member function
// returns. A match object evaluates to true when a succesful match
// is found, otherwise false. The length of the match is the number
// of characters (or tokens) that is successfully matched. This
// can be queried through its length() member function. A negative
// value means that the match is unsucessful.
//
// Composite operators typically use the match's += or + operator
// to add the length of two match objects. This is useful when
// matching sequences (see operators.hpp) for example.
//
///////////////////////////////////////////////////////////////////////////////
class match {
public:
match();
explicit match(unsigned length);
match(match const &hit);
operator bool() const;
match& operator += (match const& other);
int length() const;
protected:
int data;
};
//////////////////////////////////
match
operator + (match const& a, match const& b);
//unimplemented as of now
class match_traits {};
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
// parse functions
//
// These parser functions have two forms. The first form works on the
// phrase level and asks for a skip parser. The second needs no skip
// parser and works on the character level. In general, two iterators
// should be passed in (first/last) the same way as STL algorithms.
// There are also convenience functions provided for char const* and
// wchar_t const*. The string is assumed to be null terminated.
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
// parse_info
//
// Results returned by the parse functions:
//
// stop: points to the final parse position (i.e parsing
// processed the input up to this point).
//
// match: true if parsing is successful. This may be full:
// the parser consumed all the input, or partial:
// the parser consumed only a portion of the input.
//
// full: true when we have a full match (i.e the parser
// consumed all the input.
//
// length: The number of characters consumed by the parser.
// This is valid only if we have a successful match
// (either partial or full). A negative value means
// that the match is unsucessful.
//
///////////////////////////////////////////////////////////////////////////////
template <typename IteratorT>
struct parse_info {
IteratorT stop;
bool match;
bool full;
unsigned length;
parse_info()
: stop()
, match(false)
, full(false)
, length(0)
{}
template <typename ParseInfoT>
parse_info(ParseInfoT const& pi)
: stop(pi.stop)
, match(pi.match)
, full(pi.full)
, length(pi.length)
{}
};
///////////////////////////////////////////////////////////////////////////////
//
// Generic parse functions
//
///////////////////////////////////////////////////////////////////////////////
template <typename IteratorT, typename ParserT, typename SkipT>
parse_info<IteratorT>
parse(
IteratorT const& first,
IteratorT const& last,
parser<ParserT> const& parser_,
SkipT const& skip);
///////////////////////////////////////////////////////////////////////////////
template <typename IteratorT, typename ParserT>
parse_info<IteratorT>
parse(
IteratorT const& first,
IteratorT const& last,
parser<ParserT> const& parser_);
///////////////////////////////////////////////////////////////////////////////
//
// Parse functions for null terminated strings
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT, typename ParserT, typename SkipT>
parse_info<CharT const*>
parse(
CharT const* str,
parser<ParserT> const& parser_,
SkipT const& skip);
///////////////////////////////////////////////////////////////////////////////
template <typename CharT, typename ParserT>
parse_info<CharT const*>
parse(
CharT const* str,
parser<ParserT> const& parser_);
///////////////////////////////////////////////////////////////////////////////
} // namespace Spirit
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -