C++ patch [cp-parser-branch]

Theodore Papadopoulo Theodore.Papadopoulo@sophia.inria.fr
Mon Dec 3 12:26:00 GMT 2001


While reading the code for the new parser (which is IMHO much more understandable
than the old code up to now), I figured out some minor nits.
Most of them are just typos in comments. The remaining few are code
simplification, and one is a potential bug. These non-typos bug are described with some
details below. Unfortunately, I have not tested these changes and won't have time
to do so before january. Since this is a branch and those seem very obvious, I'm
submitting them nonetheless. If this patch is not applied, until january, I'll
try to find disk space and time to test this.

The potential bug:

    cp_lexer_maybe_grow_buffer seems to be wrong when growing buffers for which
    lexer->next_token and lexer->first_token are equal. In such a case, it will
    add the size of the old buffer to lexer->next_token when doing the pointer
    translation. The solution is simple, use cp_lexer_token_difference.

Code simplifications:

    cp_lexer_get_preprocessor_token: The diagnostic code is set at the
          beginning of each loop and reset at its end to its previous 
          state. Since the loop test has no side effect, moving this code
          outside (before and after) the loop should be equivalent.

    cp_lexer_peek_nth_token: Make the code look like in the other function,
          in particular cp_lexer_peek_token.

    cp_lexer_rollback_tokens: cp_lexer_save_tokens is careful to read a token
          so that lexer->next_token cannot conceivably be NULL at this point.
          I should remove the code completely instead of commenting it out.

    cp_parser_translation_unit: The loop is never executed more than once since
          it is exited either through the break or throught the return, change
          the code layout to reflect this and remove the unnecessary 
          loop.

2000-12-03 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>

    * parser.c: Fix typo in comments.
      (cp_lexer_maybe_grow_buffer): Use cp_lexer_token_difference.
      (cp_lexer_get_preprocessor_token): Simplify code.
      (cp_lexer_peek_nth_token): Make code more cannonic.
      (cp_lexer_rollback_tokens): Remove dead code.
      (cp_parser_translation_unit): Simplify code.

Index: gcc/cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/Attic/parser.c,v
retrieving revision 1.1.2.34
diff -c -3 -p -r1.1.2.34 parser.c
*** parser.c	2001/11/21 10:00:35	1.1.2.34
--- parser.c	2001/12/03 18:53:30
*************** cp_lexer_read_token (lexer)
*** 364,370 ****
  
        /* When we grow the buffer, we may invalidate TOKEN.  So, save
  	 the distance from the beginning of the BUFFER so that we can
! 	 recaulate it.  */
        delta = cp_lexer_token_difference (lexer, lexer->buffer, token);
        /* Make sure there is room in the buffer for another token.  */
        cp_lexer_maybe_grow_buffer (lexer);
--- 364,370 ----
  
        /* When we grow the buffer, we may invalidate TOKEN.  So, save
  	 the distance from the beginning of the BUFFER so that we can
! 	 recalculate it.  */
        delta = cp_lexer_token_difference (lexer, lexer->buffer, token);
        /* Make sure there is room in the buffer for another token.  */
        cp_lexer_maybe_grow_buffer (lexer);
*************** cp_lexer_read_token (lexer)
*** 396,402 ****
  	 order to get the type set correctly.  */
        token->value = combine_strings (nreverse (token->value));
        /* Strings should have type `const char []'.  Right now, we will
! 	 an ARRAY_TYPE that is constant rather than an array of
  	 constant elements.  */
        if (flag_const_strings)
  	{
--- 396,402 ----
  	 order to get the type set correctly.  */
        token->value = combine_strings (nreverse (token->value));
        /* Strings should have type `const char []'.  Right now, we will
! 	 get an ARRAY_TYPE that is constant rather than an array of
  	 constant elements.  */
        if (flag_const_strings)
  	{
*************** cp_lexer_maybe_grow_buffer (lexer)
*** 456,468 ****
  	= new_buffer + (lexer->first_token - old_buffer);
        if (lexer->next_token != NULL)
  	{
! 	  ptrdiff_t next_token_delta;
! 
! 	  if (lexer->next_token > lexer->first_token)
! 	    next_token_delta = lexer->next_token - lexer->first_token;
! 	  else
! 	    next_token_delta = 
! 	      buffer_length - (lexer->first_token - lexer->next_token);
  	  lexer->next_token = new_first_token + next_token_delta;
  	}
        lexer->last_token = new_first_token + buffer_length;
--- 456,464 ----
  	= new_buffer + (lexer->first_token - old_buffer);
        if (lexer->next_token != NULL)
  	{
! 	  const ptrdiff_t next_token_delta =
!             cp_lexer_token_difference(lexer, lexer->first_token,
!                                       lexer->next_token);
  	  lexer->next_token = new_first_token + next_token_delta;
  	}
        lexer->last_token = new_first_token + buffer_length;
*************** cp_lexer_get_preprocessor_token (lexer, 
*** 502,507 ****
--- 498,504 ----
    const char *saved_filename;
    int saved_lineno;
    bool done;
+   bool tentative_diagnostics_p;
  
    /* If there's no INPUT_STREAM, return a terminating CPP_EOF token.  */
    if (!lexer->input_stream)
*************** cp_lexer_get_preprocessor_token (lexer, 
*** 521,540 ****
    saved_lineno = lineno;
    saved_filename = input_filename;
  
    done = false;
    /* Keep going until we get a token we like.  */
    while (!done)
      {
-       bool tentative_diagnostics_p;
- 
-       /* Lexing the token might generate error messages.  Any such error
- 	 messages should be issued right away because if we are parsing
- 	 tentatively we will not re-lex the token if we reject this
- 	 tentative parse.  */
-       tentative_diagnostics_p 
- 	= diagnostic_buffer->ds->tentative_diagnostic;
-       if (tentative_diagnostics_p)
- 	diagnostic_issue_immediately (diagnostic_buffer);
        /* Get a new token from the preprocessor.  The call to c_lex should
  	 really require us to pass the INPUT_STREAM, but it is hardwired
  	 to use a global value.  */
--- 518,536 ----
    saved_lineno = lineno;
    saved_filename = input_filename;
  
+   /* Lexing the token might generate error messages.  Any such error
+      messages should be issued right away because if we are parsing
+      tentatively we will not re-lex the token if we reject this
+      tentative parse.  */
+   tentative_diagnostics_p 
+     = diagnostic_buffer->ds->tentative_diagnostic;
+   if (tentative_diagnostics_p)
+     diagnostic_issue_immediately (diagnostic_buffer);
+ 
    done = false;
    /* Keep going until we get a token we like.  */
    while (!done)
      {
        /* Get a new token from the preprocessor.  The call to c_lex should
  	 really require us to pass the INPUT_STREAM, but it is hardwired
  	 to use a global value.  */
*************** cp_lexer_get_preprocessor_token (lexer, 
*** 557,566 ****
  	  done = true;
  	  break;
  	}
-       /* If we switched diagnostic modes, switch back now.  */
-       if (tentative_diagnostics_p)
- 	diagnostic_cease_issuing_immediately (diagnostic_buffer);
      }
    /* Now we've got our token.  */
    token->line_number = lineno;
    token->file_name = input_filename;
--- 553,564 ----
  	  done = true;
  	  break;
  	}
      }
+ 
+   /* If we switched diagnostic modes, switch back now.  */
+   if (tentative_diagnostics_p)
+     diagnostic_cease_issuing_immediately (diagnostic_buffer);
+ 
    /* Now we've got our token.  */
    token->line_number = lineno;
    token->file_name = input_filename;
*************** cp_lexer_peek_nth_token (lexer, n)
*** 663,675 ****
    my_friendly_assert (n > 0, 20000224);
  
    /* Skip ahead from NEXT_TOKEN, reading more tokens as necessary.  */
!   token = lexer->next_token;
    /* If there are no tokens in the buffer, get one now.  */
!   if (!token)
!     {
!       cp_lexer_read_token (lexer);
!       token = lexer->next_token;
!     }
  
    /* Now, read tokens until we have enough.  */
    while (--n > 0)
--- 661,671 ----
    my_friendly_assert (n > 0, 20000224);
  
    /* Skip ahead from NEXT_TOKEN, reading more tokens as necessary.  */
! 
    /* If there are no tokens in the buffer, get one now.  */
!   if (!lexer->next_token)
!     cp_lexer_read_token (lexer);
!   token = lexer->next_token;
  
    /* Now, read tokens until we have enough.  */
    while (--n > 0)
*************** cp_lexer_commit_tokens (lexer)
*** 769,775 ****
  }
  
  /* Return all tokens saved since the last call to cp_lexer_save_tokens
!    to the token stream.  Stop saving tokens.  */
  
  static void
  cp_lexer_rollback_tokens (lexer)
--- 765,771 ----
  }
  
  /* Return all tokens saved since the last call to cp_lexer_save_tokens
!    to the token stream.  */
  
  static void
  cp_lexer_rollback_tokens (lexer)
*************** cp_lexer_rollback_tokens (lexer)
*** 786,797 ****
    token = VARRAY_TOP_GENERIC_PTR (lexer->saved_tokens);
    /* Make it the next token again now.  */
    lexer->next_token = token;
!   /* It might be the case that there wer no tokens when we started
!      saving tokens, but that there are some tokens now.  */
    if (!lexer->next_token && lexer->first_token)
      lexer->next_token = lexer->first_token;
  
!   /* Stop saving tokens.  */
    VARRAY_POP (lexer->saved_tokens);
  
    /* Set the source position back to the location where we started
--- 782,796 ----
    token = VARRAY_TOP_GENERIC_PTR (lexer->saved_tokens);
    /* Make it the next token again now.  */
    lexer->next_token = token;
! #if 0
!   /* It might be the case that there were no tokens when we started
!      saving tokens, but that there are some tokens now.
!      Can this still happen, I believe no (see cp_lexer_save_tokens) ??? (TO) */
    if (!lexer->next_token && lexer->first_token)
      lexer->next_token = lexer->first_token;
+ #endif
  
!   /* Stop this flow of saving tokens.  */
    VARRAY_POP (lexer->saved_tokens);
  
    /* Set the source position back to the location where we started
*************** cp_lexer_ggc_mark (data)
*** 825,831 ****
    cp_lexer *lexer = (cp_lexer *) data;
    cp_token *token;
  
!   /* If there are no saved tokens, there is nothing to do.  */
    if (!lexer->first_token)
      return;
  
--- 824,830 ----
    cp_lexer *lexer = (cp_lexer *) data;
    cp_token *token;
  
!   /* If there are no valid tokens, there is nothing to do.  */
    if (!lexer->first_token)
      return;
  
*************** cp_lexer_stop_debugging (lexer)
*** 1014,1020 ****
  /* FIXME: Check for all the places new types are not allowed to be 
     defined:
  
!    - Return typse
     - Parameter types
     - friend-declaration
     - va_arg?
--- 1013,1019 ----
  /* FIXME: Check for all the places new types are not allowed to be 
     defined:
  
!    - Return types
     - Parameter types
     - friend-declaration
     - va_arg?
*************** struct cp_parser
*** 1241,1247 ****
  
    /* A queue of functions whose bodies have been lexed, but may not
       have been parsed.  These functions are friends of members defined
!      within a class-specification; they are not procssed until the
       class is complete.  Functions appear in the queue in the reverse
       order that appeared in the source.  The TREE_PURPOSE of each node
       is the class in which the function was defined or declared; the
--- 1240,1246 ----
  
    /* A queue of functions whose bodies have been lexed, but may not
       have been parsed.  These functions are friends of members defined
!      within a class-specification; they are not processed until the
       class is complete.  Functions appear in the queue in the reverse
       order that appeared in the source.  The TREE_PURPOSE of each node
       is the class in which the function was defined or declared; the
*************** cp_parser_commit_to_construct (parser)
*** 1849,1855 ****
       cp_parser *parser;
  {
    /* We don't want to undo the effects of
!      cp_parser_commit_to_tenative_parse, which is stronger than this
       function.  */
    if (cp_parser_error_occurred (parser))
      parser->context->status = CP_PARSER_STATUS_KIND_NO_ERROR;
--- 1848,1854 ----
       cp_parser *parser;
  {
    /* We don't want to undo the effects of
!      cp_parser_commit_to_tentative_parse, which is stronger than this
       function.  */
    if (cp_parser_error_occurred (parser))
      parser->context->status = CP_PARSER_STATUS_KIND_NO_ERROR;
*************** static bool
*** 2090,2107 ****
  cp_parser_translation_unit (parser)
       cp_parser *parser;
  {
!   while (true)
!     {
!       cp_parser_declaration_seq_opt (parser);
  
!       /* If there are no tokens left then all went well.  */
!       if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
! 	break;
!       
!       /* Otherwise, issue an error message.  */
!       cp_parser_error (parser, "expected declaration");
!       return false;
!     }
  
    /* Consume the EOF token.  */
    cp_parser_require (parser, CPP_EOF, "end-of-file");
--- 2089,2102 ----
  cp_parser_translation_unit (parser)
       cp_parser *parser;
  {
!   cp_parser_declaration_seq_opt (parser);
  
!   /* If there are no tokens left then all went well.  */
!   if (!cp_lexer_next_token_is (parser->lexer, CPP_EOF)) {
!     /* Otherwise, issue an error message.  */
!     cp_parser_error (parser, "expected declaration");
!     return false;
!   }
  
    /* Consume the EOF token.  */
    cp_parser_require (parser, CPP_EOF, "end-of-file");

 --------------------------------------------------------------------
 Theodore Papadopoulo
 Email: Theodore.Papadopoulo@sophia.inria.fr Tel: (33) 04 92 38 76 01
 --------------------------------------------------------------------



-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 226 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20011203/600663bb/attachment.sig>


More information about the Gcc-patches mailing list