5
from pypy.translator.tool.pygame import graphclient
6
content = ["digraph G{"]
7
content.extend(self.dot())
9
p = py.test.ensuretemp("automaton").join("temp.dot")
10
p.write("\n".join(content))
11
graphclient.display_dot_file(str(p))
15
def __init__(self, symbol, additional_info, token):
17
self.additional_info = additional_info
21
return "Symbol(%r, %r)" % (self.symbol, self.additional_info)
24
addinfo = str(self.additional_info).replace('"', "'") or "_"
25
yield ('"%s" [shape=box,label="%s\\n%s"];' % (
26
id(self), self.symbol.replace("\\", "\\\\"),
27
repr(addinfo).replace('"', '').replace("\\", "\\\\")))
29
def visit(self, visitor):
31
if isinstance(visitor, RPythonVisitor):
32
return visitor.dispatch(self)
33
method = getattr(visitor, "visit_" + self.symbol, None)
38
class Nonterminal(Node):
39
def __init__(self, symbol, children):
40
self.children = children
44
return "%s(%s)" % (self.symbol, ", ".join([str(c) for c in self.children]))
47
return "Nonterminal(%r, %r)" % (self.symbol, self.children)
50
yield '"%s" [label="%s"];' % (id(self), self.symbol)
51
for child in self.children:
52
yield '"%s" -> "%s";' % (id(self), id(child))
53
for line in child.dot():
56
def visit(self, visitor):
58
if isinstance(visitor, RPythonVisitor):
59
visitor.dispatch(self)
60
general = getattr(visitor, "visit", None)
62
return getattr(visitor, "visit_" + self.symbol)(self)
64
specific = getattr(visitor, "visit_" + self.symbol, None)
70
class VisitError(Exception):
71
def __init__(self, node):
76
return "could not visit %s" % (self.node, )
78
def make_dispatch_function(__general_nonterminal_visit=None,
79
__general_symbol_visit=None,
82
def dispatch(self, node):
83
if isinstance(node, Nonterminal):
84
if node.symbol not in dispatch_table:
85
if __general_nonterminal_visit:
86
return __general_nonterminal_visit(self, node)
88
return __general_visit(self, node)
90
raise VisitError(node)
92
return dispatch_table[node.symbol](self, node)
93
if isinstance(node, Symbol):
94
if node.symbol not in dispatch_table:
95
if __general_symbol_visit:
96
return __general_symbol_visit(self, node)
98
return __general_visit(self, node)
100
raise VisitError(node)
102
return dispatch_table[node.symbol](self, node)
103
raise VisitError(node)
106
class CreateDispatchDictionaryMetaclass(type):
107
def __new__(cls, name_, bases, dct):
109
for name, value in dct.iteritems():
110
if name.startswith("visit_"):
111
dispatch_table[name[len("visit_"):]] = value
112
for special in ["general_symbol_visit",
113
"general_nonterminal_visit",
116
dispatch_table["__" + special] = dct[special]
117
dct["dispatch"] = make_dispatch_function(**dispatch_table)
118
return type.__new__(cls, name_, bases, dct)
120
class RPythonVisitor(object):
121
__metaclass__ = CreateDispatchDictionaryMetaclass