[cfe-commits] r38846 - in /cfe/cfe/trunk: Parse/ParseStmt.cpp include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Parser.h

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:25:08 PDT 2007


Author: sabre
Date: Wed Jul 11 11:25:08 2007
New Revision: 38846

URL: http://llvm.org/viewvc/llvm-project?rev=38846&view=rev
Log:
implement switch/while/do/for statement parsing, implementing Parser/statements.c:test2

Modified:
    cfe/cfe/trunk/Parse/ParseStmt.cpp
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/cfe/trunk/include/clang/Parse/Parser.h

Modified: cfe/cfe/trunk/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseStmt.cpp?rev=38846&r1=38845&r2=38846&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/ParseStmt.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseStmt.cpp Wed Jul 11 11:25:08 2007
@@ -44,9 +44,6 @@
 ///         'case' constant-expression ':' statement
 ///         'default' ':' statement
 ///
-///       expression-statement:
-///         expression[opt] ';'
-///
 ///       selection-statement:
 ///         if-statement
 ///         switch-statement
@@ -56,6 +53,9 @@
 ///         do-statement
 ///         for-statement
 ///
+///       expression-statement:
+///         expression[opt] ';'
+///
 ///       jump-statement:
 ///         'goto' identifier ';'
 ///         'continue' ';'
@@ -74,21 +74,28 @@
     SkipUntil(tok::semi);
     break;
     
-    // C99 6.8.2: compound-statement -> '{}' block
-  case tok::l_brace:
+    
+  case tok::l_brace:                // C99 6.8.2: compound-statement
     ParseCompoundStatement();
     break;
-    // C99 6.8.3: expression[opt] ';'
-  case tok::semi:
+  case tok::semi:                   // C99 6.8.3: expression[opt] ';'
     ConsumeToken();
     break;
-    
-    // C99 6.8.4.1: if-statement
-  case tok::kw_if:
+  case tok::kw_if:                  // C99 6.8.4.1: if-statement
     ParseIfStatement();
     break;
-    
-    
+  case tok::kw_switch:              // C99 6.8.4.2: switch-statement
+    ParseSwitchStatement();
+    break;
+  case tok::kw_while:               // C99 6.8.5.1: while-statement
+    ParseWhileStatement();
+    break;
+  case tok::kw_do:                  // C99 6.8.5.2: do-statement
+    ParseDoStatement();
+    break;
+  case tok::kw_for:                 // C99 6.8.5.3: for-statement
+    ParseForStatement();
+    break;
     // TODO: Handle OnlyStatement..
   }
 }
@@ -142,7 +149,7 @@
   ConsumeToken();  // eat the 'if'.
 
   if (Tok.getKind() != tok::l_paren) {
-    Diag(Tok, diag::err_expected_lparen_after_if, "if");
+    Diag(Tok, diag::err_expected_lparen_after, "if");
     SkipUntil(tok::semi);
     return;
   }
@@ -158,7 +165,151 @@
     ConsumeToken();
     ParseStatement();
   }
+}
+
+/// ParseSwitchStatement
+///       switch-statement:
+///         'switch' '(' expression ')' statement
+void Parser::ParseSwitchStatement() {
+  assert(Tok.getKind() == tok::kw_switch && "Not a switch stmt!");
+  ConsumeToken();  // eat the 'switch'.
+
+  if (Tok.getKind() != tok::l_paren) {
+    Diag(Tok, diag::err_expected_lparen_after, "switch");
+    SkipUntil(tok::semi);
+    return;
+  }
   
+  // Parse the condition.
+  ParseParenExpression();
+  
+  // Read the body statement.
+  ParseStatement();
 }
 
+/// ParseWhileStatement
+///       while-statement: [C99 6.8.5.1]
+///         'while' '(' expression ')' statement
+void Parser::ParseWhileStatement() {
+  assert(Tok.getKind() == tok::kw_while && "Not a while stmt!");
+  ConsumeToken();  // eat the 'while'.
+  
+  if (Tok.getKind() != tok::l_paren) {
+    Diag(Tok, diag::err_expected_lparen_after, "while");
+    SkipUntil(tok::semi);
+    return;
+  }
+  
+  // Parse the condition.
+  ParseParenExpression();
+  
+  // Read the body statement.
+  ParseStatement();
+}
+
+/// ParseDoStatement
+///       do-statement: [C99 6.8.5.2]
+///         'do' statement 'while' '(' expression ')' ';'
+void Parser::ParseDoStatement() {
+  assert(Tok.getKind() == tok::kw_do && "Not a do stmt!");
+  SourceLocation DoLoc = Tok.getLocation();
+  ConsumeToken();  // eat the 'do'.
+  
+  // Read the body statement.
+  ParseStatement();
+
+  if (Tok.getKind() != tok::kw_while) {
+    Diag(Tok, diag::err_expected_while);
+    Diag(DoLoc, diag::err_matching);
+    SkipUntil(tok::semi);
+    return;
+  }
+  ConsumeToken();
+  
+  if (Tok.getKind() != tok::l_paren) {
+    Diag(Tok, diag::err_expected_lparen_after, "do/while");
+    SkipUntil(tok::semi);
+    return;
+  }
+  
+  // Parse the condition.
+  ParseParenExpression();
+  
+  if (Tok.getKind() != tok::semi) {
+    Diag(Tok, diag::err_expected_semi_do_while);
+    SkipUntil(tok::semi);
+    return;
+  }
+}
+
+/// ParseForStatement
+///       for-statement: [C99 6.8.5.3]
+///         'for' '(' expr[opt] ';' expr[opt] ';' expr[opt] ')' statement
+///         'for' '(' declaration expr[opt] ';' expr[opt] ')' statement
+void Parser::ParseForStatement() {
+  assert(Tok.getKind() == tok::kw_for && "Not a for stmt!");
+  SourceLocation ForLoc = Tok.getLocation();
+  ConsumeToken();  // eat the 'for'.
+  
+  if (Tok.getKind() != tok::l_paren) {
+    Diag(Tok, diag::err_expected_lparen_after, "for");
+    SkipUntil(tok::semi);
+    return;
+  }
+
+  SourceLocation LParenLoc = Tok.getLocation();
+  ConsumeParen();
+  
+  // Parse the first part of the for specifier.
+  if (Tok.getKind() == tok::semi) {  // for (;
+    // no first part.
+  } else if (isDeclarationSpecifier()) {  // for (int X = 4;
+    // FIXME: Parse declaration.
+    assert(0);
+  } else {
+    ParseExpression();
+  }
+  
+  if (Tok.getKind() == tok::semi) {
+    ConsumeToken();
+  } else {
+    Diag(Tok, diag::err_expected_semi_for);
+    Diag(ForLoc, diag::err_matching);
+    SkipUntil(tok::semi);
+  }
+  
+  // Parse the second part of the for specifier.
+  if (Tok.getKind() == tok::semi) {  // for (...;;
+    // no second part.
+  } else {
+    ParseExpression();
+  }
+  
+  if (Tok.getKind() == tok::semi) {
+    ConsumeToken();
+  } else {
+    Diag(Tok, diag::err_expected_semi_for);
+    Diag(ForLoc, diag::err_matching);
+    SkipUntil(tok::semi);
+  }
+  
+  // Parse the third part of the for specifier.
+  if (Tok.getKind() == tok::r_paren) {  // for (...;...;)
+    // no third part.
+  } else {
+    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;
+  }
+  
+  // Read the body statement.
+  ParseStatement();
+}
 

Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=38846&r1=38845&r2=38846&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:25:08 2007
@@ -274,8 +274,14 @@
      "expected '=', ',', ';', 'asm', or '__attribute__' after declarator")
 DIAG(err_expected_statement_declaration, ERROR,
      "expected statement or declaration")
-DIAG(err_expected_lparen_after_if, ERROR,
+DIAG(err_expected_lparen_after, ERROR,
      "expected '(' after '%s'")
+DIAG(err_expected_while, ERROR,
+     "expected 'while' in do/while loop")
+DIAG(err_expected_semi_do_while, ERROR,
+     "expected ';' at end of do/while loop")
+DIAG(err_expected_semi_for, ERROR,
+     "expected ';' in 'for' statement specifier")
 
 /// err_matching - this is used as a continuation of a previous error, e.g. to 
 /// specify the '(' when we expected a ')'.  This should probably be some

Modified: cfe/cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/Parser.h?rev=38846&r1=38845&r2=38846&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:25:08 2007
@@ -162,7 +162,11 @@
   void ParseStatementOrDeclaration(bool OnlyStatement = false);
   void ParseCompoundStatement();
   void ParseIfStatement();
-
+  void ParseSwitchStatement();
+  void ParseWhileStatement();
+  void ParseDoStatement();
+  void ParseForStatement();
+  
   //===--------------------------------------------------------------------===//
   // C99 6.7: Declarations.
   void ParseDeclarationSpecifiers(DeclSpec &DS);





More information about the cfe-commits mailing list