summaryrefslogtreecommitdiff
path: root/src/experimental/regexengine.h
blob: 133d418ef9c188fd5f48e9ba0b36af09a9152a3d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#ifndef BU_REG_EX_ENGINE_H
#define BU_REG_EX_ENGINE_H

#include "bu/sharedcore.h"
#include "bu/array.h"
#include "bu/sio.h"

namespace Bu
{
    template<typename chr> class RegExEngine;

    template<typename chr>
    class RegExEngineCore
    {
    friend class RegExEngine<chr>;
    friend class SharedCore<RegExEngine<chr>, RegExEngineCore<chr> >;
    private:
        RegExEngineCore()
        {
        }

        virtual ~RegExEngineCore()
        {
        }

        class Range
        {
        public:
            Range( chr cLower, chr cUpper, int iTrgState ) :
                cLower( cLower ), cUpper( cUpper ), iTrgState( iTrgState )
            {
            }
        
            chr cLower;
            chr cUpper;
            int iTrgState;
        };

        class State
        {
        public:
            Bu::Array<Range> aRange;
        };

        int addState()
        {
            aState.append( State() );
            return aState.getSize()-1;
        }

        void addCompletion( int iState, chr cLower, chr cUpper, int iTrgState )
        {
            aState[iState].aRange.append( Range( cLower, cUpper, iTrgState ) );
        }

        template<typename str>
        bool match( const str &sIn, int &iSize, int &iCompletion )
        {
            bool bMatch;
            int iState = 0;
            iSize = 0;
            for( typename str::const_iterator i = sIn.begin(); i; i++ )
            {
                Bu::sio << "Finding char " << *i << " in state " << iState
                    << ":" << Bu::sio.nl;
                bMatch = false;
                for( typename Bu::Array<Range>::iterator j =
                     aState[iState].aRange.begin(); j; j++ )
                {
                    Bu::sio << "    Testing range " << (*j).cLower << " - " << (*j).cUpper << Bu::sio.nl;
                    if( *i >= (*j).cLower && *i <= (*j).cUpper )
                    {
                        iState = (*j).iTrgState;
                        bMatch = true;
                        iSize++;
                        if( iState < 0 )
                        {
                            iCompletion = iState;
                            return true;
                        }
                    }
                }
                if( bMatch == false )
                {
                    return false;
                }
            }

            iCompletion = 0;
            return true;
        }

        typedef Bu::Array<State> StateArray;
        StateArray aState;
    };

    template<typename chr>
    class RegExEngine : public SharedCore<RegExEngine<chr>,
                        RegExEngineCore<chr> >
    {
    private:
        typedef class RegExEngine<chr> MyType;
        typedef class RegExEngineCore<chr> Core;
        typedef class Core::Range Range;
        typedef class Core::State State;
    
    protected:
        using SharedCore<MyType, Core>::core;
        using SharedCore<MyType, Core>::_hardCopy;
        using SharedCore<MyType, Core>::_resetCore;
        using SharedCore<MyType, Core>::_allocateCore;

    public:
        RegExEngine()
        {
        }

        virtual ~RegExEngine()
        {
        }

        int addState()
        {
            return core->addState();
        }

        void addCompletion( int iState, chr cLower, chr cUpper, int iTrgState )
        {
            core->addCompletion( iState, cLower, cUpper, iTrgState );
        }

        template<typename str>
        bool match( const str &sIn, int &iSize, int &iCompletion )
        {
            return core->match( sIn, iSize, iCompletion );
        }

    private:
    };
};

#endif