1 21 22 package org.armedbear.j; 23 24 import java.util.HashSet ; 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 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 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 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 ++i; 109 } 110 ++i; 111 continue; 112 } 113 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 final LineSegment segment = getLastSegment(); 137 if (segment != null) { 138 final String 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 final LineSegment segment = getLastSegment(); 168 if (segment != null) { 169 final String 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 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 ; 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 endToken(text, i, state); 218 if (state == STATE_IDENTIFIER) { 219 final LineSegment segment = getLastSegment(); 221 if (segment != null) { 222 final String 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 s) 261 { 262 return getTypes().contains(s.toLowerCase()); 263 } 264 265 private static HashSet typeHashSet; 266 267 private static HashSet getTypes() 268 { 269 if (typeHashSet == null) { 270 String [] array = types; 271 int count = array.length; 272 typeHashSet = new HashSet (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 [] 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 |