KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdi > internal > SourceDebugExtensionParser


1 /*******************************************************************************
2  * Copyright (c) 2003, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdi.internal;
12
13 import com.ibm.icu.text.MessageFormat;
14 import java.util.ArrayList JavaDoc;
15 import java.util.List JavaDoc;
16
17 import com.sun.jdi.AbsentInformationException;
18
19 /**
20  *
21  */

22 public class SourceDebugExtensionParser {
23     
24     private static class Lexer {
25         
26         static final int UNKNOWN= 0;
27         static final int SMAP= 1;
28         static final int NON_ASTERISK_STRING= 2;
29         static final int NUMBER= 3;
30         static final int CR= 4;
31         static final int ASTERISK_CHAR= 5;
32         static final int ASTERISK_C= 6;
33         static final int ASTERISK_E= 7;
34         static final int ASTERISK_F= 8;
35         static final int ASTERISK_L= 9;
36         static final int ASTERISK_O= 10;
37         static final int ASTERISK_S= 11;
38         static final int ASTERISK_V= 12;
39         static final int WHITE_SPACE= 13;
40         static final int COLON= 14;
41         static final int COMMA= 15;
42         static final int SHARP= 16;
43         static final int PLUS= 17;
44         
45         private char[] fSmap;
46         private int fPointer;
47         private char fChar;
48         
49         private char[] fLexem;
50         private int fLexemType;
51         
52         private boolean fEOF;
53         
54         public Lexer (String JavaDoc smap) {
55             fSmap= smap.toCharArray();
56             fLexemType= UNKNOWN;
57             fPointer= -1;
58             nextChar();
59         }
60         
61         /**
62          * Compute the next lexem.
63          *
64          * @return the type of the next lexem.
65          */

66         public int nextLexem() throws AbsentInformationException {
67             if (fEOF) {
68                 throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_0);
69             }
70             startWith();
71             return fLexemType;
72         }
73
74         
75         private char nextChar() {
76             if (++fPointer == fSmap.length) {
77                 fEOF= true;
78                 return '\000';
79             }
80             fChar= fSmap[fPointer];
81             return fChar;
82         }
83         
84         private void startWith() throws AbsentInformationException {
85             switch (fChar) {
86                 case '\n':
87                 case '\r':
88                     startWithCR();
89                     break;
90                 case '*':
91                     startWithAsterisk();
92                     break;
93                 case ':':
94                     fLexem= new char[] {':'};
95                     fLexemType= COLON;
96                     nextChar();
97                     break;
98                 case ',':
99                     fLexem= new char[] {','};
100                     fLexemType= COMMA;
101                     nextChar();
102                     break;
103                 case '#':
104                     fLexem= new char[] {'#'};
105                     fLexemType= SHARP;
106                     nextChar();
107                     break;
108                 case '+':
109                     fLexem= new char[] {'+'};
110                     fLexemType= PLUS;
111                     nextChar();
112                     break;
113                 default:
114                     startWithOtherChar();
115                     break;
116             }
117         }
118
119         /**
120          *
121          */

122         private void startWithOtherChar() {
123             int lexemStart= fPointer;
124             consumeWhiteSpace();
125             if (fChar >= '0' && fChar <= '9') { // a number
126
number(lexemStart);
127             } else {
128                 nonAsteriskString(lexemStart);
129             }
130         }
131
132         /**
133          * @param lexemStart
134          */

135         private void nonAsteriskString(int lexemStart) {
136             while (fChar != '\n' && fChar != '\r' && !fEOF) {
137                 nextChar();
138             }
139             int length= fPointer - lexemStart;
140             fLexem= new char[length];
141             System.arraycopy(fSmap, lexemStart, fLexem, 0, length);
142             if (length == 4 && fLexem[0] == 'S' && fLexem[1] == 'M' && fLexem[2] == 'A' && fLexem[3] == 'P') {
143                 fLexemType= SMAP;
144             } else {
145                 fLexemType= NON_ASTERISK_STRING;
146             }
147         }
148
149         /**
150          * @param lexemStart
151          */

152         private void number(int lexemStart) {
153             while (fChar >= '0' && fChar <= '9') {
154                 nextChar();
155             }
156             consumeWhiteSpace();
157             fLexemType= NUMBER;
158             int length= fPointer - lexemStart;
159             fLexem= new char[length];
160             System.arraycopy(fSmap, lexemStart, fLexem, 0, length);
161         }
162
163         /**
164          *
165          */

166         private void startWithAsterisk() throws AbsentInformationException {
167             nextChar();
168             if (fEOF) {
169                 throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_0);
170             }
171             switch (fChar) {
172                 case 'C':
173                     fLexemType= ASTERISK_C;
174                     break;
175                 case 'E':
176                     fLexemType= ASTERISK_E;
177                     break;
178                 case 'F':
179                     fLexemType= ASTERISK_F;
180                     break;
181                 case 'L':
182                     fLexemType= ASTERISK_L;
183                     break;
184                 case 'O':
185                     fLexemType= ASTERISK_O;
186                     break;
187                 case 'S':
188                     fLexemType= ASTERISK_S;
189                     break;
190                 case 'V':
191                     fLexemType= ASTERISK_V;
192                     break;
193                 default:
194                     fLexemType= ASTERISK_CHAR;
195                     break;
196             }
197             fLexem= new char[] {'*', fChar};
198             nextChar();
199         }
200
201         /**
202          *
203          */

204         private void startWithCR() {
205             if (fChar == '\r') {
206                 if (nextChar() == '\n') {
207                     fLexem= new char[] {'\r', '\n'};
208                     nextChar();
209                 } else {
210                     fLexem= new char[] {'\r'};
211                 }
212             } else {
213                 fLexem= new char[] {fChar};
214                 nextChar();
215             }
216             fLexemType= CR;
217         }
218
219         /**
220          *
221          */

222         private void consumeWhiteSpace() {
223             while (fChar == ' ' || fChar == '\t') {
224                 nextChar();
225             }
226         }
227
228         /**
229          * @return the value of the current lexem.
230          */

231         public char[] lexem() {
232             return fLexem;
233         }
234         
235         /**
236          * @return the type of the current lexem.
237          */

238         public int lexemType() {
239             return fLexemType;
240         }
241         
242     }
243     
244     /**
245      * The reference type to which this source debug extension is associated.
246      */

247     private ReferenceTypeImpl fReferenceType;
248     
249     private List JavaDoc fDefinedStrata;
250     
251     // parser data;
252
private ReferenceTypeImpl.Stratum fCurrentStratum;
253     private boolean fFileSectionDefinedForCurrentStratum;
254     private boolean fLineSectionDefinedForCurrentStratum;
255     private int fCurrentLineFileId;
256
257
258     public static void parse(String JavaDoc smap, ReferenceTypeImpl referenceType) throws AbsentInformationException {
259         new SourceDebugExtensionParser(referenceType).parseSmap(smap);
260     }
261     
262     /**
263      * SourceDebugExtension constructor.
264      */

265     private SourceDebugExtensionParser(ReferenceTypeImpl referenceType) {
266         fReferenceType= referenceType;
267         fDefinedStrata= new ArrayList JavaDoc();
268         fDefinedStrata.add(VirtualMachineImpl.JAVA_STRATUM_NAME);
269     }
270     
271     /**
272      *
273      */

274     private void parseSmap(String JavaDoc smap) throws AbsentInformationException {
275         Lexer lexer= new Lexer(smap);
276         parseHeader(lexer);
277         parseSections(lexer);
278         if (!fDefinedStrata.contains(fReferenceType.defaultStratum())) {
279             throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_2);
280         }
281     }
282
283     /**
284      * @param lexer
285      */

286     private void parseHeader(Lexer lexer) throws AbsentInformationException {
287         int lexemType= lexer.nextLexem();
288         if (lexemType != Lexer.SMAP) {
289             throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_3);
290         }
291         if (lexer.nextLexem() != Lexer.CR) {
292             throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_4);
293         }
294         if (isAsteriskLexem(lexer.nextLexem())) {
295             throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_5);
296         }
297         fReferenceType.setOutputFileName(getNonAsteriskString(lexer));
298         if (isAsteriskLexem(lexer.lexemType())) {
299             throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_6);
300         }
301         fReferenceType.setDefaultStratumId(getNonAsteriskString(lexer));
302     }
303
304     /**
305      * @param lexer
306      */

307     private void parseSections(Lexer lexer) throws AbsentInformationException {
308         while (lexer.lexemType() != Lexer.ASTERISK_E) {
309             parseStratumSection(lexer);
310         }
311     }
312
313     /**
314      * @param lexer
315      */

316     private void parseStratumSection(Lexer lexer) throws AbsentInformationException {
317         if (lexer.lexemType() != Lexer.ASTERISK_S) {
318             throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_7);
319         }
320         if (isAsteriskLexem(lexer.nextLexem())) {
321             throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_8);
322         }
323         String JavaDoc stratumId= getNonAsteriskString(lexer);
324         if (fDefinedStrata.contains(stratumId)) {
325             throw new AbsentInformationException(MessageFormat.format(JDIMessages.SourceDebugExtensionParser_9, new String JavaDoc[] {stratumId}));
326         }
327         fCurrentStratum= new ReferenceTypeImpl.Stratum(stratumId);
328         fFileSectionDefinedForCurrentStratum= false;
329         fLineSectionDefinedForCurrentStratum= false;
330         int lexemType= lexer.lexemType();
331         while (lexemType != Lexer.ASTERISK_E && lexemType != Lexer.ASTERISK_S) {
332             switch (lexemType) {
333                 case Lexer.ASTERISK_F:
334                     if (fFileSectionDefinedForCurrentStratum) {
335                         throw new AbsentInformationException(MessageFormat.format(JDIMessages.SourceDebugExtensionParser_10, new String JavaDoc[] {stratumId}));
336                     }
337                     parseFileSection(lexer);
338                     fFileSectionDefinedForCurrentStratum= true;
339                     break;
340                 case Lexer.ASTERISK_L:
341                     if (fLineSectionDefinedForCurrentStratum) {
342                         throw new AbsentInformationException(MessageFormat.format(JDIMessages.SourceDebugExtensionParser_11, new String JavaDoc[] {stratumId}));
343                     }
344                     parseLineSection(lexer);
345                     fLineSectionDefinedForCurrentStratum= true;
346                     break;
347                 case Lexer.ASTERISK_V:
348                     parseVendorSection(lexer);
349                     break;
350                 case Lexer.ASTERISK_CHAR:
351                     parseFutureSection(lexer);
352                     break;
353                 default:
354                     throw new AbsentInformationException(MessageFormat.format(JDIMessages.SourceDebugExtensionParser_12, new String JavaDoc[] {new String JavaDoc(lexer.lexem())}));
355             }
356             lexemType= lexer.lexemType();
357         }
358         if (!fFileSectionDefinedForCurrentStratum) {
359             throw new AbsentInformationException(MessageFormat.format(JDIMessages.SourceDebugExtensionParser_13, new String JavaDoc[] {stratumId}));
360         }
361         if (!fLineSectionDefinedForCurrentStratum) {
362             throw new AbsentInformationException(MessageFormat.format(JDIMessages.SourceDebugExtensionParser_14, new String JavaDoc[] {stratumId}));
363         }
364         fDefinedStrata.add(stratumId);
365         fReferenceType.addStratum(fCurrentStratum);
366     }
367
368     /**
369      * @param lexer
370      */

371     private void parseFileSection(Lexer lexer) throws AbsentInformationException {
372         if (lexer.nextLexem() != Lexer.CR) {
373             throw new AbsentInformationException(MessageFormat.format(JDIMessages.SourceDebugExtensionParser_12, new String JavaDoc[] {new String JavaDoc(lexer.lexem())}));
374         }
375         lexer.nextLexem();
376         while (!isAsteriskLexem(lexer.lexemType())) {
377             parseFileInfo(lexer);
378         }
379     }
380
381     /**
382      * @param lexer
383      */

384     private void parseFileInfo(Lexer lexer) throws AbsentInformationException {
385         int lexemType= lexer.lexemType();
386         if (lexemType == Lexer.NUMBER) {
387             int fileId= integerValue(lexer.lexem());
388             if (isAsteriskLexem(lexer.nextLexem())) {
389                 throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_16);
390             }
391             fCurrentStratum.addFileInfo(fileId, getNonAsteriskString(lexer));
392         } else if (lexemType == Lexer.PLUS) {
393             if (lexer.nextLexem() != Lexer.NUMBER) {
394                 throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_17);
395             }
396             int fileId= integerValue(lexer.lexem());
397             if (isAsteriskLexem(lexer.nextLexem())) {
398                 throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_16);
399             }
400             String JavaDoc fileName= getNonAsteriskString(lexer);
401             if (isAsteriskLexem(lexer.lexemType())) {
402                 throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_19);
403             }
404             fCurrentStratum.addFileInfo(fileId, fileName, getNonAsteriskString(lexer));
405         } else {
406             throw new AbsentInformationException(MessageFormat.format(JDIMessages.SourceDebugExtensionParser_12, new String JavaDoc[] {new String JavaDoc(lexer.lexem())}));
407         }
408     }
409
410     /**
411      * @param lexer
412      */

413     private void parseLineSection(Lexer lexer) throws AbsentInformationException {
414         fCurrentLineFileId= 0;
415         if (lexer.nextLexem() != Lexer.CR) {
416             throw new AbsentInformationException(MessageFormat.format(JDIMessages.SourceDebugExtensionParser_12, new String JavaDoc[] {new String JavaDoc(lexer.lexem())}));
417         }
418         lexer.nextLexem();
419         while (!isAsteriskLexem(lexer.lexemType())) {
420             parseLineInfo(lexer);
421         }
422     }
423
424     /**
425      * @param lexer
426      */

427     private void parseLineInfo(Lexer lexer) throws AbsentInformationException {
428         if (lexer.lexemType() != Lexer.NUMBER) {
429             throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_22);
430         }
431         int inputStartLine= integerValue(lexer.lexem());
432         int lexemType= lexer.nextLexem();
433         if (lexemType == Lexer.SHARP) {
434             if (lexer.nextLexem() != Lexer.NUMBER) {
435                 throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_23);
436             }
437             fCurrentLineFileId= integerValue(lexer.lexem());
438             lexemType= lexer.nextLexem();
439         }
440         int repeatCount;
441         if (lexemType == Lexer.COMMA) {
442             if (lexer.nextLexem() != Lexer.NUMBER) {
443                 throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_24);
444             }
445             repeatCount= integerValue(lexer.lexem());
446             lexemType= lexer.nextLexem();
447         } else {
448             repeatCount= 1;
449         }
450         if (lexemType != Lexer.COLON) {
451             throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_25);
452         }
453         if (lexer.nextLexem() != Lexer.NUMBER) {
454             throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_26);
455         }
456         int outputStartLine= integerValue(lexer.lexem());
457         lexemType= lexer.nextLexem();
458         int outputLineIncrement;
459         if (lexemType == Lexer.COMMA) {
460             if (lexer.nextLexem() != Lexer.NUMBER) {
461                 throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_27);
462             }
463             outputLineIncrement= integerValue(lexer.lexem());
464             lexemType= lexer.nextLexem();
465         } else {
466             outputLineIncrement= 1;
467         }
468         if (lexemType != Lexer.CR) {
469             throw new AbsentInformationException(JDIMessages.SourceDebugExtensionParser_28);
470         }
471         lexer.nextLexem();
472         fCurrentStratum.addLineInfo(inputStartLine, fCurrentLineFileId, repeatCount, outputStartLine, outputLineIncrement);
473     }
474
475     /**
476      * @param lexer
477      */

478     private void parseVendorSection(Lexer lexer) throws AbsentInformationException {
479         if (lexer.nextLexem() != Lexer.CR) {
480             throw new AbsentInformationException(MessageFormat.format(JDIMessages.SourceDebugExtensionParser_12, new String JavaDoc[] {new String JavaDoc(lexer.lexem())}));
481         }
482         lexer.nextLexem();
483         while (!isAsteriskLexem(lexer.lexemType())) {
484             // do nothing in this case, just consume the lexems.
485
getNonAsteriskString(lexer);
486         }
487     }
488
489     /**
490      * @param lexer
491      */

492     private void parseFutureSection(Lexer lexer) throws AbsentInformationException {
493         if (lexer.nextLexem() != Lexer.CR) {
494             throw new AbsentInformationException(MessageFormat.format(JDIMessages.SourceDebugExtensionParser_12, new String JavaDoc[] {new String JavaDoc(lexer.lexem())}));
495         }
496         lexer.nextLexem();
497         while (!isAsteriskLexem(lexer.lexemType())) {
498             // do nothing in this case, just consume the lexems.
499
getNonAsteriskString(lexer);
500         }
501     }
502
503     private String JavaDoc getNonAsteriskString(Lexer lexer) throws AbsentInformationException {
504         StringBuffer JavaDoc string= new StringBuffer JavaDoc();
505         int lexemType= lexer.lexemType();
506         while (lexemType != Lexer.CR) {
507             string.append(lexer.lexem());
508             lexemType= lexer.nextLexem();
509         }
510         lexer.nextLexem();
511         // remove the leading white spaces
512
int i= -1, length= string.length();
513         char c;
514         while (++i < length && ((c= string.charAt(i)) == ' ' || c == '\t'));
515         return string.delete(0, i).toString();
516     }
517     
518     private int integerValue(char[] lexem) {
519         int i= 0;
520         char c= lexem[0];
521         while (c == ' ' || c == '\t') {
522             c= lexem[++i];
523         }
524         int value= 0;
525         while (c >= '0' && c <= '9') {
526             value= value * 10 + c - '0';
527             if (++i == lexem.length) {
528                 break;
529             }
530             c= lexem[i];
531         }
532         return value;
533     }
534
535     private boolean isAsteriskLexem(int lexemType) {
536         switch (lexemType) {
537             case Lexer.ASTERISK_C:
538             case Lexer.ASTERISK_E:
539             case Lexer.ASTERISK_F:
540             case Lexer.ASTERISK_L:
541             case Lexer.ASTERISK_O:
542             case Lexer.ASTERISK_S:
543             case Lexer.ASTERISK_V:
544             case Lexer.ASTERISK_CHAR:
545             return true;
546             default:
547                 return false;
548         }
549     }
550
551 }
552
Popular Tags