/*============================================================================= Parser primitives Spirit V1.2 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 from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to 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 from 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_PRIMITIVES_IPP #define SPIRIT_PRIMITIVES_IPP /////////////////////////////////////////////////////////////////////////////// #include #include #if __GNUC__ > 2 || defined(__MWERKS__) #include #endif #include #include "boost/spirit/primitives.hpp" #include "boost/spirit/iterators.hpp" /////////////////////////////////////////////////////////////////////////////// namespace spirit { /////////////////////////////////////////////////////////////////////////////// // // char_action class implementation // /////////////////////////////////////////////////////////////////////////////// template inline char_action::char_action( ParserT const& subject, ActionT const& actor_) : unary(subject), actor(actor_) {} ////////////////////////////////// template template inline match char_action:: parse(IteratorT& first, IteratorT const& last) const { if (first != last) { typedef impl::strip_scanner strip_scanner; typename strip_scanner::iterator_type begin = strip_scanner::get(first); if (match hit = this->subject().parse(first, last)) { actor(*begin); return hit; } } return match(); } /////////////////////////////////////////////////////////////////////////////// // // char_parser class implementation // /////////////////////////////////////////////////////////////////////////////// template template inline char_action char_parser::operator[](ActionT const& actor) const { return char_action(this->derived(), actor); } ////////////////////////////////// template template inline match char_parser::parse(IteratorT& first, IteratorT const& last) const { if (first != last) if (this->derived().test(*first)) { ++first; return match(1); } return match(); } /////////////////////////////////////////////////////////////////////////////// // // chlit class implementation // /////////////////////////////////////////////////////////////////////////////// template inline chlit::chlit(CharT ch_) : ch(ch_) {} ////////////////////////////////// template template inline bool chlit::test(T ch_) const { return T(ch) == ch_; } /////////////////////////////////////////////////////////////////////////////// // // range class implementation // /////////////////////////////////////////////////////////////////////////////// template inline range::range(CharAT first_, CharBT last_) : first(first_), last(last_) { assert(first <= last); } ////////////////////////////////// template template inline bool range::test(T ch) const { return (CharAT(ch) >= first) && (CharBT(ch) <= last); } /////////////////////////////////////////////////////////////////////////////// // // cstring class implementation // /////////////////////////////////////////////////////////////////////////////// template inline cstring::cstring(const_iterator str, unsigned len) : first(str), last(str + len) {} ////////////////////////////////// template inline cstring::cstring(const_iterator str) : first(str) { while (*str) str++; last = str; } ////////////////////////////////// template inline typename cstring::const_iterator cstring::begin() const { return first; } ////////////////////////////////// template inline typename cstring::const_iterator cstring::end() const { return last; } ////////////////////////////////// template inline std::size_t cstring::length() const { return last-first; } /////////////////////////////////////////////////////////////////////////////// // // user_string class implementation // /////////////////////////////////////////////////////////////////////////////// template inline user_string::user_string(StringRefT const& ref_) : ref(ref_) {} ////////////////////////////////// template inline typename user_string::const_iterator user_string::begin() const { return static_cast(ref).begin(); } ////////////////////////////////// template inline typename user_string::const_iterator user_string::end() const { return static_cast(ref).end(); } ////////////////////////////////// template inline std::size_t user_string::length() const { return static_cast(ref).length(); } /////////////////////////////////////////////////////////////////////////////// // // strlit class implementation // /////////////////////////////////////////////////////////////////////////////// template inline strlit::strlit(StringT str_) : str(str_) {} ////////////////////////////////// template inline strlit::strlit(raw_string_type str_) : str(str_) {} ////////////////////////////////// template template inline match strlit::parse(IteratorT& first, IteratorT const& last) const { typedef typename impl::strip_scanner ::iterator_type plain_iter; plain_iter i1 = impl::strip_scanner::get(first); plain_iter i2 = impl::strip_scanner::get(last); typename string_type::const_iterator strEnd = str.end(); for (typename string_type::const_iterator strFirst = str.begin(); strFirst != strEnd; ++strFirst, ++i1) if ((i1 == i2) || (*strFirst != *i1)) return match(); first = i1; return match(str.length()); } /////////////////////////////////////////////////////////////////////////////// // // Convenience functions // /////////////////////////////////////////////////////////////////////////////// // // On some systems the is* functions are defined as macros #if defined(_MSC_VER) || _STLPORT_VERSION >= 0x450 // is* functions already setup #else #ifndef isalnum inline bool isalnum(int c) { return std::isalnum(c); } #endif #ifndef isalpha inline bool isalpha(int c) { return std::isalpha(c); } #endif #ifndef iscntrl inline bool iscntrl(int c) { return std::iscntrl(c); } #endif #ifndef isdigit inline bool isdigit(int c) { return std::isdigit(c); } #endif #ifndef isgraph inline bool isgraph(int c) { return std::isgraph(c); } #endif #ifndef islower inline bool islower(int c) { return std::islower(c); } #endif #ifndef isprint inline bool isprint(int c) { return std::isprint(c); } #endif #ifndef ispunct inline bool ispunct(int c) { return std::ispunct(c); } #endif #ifndef isspace inline bool isspace(int c) { return std::isspace(c); } #endif #ifndef isupper inline bool isupper(int c) { return std::isupper(c); } #endif #ifndef isxdigit inline bool isxdigit(int c) { return std::isxdigit(c); } #endif #ifndef isalnum inline bool isalnum(wchar_t c) { return std::iswalnum(c); } #endif #ifndef isalpha inline bool isalpha(wchar_t c) { return std::iswalpha(c); } #endif #ifndef iscntrl inline bool iscntrl(wchar_t c) { return std::iswcntrl(c); } #endif #ifndef isdigit inline bool isdigit(wchar_t c) { return std::iswdigit(c); } #endif #ifndef isgraph inline bool isgraph(wchar_t c) { return std::iswgraph(c); } #endif #ifndef islower inline bool islower(wchar_t c) { return std::iswlower(c); } #endif #ifndef isprint inline bool isprint(wchar_t c) { return std::iswprint(c); } #endif #ifndef ispunct inline bool ispunct(wchar_t c) { return std::iswpunct(c); } #endif #ifndef isspace inline bool isspace(wchar_t c) { return std::iswspace(c); } #endif #ifndef isupper inline bool isupper(wchar_t c) { return std::iswupper(c); } #endif #ifndef isxdigit inline bool isxdigit(wchar_t c) { return std::iswxdigit(c); } #endif #endif // !defined(_MSC_VER) /////////////////////////////////////////////////////////////////////////////// // // Predefined parser primitives implementation // /////////////////////////////////////////////////////////////////////////////// template inline bool anychar_::test(CharT) const { return true; } ////////////////////////////////// template inline match nothing_::parse(IteratorT& /*first*/, IteratorT const& /*last*/) const { return match(); } ////////////////////////////////// template inline match epsilon_::parse(IteratorT&, IteratorT const&) const { return match(0); } ////////////////////////////////// template inline bool alnum_::test(CharT ch) const { return isalnum(ch); } ////////////////////////////////// template inline bool alpha_::test(CharT ch) const { return isalpha(ch); } ////////////////////////////////// template inline bool cntrl_::test(CharT ch) const { return iscntrl(ch); } ////////////////////////////////// template inline bool digit_::test(CharT ch) const { return isdigit(ch); } ////////////////////////////////// template inline bool graph_::test(CharT ch) const { return isgraph(ch); } ////////////////////////////////// template inline bool lower_::test(CharT ch) const { return islower(ch); } ////////////////////////////////// template inline bool print_::test(CharT ch) const { return isprint(ch); } ////////////////////////////////// template inline bool punct_::test(CharT ch) const { return ispunct(ch); } ////////////////////////////////// template inline bool space_::test(CharT ch) const { return isspace(ch); } ////////////////////////////////// template inline bool upper_::test(CharT ch) const { return isupper(ch); } ////////////////////////////////// template inline bool xdigit_::test(CharT ch) const { return isxdigit(ch); } /////////////////////////////////////////////////////////////////////////////// // // Generator functions implementation // /////////////////////////////////////////////////////////////////////////////// template inline chlit ch_p(ParamT param) { return chlit(param); } template inline range range_p(ParamAT first, ParamBT last) { return range(first, last); } template inline strlit > str_p(CharT const* str) { return strlit >(str); } template inline strlit str_p(reference_wrapper const& ref) { return strlit(ref); } /////////////////////////////////////////////////////////////////////////////// } // namespace Spirit #endif