diff src/parse.y @ 3665:0689afb1d001

[project @ 2000-05-11 19:07:56 by jwe]
author jwe
date Thu, 11 May 2000 19:10:09 +0000
parents 71bd2d124119
children 7066a8065e7e
line wrap: on
line diff
--- a/src/parse.y
+++ b/src/parse.y
@@ -46,6 +46,7 @@
 #include "file-ops.h"
 #include "file-stat.h"
 
+#include "comment-list.h"
 #include "defun.h"
 #include "dynamic-ld.h"
 #include "error.h"
@@ -103,6 +104,9 @@
 // Buffer for help text snagged from function files.
 std::string help_buf;
 
+// Buffer for comments appearing before a function statement.
+static std::string fcn_comment_header;
+
 // TRUE means we are using readline.
 // (--no-line-editing)
 bool line_editing = true;
@@ -179,28 +183,31 @@
 // Build an unwind-protect command.
 static tree_command *
 make_unwind_command (token *unwind_tok, tree_statement_list *body,
-		     tree_statement_list *cleanup, token *end_tok);
+		     tree_statement_list *cleanup, token *end_tok,
+		     octave_comment_list *lc, octave_comment_list *mc);
 
 // Build a try-catch command.
 static tree_command *
 make_try_command (token *try_tok, tree_statement_list *body,
-		  tree_statement_list *cleanup, token *end_tok);
+		  tree_statement_list *cleanup, token *end_tok,
+		  octave_comment_list *lc, octave_comment_list *mc);
 
 // Build a while command.
 static tree_command *
 make_while_command (token *while_tok, tree_expression *expr,
-		    tree_statement_list *body, token *end_tok);
+		    tree_statement_list *body, token *end_tok,
+		    octave_comment_list *lc);
 
 // Build a do-until command.
 static tree_command *
 make_do_until_command (token *do_tok, tree_statement_list *body,
-		       tree_expression *expr);
+		       tree_expression *expr, octave_comment_list *lc);
 
 // Build a for command.
 static tree_command *
 make_for_command (token *for_tok, tree_argument_list *lhs,
 		  tree_expression *expr, tree_statement_list *body,
-		  token *end_tok);
+		  token *end_tok, octave_comment_list *lc);
 
 // Build a break command.
 static tree_command *
@@ -220,20 +227,24 @@
 
 // Finish an if command.
 static tree_if_command *
-finish_if_command (token *if_tok, tree_if_command_list *list, token *end_tok);
+finish_if_command (token *if_tok, tree_if_command_list *list,
+		   token *end_tok, octave_comment_list *lc);
 
 // Build an elseif clause.
 static tree_if_clause *
-make_elseif_clause (tree_expression *expr, tree_statement_list *list);
+make_elseif_clause (tree_expression *expr, tree_statement_list *list,
+		    octave_comment_list *lc);
 
 // Finish a switch command.
 static tree_switch_command *
 finish_switch_command (token *switch_tok, tree_expression *expr,
-		       tree_switch_case_list *list, token *end_tok);
+		       tree_switch_case_list *list, token *end_tok,
+		       octave_comment_list *lc);
 
 // Build a switch case.
 static tree_switch_case *
-make_switch_case (tree_expression *expr, tree_statement_list *list);
+make_switch_case (tree_expression *expr, tree_statement_list *list,
+		  octave_comment_list *lc);
 
 // Build an assignment to a variable.
 static tree_expression *
@@ -250,11 +261,13 @@
 
 // Finish defining a function.
 static octave_user_function *
-finish_function (tree_identifier *id, octave_user_function *fcn);
+finish_function (tree_identifier *id, octave_user_function *fcn,
+		 octave_comment_list *lc);
 
 // Finish defining a function a different way.
 static octave_user_function *
-finish_function (tree_parameter_list *ret_list, octave_user_function *fcn);
+finish_function (tree_parameter_list *ret_list,
+		 octave_user_function *fcn, octave_comment_list *lc);
 
 // Reset state after parsing function.
 static void
@@ -309,6 +322,9 @@
   // The type of the basic tokens returned by the lexer.
   token *tok_val;
 
+  // Comment strings that we need to deal with mid-rule.
+  octave_comment_list *comment_type;
+
   // Types for the nonterminals we generate.
   char sep_type;
   tree *tree_type;
@@ -375,6 +391,7 @@
 %token USING TITLE WITH AXES COLON OPEN_BRACE CLOSE_BRACE CLEAR
 
 // Nonterminals we construct.
+%type <comment_type> stash_comment function_beg
 %type <sep_type> sep_no_nl opt_sep_no_nl sep opt_sep
 %type <tree_type> input
 %type <tree_constant_type> constant magic_colon
@@ -510,14 +527,28 @@
 		;
 
 statement	: expression
-		  { $$ = new tree_statement ($1); }
+		  {
+		    octave_comment_list *comment
+		      = octave_comment_buffer::get_comment ();
+
+		    $$ = new tree_statement ($1, comment);
+		  }
 		| command
-		  { $$ = new tree_statement ($1); }
+		  {
+		    octave_comment_list *comment
+		      = octave_comment_buffer::get_comment ();
+
+		    $$ = new tree_statement ($1, comment);
+		  }
 		| PLOT CLEAR
 		  {
 		    symbol_record *sr = lookup_by_name ("clearplot", 0);
 		    tree_identifier *id = new tree_identifier (sr);
-		    $$ = new tree_statement (id);
+
+		    octave_comment_list *comment
+		      = octave_comment_buffer::get_comment ();
+
+		    $$ = new tree_statement (id, comment);
 		  }
 		;
 
@@ -880,9 +911,9 @@
 // If statement
 // ============
 
-if_command	: IF if_cmd_list END
+if_command	: IF stash_comment if_cmd_list END
 		  {
-		    if (! ($$ = finish_if_command ($1, $2, $3)))
+		    if (! ($$ = finish_if_command ($1, $3, $4, $2)))
 		      ABORT_PARSE;
 		  }
 		;
@@ -905,21 +936,23 @@
 		  }
 		;
 
-elseif_clause	: ELSEIF opt_sep expression opt_sep opt_list
-		  { $$ = make_elseif_clause ($3, $5); }
+elseif_clause	: ELSEIF stash_comment opt_sep expression opt_sep opt_list
+		  { $$ = make_elseif_clause ($4, $6, $2); }
 		;
 
-else_clause	: ELSE opt_sep opt_list
-		  { $$ = new tree_if_clause ($3); }
+else_clause	: ELSE stash_comment opt_sep opt_list
+		  {
+		    $$ = new tree_if_clause ($4, $2);
+		  }
 		;
 
 // ================
 // Switch statement
 // ================
 
-switch_command	: SWITCH expression opt_sep case_list END
+switch_command	: SWITCH stash_comment expression opt_sep case_list END
 		  {
-		    if (! ($$ = finish_switch_command ($1, $2, $4, $5)))
+		    if (! ($$ = finish_switch_command ($1, $3, $5, $6, $2)))
 		      ABORT_PARSE;
 		  }
 		;
@@ -942,31 +975,33 @@
 		  }
 		;
 
-switch_case	: CASE opt_sep expression opt_sep list
-		  { $$ = make_switch_case ($3, $5); }
+switch_case	: CASE stash_comment opt_sep expression opt_sep list
+		  { $$ = make_switch_case ($4, $6, $2); }
 		;
 
-default_case	: OTHERWISE opt_sep opt_list
-		  { $$ = new tree_switch_case ($3); }
+default_case	: OTHERWISE stash_comment opt_sep opt_list
+		  {
+		    $$ = new tree_switch_case ($4, $2);
+		  }
 		;
 
 // =======
 // Looping
 // =======
 
-loop_command	: WHILE expression opt_sep opt_list END
+loop_command	: WHILE stash_comment expression opt_sep opt_list END
 		  {
-		    if (! ($$ = make_while_command ($1, $2, $4, $5)))
+		    if (! ($$ = make_while_command ($1, $3, $5, $6, $2)))
 		      ABORT_PARSE;
 		  }
-		| DO opt_sep opt_list UNTIL expression
+		| DO stash_comment opt_sep opt_list UNTIL expression
 		  {
-		    if (! ($$ = make_do_until_command ($1, $3, $5)))
+		    if (! ($$ = make_do_until_command ($1, $4, $6, $2)))
 		      ABORT_PARSE;
 		  }
-		| FOR assign_lhs '=' expression opt_sep opt_list END
+		| FOR stash_comment assign_lhs '=' expression opt_sep opt_list END
 		  {
-		    if (! ($$ = make_for_command ($1, $2, $4, $6, $7)))
+		    if (! ($$ = make_for_command ($1, $3, $5, $7, $8, $2)))
 		      ABORT_PARSE;
 		  }
 		;
@@ -996,14 +1031,16 @@
 // Exceptions
 // ==========
 
-except_command	: UNWIND opt_sep opt_list CLEANUP opt_sep opt_list END
+except_command	: UNWIND stash_comment opt_sep opt_list CLEANUP
+		  stash_comment opt_sep opt_list END
 		  {
-		    if (! ($$ = make_unwind_command ($1, $3, $6, $7)))
+		    if (! ($$ = make_unwind_command ($1, $4, $8, $9, $2, $6)))
 		      ABORT_PARSE;
 		  }
-		| TRY opt_sep opt_list CATCH opt_sep opt_list END
+		| TRY stash_comment opt_sep opt_list CATCH
+		  stash_comment opt_sep opt_list END
 		  {
-		    if (! ($$ = make_try_command ($1, $3, $6, $7)))
+		    if (! ($$ = make_try_command ($1, $4, $8, $9, $2, $6)))
 		      ABORT_PARSE;
 		  }
 		;
@@ -1136,23 +1173,25 @@
 // Function definition
 // ===================
 
-function_beg	: FCN global_symtab
+function_beg	: FCN stash_comment global_symtab
+		  { $$ = $2; }
 		;
 
 function	: function_beg function2
 		  {
+		    $2->stash_leading_comment ($1);
 		    recover_from_parsing_function ();
 		    $$ = 0;
 		  }
 		| function_beg identifier function1
 		  {
-		    finish_function ($2, $3);
+		    finish_function ($2, $3, $1);
 		    recover_from_parsing_function ();
 		    $$ = 0;
 		  }
 		| function_beg return_list function1
 		  {
-		    finish_function ($2, $3);
+		    finish_function ($2, $3, $1);
 		    recover_from_parsing_function ();
 		    $$ = 0;
 		  }
@@ -1355,6 +1394,10 @@
 // Miscellaneous
 // =============
 
+stash_comment	: // empty
+		  { $$ = octave_comment_buffer::get_comment (); }
+		;
+
 parse_error	: LEXICAL_ERROR
 		  { yyerror ("parse error"); }
 		| error
@@ -2030,16 +2073,20 @@
 
 static tree_command *
 make_unwind_command (token *unwind_tok, tree_statement_list *body,
-		     tree_statement_list *cleanup, token *end_tok)
+		     tree_statement_list *cleanup, token *end_tok,
+		     octave_comment_list *lc, octave_comment_list *mc)
 {
   tree_command *retval = 0;
 
   if (end_token_ok (end_tok, token::unwind_protect_end))
     {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
       int l = unwind_tok->line ();
       int c = unwind_tok->column ();
 
-      retval = new tree_unwind_protect_command (body, cleanup, l, c);
+      retval = new tree_unwind_protect_command (body, cleanup,
+						lc, mc, tc, l, c);
     }
 
   return retval;
@@ -2049,16 +2096,20 @@
 
 static tree_command *
 make_try_command (token *try_tok, tree_statement_list *body,
-		  tree_statement_list *cleanup, token *end_tok)
+		  tree_statement_list *cleanup, token *end_tok,
+		  octave_comment_list *lc, octave_comment_list *mc)
 {
   tree_command *retval = 0;
 
   if (end_token_ok (end_tok, token::try_catch_end))
     {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
       int l = try_tok->line ();
       int c = try_tok->column ();
 
-      retval = new tree_try_catch_command (body, cleanup, l, c);
+      retval = new tree_try_catch_command (body, cleanup,
+					   lc, mc, tc, l, c);
     }
 
   return retval;
@@ -2068,7 +2119,8 @@
 
 static tree_command *
 make_while_command (token *while_tok, tree_expression *expr,
-		    tree_statement_list *body, token *end_tok)
+		    tree_statement_list *body, token *end_tok,
+		    octave_comment_list *lc)
 {
   tree_command *retval = 0;
 
@@ -2076,12 +2128,14 @@
 
   if (end_token_ok (end_tok, token::while_end))
     {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
       lexer_flags.looping--;
 
       int l = while_tok->line ();
       int c = while_tok->column ();
 
-      retval = new tree_while_command (expr, body, l, c);
+      retval = new tree_while_command (expr, body, lc, tc, l, c);
     }
 
   return retval;
@@ -2091,18 +2145,20 @@
 
 static tree_command *
 make_do_until_command (token *do_tok, tree_statement_list *body,
-		       tree_expression *expr)
+		       tree_expression *expr, octave_comment_list *lc)
 {
   tree_command *retval = 0;
 
   maybe_warn_assign_as_truth_value (expr);
 
+  octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
   lexer_flags.looping--;
 
   int l = do_tok->line ();
   int c = do_tok->column ();
 
-  retval = new tree_do_until_command (expr, body, l, c);
+  retval = new tree_do_until_command (expr, body, lc, tc, l, c);
 
   return retval;
 }
@@ -2112,12 +2168,14 @@
 static tree_command *
 make_for_command (token *for_tok, tree_argument_list *lhs,
 		  tree_expression *expr, tree_statement_list *body,
-		  token *end_tok)
+		  token *end_tok, octave_comment_list *lc)
 {
   tree_command *retval = 0;
 
   if (end_token_ok (end_tok, token::for_end))
     {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
       lexer_flags.looping--;
 
       int l = for_tok->line ();
@@ -2127,12 +2185,14 @@
 	{
 	  tree_expression *tmp = lhs->remove_front ();
 
-	  retval = new tree_simple_for_command (tmp, expr, body, l, c);
+	  retval = new tree_simple_for_command (tmp, expr, body,
+						lc, tc, l, c);
 
 	  delete lhs;
 	}
       else
-	retval = new tree_complex_for_command (lhs, expr, body, l, c);
+	retval = new tree_complex_for_command (lhs, expr, body,
+					       lc, tc, l, c);
     }
 
   return retval;
@@ -2210,16 +2270,18 @@
 
 static tree_if_command *
 finish_if_command (token *if_tok, tree_if_command_list *list,
-		   token *end_tok)
+		   token *end_tok, octave_comment_list *lc)
 {
   tree_if_command *retval = 0;
 
   if (end_token_ok (end_tok, token::if_end))
     {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
       int l = if_tok->line ();
       int c = if_tok->column ();
 
-      retval = new tree_if_command (list, l, c);
+      retval = new tree_if_command (list, lc, tc, l, c);
     }
 
   return retval;
@@ -2228,27 +2290,31 @@
 // Build an elseif clause.
 
 static tree_if_clause *
-make_elseif_clause (tree_expression *expr, tree_statement_list *list)
+make_elseif_clause (tree_expression *expr, tree_statement_list *list,
+		    octave_comment_list *lc)
 {
   maybe_warn_assign_as_truth_value (expr);
 
-  return new tree_if_clause (expr, list);
+  return new tree_if_clause (expr, list, lc);
 }
 
 // Finish a switch command.
 
 static tree_switch_command *
 finish_switch_command (token *switch_tok, tree_expression *expr,
-		       tree_switch_case_list *list, token *end_tok)
+		       tree_switch_case_list *list, token *end_tok,
+		       octave_comment_list *lc)
 {
   tree_switch_command *retval = 0;
 
   if (end_token_ok (end_tok, token::switch_end))
     {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
       int l = switch_tok->line ();
       int c = switch_tok->column ();
 
-      retval = new tree_switch_command (expr, list, l, c);
+      retval = new tree_switch_command (expr, list, lc, tc, l, c);
     }
 
   return retval;
@@ -2257,11 +2323,12 @@
 // Build a switch case.
 
 static tree_switch_case *
-make_switch_case (tree_expression *expr, tree_statement_list *list)
+make_switch_case (tree_expression *expr, tree_statement_list *list,
+		  octave_comment_list *lc)
 {
   maybe_warn_variable_switch_label (expr);
 
-  return new tree_switch_case (expr, list);
+  return new tree_switch_case (expr, list, lc);
 }
 
 // Build an assignment to a variable.
@@ -2362,6 +2429,13 @@
   octave_user_function *fcn
     = new octave_user_function (param_list, 0, body, curr_sym_tab);
 
+  if (fcn)
+    {
+      octave_comment_list *tc = octave_comment_buffer::get_comment ();
+
+      fcn->stash_trailing_comment (tc);
+    }
+
   return fcn;
 }
 
@@ -2439,22 +2513,28 @@
 // Finish defining a function.
 
 static octave_user_function *
-finish_function (tree_identifier *id, octave_user_function *fcn)
+finish_function (tree_identifier *id, octave_user_function *fcn,
+		 octave_comment_list *lc)
 {
   tree_parameter_list *tpl = new tree_parameter_list (id);
 
   tpl->mark_as_formal_parameters ();
 
+  fcn->stash_leading_comment (lc);
+
   return fcn->define_ret_list (tpl);
 }
 
 // Finish defining a function a different way.
 
 static octave_user_function *
-finish_function (tree_parameter_list *ret_list, octave_user_function *fcn)
+finish_function (tree_parameter_list *ret_list,
+		 octave_user_function *fcn, octave_comment_list *lc)
 {
   ret_list->mark_as_formal_parameters ();
 
+  fcn->stash_leading_comment (lc);
+
   return fcn->define_ret_list (ret_list);
 }
 
@@ -2785,13 +2865,16 @@
 // comments read if it doesn't look like a copyright notice.  If
 // IN_PARTS, consider each block of comments separately; otherwise,
 // grab them all at once.  If UPDATE_POS is TRUE, line and column
-// number information is updated.
+// number information is updated.  If SAVE_COPYRIGHT is TRUE, then
+// comments that are recognized as a copyright notice are saved in the
+// comment buffer.
 
 // XXX FIXME XXX -- grab_help_text() in lex.l duplicates some of this
 // code!
 
 static std::string
-gobble_leading_white_space (FILE *ffile, bool in_parts, bool update_pos)
+gobble_leading_white_space (FILE *ffile, bool in_parts,
+			    bool update_pos, bool save_copyright)
 {
   std::string help_txt;
 
@@ -2893,11 +2976,17 @@
 
   if (! help_txt.empty ())
     {
-      if (looks_like_octave_copyright (help_txt)) 
-	help_txt.resize (0);
+      if (looks_like_octave_copyright (help_txt))
+	{
+	  if (save_copyright)
+	    octave_comment_buffer::append (help_txt);
+
+	  help_txt.resize (0);
+	}
 
       if (in_parts && help_txt.empty ())
-	help_txt = gobble_leading_white_space (ffile, in_parts, update_pos);
+	help_txt = gobble_leading_white_space (ffile, in_parts,
+					       update_pos, false);
     }
 
   return help_txt;
@@ -2916,7 +3005,7 @@
 	{
 	  unwind_protect::add (safe_fclose, (void *) fptr);
 
-	  retval = gobble_leading_white_space (fptr, true, true);
+	  retval = gobble_leading_white_space (fptr, true, true, false);
 
 	  unwind_protect::run ();
 	}
@@ -2932,7 +3021,7 @@
 
   long pos = ftell (ffile);
 
-  gobble_leading_white_space (ffile, false, false);
+  gobble_leading_white_space (ffile, false, false, false);
 
   char buf [10];
   fgets (buf, 10, ffile);
@@ -3031,10 +3120,12 @@
 
 	  reset_parser ();
 
-	  help_buf = gobble_leading_white_space (ffile, true, true);
+	  help_buf = gobble_leading_white_space (ffile, true, true, true);
+
+	  octave_comment_buffer::append (help_buf);
 
 	  // XXX FIXME XXX -- this should not be necessary.
-	  gobble_leading_white_space (ffile, false, true);
+	  gobble_leading_white_space (ffile, false, true, false);
 
 	  int status = yyparse ();