001package org.maltparser.core.syntaxgraph.node; 002 003 004import java.util.ArrayList; 005import java.util.List; 006import java.util.NoSuchElementException; 007import java.util.Set; 008import java.util.SortedSet; 009import java.util.TreeSet; 010 011import org.maltparser.core.exception.MaltChainedException; 012import org.maltparser.core.helper.SystemLogger; 013import org.maltparser.core.symbol.SymbolTable; 014import org.maltparser.core.syntaxgraph.LabelSet; 015import org.maltparser.core.syntaxgraph.SyntaxGraphException; 016import org.maltparser.core.syntaxgraph.TokenStructure; 017import org.maltparser.core.syntaxgraph.edge.Edge; 018import org.maltparser.core.syntaxgraph.headrules.Direction; 019import org.maltparser.core.syntaxgraph.headrules.HeadRules; 020 021 022public class Root extends GraphNode implements DependencyNode, PhraseStructureNode, NonTerminalNode { 023 protected final SortedSet<DependencyNode> leftDependents; 024 protected final SortedSet<DependencyNode> rightDependents; 025 protected final SortedSet<PhraseStructureNode> children; 026 027 /** 028 * a reference to a node where the node is part of a component. If the node is unconnected it will reference to it self. 029 */ 030 protected DependencyNode component; 031 protected int rank; 032 public Root() throws MaltChainedException { 033 super(); 034 leftDependents = new TreeSet<DependencyNode>(); 035 rightDependents = new TreeSet<DependencyNode>(); 036 children = new TreeSet<PhraseStructureNode>(); 037 clear(); 038 } 039 040 public void addIncomingEdge(Edge in) throws MaltChainedException { 041 throw new SyntaxGraphException("It is not allowed for a root node to have an incoming edge"); 042 } 043 044 public void removeIncomingEdge(Edge in) { } 045 046 public void addOutgoingEdge(Edge out) throws MaltChainedException { 047 super.addOutgoingEdge(out); 048 if (out.getTarget() != null) { 049 if (out.getType() == Edge.DEPENDENCY_EDGE && out.getTarget() instanceof DependencyNode) { 050 Node dependent = out.getTarget(); 051 if (compareTo(dependent) > 0) { 052 leftDependents.add((DependencyNode)dependent); 053 } else if (compareTo(dependent) < 0) { 054 rightDependents.add((DependencyNode)dependent); 055 } 056 } else if (out.getType() == Edge.PHRASE_STRUCTURE_EDGE && out.getTarget() instanceof PhraseStructureNode) { 057 children.add((PhraseStructureNode)out.getTarget()); 058 } 059 } 060 } 061 062 public void removeOutgoingEdge(Edge out) throws MaltChainedException { 063 super.removeOutgoingEdge(out); 064 if (out.getTarget() != null) { 065 if (out.getType() == Edge.DEPENDENCY_EDGE && out.getTarget() instanceof DependencyNode) { 066 Node dependent = out.getTarget(); 067 if (compareTo(dependent) > 0) { 068 leftDependents.remove((DependencyNode)dependent); 069 } else if (compareTo(dependent) < 0) { 070 rightDependents.remove((DependencyNode)dependent); 071 } 072 } else if (out.getType() == Edge.PHRASE_STRUCTURE_EDGE && out.getTarget() instanceof PhraseStructureNode) { 073 children.remove((PhraseStructureNode)out.getTarget()); 074 } 075 } 076 } 077 public DependencyNode getPredecessor() { 078 return null; 079 } 080 081 public DependencyNode getSuccessor() { 082 return null; 083 } 084 085 public DependencyNode getAncestor() throws MaltChainedException { 086 return this; 087 } 088 089 public DependencyNode getProperAncestor() throws MaltChainedException { 090 return null; 091 } 092 093 public int getRank() { 094 return rank; 095 } 096 097 public void setRank(int r) { 098 this.rank = r; 099 } 100 101 public DependencyNode findComponent() { 102 return findComponent(this); 103 } 104 105 private DependencyNode findComponent(DependencyNode x) { 106 if (x != x.getComponent()) { 107 x.setComponent(findComponent(x.getComponent())); 108 } 109 return x.getComponent(); 110 } 111 112 public DependencyNode getComponent() { 113 return component; 114 } 115 116 public void setComponent(DependencyNode x) { 117 this.component = x; 118 } 119 120 121 public boolean isContinuous() { 122 return true; 123 } 124 125 public boolean isContinuousExcludeTerminalsAttachToRoot() { 126 return true; 127 } 128 129 public PhraseStructureNode getParent() { 130 return null; 131 } 132 133 public Edge getParentEdge() throws MaltChainedException { 134 return null; 135 } 136 137 public String getParentEdgeLabelSymbol(SymbolTable table) throws MaltChainedException { 138 return null; 139 } 140 141 public int getParentEdgeLabelCode(SymbolTable table) throws MaltChainedException { 142 return -1; 143 } 144 145 public boolean hasParentEdgeLabel(SymbolTable table) throws MaltChainedException { 146 return false; 147 } 148 149 public SortedSet<PhraseStructureNode> getChildren() { 150 return new TreeSet<PhraseStructureNode>(children); 151 } 152 153 public PhraseStructureNode getChild(int index) { 154 if (index >= 0 && index < children.size()) { 155 return children.toArray(new PhraseStructureNode[children.size()])[index]; 156 } 157 return null; 158 } 159 160 public PhraseStructureNode getLeftChild() { 161 for (PhraseStructureNode node : children) { 162 return node; 163 } 164 return null; 165 } 166 167 public PhraseStructureNode getRightChild() { 168 int n = children.size(); 169 int i = 1; 170 for (PhraseStructureNode node : children) { 171 if (i == n) { 172 return node; 173 } 174 } 175 return null; 176 } 177 178 public int nChildren() { 179 return children.size(); 180 } 181 182 public boolean hasNonTerminalChildren() { 183 for (PhraseStructureNode node : children) { 184 if (node instanceof NonTerminal) { 185 return true; 186 } 187 } 188 return false; 189 } 190 191 public boolean hasTerminalChildren() { 192 for (PhraseStructureNode node : children) { 193 if (node instanceof Token) { 194 return true; 195 } 196 } 197 return false; 198 } 199 200 public int getHeight() { 201 int max = -1; 202 for (PhraseStructureNode node : children) { 203 if (node instanceof Token) { 204 if (max < 0) { 205 max = 0; 206 } 207 } else { 208 int nodeheight = ((NonTerminalNode)node).getHeight(); 209 if (max < nodeheight) { 210 max = nodeheight; 211 } 212 } 213 } 214 return max + 1; 215 } 216 217 public TokenNode getLexicalHead(HeadRules headRules) throws MaltChainedException { 218 return identifyHead(headRules); 219 } 220 221 public PhraseStructureNode getHeadChild(HeadRules headRules) throws MaltChainedException { 222 return identifyHeadChild(headRules); 223 } 224 225 public TokenNode getLexicalHead() throws MaltChainedException { 226 return identifyHead(null); 227 } 228 229 public PhraseStructureNode getHeadChild() throws MaltChainedException { 230 return identifyHeadChild(null); 231 } 232 233 private PhraseStructureNode identifyHeadChild(HeadRules headRules) throws MaltChainedException { 234 PhraseStructureNode headChild = (headRules == null)?null:headRules.getHeadChild(this); 235 if (headChild == null) { 236 Direction direction = (headRules == null)?Direction.LEFT:headRules.getDefaultDirection(this); 237 if (direction == Direction.LEFT) { 238 if ((headChild = leftmostTerminalChild()) == null) { 239 headChild = leftmostNonTerminalChild(); 240 } 241 } else { 242 if ((headChild = rightmostTerminalChild()) == null) { 243 headChild = rightmostNonTerminalChild(); 244 } 245 } 246 } 247 return headChild; 248 } 249 250 public TokenNode identifyHead(HeadRules headRules) throws MaltChainedException { 251 PhraseStructureNode headChild = identifyHeadChild(headRules); 252 TokenNode lexicalHead = null; 253 if (headChild instanceof NonTerminalNode) { 254 lexicalHead = ((NonTerminalNode)headChild).identifyHead(headRules); 255 } else if (headChild instanceof TokenNode) { 256 lexicalHead = (TokenNode)headChild; 257 } 258 for (PhraseStructureNode node : children) { 259 if (node != headChild && node instanceof NonTerminalNode) { 260 ((NonTerminalNode)node).identifyHead(headRules); 261 } 262 } 263 264 return lexicalHead; 265 } 266 267 private PhraseStructureNode leftmostTerminalChild() { 268 for (PhraseStructureNode node : children) { 269 if (node instanceof TokenNode) { 270 return node; 271 } 272 } 273 return null; 274 } 275 276 private PhraseStructureNode leftmostNonTerminalChild() { 277 for (PhraseStructureNode node : children) { 278 if (node instanceof NonTerminalNode) { 279 return node; 280 } 281 } 282 return null; 283 } 284 285 private PhraseStructureNode rightmostTerminalChild() { 286 try { 287 if (children.last() instanceof TokenNode) { 288 return children.last(); 289 } 290 } catch (NoSuchElementException e) { } 291 292 PhraseStructureNode candidate = null; 293 for (PhraseStructureNode node : children) { 294 if (node instanceof TokenNode) { 295 candidate = node; 296 } 297 } 298 return candidate; 299 } 300 301 private PhraseStructureNode rightmostNonTerminalChild() { 302 try { 303 if (children.last() instanceof NonTerminalNode) { 304 return children.last(); 305 } 306 } catch (NoSuchElementException e) { } 307 308 PhraseStructureNode candidate = null; 309 for (PhraseStructureNode node : children) { 310 if (node instanceof NonTerminalNode) { 311 candidate = node; 312 } 313 } 314 return candidate; 315 } 316 317 public boolean hasAtMostOneHead() { 318 return true; 319 } 320 321 public boolean hasAncestorInside(int left, int right) throws MaltChainedException { 322 return false; 323 } 324 325 public boolean hasHead() { 326 return false; 327 } 328 329 330 public DependencyNode getHead() throws MaltChainedException { 331 return null; 332 } 333 334 public Edge getHeadEdge() throws MaltChainedException { 335 return null; 336 } 337 338 public void addHeadEdgeLabel(SymbolTable table, String symbol) throws MaltChainedException { } 339 340 public void addHeadEdgeLabel(SymbolTable table, int code) throws MaltChainedException { } 341 342 public void addHeadEdgeLabel(LabelSet labelSet) throws MaltChainedException { } 343 344 public int getHeadEdgeLabelCode(SymbolTable table) throws MaltChainedException { 345 return 0; 346 } 347 348 public LabelSet getHeadEdgeLabelSet() throws MaltChainedException { 349 return null; 350 } 351 352 353 public String getHeadEdgeLabelSymbol(SymbolTable table) throws MaltChainedException { 354 return null; 355 } 356 357 public Set<SymbolTable> getHeadEdgeLabelTypes() throws MaltChainedException { 358 return null; 359 } 360 361 public boolean hasHeadEdgeLabel(SymbolTable table) throws MaltChainedException { 362 return false; 363 } 364 365 public boolean isHeadEdgeLabeled() throws MaltChainedException { 366 return false; 367 } 368 369 public int nHeadEdgeLabels() throws MaltChainedException { 370 return 0; 371 } 372 373 public Set<Edge> getHeadEdges() throws MaltChainedException { 374 return null; 375 } 376 377 public Set<DependencyNode> getHeads() throws MaltChainedException { 378 return null; 379 } 380 381 public boolean hasDependent() { 382 return hasLeftDependent() || hasRightDependent(); 383 } 384 385 /** 386 * Returns <code>true</code> if the node has one or more left dependents, otherwise <code>false</code>. 387 * 388 * @return <code>true</code> if the node has one or more left dependents, otherwise <code>false</code>. 389 */ 390 public boolean hasLeftDependent() { 391 return !leftDependents.isEmpty(); 392 } 393 394 /** 395 * Returns the left dependent at the position <code>index</code>, where <code>index==0</code> equals the left most dependent. 396 * 397 * @param index the index 398 * @return the left dependent at the position <code>index</code>, where <code>index==0</code> equals the left most dependent 399 */ 400 public DependencyNode getLeftDependent(int index) { 401 if (0 <= index && index < leftDependents.size()) { 402 int i = 0; 403// DependencyNode candidate = null; 404 405 for (DependencyNode node : leftDependents) { 406// candidate = node; 407 if (i == index) { 408 return node; 409 } 410 i++; 411 } 412 } 413 return null; 414 } 415 416 /** 417 * Return the number of left dependents 418 * 419 * @return the number of left dependents 420 */ 421 public int getLeftDependentCount() { 422 return leftDependents.size(); 423 } 424 425 public SortedSet<DependencyNode> getLeftDependents() { 426 return leftDependents; 427 } 428 429 /** 430 * Returns the left sibling if it exists, otherwise <code>null</code> 431 * 432 * @return the left sibling if it exists, otherwise <code>null</code> 433 */ 434 public DependencyNode getLeftSibling() throws MaltChainedException { 435 return null; 436 } 437 438 /** 439 * Returns the left sibling at the same side of head as the node it self. If not found <code>null</code> is returned 440 * 441 * @return the left sibling at the same side of head as the node it self. If not found <code>null</code> is returned 442 */ 443 public DependencyNode getSameSideLeftSibling() throws MaltChainedException { 444 return null; 445 } 446 447 /** 448 * Returns the closest left dependent to the node it self, if not found <code>null</code> is returned. 449 * 450 * @return the closest left dependent to the node it self, if not found <code>null</code> is returned. 451 */ 452 public DependencyNode getClosestLeftDependent() { 453 try { 454 return leftDependents.last(); 455 } catch (NoSuchElementException e) { 456 return null; 457 } 458 } 459 460 public DependencyNode getLeftmostDependent() { 461 for (DependencyNode dep : leftDependents) { 462 return dep; 463 } 464 return null; 465// try { 466// return leftDependents.first(); 467// } catch (NoSuchElementException e) { 468// return null; 469// } 470 } 471 472 public DependencyNode getRightDependent(int index) { 473 int size = rightDependents.size(); 474 if (index < size) { 475 return rightDependents.toArray(new DependencyNode[size])[size - 1 - index]; 476 } 477 return null; 478// if (0 <= index && index < rightDependents.size()) { 479// int i = 0; 480// DependencyNode candidate = null; 481// 482// for (DependencyNode node : rightDependents) { 483// candidate = node; 484// if (i == index) { 485// return candidate; 486// } 487// i++; 488// } 489// } 490// return null; 491 } 492 493 /** 494 * Return the number of right dependents 495 * 496 * @return the number of right dependents 497 */ 498 public int getRightDependentCount() { 499 return rightDependents.size(); 500 } 501 502 public SortedSet<DependencyNode> getRightDependents() { 503 return rightDependents; 504 } 505 506 /** 507 * Returns the right sibling if it exists, otherwise <code>null</code> 508 * 509 * @return the right sibling if it exists, otherwise <code>null</code> 510 */ 511 public DependencyNode getRightSibling() throws MaltChainedException { 512 return null; 513 } 514 515 /** 516 * Returns the right sibling at the same side of head as the node it self. If not found <code>null</code> is returned 517 * 518 * @return the right sibling at the same side of head as the node it self. If not found <code>null</code> is returned 519 */ 520 public DependencyNode getSameSideRightSibling() throws MaltChainedException { 521 return null; 522 } 523 524 /** 525 * Returns the closest right dependent to the node it self, if not found <code>null</code> is returned. 526 * 527 * @return the closest right dependent to the node it self, if not found <code>null</code> is returned. 528 */ 529 public DependencyNode getClosestRightDependent() { 530 for (DependencyNode dep : rightDependents) { 531 return dep; 532 } 533 return null; 534// try { 535// return rightDependents.first(); 536// } catch (NoSuchElementException e) { 537// return null; 538// } 539 } 540 541 public DependencyNode getRightmostDependent() { 542 int n = rightDependents.size(); 543 int i = 1; 544 for (DependencyNode node : rightDependents) { 545 if (i == n) { 546 return node; 547 } 548 i++; 549 } 550 return null; 551// try { 552// return rightDependents.last(); 553// } catch (NoSuchElementException e) { 554// return null; 555// } 556 } 557 558 /** 559 * Returns <code>true</code> if the node has one or more right dependents, otherwise <code>false</code>. 560 * 561 * @return <code>true</code> if the node has one or more right dependents, otherwise <code>false</code>. 562 */ 563 public boolean hasRightDependent() { 564 return !rightDependents.isEmpty(); 565 } 566 567 protected void getDependencyDominationSet(SortedSet<DependencyNode> dominationSet) { 568 if (leftDependents.size() > 0 || rightDependents.size() > 0) { 569 dominationSet.addAll(leftDependents); 570 dominationSet.addAll(rightDependents); 571 572 for (DependencyNode node : leftDependents) { 573 ((Token)node).getDependencyDominationSet(dominationSet); 574 } 575 for (DependencyNode node : rightDependents) { 576 ((Token)node).getDependencyDominationSet(dominationSet); 577 } 578 } 579 } 580 581// private SortedSet<DependencyNode> getDependencyDominationSet() { 582// SortedSet<DependencyNode> dominationSet = new TreeSet<DependencyNode>(); 583// getDependencyDominationSet(dominationSet); 584// return dominationSet; 585// } 586 587 public boolean isProjective() throws MaltChainedException { 588 return true; 589 } 590 591 public int getDependencyNodeDepth() throws MaltChainedException { 592 return 0; 593 } 594 @Override 595 public int getIndex() { 596 return 0; 597 } 598 599 public int getCompareToIndex() { 600 return 0; 601 } 602 603 @Override 604 public boolean isRoot() { 605 return true; 606 } 607 608 public ComparableNode getLeftmostProperDescendant() throws MaltChainedException { 609 NonTerminalNode node = this; 610 ComparableNode candidate = null; 611 while (node != null) { 612 candidate = node.getLeftChild(); 613 if (candidate == null || candidate instanceof TokenNode) { 614 break; 615 } 616 node = (NonTerminalNode)candidate; 617 } 618 619 if (candidate == null && candidate instanceof NonTerminalNode) { 620 candidate = null; 621 DependencyNode dep = null; 622 for (int index : ((TokenStructure)getBelongsToGraph()).getTokenIndices()) { 623 dep = ((TokenStructure)getBelongsToGraph()).getTokenNode(index); 624 while (dep != null) { 625 if (dep == this ) { 626 return dep; 627 } 628 dep = dep.getHead(); 629 } 630 } 631 } 632 return candidate; 633 } 634 635 public ComparableNode getRightmostProperDescendant() throws MaltChainedException { 636 NonTerminalNode node = this; 637 ComparableNode candidate = null; 638 while (node != null) { 639 candidate = node.getRightChild(); 640 if (candidate == null || candidate instanceof TokenNode) { 641 break; 642 } 643 node = (NonTerminalNode)candidate; 644 } 645 if (candidate == null && candidate instanceof NonTerminalNode) { 646 candidate = null; 647 DependencyNode dep = null; 648 for (int i = ((TokenStructure)getBelongsToGraph()).getHighestTokenIndex(); i > 0; i--) { 649 dep = ((TokenStructure)getBelongsToGraph()).getTokenNode(i); 650 while (dep != null) { 651 if (dep == this ) { 652 return dep; 653 } 654 dep = dep.getHead(); 655 } 656 } 657 } 658 return candidate; 659 } 660 661 public ComparableNode getLeftmostDescendant() throws MaltChainedException { 662 return getLeftmostProperDescendant(); 663 } 664 665 public ComparableNode getRightmostDescendant() throws MaltChainedException { 666 return getRightmostProperDescendant(); 667 } 668 669 public List<DependencyNode> getListOfDependents() { 670 List<DependencyNode> dependentList = new ArrayList<DependencyNode>(); 671 for (DependencyNode node : leftDependents) { 672 dependentList.add(node); 673 } 674 for (DependencyNode node : rightDependents) { 675 dependentList.add(node); 676 } 677 return dependentList; 678 } 679 680 public List<DependencyNode> getListOfLeftDependents() { 681 List<DependencyNode> leftDependentList = new ArrayList<DependencyNode>(); 682 683 for (DependencyNode node : leftDependents) { 684 leftDependentList.add(node); 685 } 686 return leftDependentList; 687 } 688 689 public List<DependencyNode> getListOfRightDependents() { 690 List<DependencyNode> rightDependentList = new ArrayList<DependencyNode>(); 691 for (DependencyNode node : rightDependents) { 692 rightDependentList.add(node); 693 } 694 return rightDependentList; 695 } 696 697// public void reArrangeChildrenAccordingToLeftAndRightProperDesendant() throws MaltChainedException { 698// int i = 0; 699// int leftMostCorner = -1; 700// int leftMostCornerChildIndex = -1; 701// while (i < children.size()) { 702// if (leftMostCorner == -1) { 703// leftMostCorner = getChild(i).getLeftmostProperDescendantIndex(); 704// leftMostCornerChildIndex = i; 705// } else if (getChild(i) instanceof NonTerminal && getChild(i).getLeftmostProperDescendantIndex() < leftMostCorner) { 706// NonTerminalNode child = (NonTerminal)getChild(i); 707// PhraseStructureNode leftMostCornerChild = getChild(leftMostCornerChildIndex); 708// if (leftMostCornerChild.getParent() != null) { 709// LabelSet labelSet = leftMostCornerChild.getParentEdge().getLabelSet(); 710// ((PhraseStructure)getBelongsToGraph()).removePhraseStructureEdge(this, leftMostCornerChild); 711// Edge e = ((PhraseStructure)getBelongsToGraph()).addPhraseStructureEdge(child, leftMostCornerChild); 712// e.addLabel(labelSet); 713// } 714// child.reArrangeChildrenAccordingToLeftAndRightProperDesendant(); 715// i = -1; 716// leftMostCorner = -1; 717// leftMostCornerChildIndex = -1; 718// } else { 719// leftMostCorner = getChild(i).getLeftmostProperDescendantIndex(); 720// leftMostCornerChildIndex = i; 721// } 722// i++; 723// } 724// 725// for (int j = 0, n=children.size(); j < n; j++) { 726// if (getChild(j) instanceof NonTerminalNode) { 727// ((NonTerminalNode)getChild(j)).reArrangeChildrenAccordingToLeftAndRightProperDesendant(); 728// } 729// } 730// } 731 732 @Override 733 public void setIndex(int index) throws MaltChainedException { } 734 735 public void clear() throws MaltChainedException { 736 super.clear(); 737 component = this; 738 rank = 0; 739 leftDependents.clear(); 740 rightDependents.clear(); 741 children.clear(); 742 } 743 744 public int compareTo(ComparableNode o) { 745 final int BEFORE = -1; 746 final int EQUAL = 0; 747 final int AFTER = 1; 748 if ( this == o ) return EQUAL; 749 try { 750 final int thisLCorner = this.getLeftmostProperDescendantIndex(); 751 final int thatLCorner = (o instanceof TokenNode)?o.getCompareToIndex():o.getLeftmostProperDescendantIndex(); 752 final int thisRCorner = this.getRightmostProperDescendantIndex(); 753 final int thatRCorner = (o instanceof TokenNode)?o.getCompareToIndex():o.getRightmostProperDescendantIndex(); 754 755// if (thisLCorner == -1 || thatLCorner == -1) { 756// if (thisRCorner < thatRCorner) return BEFORE; 757// if (thisRCorner > thatRCorner) return AFTER; 758// } 759// if (thisRCorner == -1 || thatRCorner == -1) { 760// if (thisLCorner < thatLCorner) return BEFORE; 761// if (thisLCorner > thatLCorner) return AFTER; 762// } 763 if (thisLCorner != -1 && thatLCorner != -1 && thisRCorner != -1 && thatRCorner != -1) { 764 if (thisLCorner < thatLCorner && thisRCorner < thatRCorner) return BEFORE; 765 if (thisLCorner > thatLCorner && thisRCorner > thatRCorner) return AFTER; 766 if (thisLCorner > thatLCorner && thisRCorner < thatRCorner) return BEFORE; 767 if (thisLCorner < thatLCorner && thisRCorner > thatRCorner) return AFTER; 768 } else { 769 if (thisLCorner != -1 && thatLCorner != -1) { 770 if (thisLCorner < thatLCorner) return BEFORE; 771 if (thisLCorner > thatLCorner) return AFTER; 772 } 773 if (thisRCorner != -1 && thatRCorner != -1) { 774 if (thisRCorner < thatRCorner) return BEFORE; 775 if (thisRCorner > thatRCorner) return AFTER; 776 } 777 } 778 779// final int thisLCorner = this.getLeftmostDescendantIndex(); 780// final int thatLCorner = (o instanceof TerminalNode)?o.getCompareToIndex():o.getLeftmostDescendantIndex(); 781// final int thisRCorner = this.getRightmostDescendantIndex(); 782// final int thatRCorner = (o instanceof TerminalNode)?o.getCompareToIndex():o.getRightmostDescendantIndex(); 783// 784// if (thisLCorner == -1 || thatLCorner == -1) { 785// if (thisRCorner < thatRCorner) return BEFORE; 786// if (thisRCorner > thatRCorner) return AFTER; 787// } 788// if (thisRCorner == -1 || thatRCorner == -1) { 789// if (thisLCorner < thatLCorner) return BEFORE; 790// if (thisLCorner > thatLCorner) return AFTER; 791// } 792// if (thisLCorner < thatLCorner && thisRCorner < thatRCorner) return BEFORE; 793// if (thisLCorner > thatLCorner && thisRCorner > thatRCorner) return AFTER; 794// if (thisLCorner > thatLCorner && thisRCorner < thatRCorner) return BEFORE; 795// if (thisLCorner < thatLCorner && thisRCorner > thatRCorner) return AFTER; 796 797 798// int thisCorner = this.getLeftmostDescendantIndex(); 799// int thatCorner = (o instanceof TerminalNode)?o.getCompareToIndex():o.getLeftmostDescendantIndex(); 800// if (thisCorner != -1 && thatCorner != -1) { 801// if (thisCorner < thatCorner) return BEFORE; 802// if (thisCorner > thatCorner) return AFTER; 803// } 804// thisCorner = this.getRightmostDescendantIndex(); 805// thatCorner = (o instanceof TerminalNode)?o.getCompareToIndex():o.getRightmostDescendantIndex(); 806// if (thisCorner != -1 && thatCorner != -1) { 807// if (thisCorner < thatCorner) return BEFORE; 808// if (thisCorner > thatCorner) return AFTER; 809// } 810 } catch (MaltChainedException e) { 811 if (SystemLogger.logger().isDebugEnabled()) { 812 SystemLogger.logger().debug("",e); 813 } else { 814 SystemLogger.logger().error(e.getMessageChain()); 815 } 816 System.exit(1); 817 } 818 if (0 < o.getCompareToIndex()) return BEFORE; 819 if (0 > o.getCompareToIndex()) return AFTER; 820 return super.compareTo(o); 821// 822// if (o instanceof TerminalNode) { 823// if (0 == o.getIndex()) { 824// 825// } else if (0 < o.getIndex()) { 826// return -1; 827// } else { 828// return 1; 829// } 830// } else if (o instanceof Root) { 831// return super.compareTo(o); 832// } else if (o instanceof NonTerminalNode) { 833// int lcorner = ((NonTerminalNode)o).getLeftCornerIndex(); 834// if (0 == lcorner) { 835// int rcorner = ((NonTerminalNode)o).getRightCornerIndex(); 836// if (0 == rcorner) { 837// if (0 == o.getIndex()) { 838// return super.compareTo(o); 839// } else if (0 < o.getIndex()) { 840// return 1; 841// } else { 842// return -1; 843// } 844// } else if (0 < rcorner) { 845// return -1; 846// } else { 847// return 1; 848// } 849// } else if (0 < lcorner) { 850// return -1; 851// } else { 852// return 1; 853// } 854// } 855// return super.compareTo(o); 856 } 857 858 public boolean equals(Object obj) { 859 return super.equals(obj); 860 } 861 862 public int hashCode() { 863 return 31 * 7 + super.hashCode(); 864 } 865 866 public String toString() { 867 final StringBuilder sb = new StringBuilder(); 868 sb.append(super.toString()); 869 return sb.toString(); 870 } 871}