KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jode > obfuscator > ScriptParser


1 /* ScriptParser Copyright (C) 1999-2002 Jochen Hoenicke.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; see the file COPYING. If not, write to
15  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
16  *
17  * $Id: ScriptParser.java.in,v 1.4.2.1 2002/05/28 17:34:14 hoenicke Exp $
18  */

19
20 package jode.obfuscator;
21
22 import java.io.BufferedReader JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.io.Reader JavaDoc;
25
26 import java.util.Collection JavaDoc;
27 import java.util.LinkedList JavaDoc;
28
29 public class ScriptParser {
30     static int NO_TOKEN = -2;
31     static int EOF_TOKEN = -1;
32     static int STRING_TOKEN = 0;
33     static int NEW_TOKEN = 1;
34     static int EQUALS_TOKEN = 2;
35     static int COMMA_TOKEN = 3;
36     static int OPENBRACE_TOKEN = 4;
37     static int CLOSEBRACE_TOKEN = 5;
38     static int IDENTIFIER_TOKEN = 6;
39     static int NUMBER_TOKEN = 7;
40     Scanner scanner;
41
42     class Scanner {
43     BufferedReader JavaDoc input;
44     String JavaDoc value;
45     String JavaDoc line;
46     int column;
47     int linenr;
48     int pushback = NO_TOKEN;
49     
50     public Scanner(Reader JavaDoc i) {
51         input = new BufferedReader JavaDoc(i);
52     }
53
54     public void readString() throws ParseException {
55         StringBuffer JavaDoc val = new StringBuffer JavaDoc();
56         while (column < line.length()) {
57         char c = line.charAt(column++);
58         if (c == '"') {
59             value = val.toString();
60             return;
61         }
62         if (c == '\\') {
63             c = line.charAt(column++);
64             switch (c) {
65             case 'n':
66             val.append('\n');
67             break;
68             case 't':
69             val.append('\t');
70             break;
71             case 'r':
72             val.append('\r');
73             break;
74             case 'u':
75             if (column+4 <= line.length()) {
76                 try {
77                 char uni = (char) Integer.parseInt
78                     (line.substring(column, column+4), 16);
79                 column += 4;
80                 val.append(uni);
81                 } catch (NumberFormatException JavaDoc ex) {
82                 throw new ParseException
83                     (linenr,
84                      "Invalid unicode escape character");
85                 }
86             } else
87                 throw new ParseException
88                 (linenr,
89                  "Invalid unicode escape character");
90             break;
91             default:
92             val.append(c);
93             }
94         } else
95             val.append(c);
96         }
97         throw new ParseException(linenr,
98                      "String spans over multiple lines");
99     }
100     public void readIdentifier() {
101         int start = column-1;
102         while (column < line.length()
103            && Character.isUnicodeIdentifierPart(line.charAt(column)))
104         column++;
105         value = line.substring(start, column);
106     }
107
108     public void readNumber() {
109         boolean hex = false;
110         int start = column-1;
111         /* special case for hex numbers */
112         if (line.charAt(start) == '0' && line.charAt(column) == 'x') {
113         column++;
114         hex = true;
115         }
116         while (column < line.length()) {
117         char c = line.charAt(column);
118         if (!Character.isDigit(c)) {
119             if (!hex)
120                 break;
121             if ((c < 'A' || c > 'F') && (c < 'a' || c > 'f'))
122             break;
123         }
124         column++;
125         }
126         value = line.substring(start, column);
127     }
128
129     public void pushbackToken(int token) {
130         if (pushback != NO_TOKEN)
131         throw new IllegalStateException JavaDoc
132             ("Can only handle one pushback");
133         pushback = token;
134     }
135
136     public int getToken() throws ParseException, IOException JavaDoc {
137         if (pushback != NO_TOKEN) {
138         int result = pushback;
139         pushback = NO_TOKEN;
140         return result;
141         }
142         value = null;
143         while (true) {
144         if (line == null) {
145             line = input.readLine();
146             if (line == null)
147             return EOF_TOKEN;
148             linenr++;
149             column = 0;
150         }
151         while (column < line.length()) {
152             char c = line.charAt(column++);
153             if (Character.isWhitespace(c))
154             continue;
155             if (c == '#')
156             // this is a comment, skip this line
157
break;
158             if (c == '=')
159             return EQUALS_TOKEN;
160             if (c == ',')
161             return COMMA_TOKEN;
162             if (c == '{')
163             return OPENBRACE_TOKEN;
164             if (c == '}')
165             return CLOSEBRACE_TOKEN;
166             if (c == '"') {
167             readString();
168             return STRING_TOKEN;
169             }
170             if (Character.isDigit(c) || c == '+' || c == '-') {
171             readNumber();
172             return NUMBER_TOKEN;
173             }
174             if (Character.isUnicodeIdentifierStart(c)) {
175             readIdentifier();
176             if (value.equals("new"))
177                 return NEW_TOKEN;
178             return IDENTIFIER_TOKEN;
179             }
180             throw new ParseException
181             (linenr, "Illegal character `"+c+"'");
182         }
183         line = null;
184         }
185     }
186         
187     public String JavaDoc getValue() {
188         return value;
189     }
190     
191     public int getLineNr() {
192         return linenr;
193     }
194     }
195     
196     public ScriptParser(Reader JavaDoc reader) {
197     this.scanner = new Scanner(reader);
198     }
199
200     public Object JavaDoc parseClass() throws ParseException, IOException JavaDoc {
201     int linenr = scanner.getLineNr();
202     int token = scanner.getToken();
203     if (token != IDENTIFIER_TOKEN)
204         throw new ParseException(linenr, "Class name expected");
205     Object JavaDoc instance;
206     try {
207         Class JavaDoc clazz = Class.forName("jode.obfuscator.modules."
208                     +scanner.getValue());
209         instance = clazz.newInstance();
210     } catch (ClassNotFoundException JavaDoc ex) {
211         throw new ParseException(scanner.getLineNr(),
212                      "Class `"+scanner.getValue()
213                      +"' not found");
214     } catch (Exception JavaDoc ex) {
215         throw new ParseException(scanner.getLineNr(),
216                      "Class `"+scanner.getValue()
217                      +"' not valid: "+ex.getMessage());
218     }
219
220     token = scanner.getToken();
221     if (token == OPENBRACE_TOKEN) {
222         if (!(instance instanceof OptionHandler))
223         throw new ParseException
224             (scanner.getLineNr(),
225              "Class `"+instance.getClass().getName()
226              +"' doesn't handle options.");
227         parseOptions((OptionHandler) instance);
228         if (scanner.getToken() != CLOSEBRACE_TOKEN)
229         throw new ParseException(scanner.getLineNr(), "`}' expected");
230     } else
231         scanner.pushbackToken(token);
232     return instance;
233     }
234
235     public void parseOptions(OptionHandler optionHandler)
236     throws ParseException, IOException JavaDoc
237     {
238     int token = scanner.getToken();
239     while (true) {
240         if (token == EOF_TOKEN || token == CLOSEBRACE_TOKEN) {
241         scanner.pushbackToken(token);
242         return;
243         }
244         if (token != IDENTIFIER_TOKEN)
245         throw new ParseException(scanner.getLineNr(),
246                      "identifier expected");
247         String JavaDoc ident = scanner.getValue();
248         if (scanner.getToken() != EQUALS_TOKEN)
249         throw new ParseException(scanner.getLineNr(),
250                      "equal sign expected");
251
252         int linenr = scanner.getLineNr();
253         Collection JavaDoc values = new LinkedList JavaDoc();
254         do {
255         token = scanner.getToken();
256         if (token == NEW_TOKEN) {
257             values.add(parseClass());
258         } else if (token == STRING_TOKEN) {
259             values.add(scanner.getValue());
260         } else if (token == NUMBER_TOKEN) {
261             values.add(new Integer JavaDoc(scanner.getValue()));
262         }
263         token = scanner.getToken();
264         } while (token == COMMA_TOKEN);
265         try {
266         optionHandler.setOption(ident, values);
267         } catch (IllegalArgumentException JavaDoc ex) {
268         throw new ParseException(linenr,
269                      optionHandler.getClass().getName()
270                      +": "+ex.getMessage());
271         } catch (RuntimeException JavaDoc ex) {
272         throw new ParseException(linenr,
273                      optionHandler.getClass().getName()
274                      +": Illegal value: "
275                      +ex.getClass().getName()
276                      +": "+ex.getMessage());
277         }
278     }
279     }
280 }
281
Popular Tags