mirror of
https://gitlab.gnome.org/jwestman/blueprint-compiler.git
synced 2025-05-04 15:59:08 -04:00
parent
5b76a3b8dd
commit
8e1a9f72dd
5 changed files with 34 additions and 5 deletions
|
@ -85,6 +85,11 @@ at {filename} line {line_num} column {col_num}:
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
class UnexpectedTokenError(CompileError):
|
||||||
|
def __init__(self, start, end):
|
||||||
|
super().__init__("Unexpected tokens", start, end)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class CodeAction:
|
class CodeAction:
|
||||||
title: str
|
title: str
|
||||||
|
|
|
@ -25,7 +25,7 @@ from collections import defaultdict
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
from .ast import AstNode
|
from .ast import AstNode
|
||||||
from .errors import assert_true, CompilerBugError, CompileError
|
from .errors import assert_true, CompilerBugError, CompileError, UnexpectedTokenError
|
||||||
from .tokenizer import Token, TokenType
|
from .tokenizer import Token, TokenType
|
||||||
|
|
||||||
|
|
||||||
|
@ -184,6 +184,22 @@ class ParseContext:
|
||||||
token = self.tokens[self.index]
|
token = self.tokens[self.index]
|
||||||
return token
|
return token
|
||||||
|
|
||||||
|
def skip_unexpected_token(self):
|
||||||
|
""" Skips a token and logs an "unexpected token" error. """
|
||||||
|
|
||||||
|
self.skip()
|
||||||
|
start = self.tokens[self.index].start
|
||||||
|
self.next_token()
|
||||||
|
self.skip()
|
||||||
|
end = self.tokens[self.index - 1].end
|
||||||
|
|
||||||
|
if (len(self.errors)
|
||||||
|
and isinstance((err := self.errors[-1]), UnexpectedTokenError)
|
||||||
|
and err.end == start):
|
||||||
|
err.end = end
|
||||||
|
else:
|
||||||
|
self.errors.append(UnexpectedTokenError(start, end))
|
||||||
|
|
||||||
def is_eof(self) -> Token:
|
def is_eof(self) -> Token:
|
||||||
return self.index >= len(self.tokens) or self.peek_token().type == TokenType.EOF
|
return self.index >= len(self.tokens) or self.peek_token().type == TokenType.EOF
|
||||||
|
|
||||||
|
@ -330,8 +346,7 @@ class Until(ParseNode):
|
||||||
while not self.delimiter.parse(ctx).succeeded():
|
while not self.delimiter.parse(ctx).succeeded():
|
||||||
try:
|
try:
|
||||||
if not self.child.parse(ctx).matched():
|
if not self.child.parse(ctx).matched():
|
||||||
token = ctx.next_token()
|
ctx.skip_unexpected_token()
|
||||||
ctx.errors.append(CompileError("Unexpected token", token.start, token.end))
|
|
||||||
except CompileError as e:
|
except CompileError as e:
|
||||||
ctx.errors.append(e)
|
ctx.errors.append(e)
|
||||||
ctx.next_token()
|
ctx.next_token()
|
||||||
|
|
7
tests/sample_errors/consecutive_unexpected_tokens.blp
Normal file
7
tests/sample_errors/consecutive_unexpected_tokens.blp
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
using Gtk 4.0;
|
||||||
|
|
||||||
|
Button {
|
||||||
|
visible: false;
|
||||||
|
not actually blueprint code;
|
||||||
|
Label {}
|
||||||
|
}
|
1
tests/sample_errors/consecutive_unexpected_tokens.err
Normal file
1
tests/sample_errors/consecutive_unexpected_tokens.err
Normal file
|
@ -0,0 +1 @@
|
||||||
|
5,3,31,Unexpected tokens
|
|
@ -71,9 +71,9 @@ class TestSamples(unittest.TestCase):
|
||||||
raise MultipleErrors(ast.errors)
|
raise MultipleErrors(ast.errors)
|
||||||
except PrintableError as e:
|
except PrintableError as e:
|
||||||
def error_str(error):
|
def error_str(error):
|
||||||
line, col = utils.idx_to_pos(error.start, blueprint)
|
line, col = utils.idx_to_pos(error.start + 1, blueprint)
|
||||||
len = error.end - error.start
|
len = error.end - error.start
|
||||||
return ",".join([str(line + 1), str(col + 1), str(len), error.message])
|
return ",".join([str(line + 1), str(col), str(len), error.message])
|
||||||
|
|
||||||
if isinstance(e, CompileError):
|
if isinstance(e, CompileError):
|
||||||
actual = error_str(e)
|
actual = error_str(e)
|
||||||
|
@ -143,6 +143,7 @@ class TestSamples(unittest.TestCase):
|
||||||
self.assert_sample_error("a11y_prop_type")
|
self.assert_sample_error("a11y_prop_type")
|
||||||
self.assert_sample_error("class_assign")
|
self.assert_sample_error("class_assign")
|
||||||
self.assert_sample_error("class_dne")
|
self.assert_sample_error("class_dne")
|
||||||
|
self.assert_sample_error("consecutive_unexpected_tokens")
|
||||||
self.assert_sample_error("duplicate_obj_id")
|
self.assert_sample_error("duplicate_obj_id")
|
||||||
self.assert_sample_error("enum_member_dne")
|
self.assert_sample_error("enum_member_dne")
|
||||||
self.assert_sample_error("filters_in_non_file_filter")
|
self.assert_sample_error("filters_in_non_file_filter")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue