omextra 0.0.0.dev424__py3-none-any.whl → 0.0.0.dev426__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/.omlish-manifests.json +14 -0
- omextra/__about__.py +3 -1
- omextra/defs.py +216 -0
- omextra/dynamic.py +219 -0
- omextra/formats/__init__.py +0 -0
- omextra/formats/json/Json.g4 +77 -0
- omextra/formats/json/__init__.py +0 -0
- omextra/formats/json/_antlr/JsonLexer.py +109 -0
- omextra/formats/json/_antlr/JsonListener.py +61 -0
- omextra/formats/json/_antlr/JsonParser.py +457 -0
- omextra/formats/json/_antlr/JsonVisitor.py +42 -0
- omextra/formats/json/_antlr/__init__.py +0 -0
- omextra/io/__init__.py +0 -0
- omextra/io/trampoline.py +289 -0
- omextra/specs/__init__.py +0 -0
- omextra/specs/irc/__init__.py +0 -0
- omextra/specs/irc/messages/__init__.py +0 -0
- omextra/specs/irc/messages/base.py +50 -0
- omextra/specs/irc/messages/formats.py +92 -0
- omextra/specs/irc/messages/messages.py +775 -0
- omextra/specs/irc/messages/parsing.py +99 -0
- omextra/specs/irc/numerics/__init__.py +0 -0
- omextra/specs/irc/numerics/formats.py +97 -0
- omextra/specs/irc/numerics/numerics.py +865 -0
- omextra/specs/irc/numerics/types.py +59 -0
- omextra/specs/irc/protocol/LICENSE +11 -0
- omextra/specs/irc/protocol/__init__.py +61 -0
- omextra/specs/irc/protocol/consts.py +6 -0
- omextra/specs/irc/protocol/errors.py +30 -0
- omextra/specs/irc/protocol/message.py +21 -0
- omextra/specs/irc/protocol/nuh.py +55 -0
- omextra/specs/irc/protocol/parsing.py +158 -0
- omextra/specs/irc/protocol/rendering.py +153 -0
- omextra/specs/irc/protocol/tags.py +102 -0
- omextra/specs/irc/protocol/utils.py +30 -0
- omextra/specs/proto/Protobuf3.g4 +396 -0
- omextra/specs/proto/__init__.py +0 -0
- omextra/specs/proto/_antlr/Protobuf3Lexer.py +340 -0
- omextra/specs/proto/_antlr/Protobuf3Listener.py +448 -0
- omextra/specs/proto/_antlr/Protobuf3Parser.py +3909 -0
- omextra/specs/proto/_antlr/Protobuf3Visitor.py +257 -0
- omextra/specs/proto/_antlr/__init__.py +0 -0
- omextra/specs/proto/nodes.py +54 -0
- omextra/specs/proto/parsing.py +98 -0
- omextra/sql/__init__.py +0 -0
- omextra/sql/parsing/Minisql.g4 +292 -0
- omextra/sql/parsing/__init__.py +0 -0
- omextra/sql/parsing/_antlr/MinisqlLexer.py +322 -0
- omextra/sql/parsing/_antlr/MinisqlListener.py +511 -0
- omextra/sql/parsing/_antlr/MinisqlParser.py +3763 -0
- omextra/sql/parsing/_antlr/MinisqlVisitor.py +292 -0
- omextra/sql/parsing/_antlr/__init__.py +0 -0
- omextra/sql/parsing/parsing.py +120 -0
- omextra/text/__init__.py +0 -0
- omextra/text/antlr/__init__.py +0 -0
- omextra/text/antlr/cli/__init__.py +0 -0
- omextra/text/antlr/cli/__main__.py +11 -0
- omextra/text/antlr/cli/cli.py +62 -0
- omextra/text/antlr/cli/consts.py +7 -0
- omextra/text/antlr/cli/gen.py +193 -0
- {omextra-0.0.0.dev424.dist-info → omextra-0.0.0.dev426.dist-info}/METADATA +2 -3
- omextra-0.0.0.dev426.dist-info/RECORD +67 -0
- omextra/.manifests.json +0 -1
- omextra-0.0.0.dev424.dist-info/RECORD +0 -9
- {omextra-0.0.0.dev424.dist-info → omextra-0.0.0.dev426.dist-info}/WHEEL +0 -0
- {omextra-0.0.0.dev424.dist-info → omextra-0.0.0.dev426.dist-info}/entry_points.txt +0 -0
- {omextra-0.0.0.dev424.dist-info → omextra-0.0.0.dev426.dist-info}/licenses/LICENSE +0 -0
- {omextra-0.0.0.dev424.dist-info → omextra-0.0.0.dev426.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,99 @@
|
|
1
|
+
import typing as ta
|
2
|
+
|
3
|
+
from omlish import dataclasses as dc
|
4
|
+
|
5
|
+
from .base import Message
|
6
|
+
from .formats import MessageFormat
|
7
|
+
|
8
|
+
|
9
|
+
##
|
10
|
+
|
11
|
+
|
12
|
+
class ParseError(Exception):
|
13
|
+
pass
|
14
|
+
|
15
|
+
|
16
|
+
def parse_message(cls: type[Message], params: ta.Sequence[str]) -> Message:
|
17
|
+
mf = cls.FORMAT
|
18
|
+
|
19
|
+
kws: dict = {}
|
20
|
+
i = 0
|
21
|
+
for fp in mf.params:
|
22
|
+
if isinstance(fp, MessageFormat.KwargParam):
|
23
|
+
if i >= len(params):
|
24
|
+
if not fp.optional:
|
25
|
+
raise ParseError(f'Missing param: {fp.name}')
|
26
|
+
continue
|
27
|
+
|
28
|
+
kv: ta.Any
|
29
|
+
if (ar := fp.arity) is MessageFormat.KwargParam.Arity.SINGLE:
|
30
|
+
kv = params[i]
|
31
|
+
i += 1
|
32
|
+
|
33
|
+
elif ar is MessageFormat.KwargParam.Arity.VARIADIC:
|
34
|
+
kv = params[i:]
|
35
|
+
i = len(params)
|
36
|
+
|
37
|
+
elif ar is MessageFormat.KwargParam.Arity.COMMA_LIST:
|
38
|
+
kv = params[i].split(',')
|
39
|
+
i += 1
|
40
|
+
|
41
|
+
else:
|
42
|
+
raise TypeError(ar)
|
43
|
+
|
44
|
+
kws[fp.name] = kv
|
45
|
+
|
46
|
+
elif isinstance(fp, MessageFormat.LiteralParam):
|
47
|
+
if i >= len(params):
|
48
|
+
raise ParseError('Missing literal param')
|
49
|
+
|
50
|
+
pv = params[i]
|
51
|
+
if fp.text != pv:
|
52
|
+
raise ParseError(f'Unexpected literal: {pv}')
|
53
|
+
i += 1
|
54
|
+
|
55
|
+
else:
|
56
|
+
raise TypeError(fp)
|
57
|
+
|
58
|
+
if i != len(params):
|
59
|
+
raise ParseError('Unconsumed params')
|
60
|
+
|
61
|
+
if (up := mf.unpack_params) is not None:
|
62
|
+
kws = dict(up(kws))
|
63
|
+
|
64
|
+
return cls(**kws)
|
65
|
+
|
66
|
+
|
67
|
+
##
|
68
|
+
|
69
|
+
|
70
|
+
class UnparsedMessage(ta.NamedTuple):
|
71
|
+
name: str
|
72
|
+
params: ta.Sequence[str]
|
73
|
+
|
74
|
+
|
75
|
+
def unparse_message(msg: Message) -> UnparsedMessage:
|
76
|
+
mf = msg.FORMAT
|
77
|
+
|
78
|
+
kws = {k: v for k, v in dc.asdict(msg).items() if v is not None}
|
79
|
+
|
80
|
+
if (up := mf.unpack_params) is not None:
|
81
|
+
kws = dict(up.backward(kws))
|
82
|
+
|
83
|
+
params = []
|
84
|
+
|
85
|
+
for fp in mf.params:
|
86
|
+
if isinstance(fp, MessageFormat.KwargParam):
|
87
|
+
# FIXME
|
88
|
+
raise NotImplementedError
|
89
|
+
|
90
|
+
elif isinstance(fp, MessageFormat.LiteralParam):
|
91
|
+
params.append(fp.text)
|
92
|
+
|
93
|
+
else:
|
94
|
+
raise TypeError(fp)
|
95
|
+
|
96
|
+
return UnparsedMessage(
|
97
|
+
name=mf.name,
|
98
|
+
params=params,
|
99
|
+
)
|
File without changes
|
@@ -0,0 +1,97 @@
|
|
1
|
+
import dataclasses as dc
|
2
|
+
import typing as ta
|
3
|
+
|
4
|
+
from omlish import check
|
5
|
+
from omlish import lang
|
6
|
+
|
7
|
+
|
8
|
+
FormatPart: ta.TypeAlias = ta.Union[str, 'Formats.Optional', 'Formats.Variadic']
|
9
|
+
FormatParts: ta.TypeAlias = ta.Sequence[FormatPart]
|
10
|
+
|
11
|
+
|
12
|
+
##
|
13
|
+
|
14
|
+
|
15
|
+
class Formats(lang.Namespace):
|
16
|
+
@dc.dataclass(frozen=True)
|
17
|
+
class Name:
|
18
|
+
name: str
|
19
|
+
|
20
|
+
@dc.dataclass(frozen=True)
|
21
|
+
class Optional:
|
22
|
+
body: FormatParts
|
23
|
+
|
24
|
+
@dc.dataclass(frozen=True)
|
25
|
+
class Variadic:
|
26
|
+
body: FormatParts
|
27
|
+
|
28
|
+
#
|
29
|
+
|
30
|
+
_PARTS_BY_DELIMITERS: ta.Mapping[tuple[str, str], type] = {
|
31
|
+
('[', ']'): Optional,
|
32
|
+
('{', '}'): Variadic,
|
33
|
+
}
|
34
|
+
|
35
|
+
_DELIMITERS_BY_PARTS: ta.Mapping[type, tuple[str, str]] = {v: k for k, v in _PARTS_BY_DELIMITERS.items()}
|
36
|
+
|
37
|
+
#
|
38
|
+
|
39
|
+
@staticmethod
|
40
|
+
def split_parts(s: str) -> FormatParts:
|
41
|
+
stk: list[tuple[str, list]] = [('', [])]
|
42
|
+
|
43
|
+
p = 0
|
44
|
+
while p < len(s):
|
45
|
+
n = lang.find_any(s, '{}[]<', p)
|
46
|
+
|
47
|
+
if n < 0:
|
48
|
+
check.state(not stk[-1][0])
|
49
|
+
stk[-1][1].append(s[p:])
|
50
|
+
break
|
51
|
+
|
52
|
+
if n != p:
|
53
|
+
stk[-1][1].append(s[p:n])
|
54
|
+
|
55
|
+
d = s[n]
|
56
|
+
if d == '<':
|
57
|
+
e = s.index('>', n)
|
58
|
+
stk[-1][1].append(Formats.Name(s[n + 1:e]))
|
59
|
+
p = e + 1
|
60
|
+
|
61
|
+
elif d in '{[':
|
62
|
+
stk.append((d, []))
|
63
|
+
p = n + 1
|
64
|
+
|
65
|
+
elif d in '}]':
|
66
|
+
x, l = stk.pop()
|
67
|
+
pc = Formats._PARTS_BY_DELIMITERS[(x, d)]
|
68
|
+
stk[-1][1].append(pc(l))
|
69
|
+
p = n + 1
|
70
|
+
|
71
|
+
else:
|
72
|
+
raise RuntimeError
|
73
|
+
|
74
|
+
_, ret = check.single(stk)
|
75
|
+
return ret
|
76
|
+
|
77
|
+
#
|
78
|
+
|
79
|
+
@staticmethod
|
80
|
+
def render_parts(p: FormatPart | FormatParts) -> ta.Iterator[str]:
|
81
|
+
if isinstance(p, str):
|
82
|
+
yield p
|
83
|
+
|
84
|
+
elif isinstance(p, Formats.Name):
|
85
|
+
yield '<'
|
86
|
+
yield p.name
|
87
|
+
yield '>'
|
88
|
+
|
89
|
+
elif isinstance(p, (Formats.Optional, Formats.Variadic)):
|
90
|
+
l, r = Formats._DELIMITERS_BY_PARTS[type(p)]
|
91
|
+
yield l
|
92
|
+
yield from Formats.render_parts(p.body)
|
93
|
+
yield r
|
94
|
+
|
95
|
+
else:
|
96
|
+
for c in p:
|
97
|
+
yield from Formats.render_parts(c)
|