KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > j > LispTagger


1 /*
2  * LispTagger.java
3  *
4  * Copyright (C) 1998-2004 Peter Graves
5  * $Id: LispTagger.java,v 1.15 2004/04/11 18:34:51 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.j;
23
24 import java.util.ArrayList JavaDoc;
25
26 public final class LispTagger extends Tagger
27 {
28     // States.
29
private static final int NEUTRAL = 0;
30     private static final int OPEN_PAREN = 1;
31     private static final int DEFINITION = 2;
32
33     private static final Mode mode = LispMode.getMode();
34
35     private ArrayList JavaDoc tags;
36
37     public LispTagger(SystemBuffer buffer)
38     {
39         super(buffer);
40     }
41
42     public synchronized void run()
43     {
44         tags = new ArrayList JavaDoc();
45         Position pos = new Position(buffer.getFirstLine(), 0);
46         int state = NEUTRAL;
47         String JavaDoc definer = null;
48         while (!pos.atEnd()) {
49             char c = pos.getChar();
50             if (Character.isWhitespace(c)) {
51                 pos.skipWhitespace();
52                 continue;
53             }
54             if (c == '\\') {
55                 // Escape.
56
if (pos.getOffset() < pos.getLineLength()-1)
57                     pos.skip(2);
58                 else {
59                     Line nextLine = pos.getNextLine();
60                     if (nextLine == null)
61                         break;
62                     pos.moveTo(nextLine, 0);
63                 }
64                 continue;
65             }
66             if (c == '#' && pos.lookingAt("#|")) {
67                 pos.skip(2);
68                 skipComment(pos);
69                 continue;
70             }
71             if (c == '\"') {
72                 pos.skipQuote();
73                 continue;
74             }
75             if (c == ';') {
76                 // Comment.
77
Line nextLine = pos.getNextLine();
78                 if (nextLine == null)
79                     break;
80                 pos.moveTo(nextLine, 0);
81                 continue;
82             }
83             if (c == '(') {
84                 if (state == DEFINITION) {
85                     if (definer != null) {
86                         if (definer.equals("defun")) {
87                             Position tokenStart = pos.copy();
88                             String JavaDoc name = gatherList(pos);
89                             addTag(name, tokenStart, definer);
90                             state = NEUTRAL;
91                             definer = null;
92                             continue;
93                         }
94                         if (definer.equals("defstruct")) {
95                             pos.next();
96                             pos.skipWhitespace();
97                             c = pos.getChar();
98                             if (mode.isIdentifierStart(c)) {
99                                 Position tokenStart = pos.copy();
100                                 String JavaDoc token = gatherToken(pos);
101                                 addTag(token, tokenStart, definer);
102                                 state = NEUTRAL;
103                                 definer = null;
104                                 continue;
105                             }
106                         }
107                     }
108                 }
109                 state = OPEN_PAREN;
110                 pos.next();
111                 continue;
112             }
113             if (mode.isIdentifierStart(c)) {
114                 if (state == DEFINITION) {
115                     Position tokenStart = pos.copy();
116                     String JavaDoc token = gatherToken(pos);
117                     addTag(token, tokenStart, definer);
118                     state = NEUTRAL;
119                     definer = null;
120                     continue;
121                 }
122                 if (state == OPEN_PAREN) {
123                     String JavaDoc preceding =
124                         pos.getLine().substring(0, pos.getOffset()).trim();
125                     if (!preceding.equals("(")) {
126                         state = NEUTRAL;
127                         continue;
128                     }
129                     String JavaDoc token = gatherToken(pos).toLowerCase();
130                     token = LispMode.translateDefiner(token);
131                     if (token != null) {
132                         state = DEFINITION;
133                         definer = token;
134                     } else
135                         state = NEUTRAL;
136                     continue;
137                 }
138                 skipToken(pos);
139                 continue;
140             }
141             state = NEUTRAL;
142             pos.next();
143         }
144         buffer.setTags(tags);
145     }
146
147     private void addTag(String JavaDoc name, Position pos, String JavaDoc definer)
148     {
149         int type = -1;
150         if (definer.equals("defclass"))
151             type = TAG_CLASS;
152         else if (definer.equals("defconstant"))
153             type = TAG_CONSTANT;
154         else if (definer.equals("defgeneric"))
155             type = TAG_GENERIC_FUNCTION;
156         else if (definer.equals("define-condition"))
157             type = TAG_CONDITION;
158         else if (definer.equals("defmacro"))
159             type = TAG_MACRO;
160         else if (definer.equals("defmethod"))
161             type = TAG_METHOD;
162         else if (definer.equals("defparameter"))
163             type = TAG_PARAMETER;
164         else if (definer.equals("defstruct"))
165             type = TAG_STRUCT;
166         else if (definer.equals("deftype"))
167             type = TAG_TYPE;
168         else if (definer.equals("defun"))
169             type = TAG_DEFUN;
170         else if (definer.equals("defvar"))
171             type = TAG_VAR;
172         else
173             Debug.bug();
174         tags.add(new LispTag(name, pos, type));
175     }
176
177     // Advances pos past list.
178
private String JavaDoc gatherList(Position pos)
179     {
180         FastStringBuffer sb = new FastStringBuffer();
181         char c = pos.getChar();
182         Debug.bugIf(c != '(');
183         if (pos.next()) {
184             while ((c = pos.getChar()) != ')') {
185                 sb.append(c);
186                 if (!pos.next())
187                     break;
188             }
189         }
190         return sb.toString();
191     }
192
193     // Advances pos past token.
194
private String JavaDoc gatherToken(Position pos)
195     {
196         FastStringBuffer sb = new FastStringBuffer();
197         char c;
198         while (mode.isIdentifierPart(c = pos.getChar()) || c == ':') {
199             sb.append(c);
200             if (!pos.next())
201                 break;
202         }
203         return sb.toString();
204     }
205
206     // Advances pos past token.
207
private void skipToken(Position pos)
208     {
209         while (mode.isIdentifierPart(pos.getChar())) {
210             if (!pos.next())
211                 return;
212         }
213     }
214
215     private void skipComment(Position pos)
216     {
217         while (!pos.atEnd()) {
218             char c = pos.getChar();
219             if (c == '\\') {
220                 // Escape.
221
if (pos.getOffset() < pos.getLineLength()-1)
222                     pos.skip(2);
223                 else {
224                     Line nextLine = pos.getNextLine();
225                     if (nextLine == null)
226                         break;
227                     pos.moveTo(nextLine, 0);
228                 }
229                 continue;
230             }
231             if (c == '|' && pos.lookingAt("|#")) {
232                 pos.skip(2);
233                 return;
234             }
235             pos.next();
236         }
237     }
238 }
239
Popular Tags