Beispiel #1
0
 /// <summary>
 /// Add a transition to the NState.
 /// Assert: if the symbol ordinals are packed
 /// the mapping has already been performed
 /// </summary>
 /// <param name="ord">The symbol index</param>
 /// <param name="nxt">The destination state</param>
 private void AddRawTransition(int ord, NState nxt)
 {
     if (GetNext(ord) == null)
         SetNext(ord, nxt);
     else        // state must have overlapping alternatives
     {
         NState temp = myNfaInst.MkState();
         this.AddEpsTrns(temp);
         temp.AddRawTransition(ord, nxt);
     }
 }
Beispiel #2
0
 internal void SetNext(int sym, NState dstState)
 {
     uint key = (this.serialNumber << 16) + (ushort)sym;
     myNfsa.next.Add(key, dstState);
 }
Beispiel #3
0
 /// <summary>
 /// Add a transition from "this" to "next"
 /// for every true bit in the BitArray cls
 /// </summary>
 /// <param name="cls">The transition bit array</param>
 /// <param name="nxt">The destination state</param>
 private void AddClsTrans(BitArray cls, NState nxt)
 {
     for (int i = 0; i < cls.Count; i++)
         if (cls[i]) AddRawTransition(i, nxt);
 }
Beispiel #4
0
 /// <summary>
 /// Add a transition from NState "this"
 /// to NState "nxt", for each character
 /// value in the leaf range list.
 /// If the characters are packed, transform 
 /// from character ordinal to equivalence class 
 /// ordinal.
 /// </summary>
 /// <param name="leaf">The regex leaf node</param>
 /// <param name="nxt">The destination state</param>
 public void AddClsTrans(Leaf leaf, NState nxt)
 {
     BitArray cls = new BitArray(myNfaInst.MaxSym);
     if (myNfaInst.Pack)
     {
         foreach (int ord in leaf.rangeLit.equivClasses)
             cls[ord] = true;
     }
     else
     {
         foreach (CharRange rng in leaf.rangeLit.list.Ranges)
             for (int i = rng.minChr; i <= rng.maxChr; i++)
                 cls[i] = true;
         if (leaf.rangeLit.list.IsInverted)
             cls = cls.Not();
     }
     AddClsTrans(cls, nxt);
 }
Beispiel #5
0
 /// <summary>
 /// Add an epsilon transition from "this" to "nxt"
 /// </summary>
 /// <param name="nxt">Destination state</param>
 public void AddEpsTrns(NState nxt)
 {
     int count = epsilons.Count;
     if (count < myNfaInst.MaxEps) epsilons.Length = myNfaInst.MaxEps;
     if (!epsilons[nxt.ord])
     {
         epsList.Add(nxt);
         epsilons[nxt.ord] = true;
     }
 }
Beispiel #6
0
 internal NState MkState()
 {
     NState s = new NState(this);
     s.ord = nStates.Count;
     if (s.ord >= maxE) maxE *= 2;
     nStates.Add(s);
     return s;
 }
Beispiel #7
0
 /// <summary>
 /// Add a transition from NState "this"
 /// to NState "nxt", for the character "chr".
 /// If the characters are packed, transform 
 /// from character ordinal to equivalence class 
 /// ordinal.
 /// </summary>
 /// <param name="chr">The character value</param>
 /// <param name="nxt">The destination state</param>
 public void AddChrTrns(int chr, NState nxt)
 {
     if (myNfaInst.Pack)
         chr = myNfaInst.parent.task.partition[chr];
     AddRawTransition(chr, nxt);
 }
Beispiel #8
0
            /// <summary>
            /// Create a transition path in the NFSA from the given 
            /// start state to the given end state, corresponding to the
            /// RegEx tree value.  The method may (almost always does)
            /// create new NFSA states and recurses to make paths for
            /// the subtrees of the given tree.
            /// </summary>
            /// <param name="tree">The tree to encode</param>
            /// <param name="start">The start state for the pattern</param>
            /// <param name="end">The end state for the pattern</param>
            internal void MakePath(RegExTree tree, NState startState, NState endState)
            {
                NState tmp1 = null;
                NState tmp2 = null;
                int rLen, lLen;

                switch (tree.op)
                {
                    case RegOp.eof:
                        break;
                    // Binary nodes ===================================
                    case RegOp.context:
                    case RegOp.concat:
                    case RegOp.alt:
                        // Binary nodes ===================================
                        Binary binNode = tree as Binary;
                        switch (tree.op)
                        {
                            case RegOp.context:
                                rLen = binNode.rKid.contextLength();
                                lLen = binNode.lKid.contextLength();
                                if (rLen <= 0 && lLen <= 0)
                                    throw new StringInterpretException("variable right context '/' not implemented");
                                else
                                {
                                    endState.rhCntx = rLen;
                                    endState.lhCntx = lLen;
                                    tmp1 = MkState();
                                    MakePath(binNode.lKid, startState, tmp1);
                                    MakePath(binNode.rKid, tmp1, endState);
                                }
                                break;
                            case RegOp.concat:
                                tmp1 = MkState();
                                MakePath(binNode.lKid, startState, tmp1);
                                MakePath(binNode.rKid, tmp1, endState);
                                break;
                            case RegOp.alt:
                                tmp1 = MkState();
                                MakePath(binNode.lKid, startState, tmp1);
                                tmp1.AddEpsTrns(endState);
                                tmp1 = MkState();
                                MakePath(binNode.rKid, startState, tmp1);
                                tmp1.AddEpsTrns(endState);
                                break;
                        }
                        break;
                    // Unary nodes ===================================
                    case RegOp.closure:
                    case RegOp.finiteRep:
                        // Unary nodes ===================================
                        Unary unaryNode = tree as Unary;
                        switch (tree.op)
                        {
                            case RegOp.closure:
                                tmp2 = MkState();
                                if (unaryNode.minRep == 0)
                                {
                                    tmp1 = MkState();
                                    startState.AddEpsTrns(tmp1);
                                }
                                else
                                {
                                    NState dummy = startState;
                                    for (int i = 0; i < unaryNode.minRep; i++)
                                    {
                                        tmp1 = MkState();
                                        MakePath(unaryNode.kid, dummy, tmp1);
                                        dummy = tmp1;
                                    }
                                }
                                MakePath(unaryNode.kid, tmp1, tmp2);
                                tmp2.AddEpsTrns(tmp1);
                                tmp1.AddEpsTrns(endState);
                                break;
                            case RegOp.finiteRep:
                                {
                                    NState dummy = tmp1 = startState;
                                    for (int i = 0; i < unaryNode.minRep; i++)
                                    {
                                        tmp1 = MkState();
                                        MakePath(unaryNode.kid, dummy, tmp1);
                                        dummy = tmp1;
                                    }
                                    tmp1.AddEpsTrns(endState);
                                    for (int i = unaryNode.minRep; i < unaryNode.maxRep; i++)
                                    {
                                        tmp1 = MkState();
                                        MakePath(unaryNode.kid, dummy, tmp1);
                                        dummy = tmp1;
                                        dummy.AddEpsTrns(endState);
                                    }
                                }
                                break;
                        }
                        break;
                    // Leaf nodes ===================================
                    case RegOp.litStr:
                    case RegOp.primitive:
                    case RegOp.charClass:
                        // Leaf nodes ===================================
                        Leaf leafNode = tree as Leaf;
                        switch (tree.op)
                        {
                            case RegOp.litStr:
                                {
                                    // Make a linear sequence of states with successive
                                    // transitions on successive string characters.
                                    //
                                    string text = leafNode.str;
                                    NState dummy = startState;
                                    // Need to deal with special case of empty string
                                    if (text.Length == 0)
                                        dummy.AddEpsTrns(endState);
                                    else
                                    {
                                        //  This code is complicated by the fact that unicode
                                        //  escape substitution may have inserted surrogate
                                        //  pairs of characters in the string.  We need
                                        //  one transition for every unicode character,
                                        //  not one for every char value in this string.
                                        //
                                        int index = 0;
                                        int code = CharacterUtilities.CodePoint(text, ref index); // First character
                                        int next = CharacterUtilities.CodePoint(text, ref index); // Next, possibly -1
                                        while (next >= 0)
                                        {
                                            tmp1 = MkState();
                                            dummy.AddChrTrns(code, tmp1);
                                            dummy = tmp1;
                                            code = next;
                                            next = CharacterUtilities.CodePoint(text, ref index);
                                        }
                                        // Postcondition ==> "code" is the last char.
                                        dummy.AddChrTrns(code, endState);
                                    }
                                }
                                break;
                            case RegOp.primitive:
                                startState.AddChrTrns(leafNode.chVal, endState);
                                break;

                            case RegOp.charClass:
                                startState.AddClsTrans(leafNode, endState);
                                break;
                        }
                        break;
                    default: throw new GplexInternalException("unknown tree op");
                }
            }
Beispiel #9
0
 internal void MarkAccept(NState acpt, RuleDesc rule)
 {
     acpt.accept = rule;
     acceptStates.Add(acpt.ord);
 }
Beispiel #10
0
 public NfsaInstance(StartState ss, NFSA parent)
 {
     myStartCondition = ss;
     this.parent = parent;
     this.pack = parent.task.ChrClasses;
     if (pack)
         maxS = parent.task.partition.Length;          // Number of equivalence classes
     else
         maxS = parent.task.TargetSymCardinality;      // Size of alphabet
     entryState = MkState();
 }
Beispiel #11
0
 //
 // For version 1.0.1 recognize any line-end character if /unicode
 //
 static void AddAnchorContext(NfsaInstance nInst, NState endS, RuleDesc rule)
 {
     NState nEnd = nInst.MkState();
     Leaf temp = new Leaf(RegOp.charClass);
     temp.rangeLit = RangeLiteral.RightAnchors;
     nInst.MakePath(temp, endS, nEnd);
     nInst.MarkAccept(nEnd, rule);
     nEnd.rhCntx = 1;
 }
Beispiel #12
0
 internal void SetNext(int sym, NState dstState)
 {
     ulong key = checked(((ulong)this.serialNumber << 32) + (ulong)sym);
     myNfsa.next.Add(key, dstState);
 }
Beispiel #13
0
            /// <summary>
            /// Add a transition from NState "this"
            /// to NState "nxt", for each character
            /// value in the leaf range list.
            /// If the characters are packed, transform 
            /// from character ordinal to equivalence class 
            /// ordinal.
            /// </summary>
            /// <param name="leaf">The regex leaf node</param>
            /// <param name="nxt">The destination state</param>
            public void AddClsTrans(Leaf leaf, NState nxt)
            {
                if (myNfaInst.parent.task.CaseAgnostic) {
                    leaf.rangeLit.list = leaf.rangeLit.list.MakeCaseAgnosticList();
                    leaf.rangeLit.list.Canonicalize();
                }

                BitArray cls = new BitArray(myNfaInst.MaxSym);
                if (myNfaInst.Pack)
                {
                    foreach (int ord in leaf.rangeLit.equivClasses)
                        cls[ord] = true;
                }
                else
                {
                    foreach (CharRange rng in leaf.rangeLit.list.Ranges)
                        for (int i = rng.minChr; i <= rng.maxChr; i++)
                            cls[i] = true;
                    if (leaf.rangeLit.list.IsInverted)
                        cls = cls.Not();
                }
                AddClsTrans(cls, nxt);
            }
Beispiel #14
0
 /// <summary>
 /// Add a transition from NState "this"
 /// to NState "nxt", for the character "chr".
 /// If the characters are packed, transform 
 /// from character ordinal to equivalence class 
 /// ordinal.
 /// </summary>
 /// <param name="chr">The character value</param>
 /// <param name="nxt">The destination state</param>
 public void AddChrTrns(int chr, NState nxt)
 {
     if (myNfaInst.parent.task.CaseAgnostic  && chr < Char.MaxValue) {
         char c = (char)chr;
         char lo = Char.ToLower(c);
         char hi = Char.ToUpper(c);
         if (lo != hi) {
             AddTrns(lo, nxt);
             AddTrns(hi, nxt);
             return;
         }
     }
     AddTrns(chr, nxt);
 }