Statistics
| Revision:

root / trunk / libraries / libIverUtiles / src / com / iver / utiles / console / jedit / EiffelTokenMarker.java @ 4890

History | View | Annotate | Download (6.9 KB)

1
package com.iver.utiles.console.jedit;
2
/*
3
 * EiffelTokenMarker.java - Eiffel token marker
4
 * Copyright (C) 1999 Slava Pestov
5
 * Copyright (C) 1999 Artur Biesiadowski
6
 *
7
 * You may use and modify this package for any purpose. Redistribution is
8
 * permitted, in both source and binary form, provided that this notice
9
 * remains intact in all source distributions of this package.
10
 */
11

    
12
import javax.swing.text.Segment;
13

    
14
/**
15
 * Eiffel token Marker.
16
 *
17
 * @author Artur Biesiadowski
18
 */
19
public class EiffelTokenMarker extends TokenMarker
20
{
21

    
22
        public EiffelTokenMarker()
23
        {
24
                this.keywords = getKeywords();
25
        }
26

    
27
        public byte markTokensImpl(byte token, Segment line, int lineIndex)
28
        {
29
                char[] array = line.array;
30
                int offset = line.offset;
31
                lastOffset = offset;
32
                lastKeyword = offset;
33
                int length = line.count + offset;
34
                boolean backslash = false;
35

    
36
loop:                for(int i = offset; i < length; i++)
37
                {
38
                        int i1 = (i+1);
39

    
40
                        char c = array[i];
41
                        if(c == '%')
42
                        {
43
                                backslash = !backslash;
44
                                continue;
45
                        }
46

    
47
                        switch(token)
48
                        {
49
                        case Token.NULL:
50
                                switch(c)
51
                                {
52
                                case '"':
53
                                        doKeyword(line,i,c);
54
                                        if(backslash)
55
                                                backslash = false;
56
                                        else
57
                                        {
58
                                                addToken(i - lastOffset,token);
59
                                                token = Token.LITERAL1;
60
                                                lastOffset = lastKeyword = i;
61
                                        }
62
                                        break;
63
                                case '\'':
64
                                        doKeyword(line,i,c);
65
                                        if(backslash)
66
                                                backslash = false;
67
                                        else
68
                                        {
69
                                                addToken(i - lastOffset,token);
70
                                                token = Token.LITERAL2;
71
                                                lastOffset = lastKeyword = i;
72
                                        }
73
                                        break;
74
                                case ':':
75
                                        if(lastKeyword == offset)
76
                                        {
77
                                                if(doKeyword(line,i,c))
78
                                                        break;
79
                                                backslash = false;
80
                                                addToken(i1 - lastOffset,Token.LABEL);
81
                                                lastOffset = lastKeyword = i1;
82
                                        }
83
                                        else if(doKeyword(line,i,c))
84
                                                break;
85
                                        break;
86
                                case '-':
87
                                        backslash = false;
88
                                        doKeyword(line,i,c);
89
                                        if(length - i > 1)
90
                                        {
91
                                                switch(array[i1])
92
                                                {
93
                                                case '-':
94
                                                        addToken(i - lastOffset,token);
95
                                                        addToken(length - i,Token.COMMENT1);
96
                                                        lastOffset = lastKeyword = length;
97
                                                        break loop;
98
                                                }
99
                                        }
100
                                        break;
101
                                default:
102
                                        backslash = false;
103
                                        if(!Character.isLetterOrDigit(c)
104
                                                && c != '_')
105
                                                doKeyword(line,i,c);
106
                                        break;
107
                                }
108
                                break;
109
                        case Token.COMMENT1:
110
                        case Token.COMMENT2:
111
                                throw new RuntimeException("Wrong eiffel parser state");
112
                        case Token.LITERAL1:
113
                                if(backslash)
114
                                        backslash = false;
115
                                else if(c == '"')
116
                                {
117
                                        addToken(i1 - lastOffset,token);
118
                                        token = Token.NULL;
119
                                        lastOffset = lastKeyword = i1;
120
                                }
121
                                break;
122
                        case Token.LITERAL2:
123
                                if(backslash)
124
                                        backslash = false;
125
                                else if(c == '\'')
126
                                {
127
                                        addToken(i1 - lastOffset,Token.LITERAL1);
128
                                        token = Token.NULL;
129
                                        lastOffset = lastKeyword = i1;
130
                                }
131
                                break;
132
                        default:
133
                                throw new InternalError("Invalid state: "
134
                                        + token);
135
                        }
136
                }
137

    
138
                if(token == Token.NULL)
139
                        doKeyword(line,length,'\0');
140

    
141
                switch(token)
142
                {
143
                case Token.LITERAL1:
144
                case Token.LITERAL2:
145
                        addToken(length - lastOffset,Token.INVALID);
146
                        token = Token.NULL;
147
                        break;
148
                case Token.KEYWORD2:
149
                        addToken(length - lastOffset,token);
150
                        if(!backslash)
151
                                token = Token.NULL;
152
                default:
153
                        addToken(length - lastOffset,token);
154
                        break;
155
                }
156

    
157
                return token;
158
        }
159

    
160
        public static KeywordMap getKeywords()
161
        {
162
                if(eiffelKeywords == null)
163
                {
164
                        eiffelKeywords = new KeywordMap(true);
165
                        eiffelKeywords.add("alias", Token.KEYWORD1);
166
                        eiffelKeywords.add("all", Token.KEYWORD1);
167
                        eiffelKeywords.add("and", Token.KEYWORD1);
168
                        eiffelKeywords.add("as", Token.KEYWORD1);
169
                        eiffelKeywords.add("check", Token.KEYWORD1);
170
                        eiffelKeywords.add("class", Token.KEYWORD1);
171
                        eiffelKeywords.add("creation", Token.KEYWORD1);
172
                        eiffelKeywords.add("debug", Token.KEYWORD1);
173
                        eiffelKeywords.add("deferred", Token.KEYWORD1);
174
                        eiffelKeywords.add("do", Token.KEYWORD1);
175
                        eiffelKeywords.add("else",Token.KEYWORD1);
176
                        eiffelKeywords.add("elseif", Token.KEYWORD1);
177
                        eiffelKeywords.add("end", Token.KEYWORD1);
178
                        eiffelKeywords.add("ensure", Token.KEYWORD1);
179
                        eiffelKeywords.add("expanded", Token.KEYWORD1);
180
                        eiffelKeywords.add("export", Token.KEYWORD1);
181
                        eiffelKeywords.add("external", Token.KEYWORD1);
182
                        eiffelKeywords.add("feature", Token.KEYWORD1);
183
                        eiffelKeywords.add("from", Token.KEYWORD1);
184
                        eiffelKeywords.add("frozen", Token.KEYWORD1);
185
                        eiffelKeywords.add("if", Token.KEYWORD1);
186
                        eiffelKeywords.add("implies",Token.KEYWORD1);
187
                        eiffelKeywords.add("indexing", Token.KEYWORD1);
188
                        eiffelKeywords.add("infix", Token.KEYWORD1);
189
                        eiffelKeywords.add("inherit", Token.KEYWORD1);
190
                        eiffelKeywords.add("inspect", Token.KEYWORD1);
191
                        eiffelKeywords.add("invariant", Token.KEYWORD1);
192
                        eiffelKeywords.add("is", Token.KEYWORD1);
193
                        eiffelKeywords.add("like", Token.KEYWORD1);
194
                        eiffelKeywords.add("local", Token.KEYWORD1);
195
                        eiffelKeywords.add("loop", Token.KEYWORD1);
196
                        eiffelKeywords.add("not", Token.KEYWORD1);
197
                        eiffelKeywords.add("obsolete", Token.KEYWORD1);
198
                        eiffelKeywords.add("old",Token.KEYWORD1);
199
                        eiffelKeywords.add("once", Token.KEYWORD1);
200
                        eiffelKeywords.add("or", Token.KEYWORD1);
201
                        eiffelKeywords.add("prefix", Token.KEYWORD1);
202
                        eiffelKeywords.add("redefine", Token.KEYWORD1);
203
                        eiffelKeywords.add("rename", Token.KEYWORD1);
204
                        eiffelKeywords.add("require", Token.KEYWORD1);
205
                        eiffelKeywords.add("rescue", Token.KEYWORD1);
206
                        eiffelKeywords.add("retry", Token.KEYWORD1);
207
                        eiffelKeywords.add("select", Token.KEYWORD1);
208
                        eiffelKeywords.add("separate", Token.KEYWORD1);
209
                        eiffelKeywords.add("then",Token.KEYWORD1);
210
                        eiffelKeywords.add("undefine", Token.KEYWORD1);
211
                        eiffelKeywords.add("until", Token.KEYWORD1);
212
                        eiffelKeywords.add("variant", Token.KEYWORD1);
213
                        eiffelKeywords.add("when", Token.KEYWORD1);
214
                        eiffelKeywords.add("xor", Token.KEYWORD1);
215

    
216
                        eiffelKeywords.add("current",Token.LITERAL2);
217
                        eiffelKeywords.add("false",Token.LITERAL2);
218
                        eiffelKeywords.add("precursor",Token.LITERAL2);
219
                        eiffelKeywords.add("result",Token.LITERAL2);
220
                        eiffelKeywords.add("strip",Token.LITERAL2);
221
                        eiffelKeywords.add("true",Token.LITERAL2);
222
                        eiffelKeywords.add("unique",Token.LITERAL2);
223
                        eiffelKeywords.add("void",Token.LITERAL2);
224

    
225
                }
226
                return eiffelKeywords;
227
        }
228

    
229
        // private members
230
        private static KeywordMap eiffelKeywords;
231

    
232
        private boolean cpp;
233
        private KeywordMap keywords;
234
        private int lastOffset;
235
        private int lastKeyword;
236

    
237
        private boolean doKeyword(Segment line, int i, char c)
238
        {
239
                int i1 = i+1;
240
                boolean klassname = false;
241

    
242
                int len = i - lastKeyword;
243
                byte id = keywords.lookup(line,lastKeyword,len);
244
                if ( id == Token.NULL )
245
                {
246
                        klassname = true;
247
                        for ( int at = lastKeyword; at < lastKeyword + len; at++ )
248
                        {
249
                                char ch = line.array[at];
250
                                if ( ch != '_' && !Character.isUpperCase(ch) )
251
                                {
252
                                        klassname = false;
253
                                        break;
254
                                }
255
                        }
256
                        if ( klassname )
257
                                id = Token.KEYWORD3;
258
                }
259

    
260
                if(id != Token.NULL)
261
                {
262
                        if(lastKeyword != lastOffset)
263
                                addToken(lastKeyword - lastOffset,Token.NULL);
264
                        addToken(len,id);
265
                        lastOffset = i;
266
                }
267
                lastKeyword = i1;
268
                return false;
269
        }
270
}