1 21 22 package net.percederberg.grammatica; 23 24 import java.util.HashMap ; 25 26 import net.percederberg.grammatica.parser.Node; 27 import net.percederberg.grammatica.parser.ParseException; 28 import net.percederberg.grammatica.parser.Production; 29 import net.percederberg.grammatica.parser.ProductionPattern; 30 import net.percederberg.grammatica.parser.Token; 31 import net.percederberg.grammatica.parser.TokenPattern; 32 33 46 class FirstPassAnalyzer extends GrammarAnalyzer { 47 48 51 private Grammar grammar; 52 53 56 private int nextTokenId = 1001; 57 58 61 private int nextProductionId = 2001; 62 63 68 private HashMap names = new HashMap (); 69 70 75 public FirstPassAnalyzer(Grammar grammar) { 76 this.grammar = grammar; 77 } 78 79 87 protected Node exitIgnore(Token node) { 88 String str = node.getImage(); 89 90 str = str.substring(7, str.length() - 1).trim(); 91 if (!str.equals("")) { 92 node.addValue(str); 93 } 94 return node; 95 } 96 97 105 protected Node exitError(Token node) { 106 String str = node.getImage(); 107 108 str = str.substring(6, str.length() - 1).trim(); 109 if (!str.equals("")) { 110 node.addValue(str); 111 } 112 return node; 113 } 114 115 122 protected Node exitIdentifier(Token node) { 123 node.addValue(node.getImage()); 124 return node; 125 } 126 127 136 protected Node exitQuotedString(Token node) { 137 String str = node.getImage(); 138 139 node.addValue(str.substring(1, str.length() - 1)); 140 return node; 141 } 142 143 153 protected Node exitRegexp(Token node) { 154 String str = node.getImage(); 155 StringBuffer buf = new StringBuffer (); 156 157 str = str.substring(2, str.length() - 2); 158 for (int i = 0; i < str.length(); i++) { 159 if (str.startsWith("\\<", i)) { 160 buf.append('<'); 161 i++; 162 } else if (str.startsWith("\\>", i)) { 163 buf.append('>'); 164 i++; 165 } else { 166 buf.append(str.charAt(i)); 167 } 168 } 169 node.addValue(buf.toString()); 170 return node; 171 } 172 173 180 protected Node exitHeaderPart(Production node) { 181 return null; 182 } 183 184 195 protected Node exitHeaderDeclaration(Production node) 196 throws ParseException { 197 198 String name; 199 String value; 200 201 name = getStringValue(getChildAt(node, 0), 0); 202 value = getStringValue(getChildAt(node, 2), 0); 203 grammar.addDeclaration(name, value); 204 return null; 205 } 206 207 214 protected Node exitTokenPart(Production node) { 215 return null; 216 } 217 218 229 protected Node exitTokenDeclaration(Production node) 230 throws ParseException { 231 232 TokenPattern pattern; 233 String name; 234 int type; 235 String str; 236 Token token; 237 Node child; 238 239 name = getIdentifier((Token) getChildAt(node, 0)); 241 child = getChildAt(node, 2); 242 type = getIntValue(child, 0); 243 str = getStringValue(child, 1); 244 pattern = new TokenPattern(nextTokenId++, name, type, str); 245 246 if (node.getChildCount() == 4) { 248 child = getChildAt(node, 3); 249 token = (Token) getValue(child, 0); 250 str = null; 251 if (child.getValueCount() == 2) { 252 str = getStringValue(child, 1); 253 } 254 switch (token.getId()) { 255 case GrammarConstants.IGNORE: 256 if (str == null) { 257 pattern.setIgnore(); 258 } else { 259 pattern.setIgnore(str); 260 } 261 break; 262 case GrammarConstants.ERROR: 263 if (str == null) { 264 pattern.setError(); 265 } else { 266 pattern.setError(str); 267 } 268 break; 269 } 270 } 271 272 grammar.addToken(pattern, 274 node.getStartLine(), 275 node.getEndLine()); 276 return null; 277 } 278 279 289 protected Node exitTokenValue(Production node) throws ParseException { 290 switch (getChildAt(node, 0).getId()) { 291 case GrammarConstants.QUOTED_STRING: 292 node.addValue(new Integer (TokenPattern.STRING_TYPE)); 293 break; 294 case GrammarConstants.REGEXP: 295 node.addValue(new Integer (TokenPattern.REGEXP_TYPE)); 296 break; 297 } 298 node.addValue(getStringValue(getChildAt(node, 0), 0)); 299 return node; 300 } 301 302 312 protected Node exitTokenHandling(Production node) 313 throws ParseException { 314 315 Node child = getChildAt(node, 0); 316 317 node.addValue(child); 318 if (child.getValueCount() > 0) { 319 node.addValue(getValue(child, 0)); 320 } 321 return node; 322 } 323 324 335 protected Node exitProductionDeclaration(Production node) 336 throws ParseException { 337 338 ProductionPattern production; 339 String name; 340 341 name = getIdentifier((Token) getChildAt(node, 0)); 342 production = new ProductionPattern(nextProductionId++, name); 343 grammar.addProduction(production, 344 node.getStartLine(), 345 node.getEndLine()); 346 return node; 347 } 348 349 362 private String getIdentifier(Token token) throws ParseException { 363 String name = token.getImage(); 364 StringBuffer buf = new StringBuffer (name.toUpperCase()); 365 char c; 366 367 if (token.getId() != GrammarConstants.IDENTIFIER) { 369 throw new ParseException(ParseException.INTERNAL_ERROR, 370 null, 371 token.getStartLine(), 372 token.getStartColumn()); 373 } 374 375 for (int i = 0; i < buf.length(); i++) { 377 c = buf.charAt(i); 378 if (('A' <= c && c <= 'Z') || ('0' <= c && c <= '9')) { 379 } else { 381 buf.deleteCharAt(i--); 382 } 383 } 384 385 if (names.containsKey(buf.toString())) { 387 throw new ParseException( 388 ParseException.ANALYSIS_ERROR, 389 "duplicate identifier '" + name + "' is similar or " + 390 "equal to previously defined identifier '" + 391 names.get(buf.toString()) + "'", 392 token.getStartLine(), 393 token.getStartColumn()); 394 } else { 395 names.put(buf.toString(), name); 396 } 397 398 return name; 400 } 401 } 402 | Popular Tags |