KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > text > rules > RuleBasedScanner


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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
12 package org.eclipse.jface.text.rules;
13
14
15 import org.eclipse.core.runtime.Assert;
16
17 import org.eclipse.jface.text.BadLocationException;
18 import org.eclipse.jface.text.IDocument;
19
20
21 /**
22  * A generic scanner which can be "programmed" with a sequence of rules.
23  * The scanner is used to get the next token by evaluating its rule in sequence until
24  * one is successful. If a rule returns a token which is undefined, the scanner will proceed to
25  * the next rule. Otherwise the token provided by the rule will be returned by
26  * the scanner. If no rule returned a defined token, this scanner returns a token
27  * which returns <code>true</code> when calling <code>isOther</code>, unless the end
28  * of the file is reached. In this case the token returns <code>true</code> when calling
29  * <code>isEOF</code>.
30  *
31  * @see IRule
32  */

33 public class RuleBasedScanner implements ICharacterScanner, ITokenScanner {
34
35     /** The list of rules of this scanner */
36     protected IRule[] fRules;
37     /** The token to be returned by default if no rule fires */
38     protected IToken fDefaultReturnToken;
39     /** The document to be scanned */
40     protected IDocument fDocument;
41     /** The cached legal line delimiters of the document */
42     protected char[][] fDelimiters;
43     /** The offset of the next character to be read */
44     protected int fOffset;
45     /** The end offset of the range to be scanned */
46     protected int fRangeEnd;
47     /** The offset of the last read token */
48     protected int fTokenOffset;
49     /** The cached column of the current scanner position */
50     protected int fColumn;
51     /** Internal setting for the un-initialized column cache. */
52     protected static final int UNDEFINED= -1;
53
54     /**
55      * Creates a new rule based scanner which does not have any rule.
56      */

57     public RuleBasedScanner() {
58     }
59
60     /**
61      * Configures the scanner with the given sequence of rules.
62      *
63      * @param rules the sequence of rules controlling this scanner
64      */

65     public void setRules(IRule[] rules) {
66         if (rules != null) {
67             fRules= new IRule[rules.length];
68             System.arraycopy(rules, 0, fRules, 0, rules.length);
69         } else
70             fRules= null;
71     }
72
73     /**
74      * Configures the scanner's default return token. This is the token
75      * which is returned when none of the rules fired and EOF has not been
76      * reached.
77      *
78      * @param defaultReturnToken the default return token
79      * @since 2.0
80      */

81     public void setDefaultReturnToken(IToken defaultReturnToken) {
82         Assert.isNotNull(defaultReturnToken.getData());
83         fDefaultReturnToken= defaultReturnToken;
84     }
85
86     /*
87      * @see ITokenScanner#setRange(IDocument, int, int)
88      */

89     public void setRange(final IDocument document, int offset, int length) {
90         Assert.isLegal(document != null);
91         final int documentLength= document.getLength();
92         checkRange(offset, length, documentLength);
93
94         fDocument= document;
95         fOffset= offset;
96         fColumn= UNDEFINED;
97         fRangeEnd= offset + length;
98
99         String JavaDoc[] delimiters= fDocument.getLegalLineDelimiters();
100         fDelimiters= new char[delimiters.length][];
101         for (int i= 0; i < delimiters.length; i++)
102             fDelimiters[i]= delimiters[i].toCharArray();
103
104         if (fDefaultReturnToken == null)
105             fDefaultReturnToken= new Token(null);
106     }
107
108     /**
109      * Checks that the given range is valid.
110      * See: // https://bugs.eclipse.org/bugs/show_bug.cgi?id=69292
111      *
112      * @param offset the offset of the document range to scan
113      * @param length the length of the document range to scan
114      * @param documentLength the document's length
115      * @since 3.3
116      */

117     private void checkRange(int offset, int length, int documentLength) {
118         Assert.isLegal(offset > -1);
119         Assert.isLegal(length > -1);
120         Assert.isLegal(offset + length <= documentLength);
121     }
122
123     /*
124      * @see ITokenScanner#getTokenOffset()
125      */

126     public int getTokenOffset() {
127         return fTokenOffset;
128     }
129
130     /*
131      * @see ITokenScanner#getTokenLength()
132      */

133     public int getTokenLength() {
134         if (fOffset < fRangeEnd)
135             return fOffset - getTokenOffset();
136         return fRangeEnd - getTokenOffset();
137     }
138
139
140     /*
141      * @see ICharacterScanner#getColumn()
142      */

143     public int getColumn() {
144         if (fColumn == UNDEFINED) {
145             try {
146                 int line= fDocument.getLineOfOffset(fOffset);
147                 int start= fDocument.getLineOffset(line);
148
149                 fColumn= fOffset - start;
150
151             } catch (BadLocationException ex) {
152             }
153         }
154         return fColumn;
155     }
156
157     /*
158      * @see ICharacterScanner#getLegalLineDelimiters()
159      */

160     public char[][] getLegalLineDelimiters() {
161         return fDelimiters;
162     }
163
164     /*
165      * @see ITokenScanner#nextToken()
166      */

167     public IToken nextToken() {
168
169         fTokenOffset= fOffset;
170         fColumn= UNDEFINED;
171
172         if (fRules != null) {
173             for (int i= 0; i < fRules.length; i++) {
174                 IToken token= (fRules[i].evaluate(this));
175                 if (!token.isUndefined())
176                     return token;
177             }
178         }
179
180         if (read() == EOF)
181             return Token.EOF;
182         return fDefaultReturnToken;
183     }
184
185     /*
186      * @see ICharacterScanner#read()
187      */

188     public int read() {
189
190         try {
191
192             if (fOffset < fRangeEnd) {
193                 try {
194                     return fDocument.getChar(fOffset);
195                 } catch (BadLocationException e) {
196                 }
197             }
198
199             return EOF;
200
201         } finally {
202             ++ fOffset;
203             fColumn= UNDEFINED;
204         }
205     }
206
207     /*
208      * @see ICharacterScanner#unread()
209      */

210     public void unread() {
211             --fOffset;
212     }
213 }
214
215
216
Popular Tags