File: visitor.py

package info (click to toggle)
sphinx-a4doc 1.6.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,092 kB
  • sloc: python: 9,560; makefile: 15
file content (142 lines) | stat: -rw-r--r-- 4,205 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
from weakref import WeakKeyDictionary

from sphinx_a4doc.model.model import RuleBase, LexerRule, ParserRule

from typing import *


__all__ = [
    'RuleContentVisitor',
    'CachedRuleContentVisitor',
]


T = TypeVar('T')


class RuleContentVisitor(Generic[T]):
    """
    Generic visitor for rule contents.

    """

    def visit(self, r: RuleBase.RuleContent) -> T:
        return getattr(self, r.__meta__.visitor_relay, self.visit_default)(r)

    def visit_default(self, r: RuleBase.RuleContent) -> T:
        raise RuntimeError(f'no visitor for {r.__class__.__name__!r}')

    # Lexer

    def visit_lexer_literal(self, r: LexerRule.Literal) -> T:
        return self.visit_literal(r)

    def visit_lexer_range(self, r: LexerRule.Range) -> T:
        return self.visit_range(r)

    def visit_lexer_charset(self, r: LexerRule.CharSet) -> T:
        return self.visit_charset(r)

    def visit_lexer_reference(self, r: LexerRule.Reference) -> T:
        return self.visit_reference(r)

    def visit_lexer_doc(self, r: LexerRule.Doc) -> T:
        return self.visit_doc(r)

    def visit_lexer_wildcard(self, r: LexerRule.Wildcard) -> T:
        return self.visit_wildcard(r)

    def visit_lexer_negation(self, r: LexerRule.Negation) -> T:
        return self.visit_negation(r)

    def visit_lexer_zero_plus(self, r: LexerRule.ZeroPlus) -> T:
        return self.visit_zero_plus(r)

    def visit_lexer_one_plus(self, r: LexerRule.OnePlus) -> T:
        return self.visit_one_plus(r)

    def visit_lexer_maybe(self, r: LexerRule.Maybe) -> T:
        return self.visit_maybe(r)

    def visit_lexer_sequence(self, r: LexerRule.Sequence) -> T:
        return self.visit_sequence(r)

    def visit_lexer_alternative(self, r: LexerRule.Alternative) -> T:
        return self.visit_alternative(r)

    # Parser

    def visit_parser_reference(self, r: ParserRule.Reference) -> T:
        return self.visit_reference(r)

    def visit_parser_doc(self, r: ParserRule.Doc) -> T:
        return self.visit_doc(r)

    def visit_parser_wildcard(self, r: ParserRule.Wildcard) -> T:
        return self.visit_wildcard(r)

    def visit_parser_negation(self, r: ParserRule.Negation) -> T:
        return self.visit_negation(r)

    def visit_parser_zero_plus(self, r: ParserRule.ZeroPlus) -> T:
        return self.visit_zero_plus(r)

    def visit_parser_one_plus(self, r: ParserRule.OnePlus) -> T:
        return self.visit_one_plus(r)

    def visit_parser_maybe(self, r: ParserRule.Maybe) -> T:
        return self.visit_maybe(r)

    def visit_parser_sequence(self, r: ParserRule.Sequence) -> T:
        return self.visit_sequence(r)

    def visit_parser_alternative(self, r: ParserRule.Alternative) -> T:
        return self.visit_alternative(r)

    # Common

    def visit_literal(self, r: LexerRule.Literal) -> T:
        return self.visit_default(r)

    def visit_range(self, r: LexerRule.Range) -> T:
        return self.visit_default(r)

    def visit_charset(self, r: LexerRule.CharSet) -> T:
        return self.visit_default(r)

    def visit_reference(self, r: RuleBase.Reference) -> T:
        return self.visit_default(r)

    def visit_doc(self, r: RuleBase.Doc) -> T:
        return self.visit_default(r)

    def visit_wildcard(self, r: RuleBase.Wildcard) -> T:
        return self.visit_default(r)

    def visit_negation(self, r: RuleBase.Negation) -> T:
        return self.visit_default(r)

    def visit_zero_plus(self, r: RuleBase.ZeroPlus) -> T:
        return self.visit_default(r)

    def visit_one_plus(self, r: RuleBase.OnePlus) -> T:
        return self.visit_default(r)

    def visit_maybe(self, r: RuleBase.Maybe) -> T:
        return self.visit_default(r)

    def visit_sequence(self, r: RuleBase.Sequence) -> T:
        return self.visit_default(r)

    def visit_alternative(self, r: RuleBase.Alternative) -> T:
        return self.visit_default(r)


class CachedRuleContentVisitor(RuleContentVisitor[T]):
    def __init__(self):
        self._cache: Dict[RuleBase.RuleContent, T] = WeakKeyDictionary()

    def visit(self, r: RuleBase.RuleContent) -> T:
        if r not in self._cache:
            self._cache[r] = super().visit(r)
        return self._cache[r]