Mercurial > octave
changeset 27736:bd80e14f268a
improve parse error message for @()x+=expr (bug #57255)
* oct-parse.yy (anon_fcn_begin): New utility non-terminal to set both
m_parsing_anon_fcn and m_at_beginning_of_statement lexer feedback
flags.
(anon_fcn_handle): Use it instead of stmt_begin. Reset
m_parsing_anon_fcn after parsing expression.
* lex.h (lexical_feedback::m_parsing_anon_fcn): New flag.
(lexical_feedback::lexical_feedback: Initialize it.
(lexical_feedback::reset): Reset it.
(base_lexer::handle_identifier): Don't recognize identifier as a
command when parsing anonymous function body.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 22 Nov 2019 12:18:21 -0600 |
parents | 8600f5ea1ec1 |
children | 527e25f7ee38 |
files | libinterp/parse-tree/lex.h libinterp/parse-tree/lex.ll libinterp/parse-tree/oct-parse.yy |
diffstat | 3 files changed, 32 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/parse-tree/lex.h Thu Nov 21 19:23:20 2019 -0600 +++ b/libinterp/parse-tree/lex.h Fri Nov 22 12:18:21 2019 -0600 @@ -272,6 +272,7 @@ m_looking_at_matrix_or_assign_lhs (false), m_looking_for_object_index (false), m_looking_at_indirect_ref (false), + m_parsing_anon_fcn_body (false), m_parsing_class_method (false), m_parsing_classdef (false), m_parsing_classdef_decl (false), @@ -387,6 +388,9 @@ // structure element. bool m_looking_at_indirect_ref; + // true means we are parsing the body of an anonymous function. + bool m_parsing_anon_fcn_body; + // true means we are parsing a class method in function or classdef file. bool m_parsing_class_method;
--- a/libinterp/parse-tree/lex.ll Thu Nov 21 19:23:20 2019 -0600 +++ b/libinterp/parse-tree/lex.ll Fri Nov 22 12:18:21 2019 -0600 @@ -2156,6 +2156,7 @@ m_looking_at_matrix_or_assign_lhs = false; m_looking_for_object_index = false; m_looking_at_indirect_ref = false; + m_parsing_anon_fcn_body = false; m_parsing_class_method = false; m_parsing_classdef = false; m_parsing_classdef_decl = false; @@ -3170,12 +3171,13 @@ // function call with the argument "+1". if (m_at_beginning_of_statement - && (! (is_variable (ident, scope) - || ident == "e" || ident == "pi" - || ident == "I" || ident == "i" - || ident == "J" || ident == "j" - || ident == "Inf" || ident == "inf" - || ident == "NaN" || ident == "nan"))) + && ! (m_parsing_anon_fcn_body + || is_variable (ident, scope) + || ident == "e" || ident == "pi" + || ident == "I" || ident == "i" + || ident == "J" || ident == "j" + || ident == "Inf" || ident == "inf" + || ident == "NaN" || ident == "nan")) tok->mark_may_be_command (); push_token (tok);
--- a/libinterp/parse-tree/oct-parse.yy Thu Nov 21 19:23:20 2019 -0600 +++ b/libinterp/parse-tree/oct-parse.yy Fri Nov 22 12:18:21 2019 -0600 @@ -229,8 +229,8 @@ // Nonterminals we construct. %type <dummy_type> indirect_ref_op decl_param_init %type <dummy_type> push_fcn_symtab push_script_symtab begin_file -%type <dummy_type> param_list_beg param_list_end stmt_begin parse_error -%type <dummy_type> parsing_local_fcns +%type <dummy_type> param_list_beg param_list_end stmt_begin anon_fcn_begin +%type <dummy_type> parsing_local_fcns parse_error %type <comment_type> stash_comment %type <tok_val> function_beg classdef_beg %type <punct_type> sep_no_nl opt_sep_no_nl nl opt_nl sep opt_sep @@ -604,7 +604,11 @@ { $$ = parser.make_fcn_handle ($1); } ; -anon_fcn_handle : '@' param_list stmt_begin expression +// Note that we are deliberately not setting the beginning of statement +// flag after recognizing the parameter list because we don't want to +// accept word list commands in anonymous function bodies. + +anon_fcn_handle : '@' param_list anon_fcn_begin expression { $$ = parser.make_anon_fcn_handle ($2, $4); if (! $$) @@ -612,12 +616,16 @@ // make_anon_fcn_handle deleted $2 and $4. YYABORT; } + + lexer.m_parsing_anon_fcn_body = false; lexer.m_nesting_level.remove (); } - | '@' param_list stmt_begin error + | '@' param_list anon_fcn_begin error { YYUSE ($2); + lexer.m_parsing_anon_fcn_body = false; + $$ = nullptr; parser.bison_error ("anonymous function bodies must be single expressions"); YYABORT; @@ -1975,6 +1983,14 @@ } ; +anon_fcn_begin : // empty + { + $$ = 0; + lexer.m_at_beginning_of_statement = true; + lexer.m_parsing_anon_fcn_body = true; + } + ; + stash_comment : // empty { $$ = lexer.get_comment (); } ;