PageRenderTime 64ms CodeModel.GetById 32ms RepoModel.GetById 1ms app.codeStats 0ms

/antlr-3.4/tool/src/main/java/org/antlr/misc/Graph.java

https://bitbucket.org/cyanogenmod/android_external_antlr
Java | 107 lines | 51 code | 11 blank | 45 comment | 9 complexity | 8bea92c47f1c180702d02aa395751495 MD5 | raw file
  1. /*
  2. * [The "BSD license"]
  3. * Copyright (c) 2010 Terence Parr
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. The name of the author may not be used to endorse or promote products
  15. * derived from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. package org.antlr.misc;
  29. import java.util.*;
  30. /** A generic graph with edges; Each node as a single Object payload.
  31. * This is only used to topologically sort a list of file dependencies
  32. * at the moment.
  33. */
  34. public class Graph {
  35. public static class Node {
  36. Object payload;
  37. List<Node> edges; // points at which nodes?
  38. public Node(Object payload) { this.payload = payload; }
  39. public void addEdge(Node n) {
  40. if ( edges==null ) edges = new ArrayList<Node>();
  41. if ( !edges.contains(n) ) edges.add(n);
  42. }
  43. public String toString() { return payload.toString(); }
  44. }
  45. /** Map from node payload to node containing it */
  46. protected Map<Object,Node> nodes = new HashMap<Object,Node>();
  47. public void addEdge(Object a, Object b) {
  48. //System.out.println("add edge "+a+" to "+b);
  49. Node a_node = getNode(a);
  50. Node b_node = getNode(b);
  51. a_node.addEdge(b_node);
  52. }
  53. protected Node getNode(Object a) {
  54. Node existing = nodes.get(a);
  55. if ( existing!=null ) return existing;
  56. Node n = new Node(a);
  57. nodes.put(a, n);
  58. return n;
  59. }
  60. /** DFS-based topological sort. A valid sort is the reverse of
  61. * the post-order DFA traversal. Amazingly simple but true.
  62. * For sorting, I'm not following convention here since ANTLR
  63. * needs the opposite. Here's what I assume for sorting:
  64. *
  65. * If there exists an edge u -> v then u depends on v and v
  66. * must happen before u.
  67. *
  68. * So if this gives nonreversed postorder traversal, I get the order
  69. * I want.
  70. */
  71. public List<Object> sort() {
  72. Set<Node> visited = new OrderedHashSet<Node>();
  73. ArrayList<Object> sorted = new ArrayList<Object>();
  74. while ( visited.size() < nodes.size() ) {
  75. // pick any unvisited node, n
  76. Node n = null;
  77. for (Iterator it = nodes.values().iterator(); it.hasNext();) {
  78. n = (Node)it.next();
  79. if ( !visited.contains(n) ) break;
  80. }
  81. DFS(n, visited, sorted);
  82. }
  83. return sorted;
  84. }
  85. public void DFS(Node n, Set<Node> visited, ArrayList<Object> sorted) {
  86. if ( visited.contains(n) ) return;
  87. visited.add(n);
  88. if ( n.edges!=null ) {
  89. for (Iterator it = n.edges.iterator(); it.hasNext();) {
  90. Node target = (Node) it.next();
  91. DFS(target, visited, sorted);
  92. }
  93. }
  94. sorted.add(n.payload);
  95. }
  96. }