diff libinterp/parse-tree/lex.ll @ 16203:127cccb037bf

move more global parser and lexer variables to classes * pt-check.h, pt-check.cc (tree_checker::file_name): New data member. (tree_checker::gripe): Use it instead of curr_fcn_file_name. * input.h, input.cc, octave.cc (input_from_command_line_file): Delete global variable and all uses. * parse.h, oct-parse.in.yy (input_from_startup_file): Delete global variable and all uses. * input.h, input.cc, lex.h, lex.ll (curr_fcn_file_name, curr_fcn_file_full_name): Declare as members of lexical_feedback class. Rename to fcn_file_name and fcn_file_full_name. Change all uses. * oct-parse.in.yy (parse_fcn_file): New arg, file. Set curr_lexer->fcn_file_name and curr_lexer->fcn_file_full_name here. (load_fcn_from_file): Pass short file name to parse_fcn_file. * octave.cc (execute_command_line_file): Not here. * lex.h, lex.ll (lexical_feedback::force_script): New data member. * oct-parse.in.yy (parse_fcn_file): Set it here. * lex.h, lex.ll (lexical_feedback::input_from_terminal, lexical_feedback::input_from_file): New functions. * lex.ll (octave_lexer::handle_keyword): Set reading_fcn_file, reading_classdef_file, and reading_script_file. * lex.h, lex.ll (lexical_feedback::token_count): New variable. (COUNT_TOK_AND_RETURN): Increment it here. Don't count '\n' as a token. * lex.h, lex.ll (lexical_feedback::help_text): New variable. * parse.h, parse.in.yy (help_buf): Delete global variable and all uses. (octave_parser::frob_function, octave_parser::make_script): Use help_text. * lex.ll (octave_lexer::process_comment): Cache doc string directly in help_text variable. (looks_like_copyright): Move here from parse.in.yy. * lex.h, lex.ll (octave_lexer::prep_for_file): New function. (octave_lexer::prep_for_function_file, octave_lexer::prep_for_script_file): Delete. * parse.in.yy (INPUT_FILE_BEGIN): New start state. Delete SCRIPT_FILE_BEGIN and FCN_FILE_BEGIN. Tentatively set curr_lexer->reading_script_file to true. (parse_fcn_file): Call curr_lexer->prep_for_file. Don't call gobble_leading_whitespace. Don't attempt to determine function script, or classdef file status here. * parse.in.yy (INPUT_FILE): New token. (SCRIPT_FILE, FUNCTION_FILE): Delete. * lex.ll (octave_lexer::display_token): Update. * parse.in.yy (nl, opt_nl): New non-terminals. (function_file): Delete rule. (file): Rename from script_file. Allow opt_nl before opt_list. Don't make script if reading fcn file. * parse.in.yy (text_getc, class stdio_stream_reader, skip_white_space, looking_at_classdef_keyword, gobble_leading_white_space, looking_at_function_keyword): Delete. (get_help_from_file): Parse file to get help instead of calling gobble_leading_white_space
author John W. Eaton <jwe@octave.org>
date Wed, 06 Mar 2013 14:36:19 -0500
parents 810a71122c25
children a8f9eb92fa6e 0467d68ca891
line wrap: on
line diff
--- a/libinterp/parse-tree/lex.ll	Wed Mar 06 11:29:44 2013 -0800
+++ b/libinterp/parse-tree/lex.ll	Wed Mar 06 14:36:19 2013 -0500
@@ -46,8 +46,7 @@
 %s COMMAND_START
 %s MATRIX_START
 
-%x SCRIPT_FILE_BEGIN
-%x FUNCTION_FILE_BEGIN
+%x INPUT_FILE_BEGIN
 
 %{
 
@@ -147,7 +146,11 @@
 #define COUNT_TOK_AND_RETURN(tok) \
   do \
     { \
-      Vtoken_count++; \
+      if (tok != '\n') \
+        { \
+          Vtoken_count++; \
+          curr_lexer->token_count++; \
+        } \
       DISPLAY_TOK_AND_RETURN (tok); \
     } \
   while (0)
@@ -256,20 +259,17 @@
 // the parser go down a special path.
 %}
 
-<SCRIPT_FILE_BEGIN>. {
-    LEXER_DEBUG ("<SCRIPT_FILE_BEGIN>.");
+<INPUT_FILE_BEGIN>. {
+    LEXER_DEBUG ("<INPUT_FILE_BEGIN>.");
 
     BEGIN (INITIAL);
     curr_lexer->xunput (yytext[0]);
-    COUNT_TOK_AND_RETURN (SCRIPT_FILE);
-  }
-
-<FUNCTION_FILE_BEGIN>. {
-    LEXER_DEBUG ("<FUNCTION_FILE_BEGIN>.");
-
-    BEGIN (INITIAL);
-    curr_lexer->xunput (yytext[0]);
-    COUNT_TOK_AND_RETURN (FUNCTION_FILE);
+
+    // May be reset later if we see "function" or "classdef" appears
+    // as the first token.
+    curr_lexer->reading_script_file = true;
+
+    DISPLAY_TOK_AND_RETURN (INPUT_FILE);
   }
 
 %{
@@ -1324,6 +1324,7 @@
   maybe_classdef_get_set_method = false;
   parsing_classdef = false;
   quote_is_transpose = false;
+  force_script = false;
   reading_fcn_file = false;
   reading_script_file = false;
   reading_classdef_file = false;
@@ -1335,7 +1336,10 @@
   defining_func = 0;
   looking_at_function_handle = 0;
   block_comment_nesting_level = 0;
-
+  token_count = 0;
+  help_text = "";
+  fcn_file_name = "";
+  fcn_file_full_name = "";
   looking_at_object_index.clear ();
   looking_at_object_index.push_front (false);
 
@@ -1451,31 +1455,20 @@
       && ! (reading_fcn_file
             || reading_classdef_file
             || reading_script_file
-            || input_from_eval_string ()
-            || input_from_startup_file))
+            || input_from_eval_string ()))
     yyrestart (stdin, scanner);
 
-  // Clear the buffer for help text.
-  while (! help_buf.empty ())
-    help_buf.pop ();
-
   lexical_feedback::reset ();
 }
 
 void
-octave_lexer::prep_for_script_file (void)
+octave_lexer::prep_for_file (void)
 {
   OCTAVE_YYG;
 
-  BEGIN (SCRIPT_FILE_BEGIN);
-}
-
-void
-octave_lexer::prep_for_function_file (void)
-{
-  OCTAVE_YYG;
-
-  BEGIN (FUNCTION_FILE_BEGIN);
+  reading_script_file = true;
+
+  BEGIN (INPUT_FILE_BEGIN);
 }
 
 int
@@ -1517,9 +1510,9 @@
       warning ("block comment open at end of input");
 
       if ((reading_fcn_file || reading_script_file || reading_classdef_file)
-          && ! curr_fcn_file_name.empty ())
+          && ! fcn_file_name.empty ())
         warning ("near line %d of file '%s.m'",
-                 input_line_number, curr_fcn_file_name.c_str ());
+                 input_line_number, fcn_file_name.c_str ());
     }
 
   TOK_RETURN (END_OF_INPUT);
@@ -1691,11 +1684,11 @@
         case static_kw:
           if ((reading_fcn_file || reading_script_file
                || reading_classdef_file)
-              && ! curr_fcn_file_full_name.empty ())
+              && ! fcn_file_full_name.empty ())
             warning_with_id ("Octave:deprecated-keyword",
                              "the 'static' keyword is obsolete and will be removed from a future version of Octave; please use 'persistent' instead; near line %d of file '%s'",
                              input_line_number,
-                             curr_fcn_file_full_name.c_str ());
+                             fcn_file_full_name.c_str ());
           else
             warning_with_id ("Octave:deprecated-keyword",
                              "the 'static' keyword is obsolete and will be removed from a future version of Octave; please use 'persistent' instead; near line %d",
@@ -1834,6 +1827,12 @@
         case classdef_kw:
           // 'classdef' is always a keyword.
           promptflag--;
+
+          if (! force_script && token_count == 0 && input_from_file ())
+            {
+              reading_classdef_file = true;
+              reading_script_file = false;
+            }
           break;
 
         case function_kw:
@@ -1842,6 +1841,12 @@
           defining_func++;
           parsed_function_name.push (false);
 
+          if (! force_script && token_count == 0 && input_from_file ())
+            {
+              reading_fcn_file = true;
+              reading_script_file = false;
+            }
+
           if (! (reading_fcn_file || reading_script_file
                  || reading_classdef_file))
             input_line_number = 1;
@@ -1851,8 +1856,8 @@
           {
             if ((reading_fcn_file || reading_script_file
                  || reading_classdef_file)
-                && ! curr_fcn_file_full_name.empty ())
-              tok_val = new token (curr_fcn_file_full_name, l, c);
+                && ! fcn_file_full_name.empty ())
+              tok_val = new token (fcn_file_full_name, l, c);
             else
               tok_val = new token ("stdin", l, c);
           }
@@ -2131,6 +2136,21 @@
   return buf;
 }
 
+static bool
+looks_like_copyright (const std::string& s)
+{
+  bool retval = false;
+
+  if (! s.empty ())
+    {
+      size_t offset = s.find_first_not_of (" \t");
+
+      retval = (s.substr (offset, 9) == "Copyright" || s.substr (offset, 6) == "Author");
+    }
+
+  return retval;
+}
+
 int
 octave_lexer::process_comment (bool start_in_block, bool& eof)
 {
@@ -2138,11 +2158,6 @@
 
   eof = false;
 
-  std::string help_txt;
-
-  if (! help_buf.empty ())
-    help_txt = help_buf.top ();
-
   char *yytxt = flex_yytext ();
   flex_stream_reader flex_reader (this, yytxt);
 
@@ -2156,13 +2171,9 @@
   if (lexer_debug_flag)
     std::cerr << "C: " << txt << std::endl;
 
-  if (help_txt.empty () && nesting_level.none ())
-    {
-      if (! help_buf.empty ())
-        help_buf.pop ();
-
-      help_buf.push (txt);
-    }
+  if (nesting_level.none () && help_text.empty () && ! txt.empty ()
+      && ! looks_like_copyright (txt))
+    help_text = txt;
 
   octave_comment_buffer::append (txt);
 
@@ -3513,7 +3524,7 @@
 void
 octave_lexer::maybe_warn_separator_insert (char sep)
 {
-  std::string nm = curr_fcn_file_full_name;
+  std::string nm = fcn_file_full_name;
 
   if (nm.empty ())
     warning_with_id ("Octave:separator-insert",
@@ -3528,7 +3539,7 @@
 void
 octave_lexer::gripe_single_quote_string (void)
 {
-  std::string nm = curr_fcn_file_full_name;
+  std::string nm = fcn_file_full_name;
 
   if (nm.empty ())
     warning_with_id ("Octave:single-quote-string",
@@ -3543,7 +3554,7 @@
 void
 octave_lexer::gripe_matlab_incompatible (const std::string& msg)
 {
-  std::string nm = curr_fcn_file_full_name;
+  std::string nm = fcn_file_full_name;
 
   if (nm.empty ())
     warning_with_id ("Octave:matlab-incompatible",
@@ -3707,8 +3718,7 @@
     case LEXICAL_ERROR: std::cerr << "LEXICAL_ERROR\n\n"; break;
     case FCN: std::cerr << "FCN\n"; break;
     case CLOSE_BRACE: std::cerr << "CLOSE_BRACE\n"; break;
-    case SCRIPT_FILE: std::cerr << "SCRIPT_FILE\n"; break;
-    case FUNCTION_FILE: std::cerr << "FUNCTION_FILE\n"; break;
+    case INPUT_FILE: std::cerr << "INPUT_FILE\n"; break;
     case SUPERCLASSREF: std::cerr << "SUPERCLASSREF\n"; break;
     case METAQUERY: std::cerr << "METAQUERY\n"; break;
     case GET: std::cerr << "GET\n"; break;
@@ -3750,12 +3760,8 @@
       std::cerr << "MATRIX_START" << std::endl;
       break;
 
-    case SCRIPT_FILE_BEGIN:
-      std::cerr << "SCRIPT_FILE_BEGIN" << std::endl;
-      break;
-
-    case FUNCTION_FILE_BEGIN:
-      std::cerr << "FUNCTION_FILE_BEGIN" << std::endl;
+    case INPUT_FILE_BEGIN:
+      std::cerr << "INPUT_FILE_BEGIN" << std::endl;
       break;
 
     default: