001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.languages.parser;
043:
044: import org.netbeans.api.languages.*;
045: import org.netbeans.api.languages.CharInput;
046: import org.netbeans.api.languages.ASTToken;
047: import org.netbeans.modules.languages.Feature;
048: import org.netbeans.modules.languages.parser.Parser.Cookie;
049:
050: import java.util.ArrayList;
051: import java.util.List;
052: import org.netbeans.modules.languages.lexer.SLexer;
053:
054: public abstract class TokenInputUtils {
055:
056: public static TokenInput create(Language language, Parser parser,
057: CharInput input) {
058: return new TokenInputImpl(new TokenReader(language, parser,
059: input), input);
060: }
061:
062: public static TokenInput create(ASTToken[] array) {
063: return new ArrayInput(array);
064: }
065:
066: public static TokenInput create(List list) {
067: return new ListInput(list);
068: }
069:
070: // innerclasses ............................................................
071:
072: private static class TokenReader {
073:
074: private Language language;
075: private Parser parser;
076: private CharInput input;
077: private int state = -1;
078: private Cookie cookie = new MyCookie();
079:
080: private TokenReader(Language language, Parser parser,
081: CharInput input) {
082: this .language = language;
083: this .parser = parser;
084: this .input = input;
085: }
086:
087: private ASTToken next;
088:
089: public ASTToken nextToken(CharInput input) {
090: if (next == null)
091: next = readToken(input);
092: return next;
093: }
094:
095: public ASTToken readToken(CharInput input) {
096: if (input.eof())
097: return null;
098: if (next != null) {
099: ASTToken p = next;
100: next = null;
101: return p;
102: }
103: ASTToken token = parser.read(cookie, input, language);
104: if (token != null)
105: return token;
106: int offset = input.getIndex();
107: return ASTToken.create(language,
108: SLexer.ERROR_TOKEN_TYPE_NAME, String.valueOf(input
109: .read()), offset, 1, null);
110: }
111:
112: private class MyCookie implements Cookie {
113: public int getState() {
114: return state;
115: }
116:
117: public void setState(int state) {
118: TokenReader.this .state = state;
119: }
120:
121: public void setProperties(Feature tokenProperties) {
122: }
123: }
124: }
125:
126: private static class TokenInputImpl extends TokenInput {
127:
128: private TokenReader tokenReader;
129: private List<ASTToken> tokens = new ArrayList<ASTToken>();
130: private int index = 0;
131: private CharInput input;
132:
133: TokenInputImpl(TokenReader tokenReader, CharInput input) {
134: this .input = input;
135: this .tokenReader = tokenReader;
136: }
137:
138: public ASTToken next(int i) {
139: while (index + i - 1 >= tokens.size())
140: tokens.add(tokenReader.readToken(input));
141: return (ASTToken) tokens.get(index + i - 1);
142: }
143:
144: public boolean eof() {
145: return next(1) == null;
146: }
147:
148: public int getIndex() {
149: return index;
150: }
151:
152: public int getOffset() {
153: ASTToken t = null;
154: if (eof()) {
155: if (getIndex() == 0)
156: return 0;
157: int i = tokens.size() - 1;
158: do {
159: t = ((ASTToken) tokens.get(i--));
160: } while (t == null && i > 0);
161: if (t == null)
162: return 0;
163: return t.getOffset() + t.getLength();
164: } else {
165: t = (ASTToken) next(1);
166: return t.getOffset();
167: }
168: }
169:
170: public ASTToken read() {
171: ASTToken t = next(1);
172: if (t != null)
173: index++;
174: return t;
175: }
176:
177: public void setIndex(int index) {
178: if (index > tokens.size())
179: throw new IndexOutOfBoundsException();
180: this .index = index;
181: }
182:
183: public String getString(int from) {
184: throw new InternalError();
185: }
186:
187: public String toString() {
188: return input.toString();
189: }
190: }
191:
192: private static class ArrayInput extends TokenInput {
193:
194: private ASTToken[] array;
195: private int index = 0;
196: private int length;
197:
198: private ArrayInput(ASTToken[] array) {
199: this .array = array;
200: length = array.length;
201: }
202:
203: public ASTToken read() {
204: if (index < length)
205: return array[index++];
206: return null;
207: }
208:
209: public void setIndex(int index) {
210: this .index = index;
211: }
212:
213: public int getIndex() {
214: return index;
215: }
216:
217: public int getOffset() {
218: ASTToken t = null;
219: if (eof()) {
220: if (getIndex() == 0)
221: return 0;
222: t = (ASTToken) array[array.length - 1];
223: return t.getOffset() + t.getLength();
224: } else {
225: t = (ASTToken) next(1);
226: return t.getOffset();
227: }
228: }
229:
230: public boolean eof() {
231: return index >= length;
232: }
233:
234: public ASTToken next(int i) {
235: if (index + i - 1 < length)
236: return array[index + i - 1];
237: return null;
238: }
239:
240: public String toString() {
241: StringBuilder sb = new StringBuilder();
242: int i = index, j = 0;
243: while (j < 10 && i < length) {
244: sb.append(array[i]).append(" ");
245: i++;
246: j++;
247: }
248: return sb.toString();
249: }
250: }
251:
252: private static class ListInput extends TokenInput {
253:
254: private List list;
255: private int index = 0;
256: private int length;
257:
258: private ListInput(List list) {
259: this .list = list;
260: length = list.size();
261: }
262:
263: public ASTToken read() {
264: if (index < length)
265: return (ASTToken) list.get(index++);
266: return null;
267: }
268:
269: public void setIndex(int index) {
270: this .index = index;
271: }
272:
273: public int getIndex() {
274: return index;
275: }
276:
277: public int getOffset() {
278: ASTToken t = null;
279: if (eof()) {
280: if (getIndex() == 0)
281: return 0;
282: t = ((ASTToken) list.get(list.size() - 1));
283: return t.getOffset() + t.getLength();
284: } else {
285: t = (ASTToken) next(1);
286: return t.getOffset();
287: }
288: }
289:
290: public boolean eof() {
291: return index >= length;
292: }
293:
294: public ASTToken next(int i) {
295: if (index + i - 1 < length)
296: return (ASTToken) list.get(index + i - 1);
297: return null;
298: }
299:
300: public String toString() {
301: StringBuilder sb = new StringBuilder();
302: int i = index, j = 0;
303: while (j < 10 && i < length) {
304: sb.append(list.get(i)).append(" ");
305: i++;
306: j++;
307: }
308: return sb.toString();
309: }
310: }
311: }
|