mirror of
https://gitlab.gnome.org/jwestman/blueprint-compiler.git
synced 2025-05-07 16:29:07 -04:00
parser: Tweak parsing during error conditions
When an explicit parsing error is encountered and a CompileError raised, apply the changes to the context state. This way, the rule that catches the exception (e.g. Statement or Until) knows where the error occurred. Also, changed "Expected" errors to be reported at the end of the previous non-whitespace token.
This commit is contained in:
parent
69e05bba34
commit
d3c31447c9
6 changed files with 18 additions and 11 deletions
|
@ -111,6 +111,8 @@ class CompileError(PrintableError):
|
|||
n_carets += line.count("\t", col_num, col_num + n_carets)
|
||||
line = line.replace("\t", " ")
|
||||
|
||||
n_carets = max(n_carets, 1)
|
||||
|
||||
stream.write(
|
||||
f"""{self.color}{Colors.BOLD}{self.category}: {self.message}{Colors.CLEAR}
|
||||
at {filename} line {line_num} column {col_num}:
|
||||
|
|
|
@ -235,7 +235,15 @@ class ParseNode:
|
|||
start_idx = ctx.index
|
||||
inner_ctx = ctx.create_child()
|
||||
|
||||
if self._parse(inner_ctx):
|
||||
try:
|
||||
result = self._parse(inner_ctx)
|
||||
except Exception as e:
|
||||
# If an exception occurs, there's an explicit error, not just a rule that didn't match. Apply the context
|
||||
# state so that whichever rule handles the exception (e.g. a Statement) knows where the error occurred.
|
||||
ctx.apply_child(inner_ctx)
|
||||
raise e
|
||||
|
||||
if result:
|
||||
ctx.apply_child(inner_ctx)
|
||||
if ctx.index == start_idx:
|
||||
return ParseResult.EMPTY
|
||||
|
@ -269,11 +277,11 @@ class Err(ParseNode):
|
|||
if self.child.parse(ctx).failed():
|
||||
start_idx = ctx.start
|
||||
while ctx.tokens[start_idx].type in SKIP_TOKENS:
|
||||
start_idx += 1
|
||||
start_idx -= 1
|
||||
start_token = ctx.tokens[start_idx]
|
||||
|
||||
raise CompileError(
|
||||
self.message, Range(start_token.start, start_token.start, ctx.text)
|
||||
self.message, Range(start_token.end, start_token.end, ctx.text)
|
||||
)
|
||||
return True
|
||||
|
||||
|
@ -411,7 +419,6 @@ class Until(ParseNode):
|
|||
ctx.skip_unexpected_token()
|
||||
except CompileError as e:
|
||||
ctx.errors.append(e)
|
||||
ctx.next_token()
|
||||
|
||||
return True
|
||||
|
||||
|
|
|
@ -76,8 +76,8 @@ def did_you_mean(word: str, options: T.List[str]) -> T.Optional[str]:
|
|||
def idx_to_pos(idx: int, text: str) -> T.Tuple[int, int]:
|
||||
if idx == 0 or len(text) == 0:
|
||||
return (0, 0)
|
||||
line_num = text.count("\n", 0, idx) + 1
|
||||
col_num = idx - text.rfind("\n", 0, idx) - 1
|
||||
line_num = text.count("\n", 0, idx - 1) + 1
|
||||
col_num = idx - text.rfind("\n", 0, idx - 1) - 1
|
||||
return (line_num - 1, col_num)
|
||||
|
||||
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
5,1,0,Expected a signal detail name
|
||||
4,9,3,Unexpected tokens
|
||||
4,11,0,Expected a signal detail name
|
|
@ -1,2 +1 @@
|
|||
4,5,21,Attributes are not permitted at the top level of a menu
|
||||
4,16,10,Unexpected tokens
|
||||
4,5,21,Attributes are not permitted at the top level of a menu
|
|
@ -1 +1 @@
|
|||
1,11,0,Expected a version number for GTK
|
||||
1,10,0,Expected a version number for GTK
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue