1 package org.antlr.works.syntax.element; 2 3 import org.antlr.works.ate.breakpoint.ATEBreakpointEntity; 4 import org.antlr.works.ate.folding.ATEFoldingEntity; 5 import org.antlr.works.ate.syntax.misc.ATEToken; 6 import org.antlr.works.editor.EditorPersistentObject; 7 import org.antlr.works.grammar.EngineGrammarError; 8 import org.antlr.works.syntax.GrammarSyntaxParser; 9 10 import java.util.ArrayList ; 11 import java.util.Iterator ; 12 import java.util.List ; 13 import java.util.Set ; 14 44 45 public class ElementRule extends ElementScopable implements Comparable , EditorPersistentObject, ATEFoldingEntity, ATEBreakpointEntity { 46 47 public String name; 48 public ATEToken start; 49 public ATEToken colon; 50 public ATEToken end; 51 52 public boolean ignored = false; 53 public boolean expanded = true; 54 public boolean breakpoint = false; 55 56 public boolean lexer = false; 57 58 public boolean hasLeftRecursion = false; 60 public boolean leftRecursionAnalyzed = false; 61 62 public Set leftRecursiveRulesSet; 64 65 public List <EngineGrammarError> errors; 66 public boolean needsToBuildErrors = true; 67 68 protected GrammarSyntaxParser parser; 69 70 protected int refsStartIndex = -1; 71 protected int refsEndIndex = -1; 72 73 protected int blocksStartIndex = -1; 74 protected int blocksEndIndex = -1; 75 76 protected int actionsStartIndex = -1; 77 protected int actionsEndIndex = -1; 78 79 public ElementRule(String name) { 80 this.name = name; 81 this.lexer = ATEToken.isLexerName(name); 82 } 83 84 public ElementRule(GrammarSyntaxParser parser, String name, ATEToken start, ATEToken colon, ATEToken end) { 85 this.parser = parser; 86 this.name = name; 87 this.start = start; 88 this.colon = colon; 89 this.end = end; 90 this.lexer = ATEToken.isLexerName(name); 91 } 92 93 public void completed() { 94 leftRecursionAnalyzed = false; 97 } 98 99 public void setReferencesIndexes(int startIndex, int endIndex) { 100 this.refsStartIndex = Math.max(0, startIndex); 101 this.refsEndIndex = endIndex; 102 } 103 104 public List <ElementReference> getReferences() { 105 if(refsStartIndex != -1 && refsEndIndex != -1) 106 return parser.references.subList(refsStartIndex, refsEndIndex+1); 107 else 108 return null; 109 } 110 111 public void setBlocksIndexes(int startIndex, int endIndex) { 112 this.blocksStartIndex = Math.max(0, startIndex); 113 this.blocksEndIndex = endIndex; 114 } 115 116 public List <ElementBlock> getBlocks() { 117 if(blocksStartIndex != -1 && blocksEndIndex != -1) 118 return parser.blocks.subList(blocksStartIndex, blocksEndIndex+1); 119 else 120 return null; 121 } 122 123 public void setActionsIndexes(int startIndex, int endIndex) { 124 this.actionsStartIndex = Math.max(0, startIndex); 125 this.actionsEndIndex = endIndex; 126 } 127 128 public List <ElementAction> getActions() { 129 if(actionsStartIndex != -1 && actionsEndIndex != -1) 130 return parser.actions.subList(actionsStartIndex, actionsEndIndex+1); 131 else 132 return null; 133 } 134 135 public int getStartIndex() { 136 return start.getStartIndex(); 137 } 138 139 public int getEndIndex() { 140 return end.getEndIndex(); 141 } 142 143 public int getLength() { 144 return getEndIndex()-getStartIndex(); 145 } 146 147 public int getInternalTokensStartIndex() { 148 for(Iterator <ATEToken> iter = getTokens().iterator(); iter.hasNext(); ) { 149 ATEToken token = iter.next(); 150 if(token.getAttribute().equals(":")) { 151 token = iter.next(); 152 return token.getStartIndex(); 153 } 154 } 155 return -1; 156 } 157 158 public int getInternalTokensEndIndex() { 159 ATEToken token = parser.getTokens().get(end.index-1); 160 return token.getEndIndex(); 161 } 162 163 public List <ATEToken> getTokens() { 164 List <ATEToken> t = new ArrayList <ATEToken>(); 165 for(int index=start.index; index<end.index; index++) { 166 t.add(parser.getTokens().get(index)); 167 } 168 return t; 169 } 170 171 public List <List <ATEToken>> getAlternatives() { 172 List <List <ATEToken>> alts = new ArrayList <List <ATEToken>>(); 173 List <ATEToken> alt = null; 174 boolean findColon = true; 175 int level = 0; 176 for (ATEToken token : getTokens()) { 177 if (findColon) { 178 if (token.getAttribute().equals(":")) { 179 findColon = false; 180 alt = new ArrayList <ATEToken>(); 181 } 182 } else { 183 if (token.getAttribute().equals("(")) 184 level++; 185 else if (token.getAttribute().equals(")")) 186 level--; 187 else if (level == 0) { if (token.getAttribute().equals("|")) { 189 alts.add(alt); 190 alt = new ArrayList <ATEToken>(); 191 continue; 192 } 193 } 194 alt.add(token); 195 } 196 } 197 if(alt != null && !alt.isEmpty()) { 198 alts.add(alt); 199 } 200 return alts; 201 } 202 203 public void setErrors(List <EngineGrammarError> errors) { 204 this.errors = errors; 205 } 206 207 public List <EngineGrammarError> getErrors() { 208 return errors; 209 } 210 211 public void setExpanded(boolean expanded) { 212 this.expanded = expanded; 213 } 214 215 public boolean isExpanded() { 216 return expanded; 217 } 218 219 public void setLeftRecursiveRulesSet(Set rulesSet) { 220 leftRecursiveRulesSet = rulesSet; 221 } 222 223 public Set getLeftRecursiveRulesSet() { 224 return leftRecursiveRulesSet; 225 } 226 227 public boolean hasLeftRecursion() { 228 if(!leftRecursionAnalyzed) { 229 leftRecursionAnalyzed = true; 230 hasLeftRecursion = detectLeftRecursion(); 231 } 232 return hasLeftRecursion; 233 } 234 235 public boolean detectLeftRecursion() { 236 for (List <ATEToken> alts : getAlternatives()) { 237 if (alts.isEmpty()) 238 continue; 239 240 ATEToken firstTokenInAlt = alts.get(0); 241 if (firstTokenInAlt.getAttribute().equals(name)) 242 return true; 243 } 244 return false; 245 } 246 247 public String getTextRuleAfterRemovingLeftRecursion() { 248 StringBuffer head = new StringBuffer (); 249 StringBuffer star = new StringBuffer (); 250 251 for (List <ATEToken> alts : getAlternatives()) { 252 ATEToken firstTokenInAlt = alts.get(0); 253 if (firstTokenInAlt.getAttribute().equals(name)) { 254 if (alts.size() > 1) { 255 if (star.length() > 0) 256 star.append(" | "); 257 int start = (alts.get(1)).getStartIndex(); 258 int end = (alts.get(alts.size() - 1)).getEndIndex(); 259 star.append(firstTokenInAlt.getText().substring(start, end)); 260 } 261 } else { 262 if (head.length() > 0) 263 head.append(" | "); 264 int start = firstTokenInAlt.getStartIndex(); 265 int end = (alts.get(alts.size() - 1)).getEndIndex(); 266 head.append(firstTokenInAlt.getText().substring(start, end)); 267 } 268 } 269 270 StringBuffer sb = new StringBuffer (); 271 sb.append("("); 272 sb.append(head); 273 sb.append(")"); 274 if(star.length() > 0) { 275 sb.append(" ("); 276 sb.append(star); 277 sb.append(")*"); 278 } 279 280 return sb.toString(); 281 } 282 283 public boolean hasErrors() { 284 if(errors == null) 285 return false; 286 else 287 return !errors.isEmpty(); 288 } 289 290 public void setNeedsToBuildErrors(boolean flag) { 291 this.needsToBuildErrors = flag; 292 } 293 294 public boolean needsToBuildErrors() { 295 return needsToBuildErrors; 296 } 297 298 public String getErrorMessageString(int index) { 299 EngineGrammarError error = errors.get(index); 300 return error.messageText; 301 } 302 303 public String getErrorMessageHTML() { 304 StringBuffer message = new StringBuffer (); 305 message.append("<html>"); 306 for (Iterator <EngineGrammarError> iterator = errors.iterator(); iterator.hasNext();) { 307 EngineGrammarError error = iterator.next(); 308 message.append(error.messageText); 309 if(iterator.hasNext()) 310 message.append("<br>"); 311 } 312 message.append("</html>"); 313 return message.toString(); 314 } 315 316 public String toString() { 317 return name; 318 } 319 320 public boolean containsIndex(int index) { 321 return index >= getStartIndex() && index <= getEndIndex(); 322 } 323 324 public int compareTo(Object o) { 325 ElementRule otherRule = (ElementRule) o; 326 return this.name.compareTo(otherRule.name); 327 } 328 329 public int getUniqueIdentifier() { 330 return name.hashCode(); 331 } 332 333 public boolean canBeCollapsed() { 334 return colon.startLineNumber <= end.startLineNumber - 1; 335 } 336 337 public void foldingEntitySetExpanded(boolean expanded) { 338 setExpanded(expanded); 339 } 340 341 public boolean foldingEntityIsExpanded() { 342 return isExpanded(); 343 } 344 345 public boolean foldingEntityCanBeCollapsed() { 346 return canBeCollapsed(); 347 } 348 349 public int foldingEntityGetStartParagraphIndex() { 350 return getStartIndex(); 351 } 352 353 public int foldingEntityGetStartIndex() { 354 return colon.getStartIndex(); 355 } 356 357 public int foldingEntityGetEndIndex() { 358 return getEndIndex(); 359 } 360 361 public int foldingEntityGetStartLine() { 362 return colon.startLineNumber; 363 } 364 365 public int foldingEntityGetEndLine() { 366 return end.endLineNumber; 367 } 368 369 public String foldingEntityPlaceholderString() { 370 return ": ... ;"; 371 } 372 373 public String foldingEntityID() { 374 return String.valueOf(getUniqueIdentifier()); 375 } 376 377 public int foldingEntityLevel() { 378 return 0; 379 } 380 381 public int breakpointEntityUniqueID() { 382 return getUniqueIdentifier(); 383 } 384 385 public int breakpointEntityIndex() { 386 return getStartIndex(); 387 } 388 389 public int breakpointEntityLine() { 390 return start.startLineNumber; 391 } 392 393 public void breakpointEntitySetBreakpoint(boolean flag) { 394 this.breakpoint = flag; 395 } 396 397 public boolean breakpointEntityIsBreakpoint() { 398 return breakpoint; 399 } 400 401 public Object getPersistentID() { 402 return getUniqueIdentifier(); 403 } 404 405 public void persistentAssign(EditorPersistentObject otherObject) { 406 ElementRule oldRule = (ElementRule)otherObject; 407 this.ignored = oldRule.ignored; 408 this.expanded = oldRule.expanded; 409 this.breakpoint = oldRule.breakpoint; 410 this.leftRecursiveRulesSet = oldRule.leftRecursiveRulesSet; 411 } 412 413 } 414 | Popular Tags |