Package org.jkff.ire

Source Code of org.jkff.ire.DFAMatcher$SP

package org.jkff.ire;

import org.jkff.ire.fa.BiDFA;
import org.jkff.ire.fa.State;
import org.jkff.ire.util.Function2;
import org.jkff.ire.util.Pair;
import org.jkff.ire.util.Predicate;

import org.jkff.ire.util.WrappedBitSet;
import java.util.List;

import static org.jkff.ire.util.CollectionFactory.newArrayList;

/**
* Created on: 31.07.2010 12:19:28
*/
public class DFAMatcher {
    @SuppressWarnings("unchecked")
    public static <ST extends State>
        Iterable<Match> getMatches(
            final BiDFA<Character, ST> bidfa, final DFAIndexedString<ST> string)
    {
        final ST initial = bidfa.getForward().getInitialState();

        Function2<SP<ST>, IndexedString, SP<ST>> addString = new Function2<SP<ST>, IndexedString, SP<ST>>() {
            public SP<ST> applyTo(SP<ST> sp, IndexedString s) {
                return new SP<ST>(((DFAIndexedString<ST>) s).getForward().next(sp.state), sp.pos+s.length());
            }
        };

        Function2<SP<ST>, Character, SP<ST>> addChar = new Function2<SP<ST>, Character, SP<ST>>() {
            public SP<ST> applyTo(SP<ST> sp, Character c) {
                return new SP<ST>(bidfa.getForward().transfer(c).next(sp.state), sp.pos+1);
            }
        };

        List<Match> res = newArrayList();

        int shift = 0;

        SP<ST> matchStartState = new SP<ST>(initial, 0);
        IndexedString rem = string;
        IndexedString seen = string.subSequence(0,0);

        while(true) {
            Pair<IndexedString, IndexedString> p = rem.splitAfterRise(
                    matchStartState, addString, addChar, DFAMatcher.<ST>hasForwardMatchAfter(shift));
            if(p == null)
                break;

            DFAIndexedString<ST> matchingPrefix = (DFAIndexedString<ST>) p.first;
            rem = p.second;
            seen = seen.append(matchingPrefix);

            final ST stateAfterMatch = matchingPrefix.getForward().next(matchStartState.state);
            WrappedBitSet term = stateAfterMatch.getTerminatedPatterns();

            ST backwardInitial = bidfa.getBackward().getInitialState();

            ST nextMatchStart = stateAfterMatch;

            for(int bit = term.nextSetBit(0); bit >= 0; bit = term.nextSetBit(bit+1)) {
                final int bit2 = bit;

                Function2<ST, IndexedString, ST> addStringBack = new Function2<ST, IndexedString, ST>() {
                    public ST applyTo(ST st, IndexedString s) {
                        return ((DFAIndexedString<ST>) s).getBackward().next(st);
                    }
                };

                Function2<ST, Character, ST> addCharBack = new Function2<ST, Character, ST>() {
                    public ST applyTo(ST st, Character c) {
                        return bidfa.getBackward().transfer(c).next(st);
                    }
                };

                Predicate<ST> startsThisMatch = new Predicate<ST>() {
                    public boolean isTrueFor(ST state) {
                        WrappedBitSet tp = state.getTerminatedPatterns();
                        return tp!=null && tp.get(bit2);
                    }
                };

                int len = seen.splitAfterBackRise(
                        backwardInitial, addStringBack, addCharBack, startsThisMatch).second.length();
                int startPos = seen.length() - len;
                res.add(new Match(bit, startPos, len));

                nextMatchStart = bidfa.getForward().resetTerminatedPattern(nextMatchStart, bit);
            }

            matchStartState = new SP<ST>(nextMatchStart, matchingPrefix.length() + 1);
        }

        return res;
    }

    private static <ST extends State> Predicate<SP<ST>> hasForwardMatchAfter(final int pos) {
        return new Predicate<SP<ST>>() {
            public boolean isTrueFor(SP<ST> sp) {
                return !sp.state.getTerminatedPatterns().isEmpty() && sp.pos >= pos;
            }
        };
    }

    // State and position.
    private static class SP<ST extends State> {
        ST state;
        int pos;

        SP(ST state, int pos) {
            this.state = state;
            this.pos = pos;
        }
    }
}
TOP

Related Classes of org.jkff.ire.DFAMatcher$SP

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.