Mercurial > hg > octave-avbm
changeset 16320:09f0cb9cac7d
don't modify symbol table scope in the parser
* symtab.h (symbol_table::insert): Accept scope as argument.
* lex.h (symbol_table_context): New class.
(octave_lexer::symtab_context: New data member.
* parse-private.h: Delete.
* parse.h, oct-parse.in.yy (parser_symtab_context): Delete global
variable and all uses.
* lex.ll (octave_lexer::reset): Clear symtab_context.
(octave_base_lexer::handle_superclass_identifier,
octave_base_lexer::handle_meta_identifier,
octave_base_lexer::handle_identifier): Get current symbol table scope
for parsing from symtab_context. Use it to insert new variables in
the symbol table.
* oct-parse.in.yy (ABORT_PARSE): Don't pop symtab_context.
(push_fcn_symtab, param_list_beg): Push newly allocated scope on the
symtab_context stack. Don't modify symbol table scope.
(make_anon_fcn_handle): Get function scope from symtab_context instead
of the symbol table. Pop symtab_context.
(start_function): Get function scope from symtab_context instead
of the symbol table.
(octave_base_parser::recover_from_parsing_function):
Pop symtab_context.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Sat, 16 Mar 2013 02:02:43 -0400 |
parents | 54c4b4b58a24 |
children | 7612d75a559b |
files | libinterp/interpfcn/symtab.h libinterp/parse-tree/lex.h libinterp/parse-tree/lex.ll libinterp/parse-tree/oct-parse.in.yy libinterp/parse-tree/parse-private.h |
diffstat | 5 files changed, 90 insertions(+), 133 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/interpfcn/symtab.h +++ b/libinterp/interpfcn/symtab.h @@ -1171,11 +1171,12 @@ static octave_value builtin_find (const std::string& name); // Insert a new name in the table. - static symbol_record& insert (const std::string& name) + static symbol_record& insert (const std::string& name, + scope_id scope = xcurrent_scope) { static symbol_record foobar; - symbol_table *inst = get_instance (xcurrent_scope); + symbol_table *inst = get_instance (scope); return inst ? inst->do_insert (name) : foobar; }
--- a/libinterp/parse-tree/lex.h +++ b/libinterp/parse-tree/lex.h @@ -43,6 +43,55 @@ { public: + // Track symbol table information when parsing functions. + + class symbol_table_context + { + public: + + symbol_table_context (void) + : frame_stack (), init_scope (symbol_table::current_scope ()) + { + push (init_scope); + } + + void clear (void) + { + while (! frame_stack.empty ()) + frame_stack.pop (); + + push (init_scope); + } + + bool empty (void) const { return frame_stack.empty (); } + + void pop (void) + { + frame_stack.pop (); + } + + void push (symbol_table::scope_id scope) + { + frame_stack.push (scope); + } + + void push (void) + { + push (symbol_table::current_scope ()); + } + + symbol_table::scope_id curr_scope (void) const + { + return frame_stack.top (); + } + + private: + + std::stack<symbol_table::scope_id> frame_stack; + + symbol_table::scope_id init_scope; + }; + // Track nesting of square brackets, curly braces, and parentheses. class bbp_nesting_level @@ -233,7 +282,7 @@ current_input_line (), comment_text (), help_text (), fcn_file_name (), fcn_file_full_name (), looking_at_object_index (), parsed_function_name (), pending_local_variables (), - nesting_level (), tokens () + symtab_context (), nesting_level (), tokens () { init (); } @@ -375,6 +424,9 @@ // set of identifiers that might be local variable names. std::set<std::string> pending_local_variables; + // Track current symbol table scope and context. + symbol_table_context symtab_context; + // is the closest nesting level a square bracket, squiggly brace, // a paren, or an anonymous function body? bbp_nesting_level nesting_level;
--- a/libinterp/parse-tree/lex.ll +++ b/libinterp/parse-tree/lex.ll @@ -84,7 +84,6 @@ #include "lex.h" #include "ov.h" #include "parse.h" -#include "parse-private.h" #include "pt-all.h" #include "symtab.h" #include "token.h" @@ -1622,7 +1621,7 @@ // Start off on the right foot. clear_start_state (); - parser_symtab_context.clear (); + symtab_context.clear (); // We do want a prompt by default. promptflag (1); @@ -2403,11 +2402,14 @@ return LEXICAL_ERROR; } - push_token (new token (SUPERCLASSREF, - meth.empty () ? 0 : &(symbol_table::insert (meth)), - cls.empty () ? 0 : &(symbol_table::insert (cls)), - pkg.empty () ? 0 : &(symbol_table::insert (pkg)), - input_line_number, current_input_column)); + symbol_table::scope_id sid = symtab_context.curr_scope (); + + push_token (new token + (SUPERCLASSREF, + meth.empty () ? 0 : &(symbol_table::insert (meth, sid)), + cls.empty () ? 0 : &(symbol_table::insert (cls, sid)), + pkg.empty () ? 0 : &(symbol_table::insert (pkg, sid)), + input_line_number, current_input_column)); current_input_column += flex_yyleng (); @@ -2435,10 +2437,13 @@ return LEXICAL_ERROR; } - push_token (new token (METAQUERY, - cls.empty () ? 0 : &(symbol_table::insert (cls)), - pkg.empty () ? 0 : &(symbol_table::insert (pkg)), - input_line_number, current_input_column)); + symbol_table::scope_id sid = symtab_context.curr_scope (); + + push_token (new token + (METAQUERY, + cls.empty () ? 0 : &(symbol_table::insert (cls, sid)), + pkg.empty () ? 0 : &(symbol_table::insert (pkg, sid)), + input_line_number, current_input_column)); current_input_column += flex_yyleng (); @@ -2527,7 +2532,9 @@ if (tok == "end") tok = "__end__"; - token *tok_val = new token (NAME, &(symbol_table::insert (tok)), + symbol_table::scope_id sid = symtab_context.curr_scope (); + + token *tok_val = new token (NAME, &(symbol_table::insert (tok, sid)), input_line_number, current_input_column); if (at_beginning_of_statement
--- a/libinterp/parse-tree/oct-parse.in.yy +++ b/libinterp/parse-tree/oct-parse.in.yy @@ -68,7 +68,6 @@ #include "toplev.h" #include "pager.h" #include "parse.h" -#include "parse-private.h" #include "pt-all.h" #include "pt-eval.h" #include "symtab.h" @@ -98,9 +97,6 @@ // TRUE means we printed messages about reading startup files. bool reading_startup_message_printed = false; -// Keep track of symbol table information when parsing functions. -symtab_context parser_symtab_context; - // List of autoloads (function -> file mapping). static std::map<std::string, std::string> autoload_map; @@ -123,9 +119,7 @@ do \ { \ yyerrok; \ - if (! parser_symtab_context.empty ()) \ - parser_symtab_context.pop (); \ - if ((interactive || forced_interactive) \ + if ((interactive || forced_interactive) \ && ! lexer.input_from_eval_string ()) \ YYACCEPT; \ else \ @@ -1000,16 +994,16 @@ if (parser.max_fcn_depth < parser.curr_fcn_depth) parser.max_fcn_depth = parser.curr_fcn_depth; - parser_symtab_context.push (); - - symbol_table::set_scope (symbol_table::alloc_scope ()); - - parser.function_scopes.push_back (symbol_table::current_scope ()); + lexer.symtab_context.push (symbol_table::alloc_scope ()); + + parser.function_scopes.push_back + (lexer.symtab_context.curr_scope ()); if (! lexer.reading_script_file && parser.curr_fcn_depth == 1 && ! parser.parsing_subfunctions) - parser.primary_fcn_scope = symbol_table::current_scope (); + parser.primary_fcn_scope + = lexer.symtab_context.curr_scope (); if (lexer.reading_script_file && parser.curr_fcn_depth > 1) @@ -1027,8 +1021,7 @@ if (lexer.looking_at_function_handle) { - parser_symtab_context.push (); - symbol_table::set_scope (symbol_table::alloc_scope ()); + lexer.symtab_context.push (symbol_table::alloc_scope ()); lexer.looking_at_function_handle--; lexer.looking_at_anon_fcn_args = true; } @@ -1892,12 +1885,12 @@ tree_parameter_list *ret_list = 0; - symbol_table::scope_id fcn_scope = symbol_table::current_scope (); - - if (parser_symtab_context.empty ()) + symbol_table::scope_id fcn_scope = lexer.symtab_context.curr_scope (); + + if (lexer.symtab_context.empty ()) panic_impossible (); - parser_symtab_context.pop (); + lexer.symtab_context.pop (); stmt->set_print_flag (false); @@ -2579,7 +2572,7 @@ body->append (end_fcn_stmt); octave_user_function *fcn - = new octave_user_function (symbol_table::current_scope (), + = new octave_user_function (lexer.symtab_context.curr_scope (), param_list, 0, body); if (fcn) @@ -2770,10 +2763,10 @@ void octave_base_parser::recover_from_parsing_function (void) { - if (parser_symtab_context.empty ()) + if (lexer.symtab_context.empty ()) panic_impossible (); - parser_symtab_context.pop (); + lexer.symtab_context.pop (); if (lexer.reading_fcn_file && curr_fcn_depth == 1 && ! parsing_subfunctions)
deleted file mode 100644 --- a/libinterp/parse-tree/parse-private.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - -Copyright (C) 2012 John W. Eaton - -This file is part of Octave. - -Octave is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3 of the License, or (at your -option) any later version. - -Octave is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Octave; see the file COPYING. If not, see -<http://www.gnu.org/licenses/>. - -*/ - -#if !defined (octave_parse_private_h) -#define octave_parse_private_h 1 - -#include <stack> - -#include "symtab.h" - -// Keep track of symbol table information when parsing functions. -class symtab_context -{ -private: - - class frame - { - public: - frame (symbol_table::scope_id s, symbol_table::scope_id c) - : m_scope (s), m_context (c) { } - - frame (const frame& f) : m_scope (f.m_scope), m_context (f.m_context) { } - - frame& operator = (const frame& f) - { - if (&f != this) - { - m_scope = f.m_scope; - m_context = f.m_context; - } - - return *this; - } - - ~frame (void) { } - - symbol_table::scope_id scope (void) const { return m_scope; } - symbol_table::scope_id context (void) const { return m_context; } - - private: - - symbol_table::scope_id m_scope; - symbol_table::scope_id m_context; - }; - - std::stack<frame> frame_stack; - -public: - symtab_context (void) : frame_stack () { } - - void clear (void) - { - while (! frame_stack.empty ()) - frame_stack.pop (); - } - - bool empty (void) const { return frame_stack.empty (); } - - void pop (void) - { - frame tmp = frame_stack.top (); - - symbol_table::set_scope_and_context (tmp.scope (), tmp.context ()); - - frame_stack.pop (); - } - - void push (void) - { - frame_stack.push (frame (symbol_table::current_scope (), - symbol_table::current_context ())); - } -}; - -extern symtab_context parser_symtab_context; - -#endif