1 20 21 package org.armedbear.j; 22 23 import java.util.ArrayList ; 24 import java.util.Stack ; 25 26 public final class CppTagger extends JavaTagger implements Constants 27 { 28 private static final int NEUTRAL = 0; 30 private static final int CLASS_NAME = 1; 31 private static final int CLASS_PROLOG = 2; 32 private static final int METHOD_NAME = 3; 33 private static final int METHOD_PROLOG = 4; 34 private static final int INITIALIZATION_LIST = 5; 35 36 private static final String classSeparator = "::"; 37 38 public CppTagger(SystemBuffer buffer) 39 { 40 super(buffer); 41 } 42 43 public void run() 44 { 45 ArrayList tags = new ArrayList (); 46 String className = null; 47 Stack classNames = new Stack (); 48 pos = new Position(buffer.getFirstLine(), 0); 49 token = null; 50 tokenStart = null; 51 int state = NEUTRAL; 52 while (!pos.atEnd()) { 53 char c = pos.getChar(); 54 if (Character.isWhitespace(c)) { 55 pos.skipWhitespace(); 56 continue; 57 } 58 if (c == '\'' || c == '"') { 59 pos.skipQuote(); 60 continue; 61 } 62 if (pos.lookingAt("/*")) { 63 skipComment(pos); 64 continue; 65 } 66 if (pos.lookingAt("//")) { 67 skipSingleLineComment(pos); 68 continue; 69 } 70 if (c == '#' && pos.getOffset() == 0) { 71 skipPreprocessor(pos); 72 continue; 73 } 74 if (state == METHOD_NAME) { 75 if (c == '{') { 76 if (className != null) 77 token = className + classSeparator + token; 78 tags.add(new CppTag(token, tokenStart, TAG_METHOD)); 79 skipBrace(); 80 state = NEUTRAL; 81 continue; 82 } 83 if (c == ':') { 84 if (className != null) 85 token = className + classSeparator + token; 86 tags.add(new CppTag(token, tokenStart, TAG_METHOD)); 87 state = INITIALIZATION_LIST; 88 pos.skip(1); 89 continue; 90 } 91 if (pos.lookingAt("throw")) { 92 if (className != null) 93 token = className + classSeparator + token; 94 state = METHOD_PROLOG; 95 pos.skip(5); continue; 97 } 98 if (pos.lookingAt("const")) { 99 if (className != null) 100 token = className + classSeparator + token; 101 state = METHOD_PROLOG; 102 pos.skip(5); continue; 104 } 105 state = NEUTRAL; } 107 if (state == INITIALIZATION_LIST) { 108 if (c == '{') { 109 skipBrace(); 110 state = NEUTRAL; 111 continue; 112 } 113 pos.next(); 114 continue; 115 } 116 if (state == CLASS_PROLOG){ 117 if (c == '{') { 118 if (className != null) 119 classNames.push(className); 120 className = token; 121 tags.add(new CppTag("class " + token, tokenStart, TAG_CLASS)); 123 state = NEUTRAL; 124 pos.next(); 125 continue; 126 } 127 if (c == ';') { 128 pos.next(); 130 state = NEUTRAL; 131 continue; 132 } 133 pos.next(); 134 continue; 135 } 136 if (state == METHOD_PROLOG) { 137 if (c == '{') { 138 tags.add(new CppTag(token, tokenStart, TAG_METHOD)); 140 skipBrace(); 141 state = NEUTRAL; 142 continue; 143 } 144 if (c == ';') { 145 pos.next(); 147 state = NEUTRAL; 148 continue; 149 } 150 pos.next(); 151 continue; 152 } 153 if (c == '}') { 154 if (classNames.empty()) 155 className = null; 156 else 157 className = (String ) classNames.pop(); 158 pos.next(); 159 continue; 160 } 161 if (isIdentifierStart(c)) { 162 gatherToken(); 163 if (state == CLASS_NAME) 164 state = CLASS_PROLOG; 165 else if (token.equals("class")) 166 state = CLASS_NAME; 167 else if (token.equals("operator") || token.endsWith("::operator")) { 168 gatherOperatorName(); 169 token = "operator " + token; 170 state = METHOD_NAME; 171 } 172 continue; 173 } 174 if (c == '(') { 175 skipParen(); 176 state = METHOD_NAME; 177 continue; 178 } 179 pos.next(); 180 } 181 buffer.setTags(tags); 182 } 183 184 private void gatherToken() 185 { 186 tokenStart = new Position(pos); 187 FastStringBuffer sb = new FastStringBuffer(); 188 char c; 189 while (isIdentifierPart(c = pos.getChar())) { 190 sb.append(c); 191 if (!pos.next()) 192 break; 193 } 194 while (sb.length() > 0 && sb.charAt(sb.length()-1) == ':') 196 sb.setLength(sb.length()-1); 197 token = sb.toString(); 198 } 199 200 private void gatherOperatorName() 201 { 202 pos.skipWhitespace(); 203 tokenStart = new Position(pos); 204 FastStringBuffer sb = new FastStringBuffer(); 205 char c; 206 while ((c = pos.getChar()) != '(') { 207 sb.append(c); 208 if (!pos.next()) 209 break; 210 } 211 token = sb.toString(); 212 } 213 214 private static final boolean isIdentifierStart(char c) 215 { 216 if (c >= 'a' && c <= 'z') 217 return true; 218 if (c >='A' && c <= 'Z') 219 return true; 220 if (c == '_' || c == ':' || c == '~') 221 return true; 222 return false; 223 } 224 225 private static final boolean isIdentifierPart(char c) 226 { 227 if (c >= 'a' && c <= 'z') 228 return true; 229 if (c >='A' && c <= 'Z') 230 return true; 231 if (c >= '0' && c <= '9') 232 return true; 233 if (c == '_' || c == ':' || c == '~') 234 return true; 235 return false; 236 } 237 } 238 | Popular Tags |