Factor some code into the new Parser::MatchRHSPunctuation method.

llvm-svn: 38864
This commit is contained in:
Chris Lattner 2006-08-10 23:14:52 +00:00
parent b33dd875fe
commit 4564bc1123
5 changed files with 67 additions and 51 deletions

View File

@ -481,14 +481,9 @@ void Parser::ParseParenDeclarator(Declarator &D) {
// direct-declarator: '(' attributes declarator ')' [TODO]
if (isGrouping) {
ParseDeclaratorInternal(D);
if (Tok.getKind() == tok::r_paren) {
ConsumeParen();
} else {
// expected ')': skip until we find ')'.
Diag(Tok, diag::err_expected_rparen);
Diag(StartLoc, diag::err_matching, "(");
SkipUntil(tok::r_paren);
}
// Match the ')'.
MatchRHSPunctuation(tok::r_paren, StartLoc, "(",
diag::err_expected_rparen);
return;
}

View File

@ -34,9 +34,22 @@ void Parser::ParseAssignmentExpression() {
ParseExpression();
}
/// ParseCastExpression
/// cast-expression: [C99 6.5.4]
/// unary-expression
/// '(' type-name ')' cast-expression
///
void Parser::ParseCastExpression() {
ParseUnaryExpression();
// If this doesn't start with an '(', then it is a unary-expression.
if (Tok.getKind() != tok::l_paren)
return ParseUnaryExpression();
// Otherwise this is either a cast, a compound literal, or a parenthesized
// expression.
SourceLocation LParenLoc = Tok.getLocation();
ConsumeParen();
assert(0);
}
/// ParseUnaryExpression
@ -135,13 +148,8 @@ void Parser::ParseSizeofAlignofExpression() {
}
if (Tok.getKind() == tok::r_paren) {
ConsumeParen();
} else {
Diag(Tok, diag::err_expected_rparen);
Diag(LParenLoc, diag::err_matching, "(");
SkipUntil(tok::r_paren);
}
// Match the ')'.
MatchRHSPunctuation(tok::r_paren, LParenLoc, "(", diag::err_expected_rparen);
}
/// ParsePostfixExpression
@ -238,13 +246,8 @@ void Parser::ParsePostfixExpression() {
Loc = Tok.getLocation();
ConsumeBracket();
ParseExpression();
if (Tok.getKind() == tok::r_square) {
ConsumeBracket();
} else {
Diag(Tok, diag::err_expected_rsquare);
Diag(Loc, diag::err_matching, "[");
SkipUntil(tok::r_square);
}
// Match the ']'.
MatchRHSPunctuation(tok::r_square, Loc, "[", diag::err_expected_rsquare);
break;
case tok::l_paren: // p-e: p-e '(' argument-expression-list[opt] ')'
@ -260,13 +263,8 @@ void Parser::ParsePostfixExpression() {
ConsumeToken(); // Next argument.
}
if (Tok.getKind() == tok::r_paren) {
ConsumeParen();
} else {
Diag(Tok, diag::err_expected_rparen);
Diag(Loc, diag::err_matching, "(");
SkipUntil(tok::r_paren);
}
// Match the ')'.
MatchRHSPunctuation(tok::r_paren, Loc, "(", diag::err_expected_rparen);
break;
case tok::arrow: // postfix-expression: p-e '->' identifier
@ -294,12 +292,12 @@ void Parser::ParsePostfixExpression() {
/// primary-expression: [C99 6.5.1]
/// string-literal
void Parser::ParseStringLiteralExpression() {
assert(isStringLiteral() && "Not a string literal!");
assert(isTokenStringLiteral() && "Not a string literal!");
ConsumeStringToken();
// String concat. Note that keywords like __func__ and __FUNCTION__ aren't
// considered to be strings.
while (isStringLiteral())
while (isTokenStringLiteral())
ConsumeStringToken();
}
@ -328,10 +326,7 @@ void Parser::ParseParenExpression(bool ParenExprOnly) {
ParseExpression();
}
if (Tok.getKind() == tok::r_paren) {
ConsumeParen();
} else {
Diag(Tok, diag::err_expected_rparen);
Diag(OpenLoc, diag::err_matching, "(");
}
// Match the ')'.
MatchRHSPunctuation(tok::r_paren, OpenLoc, "(", diag::err_expected_rparen);
}

View File

@ -444,14 +444,8 @@ void Parser::ParseForStatement() {
ParseExpression();
}
if (Tok.getKind() == tok::r_paren) {
ConsumeParen();
} else {
Diag(Tok, diag::err_expected_rparen);
Diag(LParenLoc, diag::err_matching, "(");
SkipUntil(tok::r_paren);
return;
}
// Match the ')'.
MatchRHSPunctuation(tok::r_paren, LParenLoc, "(", diag::err_expected_rparen);
// Read the body statement.
ParseStatement();

View File

@ -36,6 +36,30 @@ void Parser::Diag(SourceLocation Loc, unsigned DiagID,
Diags.Report(Loc, DiagID, Msg);
}
/// MatchRHSPunctuation - For punctuation with a LHS and RHS (e.g. '['/']'),
/// this helper function matches and consumes the specified RHS token if
/// present. If not present, it emits the specified diagnostic indicating
/// that the parser failed to match the RHS of the token at LHSLoc. LHSName
/// should be the name of the unmatched LHS token.
void Parser::MatchRHSPunctuation(tok::TokenKind RHSTok, SourceLocation LHSLoc,
const char *LHSName, unsigned DiagID) {
if (Tok.getKind() == RHSTok) {
if (isTokenParen())
ConsumeParen();
else if (isTokenBracket())
ConsumeBracket();
else if (isTokenBrace())
ConsumeBrace();
else
ConsumeParen();
} else {
Diag(Tok, DiagID);
Diag(LHSLoc, diag::err_matching, LHSName);
SkipUntil(RHSTok);
}
}
//===----------------------------------------------------------------------===//
// Error recovery.
//===----------------------------------------------------------------------===//

View File

@ -75,9 +75,9 @@ public:
return Tok.getKind() == tok::l_brace || Tok.getKind() == tok::r_brace;
}
/// isStringLiteral - True if this token is a string-literal.
/// isTokenStringLiteral - True if this token is a string-literal.
///
bool isStringLiteral() const {
bool isTokenStringLiteral() const {
return Tok.getKind() == tok::string_literal;
}
@ -86,7 +86,7 @@ public:
/// tokens must be consumed with custom methods below.
void ConsumeToken() {
// Note: update Parser::SkipUntil if any other special tokens are added.
assert(!isStringLiteral() && !isTokenParen() && !isTokenBracket() &&
assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() &&
!isTokenBrace() &&
"Should consume special tokens with Consume*Token");
PP.Lex(Tok);
@ -133,11 +133,19 @@ public:
/// handles string literal concatenation, as per C99 5.1.1.2, translation
/// phase #6.
void ConsumeStringToken() {
assert(isStringLiteral() &&
assert(isTokenStringLiteral() &&
"Should only consume string literals with this method");
PP.Lex(Tok);
}
/// MatchRHSPunctuation - For punctuation with a LHS and RHS (e.g. '['/']'),
/// this helper function matches and consumes the specified RHS token if
/// present. If not present, it emits the specified diagnostic indicating
/// that the parser failed to match the RHS of the token at LHSLoc. LHSName
/// should be the name of the unmatched LHS token.
void MatchRHSPunctuation(tok::TokenKind RHSTok, SourceLocation LHSLoc,
const char *LHSName, unsigned Diag);
private:
//===--------------------------------------------------------------------===//
// Error recovery.