[cfe-commits] r53376 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseExpr.cpp lib/Parse/ParseInit.cpp lib/Parse/ParseStmt.cpp
Argiris Kirtzidis
akyrtzi at gmail.com
Wed Jul 9 15:53:07 PDT 2008
Author: akirtzidis
Date: Wed Jul 9 17:53:07 2008
New Revision: 53376
URL: http://llvm.org/viewvc/llvm-project?rev=53376&view=rev
Log:
Simplify the parser a bit by looking at the next token without consuming it (by Preprocessor::LookNext):
-Remove ParseExpressionWithLeadingIdentifier and ParseAssignmentExprWithLeadingIdentifier.
-Separate ParseLabeledStatement from ParseIdentifierStatement.
Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Parse/ParseInit.cpp
cfe/trunk/lib/Parse/ParseStmt.cpp
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=53376&r1=53375&r2=53376&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Wed Jul 9 17:53:07 2008
@@ -205,6 +205,12 @@
if (N == 0 || Tok.is(tok::eof)) return Tok;
return PP.LookAhead(N-1);
}
+
+ /// NextToken - This peeks ahead one token and returns it without
+ /// consuming it.
+ const Token &NextToken() {
+ return PP.LookNext();
+ }
/// MatchRHSPunctuation - For punctuation with a LHS and RHS (e.g. '['/']'),
@@ -369,9 +375,7 @@
ExprResult ParseConstantExpression();
ExprResult ParseAssignmentExpression(); // Expr that doesn't include commas.
- ExprResult ParseExpressionWithLeadingIdentifier(const Token &Tok);
ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc);
- ExprResult ParseAssignmentExprWithLeadingIdentifier(const Token &Tok);
ExprResult ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec);
ExprResult ParseCastExpression(bool isUnaryExpression);
@@ -453,6 +457,7 @@
StmtResult ParseStatement() { return ParseStatementOrDeclaration(true); }
StmtResult ParseStatementOrDeclaration(bool OnlyStatement = false);
StmtResult ParseIdentifierStatement(bool OnlyStatement);
+ StmtResult ParseLabeledStatement();
StmtResult ParseCaseStatement();
StmtResult ParseDefaultStatement();
StmtResult ParseCompoundStatement(bool isStmtExpr = false);
Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=53376&r1=53375&r2=53376&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Wed Jul 9 17:53:07 2008
@@ -228,69 +228,6 @@
return ParseRHSOfBinaryExpression(LHS, prec::Conditional);
}
-/// ParseExpressionWithLeadingIdentifier - This special purpose method is used
-/// in contexts where we have already consumed an identifier (which we saved in
-/// 'IdTok'), 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 'IdTok') and the current token is "[".
-Parser::ExprResult Parser::
-ParseExpressionWithLeadingIdentifier(const Token &IdTok) {
- // We know that 'IdTok' must correspond to this production:
- // primary-expression: identifier
-
- // Let the actions module handle the identifier.
- ExprResult Res = Actions.ActOnIdentifierExpr(CurScope, IdTok.getLocation(),
- *IdTok.getIdentifierInfo(),
- Tok.is(tok::l_paren));
-
- // 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);
-}
-
-/// ParseExpressionWithLeadingIdentifier - This special purpose method is used
-/// in contexts where we have already consumed an identifier (which we saved in
-/// 'IdTok'), then discovered that the identifier was really the leading token
-/// of part of an assignment-expression. For example, in "A[1]+B", we consumed
-/// "A" (which is now in 'IdTok') and the current token is "[".
-Parser::ExprResult Parser::
-ParseAssignmentExprWithLeadingIdentifier(const Token &IdTok) {
- // We know that 'IdTok' must correspond to this production:
- // primary-expression: identifier
-
- // Let the actions module handle the identifier.
- ExprResult Res = Actions.ActOnIdentifierExpr(CurScope, IdTok.getLocation(),
- *IdTok.getIdentifierInfo(),
- Tok.is(tok::l_paren));
-
- // 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::Assignment);
-}
-
-
/// ParseRHSOfBinaryExpression - Parse a binary expression that starts with
/// LHS and has a precedence of at least MinPrec.
Parser::ExprResult
Modified: cfe/trunk/lib/Parse/ParseInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseInit.cpp?rev=53376&r1=53375&r2=53376&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseInit.cpp (original)
+++ cfe/trunk/lib/Parse/ParseInit.cpp Wed Jul 9 17:53:07 2008
@@ -142,19 +142,18 @@
// assignment-expression or if it is an old-style structure field
// designator.
// TODO: Check that this is the first designator.
- Token Ident = Tok;
- ConsumeToken();
// If this is the gross GNU extension, handle it now.
- if (Tok.is(tok::colon)) {
- Diag(Ident, diag::ext_gnu_old_style_field_designator);
+ if (NextToken().is(tok::colon)) {
+ Diag(Tok, diag::ext_gnu_old_style_field_designator);
+ ConsumeToken(); // The identifier.
+ assert(Tok.is(tok::colon) && "NextToken() not working properly!");
ConsumeToken();
return ParseInitializer();
}
- // Otherwise, we just consumed the first token of an expression. Parse
- // the rest of it now.
- return ParseAssignmentExprWithLeadingIdentifier(Ident);
+ // Otherwise, parse the assignment-expression.
+ return ParseAssignmentExpression();
}
}
}
Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=53376&r1=53375&r2=53376&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Wed Jul 9 17:53:07 2008
@@ -79,8 +79,11 @@
tok::TokenKind Kind = Tok.getKind();
SourceLocation AtLoc;
switch (Kind) {
- case tok::identifier: // C99 6.8.1: labeled-statement
- // identifier ':' statement
+ case tok::identifier:
+ if (NextToken().is(tok::colon)) { // C99 6.8.1: labeled-statement
+ // identifier ':' statement
+ return ParseLabeledStatement();
+ }
// declaration (if !OnlyStatement)
// expression[opt] ';'
return ParseIdentifierStatement(OnlyStatement);
@@ -174,53 +177,61 @@
return Res;
}
-/// ParseIdentifierStatement - Because we don't have two-token lookahead, we
-/// have a bit of a quandry here. Reading the identifier is necessary to see if
-/// there is a ':' after it. If there is, this is a label, regardless of what
-/// else the identifier can mean. If not, this is either part of a declaration
-/// (if the identifier is a type-name) or part of an expression.
+/// ParseLabeledStatement - We have an identifier and a ':' after it.
///
/// labeled-statement:
/// identifier ':' statement
/// [GNU] identifier ':' attributes[opt] statement
-/// declaration (if !OnlyStatement)
-/// expression[opt] ';'
///
-Parser::StmtResult Parser::ParseIdentifierStatement(bool OnlyStatement) {
+Parser::StmtResult Parser::ParseLabeledStatement() {
assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
"Not an identifier!");
Token IdentTok = Tok; // Save the whole token.
ConsumeToken(); // eat the identifier.
+
+ assert(Tok.is(tok::colon) && "Not a label!");
// identifier ':' statement
- if (Tok.is(tok::colon)) {
- SourceLocation ColonLoc = ConsumeToken();
+ SourceLocation ColonLoc = ConsumeToken();
- // Read label attributes, if present.
- DeclTy *AttrList = 0;
- if (Tok.is(tok::kw___attribute))
- // TODO: save these somewhere.
- AttrList = ParseAttributes();
-
- StmtResult SubStmt = ParseStatement();
-
- // Broken substmt shouldn't prevent the label from being added to the AST.
- if (SubStmt.isInvalid)
- SubStmt = Actions.ActOnNullStmt(ColonLoc);
-
- return Actions.ActOnLabelStmt(IdentTok.getLocation(),
- IdentTok.getIdentifierInfo(),
- ColonLoc, SubStmt.Val);
- }
+ // Read label attributes, if present.
+ DeclTy *AttrList = 0;
+ if (Tok.is(tok::kw___attribute))
+ // TODO: save these somewhere.
+ AttrList = ParseAttributes();
+
+ StmtResult SubStmt = ParseStatement();
+
+ // Broken substmt shouldn't prevent the label from being added to the AST.
+ if (SubStmt.isInvalid)
+ SubStmt = Actions.ActOnNullStmt(ColonLoc);
+ return Actions.ActOnLabelStmt(IdentTok.getLocation(),
+ IdentTok.getIdentifierInfo(),
+ ColonLoc, SubStmt.Val);
+}
+
+/// ParseIdentifierStatement - This is either part of a declaration
+/// (if the identifier is a type-name) or part of an expression.
+///
+/// declaration (if !OnlyStatement)
+/// expression[opt] ';'
+///
+Parser::StmtResult Parser::ParseIdentifierStatement(bool OnlyStatement) {
+ assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
+ "Not an identifier!");
+
// Check to see if this is a declaration.
void *TypeRep;
if (!OnlyStatement &&
- (TypeRep = Actions.isTypeName(*IdentTok.getIdentifierInfo(), CurScope))) {
+ (TypeRep = Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope))) {
// Handle this. Warn/disable if in middle of block and !C99.
DeclSpec DS;
+ Token IdentTok = Tok; // Save the whole token.
+ ConsumeToken(); // eat the identifier.
+
// Add the typedef name to the start of the decl-specs.
const char *PrevSpec = 0;
int isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef,
@@ -263,8 +274,8 @@
DeclaratorInfo.getSourceRange().getEnd());
}
- // Otherwise, this is an expression. Seed it with II and parse it.
- ExprResult Res = ParseExpressionWithLeadingIdentifier(IdentTok);
+ // Otherwise, this is an expression.
+ ExprResult Res = ParseExpression();
if (Res.isInvalid) {
SkipUntil(tok::semi);
return true;
More information about the cfe-commits
mailing list