1
2
3
4
5
6
7
8
9
10
11 package org.syntax.jedit.tokenmarker;
12
13 import javax.swing.text.Segment;
14
15 import org.syntax.jedit.KeywordMap;
16
17 /***
18 * Eiffel token Marker.
19 *
20 * @author Artur Biesiadowski
21 */
22 public class EiffelTokenMarker extends TokenMarker
23 {
24
25 public EiffelTokenMarker()
26 {
27 this.keywords = getKeywords();
28 }
29
30 public byte markTokensImpl(byte token, Segment line, int lineIndex)
31 {
32 char[] array = line.array;
33 int offset = line.offset;
34 lastOffset = offset;
35 lastKeyword = offset;
36 int length = line.count + offset;
37 boolean backslash = false;
38
39 loop: for(int i = offset; i < length; i++)
40 {
41 int i1 = (i+1);
42
43 char c = array[i];
44 if(c == '%')
45 {
46 backslash = !backslash;
47 continue;
48 }
49
50 switch(token)
51 {
52 case Token.NULL:
53 switch(c)
54 {
55 case '"':
56 doKeyword(line,i,c);
57 if(backslash)
58 backslash = false;
59 else
60 {
61 addToken(i - lastOffset,token);
62 token = Token.LITERAL1;
63 lastOffset = lastKeyword = i;
64 }
65 break;
66 case '\'':
67 doKeyword(line,i,c);
68 if(backslash)
69 backslash = false;
70 else
71 {
72 addToken(i - lastOffset,token);
73 token = Token.LITERAL2;
74 lastOffset = lastKeyword = i;
75 }
76 break;
77 case ':':
78 if(lastKeyword == offset)
79 {
80 if(doKeyword(line,i,c))
81 break;
82 backslash = false;
83 addToken(i1 - lastOffset,Token.LABEL);
84 lastOffset = lastKeyword = i1;
85 }
86 else if(doKeyword(line,i,c))
87 break;
88 break;
89 case '-':
90 backslash = false;
91 doKeyword(line,i,c);
92 if(length - i > 1)
93 {
94 switch(array[i1])
95 {
96 case '-':
97 addToken(i - lastOffset,token);
98 addToken(length - i,Token.COMMENT1);
99 lastOffset = lastKeyword = length;
100 break loop;
101 }
102 }
103 break;
104 default:
105 backslash = false;
106 if(!Character.isLetterOrDigit(c)
107 && c != '_')
108 doKeyword(line,i,c);
109 break;
110 }
111 break;
112 case Token.COMMENT1:
113 case Token.COMMENT2:
114 throw new RuntimeException("Wrong eiffel parser state");
115 case Token.LITERAL1:
116 if(backslash)
117 backslash = false;
118 else if(c == '"')
119 {
120 addToken(i1 - lastOffset,token);
121 token = Token.NULL;
122 lastOffset = lastKeyword = i1;
123 }
124 break;
125 case Token.LITERAL2:
126 if(backslash)
127 backslash = false;
128 else if(c == '\'')
129 {
130 addToken(i1 - lastOffset,Token.LITERAL1);
131 token = Token.NULL;
132 lastOffset = lastKeyword = i1;
133 }
134 break;
135 default:
136 throw new InternalError("Invalid state: "
137 + token);
138 }
139 }
140
141 if(token == Token.NULL)
142 doKeyword(line,length,'\0');
143
144 switch(token)
145 {
146 case Token.LITERAL1:
147 case Token.LITERAL2:
148 addToken(length - lastOffset,Token.INVALID);
149 token = Token.NULL;
150 break;
151 case Token.KEYWORD2:
152 addToken(length - lastOffset,token);
153 if(!backslash)
154 token = Token.NULL;
155 default:
156 addToken(length - lastOffset,token);
157 break;
158 }
159
160 return token;
161 }
162
163 public static KeywordMap getKeywords()
164 {
165 if(eiffelKeywords == null)
166 {
167 eiffelKeywords = new KeywordMap(true);
168 eiffelKeywords.add("alias", Token.KEYWORD1);
169 eiffelKeywords.add("all", Token.KEYWORD1);
170 eiffelKeywords.add("and", Token.KEYWORD1);
171 eiffelKeywords.add("as", Token.KEYWORD1);
172 eiffelKeywords.add("check", Token.KEYWORD1);
173 eiffelKeywords.add("class", Token.KEYWORD1);
174 eiffelKeywords.add("creation", Token.KEYWORD1);
175 eiffelKeywords.add("debug", Token.KEYWORD1);
176 eiffelKeywords.add("deferred", Token.KEYWORD1);
177 eiffelKeywords.add("do", Token.KEYWORD1);
178 eiffelKeywords.add("else",Token.KEYWORD1);
179 eiffelKeywords.add("elseif", Token.KEYWORD1);
180 eiffelKeywords.add("end", Token.KEYWORD1);
181 eiffelKeywords.add("ensure", Token.KEYWORD1);
182 eiffelKeywords.add("expanded", Token.KEYWORD1);
183 eiffelKeywords.add("export", Token.KEYWORD1);
184 eiffelKeywords.add("external", Token.KEYWORD1);
185 eiffelKeywords.add("feature", Token.KEYWORD1);
186 eiffelKeywords.add("from", Token.KEYWORD1);
187 eiffelKeywords.add("frozen", Token.KEYWORD1);
188 eiffelKeywords.add("if", Token.KEYWORD1);
189 eiffelKeywords.add("implies",Token.KEYWORD1);
190 eiffelKeywords.add("indexing", Token.KEYWORD1);
191 eiffelKeywords.add("infix", Token.KEYWORD1);
192 eiffelKeywords.add("inherit", Token.KEYWORD1);
193 eiffelKeywords.add("inspect", Token.KEYWORD1);
194 eiffelKeywords.add("invariant", Token.KEYWORD1);
195 eiffelKeywords.add("is", Token.KEYWORD1);
196 eiffelKeywords.add("like", Token.KEYWORD1);
197 eiffelKeywords.add("local", Token.KEYWORD1);
198 eiffelKeywords.add("loop", Token.KEYWORD1);
199 eiffelKeywords.add("not", Token.KEYWORD1);
200 eiffelKeywords.add("obsolete", Token.KEYWORD1);
201 eiffelKeywords.add("old",Token.KEYWORD1);
202 eiffelKeywords.add("once", Token.KEYWORD1);
203 eiffelKeywords.add("or", Token.KEYWORD1);
204 eiffelKeywords.add("prefix", Token.KEYWORD1);
205 eiffelKeywords.add("redefine", Token.KEYWORD1);
206 eiffelKeywords.add("rename", Token.KEYWORD1);
207 eiffelKeywords.add("require", Token.KEYWORD1);
208 eiffelKeywords.add("rescue", Token.KEYWORD1);
209 eiffelKeywords.add("retry", Token.KEYWORD1);
210 eiffelKeywords.add("select", Token.KEYWORD1);
211 eiffelKeywords.add("separate", Token.KEYWORD1);
212 eiffelKeywords.add("then",Token.KEYWORD1);
213 eiffelKeywords.add("undefine", Token.KEYWORD1);
214 eiffelKeywords.add("until", Token.KEYWORD1);
215 eiffelKeywords.add("variant", Token.KEYWORD1);
216 eiffelKeywords.add("when", Token.KEYWORD1);
217 eiffelKeywords.add("xor", Token.KEYWORD1);
218
219 eiffelKeywords.add("current",Token.LITERAL2);
220 eiffelKeywords.add("false",Token.LITERAL2);
221 eiffelKeywords.add("precursor",Token.LITERAL2);
222 eiffelKeywords.add("result",Token.LITERAL2);
223 eiffelKeywords.add("strip",Token.LITERAL2);
224 eiffelKeywords.add("true",Token.LITERAL2);
225 eiffelKeywords.add("unique",Token.LITERAL2);
226 eiffelKeywords.add("void",Token.LITERAL2);
227
228 }
229 return eiffelKeywords;
230 }
231
232
233 private static KeywordMap eiffelKeywords;
234
235 private boolean cpp;
236 private KeywordMap keywords;
237 private int lastOffset;
238 private int lastKeyword;
239
240 private boolean doKeyword(Segment line, int i, char c)
241 {
242 int i1 = i+1;
243 boolean klassname = false;
244
245 int len = i - lastKeyword;
246 byte id = keywords.lookup(line,lastKeyword,len);
247 if ( id == Token.NULL )
248 {
249 klassname = true;
250 for ( int at = lastKeyword; at < lastKeyword + len; at++ )
251 {
252 char ch = line.array[at];
253 if ( ch != '_' && !Character.isUpperCase(ch) )
254 {
255 klassname = false;
256 break;
257 }
258 }
259 if ( klassname )
260 id = Token.KEYWORD3;
261 }
262
263 if(id != Token.NULL)
264 {
265 if(lastKeyword != lastOffset)
266 addToken(lastKeyword - lastOffset,Token.NULL);
267 addToken(len,id);
268 lastOffset = i;
269 }
270 lastKeyword = i1;
271 return false;
272 }
273 }