Consolidate list parsing and error recovery boilerplate

Fix array/dictionary literal parsing robustness by consolidating and improving
the parsing of lists in general (tuples/array/dictionary literals, attribute
lists, statement lists, declaration lists, etc).

Missing commas in tuple/array/dictionary literals or declaration attributes
are now detected, reported, and recovered from.

Premature ellipsis in tuples are now detected, reported, and recovered from.

Swift SVN r4631
This commit is contained in:
Dave Zarzycki
2013-04-08 08:29:51 +00:00
parent 8c1ef9bd89
commit 54f8cdeb32
7 changed files with 313 additions and 336 deletions

View File

@@ -302,6 +302,56 @@ bool Parser::parseMatchingToken(tok K, SourceLoc &TokLoc, Diag<> ErrorDiag,
return false;
}
/// parseList - Parse the list of statements, expressions, or declarations.
bool Parser::parseList(tok RightK, SourceLoc LeftLoc, SourceLoc &RightLoc,
tok SeparatorK, bool OptionalSep, Diag<> ErrorDiag,
std::function<bool()> callback)
{
assert(SeparatorK == tok::comma || SeparatorK == tok::semi);
if (Tok.is(RightK)) {
RightLoc = consumeToken(RightK);
return false;
}
bool Invalid = false;
while (true) {
while (Tok.is(SeparatorK)) {
// FIXME: Add a fixit to remove optional separators
diagnose(Tok, diag::unexpected_separator,
SeparatorK == tok::comma ? "," : ";");
consumeToken();
}
SourceLoc StartLoc = Tok.getLoc();
Invalid |= callback();
if (Tok.is(RightK))
break;
// If the lexer stopped with an EOF token whose spelling is ')', then this
// is actually the tuple that is a string literal interpolation context.
// Just accept the ) and build the tuple as we usually do.
if (Tok.is(tok::eof) && Tok.getText()[0] == ')') {
RightLoc = Tok.getLoc();
return Invalid;
}
if (consumeIf(SeparatorK))
continue;
if (!OptionalSep) {
diagnose(Tok, diag::expected_separator,
SeparatorK == tok::comma ? "," : ";");
Invalid = true;
}
// If we haven't made progress, skip ahead
if (Tok.getLoc() == StartLoc) {
skipUntil(RightK, SeparatorK);
if (Tok.is(RightK))
break;
consumeIf(SeparatorK);
}
}
Invalid |= parseMatchingToken(RightK, RightLoc, ErrorDiag, LeftLoc);
return Invalid;
}
/// value-specifier: