KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > regexp > internal > REDebugCompiler


1 package com.sun.org.apache.regexp.internal;
2
3 /*
4  * ====================================================================
5  *
6  * The Apache Software License, Version 1.1
7  *
8  * Copyright (c) 1999 The Apache Software Foundation. All rights
9  * reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in
20  * the documentation and/or other materials provided with the
21  * distribution.
22  *
23  * 3. The end-user documentation included with the redistribution, if
24  * any, must include the following acknowlegement:
25  * "This product includes software developed by the
26  * Apache Software Foundation (http://www.apache.org/)."
27  * Alternately, this acknowlegement may appear in the software itself,
28  * if and wherever such third-party acknowlegements normally appear.
29  *
30  * 4. The names "The Jakarta Project", "Jakarta-Regexp", and "Apache Software
31  * Foundation" must not be used to endorse or promote products derived
32  * from this software without prior written permission. For written
33  * permission, please contact apache@apache.org.
34  *
35  * 5. Products derived from this software may not be called "Apache"
36  * nor may "Apache" appear in their names without prior written
37  * permission of the Apache Group.
38  *
39  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
40  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
41  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
45  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
46  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
48  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
49  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This software consists of voluntary contributions made by many
54  * individuals on behalf of the Apache Software Foundation. For more
55  * information on the Apache Software Foundation, please see
56  * <http://www.apache.org/>.
57  *
58  */

59
60 import java.util.*;
61 import java.io.*;
62
63 /**
64  * A subclass of RECompiler which can dump a regular expression program
65  * for debugging purposes.
66  *
67  * @author <a HREF="mailto:jonl@muppetlabs.com">Jonathan Locke</a>
68  * @version $Id: REDebugCompiler.java,v 1.1 2000/04/27 01:22:33 jon Exp $
69  */

70 public class REDebugCompiler extends RECompiler
71 {
72     /**
73      * Mapping from opcodes to descriptive strings
74      */

75     static Hashtable hashOpcode = new Hashtable();
76     static
77     {
78         hashOpcode.put(new Integer JavaDoc(RE.OP_RELUCTANTSTAR), "OP_RELUCTANTSTAR");
79         hashOpcode.put(new Integer JavaDoc(RE.OP_RELUCTANTPLUS), "OP_RELUCTANTPLUS");
80         hashOpcode.put(new Integer JavaDoc(RE.OP_RELUCTANTMAYBE), "OP_RELUCTANTMAYBE");
81         hashOpcode.put(new Integer JavaDoc(RE.OP_END), "OP_END");
82         hashOpcode.put(new Integer JavaDoc(RE.OP_BOL), "OP_BOL");
83         hashOpcode.put(new Integer JavaDoc(RE.OP_EOL), "OP_EOL");
84         hashOpcode.put(new Integer JavaDoc(RE.OP_ANY), "OP_ANY");
85         hashOpcode.put(new Integer JavaDoc(RE.OP_ANYOF), "OP_ANYOF");
86         hashOpcode.put(new Integer JavaDoc(RE.OP_BRANCH), "OP_BRANCH");
87         hashOpcode.put(new Integer JavaDoc(RE.OP_ATOM), "OP_ATOM");
88         hashOpcode.put(new Integer JavaDoc(RE.OP_STAR), "OP_STAR");
89         hashOpcode.put(new Integer JavaDoc(RE.OP_PLUS), "OP_PLUS");
90         hashOpcode.put(new Integer JavaDoc(RE.OP_MAYBE), "OP_MAYBE");
91         hashOpcode.put(new Integer JavaDoc(RE.OP_NOTHING), "OP_NOTHING");
92         hashOpcode.put(new Integer JavaDoc(RE.OP_GOTO), "OP_GOTO");
93         hashOpcode.put(new Integer JavaDoc(RE.OP_ESCAPE), "OP_ESCAPE");
94         hashOpcode.put(new Integer JavaDoc(RE.OP_OPEN), "OP_OPEN");
95         hashOpcode.put(new Integer JavaDoc(RE.OP_CLOSE), "OP_CLOSE");
96         hashOpcode.put(new Integer JavaDoc(RE.OP_BACKREF), "OP_BACKREF");
97         hashOpcode.put(new Integer JavaDoc(RE.OP_POSIXCLASS), "OP_POSIXCLASS");
98     }
99
100     /**
101      * Returns a descriptive string for an opcode.
102      * @param opcode Opcode to convert to a string
103      * @return Description of opcode
104      */

105     String JavaDoc opcodeToString(char opcode)
106     {
107         // Get string for opcode
108
String JavaDoc ret =(String JavaDoc)hashOpcode.get(new Integer JavaDoc(opcode));
109
110         // Just in case we have a corrupt program
111
if (ret == null)
112         {
113             ret = "OP_????";
114         }
115         return ret;
116     }
117
118     /**
119      * Return a string describing a (possibly unprintable) character.
120      * @param c Character to convert to a printable representation
121      * @return String representation of character
122      */

123     String JavaDoc charToString(char c)
124     {
125         // If it's unprintable, convert to '\###'
126
if (c < ' ' || c > 127)
127         {
128             return "\\" + (int)c;
129         }
130
131         // Return the character as a string
132
return String.valueOf(c);
133     }
134
135     /**
136      * Returns a descriptive string for a node in a regular expression program.
137      * @param node Node to describe
138      * @return Description of node
139      */

140     String JavaDoc nodeToString(int node)
141     {
142         // Get opcode and opdata for node
143
char opcode = instruction[node + RE.offsetOpcode];
144         int opdata = (int)instruction[node + RE.offsetOpdata];
145
146         // Return opcode as a string and opdata value
147
return opcodeToString(opcode) + ", opdata = " + opdata;
148     }
149
150     /**
151      * Dumps the current program to a PrintWriter
152      * @param p PrintWriter for program dump output
153      */

154     public void dumpProgram(PrintWriter p)
155     {
156         // Loop through the whole program
157
for (int i = 0; i < lenInstruction; )
158         {
159             // Get opcode, opdata and next fields of current program node
160
char opcode = instruction[i + RE.offsetOpcode];
161             char opdata = instruction[i + RE.offsetOpdata];
162             short next = (short)instruction[i + RE.offsetNext];
163
164             // Display the current program node
165
p.print(i + ". " + nodeToString(i) + ", next = ");
166
167             // If there's no next, say 'none', otherwise give absolute index of next node
168
if (next == 0)
169             {
170                 p.print("none");
171             }
172             else
173             {
174                 p.print(i + next);
175             }
176
177             // Move past node
178
i += RE.nodeSize;
179
180             // If character class
181
if (opcode == RE.OP_ANYOF)
182             {
183                 // Opening bracket for start of char class
184
p.print(", [");
185
186                 // Show each range in the char class
187
int rangeCount = opdata;
188                 for (int r = 0; r < rangeCount; r++)
189                 {
190                     // Get first and last chars in range
191
char charFirst = instruction[i++];
192                     char charLast = instruction[i++];
193
194                     // Print range as X-Y, unless range encompasses only one char
195
if (charFirst == charLast)
196                     {
197                         p.print(charToString(charFirst));
198                     }
199                     else
200                     {
201                         p.print(charToString(charFirst) + "-" + charToString(charLast));
202                     }
203                 }
204
205                 // Annotate the end of the char class
206
p.print("]");
207             }
208
209             // If atom
210
if (opcode == RE.OP_ATOM)
211             {
212                 // Open quote
213
p.print(", \"");
214
215                 // Print each character in the atom
216
for (int len = opdata; len-- != 0; )
217                 {
218                     p.print(charToString(instruction[i++]));
219                 }
220
221                 // Close quote
222
p.print("\"");
223             }
224
225             // Print a newline
226
p.println("");
227         }
228     }
229 }
230
Popular Tags