~ubuntu-branches/ubuntu/karmic/pypy/karmic

« back to all changes in this revision

Viewing changes to pypy/rlib/parsing/tree.py

  • Committer: Bazaar Package Importer
  • Author(s): Alexandre Fayolle
  • Date: 2007-04-13 09:33:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070413093309-yoojh4jcoocu2krz
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import py
 
2
 
 
3
class Node(object):
 
4
    def view(self):
 
5
        from pypy.translator.tool.pygame import graphclient
 
6
        content = ["digraph G{"]
 
7
        content.extend(self.dot())
 
8
        content.append("}")
 
9
        p = py.test.ensuretemp("automaton").join("temp.dot")
 
10
        p.write("\n".join(content))
 
11
        graphclient.display_dot_file(str(p))
 
12
 
 
13
class Symbol(Node):
 
14
 
 
15
    def __init__(self, symbol, additional_info, token):
 
16
        self.symbol = symbol
 
17
        self.additional_info = additional_info
 
18
        self.token = token
 
19
    
 
20
    def __repr__(self):
 
21
        return "Symbol(%r, %r)" % (self.symbol, self.additional_info)
 
22
 
 
23
    def dot(self):
 
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("\\", "\\\\")))
 
28
 
 
29
    def visit(self, visitor):
 
30
        "NOT_RPYTHON"
 
31
        if isinstance(visitor, RPythonVisitor):
 
32
            return visitor.dispatch(self)
 
33
        method = getattr(visitor, "visit_" + self.symbol, None)
 
34
        if method is None:
 
35
            return self
 
36
        return method(self)
 
37
 
 
38
class Nonterminal(Node):
 
39
    def __init__(self, symbol, children):
 
40
        self.children = children
 
41
        self.symbol = symbol
 
42
 
 
43
    def __str__(self):
 
44
        return "%s(%s)" % (self.symbol, ", ".join([str(c) for c in self.children]))
 
45
 
 
46
    def __repr__(self):
 
47
        return "Nonterminal(%r, %r)" % (self.symbol, self.children)
 
48
 
 
49
    def dot(self):
 
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():
 
54
                yield line
 
55
 
 
56
    def visit(self, visitor):
 
57
        "NOT_RPYTHON"
 
58
        if isinstance(visitor, RPythonVisitor):
 
59
            visitor.dispatch(self)
 
60
        general = getattr(visitor, "visit", None)
 
61
        if general is None:
 
62
            return getattr(visitor, "visit_" + self.symbol)(self)
 
63
        else:
 
64
            specific = getattr(visitor, "visit_" + self.symbol, None)
 
65
            if specific is None:
 
66
                return general(self)
 
67
            else:
 
68
                return specific(self)
 
69
 
 
70
class VisitError(Exception):
 
71
    def __init__(self, node):
 
72
        self.node = node
 
73
        self.args = (node, )
 
74
 
 
75
    def __str__(self):
 
76
        return "could not visit %s" % (self.node, )
 
77
 
 
78
def make_dispatch_function(__general_nonterminal_visit=None,
 
79
                           __general_symbol_visit=None,
 
80
                           __general_visit=None,
 
81
                           **dispatch_table):
 
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)
 
87
                elif __general_visit:
 
88
                    return __general_visit(self, node)
 
89
                else:
 
90
                    raise VisitError(node)
 
91
            else:
 
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)
 
97
                elif __general_visit:
 
98
                    return __general_visit(self, node)
 
99
                else:
 
100
                    raise VisitError(node)
 
101
            else:
 
102
                return dispatch_table[node.symbol](self, node)
 
103
        raise VisitError(node)
 
104
    return dispatch
 
105
 
 
106
class CreateDispatchDictionaryMetaclass(type):
 
107
    def __new__(cls, name_, bases, dct):
 
108
        dispatch_table = {}
 
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",
 
114
                        "general_visit"]:
 
115
            if special in dct:
 
116
                dispatch_table["__" + special] = dct[special]
 
117
        dct["dispatch"] = make_dispatch_function(**dispatch_table)
 
118
        return type.__new__(cls, name_, bases, dct)
 
119
 
 
120
class RPythonVisitor(object):
 
121
    __metaclass__ = CreateDispatchDictionaryMetaclass