KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * VHDLFormatter.java
3  *
4  * Copyright (C) 2002 Peter Graves
5  * $Id: VHDLFormatter.java,v 1.1.1.1 2002/09/24 16:09:20 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.HashSet JavaDoc;
25
26 public final class VHDLFormatter extends Formatter implements Constants
27 {
28     private static final int VHDL_FORMAT_TEXT = 0;
29     private static final int VHDL_FORMAT_COMMENT = 1;
30     private static final int VHDL_FORMAT_STRING = 2;
31     private static final int VHDL_FORMAT_IDENTIFIER = 3;
32     private static final int VHDL_FORMAT_KEYWORD = 4;
33     private static final int VHDL_FORMAT_TYPE = 5;
34     private static final int VHDL_FORMAT_FUNCTION = 6;
35     private static final int VHDL_FORMAT_OPERATOR = 7;
36     private static final int VHDL_FORMAT_NUMBER = 8;
37
38     private static final VHDLMode mode = VHDLMode.getMode();
39
40     public VHDLFormatter(Buffer buffer)
41     {
42         this.buffer = buffer;
43     }
44
45     private int tokenBegin = 0;
46
47     private void endToken(String JavaDoc text, int tokenEnd, int state)
48     {
49         if (tokenEnd - tokenBegin > 0) {
50             int format = VHDL_FORMAT_TEXT;
51             switch (state) {
52                 case STATE_NEUTRAL:
53                     format = VHDL_FORMAT_TEXT;
54                     break;
55                 case STATE_QUOTE:
56                     format = VHDL_FORMAT_STRING;
57                     break;
58                 case STATE_IDENTIFIER:
59                     format = VHDL_FORMAT_IDENTIFIER;
60                     break;
61                 case STATE_COMMENT:
62                     format = VHDL_FORMAT_COMMENT;
63                     break;
64                 case STATE_OPERATOR:
65                     format = VHDL_FORMAT_OPERATOR;
66                     break;
67                 case STATE_NUMBER:
68                     format = VHDL_FORMAT_NUMBER;
69                     break;
70             }
71             addSegment(text, tokenBegin, tokenEnd, format);
72             tokenBegin = tokenEnd;
73         }
74     }
75
76     private void parseLine(Line line)
77     {
78         if (line == null) {
79             addSegment("", VHDL_FORMAT_TEXT);
80             return;
81         }
82         String JavaDoc text;
83         if (Editor.tabsAreVisible())
84             text = Utilities.makeTabsVisible(line.getText(), buffer.getTabWidth());
85         else
86             text = Utilities.detab(line.getText(), buffer.getTabWidth());
87         tokenBegin = 0;
88         int state = STATE_NEUTRAL;
89         int i = 0;
90         final int limit = text.length();
91         // Skip whitespace at start of line.
92
while (i < limit) {
93             if (Character.isWhitespace(text.charAt(i))) {
94                 ++i;
95             } else {
96                 endToken(text, i, state);
97                 break;
98             }
99         }
100         while (i < limit) {
101             char c = text.charAt(i);
102             if (state == STATE_QUOTE) {
103                 if (c == '"') {
104                     endToken(text, i+1, state);
105                     state = STATE_NEUTRAL;
106                 } else if (c == '\\' && i < limit-1) {
107                     // Escape char.
108
++i;
109                 }
110                 ++i;
111                 continue;
112             }
113             // Reaching here, we're not in a comment or a quoted string.
114
if (c == '"') {
115                 endToken(text, i, state);
116                 state = STATE_QUOTE;
117                 ++i;
118                 continue;
119             }
120             if (c == '-') {
121                 if (i < limit-1) {
122                     if (text.charAt(i+1) == '-') {
123                         endToken(text, i, state);
124                         endToken(text, limit, STATE_COMMENT);
125                         return;
126                     } else
127                         ++i;
128                 } else
129                     ++i;
130                 continue;
131             }
132             if (isOperatorChar(c)) {
133                 if (state != STATE_OPERATOR) {
134                     endToken(text, i, state);
135                     // Check for keyword.
136
final LineSegment segment = getLastSegment();
137                     if (segment != null) {
138                         final String JavaDoc segmentText = segment.getText();
139                         if (isKeyword(segmentText))
140                             segment.setFormat(VHDL_FORMAT_KEYWORD);
141                         else if (isType(segmentText))
142                             segment.setFormat(VHDL_FORMAT_TYPE);
143                     }
144                     state = STATE_OPERATOR;
145                 }
146                 ++i;
147                 continue;
148             }
149             if (state == STATE_OPERATOR) {
150                 if (mode.isIdentifierStart(c)) {
151                     endToken(text, i, state);
152                     state = STATE_IDENTIFIER;
153                 } else if (Character.isDigit(c)) {
154                     endToken(text, i, state);
155                     state = STATE_NUMBER;
156                 } else {
157                     endToken(text, i, state);
158                     state = STATE_NEUTRAL;
159                 }
160                 ++i;
161                 continue;
162             }
163             if (state == STATE_IDENTIFIER) {
164                 if (!mode.isIdentifierPart(c)) {
165                     endToken(text, i, state);
166                     // Check for keyword or function.
167
final LineSegment segment = getLastSegment();
168                     if (segment != null) {
169                         final String JavaDoc segmentText = segment.getText();
170                         if (isKeyword(segmentText)) {
171                             segment.setFormat(VHDL_FORMAT_KEYWORD);
172                         } else if (isType(segmentText)) {
173                             segment.setFormat(VHDL_FORMAT_TYPE);
174                         } else if (c == '(') {
175                             segment.setFormat(VHDL_FORMAT_FUNCTION);
176                         } else if (Character.isWhitespace(c)) {
177                             // Look ahead to see if next non-whitespace char is '('.
178
int j = i + 1;
179                             while (j < limit && Character.isWhitespace(c = text.charAt(j)))
180                                 ++j;
181                             if (c == '(')
182                                 segment.setFormat(VHDL_FORMAT_FUNCTION);
183                         }
184                     }
185                     state = STATE_NEUTRAL;
186                 }
187                 ++i;
188                 continue;
189             }
190             if (state == STATE_NUMBER) {
191                 if (Character.isDigit(c))
192                     ;
193                 else if ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
194                     ; // Hex digits are OK.
195
else {
196                     endToken(text, i, state);
197                     if (mode.isIdentifierStart(c))
198                         state = STATE_IDENTIFIER;
199                     else
200                         state = STATE_NEUTRAL;
201                 }
202                 ++i;
203                 continue;
204             }
205             if (state == STATE_NEUTRAL) {
206                 if (mode.isIdentifierStart(c)) {
207                     endToken(text, i, state);
208                     state = STATE_IDENTIFIER;
209                 } else if (Character.isDigit(c)) {
210                     endToken(text, i, state);
211                     state = STATE_NUMBER;
212                 }
213             }
214             ++i;
215         }
216         // Reached end of line.
217
endToken(text, i, state);
218         if (state == STATE_IDENTIFIER) {
219             // Last token might be a keyword.
220
final LineSegment segment = getLastSegment();
221             if (segment != null) {
222                 final String JavaDoc segmentText = segment.getText();
223                 if (isKeyword(segmentText))
224                     segment.setFormat(VHDL_FORMAT_KEYWORD);
225                 else if (isType(segmentText))
226                     segment.setFormat(VHDL_FORMAT_TYPE);
227             }
228         }
229     }
230
231     public LineSegmentList formatLine(Line line)
232     {
233         clearSegmentList();
234         parseLine(line);
235         return segmentList;
236     }
237
238     private static final boolean isOperatorChar(char c)
239     {
240         return "!&|<>=+/*-".indexOf(c) >= 0;
241     }
242
243     public FormatTable getFormatTable()
244     {
245         if (formatTable == null) {
246             formatTable = new FormatTable("VHDLMode");
247             formatTable.addEntryFromPrefs(VHDL_FORMAT_TEXT, "text");
248             formatTable.addEntryFromPrefs(VHDL_FORMAT_COMMENT, "comment");
249             formatTable.addEntryFromPrefs(VHDL_FORMAT_STRING, "string");
250             formatTable.addEntryFromPrefs(VHDL_FORMAT_IDENTIFIER, "identifier", "text");
251             formatTable.addEntryFromPrefs(VHDL_FORMAT_KEYWORD, "keyword");
252             formatTable.addEntryFromPrefs(VHDL_FORMAT_TYPE, "type", "preprocessor");
253             formatTable.addEntryFromPrefs(VHDL_FORMAT_FUNCTION, "function");
254             formatTable.addEntryFromPrefs(VHDL_FORMAT_OPERATOR, "operator");
255             formatTable.addEntryFromPrefs(VHDL_FORMAT_NUMBER, "number");
256         }
257         return formatTable;
258     }
259
260     private static boolean isType(String JavaDoc s)
261     {
262         return getTypes().contains(s.toLowerCase());
263     }
264
265     private static HashSet JavaDoc typeHashSet;
266
267     private static HashSet JavaDoc getTypes()
268     {
269         if (typeHashSet == null) {
270             String JavaDoc[] array = types;
271             int count = array.length;
272             typeHashSet = new HashSet JavaDoc(Math.max(2 * count, 11));
273             for (int i = count - 1; i >= 0; i--)
274                 typeHashSet.add(array[i]);
275         }
276         return typeHashSet;
277     }
278
279     private static final String JavaDoc[] types = {
280         "bit",
281         "bit_vector",
282         "boolean",
283         "character",
284         "delay_length",
285         "file_open_kind",
286         "file_open_status",
287         "integer",
288         "line",
289         "natural",
290         "positive",
291         "real",
292         "severity_level",
293         "side",
294         "signed",
295         "std_logic",
296         "std_logic_vector",
297         "std_ulogic",
298         "std_ulogic_vector",
299         "string",
300         "text",
301         "time",
302         "unsigned"
303     };
304 }
305
Popular Tags