comparison libinterp/parse-tree/oct-parse.in.yy @ 21369:105224df2330

also disallow assignment to keywords in assignin (bug #46459) * lex.ll (is_keyword): Don't treat "enumeration", "events", "methods", or "properties" as keywords. * oct-parse.in.yy, parse.h: New tests. (Fassignin): Check for assignments to keywords. (octave_base_parser::valid_id_for_assignment): Delete. (octave_base_parser::make_assign_op): Use is_keyword instead of valid_id_for_assignment.
author John W. Eaton <jwe@octave.org>
date Fri, 26 Feb 2016 20:35:45 -0500
parents 9ca194f7a858
children 74a676d5ce09
comparison
equal deleted inserted replaced
21368:e789571034bc 21369:105224df2330
3033 // We are looking at a simple assignment statement like x = rhs; 3033 // We are looking at a simple assignment statement like x = rhs;
3034 3034
3035 tree_expression *tmp = lhs->remove_front (); 3035 tree_expression *tmp = lhs->remove_front ();
3036 3036
3037 if ((tmp->is_identifier () || tmp->is_index_expression ()) 3037 if ((tmp->is_identifier () || tmp->is_index_expression ())
3038 && ! valid_id_for_assignment (tmp->name ())) 3038 && is_keyword (tmp->name ()))
3039 { 3039 {
3040 std::string kw = tmp->name (); 3040 std::string kw = tmp->name ();
3041 3041
3042 delete tmp; 3042 delete tmp;
3043 delete lhs; 3043 delete lhs;
3059 for (std::list<std::string>::const_iterator it = names.begin (); 3059 for (std::list<std::string>::const_iterator it = names.begin ();
3060 it != names.end (); it++) 3060 it != names.end (); it++)
3061 { 3061 {
3062 std::string kw = *it; 3062 std::string kw = *it;
3063 3063
3064 if (! valid_id_for_assignment (kw)) 3064 if (is_keyword (kw))
3065 { 3065 {
3066 delete lhs; 3066 delete lhs;
3067 delete rhs; 3067 delete rhs;
3068 3068
3069 bison_error ("invalid assignment to keyword \"" + kw + "\"", l, c); 3069 bison_error ("invalid assignment to keyword \"" + kw + "\"", l, c);
4020 } 4020 }
4021 4021
4022 output_buf << "\n"; 4022 output_buf << "\n";
4023 4023
4024 parse_error_msg = output_buf.str (); 4024 parse_error_msg = output_buf.str ();
4025 }
4026
4027 bool
4028 octave_base_parser::valid_id_for_assignment (const std::string& s)
4029 {
4030 // is_keyword will return true for some identfiers that are only
4031 // keywords in certain contexts.
4032
4033 return (! is_keyword (s)
4034 || (! lexer.parsing_classdef
4035 && (s == "enumeration" || s == "events"
4036 || s == "methods" || s == "properties")));
4037 } 4025 }
4038 4026
4039 int 4027 int
4040 octave_parser::run (void) 4028 octave_parser::run (void)
4041 { 4029 {
5129 % bug #35645 5117 % bug #35645
5130 %!test 5118 %!test
5131 %! [a,] = gcd (1,2); 5119 %! [a,] = gcd (1,2);
5132 %! [a,b,] = gcd (1, 2); 5120 %! [a,b,] = gcd (1, 2);
5133 5121
5122 %!error eval ("switch = 13;");
5123
5134 */ 5124 */
5135 5125
5136 DEFUN (assignin, args, , 5126 DEFUN (assignin, args, ,
5137 "-*- texinfo -*-\n\ 5127 "-*- texinfo -*-\n\
5138 @deftypefn {} {} assignin (@var{context}, @var{varname}, @var{value})\n\ 5128 @deftypefn {} {} assignin (@var{context}, @var{varname}, @var{value})\n\
5160 frame.add_fcn (octave_call_stack::pop); 5150 frame.add_fcn (octave_call_stack::pop);
5161 5151
5162 std::string nm = args(1).xstring_value ("assignin: VARNAME must be a string"); 5152 std::string nm = args(1).xstring_value ("assignin: VARNAME must be a string");
5163 5153
5164 if (valid_identifier (nm)) 5154 if (valid_identifier (nm))
5165 symbol_table::assign (nm, args(2)); 5155 {
5156 // Put the check here so that we don't slow down assignments
5157 // generally. Any that go through Octave's parser should have
5158 // already been checked.
5159
5160 if (is_keyword (nm))
5161 error ("assignin: invalid assignment to keyword '%s'", nm.c_str ());
5162
5163 symbol_table::assign (nm, args(2));
5164 }
5166 else 5165 else
5167 error ("assignin: invalid variable name in argument VARNAME"); 5166 error ("assignin: invalid variable name in argument VARNAME");
5168 5167
5169 return retval; 5168 return retval;
5170 } 5169 }
5170
5171 /*
5172
5173 %!error assignin ("base", "switch", "13");
5174
5175 */
5171 5176
5172 DEFUN (evalin, args, nargout, 5177 DEFUN (evalin, args, nargout,
5173 "-*- texinfo -*-\n\ 5178 "-*- texinfo -*-\n\
5174 @deftypefn {} {} evalin (@var{context}, @var{try})\n\ 5179 @deftypefn {} {} evalin (@var{context}, @var{try})\n\
5175 @deftypefnx {} {} evalin (@var{context}, @var{try}, @var{catch})\n\ 5180 @deftypefnx {} {} evalin (@var{context}, @var{try}, @var{catch})\n\
5383 5388
5384 %!test 5389 %!test
5385 %! warning ("off", "quiet", "local"); 5390 %! warning ("off", "quiet", "local");
5386 %! assert (evalc ("error ('foo')", "warning ('bar')"), "warning: bar\n"); 5391 %! assert (evalc ("error ('foo')", "warning ('bar')"), "warning: bar\n");
5387 5392
5393 %!error evalc ("switch = 13;");
5394
5388 */ 5395 */
5389 5396
5390 DEFUN (__parser_debug_flag__, args, nargout, 5397 DEFUN (__parser_debug_flag__, args, nargout,
5391 "-*- texinfo -*-\n\ 5398 "-*- texinfo -*-\n\
5392 @deftypefn {} {@var{val} =} __parser_debug_flag__ ()\n\ 5399 @deftypefn {} {@var{val} =} __parser_debug_flag__ ()\n\