graph_vals.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import pydotplus.graphviz as pdp
  2. import sys
  3. import re
  4. def parse(str_in, alias=None):
  5. str_in = "("+str_in+")"
  6. ends = {}
  7. nests = {}
  8. names = {}
  9. styles = {}
  10. parens = []
  11. name = ""
  12. name_start = 0
  13. name_end = 0
  14. for i, char in enumerate(str_in):
  15. if char == "(":
  16. nests[name_start] = []
  17. if parens:
  18. nests[parens[-1]].append(name_start)
  19. names[name_start] = name # save function name
  20. styles[name_start] = {"shape": "ellipse"}
  21. name = ""
  22. parens.append(name_start)
  23. elif char == ")":
  24. if name:
  25. ends[name_start] = name_end
  26. names[name_start] = name
  27. styles[name_start] = {"shape": "rectangle"}
  28. nests[parens[-1]].append(name_start)
  29. name = ""
  30. ends[parens.pop()] = i
  31. elif char in ",:":
  32. if name:
  33. ends[name_start] = name_end
  34. names[name_start] = name
  35. if char == ",":
  36. styles[name_start] = {"shape": "rectangle"}
  37. else:
  38. styles[name_start] = {"shape": "invhouse"}
  39. nests[parens[-1]].append(name_start)
  40. name = ""
  41. else:
  42. if not name:
  43. name_start = i
  44. name += char
  45. name_end = i
  46. # clean up duplicate sub-trees
  47. text = {}
  48. for start, end in ends.items():
  49. s = str_in[start:end+1]
  50. if s in text:
  51. dup_id = text[s]
  52. names.pop(start)
  53. if start in nests:
  54. nests.pop(start)
  55. for l in nests.values():
  56. for i in range(len(l)):
  57. if l[i] == start:
  58. l[i] = dup_id
  59. else:
  60. text[s] = start
  61. names.pop(0)
  62. nests.pop(0)
  63. g = pdp.Dot()
  64. for id_, name in names.items():
  65. g.add_node(pdp.Node(str(id_), label=name, **styles[id_]))
  66. for group_id, children in nests.items():
  67. for child_id in children:
  68. g.add_edge(pdp.Edge(str(group_id), str(child_id)))
  69. if alias:
  70. g.add_node(pdp.Node(alias, shape="plain", pos="0,0!"))
  71. return g
  72. if __name__ == '__main__':
  73. aliases = {}
  74. ali_re = re.compile(r"ALIAS::\"([^\"]*)\" referring to \"([^\"]*)\"")
  75. with open(sys.argv[1]) as f:
  76. for line in f.readlines():
  77. res = ali_re.findall(line)
  78. if res:
  79. aliases[res[0][1]] = res[0][0]
  80. continue
  81. for name, alias in aliases.items():
  82. graph = parse(name, alias)
  83. fname = "val_graph_{}.gif".format(alias)
  84. with open(fname, "wb") as f:
  85. try:
  86. f.write(graph.create_gif())
  87. except Exception as e:
  88. print(e)
  89. print(graph.to_string())