Mercurial > octave
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; } }