Abstract class for AST representing regular expressions. Concrete subclasses correspond to --- binary trees (context, alternation and concatenation) unary trees (closure, finite repetition and anchored patterns) leaf nodes (chars, char classes, literal strings and the eof marker)
예제 #1
0
 internal Binary( RegOp op, RegExTree l, RegExTree r ) : base( op ) { lKid = l; rKid = r; }
예제 #2
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");
                }
            }
예제 #3
0
 internal int maxRep;         // max repetitions for finiteRep.
 internal Unary( RegOp op, RegExTree l ) : base( op ) { kid = l; }
예제 #4
0
 internal abstract void Op( RegExTree tree );
예제 #5
0
 internal void ParseRE( AAST aast ) { regX = new AAST.ReParser( verb, vrbSpan, aast ).Parse(); }
예제 #6
0
        void Check( AAST aast, RegExTree tree ) {
            Binary bnryTree;
            Unary unryTree;

            if (tree == null) return;
            switch (tree.op) {
                case RegOp.charClass:
                case RegOp.primitive:
                case RegOp.litStr:
                case RegOp.eof:
                    break;
                case RegOp.context:
                case RegOp.concat:
                case RegOp.alt:
                    bnryTree = (Binary)tree;
                    Check( aast, bnryTree.lKid );
                    Check( aast, bnryTree.rKid );
                    if (tree.op == RegOp.context &&
                        bnryTree.lKid.contextLength() == 0 &&
                        bnryTree.rKid.contextLength() == 0) aast.hdlr.ListError( pSpan, 75 );
                    break;
                case RegOp.closure:
                case RegOp.finiteRep:
                    unryTree = (Unary)tree;
                    Check( aast, unryTree.kid );
                    break;
                case RegOp.leftAnchor:
                case RegOp.rightAnchor:
                    aast.hdlr.ListError( pSpan, 69 );
                    break;
            }
        }
예제 #7
0
        // internal void Dump() { Console.WriteLine(pattern); }

        internal void ParseRE( AAST aast ) {
            reAST = new AAST.ReParser( pattern, pSpan, aast ).Parse();
            SemanticCheck( aast );
        }