KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > oro > text > regex > Perl5Debug


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

59
60 /**
61  * The Perl5Debug class is not intended for general use and should not
62  * be instantiated, but is provided because some users may find the output
63  * of its single method to be useful.
64  * The Perl5Compiler class generates a representation of a
65  * regular expression identical to that of Perl5 in the abstract, but
66  * not in terms of actual data structures. The Perl5Debug class allows
67  * the bytecode program contained by a Perl5Pattern to be printed out for
68  * comparison with the program generated by Perl5 with the -r option.
69
70  @author <a HREF="dfs@savarese.org">Daniel F. Savarese</a>
71  @version $Id: Perl5Debug.java,v 1.1.1.1 2000/07/23 23:08:52 jon Exp $
72
73  * @see Perl5Pattern
74  */

75 public final class Perl5Debug {
76
77   /**
78    * A dummy constructor to prevent instantiation of Perl5Debug.
79    */

80   private Perl5Debug() { }
81
82
83   /**
84    * This method prints to a String the bytecode program contained in a
85    * Perl5Pattern._ The program byte codes are identical to those
86    * generated by Perl5 with the -r option, but the offsets are
87    * different due to the different data structures used. This
88    * method is useful for diagnosing suspected bugs. The Perl5Compiler
89    * class is designed to produce regular expression programs identical
90    * to those produced by Perl5. By comparing the output of this method
91    * and the output of Perl5 with the -r option on the same regular
92    * expression, you can determine if Perl5Compiler correctly compiled
93    * an expression.
94    * <p>
95    * @param regexp The Perl5Pattern to print.
96    * @return A string representation of the bytecode program defining the
97    * regular expression.
98    */

99
100
101   public static String JavaDoc printProgram(Perl5Pattern regexp) {
102     StringBuffer JavaDoc buffer;
103     char operator = OpCode._OPEN, prog[];
104     int offset, next;
105
106     prog = regexp._program;
107     offset = 1;
108     buffer = new StringBuffer JavaDoc();
109
110     while(operator != OpCode._END) {
111       operator = prog[offset];
112       buffer.append(offset);
113       _printOperator(prog, offset, buffer);
114
115       next = OpCode._getNext(prog, offset);
116       offset+=OpCode._operandLength[operator];
117
118       buffer.append("(" + next + ")");
119
120       offset+=2;
121
122       if(operator == OpCode._ANYOF) {
123     offset += 16;
124       } else if(operator == OpCode._EXACTLY) {
125     ++offset;
126     buffer.append(" <");
127
128     //while(prog[offset] != '0')
129
while(prog[offset] != CharStringPointer._END_OF_STRING) {
130       //while(prog[offset] != 0 &&
131
// prog[offset] != CharStringPointer._END_OF_STRING) {
132
buffer.append(prog[offset]);
133       ++offset;
134     }
135     buffer.append(">");
136     ++offset;
137       }
138
139       buffer.append('\n');
140     }
141
142     // Can print some other stuff here.
143
if(regexp._startString != null)
144       buffer.append("start `" + new String JavaDoc(regexp._startString) + "' ");
145     if(regexp._startClassOffset != OpCode._NULL_OFFSET) {
146       buffer.append("stclass `");
147       _printOperator(prog, regexp._startClassOffset, buffer);
148       buffer.append("' ");
149     }
150     if((regexp._anchor & Perl5Pattern._OPT_ANCH) != 0)
151       buffer.append("anchored ");
152     if((regexp._anchor & Perl5Pattern._OPT_SKIP) != 0)
153       buffer.append("plus ");
154     if((regexp._anchor & Perl5Pattern._OPT_IMPLICIT) != 0)
155       buffer.append("implicit ");
156     if(regexp._mustString != null)
157       buffer.append("must have \""+ new String JavaDoc(regexp._mustString) +
158                "\" back " + regexp._back + " ");
159     buffer.append("minlen " + regexp._minLength + '\n');
160
161     return buffer.toString();
162   }
163
164
165   static void _printOperator(char[] program, int offset, StringBuffer JavaDoc buffer) {
166     String JavaDoc str = null;
167
168     buffer.append(":");
169
170     switch(program[offset]) {
171     case OpCode._BOL : str = "BOL"; break;
172     case OpCode._MBOL : str = "MBOL"; break;
173     case OpCode._SBOL : str = "SBOL"; break;
174     case OpCode._EOL : str = "EOL"; break;
175     case OpCode._MEOL : str = "MEOL"; break;
176     case OpCode._ANY : str = "ANY"; break;
177     case OpCode._SANY : str = "SANY"; break;
178     case OpCode._ANYOF : str = "ANYOF"; break;
179       /*
180     case OpCode._ANYOF : // debug
181       buffer.append("ANYOF\n\n");
182       int foo = OpCode._OPERAND(offset);
183       char ch;
184       for(ch=0; ch < 256; ch++) {
185     if(ch % 16 == 0)
186       buffer.append(" ");
187     buffer.append((program[foo + (ch >> 4)] &
188                (1 << (ch & 0xf))) == 0 ? 0 : 1);
189       }
190       buffer.append("\n\n");
191       break;
192       */

193     case OpCode._BRANCH: str = "BRANCH"; break;
194     case OpCode._EXACTLY: str = "EXACTLY"; break;
195     case OpCode._NOTHING: str = "NOTHING"; break;
196     case OpCode._BACK : str = "BACK"; break;
197     case OpCode._END : str = "END"; break;
198     case OpCode._ALNUM : str = "ALNUM"; break;
199     case OpCode._NALNUM: str = "NALNUM"; break;
200     case OpCode._BOUND : str = "BOUND"; break;
201     case OpCode._NBOUND: str = "NBOUND"; break;
202     case OpCode._SPACE : str = "SPACE"; break;
203     case OpCode._NSPACE: str = "NSPACE"; break;
204     case OpCode._DIGIT : str = "DIGIT"; break;
205     case OpCode._NDIGIT: str = "NDIGIT"; break;
206     case OpCode._CURLY :
207       buffer.append("CURLY {");
208       buffer.append((int)OpCode._getArg1(program, offset));
209       buffer.append(','); buffer.append((int)OpCode._getArg2(program, offset));
210       buffer.append('}');
211       break;
212     case OpCode._CURLYX:
213       buffer.append("CURLYX {");
214       buffer.append((int)OpCode._getArg1(program, offset));
215       buffer.append(','); buffer.append((int)OpCode._getArg2(program, offset));
216       buffer.append('}');
217       break;
218     case OpCode._REF:
219       buffer.append("REF"); buffer.append((int)OpCode._getArg1(program, offset));
220       break;
221     case OpCode._OPEN:
222       buffer.append("OPEN"); buffer.append((int)OpCode._getArg1(program, offset));
223       break;
224     case OpCode._CLOSE:
225       buffer.append("CLOSE"); buffer.append((int)OpCode._getArg1(program, offset));
226       break;
227     case OpCode._STAR : str = "STAR"; break;
228     case OpCode._PLUS : str = "PLUS"; break;
229     case OpCode._MINMOD : str = "MINMOD"; break;
230     case OpCode._GBOL : str = "GBOL"; break;
231     case OpCode._UNLESSM: str = "UNLESSM"; break;
232     case OpCode._IFMATCH: str = "IFMATCH"; break;
233     case OpCode._SUCCEED: str = "SUCCEED"; break;
234     case OpCode._WHILEM : str = "WHILEM"; break;
235     default:
236       buffer.append("Operator is unrecognized. Faulty expression code!");
237       break;
238     }
239     
240     if(str != null)
241       buffer.append(str);
242   }
243 }
244
Popular Tags