omextra 0.0.0.dev467__py3-none-any.whl → 0.0.0.dev487__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- omextra/__about__.py +2 -0
- omextra/asyncs/bridge.py +1 -1
- omextra/collections/__init__.py +0 -0
- omextra/collections/hamt/LICENSE +35 -0
- omextra/collections/hamt/__init__.py +0 -0
- omextra/collections/hamt/_hamt.c +3621 -0
- omextra/formats/goyaml/LICENSE +16 -0
- omextra/formats/goyaml/__init__.py +29 -0
- omextra/formats/goyaml/ast.py +2217 -0
- omextra/formats/goyaml/errors.py +49 -0
- omextra/formats/goyaml/parsing.py +2332 -0
- omextra/formats/goyaml/scanning.py +1888 -0
- omextra/formats/goyaml/tokens.py +998 -0
- omextra/text/abnf/LICENSE +16 -0
- omextra/text/abnf/__init__.py +79 -0
- omextra/text/abnf/base.py +313 -0
- omextra/text/abnf/core.py +141 -0
- omextra/text/abnf/errors.py +10 -0
- omextra/text/abnf/meta.py +583 -0
- omextra/text/abnf/parsers.py +343 -0
- omextra/text/abnf/utils.py +76 -0
- omextra/text/abnf/visitors.py +55 -0
- {omextra-0.0.0.dev467.dist-info → omextra-0.0.0.dev487.dist-info}/METADATA +9 -4
- {omextra-0.0.0.dev467.dist-info → omextra-0.0.0.dev487.dist-info}/RECORD +28 -8
- {omextra-0.0.0.dev467.dist-info → omextra-0.0.0.dev487.dist-info}/WHEEL +0 -0
- {omextra-0.0.0.dev467.dist-info → omextra-0.0.0.dev487.dist-info}/entry_points.txt +0 -0
- {omextra-0.0.0.dev467.dist-info → omextra-0.0.0.dev487.dist-info}/licenses/LICENSE +0 -0
- {omextra-0.0.0.dev467.dist-info → omextra-0.0.0.dev487.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import typing as ta
|
|
2
|
+
|
|
3
|
+
from omlish import check
|
|
4
|
+
from omlish import dataclasses as dc
|
|
5
|
+
from omlish import lang
|
|
6
|
+
|
|
7
|
+
from .base import Match
|
|
8
|
+
from .base import Parser
|
|
9
|
+
from .base import _Context
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Literal(Parser, lang.Abstract):
|
|
16
|
+
def _match_repr(self) -> str:
|
|
17
|
+
return repr(self)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class StringLiteral(Literal):
|
|
21
|
+
def __init__(self, value: str) -> None:
|
|
22
|
+
super().__init__()
|
|
23
|
+
|
|
24
|
+
self._value = check.non_empty_str(value)
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def value(self) -> str:
|
|
28
|
+
return self._value
|
|
29
|
+
|
|
30
|
+
def __repr__(self) -> str:
|
|
31
|
+
return f'{self.__class__.__name__}@{id(self):x}({self._value!r})'
|
|
32
|
+
|
|
33
|
+
def _iter_parse(self, ctx: _Context, start: int) -> ta.Iterator[Match]:
|
|
34
|
+
if start < len(ctx._source): # noqa
|
|
35
|
+
source = ctx._source[start : start + len(self._value)] # noqa
|
|
36
|
+
if source == self._value:
|
|
37
|
+
yield Match(self, start, start + len(source), ())
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class CaseInsensitiveStringLiteral(Literal):
|
|
41
|
+
def __init__(self, value: str) -> None:
|
|
42
|
+
super().__init__()
|
|
43
|
+
|
|
44
|
+
self._value = check.non_empty_str(value).casefold()
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def value(self) -> str:
|
|
48
|
+
return self._value
|
|
49
|
+
|
|
50
|
+
def __repr__(self) -> str:
|
|
51
|
+
return f'{self.__class__.__name__}@{id(self):x}({self._value!r})'
|
|
52
|
+
|
|
53
|
+
def _iter_parse(self, ctx: _Context, start: int) -> ta.Iterator[Match]:
|
|
54
|
+
if start < len(ctx._source): # noqa
|
|
55
|
+
source = ctx._source[start : start + len(self._value)].casefold() # noqa
|
|
56
|
+
if source == self._value:
|
|
57
|
+
yield Match(self, start, start + len(source), ())
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class RangeLiteral(Literal):
|
|
61
|
+
@dc.dataclass(frozen=True)
|
|
62
|
+
class Range:
|
|
63
|
+
lo: str
|
|
64
|
+
hi: str
|
|
65
|
+
|
|
66
|
+
def __post_init__(self) -> None:
|
|
67
|
+
check.non_empty_str(self.lo)
|
|
68
|
+
check.non_empty_str(self.hi)
|
|
69
|
+
check.state(self.hi >= self.lo)
|
|
70
|
+
|
|
71
|
+
def __init__(self, value: Range) -> None:
|
|
72
|
+
super().__init__()
|
|
73
|
+
|
|
74
|
+
self._value = check.isinstance(value, RangeLiteral.Range)
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def value(self) -> Range:
|
|
78
|
+
return self._value
|
|
79
|
+
|
|
80
|
+
def __repr__(self) -> str:
|
|
81
|
+
return f'{self.__class__.__name__}@{id(self):x}({self._value!r})'
|
|
82
|
+
|
|
83
|
+
def _iter_parse(self, ctx: _Context, start: int) -> ta.Iterator[Match]:
|
|
84
|
+
try:
|
|
85
|
+
source = ctx._source[start] # noqa
|
|
86
|
+
except IndexError:
|
|
87
|
+
return
|
|
88
|
+
# ranges are always case-sensitive
|
|
89
|
+
if (value := self._value).lo <= source <= value.hi:
|
|
90
|
+
yield Match(self, start, start + 1, ())
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@ta.overload
|
|
94
|
+
def literal(s: str, *, case_sensitive: bool = False) -> StringLiteral:
|
|
95
|
+
...
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@ta.overload
|
|
99
|
+
def literal(lo: str, hi: str) -> RangeLiteral:
|
|
100
|
+
...
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def literal(*args, case_sensitive=None):
|
|
104
|
+
if not args:
|
|
105
|
+
raise TypeError
|
|
106
|
+
elif len(args) == 1:
|
|
107
|
+
s = check.isinstance(check.single(args), str)
|
|
108
|
+
if case_sensitive:
|
|
109
|
+
return StringLiteral(s)
|
|
110
|
+
else:
|
|
111
|
+
return CaseInsensitiveStringLiteral(s)
|
|
112
|
+
elif len(args) == 2:
|
|
113
|
+
check.none(case_sensitive)
|
|
114
|
+
return RangeLiteral(RangeLiteral.Range(*map(check.of_isinstance(str), args)))
|
|
115
|
+
else:
|
|
116
|
+
raise TypeError(args)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
##
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class Concat(Parser):
|
|
123
|
+
def __init__(self, *children: Parser) -> None:
|
|
124
|
+
super().__init__()
|
|
125
|
+
|
|
126
|
+
for c in check.not_empty(children):
|
|
127
|
+
check.isinstance(c, Parser)
|
|
128
|
+
self._children = children
|
|
129
|
+
|
|
130
|
+
@property
|
|
131
|
+
def children(self) -> ta.Sequence[Parser]:
|
|
132
|
+
return self._children
|
|
133
|
+
|
|
134
|
+
def __repr__(self) -> str:
|
|
135
|
+
return f'{self.__class__.__name__}@{id(self):x}({", ".join(map(repr, self._children))})'
|
|
136
|
+
|
|
137
|
+
def _iter_parse(self, ctx: _Context, start: int) -> ta.Iterator[Match]:
|
|
138
|
+
i = 0
|
|
139
|
+
match_tups: list[tuple[Match, ...]] = [()]
|
|
140
|
+
for cp in self._children:
|
|
141
|
+
next_match_tups: list[tuple[Match, ...]] = []
|
|
142
|
+
for mt in match_tups:
|
|
143
|
+
for cm in ctx.iter_parse(cp, mt[-1].end if mt else start):
|
|
144
|
+
next_match_tups.append((*mt, cm))
|
|
145
|
+
i += 1
|
|
146
|
+
if not next_match_tups:
|
|
147
|
+
return
|
|
148
|
+
match_tups = next_match_tups
|
|
149
|
+
if not i:
|
|
150
|
+
return
|
|
151
|
+
for mt in sorted(match_tups, key=len, reverse=True):
|
|
152
|
+
yield Match(self, start, mt[-1].end if mt else start, mt)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
concat = Concat
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
##
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class Repeat(Parser):
|
|
162
|
+
@dc.dataclass(frozen=True)
|
|
163
|
+
class Times:
|
|
164
|
+
min: int = 0
|
|
165
|
+
max: int | None = None
|
|
166
|
+
|
|
167
|
+
def __post_init__(self) -> None:
|
|
168
|
+
if self.max is not None:
|
|
169
|
+
check.state(self.max >= self.min)
|
|
170
|
+
|
|
171
|
+
def __repr__(self) -> str:
|
|
172
|
+
return f'{self.__class__.__name__}({self.min}{f", {self.max!r}" if self.max is not None else ""})'
|
|
173
|
+
|
|
174
|
+
def __init__(self, times: Times, child: Parser) -> None:
|
|
175
|
+
super().__init__()
|
|
176
|
+
|
|
177
|
+
self._times = check.isinstance(times, Repeat.Times)
|
|
178
|
+
self._child = check.isinstance(child, Parser)
|
|
179
|
+
|
|
180
|
+
@property
|
|
181
|
+
def times(self) -> Times:
|
|
182
|
+
return self._times
|
|
183
|
+
|
|
184
|
+
@property
|
|
185
|
+
def child(self) -> Parser:
|
|
186
|
+
return self._child
|
|
187
|
+
|
|
188
|
+
def __repr__(self) -> str:
|
|
189
|
+
return f'{self.__class__.__name__}@{id(self):x}({self._times}, {self._child!r})'
|
|
190
|
+
|
|
191
|
+
def _iter_parse(self, ctx: _Context, start: int) -> ta.Iterator[Match]:
|
|
192
|
+
match_tup_set: set[tuple[Match, ...]] = set()
|
|
193
|
+
last_match_tup_set: set[tuple[Match, ...]] = {()}
|
|
194
|
+
i = 0
|
|
195
|
+
while True:
|
|
196
|
+
if self._times.max is not None and i == self._times.max:
|
|
197
|
+
break
|
|
198
|
+
next_match_tup_set: set[tuple[Match, ...]] = set()
|
|
199
|
+
for mt in last_match_tup_set:
|
|
200
|
+
for cm in ctx.iter_parse(self._child, mt[-1].end if mt else start):
|
|
201
|
+
next_match_tup_set.add((*mt, cm))
|
|
202
|
+
if not next_match_tup_set or next_match_tup_set < match_tup_set:
|
|
203
|
+
break
|
|
204
|
+
i += 1
|
|
205
|
+
match_tup_set |= next_match_tup_set
|
|
206
|
+
last_match_tup_set = next_match_tup_set
|
|
207
|
+
if i < self._times.min:
|
|
208
|
+
return
|
|
209
|
+
for mt in sorted(match_tup_set or [()], key=len, reverse=True):
|
|
210
|
+
yield Match(self, start, mt[-1].end if mt else start, mt) # noqa
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
class Option(Repeat):
|
|
214
|
+
def __init__(self, child: Parser) -> None:
|
|
215
|
+
super().__init__(Repeat.Times(0, 1), child)
|
|
216
|
+
|
|
217
|
+
def __repr__(self) -> str:
|
|
218
|
+
return f'{self.__class__.__name__}@{id(self):x}({self._child!r})'
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
option = Option
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
@ta.overload
|
|
225
|
+
def repeat(child: Parser) -> Repeat: # noqa
|
|
226
|
+
...
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
@ta.overload
|
|
230
|
+
def repeat(times: Repeat.Times, child: Parser) -> Repeat: # noqa
|
|
231
|
+
...
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
@ta.overload
|
|
235
|
+
def repeat(min: int, child: Parser) -> Repeat: # noqa
|
|
236
|
+
...
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
@ta.overload
|
|
240
|
+
def repeat(min: int, max: int | None, child: Parser) -> Repeat: # noqa
|
|
241
|
+
...
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def repeat(*args):
|
|
245
|
+
min: int # noqa
|
|
246
|
+
max: int | None # noqa
|
|
247
|
+
|
|
248
|
+
if len(args) < 2:
|
|
249
|
+
[child] = args
|
|
250
|
+
min, max = 0, None # noqa
|
|
251
|
+
|
|
252
|
+
elif len(args) > 2:
|
|
253
|
+
min, max, child = args # noqa
|
|
254
|
+
|
|
255
|
+
else:
|
|
256
|
+
ti, child = args # noqa
|
|
257
|
+
|
|
258
|
+
if isinstance(ti, Repeat.Times):
|
|
259
|
+
min, max = ti.min, ti.max # noqa
|
|
260
|
+
|
|
261
|
+
else:
|
|
262
|
+
min, max = ti, None # noqa
|
|
263
|
+
|
|
264
|
+
if (min, max) == (0, 1):
|
|
265
|
+
return Option(check.isinstance(child, Parser))
|
|
266
|
+
|
|
267
|
+
else:
|
|
268
|
+
return Repeat(
|
|
269
|
+
Repeat.Times(
|
|
270
|
+
check.isinstance(min, int),
|
|
271
|
+
check.isinstance(max, (int, None)),
|
|
272
|
+
),
|
|
273
|
+
check.isinstance(child, Parser),
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
##
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
class Either(Parser):
|
|
281
|
+
def __init__(self, *children: Parser, first_match: bool = False) -> None:
|
|
282
|
+
super().__init__()
|
|
283
|
+
|
|
284
|
+
for c in check.not_empty(children):
|
|
285
|
+
check.isinstance(c, Parser)
|
|
286
|
+
self._children = children
|
|
287
|
+
self._first_match = first_match
|
|
288
|
+
|
|
289
|
+
@property
|
|
290
|
+
def children(self) -> ta.Sequence[Parser]:
|
|
291
|
+
return self._children
|
|
292
|
+
|
|
293
|
+
@property
|
|
294
|
+
def first_match(self) -> bool:
|
|
295
|
+
return self._first_match
|
|
296
|
+
|
|
297
|
+
def __repr__(self) -> str:
|
|
298
|
+
return (
|
|
299
|
+
f'{self.__class__.__name__}@{id(self):x}('
|
|
300
|
+
f'{", ".join(map(repr, self._children))}'
|
|
301
|
+
f'{", first_match=True" if self._first_match else ""})'
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
def _iter_parse(self, ctx: _Context, start: int) -> ta.Iterator[Match]:
|
|
305
|
+
for cp in self._children:
|
|
306
|
+
found = False
|
|
307
|
+
for cm in ctx.iter_parse(cp, start):
|
|
308
|
+
found = True
|
|
309
|
+
yield Match(self, start, cm.end, (cm,))
|
|
310
|
+
if found and self._first_match:
|
|
311
|
+
return
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
either = Either
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
##
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
class RuleRef(Parser):
|
|
321
|
+
def __init__(self, name: str) -> None:
|
|
322
|
+
super().__init__()
|
|
323
|
+
|
|
324
|
+
self._name = check.non_empty_str(name)
|
|
325
|
+
self._name_f = name.casefold()
|
|
326
|
+
|
|
327
|
+
@property
|
|
328
|
+
def name(self) -> str:
|
|
329
|
+
return self._name
|
|
330
|
+
|
|
331
|
+
def __repr__(self) -> str:
|
|
332
|
+
return f'{self.__class__.__name__}@{id(self):x}({self._name!r})'
|
|
333
|
+
|
|
334
|
+
def _match_repr(self) -> str:
|
|
335
|
+
return repr(self)
|
|
336
|
+
|
|
337
|
+
def _iter_parse(self, ctx: _Context, start: int) -> ta.Iterator[Match]:
|
|
338
|
+
cp = ctx._grammar._rules_by_name_f[self._name_f].parser # noqa
|
|
339
|
+
for cm in ctx.iter_parse(cp, start):
|
|
340
|
+
yield Match(self, cm.start, cm.end, (cm,))
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
rule = RuleRef
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import itertools
|
|
2
|
+
import textwrap
|
|
3
|
+
import typing as ta
|
|
4
|
+
|
|
5
|
+
from omlish import check
|
|
6
|
+
|
|
7
|
+
from .base import Grammar
|
|
8
|
+
from .base import Match
|
|
9
|
+
from .errors import AbnfIncompleteParseError
|
|
10
|
+
from .parsers import RuleRef
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
##
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def strip_insignificant_match_rules(m: Match, g: Grammar) -> Match:
|
|
17
|
+
def rec(c: Match) -> Match:
|
|
18
|
+
return c.flat_map_children(
|
|
19
|
+
lambda x: (
|
|
20
|
+
(rec(x),) if not (
|
|
21
|
+
isinstance((xp := x.parser), RuleRef) and
|
|
22
|
+
check.not_none(g.rule(xp.name)).insignificant
|
|
23
|
+
) else ()
|
|
24
|
+
),
|
|
25
|
+
)
|
|
26
|
+
return rec(m)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def only_match_rules(m: Match) -> Match:
|
|
30
|
+
def rec(c: Match) -> ta.Iterable[Match]:
|
|
31
|
+
if isinstance(c.parser, RuleRef):
|
|
32
|
+
return (c.flat_map_children(rec),)
|
|
33
|
+
else:
|
|
34
|
+
return itertools.chain.from_iterable(map(rec, c.children))
|
|
35
|
+
return m.flat_map_children(rec)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
#
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def parse_rules(
|
|
42
|
+
grammar: Grammar,
|
|
43
|
+
source: str,
|
|
44
|
+
root: str | None = None,
|
|
45
|
+
*,
|
|
46
|
+
start: int = 0,
|
|
47
|
+
complete: bool = False,
|
|
48
|
+
**kwargs: ta.Any,
|
|
49
|
+
) -> Match | None:
|
|
50
|
+
if (match := grammar.parse(
|
|
51
|
+
source,
|
|
52
|
+
root,
|
|
53
|
+
start=start,
|
|
54
|
+
**kwargs,
|
|
55
|
+
)) is None:
|
|
56
|
+
return None
|
|
57
|
+
|
|
58
|
+
if complete and (match.start, match.end) != (start, len(source)):
|
|
59
|
+
raise AbnfIncompleteParseError
|
|
60
|
+
|
|
61
|
+
match = only_match_rules(match)
|
|
62
|
+
match = strip_insignificant_match_rules(match, grammar)
|
|
63
|
+
|
|
64
|
+
return match
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
##
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def fix_grammar_ws(s: str) -> str:
|
|
71
|
+
return (
|
|
72
|
+
textwrap.dedent(s)
|
|
73
|
+
.rstrip()
|
|
74
|
+
.replace('\r', '')
|
|
75
|
+
.replace('\n', '\r\n')
|
|
76
|
+
) + '\r\n'
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import typing as ta
|
|
2
|
+
|
|
3
|
+
from omlish import check
|
|
4
|
+
from omlish import collections as col
|
|
5
|
+
from omlish import dispatch
|
|
6
|
+
from omlish import lang
|
|
7
|
+
|
|
8
|
+
from .base import Match
|
|
9
|
+
from .base import Parser
|
|
10
|
+
from .parsers import RuleRef
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
T = ta.TypeVar('T')
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
##
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ParserVisitor(lang.Abstract, ta.Generic[T]):
|
|
20
|
+
@dispatch.method()
|
|
21
|
+
def visit_parser(self, p: Parser, m: Match) -> T:
|
|
22
|
+
raise TypeError(p)
|
|
23
|
+
|
|
24
|
+
#
|
|
25
|
+
|
|
26
|
+
def visit_match(self, m: Match) -> T:
|
|
27
|
+
return self.visit_parser(m.parser, m)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
##
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class RuleVisitor(lang.Abstract, ta.Generic[T]):
|
|
34
|
+
_registry = col.AttrRegistry[ta.Callable, str]()
|
|
35
|
+
|
|
36
|
+
@classmethod
|
|
37
|
+
def register(cls, name):
|
|
38
|
+
return cls._registry.register(name)
|
|
39
|
+
|
|
40
|
+
@lang.cached_function
|
|
41
|
+
@classmethod
|
|
42
|
+
def _registry_cache(cls) -> col.AttrRegistryCache[ta.Callable, str, ta.Mapping[str, str]]:
|
|
43
|
+
def prepare(_, dct):
|
|
44
|
+
return col.make_map(((n, a) for a, (_, n) in dct.items()), strict=True)
|
|
45
|
+
|
|
46
|
+
return col.AttrRegistryCache(cls._registry, prepare)
|
|
47
|
+
|
|
48
|
+
def visit_rule(self, name: str, m: Match) -> T:
|
|
49
|
+
att = self._registry_cache().get(self.__class__)[name]
|
|
50
|
+
return getattr(self, att)(m)
|
|
51
|
+
|
|
52
|
+
#
|
|
53
|
+
|
|
54
|
+
def visit_match(self, m: Match) -> T:
|
|
55
|
+
return self.visit_rule(check.isinstance(m.parser, RuleRef).name, m)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: omextra
|
|
3
|
-
Version: 0.0.0.
|
|
3
|
+
Version: 0.0.0.dev487
|
|
4
4
|
Summary: omextra
|
|
5
5
|
Author: wrmsr
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -14,15 +14,20 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
14
14
|
Requires-Python: >=3.13
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
License-File: LICENSE
|
|
17
|
-
Requires-Dist: omlish==0.0.0.
|
|
17
|
+
Requires-Dist: omlish==0.0.0.dev487
|
|
18
18
|
Dynamic: license-file
|
|
19
19
|
|
|
20
20
|
# Overview
|
|
21
21
|
|
|
22
22
|
Core-like code not appropriate for inclusion in `omlish` for one reason or another. A bit like
|
|
23
|
-
[`golang.org/x`](https://pkg.go.dev/golang.org/x).
|
|
23
|
+
[`golang.org/x`](https://pkg.go.dev/golang.org/x) but even less suitable for production use.
|
|
24
|
+
|
|
25
|
+
Code here is usually in the process of either moving out of or moving into `omlish` proper, or being demoted to the
|
|
26
|
+
unpublished `x` root dir, or just being deleted.
|
|
24
27
|
|
|
25
28
|
# Notable packages
|
|
26
29
|
|
|
27
30
|
- **[text.antlr](https://github.com/wrmsr/omlish/blob/master/omextra/text/antlr)** -
|
|
28
|
-
[ANTLR](https://www.antlr.org/)-related code.
|
|
31
|
+
[ANTLR](https://www.antlr.org/)-related code. The codebase is generally moving away from antlr in favor of an internal
|
|
32
|
+
[abnf engine](text/abnf), but I have other projects that need the full power of antlr, so it may remain as an optional
|
|
33
|
+
dep for utility code (much like sqlalchemy).
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
omextra/.omlish-manifests.json,sha256=E1M9UJ31RfpLfsZ2MfbN0_GAh_Lu_vj9wVJKPgak8jQ,290
|
|
2
|
-
omextra/__about__.py,sha256=
|
|
2
|
+
omextra/__about__.py,sha256=8R-v5C4UWEiLEyDv1CoxATr7YTxZxs6-7QRlva-gGWY,706
|
|
3
3
|
omextra/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
omextra/defs.py,sha256=iMaDGj5VSG7QdYA1s7MvIYTbtTsXc1msINsuuZym1vs,4902
|
|
5
5
|
omextra/dynamic.py,sha256=i3aJRWwHJOmsrXI9a2iWCLa7pUQXx5YbMvUOS5LZ_Bs,6531
|
|
6
6
|
omextra/asyncs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
-
omextra/asyncs/bridge.py,sha256=
|
|
7
|
+
omextra/asyncs/bridge.py,sha256=QHh4gtiSid5bjmV9lqQrGHHBkE0yPFFYGW_NbJ2KGhI,10162
|
|
8
8
|
omextra/asyncs/bluelet/LICENSE,sha256=q5Kpj4s30qpi8H66tXFlh5v8_fkaKMFIzqdGfnN0Hz0,555
|
|
9
9
|
omextra/asyncs/bluelet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
10
|
omextra/asyncs/bluelet/all.py,sha256=aUV6PwnR8DqnEBS9wsZuPW_UtP6G9M8_KY-mmxZeVG0,1516
|
|
@@ -14,7 +14,18 @@ omextra/asyncs/bluelet/events.py,sha256=PJ55CuXNmvzhYYhMmIDOUWegWTMcn9IkxL4dHcjd
|
|
|
14
14
|
omextra/asyncs/bluelet/files.py,sha256=wpvzFPfQltqPcSKUgmAUZ1sjSSawX_nr5rZ4InLhsTM,2424
|
|
15
15
|
omextra/asyncs/bluelet/runner.py,sha256=pE080AUs66AIxY5WBOWqh-9V1i1JYOvxaE2wB8t72Mw,15516
|
|
16
16
|
omextra/asyncs/bluelet/sockets.py,sha256=nTVPdLbsmmjI0e6G9Di2DA-JoTTnvu8xc_Yv8N_7g48,6781
|
|
17
|
+
omextra/collections/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
+
omextra/collections/hamt/LICENSE,sha256=82rcXdtBwd6vGLddjx9Jk09kkwPL6yqqv1NzGjPUCoM,2460
|
|
19
|
+
omextra/collections/hamt/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
+
omextra/collections/hamt/_hamt.c,sha256=LDYWBuAl4685DbAZICrzO--EfIN8PjHZq0MUJYBAD74,100898
|
|
17
21
|
omextra/formats/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
+
omextra/formats/goyaml/LICENSE,sha256=qkavv9cjd59BFIFOMVMJMrC3FCEIELrBTA-GPhAFkoY,1071
|
|
23
|
+
omextra/formats/goyaml/__init__.py,sha256=Wf7WukYGHk2Pqep2ZGRzz2ZznXcay0oVVmrqvqgYIoo,1821
|
|
24
|
+
omextra/formats/goyaml/ast.py,sha256=55CyoNRiaDmu6YeKE_PRt51fE7zr35YcTWSDzVRjPRo,69984
|
|
25
|
+
omextra/formats/goyaml/errors.py,sha256=UQfuManw4kOJKnXrV6MjFqt0ZU6KkwZL75KMdQQ6ZyU,949
|
|
26
|
+
omextra/formats/goyaml/parsing.py,sha256=vZotOxOhLTrE9AGfXbSZcDrVC652PJ3K3ageu6aRT6Q,90558
|
|
27
|
+
omextra/formats/goyaml/scanning.py,sha256=X5hl5lhQAPtiqiKC0pGAo46D2rrB2nZOtJuQOAtaXDM,63208
|
|
28
|
+
omextra/formats/goyaml/tokens.py,sha256=fRshyMRU3XzZ5Pi9_C1F2BTzjtcrqIuIsHmQuqMu3Oo,29278
|
|
18
29
|
omextra/formats/json/Json.g4,sha256=fYImsljcVPdlMTHBabM_rza2j4udqjfLQNxIz4S_TpY,1206
|
|
19
30
|
omextra/formats/json/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
31
|
omextra/formats/json/_antlr/JsonLexer.py,sha256=SYlMV8XKi_kJ9meEulNmm2B98hjdzz_xLyPsoqCyYoE,4957
|
|
@@ -52,6 +63,15 @@ omextra/sql/parsing/_antlr/MinisqlParser.py,sha256=htIMgNde8PqLj7mDV2cLo7kDiwn-a
|
|
|
52
63
|
omextra/sql/parsing/_antlr/MinisqlVisitor.py,sha256=UPs2qA2VlNRP_LMwF0DpMxMir9tIS9w59vGTq07mmlI,10052
|
|
53
64
|
omextra/sql/parsing/_antlr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
54
65
|
omextra/text/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
66
|
+
omextra/text/abnf/LICENSE,sha256=UJzrhSePw9TVm0VfkVmx9NRHkPS1n6jx2UgajTb14ts,1054
|
|
67
|
+
omextra/text/abnf/__init__.py,sha256=4ckTD1WSkte_7LzO7vvhcZ17uEdSrNdnpkkuJBRJ2BY,1095
|
|
68
|
+
omextra/text/abnf/base.py,sha256=xDlMH9jaGXh2PN4DMR6AIMB-zOU_MVy20BcEd6Bpu4U,8128
|
|
69
|
+
omextra/text/abnf/core.py,sha256=VUD52hKgDsesvPjmhL1UZVXtpYr-EpWyBprdy722YTY,2303
|
|
70
|
+
omextra/text/abnf/errors.py,sha256=uj1oQvRVRlWkMG8mpmcRUg25kICeIJx5EWAVij3pmXc,142
|
|
71
|
+
omextra/text/abnf/meta.py,sha256=1i2AAGZBLEQhF2HUYQPr385qAMMYLEo0dZT-dcH2Gv0,14447
|
|
72
|
+
omextra/text/abnf/parsers.py,sha256=JKRff1lXbjbKokGL5IBG9tnPflrQ0Fd7X--MRcKTdtE,9209
|
|
73
|
+
omextra/text/abnf/utils.py,sha256=UXJ0MlTkigm3cWuKVU1Ao3bVjQKqy6sZgPni1aVgFgk,1667
|
|
74
|
+
omextra/text/abnf/visitors.py,sha256=kAWPmc3fAOLynLoVl_-ciG_TA3XG7HPca9_I1vI4rL0,1288
|
|
55
75
|
omextra/text/antlr/__init__.py,sha256=88bMl_28cfSKslgOkMGYXqALgsHz3KC4LFvAVtzj7k8,89
|
|
56
76
|
omextra/text/antlr/delimit.py,sha256=s0Jlu6oOamtuyWv_V98P0YC7HmgFJBF7GHVsDfMYTdI,3476
|
|
57
77
|
omextra/text/antlr/dot.py,sha256=37ZBYpum-n6Xg9UGj1Wc0wyuR3gL_uX63KwrSzyWNmk,967
|
|
@@ -125,9 +145,9 @@ omextra/text/antlr/cli/__main__.py,sha256=ckYkj0drxabBVwWYewH2SS36TTeAxllZtS4xEl
|
|
|
125
145
|
omextra/text/antlr/cli/cli.py,sha256=LW8pJNmySBOV3g8QxquPjUgxFv7YblzEyi555hHH3_M,1234
|
|
126
146
|
omextra/text/antlr/cli/consts.py,sha256=HUYJP9j4RfeuuQv6HFd2oFMS0piWJ9Sq1tbeAs4OlBc,290
|
|
127
147
|
omextra/text/antlr/cli/gen.py,sha256=HYleVptrpynwcl6GspX6O9_oMRSxwdYAQGuUFfDYse8,5236
|
|
128
|
-
omextra-0.0.0.
|
|
129
|
-
omextra-0.0.0.
|
|
130
|
-
omextra-0.0.0.
|
|
131
|
-
omextra-0.0.0.
|
|
132
|
-
omextra-0.0.0.
|
|
133
|
-
omextra-0.0.0.
|
|
148
|
+
omextra-0.0.0.dev487.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
|
149
|
+
omextra-0.0.0.dev487.dist-info/METADATA,sha256=Har3sQSHp-k46tx0TK0lHiq_TAqZFdaGfl-dBpqKUU4,1357
|
|
150
|
+
omextra-0.0.0.dev487.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
151
|
+
omextra-0.0.0.dev487.dist-info/entry_points.txt,sha256=-MFAMks5HgZ60Ore0Wl5lKVKk8z4kf1Ls3WY9E_OlCU,37
|
|
152
|
+
omextra-0.0.0.dev487.dist-info/top_level.txt,sha256=o1nCNRejLMcayDngLuWMWwaeOucz33BXbpuoVvvzjPc,8
|
|
153
|
+
omextra-0.0.0.dev487.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|