dbrownell-parserlib 0.8.1__tar.gz → 0.8.2__tar.gz
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.
- {dbrownell_parserlib-0.8.1 → dbrownell_parserlib-0.8.2}/PKG-INFO +1 -1
- {dbrownell_parserlib-0.8.1 → dbrownell_parserlib-0.8.2}/pyproject.toml +1 -1
- {dbrownell_parserlib-0.8.1 → dbrownell_parserlib-0.8.2}/src/dbrownell_ParserLib/antlr/antlr_parser.py +1 -1
- {dbrownell_parserlib-0.8.1 → dbrownell_parserlib-0.8.2}/src/dbrownell_ParserLib/antlr/antlr_visitor_mixins.py +57 -72
- {dbrownell_parserlib-0.8.1 → dbrownell_parserlib-0.8.2}/README.md +0 -0
- {dbrownell_parserlib-0.8.1 → dbrownell_parserlib-0.8.2}/src/dbrownell_ParserLib/__init__.py +0 -0
- {dbrownell_parserlib-0.8.1 → dbrownell_parserlib-0.8.2}/src/dbrownell_ParserLib/antlr/__init__.py +0 -0
- {dbrownell_parserlib-0.8.1 → dbrownell_parserlib-0.8.2}/src/dbrownell_ParserLib/antlr/build_antlr_grammar/__init__.py +0 -0
- {dbrownell_parserlib-0.8.1 → dbrownell_parserlib-0.8.2}/src/dbrownell_ParserLib/antlr/build_antlr_grammar/antlr-4.13.2-complete.jar +0 -0
- {dbrownell_parserlib-0.8.1 → dbrownell_parserlib-0.8.2}/src/dbrownell_ParserLib/errors.py +0 -0
- {dbrownell_parserlib-0.8.1 → dbrownell_parserlib-0.8.2}/src/dbrownell_ParserLib/expression.py +0 -0
- {dbrownell_parserlib-0.8.1 → dbrownell_parserlib-0.8.2}/src/dbrownell_ParserLib/location.py +0 -0
- {dbrownell_parserlib-0.8.1 → dbrownell_parserlib-0.8.2}/src/dbrownell_ParserLib/py.typed +0 -0
- {dbrownell_parserlib-0.8.1 → dbrownell_parserlib-0.8.2}/src/dbrownell_ParserLib/region.py +0 -0
- {dbrownell_parserlib-0.8.1 → dbrownell_parserlib-0.8.2}/src/dbrownell_ParserLib/terminal_expression.py +0 -0
- {dbrownell_parserlib-0.8.1 → dbrownell_parserlib-0.8.2}/src/dbrownell_ParserLib/visitors.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "dbrownell-parserlib"
|
|
3
|
-
version = "0.8.
|
|
3
|
+
version = "0.8.2"
|
|
4
4
|
# ^^^^^
|
|
5
5
|
# Wheel names will be generated according to this value. Do not manually modify this value; instead
|
|
6
6
|
# update it according to committed changes by running this command from the root of the repository:
|
|
@@ -485,7 +485,7 @@ class _ErrorListener(antlr4.DiagnosticErrorListener):
|
|
|
485
485
|
return
|
|
486
486
|
|
|
487
487
|
location = Location(line, column + 1)
|
|
488
|
-
error = Error(msg, Region(self._source, location, location))
|
|
488
|
+
error = Error(f"Syntax error: {msg}", Region(self._source, location, location))
|
|
489
489
|
ex = AntlrParserException(error)
|
|
490
490
|
|
|
491
491
|
if e is None:
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""Various ANTLR visitor mixins that can be used to add functionality to the generated visitor classes."""
|
|
2
2
|
|
|
3
|
+
import re
|
|
4
|
+
|
|
3
5
|
from abc import ABC, abstractmethod
|
|
4
6
|
from typing import cast, override, TYPE_CHECKING
|
|
5
7
|
|
|
@@ -35,14 +37,36 @@ class AntlrVisitorMixinBase(ABC):
|
|
|
35
37
|
self._current_line: int = 0
|
|
36
38
|
|
|
37
39
|
# ----------------------------------------------------------------------
|
|
38
|
-
@abstractmethod
|
|
39
40
|
def CreateRegion(
|
|
40
41
|
self,
|
|
41
|
-
ctx: antlr4.ParserRuleContext,
|
|
42
|
+
ctx: antlr4.TerminalNode | antlr4.ParserRuleContext,
|
|
42
43
|
) -> Region:
|
|
43
44
|
"""Create a `Region` from the given context."""
|
|
44
45
|
|
|
45
|
-
|
|
46
|
+
if isinstance(ctx, antlr4.TerminalNode):
|
|
47
|
+
token = cast(antlr4.Token, ctx.symbol) # ty: ignore[unresolved-attribute]
|
|
48
|
+
|
|
49
|
+
assert token.column is not None
|
|
50
|
+
|
|
51
|
+
start_line = token.line
|
|
52
|
+
start_col = token.column + 1
|
|
53
|
+
end_line = token.line
|
|
54
|
+
end_col = token.column + 1 + len(token.text)
|
|
55
|
+
|
|
56
|
+
assert start_line is not None
|
|
57
|
+
assert end_line is not None
|
|
58
|
+
|
|
59
|
+
region = Region(
|
|
60
|
+
self.filename,
|
|
61
|
+
Location(start_line, start_col),
|
|
62
|
+
Location(end_line, end_col),
|
|
63
|
+
)
|
|
64
|
+
else:
|
|
65
|
+
region = self._CreateRegionFromRule(ctx)
|
|
66
|
+
|
|
67
|
+
self._OnProgress(region.end.line)
|
|
68
|
+
|
|
69
|
+
return region
|
|
46
70
|
|
|
47
71
|
# ----------------------------------------------------------------------
|
|
48
72
|
def GetChildren(self, ctx: antlr4.ParserRuleContext) -> list[object]:
|
|
@@ -64,49 +88,28 @@ class AntlrVisitorMixinBase(ABC):
|
|
|
64
88
|
self._current_line = end_line
|
|
65
89
|
self._on_progress_func(end_line)
|
|
66
90
|
|
|
91
|
+
# ----------------------------------------------------------------------
|
|
92
|
+
@abstractmethod
|
|
93
|
+
def _CreateRegionFromRule(self, ctx: antlr4.ParserRuleContext) -> Region: ...
|
|
94
|
+
|
|
67
95
|
|
|
68
96
|
# ----------------------------------------------------------------------
|
|
69
97
|
class InsignificantWhitespaceAntlrVisitorMixin(AntlrVisitorMixinBase):
|
|
70
98
|
"""Mixin that adds functionality used for grammars that ignore insignificant whitespace."""
|
|
71
99
|
|
|
72
100
|
# ----------------------------------------------------------------------
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
ctx: antlr4.ParserRuleContext | antlr4.TerminalNode,
|
|
77
|
-
) -> Region:
|
|
78
|
-
"""Create a `Region` from the given context."""
|
|
79
|
-
|
|
80
|
-
if isinstance(ctx, antlr4.ParserRuleContext):
|
|
81
|
-
start_token = ctx.start
|
|
82
|
-
stop_token = ctx.stop
|
|
83
|
-
|
|
84
|
-
if start_token is None or stop_token is None:
|
|
85
|
-
msg = "Context does not have start or stop token"
|
|
86
|
-
raise ValueError(msg)
|
|
101
|
+
def _CreateRegionFromRule(self, ctx: antlr4.ParserRuleContext) -> Region:
|
|
102
|
+
start_token = ctx.start
|
|
103
|
+
stop_token = ctx.stop
|
|
87
104
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
end_col = stop_token.column + 1
|
|
92
|
-
|
|
93
|
-
if start_line == end_line:
|
|
94
|
-
end_col += len(stop_token.text)
|
|
95
|
-
else:
|
|
96
|
-
end_col += 1
|
|
97
|
-
|
|
98
|
-
elif isinstance(ctx, antlr4.TerminalNode):
|
|
99
|
-
token = cast(antlr4.Token, ctx.symbol) # ty: ignore[unresolved-attribute]
|
|
100
|
-
|
|
101
|
-
assert token.column is not None
|
|
102
|
-
|
|
103
|
-
start_line = token.line
|
|
104
|
-
start_col = token.column + 1
|
|
105
|
-
end_line = token.line
|
|
106
|
-
end_col = token.column + 1 + len(token.text)
|
|
105
|
+
if start_token is None or stop_token is None:
|
|
106
|
+
msg = "Context does not have start or stop token"
|
|
107
|
+
raise ValueError(msg)
|
|
107
108
|
|
|
108
|
-
|
|
109
|
-
|
|
109
|
+
start_line = start_token.line
|
|
110
|
+
start_col = start_token.column + 1
|
|
111
|
+
end_line = stop_token.line
|
|
112
|
+
end_col = stop_token.column + 1 + len(stop_token.text)
|
|
110
113
|
|
|
111
114
|
assert start_line is not None
|
|
112
115
|
assert end_line is not None
|
|
@@ -133,52 +136,34 @@ class SignificantWhitespaceAntlrVisitorMixin(AntlrVisitorMixinBase):
|
|
|
133
136
|
self._newline_token = newline_token
|
|
134
137
|
self._newline_token_string = newline_token_string
|
|
135
138
|
|
|
139
|
+
self._newline_indent_regex = re.compile(r"^\r?\n[ \t]*$")
|
|
140
|
+
|
|
136
141
|
# ----------------------------------------------------------------------
|
|
137
142
|
@override
|
|
138
|
-
def
|
|
143
|
+
def _CreateRegionFromRule(
|
|
139
144
|
self,
|
|
140
145
|
ctx: antlr4.ParserRuleContext,
|
|
141
146
|
) -> Region:
|
|
142
147
|
assert isinstance(ctx.start, antlr4.Token), ctx.start
|
|
143
148
|
assert isinstance(ctx.stop, antlr4.Token), ctx.stop
|
|
144
149
|
|
|
145
|
-
if ctx.stop.
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
if ctx.stop.line == ctx.start.line:
|
|
151
|
-
# This is the scenario where the statement is followed by a dedent followed by another
|
|
152
|
-
# statement. We don't want the range of this item to overlap with the range of the
|
|
153
|
-
# next item, so use the values as they are, even though it means that a statement
|
|
154
|
-
# that terminates with a newline will not have the newline here.
|
|
155
|
-
stop_line = ctx.stop.line
|
|
156
|
-
stop_col = ctx.stop.column
|
|
157
|
-
else:
|
|
158
|
-
stop_line = ctx.stop.line
|
|
159
|
-
stop_col = ctx.stop.column if ctx.stop.column == 0 else ctx.start.column
|
|
160
|
-
|
|
161
|
-
else:
|
|
162
|
-
stop_line = ctx.stop.line
|
|
163
|
-
|
|
164
|
-
content = ctx.stop.text
|
|
165
|
-
lines = content.split("\n")
|
|
166
|
-
|
|
167
|
-
if ctx.stop.type == self._newline_token:
|
|
168
|
-
assert content.startswith("\n"), content
|
|
169
|
-
assert len(lines) == 2, lines # noqa: PLR2004
|
|
170
|
-
|
|
171
|
-
stop_col = len(lines[-1])
|
|
172
|
-
|
|
173
|
-
if stop_line == ctx.stop.line:
|
|
174
|
-
stop_col += ctx.stop.column
|
|
150
|
+
if ctx.stop.text == self._newline_token_string or self._newline_indent_regex.match(ctx.stop.text):
|
|
151
|
+
assert ctx.stop.line == ctx.start.line or ctx.stop.line - 1 == ctx.start.line, (
|
|
152
|
+
ctx.start.line,
|
|
153
|
+
ctx.stop.line,
|
|
154
|
+
)
|
|
175
155
|
|
|
176
|
-
stop_line
|
|
156
|
+
stop_line = ctx.start.line
|
|
157
|
+
stop_column = ctx.start.column + 1 + len(ctx.start.text)
|
|
177
158
|
|
|
178
|
-
|
|
159
|
+
return Region(
|
|
160
|
+
self.filename,
|
|
161
|
+
Location(ctx.start.line, ctx.start.column + 1),
|
|
162
|
+
Location(stop_line, stop_column),
|
|
163
|
+
)
|
|
179
164
|
|
|
180
165
|
return Region(
|
|
181
166
|
self.filename,
|
|
182
167
|
Location(ctx.start.line, ctx.start.column + 1),
|
|
183
|
-
Location(
|
|
168
|
+
Location(ctx.stop.line, ctx.stop.column + 1),
|
|
184
169
|
)
|
|
File without changes
|
|
File without changes
|
{dbrownell_parserlib-0.8.1 → dbrownell_parserlib-0.8.2}/src/dbrownell_ParserLib/antlr/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dbrownell_parserlib-0.8.1 → dbrownell_parserlib-0.8.2}/src/dbrownell_ParserLib/expression.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|