⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 re_ops.hpp

📁 yard lib, template for regular rule
💻 HPP
字号:

// released into the public domain
// by Christopher Diggins 2004
// http://www.cdiggins.com

#ifndef REOPS_HPP_INCLUDED
#define REOPS_HPP_INCLUDED

#include "parser_input_stream.hpp"

namespace yard {
    // in order execute semantic actions, this class simply needs to be specialized by the user
    // for the Rules_T type

    template < typename Iter_T, typename Rules_T >
    struct Actor {
        static void OnBefore(Iter_T pos) { }
        static void OnSuccess(Iter_T begin, Iter_T end) { }
        static void OnFailure(Iter_T pos) { }
    };


    //This template function can be compile well but run badly in vc6.0 .It reveals the bugs that  vc6.0 does not
    //overload normal function depending on exlicit template argument  chinahardbone@yahoo.com
#if 0
    // this function attempts to match the pattern, but failing it backs the stream up to before failing

    template < typename Rules_T, typename Stream_T >
    bool match(Stream_T & stream) {
        // store stream position
        // typename Stream_T::iter_type pos = stream.GetPos();
        const char * pos = stream.GetPos();
        // notify of attempt to parse
        //Actor<typename Stream_T::iter_type, Rules_T>::OnBefore(pos);
        Actor < const char *, Rules_T >::OnBefore(pos);
        // try to match
        if (Rules_T::Accept(stream)) {
            // if successful trigger action ( this either goes to the default implementation at semantic_actions.hpp
            // or it calls a user defined actor ( this is done through specialization )
            // Actor<typename Stream_T::iter_type, Rules_T>::OnSuccess(pos, stream.GetPos());
            Actor < const char *, Rules_T >::OnSuccess(pos, stream.GetPos());
            return true;
        }
        // notify of failure parsing
        //    Actor<typename Stream_T::iter_type, Rules_T>::OnFailure(stream.GetPos());
        Actor < const char *, Rules_T >::OnFailure(stream.GetPos());
        // restore stream position
        stream.SetPos(pos);
        return false;
    };
#endif

    //The best way to retain the original interface of match template function is changing match as a template class

    template < typename Rules_T >
    struct match {
        template < typename Stream_T >
        bool operator() (Stream_T & stream) {
		//re check chinahardbone@yahoo.com 2005/02/16
		if (stream.AtEnd()) return false;
		
            // store stream position
            // typename Stream_T::iter_type pos = stream.GetPos();
            const char * pos = stream.GetPos();
            // notify of attempt to parse
            //Actor<typename Stream_T::iter_type, Rules_T>::OnBefore(pos);
            Actor < const char *, Rules_T >::OnBefore(pos);
            // try to match
            if (Rules_T::Accept(stream)) {
                // if successful trigger action ( this either goes to the default implementation at semantic_actions.hpp
                // or it calls a user defined actor ( this is done through specialization )
                // Actor<typename Stream_T::iter_type, Rules_T>::OnSuccess(pos, stream.GetPos());
                Actor < const char *, Rules_T >::OnSuccess(pos, stream.GetPos());
                return true;
            }
            // notify of failure parsing
            //    Actor<typename Stream_T::iter_type, Rules_T>::OnFailure(stream.GetPos());
            Actor < const char *, Rules_T >::OnFailure(stream.GetPos());
            // restore stream position
            stream.SetPos(pos);
            return false;
        }
    };

    template < typename T0, typename T1 >
    struct re_or {
        // attempts to match T0, failing that it attempt to match T1

        template < typename Stream_T >
        static bool Accept(Stream_T & stream) {
            return (match < T0 > () (stream) || match < T1 > () (stream));
        }
    };

    template < typename T0, typename T1, typename T2 >
    struct re_or3 {
        // attempts to match T0, failing that it attempt to match T1

        template < typename Stream_T >
        static bool Accept(Stream_T & stream) {
            return (match < T0 > () (stream) || match < T1 > () (stream) || match < T2 > () (stream));
        }
    };

    template < typename T0, typename T1 >
    struct re_and {
        // matches T0 then T1

        template < typename Stream_T >
        static bool Accept(Stream_T & stream) {
            return (match < T0 > () (stream) && match < T1 > () (stream));
        }
    };

    template < typename T0, typename T1, typename T2 >
    struct re_and3 {
        // matches T0 then T1

        template < typename Stream_T >
        static bool Accept(Stream_T & stream) {
            return (match < T0 > () (stream) && match < T1 > () (stream) && match < T2 > () (stream));
        }
    };

    template < typename T0, typename T1, typename T2, typename T3 >
    struct re_and4 {
        // matches T0 then T1

        template < typename Stream_T >
        static bool Accept(Stream_T & stream) {
            return (match < T0 > () (stream) && match < T1 > () (stream) && match < T2 > () (stream) &&
               match < T3 > () (stream));
        }
    };


    template < typename T >
    struct re_star {
        // matches 0 or more times the pattern represented by T

        template < typename Stream_T >
        static bool Accept(Stream_T & stream) {
            while (match < T > () (stream)) { }
            return true;
        }
    };

    template < typename T >
    struct re_plus {
        // matches 1 or more times the pattern represented by T

        template < typename Stream_T >
        static bool Accept(Stream_T & stream) {
            if (match < T > () (stream)) {
                while (match < T > () (stream)) { }
                return true;
            }
            else {
                return false;
            }
        }
    };

    template < typename T >
    struct re_opt {
        // matches 0 or 1 times the pattern represented by T

        template < typename Stream_T >
        static bool Accept(Stream_T & stream) {
            match < T > () (stream);
            return true;
        }
    };

    template < typename T, unsigned int N >
    struct re_repeat {
        // matches exactly N times the pattern represented by T

        template < typename Stream_T >
        static bool Accept(Stream_T & stream) {
            for (int i = 0; i < N; ++i) {
                if (!match < T > () (stream)) {
                    return false;
                }
            }
            return true;
        }
    };

    template < typename T >
    struct re_until {
        template < typename Stream_T >
        static bool Accept(Stream_T & stream) {
            if (stream.AtEnd()) return false;
            while (!match < T > () (stream)) {
                if (stream.AtEnd()) return false;
                stream.GotoNext();
            }
            return true;
        }
    };

    /**
     * The class re_not<typename T> emulate the regular expression operator ^. The accept function should always return true.
     * IF NOT THEN GONEXT, RETURNT TRUE.
     */

    template < typename T >
    struct re_not {
        template < typename Stream_T >
        static bool Accept(Stream_T & stream) {
            return !match < T > () (stream);
        }
    };

    /** Exclusive or (XOR) */

    template < typename T0, typename T1 >
    struct re_XOR {
        template < typename Stream_T >
        static bool Accept(Stream_T & stream) {
            if (stream.AtEnd()) return true;

            bool a, b;
            a = match < T0 > () (stream);
            b = match < T1 > () (stream);

            return (a != b);
        }
    };

    template < typename TRule >
    struct Control_Probe {
        template < typename Stream_T >
        static bool Accept(Stream_T & stream) {
            Stream_T::iter_type itbegin = stream.GetPos();
            bool ret;
            ret = match < TRule > () (stream);
            stream.SetPos(itbegin);
            return ret;
        }
    };

    template < int number >
    struct Control_GoTo {
        template < typename Stream_T >
        static bool Accept(Stream_T & stream) {
            Stream_T::iter_type itbegin = stream.GetPos();
            stream.SetPos(itbegin + number);
            return true;
        }
    };

    /** LeftIndenty and RightIndenty > 0 if the renge in the behind of current position */

    template < typename Rules_T, int LeftIndenty, int RightIndenty >
    struct Control_RangeMatch {
        template < typename Stream_T >
        static bool Accept(Stream_T & stream) {
            //adjust the indenty position
            Stream_T::iter_type beginPos;
            int leftDiff;
            Stream_T::iter_type endPos;
            int rightDiff;
            leftDiff = (stream.GetPos() - stream.getBeginPos());
            rightDiff = (stream.getEndPos() - stream.GetPos());
            beginPos = stream.GetPos() + ((leftDiff < 0) ? leftDiff : LeftIndenty);
            endPos = stream.GetPos() + ((rightDiff < 0) ? rightDiff : RightIndenty);
            ParserInputStream < char > input(beginPos, endPos);
            return Rules_T::Accept(input);
        }
    };

    /** Nest rule */


    template < typename T0, typename T1 >
    class re_NestRule {
    public:
        template < typename Stream_T >
        static bool Accept(Stream_T & stream) {
            return MatchHelp::Accept(stream);
        }

    private:
        struct MatchHelp;

        /** match ... */
        struct Help1 : public re_until < re_or < Control_Probe < T0 >, Control_Probe < T1 > > > { };


        /** match ...[...]... */
        struct Help2 : public re_and3 < //
        Help1, MatchHelp, Help1 > { };


        struct MatchHelp : public re_and3 < T0, re_star < Help2 >, re_until < T1 > > { };



    };


}

#endif // #ifndef REOPS_HPP_INCLUDED

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -