Fix error recovery on early finished statements #453

This commit is contained in:
Simon Binder 2020-03-21 22:02:27 +01:00
parent 5d6fcec438
commit d533a0a254
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
2 changed files with 30 additions and 8 deletions

View File

@ -376,12 +376,17 @@ class Parser extends ParserBase
T result;
try {
result = parser();
if (result != null) {
result.semicolon = _consume(TokenType.semicolon,
'Expected a semicolon after the statement ended');
result.setSpan(first, _previous);
}
} on ParsingError {
_lastStmtHadParsingError = true;
// the error is added to the list errors, so ignore. We skip after the
// next semicolon to parse the next statement.
_synchronize(TokenType.semicolon, skipTarget: true);
}
if (result == null) return null;
@ -390,6 +395,8 @@ class Parser extends ParserBase
}
result.setSpan(first, _previous);
}
return result;
}

View File

@ -11,7 +11,7 @@ CREATE TABLE tbl (
id INT NOT NULL PRIMARY KEY AUTOINCREMENT,
-- this is a single-line comment
place VARCHAR REFERENCES other(location)
) AS RowName
) AS RowName;
all: SELECT /* COUNT(*), */ * FROM tbl WHERE $predicate;
@special: SELECT * FROM tbl;
@ -111,4 +111,19 @@ void main() {
isNot(contains(const TypeMatcher<DeclaredStatement>())),
);
});
test('syntax errors contain correct position', () {
final engine = SqlEngine(EngineOptions(useMoorExtensions: true));
final result = engine.parseMoorFile('''
worksByComposer:
SELECT DISTINCT A.* FROM works A, works B ON A.id = B.part_of
WHERE A.composer = :id OR B.composer = :id;
''');
expect(result.errors, hasLength(1));
expect(
result.errors.single,
isA<ParsingError>()
.having((e) => e.token.lexeme, 'token.lexeme', 'ON'));
});
}