001: /*
002: * Copyright (C) 2005 - 2008 JasperSoft Corporation. All rights reserved.
003: * http://www.jaspersoft.com.
004: *
005: * Unless you have purchased a commercial license agreement from JasperSoft,
006: * the following license terms apply:
007: *
008: * This program is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU General Public License version 2 as published by
010: * the Free Software Foundation.
011: *
012: * This program is distributed WITHOUT ANY WARRANTY; and without the
013: * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
014: * See the GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, see http://www.gnu.org/licenses/gpl.txt
018: * or write to:
019: *
020: * Free Software Foundation, Inc.,
021: * 59 Temple Place - Suite 330,
022: * Boston, MA USA 02111-1307
023: *
024: *
025: *
026: *
027: * EiffelTokenMarker.java
028: *
029: */
030:
031: package org.syntax.jedit.tokenmarker;
032:
033: import org.syntax.jedit.*;
034: import javax.swing.text.Segment;
035:
036: /**
037: * Eiffel token Marker.
038: *
039: * @author Artur Biesiadowski
040: */
041: public class EiffelTokenMarker extends TokenMarker {
042:
043: public EiffelTokenMarker() {
044: this .keywords = getKeywords();
045: }
046:
047: public byte markTokensImpl(byte token, Segment line, int lineIndex) {
048: char[] array = line.array;
049: int offset = line.offset;
050: lastOffset = offset;
051: lastKeyword = offset;
052: int length = line.count + offset;
053: boolean backslash = false;
054:
055: loop: for (int i = offset; i < length; i++) {
056: int i1 = (i + 1);
057:
058: char c = array[i];
059: if (c == '%') {
060: backslash = !backslash;
061: continue;
062: }
063:
064: switch (token) {
065: case Token.NULL:
066: switch (c) {
067: case '"':
068: doKeyword(line, i, c);
069: if (backslash)
070: backslash = false;
071: else {
072: addToken(i - lastOffset, token);
073: token = Token.LITERAL1;
074: lastOffset = lastKeyword = i;
075: }
076: break;
077: case '\'':
078: doKeyword(line, i, c);
079: if (backslash)
080: backslash = false;
081: else {
082: addToken(i - lastOffset, token);
083: token = Token.LITERAL2;
084: lastOffset = lastKeyword = i;
085: }
086: break;
087: case ':':
088: if (lastKeyword == offset) {
089: if (doKeyword(line, i, c))
090: break;
091: backslash = false;
092: addToken(i1 - lastOffset, Token.LABEL);
093: lastOffset = lastKeyword = i1;
094: } else if (doKeyword(line, i, c))
095: break;
096: break;
097: case '-':
098: backslash = false;
099: doKeyword(line, i, c);
100: if (length - i > 1) {
101: switch (array[i1]) {
102: case '-':
103: addToken(i - lastOffset, token);
104: addToken(length - i, Token.COMMENT1);
105: lastOffset = lastKeyword = length;
106: break loop;
107: }
108: }
109: break;
110: default:
111: backslash = false;
112: if (!Character.isLetterOrDigit(c) && c != '_')
113: doKeyword(line, i, c);
114: break;
115: }
116: break;
117: case Token.COMMENT1:
118: case Token.COMMENT2:
119: throw new RuntimeException("Wrong eiffel parser state");
120: case Token.LITERAL1:
121: if (backslash)
122: backslash = false;
123: else if (c == '"') {
124: addToken(i1 - lastOffset, token);
125: token = Token.NULL;
126: lastOffset = lastKeyword = i1;
127: }
128: break;
129: case Token.LITERAL2:
130: if (backslash)
131: backslash = false;
132: else if (c == '\'') {
133: addToken(i1 - lastOffset, Token.LITERAL1);
134: token = Token.NULL;
135: lastOffset = lastKeyword = i1;
136: }
137: break;
138: default:
139: throw new InternalError("Invalid state: " + token);
140: }
141: }
142:
143: if (token == Token.NULL)
144: doKeyword(line, length, '\0');
145:
146: switch (token) {
147: case Token.LITERAL1:
148: case Token.LITERAL2:
149: addToken(length - lastOffset, Token.INVALID);
150: token = Token.NULL;
151: break;
152: case Token.KEYWORD2:
153: addToken(length - lastOffset, token);
154: if (!backslash)
155: token = Token.NULL;
156: default:
157: addToken(length - lastOffset, token);
158: break;
159: }
160:
161: return token;
162: }
163:
164: public static KeywordMap getKeywords() {
165: if (eiffelKeywords == null) {
166: eiffelKeywords = new KeywordMap(true);
167: eiffelKeywords.add("alias", Token.KEYWORD1);
168: eiffelKeywords.add("all", Token.KEYWORD1);
169: eiffelKeywords.add("and", Token.KEYWORD1);
170: eiffelKeywords.add("as", Token.KEYWORD1);
171: eiffelKeywords.add("check", Token.KEYWORD1);
172: eiffelKeywords.add("class", Token.KEYWORD1);
173: eiffelKeywords.add("creation", Token.KEYWORD1);
174: eiffelKeywords.add("debug", Token.KEYWORD1);
175: eiffelKeywords.add("deferred", Token.KEYWORD1);
176: eiffelKeywords.add("do", Token.KEYWORD1);
177: eiffelKeywords.add("else", Token.KEYWORD1);
178: eiffelKeywords.add("elseif", Token.KEYWORD1);
179: eiffelKeywords.add("end", Token.KEYWORD1);
180: eiffelKeywords.add("ensure", Token.KEYWORD1);
181: eiffelKeywords.add("expanded", Token.KEYWORD1);
182: eiffelKeywords.add("export", Token.KEYWORD1);
183: eiffelKeywords.add("external", Token.KEYWORD1);
184: eiffelKeywords.add("feature", Token.KEYWORD1);
185: eiffelKeywords.add("from", Token.KEYWORD1);
186: eiffelKeywords.add("frozen", Token.KEYWORD1);
187: eiffelKeywords.add("if", Token.KEYWORD1);
188: eiffelKeywords.add("implies", Token.KEYWORD1);
189: eiffelKeywords.add("indexing", Token.KEYWORD1);
190: eiffelKeywords.add("infix", Token.KEYWORD1);
191: eiffelKeywords.add("inherit", Token.KEYWORD1);
192: eiffelKeywords.add("inspect", Token.KEYWORD1);
193: eiffelKeywords.add("invariant", Token.KEYWORD1);
194: eiffelKeywords.add("is", Token.KEYWORD1);
195: eiffelKeywords.add("like", Token.KEYWORD1);
196: eiffelKeywords.add("local", Token.KEYWORD1);
197: eiffelKeywords.add("loop", Token.KEYWORD1);
198: eiffelKeywords.add("not", Token.KEYWORD1);
199: eiffelKeywords.add("obsolete", Token.KEYWORD1);
200: eiffelKeywords.add("old", Token.KEYWORD1);
201: eiffelKeywords.add("once", Token.KEYWORD1);
202: eiffelKeywords.add("or", Token.KEYWORD1);
203: eiffelKeywords.add("prefix", Token.KEYWORD1);
204: eiffelKeywords.add("redefine", Token.KEYWORD1);
205: eiffelKeywords.add("rename", Token.KEYWORD1);
206: eiffelKeywords.add("require", Token.KEYWORD1);
207: eiffelKeywords.add("rescue", Token.KEYWORD1);
208: eiffelKeywords.add("retry", Token.KEYWORD1);
209: eiffelKeywords.add("select", Token.KEYWORD1);
210: eiffelKeywords.add("separate", Token.KEYWORD1);
211: eiffelKeywords.add("then", Token.KEYWORD1);
212: eiffelKeywords.add("undefine", Token.KEYWORD1);
213: eiffelKeywords.add("until", Token.KEYWORD1);
214: eiffelKeywords.add("variant", Token.KEYWORD1);
215: eiffelKeywords.add("when", Token.KEYWORD1);
216: eiffelKeywords.add("xor", Token.KEYWORD1);
217:
218: eiffelKeywords.add("current", Token.LITERAL2);
219: eiffelKeywords.add("false", Token.LITERAL2);
220: eiffelKeywords.add("precursor", Token.LITERAL2);
221: eiffelKeywords.add("result", Token.LITERAL2);
222: eiffelKeywords.add("strip", Token.LITERAL2);
223: eiffelKeywords.add("true", Token.LITERAL2);
224: eiffelKeywords.add("unique", Token.LITERAL2);
225: eiffelKeywords.add("void", Token.LITERAL2);
226:
227: }
228: return eiffelKeywords;
229: }
230:
231: // private members
232: private static KeywordMap eiffelKeywords;
233:
234: private boolean cpp;
235: private KeywordMap keywords;
236: private int lastOffset;
237: private int lastKeyword;
238:
239: private boolean doKeyword(Segment line, int i, char c) {
240: int i1 = i + 1;
241: boolean klassname = false;
242:
243: int len = i - lastKeyword;
244: byte id = keywords.lookup(line, lastKeyword, len);
245: if (id == Token.NULL) {
246: klassname = true;
247: for (int at = lastKeyword; at < lastKeyword + len; at++) {
248: char ch = line.array[at];
249: if (ch != '_' && !Character.isUpperCase(ch)) {
250: klassname = false;
251: break;
252: }
253: }
254: if (klassname)
255: id = Token.KEYWORD3;
256: }
257:
258: if (id != Token.NULL) {
259: if (lastKeyword != lastOffset)
260: addToken(lastKeyword - lastOffset, Token.NULL);
261: addToken(len, id);
262: lastOffset = i;
263: }
264: lastKeyword = i1;
265: return false;
266: }
267: }
|