jaxp/src/com/sun/org/apache/regexp/internal/REDebugCompiler.java
author ehelin
Mon, 31 Mar 2014 14:02:40 +0200
changeset 23544 e6362a5ba011
parent 12457 c348e06f0e82
permissions -rw-r--r--
8033251: Use DWARF debug symbols for Linux 32-bit as default Reviewed-by: dcubed, dholmes, coleenp
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6
7f561c08de6b Initial load
duke
parents:
diff changeset
     1
/*
7f561c08de6b Initial load
duke
parents:
diff changeset
     2
 * reserved comment block
7f561c08de6b Initial load
duke
parents:
diff changeset
     3
 * DO NOT REMOVE OR ALTER!
7f561c08de6b Initial load
duke
parents:
diff changeset
     4
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
     5
/*
7f561c08de6b Initial load
duke
parents:
diff changeset
     6
 * Copyright 1999-2004 The Apache Software Foundation.
7f561c08de6b Initial load
duke
parents:
diff changeset
     7
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
     8
 * Licensed under the Apache License, Version 2.0 (the "License");
7f561c08de6b Initial load
duke
parents:
diff changeset
     9
 * you may not use this file except in compliance with the License.
7f561c08de6b Initial load
duke
parents:
diff changeset
    10
 * You may obtain a copy of the License at
7f561c08de6b Initial load
duke
parents:
diff changeset
    11
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    12
 *     http://www.apache.org/licenses/LICENSE-2.0
7f561c08de6b Initial load
duke
parents:
diff changeset
    13
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    14
 * Unless required by applicable law or agreed to in writing, software
7f561c08de6b Initial load
duke
parents:
diff changeset
    15
 * distributed under the License is distributed on an "AS IS" BASIS,
7f561c08de6b Initial load
duke
parents:
diff changeset
    16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7f561c08de6b Initial load
duke
parents:
diff changeset
    17
 * See the License for the specific language governing permissions and
7f561c08de6b Initial load
duke
parents:
diff changeset
    18
 * limitations under the License.
7f561c08de6b Initial load
duke
parents:
diff changeset
    19
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    20
7f561c08de6b Initial load
duke
parents:
diff changeset
    21
package com.sun.org.apache.regexp.internal;
7f561c08de6b Initial load
duke
parents:
diff changeset
    22
7f561c08de6b Initial load
duke
parents:
diff changeset
    23
import java.io.PrintWriter;
7f561c08de6b Initial load
duke
parents:
diff changeset
    24
import java.util.Hashtable;
7f561c08de6b Initial load
duke
parents:
diff changeset
    25
7f561c08de6b Initial load
duke
parents:
diff changeset
    26
/**
7f561c08de6b Initial load
duke
parents:
diff changeset
    27
 * A subclass of RECompiler which can dump a regular expression program
7f561c08de6b Initial load
duke
parents:
diff changeset
    28
 * for debugging purposes.
7f561c08de6b Initial load
duke
parents:
diff changeset
    29
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    30
 * @author <a href="mailto:jonl@muppetlabs.com">Jonathan Locke</a>
7f561c08de6b Initial load
duke
parents:
diff changeset
    31
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    32
public class REDebugCompiler extends RECompiler
7f561c08de6b Initial load
duke
parents:
diff changeset
    33
{
7f561c08de6b Initial load
duke
parents:
diff changeset
    34
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    35
     * Mapping from opcodes to descriptive strings
7f561c08de6b Initial load
duke
parents:
diff changeset
    36
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    37
    static Hashtable hashOpcode = new Hashtable();
7f561c08de6b Initial load
duke
parents:
diff changeset
    38
    static
7f561c08de6b Initial load
duke
parents:
diff changeset
    39
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
    40
        hashOpcode.put(new Integer(RE.OP_RELUCTANTSTAR),    "OP_RELUCTANTSTAR");
7f561c08de6b Initial load
duke
parents:
diff changeset
    41
        hashOpcode.put(new Integer(RE.OP_RELUCTANTPLUS),    "OP_RELUCTANTPLUS");
7f561c08de6b Initial load
duke
parents:
diff changeset
    42
        hashOpcode.put(new Integer(RE.OP_RELUCTANTMAYBE),   "OP_RELUCTANTMAYBE");
7f561c08de6b Initial load
duke
parents:
diff changeset
    43
        hashOpcode.put(new Integer(RE.OP_END),              "OP_END");
7f561c08de6b Initial load
duke
parents:
diff changeset
    44
        hashOpcode.put(new Integer(RE.OP_BOL),              "OP_BOL");
7f561c08de6b Initial load
duke
parents:
diff changeset
    45
        hashOpcode.put(new Integer(RE.OP_EOL),              "OP_EOL");
7f561c08de6b Initial load
duke
parents:
diff changeset
    46
        hashOpcode.put(new Integer(RE.OP_ANY),              "OP_ANY");
7f561c08de6b Initial load
duke
parents:
diff changeset
    47
        hashOpcode.put(new Integer(RE.OP_ANYOF),            "OP_ANYOF");
7f561c08de6b Initial load
duke
parents:
diff changeset
    48
        hashOpcode.put(new Integer(RE.OP_BRANCH),           "OP_BRANCH");
7f561c08de6b Initial load
duke
parents:
diff changeset
    49
        hashOpcode.put(new Integer(RE.OP_ATOM),             "OP_ATOM");
7f561c08de6b Initial load
duke
parents:
diff changeset
    50
        hashOpcode.put(new Integer(RE.OP_STAR),             "OP_STAR");
7f561c08de6b Initial load
duke
parents:
diff changeset
    51
        hashOpcode.put(new Integer(RE.OP_PLUS),             "OP_PLUS");
7f561c08de6b Initial load
duke
parents:
diff changeset
    52
        hashOpcode.put(new Integer(RE.OP_MAYBE),            "OP_MAYBE");
7f561c08de6b Initial load
duke
parents:
diff changeset
    53
        hashOpcode.put(new Integer(RE.OP_NOTHING),          "OP_NOTHING");
7f561c08de6b Initial load
duke
parents:
diff changeset
    54
        hashOpcode.put(new Integer(RE.OP_GOTO),             "OP_GOTO");
7f561c08de6b Initial load
duke
parents:
diff changeset
    55
        hashOpcode.put(new Integer(RE.OP_ESCAPE),           "OP_ESCAPE");
7f561c08de6b Initial load
duke
parents:
diff changeset
    56
        hashOpcode.put(new Integer(RE.OP_OPEN),             "OP_OPEN");
7f561c08de6b Initial load
duke
parents:
diff changeset
    57
        hashOpcode.put(new Integer(RE.OP_CLOSE),            "OP_CLOSE");
7f561c08de6b Initial load
duke
parents:
diff changeset
    58
        hashOpcode.put(new Integer(RE.OP_BACKREF),          "OP_BACKREF");
7f561c08de6b Initial load
duke
parents:
diff changeset
    59
        hashOpcode.put(new Integer(RE.OP_POSIXCLASS),       "OP_POSIXCLASS");
7f561c08de6b Initial load
duke
parents:
diff changeset
    60
        hashOpcode.put(new Integer(RE.OP_OPEN_CLUSTER),      "OP_OPEN_CLUSTER");
7f561c08de6b Initial load
duke
parents:
diff changeset
    61
        hashOpcode.put(new Integer(RE.OP_CLOSE_CLUSTER),      "OP_CLOSE_CLUSTER");
7f561c08de6b Initial load
duke
parents:
diff changeset
    62
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
    63
7f561c08de6b Initial load
duke
parents:
diff changeset
    64
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    65
     * Returns a descriptive string for an opcode.
7f561c08de6b Initial load
duke
parents:
diff changeset
    66
     * @param opcode Opcode to convert to a string
7f561c08de6b Initial load
duke
parents:
diff changeset
    67
     * @return Description of opcode
7f561c08de6b Initial load
duke
parents:
diff changeset
    68
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    69
    String opcodeToString(char opcode)
7f561c08de6b Initial load
duke
parents:
diff changeset
    70
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
    71
        // Get string for opcode
7f561c08de6b Initial load
duke
parents:
diff changeset
    72
        String ret =(String)hashOpcode.get(new Integer(opcode));
7f561c08de6b Initial load
duke
parents:
diff changeset
    73
7f561c08de6b Initial load
duke
parents:
diff changeset
    74
        // Just in case we have a corrupt program
7f561c08de6b Initial load
duke
parents:
diff changeset
    75
        if (ret == null)
7f561c08de6b Initial load
duke
parents:
diff changeset
    76
        {
7f561c08de6b Initial load
duke
parents:
diff changeset
    77
            ret = "OP_????";
7f561c08de6b Initial load
duke
parents:
diff changeset
    78
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
    79
        return ret;
7f561c08de6b Initial load
duke
parents:
diff changeset
    80
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
    81
7f561c08de6b Initial load
duke
parents:
diff changeset
    82
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    83
     * Return a string describing a (possibly unprintable) character.
7f561c08de6b Initial load
duke
parents:
diff changeset
    84
     * @param c Character to convert to a printable representation
7f561c08de6b Initial load
duke
parents:
diff changeset
    85
     * @return String representation of character
7f561c08de6b Initial load
duke
parents:
diff changeset
    86
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    87
    String charToString(char c)
7f561c08de6b Initial load
duke
parents:
diff changeset
    88
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
    89
        // If it's unprintable, convert to '\###'
7f561c08de6b Initial load
duke
parents:
diff changeset
    90
        if (c < ' ' || c > 127)
7f561c08de6b Initial load
duke
parents:
diff changeset
    91
        {
7f561c08de6b Initial load
duke
parents:
diff changeset
    92
            return "\\" + (int)c;
7f561c08de6b Initial load
duke
parents:
diff changeset
    93
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
    94
7f561c08de6b Initial load
duke
parents:
diff changeset
    95
        // Return the character as a string
7f561c08de6b Initial load
duke
parents:
diff changeset
    96
        return String.valueOf(c);
7f561c08de6b Initial load
duke
parents:
diff changeset
    97
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
    98
7f561c08de6b Initial load
duke
parents:
diff changeset
    99
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   100
     * Returns a descriptive string for a node in a regular expression program.
7f561c08de6b Initial load
duke
parents:
diff changeset
   101
     * @param node Node to describe
7f561c08de6b Initial load
duke
parents:
diff changeset
   102
     * @return Description of node
7f561c08de6b Initial load
duke
parents:
diff changeset
   103
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   104
    String nodeToString(int node)
7f561c08de6b Initial load
duke
parents:
diff changeset
   105
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
   106
        // Get opcode and opdata for node
7f561c08de6b Initial load
duke
parents:
diff changeset
   107
        char opcode =      instruction[node + RE.offsetOpcode];
7f561c08de6b Initial load
duke
parents:
diff changeset
   108
        int opdata  = (int)instruction[node + RE.offsetOpdata];
7f561c08de6b Initial load
duke
parents:
diff changeset
   109
7f561c08de6b Initial load
duke
parents:
diff changeset
   110
        // Return opcode as a string and opdata value
7f561c08de6b Initial load
duke
parents:
diff changeset
   111
        return opcodeToString(opcode) + ", opdata = " + opdata;
7f561c08de6b Initial load
duke
parents:
diff changeset
   112
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   113
7f561c08de6b Initial load
duke
parents:
diff changeset
   114
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   115
     * Inserts a node with a given opcode and opdata at insertAt.  The node relative next
7f561c08de6b Initial load
duke
parents:
diff changeset
   116
     * pointer is initialized to 0.
7f561c08de6b Initial load
duke
parents:
diff changeset
   117
     * @param opcode Opcode for new node
7f561c08de6b Initial load
duke
parents:
diff changeset
   118
     * @param opdata Opdata for new node (only the low 16 bits are currently used)
7f561c08de6b Initial load
duke
parents:
diff changeset
   119
     * @param insertAt Index at which to insert the new node in the program * /
7f561c08de6b Initial load
duke
parents:
diff changeset
   120
    void nodeInsert(char opcode, int opdata, int insertAt) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   121
        System.out.println( "====> " + opcode + " " + opdata + " " + insertAt );
7f561c08de6b Initial load
duke
parents:
diff changeset
   122
        PrintWriter writer = new PrintWriter( System.out );
7f561c08de6b Initial load
duke
parents:
diff changeset
   123
        dumpProgram( writer );
7f561c08de6b Initial load
duke
parents:
diff changeset
   124
        super.nodeInsert( opcode, opdata, insertAt );
7f561c08de6b Initial load
duke
parents:
diff changeset
   125
        System.out.println( "====< " );
7f561c08de6b Initial load
duke
parents:
diff changeset
   126
        dumpProgram( writer );
7f561c08de6b Initial load
duke
parents:
diff changeset
   127
        writer.flush();
7f561c08de6b Initial load
duke
parents:
diff changeset
   128
    }/**/
7f561c08de6b Initial load
duke
parents:
diff changeset
   129
7f561c08de6b Initial load
duke
parents:
diff changeset
   130
7f561c08de6b Initial load
duke
parents:
diff changeset
   131
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   132
    * Appends a node to the end of a node chain
7f561c08de6b Initial load
duke
parents:
diff changeset
   133
    * @param node Start of node chain to traverse
7f561c08de6b Initial load
duke
parents:
diff changeset
   134
    * @param pointTo Node to have the tail of the chain point to * /
7f561c08de6b Initial load
duke
parents:
diff changeset
   135
    void setNextOfEnd(int node, int pointTo) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   136
        System.out.println( "====> " + node + " " + pointTo );
7f561c08de6b Initial load
duke
parents:
diff changeset
   137
        PrintWriter writer = new PrintWriter( System.out );
7f561c08de6b Initial load
duke
parents:
diff changeset
   138
        dumpProgram( writer );
7f561c08de6b Initial load
duke
parents:
diff changeset
   139
        super.setNextOfEnd( node, pointTo );
7f561c08de6b Initial load
duke
parents:
diff changeset
   140
        System.out.println( "====< " );
7f561c08de6b Initial load
duke
parents:
diff changeset
   141
        dumpProgram( writer );
7f561c08de6b Initial load
duke
parents:
diff changeset
   142
        writer.flush();
7f561c08de6b Initial load
duke
parents:
diff changeset
   143
    }/**/
7f561c08de6b Initial load
duke
parents:
diff changeset
   144
7f561c08de6b Initial load
duke
parents:
diff changeset
   145
7f561c08de6b Initial load
duke
parents:
diff changeset
   146
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   147
     * Dumps the current program to a PrintWriter
7f561c08de6b Initial load
duke
parents:
diff changeset
   148
     * @param p PrintWriter for program dump output
7f561c08de6b Initial load
duke
parents:
diff changeset
   149
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   150
    public void dumpProgram(PrintWriter p)
7f561c08de6b Initial load
duke
parents:
diff changeset
   151
    {
7f561c08de6b Initial load
duke
parents:
diff changeset
   152
        // Loop through the whole program
7f561c08de6b Initial load
duke
parents:
diff changeset
   153
        for (int i = 0; i < lenInstruction; )
7f561c08de6b Initial load
duke
parents:
diff changeset
   154
        {
7f561c08de6b Initial load
duke
parents:
diff changeset
   155
            // Get opcode, opdata and next fields of current program node
7f561c08de6b Initial load
duke
parents:
diff changeset
   156
            char opcode =        instruction[i + RE.offsetOpcode];
7f561c08de6b Initial load
duke
parents:
diff changeset
   157
            char opdata =        instruction[i + RE.offsetOpdata];
7f561c08de6b Initial load
duke
parents:
diff changeset
   158
            short next  = (short)instruction[i + RE.offsetNext];
7f561c08de6b Initial load
duke
parents:
diff changeset
   159
7f561c08de6b Initial load
duke
parents:
diff changeset
   160
            // Display the current program node
7f561c08de6b Initial load
duke
parents:
diff changeset
   161
            p.print(i + ". " + nodeToString(i) + ", next = ");
7f561c08de6b Initial load
duke
parents:
diff changeset
   162
7f561c08de6b Initial load
duke
parents:
diff changeset
   163
            // If there's no next, say 'none', otherwise give absolute index of next node
7f561c08de6b Initial load
duke
parents:
diff changeset
   164
            if (next == 0)
7f561c08de6b Initial load
duke
parents:
diff changeset
   165
            {
7f561c08de6b Initial load
duke
parents:
diff changeset
   166
                p.print("none");
7f561c08de6b Initial load
duke
parents:
diff changeset
   167
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   168
            else
7f561c08de6b Initial load
duke
parents:
diff changeset
   169
            {
7f561c08de6b Initial load
duke
parents:
diff changeset
   170
                p.print(i + next);
7f561c08de6b Initial load
duke
parents:
diff changeset
   171
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   172
7f561c08de6b Initial load
duke
parents:
diff changeset
   173
            // Move past node
7f561c08de6b Initial load
duke
parents:
diff changeset
   174
            i += RE.nodeSize;
7f561c08de6b Initial load
duke
parents:
diff changeset
   175
7f561c08de6b Initial load
duke
parents:
diff changeset
   176
            // If character class
7f561c08de6b Initial load
duke
parents:
diff changeset
   177
            if (opcode == RE.OP_ANYOF)
7f561c08de6b Initial load
duke
parents:
diff changeset
   178
            {
7f561c08de6b Initial load
duke
parents:
diff changeset
   179
                // Opening bracket for start of char class
7f561c08de6b Initial load
duke
parents:
diff changeset
   180
                p.print(", [");
7f561c08de6b Initial load
duke
parents:
diff changeset
   181
7f561c08de6b Initial load
duke
parents:
diff changeset
   182
                // Show each range in the char class
7f561c08de6b Initial load
duke
parents:
diff changeset
   183
                int rangeCount = opdata;
7f561c08de6b Initial load
duke
parents:
diff changeset
   184
                for (int r = 0; r < rangeCount; r++)
7f561c08de6b Initial load
duke
parents:
diff changeset
   185
                {
7f561c08de6b Initial load
duke
parents:
diff changeset
   186
                    // Get first and last chars in range
7f561c08de6b Initial load
duke
parents:
diff changeset
   187
                    char charFirst = instruction[i++];
7f561c08de6b Initial load
duke
parents:
diff changeset
   188
                    char charLast  = instruction[i++];
7f561c08de6b Initial load
duke
parents:
diff changeset
   189
7f561c08de6b Initial load
duke
parents:
diff changeset
   190
                    // Print range as X-Y, unless range encompasses only one char
7f561c08de6b Initial load
duke
parents:
diff changeset
   191
                    if (charFirst == charLast)
7f561c08de6b Initial load
duke
parents:
diff changeset
   192
                    {
7f561c08de6b Initial load
duke
parents:
diff changeset
   193
                        p.print(charToString(charFirst));
7f561c08de6b Initial load
duke
parents:
diff changeset
   194
                    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   195
                    else
7f561c08de6b Initial load
duke
parents:
diff changeset
   196
                    {
7f561c08de6b Initial load
duke
parents:
diff changeset
   197
                        p.print(charToString(charFirst) + "-" + charToString(charLast));
7f561c08de6b Initial load
duke
parents:
diff changeset
   198
                    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   199
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   200
7f561c08de6b Initial load
duke
parents:
diff changeset
   201
                // Annotate the end of the char class
7f561c08de6b Initial load
duke
parents:
diff changeset
   202
                p.print("]");
7f561c08de6b Initial load
duke
parents:
diff changeset
   203
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   204
7f561c08de6b Initial load
duke
parents:
diff changeset
   205
            // If atom
7f561c08de6b Initial load
duke
parents:
diff changeset
   206
            if (opcode == RE.OP_ATOM)
7f561c08de6b Initial load
duke
parents:
diff changeset
   207
            {
7f561c08de6b Initial load
duke
parents:
diff changeset
   208
                // Open quote
7f561c08de6b Initial load
duke
parents:
diff changeset
   209
                p.print(", \"");
7f561c08de6b Initial load
duke
parents:
diff changeset
   210
7f561c08de6b Initial load
duke
parents:
diff changeset
   211
                // Print each character in the atom
7f561c08de6b Initial load
duke
parents:
diff changeset
   212
                for (int len = opdata; len-- != 0; )
7f561c08de6b Initial load
duke
parents:
diff changeset
   213
                {
7f561c08de6b Initial load
duke
parents:
diff changeset
   214
                    p.print(charToString(instruction[i++]));
7f561c08de6b Initial load
duke
parents:
diff changeset
   215
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   216
7f561c08de6b Initial load
duke
parents:
diff changeset
   217
                // Close quote
7f561c08de6b Initial load
duke
parents:
diff changeset
   218
                p.print("\"");
7f561c08de6b Initial load
duke
parents:
diff changeset
   219
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   220
7f561c08de6b Initial load
duke
parents:
diff changeset
   221
            // Print a newline
7f561c08de6b Initial load
duke
parents:
diff changeset
   222
            p.println("");
7f561c08de6b Initial load
duke
parents:
diff changeset
   223
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   224
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   225
}