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 import org.syntax.jedit.SyntaxUtilities;
17
18 /***
19 * PHP token marker.
20 *
21 * @author Clancy Malcolm
22 * @version $Id: PHPTokenMarker.java,v 1.1 1999/12/14 04:20:35 sp Exp $
23 */
24 public class PHPTokenMarker extends TokenMarker
25 {
26 public static final byte SCRIPT = Token.INTERNAL_FIRST;
27
28 public byte markTokensImpl(byte token, Segment line, int lineIndex)
29 {
30 char[] array = line.array;
31 int offset = line.offset;
32 lastOffset = offset;
33 lastKeyword = offset;
34 int length = line.count + offset;
35 boolean backslash = false;
36
37 loop: for(int i = offset; i < length; i++)
38 {
39 int i1 = (i+1);
40
41 char c = array[i];
42 if(c == '//')
43 {
44 backslash = !backslash;
45 continue;
46 }
47
48 switch(token)
49 {
50 case Token.NULL:
51 backslash = false;
52 switch(c)
53 {
54 case '<':
55 addToken(i - lastOffset,token);
56 lastOffset = lastKeyword = i;
57 if(SyntaxUtilities.regionMatches(false,
58 line,i1,"!--"))
59 {
60 i += 3;
61 token = Token.COMMENT1;
62 }
63 else if(SyntaxUtilities.regionMatches(
64 true,line,i1,"?php"))
65 {
66 addToken(5,Token.LABEL);
67 lastOffset = lastKeyword = (i += 4) + 1;
68 token = SCRIPT;
69 }
70 else if(SyntaxUtilities.regionMatches(
71 true,line,i1,"?"))
72 {
73 addToken(2,Token.LABEL);
74 lastOffset = lastKeyword = (i += 1) + 1;
75 token = SCRIPT;
76 }
77 else if(SyntaxUtilities.regionMatches(
78 true,line,i1,"script>"))
79 {
80 addToken(8,Token.LABEL);
81 lastOffset = lastKeyword = (i += 7) + 1;
82 token = SCRIPT;
83 }
84 else
85 {
86 token = Token.KEYWORD1;
87 }
88 break;
89 case '&':
90 addToken(i - lastOffset,token);
91 lastOffset = lastKeyword = i;
92 token = Token.KEYWORD2;
93 break;
94 }
95 break;
96 case Token.KEYWORD1:
97 backslash = false;
98 if(c == '>')
99 {
100 addToken(i1 - lastOffset,token);
101 lastOffset = lastKeyword = i1;
102 token = Token.NULL;
103 }
104 break;
105 case Token.KEYWORD2:
106 backslash = false;
107 if(c == ';')
108 {
109 addToken(i1 - lastOffset,token);
110 lastOffset = lastKeyword = i1;
111 token = Token.NULL;
112 break;
113 }
114 break;
115 case Token.COMMENT1:
116 backslash = false;
117 if(SyntaxUtilities.regionMatches(false,line,i,"-->"))
118 {
119 addToken(i + 3 - lastOffset,token);
120 i += 2;
121 lastOffset = lastKeyword = i + 1;
122 token = Token.NULL;
123 }
124 break;
125 case SCRIPT:
126 switch(c)
127 {
128 case '<':
129 backslash = false;
130 doKeyword(line,i,c);
131 if(SyntaxUtilities.regionMatches(true,
132 line,i1,"/script>"))
133 {
134
135 addToken(i - lastOffset,
136 Token.KEYWORD3);
137 addToken(9,Token.LABEL);
138 lastOffset = lastKeyword = (i += 8) + 1;
139 token = Token.NULL;
140 }
141 else
142 {
143
144 addToken(i - lastOffset,
145 Token.KEYWORD3);
146 addToken(1,Token.OPERATOR);
147 lastOffset = lastKeyword = i1;
148 }
149 break;
150 case '?':
151 backslash = false;
152 doKeyword(line, i, c);
153 if (array[i1] == '>')
154 {
155
156 addToken(i - lastOffset,
157 Token.KEYWORD3);
158 addToken(2,Token.LABEL);
159 lastOffset = lastKeyword = (i += 1) + 1;
160 token = Token.NULL;
161 }
162 else
163 {
164
165 addToken(i - lastOffset, Token.KEYWORD3);
166 addToken(1,Token.OPERATOR);
167 lastOffset = lastKeyword = i1;
168 }
169 break;
170 case '"':
171 if(backslash)
172 backslash = false;
173 else
174 {
175 doKeyword(line,i,c);
176 addToken(i - lastOffset,Token.KEYWORD3);
177 lastOffset = lastKeyword = i;
178 token = Token.LITERAL1;
179 }
180 break;
181 case '\'':
182 if(backslash)
183 backslash = false;
184 else
185 {
186 doKeyword(line,i,c);
187 addToken(i - lastOffset,Token.KEYWORD3);
188 lastOffset = lastKeyword = i;
189 token = Token.LITERAL2;
190 }
191 break;
192 case '#':
193 doKeyword(line,i,c);
194 addToken(i - lastOffset,Token.KEYWORD3);
195 addToken(length - i,Token.COMMENT2);
196 lastOffset = lastKeyword = length;
197 break loop;
198 case '/':
199 backslash = false;
200 doKeyword(line,i,c);
201 if(length - i > 1)
202 {
203 addToken(i - lastOffset,Token.KEYWORD3);
204 lastOffset = lastKeyword = i;
205 if(array[i1] == '/')
206 {
207 addToken(length - i,Token.COMMENT2);
208 lastOffset = lastKeyword = length;
209 break loop;
210 }
211 else if(array[i1] == '*')
212 {
213 token = Token.COMMENT2;
214 }
215 else
216 {
217
218 addToken(i - lastOffset, Token.KEYWORD3);
219 addToken(1,Token.OPERATOR);
220 lastOffset = lastKeyword = i1;
221 }
222 }
223 else
224 {
225
226 addToken(i - lastOffset, Token.KEYWORD3);
227 addToken(1,Token.OPERATOR);
228 lastOffset = lastKeyword = i1;
229 }
230 break;
231 default:
232 backslash = false;
233 if(!Character.isLetterOrDigit(c)
234 && c != '_' && c != '$')
235 {
236 doKeyword(line,i,c);
237 if (c != ' ')
238 {
239
240 addToken(i - lastOffset, Token.KEYWORD3);
241 addToken(1,Token.OPERATOR);
242 lastOffset = lastKeyword = i1;
243 }
244 }
245 break;
246 }
247 break;
248 case Token.LITERAL1:
249 if(backslash)
250 backslash = false;
251 else if(c == '"')
252 {
253 addToken(i1 - lastOffset,Token.LITERAL1);
254 lastOffset = lastKeyword = i1;
255 token = SCRIPT;
256 }
257 break;
258 case Token.LITERAL2:
259 if(backslash)
260 backslash = false;
261 else if(c == '\'')
262 {
263 addToken(i1 - lastOffset,Token.LITERAL1);
264 lastOffset = lastKeyword = i1;
265 token = SCRIPT;
266 }
267 break;
268 case Token.COMMENT2:
269 backslash = false;
270 if(c == '*' && length - i > 1 && array[i1] == '/')
271 {
272 addToken(i + 2 - lastOffset,Token.COMMENT2);
273 i += 1;
274 lastOffset = lastKeyword = i + 1;
275 token = SCRIPT;
276 }
277 break;
278 default:
279 throw new InternalError("Invalid state: "
280 + token);
281 }
282 }
283
284 switch(token)
285 {
286 case Token.LITERAL1:
287 addToken(length - lastOffset,Token.LITERAL1);
288 break;
289 case Token.LITERAL2:
290 addToken(length - lastOffset,Token.LITERAL2);
291 break;
292 case Token.KEYWORD2:
293 addToken(length - lastOffset,Token.INVALID);
294 token = Token.NULL;
295 break;
296 case SCRIPT:
297 doKeyword(line,length,'\0');
298 addToken(length - lastOffset,Token.KEYWORD3);
299 break;
300 default:
301 addToken(length - lastOffset,token);
302 break;
303 }
304
305 return token;
306 }
307
308
309 private static KeywordMap keywords;
310 private int lastOffset;
311 private int lastKeyword;
312
313 static
314 {
315 keywords = new KeywordMap(false);
316 keywords.add("function",Token.KEYWORD2);
317 keywords.add("class",Token.KEYWORD2);
318 keywords.add("var",Token.KEYWORD2);
319 keywords.add("require",Token.KEYWORD2);
320 keywords.add("include",Token.KEYWORD2);
321 keywords.add("else",Token.KEYWORD1);
322 keywords.add("elseif",Token.KEYWORD1);
323 keywords.add("do",Token.KEYWORD1);
324 keywords.add("for",Token.KEYWORD1);
325 keywords.add("if",Token.KEYWORD1);
326 keywords.add("endif",Token.KEYWORD1);
327 keywords.add("in",Token.KEYWORD1);
328 keywords.add("new",Token.KEYWORD1);
329 keywords.add("return",Token.KEYWORD1);
330 keywords.add("while",Token.KEYWORD1);
331 keywords.add("endwhile",Token.KEYWORD1);
332 keywords.add("with",Token.KEYWORD1);
333 keywords.add("break",Token.KEYWORD1);
334 keywords.add("switch",Token.KEYWORD1);
335 keywords.add("case",Token.KEYWORD1);
336 keywords.add("continue",Token.KEYWORD1);
337 keywords.add("default",Token.KEYWORD1);
338 keywords.add("echo",Token.KEYWORD1);
339 keywords.add("false",Token.KEYWORD1);
340 keywords.add("this",Token.KEYWORD1);
341 keywords.add("true",Token.KEYWORD1);
342 keywords.add("array",Token.KEYWORD1);
343 keywords.add("extends",Token.KEYWORD1);
344 }
345
346 private boolean doKeyword(Segment line, int i, char c)
347 {
348 int i1 = i+1;
349
350 int len = i - lastKeyword;
351 byte id = keywords.lookup(line,lastKeyword,len);
352 if(id != Token.NULL)
353 {
354 if(lastKeyword != lastOffset)
355 addToken(lastKeyword - lastOffset,Token.KEYWORD3);
356 addToken(len,id);
357 lastOffset = i;
358 }
359 lastKeyword = i1;
360 return false;
361 }
362 }