diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2008-07-09 22:53:07 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2008-07-09 22:53:07 +0000 |
commit | f7da726f09a6b7c5b9f5308e9690cb015398e671 (patch) | |
tree | 5ad8b5e569574f0626a77cc6be84b9c88a0e5e72 | |
parent | 9e0ed0bd5a3a7bac73973980ff32132a7724e674 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53376 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Parse/Parser.h | 9 | ||||
-rw-r--r-- | lib/Parse/ParseExpr.cpp | 63 | ||||
-rw-r--r-- | lib/Parse/ParseInit.cpp | 13 | ||||
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 71 |
4 files changed, 54 insertions, 102 deletions
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 640a2044a8..e45aa3501a 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -205,6 +205,12 @@ private: 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 @@ private: 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 @@ private: 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); diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index b1499c9fd6..17797ec488 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -228,69 +228,6 @@ Parser::ExprResult Parser::ParseConstantExpression() { 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 diff --git a/lib/Parse/ParseInit.cpp b/lib/Parse/ParseInit.cpp index a1fe04b731..c7c08dccbc 100644 --- a/lib/Parse/ParseInit.cpp +++ b/lib/Parse/ParseInit.cpp @@ -142,19 +142,18 @@ Parser::ExprResult Parser::ParseInitializerWithPotentialDesignator() { // 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(); } } } diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 670181e224..b8ebc42a06 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -79,8 +79,11 @@ Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) { 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 @@ Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) { 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(); + // 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); - } + 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 @@ Parser::StmtResult Parser::ParseIdentifierStatement(bool OnlyStatement) { 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; |