Two fixes:

1. Allow argument list of a call to be empty.
2. Handle expressions in a statement context that start with an identifier.
   These are nasty to handle due to the 'label:' production which requires
   having two tokens of look-ahead, or by having tricky code (which we
   choose to do).

llvm-svn: 38887
This commit is contained in:
Chris Lattner 2006-08-12 18:12:45 +00:00
parent 2c5c421203
commit 0c6c034c48
3 changed files with 50 additions and 9 deletions

View File

@ -195,7 +195,8 @@ Parser::ExprResult Parser::ParseExpression() {
return ParseRHSOfBinaryExpression(LHS, prec::Comma);
}
// Expr that doesn't include commas.
/// ParseAssignmentExpression - Parse an expr that doesn't include commas.
///
Parser::ExprResult Parser::ParseAssignmentExpression() {
ExprResult LHS = ParseCastExpression(false);
if (LHS.isInvalid) return LHS;
@ -203,6 +204,35 @@ Parser::ExprResult Parser::ParseAssignmentExpression() {
return ParseRHSOfBinaryExpression(LHS, prec::Assignment);
}
/// ParseExpressionWithLeadingIdentifier - This special purpose method is used
/// in contexts where we have already consumed an identifier (which we saved in
/// 'Tok'), then discovered that the identifier was really the leading token of
/// part of an expression. For example, in "A[1]+B", we consumed "A" (which is
/// now in 'Tok') and the current token is "[".
Parser::ExprResult Parser::
ParseExpressionWithLeadingIdentifier(const LexerToken &Tok) {
// We know that 'Tok' must correspond to this production:
// primary-expression: identifier
// TODO: Pass 'Tok' to the action.
ExprResult Res = ExprResult(false);
// Because we have to parse an entire cast-expression before starting the
// ParseRHSOfBinaryExpression method (which parses any trailing binops), we
// need to handle the 'postfix-expression' rules. We do this by invoking
// ParsePostfixExpressionSuffix to consume any postfix-expression suffixes:
Res = ParsePostfixExpressionSuffix(Res);
if (Res.isInvalid) return Res;
// At this point, the "A[1]" part of "A[1]+B" has been consumed. Once this is
// done, we know we don't have to do anything for cast-expression, because the
// only non-postfix-expression production starts with a '(' token, and we know
// we have an identifier. As such, we can invoke ParseRHSOfBinaryExpression
// to consume any trailing operators (e.g. "+" in this example) and connected
// chunks of the expression.
return ParseRHSOfBinaryExpression(Res, prec::Comma);
}
/// ParseRHSOfBinaryExpression - Parse a binary expression that starts with
/// LHS and has a precedence of at least MinPrec.
Parser::ExprResult
@ -476,11 +506,13 @@ Parser::ExprResult Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
Loc = Tok.getLocation();
ConsumeParen();
while (1) {
ParseAssignmentExpression();
if (Tok.getKind() != tok::comma)
break;
ConsumeToken(); // Next argument.
if (Tok.getKind() != tok::r_paren) {
while (1) {
ParseAssignmentExpression();
if (Tok.getKind() != tok::comma)
break;
ConsumeToken(); // Next argument.
}
}
// Match the ')'.

View File

@ -185,6 +185,7 @@ void Parser::ParseIdentifierStatement(bool OnlyStatement) {
IdentifierInfo *II = Tok.getIdentifierInfo();
assert(Tok.getKind() == tok::identifier && II && "Not an identifier!");
LexerToken IdentTok = Tok; // Save the token.
ConsumeToken(); // eat the identifier.
// identifier ':' statement
@ -211,9 +212,16 @@ void Parser::ParseIdentifierStatement(bool OnlyStatement) {
return;
}
// Otherwise, this is an expression. Seed it with II.
assert(0);
// Otherwise, this is an expression. Seed it with II and parse it.
ExprResult Res = ParseExpressionWithLeadingIdentifier(IdentTok);
if (Res.isInvalid)
SkipUntil(tok::semi);
else if (Tok.getKind() == tok::semi)
ConsumeToken();
else {
Diag(Tok, diag::err_expected_semi_after, "expression");
SkipUntil(tok::semi);
}
}
/// ParseCaseStatement

View File

@ -178,6 +178,7 @@ private:
//===--------------------------------------------------------------------===//
// C99 6.5: Expressions.
//ExprResult ParseExpression(); // Above.
ExprResult ParseExpressionWithLeadingIdentifier(const LexerToken &Tok);
ExprResult ParseAssignmentExpression(); // Expr that doesn't include commas.
ExprResult ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec);