changeset 27510:5438a82a18fb

declare base_parser class data protected * parse.h, oct-parse.yy (class base_parser): Declare member data protected. (base_parser::maybe_warn_assign_as_truth_value, base_parser::maybe_warn_variable_switch_label, base_parser::maybe_warn_missing_semi): Now private. (base_parser::get_lexer, base_parser::at_end_of_input, base_parser::parsing_local_functions, base_parser::endfunction_found, base_parser::push_fcn_symtab, base_parser::make_fcn_name, base_parser::make_function): New functions. Use them in parser actions to avoid direct access to base_parser member data. * pt-eval.cc (tree_evaluator::repl, tree_evaluator::eval_string): Use function to access lexer state.
author John W. Eaton <jwe@octave.org>
date Fri, 11 Oct 2019 11:17:02 -0400
parents fefc780b4e2e
children 257105b5193a
files libinterp/parse-tree/oct-parse.yy libinterp/parse-tree/parse.h libinterp/parse-tree/pt-eval.cc
diffstat 3 files changed, 159 insertions(+), 110 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/oct-parse.yy	Fri Oct 11 09:36:08 2019 -0400
+++ b/libinterp/parse-tree/oct-parse.yy	Fri Oct 11 11:17:02 2019 -0400
@@ -89,7 +89,7 @@
 
 static void yyerror (octave::base_parser& parser, const char *s);
 
-#define lexer parser.m_lexer
+#define lexer (parser.get_lexer ())
 #define scanner lexer.m_scanner
 
 #if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC)
@@ -1280,29 +1280,10 @@
 
 push_fcn_symtab : // empty
                   {
+                    if (! parser.push_fcn_symtab ())
+                      YYABORT;
+
                     $$ = 0;
-
-                    parser.m_curr_fcn_depth++;
-
-                    if (parser.m_max_fcn_depth < parser.m_curr_fcn_depth)
-                      parser.m_max_fcn_depth = parser.m_curr_fcn_depth;
-
-                    // Will get a real name later.
-                    lexer.m_symtab_context.push (octave::symbol_scope ("parser:push_fcn_symtab"));
-                    parser.m_function_scopes.push (lexer.m_symtab_context.curr_scope ());
-
-                    if (! lexer.m_reading_script_file
-                        && parser.m_curr_fcn_depth == 0
-                        && ! parser.m_parsing_subfunctions)
-                      parser.m_primary_fcn_scope
-                        = lexer.m_symtab_context.curr_scope ();
-
-                    if (lexer.m_reading_script_file
-                        && parser.m_curr_fcn_depth > 0)
-                      {
-                        parser.bison_error ("nested functions not implemented in this context");
-                        YYABORT;
-                      }
                   }
                 ;
 
@@ -1448,7 +1429,7 @@
 
 parsing_local_fcns
                 : // empty
-                  { parser.m_parsing_local_functions = true; }
+                  { parser.parsing_local_functions (true); }
                 ;
 
 push_script_symtab : // empty
@@ -1523,33 +1504,12 @@
 
 fcn_name        : identifier
                   {
-                    std::string id = $1->name ();
-
-                    // Make classdef local functions unique from
-                    // classdef methods.
-
-                    if (parser.m_parsing_local_functions
-                        && parser.m_curr_fcn_depth == 0)
-                      id = lexer.m_fcn_file_name + ">" + id;
-
-                    if (! parser.m_function_scopes.name_current_scope (id))
+                    $$ = parser.make_fcn_name ($1);
+                    if (! $$)
                       {
-                        parser.bison_error ("duplicate subfunction or nested function name",
-                                            $1->line (), $1->column ());
-
-                        delete $1;
-
+                        // make_fcn_name deleted $1.
                         YYABORT;
                       }
-
-                    octave::symbol_scope curr_scope
-                      = lexer.m_symtab_context.curr_scope ();
-                    curr_scope.cache_name (id);
-
-                    lexer.m_parsed_function_name.top () = true;
-                    lexer.m_maybe_classdef_get_set_method = false;
-
-                    $$ = $1;
                   }
                 | GET '.' identifier
                   {
@@ -1573,7 +1533,7 @@
 
 function_end    : END
                   {
-                    parser.m_endfunction_found = true;
+                    parser.endfunction_found (true);
 
                     if (parser.end_token_ok ($1, octave::token::function_end))
                       $$ = parser.make_end ("endfunction", false,
@@ -1593,7 +1553,7 @@
 //                      YYABORT;
 //                    }
 
-                    if (parser.m_endfunction_found)
+                    if (parser.endfunction_found ())
                       {
                         parser.bison_error ("inconsistent function endings -- "
                                  "if one function is explicitly ended, "
@@ -2321,43 +2281,30 @@
     return ettype == expected || ettype == token::simple_end;
   }
 
-  // Maybe print a warning if an assignment expression is used as the
-  // test in a logical expression.
-
-  void
-  base_parser::maybe_warn_assign_as_truth_value (tree_expression *expr)
+  bool
+  base_parser::push_fcn_symtab (void)
   {
-    if (expr->is_assignment_expression ()
-        && expr->paren_count () < 2)
+    m_curr_fcn_depth++;
+
+    if (m_max_fcn_depth < m_curr_fcn_depth)
+      m_max_fcn_depth = m_curr_fcn_depth;
+
+    // Will get a real name later.
+    m_lexer.m_symtab_context.push (octave::symbol_scope ("parser:push_fcn_symtab"));
+    m_function_scopes.push (m_lexer.m_symtab_context.curr_scope ());
+
+    if (! m_lexer.m_reading_script_file && m_curr_fcn_depth == 0
+        && ! m_parsing_subfunctions)
+      m_primary_fcn_scope = m_lexer.m_symtab_context.curr_scope ();
+
+    if (m_lexer.m_reading_script_file && m_curr_fcn_depth > 0)
       {
-        if (m_lexer.m_fcn_file_full_name.empty ())
-          warning_with_id
-            ("Octave:assign-as-truth-value",
-             "suggest parenthesis around assignment used as truth value");
-        else
-          warning_with_id
-            ("Octave:assign-as-truth-value",
-             "suggest parenthesis around assignment used as truth value near line %d, column %d in file '%s'",
-             expr->line (), expr->column (), m_lexer.m_fcn_file_full_name.c_str ());
+        bison_error ("nested functions not implemented in this context");
+
+        return false;
       }
-  }
-
-  // Maybe print a warning about switch labels that aren't constants.
-
-  void
-  base_parser::maybe_warn_variable_switch_label (tree_expression *expr)
-  {
-    if (! expr->is_constant ())
-      {
-        if (m_lexer.m_fcn_file_full_name.empty ())
-          warning_with_id ("Octave:variable-switch-label",
-                           "variable switch label");
-        else
-          warning_with_id
-            ("Octave:variable-switch-label",
-             "variable switch label near line %d, column %d in file '%s'",
-             expr->line (), expr->column (), m_lexer.m_fcn_file_full_name.c_str ());
-      }
+
+    return true;
   }
 
   // Make a constant.
@@ -3291,6 +3238,34 @@
     m_primary_fcn = octave_value (script);
   }
 
+  tree_identifier *
+  base_parser::make_fcn_name (tree_identifier *id)
+  {
+    std::string id_name = id->name ();
+
+    // Make classdef local functions unique from classdef methods.
+
+    if (m_parsing_local_functions && m_curr_fcn_depth == 0)
+      id_name = m_lexer.m_fcn_file_name + ">" + id_name;
+
+    if (! m_function_scopes.name_current_scope (id_name))
+      {
+        bison_error ("duplicate subfunction or nested function name",
+                     id->line (), id->column ());
+
+        delete id;
+        return nullptr;
+      }
+
+    octave::symbol_scope curr_scope = m_lexer.m_symtab_context.curr_scope ();
+    curr_scope.cache_name (id_name);
+
+    m_lexer.m_parsed_function_name.top () = true;
+    m_lexer.m_maybe_classdef_get_set_method = false;
+
+    return id;
+  }
+
   // Define a function.
 
   // FIXME: combining start_function, finish_function, and
@@ -4222,21 +4197,6 @@
             : new tree_constant (octave_value (Cell ())));
   }
 
-  void
-  base_parser::maybe_warn_missing_semi (tree_statement_list *t)
-  {
-    if (m_curr_fcn_depth >= 0)
-      {
-        tree_statement *tmp = t->back ();
-
-        if (tmp->is_expression ())
-          warning_with_id
-            ("Octave:missing-semicolon",
-             "missing semicolon near line %d, column %d in file '%s'",
-             tmp->line (), tmp->column (), m_lexer.m_fcn_file_full_name.c_str ());
-      }
-  }
-
   tree_statement_list *
   base_parser::set_stmt_print_flag (tree_statement_list *list,
                                     char sep, bool warn_missing_semi)
@@ -4593,6 +4553,60 @@
     return octave_value ();
   }
 
+  // Maybe print a warning if an assignment expression is used as the
+  // test in a logical expression.
+
+  void
+  base_parser::maybe_warn_assign_as_truth_value (tree_expression *expr)
+  {
+    if (expr->is_assignment_expression ()
+        && expr->paren_count () < 2)
+      {
+        if (m_lexer.m_fcn_file_full_name.empty ())
+          warning_with_id
+            ("Octave:assign-as-truth-value",
+             "suggest parenthesis around assignment used as truth value");
+        else
+          warning_with_id
+            ("Octave:assign-as-truth-value",
+             "suggest parenthesis around assignment used as truth value near line %d, column %d in file '%s'",
+             expr->line (), expr->column (), m_lexer.m_fcn_file_full_name.c_str ());
+      }
+  }
+
+  // Maybe print a warning about switch labels that aren't constants.
+
+  void
+  base_parser::maybe_warn_variable_switch_label (tree_expression *expr)
+  {
+    if (! expr->is_constant ())
+      {
+        if (m_lexer.m_fcn_file_full_name.empty ())
+          warning_with_id ("Octave:variable-switch-label",
+                           "variable switch label");
+        else
+          warning_with_id
+            ("Octave:variable-switch-label",
+             "variable switch label near line %d, column %d in file '%s'",
+             expr->line (), expr->column (), m_lexer.m_fcn_file_full_name.c_str ());
+      }
+  }
+
+  void
+  base_parser::maybe_warn_missing_semi (tree_statement_list *t)
+  {
+    if (m_curr_fcn_depth >= 0)
+      {
+        tree_statement *tmp = t->back ();
+
+        if (tmp->is_expression ())
+          warning_with_id
+            ("Octave:missing-semicolon",
+             "missing semicolon near line %d, column %d in file '%s'",
+             tmp->line (), tmp->column (), m_lexer.m_fcn_file_full_name.c_str ());
+      }
+  }
+
   std::string
   get_help_from_file (const std::string& nm, bool& symbol_found,
                       std::string& full_file)
--- a/libinterp/parse-tree/parse.h	Fri Oct 11 09:36:08 2019 -0400
+++ b/libinterp/parse-tree/parse.h	Fri Oct 11 11:17:02 2019 -0400
@@ -152,6 +152,10 @@
 
     ~base_parser (void);
 
+    base_lexer& get_lexer (void) const { return m_lexer; }
+
+    bool at_end_of_input (void) const { return m_lexer.m_end_of_input; }
+
     void reset (void);
 
     void classdef_object (const std::shared_ptr<tree_classdef>& obj)
@@ -174,18 +178,34 @@
       return m_stmt_list;
     }
 
+    void parsing_local_functions (bool flag)
+    {
+      m_parsing_local_functions = flag;
+    }
+
+    bool parsing_local_functions (void) const
+    {
+      return m_parsing_local_functions;
+    }
+
+    void endfunction_found (bool flag)
+    {
+      m_endfunction_found = flag;
+    }
+
+    bool endfunction_found (void) const
+    {
+      return m_endfunction_found;
+    }
+
     // Error mesages for mismatched end tokens.
     void end_token_error (token *tok, token::end_tok_type expected);
 
     // Check to see that end tokens are properly matched.
     bool end_token_ok (token *tok, token::end_tok_type expected);
 
-    // Maybe print a warning if an assignment expression is used as the
-    // test in a logical expression.
-    void maybe_warn_assign_as_truth_value (tree_expression *expr);
-
-    // Maybe print a warning about switch labels that aren't constants.
-    void maybe_warn_variable_switch_label (tree_expression *expr);
+    // Handle pushing symbol table for new function scope.
+    bool push_fcn_symtab (void);
 
     // Build a constant.
     tree_constant * make_constant (int op, token *tok_val);
@@ -294,6 +314,10 @@
     // Define a script.
     void make_script (tree_statement_list *cmds, tree_statement *end_script);
 
+    // Handle identifier that is recognized as a function name.
+    tree_identifier *
+    make_fcn_name (tree_identifier *id);
+
     // Define a function.
     tree_function_def *
     make_function (token *fcn_tok, tree_parameter_list *ret_list,
@@ -402,9 +426,6 @@
     // Finish building a cell list.
     tree_expression * finish_cell (tree_cell *c);
 
-    // Maybe print a warning.  Duh.
-    void maybe_warn_missing_semi (tree_statement_list *);
-
     // Set the print flag for a statement based on the separator type.
     tree_statement_list *
     set_stmt_print_flag (tree_statement_list *, char, bool);
@@ -436,6 +457,8 @@
                     const std::string& package_name, bool require_file,
                     bool force_script, bool autoload, bool relative_lookup);
 
+  protected:
+
     // Contains error message if Bison-generated parser returns non-zero
     // status.
     std::string m_parse_error_msg;
@@ -504,6 +527,18 @@
 
     // Internal state of the Bison parser.
     void *m_parser_state;
+
+  private:
+
+    // Maybe print a warning if an assignment expression is used as the
+    // test in a logical expression.
+    void maybe_warn_assign_as_truth_value (tree_expression *expr);
+
+    // Maybe print a warning about switch labels that aren't constants.
+    void maybe_warn_variable_switch_label (tree_expression *expr);
+
+    // Maybe print a warning.
+    void maybe_warn_missing_semi (tree_statement_list *);
   };
 
   // Publish externally used friend functions.
--- a/libinterp/parse-tree/pt-eval.cc	Fri Oct 11 09:36:08 2019 -0400
+++ b/libinterp/parse-tree/pt-eval.cc	Fri Oct 11 11:17:02 2019 -0400
@@ -416,7 +416,7 @@
                     if (octave_completion_matches_called)
                       octave_completion_matches_called = false;
                   }
-                else if (repl_parser.m_lexer.m_end_of_input)
+                else if (repl_parser.at_end_of_input ())
                   {
                     retval = EOF;
                     break;
@@ -588,7 +588,7 @@
                 if (returning () || breaking () || continuing ())
                   break;
               }
-            else if (eval_parser.m_lexer.m_end_of_input)
+            else if (eval_parser.at_end_of_input ())
               break;
           }
       }