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 Matchers that call the regular expression engine.
32
33 These are used internally for rewriting; users typically use `Regexp` which
34 calls the standard Python regular expression library (and so is faster).
35 '''
36
37 from lepl.matchers.support import Transformable, NoTrampoline
38 from lepl.matchers.transform import raise_
39 from lepl.core.parser import tagged
40 from lepl.regexp.core import Compiler
41 from lepl.regexp.unicode import UnicodeAlphabet
42
43
44
45
46 -class BaseRegexp(NoTrampoline, Transformable):
47 '''
48 Common code for all matchers.
49 '''
50
51
52
53 - def __init__(self, regexp, alphabet=None):
57
59 '''
60 Implement the Transformable interface.
61 '''
62 copy = type(self)(self.regexp, self.alphabet)
63 copy.wrapper = self.wrapper.compose(wrapper)
64 return copy
65
66 @tagged
68 '''
69 Delegate to the implementation.
70 '''
71 for result in self._untagged_match(stream_in):
72 yield result
73
76 '''
77 A matcher for NFA-based regular expressions. This will yield alternative
78 matches.
79
80 This doesn't suffer from the same limitations as `Regexp` (it can "see"
81 all the input data, if necessary), but currently has quite basic syntax
82 and no grouping (the syntax may improve, but grouping will not be added -
83 use LEPL itself for complex problems).
84 '''
85
86 - def __init__(self, regexp, alphabet=None):
90
92 '''
93 Compile the matcher.
94 '''
95 if self.__cached_matcher is None:
96 self.__cached_matcher = \
97 Compiler.single(self.alphabet, self.regexp).nfa().match
98 return self.__cached_matcher
99
101 '''
102 Actually do the work of matching.
103 '''
104 function = self.wrapper.function
105 matches = self._compile()(stream_in)
106 for (_terminal, match, stream_out) in matches:
107 yield function(stream_in, lambda: ([match], stream_out)) \
108 if function else ([match], stream_out)
109 while True:
110 yield function(stream_in, lambda: raise_(StopIteration))
111
114 '''
115 A matcher for DFA-based regular expressions. This yields a single greedy
116 match.
117
118 Typically used only in specialised situations (see `Regexp`).
119 '''
120
121 - def __init__(self, regexp, alphabet=None):
125
127 '''
128 Compile the matcher.
129 '''
130 if self.__cached_matcher is None:
131 self.__cached_matcher = \
132 Compiler.single(self.alphabet, self.regexp).dfa().match
133 return self.__cached_matcher
134
136 '''
137 Actually do the work of matching.
138 '''
139 function = self.wrapper.function
140 match = self._compile()(stream_in)
141 if match is not None:
142 (_terminals, match, stream_out) = match
143 yield function(stream_in, lambda: ([match], stream_out)) \
144 if function else ([match], stream_out)
145 while True:
146 yield function(stream_in, lambda: raise_(StopIteration))
147