Mercurial > octave
diff libinterp/parse-tree/lex.ll @ 29864:e2e493712818
improve previous change for command syntax parsing (bug #60882)
* symrec.h (symbol_record::variable): New static constant.
(symbol_record_rep::is_variable, symbol_record_rep::mark_as_variable,
symbol_record_rep::unmark_as_variable): New functions.
(symbol_record_rep::mark_formal): Also mark as variable.
(symbol_record::is_variable, symbol_record::mark_as_variable,
symbol_record::unmark_as_variable): New functions.
* symscope.h, symscope.cc (symbol_scope_rep::mark_as_variable,
symbol_scope_rep::mark_as_variables, symbol_scope_rep::is_variable,
symbol_scope::mark_as_variable, symbol_scope::mark_as_variables,
symbol_scope::is_variable): New functions.
* lex.h, lex.ll (lexical_feedback::m_pending_local_variables): Delete
member variable and all uses.
(CMD_OR_COMPUTED_ASSIGN_OP): Don't attempt Matlab compatibility for
computed assignment operators.
(lexical_feedback::mark_as_variable,
lexical_feedback::mark_as_variables, lexical_feedback::is_variable):
Store status of symbols as variables in scope objects instead of
m_pending_local_variables lists.
(base_lexer::handle_identifier): Don't check for variables when
deciding whether an identifier can be recognized as a command.
* parse.h, oct-parse.yy (parse_exception, parse_tree_validator):
New classes.
(base_parser::bison_error): New overloads that accept parse_exception
and list of parse_exception objects.
(base_parser::finish_classdef_file): Validate classdef object and
local functions and return status.
(base_parser::validate_primary_fcn, base_parser::finish_input):
New functions.
(file): Validate primary function after parser is finished reading and
parsing file.
(input): Call base_parser::finish_input to validate and accept
statement list.
* try.tst: Fix syntax in test.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 09 Jul 2021 04:05:58 -0400 |
parents | 0b01806bb663 |
children | da6e5914ddaf |
line wrap: on
line diff
--- a/libinterp/parse-tree/lex.ll Fri Jul 09 04:03:36 2021 -0400 +++ b/libinterp/parse-tree/lex.ll Fri Jul 09 04:05:58 2021 -0400 @@ -183,7 +183,19 @@ } \ while (0) -#define CMD_OR_COMPUTED_ASSIGN_OP(PATTERN, TOK) \ +#if 0 +// Use the following to handle computed assignment operators +// (+=, -=, etc.) in word list commands in a way that is compatible +// with Matlab. However, that will also make it impossible to use +// these operators with a space before them: +// +// x = 1; +// x+=2; ## ok +// x+= 2; ## ok +// x +=2; ## error: invalid use of symbol as both variable and command +// x += 2; ## error: invalid use of symbol as both variable and command +// +# define CMD_OR_COMPUTED_ASSIGN_OP(PATTERN, TOK) \ do \ { \ curr_lexer->lexer_debug (PATTERN); \ @@ -198,6 +210,10 @@ return curr_lexer->handle_op (TOK, false, false); \ } \ while (0) +#else +# define CMD_OR_COMPUTED_ASSIGN_OP(PATTERN, TOK) \ + return curr_lexer->handle_op (TOK, false, false) +#endif #define CMD_OR_UNARY_OP(PATTERN, TOK, COMPAT) \ do \ @@ -2221,12 +2237,6 @@ // The closest paren, brace, or bracket nesting is not an object // index. m_looking_at_object_index.push_front (false); - - // Provide an initial set to store variables at the top-level. - // Don't clear this one when resetting lexical_feedback state. - // It should persist since the top-level scope does. Hmm maybe - // we should just use the symbol scope object for this job? - m_pending_local_variables.push_front (std::set<std::string> ()); } void @@ -2284,9 +2294,6 @@ while (! m_parsed_function_name.empty ()) m_parsed_function_name.pop (); - while (m_pending_local_variables.size () > 1) - m_pending_local_variables.pop_front (); - m_symtab_context.clear (); m_nesting_level.reset (); m_tokens.clear (); @@ -2348,6 +2355,24 @@ return tok ? tok->iskeyword () : false; } + void + lexical_feedback::mark_as_variable (const std::string& nm) + { + symbol_scope scope = m_symtab_context.curr_scope (); + + if (scope) + scope.mark_as_variable (nm); + } + + void + lexical_feedback::mark_as_variables (const std::list<std::string>& lst) + { + symbol_scope scope = m_symtab_context.curr_scope (); + + if (scope) + scope.mark_as_variables (lst); + } + bool lexical_feedback::previous_token_may_be_command (void) const { @@ -2357,37 +2382,6 @@ const token *tok = m_tokens.front (); return tok ? tok->may_be_command () : false; } - - void - lexical_feedback::mark_as_variable (const std::string& nm) - { - auto& vars = m_pending_local_variables.front (); - vars.insert (nm); - } - - void - lexical_feedback::mark_as_variables (const std::list<std::string>& lst) - { - auto& vars = m_pending_local_variables.front (); - for (const auto& nm : lst) - vars.insert (nm); - } - - bool - lexical_feedback::is_variable (const std::string& nm) const - { - if (m_interpreter.at_top_level () && m_interpreter.is_variable (nm)) - return true; - - // Search current scope, then parents. - for (const auto& vars : m_pending_local_variables) - { - if (vars.find (nm) != vars.end ()) - return true; - } - - return false; - } } static bool @@ -3599,7 +3593,6 @@ if (m_at_beginning_of_statement && ! (m_parsing_anon_fcn_body - || is_variable (ident) || ident == "e" || ident == "pi" || ident == "I" || ident == "i" || ident == "J" || ident == "j"