comparison libinterp/parse-tree/oct-parse.in.yy @ 17577:c702371ff6df classdef

maint: periodic merge of default to classdef
author John W. Eaton <jwe@octave.org>
date Sat, 05 Oct 2013 11:22:09 -0400
parents 498b2dd1bd56 15e2ad6372f7
children bb2fa6e5b348
comparison
equal deleted inserted replaced
17414:20d1b911b4e7 17577:c702371ff6df
255 %type <sep_type> sep_no_nl opt_sep_no_nl nl opt_nl sep opt_sep 255 %type <sep_type> sep_no_nl opt_sep_no_nl nl opt_nl sep opt_sep
256 %type <tree_type> input 256 %type <tree_type> input
257 %type <tree_constant_type> string constant magic_colon 257 %type <tree_constant_type> string constant magic_colon
258 %type <tree_anon_fcn_handle_type> anon_fcn_handle 258 %type <tree_anon_fcn_handle_type> anon_fcn_handle
259 %type <tree_fcn_handle_type> fcn_handle 259 %type <tree_fcn_handle_type> fcn_handle
260 %type <tree_matrix_type> matrix_rows matrix_rows1 260 %type <tree_matrix_type> matrix_rows
261 %type <tree_cell_type> cell_rows cell_rows1 261 %type <tree_cell_type> cell_rows
262 %type <tree_expression_type> matrix cell 262 %type <tree_expression_type> matrix cell
263 %type <tree_expression_type> primary_expr oper_expr 263 %type <tree_expression_type> primary_expr oper_expr
264 %type <tree_expression_type> simple_expr colon_expr assign_expr expression 264 %type <tree_expression_type> simple_expr colon_expr assign_expr expression
265 %type <tree_identifier_type> identifier fcn_name magic_tilde 265 %type <tree_identifier_type> identifier fcn_name magic_tilde
266 %type <tree_funcall_type> superclass_identifier meta_identifier 266 %type <tree_funcall_type> superclass_identifier meta_identifier
280 %type <tree_if_clause_type> elseif_clause else_clause 280 %type <tree_if_clause_type> elseif_clause else_clause
281 %type <tree_if_command_list_type> if_cmd_list1 if_cmd_list 281 %type <tree_if_command_list_type> if_cmd_list1 if_cmd_list
282 %type <tree_switch_command_type> switch_command 282 %type <tree_switch_command_type> switch_command
283 %type <tree_switch_case_type> switch_case default_case 283 %type <tree_switch_case_type> switch_case default_case
284 %type <tree_switch_case_list_type> case_list1 case_list 284 %type <tree_switch_case_list_type> case_list1 case_list
285 %type <tree_decl_elt_type> decl2 285 %type <tree_decl_elt_type> decl2 param_list_elt
286 %type <tree_decl_init_list_type> decl1 286 %type <tree_decl_init_list_type> decl1
287 %type <tree_decl_command_type> declaration 287 %type <tree_decl_command_type> declaration
288 %type <tree_statement_type> statement function_end 288 %type <tree_statement_type> statement function_end
289 %type <tree_statement_list_type> simple_list simple_list1 list list1 289 %type <tree_statement_list_type> simple_list simple_list1 list list1
290 %type <tree_statement_list_type> opt_list input1 290 %type <tree_statement_list_type> opt_list
291
292 %type <tree_classdef_attribute_type> attr 291 %type <tree_classdef_attribute_type> attr
293 %type <tree_classdef_attribute_list_type> attr_list opt_attr_list 292 %type <tree_classdef_attribute_list_type> attr_list opt_attr_list
294 %type <tree_classdef_superclass_type> superclass 293 %type <tree_classdef_superclass_type> superclass
295 %type <tree_classdef_superclass_list_type> superclass_list opt_superclass_list 294 %type <tree_classdef_superclass_list_type> superclass_list opt_superclass_list
296 %type <tree_classdef_body_type> class_body 295 %type <tree_classdef_body_type> class_body
329 328
330 // ============================== 329 // ==============================
331 // Statements and statement lists 330 // Statements and statement lists
332 // ============================== 331 // ==============================
333 332
334 input : input1 333 input : simple_list '\n'
335 { 334 {
336 parser.stmt_list = $1; 335 parser.stmt_list = $1;
337 YYACCEPT; 336 YYACCEPT;
338 } 337 }
339 | simple_list parse_error 338 | simple_list END_OF_INPUT
340 { ABORT_PARSE; } 339 {
340 lexer.end_of_input = true;
341 parser.stmt_list = $1;
342 YYACCEPT;
343 }
341 | parse_error 344 | parse_error
342 { ABORT_PARSE; } 345 { ABORT_PARSE; }
343 ; 346 ;
344 347
345 input1 : '\n' 348 simple_list : opt_sep_no_nl
346 { $$ = 0; } 349 { $$ = 0; }
347 | END_OF_INPUT 350 | simple_list1 opt_sep_no_nl
348 {
349 lexer.end_of_input = true;
350 $$ = 0;
351 }
352 | simple_list
353 { $$ = $1; }
354 | simple_list '\n'
355 { $$ = $1; }
356 | simple_list END_OF_INPUT
357 { $$ = $1; }
358 ;
359
360 simple_list : simple_list1 opt_sep_no_nl
361 { $$ = parser.set_stmt_print_flag ($1, $2, false); } 351 { $$ = parser.set_stmt_print_flag ($1, $2, false); }
362 ; 352 ;
363 353
364 simple_list1 : statement 354 simple_list1 : statement
365 { $$ = parser.make_statement_list ($1); } 355 { $$ = parser.make_statement_list ($1); }
463 { $$ = parser.make_constant (IMAG_NUM, $1); } 453 { $$ = parser.make_constant (IMAG_NUM, $1); }
464 | string 454 | string
465 { $$ = $1; } 455 { $$ = $1; }
466 ; 456 ;
467 457
468 matrix : '[' ']' 458 matrix : '[' matrix_rows ']'
469 { $$ = new tree_constant (octave_null_matrix::instance); }
470 | '[' ';' ']'
471 { $$ = new tree_constant (octave_null_matrix::instance); }
472 | '[' ',' ']'
473 { $$ = new tree_constant (octave_null_matrix::instance); }
474 | '[' matrix_rows ']'
475 { $$ = parser.finish_matrix ($2); } 459 { $$ = parser.finish_matrix ($2); }
476 ; 460 ;
477 461
478 matrix_rows : matrix_rows1 462 matrix_rows : cell_or_matrix_row
463 { $$ = $1 ? new tree_matrix ($1) : 0; }
464 | matrix_rows ';' cell_or_matrix_row
465 {
466 if ($1)
467 {
468 if ($3)
469 $1->append ($3);
470
471 $$ = $1;
472 }
473 else
474 $$ = $3 ? new tree_matrix ($3) : 0;
475 }
476 ;
477
478 cell : '{' cell_rows '}'
479 { $$ = parser.finish_cell ($2); }
480 ;
481
482 cell_rows : cell_or_matrix_row
483 { $$ = $1 ? new tree_cell ($1) : 0; }
484 | cell_rows ';' cell_or_matrix_row
485 {
486 if ($1)
487 {
488 if ($3)
489 $1->append ($3);
490
491 $$ = $1;
492 }
493 else
494 $$ = $3 ? new tree_cell ($3) : 0;
495 }
496 ;
497
498 // tree_argument_list objects can't be empty or have leading or trailing
499 // commas, but those are all allowed in matrix and cell array rows.
500
501 cell_or_matrix_row
502 : // empty
503 { $$ = 0; }
504 | ','
505 { $$ = 0; }
506 | arg_list
479 { $$ = $1; } 507 { $$ = $1; }
480 | matrix_rows1 ';' // Ignore trailing semicolon. 508 | arg_list ','
481 { $$ = $1; } 509 { $$ = $1; }
482 ; 510 | ',' arg_list
483 511 { $$ = $2; }
484 matrix_rows1 : cell_or_matrix_row 512 | ',' arg_list ','
485 { $$ = new tree_matrix ($1); } 513 { $$ = $2; }
486 | matrix_rows1 ';' cell_or_matrix_row
487 {
488 $1->append ($3);
489 $$ = $1;
490 }
491 ;
492
493 cell : '{' '}'
494 { $$ = new tree_constant (octave_value (Cell ())); }
495 | '{' ';' '}'
496 { $$ = new tree_constant (octave_value (Cell ())); }
497 | '{' cell_rows '}'
498 { $$ = parser.finish_cell ($2); }
499 ;
500
501 cell_rows : cell_rows1
502 { $$ = $1; }
503 | cell_rows1 ';' // Ignore trailing semicolon.
504 { $$ = $1; }
505 ;
506
507 cell_rows1 : cell_or_matrix_row
508 { $$ = new tree_cell ($1); }
509 | cell_rows1 ';' cell_or_matrix_row
510 {
511 $1->append ($3);
512 $$ = $1;
513 }
514 ;
515
516 cell_or_matrix_row
517 : arg_list
518 { $$ = $1; }
519 | arg_list ',' // Ignore trailing comma.
520 { $$ = $1; }
521 ; 514 ;
522 515
523 fcn_handle : '@' FCN_HANDLE 516 fcn_handle : '@' FCN_HANDLE
524 { 517 {
525 $$ = parser.make_fcn_handle ($2); 518 $$ = parser.make_fcn_handle ($2);
830 | identifier '=' decl_param_init expression 823 | identifier '=' decl_param_init expression
831 { 824 {
832 lexer.looking_at_initializer_expression = false; 825 lexer.looking_at_initializer_expression = false;
833 $$ = new tree_decl_elt ($1, $4); 826 $$ = new tree_decl_elt ($1, $4);
834 } 827 }
835 | magic_tilde
836 {
837 $$ = new tree_decl_elt ($1);
838 }
839 ; 828 ;
840 829
841 // ==================== 830 // ====================
842 // Selection statements 831 // Selection statements
843 // ==================== 832 // ====================
1007 stash_comment opt_sep opt_list END 996 stash_comment opt_sep opt_list END
1008 { 997 {
1009 if (! ($$ = parser.make_unwind_command ($1, $4, $8, $9, $2, $6))) 998 if (! ($$ = parser.make_unwind_command ($1, $4, $8, $9, $2, $6)))
1010 ABORT_PARSE; 999 ABORT_PARSE;
1011 } 1000 }
1012 | TRY stash_comment opt_sep opt_list CATCH 1001 | TRY stash_comment opt_sep opt_list CATCH stash_comment
1013 stash_comment opt_sep opt_list END 1002 opt_sep opt_list END
1014 { 1003 {
1015 if (! ($$ = parser.make_try_command ($1, $4, $8, $9, $2, $6))) 1004 if (! ($$ = parser.make_try_command ($1, $4, $7, $8, $9, $2, $6)))
1016 ABORT_PARSE; 1005 ABORT_PARSE;
1017 } 1006 }
1018 | TRY stash_comment opt_sep opt_list END 1007 | TRY stash_comment opt_sep opt_list END
1019 { 1008 {
1020 if (! ($$ = parser.make_try_command ($1, $4, 0, $5, $2, 0))) 1009 if (! ($$ = parser.make_try_command ($1, $4, 0, 0, $5, $2, 0)))
1021 ABORT_PARSE; 1010 ABORT_PARSE;
1022 } 1011 }
1023 ; 1012 ;
1024 1013
1025 // =========================================== 1014 // ===========================================
1102 else 1091 else
1103 ABORT_PARSE; 1092 ABORT_PARSE;
1104 } 1093 }
1105 ; 1094 ;
1106 1095
1107 param_list2 : decl2 1096 param_list2 : param_list_elt
1108 { $$ = new tree_parameter_list ($1); } 1097 { $$ = new tree_parameter_list ($1); }
1109 | param_list2 ',' decl2 1098 | param_list2 ',' param_list_elt
1110 { 1099 {
1111 $1->append ($3); 1100 $1->append ($3);
1112 $$ = $1; 1101 $$ = $1;
1113 } 1102 }
1103 ;
1104
1105 param_list_elt : decl2
1106 { $$ = $1; }
1107 | magic_tilde
1108 { $$ = new tree_decl_elt ($1); }
1114 ; 1109 ;
1115 1110
1116 // =================================== 1111 // ===================================
1117 // List of function return value names 1112 // List of function return value names
1118 // =================================== 1113 // ===================================
1119 1114
1120 return_list : '[' ']' 1115 return_list : '[' ']'
1121 { 1116 {
1122 lexer.looking_at_return_list = false; 1117 lexer.looking_at_return_list = false;
1118
1123 $$ = new tree_parameter_list (); 1119 $$ = new tree_parameter_list ();
1124 } 1120 }
1125 | return_list1 1121 | identifier
1126 { 1122 {
1127 lexer.looking_at_return_list = false; 1123 lexer.looking_at_return_list = false;
1128 if ($1->validate (tree_parameter_list::out)) 1124
1129 $$ = $1; 1125 tree_parameter_list *tmp = new tree_parameter_list ($1);
1126
1127 // Even though this parameter list can contain only
1128 // a single identifier, we still need to validate it
1129 // to check for varargin or varargout.
1130
1131 if (tmp->validate (tree_parameter_list::out))
1132 $$ = tmp;
1130 else 1133 else
1131 ABORT_PARSE; 1134 ABORT_PARSE;
1132 } 1135 }
1133 | '[' return_list1 ']' 1136 | '[' return_list1 ']'
1134 { 1137 {
1135 lexer.looking_at_return_list = false; 1138 lexer.looking_at_return_list = false;
1139
1140 // Check for duplicate parameter names, varargin,
1141 // or varargout.
1142
1136 if ($2->validate (tree_parameter_list::out)) 1143 if ($2->validate (tree_parameter_list::out))
1137 $$ = $2; 1144 $$ = $2;
1138 else 1145 else
1139 ABORT_PARSE; 1146 ABORT_PARSE;
1140 } 1147 }
2281 // Build a try-catch command. 2288 // Build a try-catch command.
2282 2289
2283 tree_command * 2290 tree_command *
2284 octave_base_parser::make_try_command (token *try_tok, 2291 octave_base_parser::make_try_command (token *try_tok,
2285 tree_statement_list *body, 2292 tree_statement_list *body,
2293 char catch_sep,
2286 tree_statement_list *cleanup_stmts, 2294 tree_statement_list *cleanup_stmts,
2287 token *end_tok, 2295 token *end_tok,
2288 octave_comment_list *lc, 2296 octave_comment_list *lc,
2289 octave_comment_list *mc) 2297 octave_comment_list *mc)
2290 { 2298 {
2295 octave_comment_list *tc = octave_comment_buffer::get_comment (); 2303 octave_comment_list *tc = octave_comment_buffer::get_comment ();
2296 2304
2297 int l = try_tok->line (); 2305 int l = try_tok->line ();
2298 int c = try_tok->column (); 2306 int c = try_tok->column ();
2299 2307
2300 retval = new tree_try_catch_command (body, cleanup_stmts, 2308 tree_identifier *id = 0;
2309
2310 if (! catch_sep && cleanup_stmts && ! cleanup_stmts->empty ())
2311 {
2312 tree_statement *stmt = cleanup_stmts->front ();
2313
2314 if (stmt)
2315 {
2316 tree_expression *expr = stmt->expression ();
2317
2318 if (expr && expr->is_identifier ())
2319 {
2320 id = dynamic_cast<tree_identifier *> (expr);
2321
2322 cleanup_stmts->pop_front ();
2323 }
2324 }
2325 }
2326
2327 retval = new tree_try_catch_command (body, cleanup_stmts, id,
2301 lc, mc, tc, l, c); 2328 lc, mc, tc, l, c);
2302 } 2329 }
2303 2330
2304 return retval; 2331 return retval;
2305 } 2332 }
3338 // Finish building a matrix list. 3365 // Finish building a matrix list.
3339 3366
3340 tree_expression * 3367 tree_expression *
3341 octave_base_parser::finish_matrix (tree_matrix *m) 3368 octave_base_parser::finish_matrix (tree_matrix *m)
3342 { 3369 {
3343 return finish_array_list (m); 3370 return (m
3371 ? finish_array_list (m)
3372 : new tree_constant (octave_null_matrix::instance));
3344 } 3373 }
3345 3374
3346 // Finish building a cell list. 3375 // Finish building a cell list.
3347 3376
3348 tree_expression * 3377 tree_expression *
3349 octave_base_parser::finish_cell (tree_cell *c) 3378 octave_base_parser::finish_cell (tree_cell *c)
3350 { 3379 {
3351 return finish_array_list (c); 3380 return (c
3381 ? finish_array_list (c)
3382 : new tree_constant (octave_value (Cell ())));
3352 } 3383 }
3353 3384
3354 void 3385 void
3355 octave_base_parser::maybe_warn_missing_semi (tree_statement_list *t) 3386 octave_base_parser::maybe_warn_missing_semi (tree_statement_list *t)
3356 { 3387 {
3802 return retval; 3833 return retval;
3803 } 3834 }
3804 3835
3805 DEFUN (autoload, args, , 3836 DEFUN (autoload, args, ,
3806 "-*- texinfo -*-\n\ 3837 "-*- texinfo -*-\n\
3807 @deftypefn {Built-in Function} {} autoload (@var{function}, @var{file})\n\ 3838 @deftypefn {Built-in Function} {} autoload (@var{function}, @var{file})\n\
3808 @deftypefnx {Built-in Function} {} autoload (@dots{}, @asis{\"remove\"})\n\ 3839 @deftypefnx {Built-in Function} {} autoload (@dots{}, @asis{\"remove\"})\n\
3809 Define @var{function} to autoload from @var{file}.\n\ 3840 Define @var{function} to autoload from @var{file}.\n\
3810 \n\ 3841 \n\
3811 The second argument, @var{file}, should be an absolute file name or\n\ 3842 The second argument, @var{file}, should be an absolute file name or\n\
3812 a file name in the same directory as the function or script from which\n\ 3843 a file name in the same directory as the function or script from which\n\
4032 "-*- texinfo -*-\n\ 4063 "-*- texinfo -*-\n\
4033 @deftypefn {Built-in Function} {} mfilename ()\n\ 4064 @deftypefn {Built-in Function} {} mfilename ()\n\
4034 @deftypefnx {Built-in Function} {} mfilename (\"fullpath\")\n\ 4065 @deftypefnx {Built-in Function} {} mfilename (\"fullpath\")\n\
4035 @deftypefnx {Built-in Function} {} mfilename (\"fullpathext\")\n\ 4066 @deftypefnx {Built-in Function} {} mfilename (\"fullpathext\")\n\
4036 Return the name of the currently executing file. At the top-level,\n\ 4067 Return the name of the currently executing file. At the top-level,\n\
4037 return the empty string. Given the argument @code{\"fullpath\"},\n\ 4068 return the empty string. Given the argument @qcode{\"fullpath\"},\n\
4038 include the directory part of the file name, but not the extension.\n\ 4069 include the directory part of the file name, but not the extension.\n\
4039 Given the argument @code{\"fullpathext\"}, include the directory part\n\ 4070 Given the argument @qcode{\"fullpathext\"}, include the directory part\n\
4040 of the file name and the extension.\n\ 4071 of the file name and the extension.\n\
4041 @end deftypefn") 4072 @end deftypefn")
4042 { 4073 {
4043 octave_value retval; 4074 octave_value retval;
4044 4075
4553 4584
4554 DEFUN (assignin, args, , 4585 DEFUN (assignin, args, ,
4555 "-*- texinfo -*-\n\ 4586 "-*- texinfo -*-\n\
4556 @deftypefn {Built-in Function} {} assignin (@var{context}, @var{varname}, @var{value})\n\ 4587 @deftypefn {Built-in Function} {} assignin (@var{context}, @var{varname}, @var{value})\n\
4557 Assign @var{value} to @var{varname} in context @var{context}, which\n\ 4588 Assign @var{value} to @var{varname} in context @var{context}, which\n\
4558 may be either @code{\"base\"} or @code{\"caller\"}.\n\ 4589 may be either @qcode{\"base\"} or @qcode{\"caller\"}.\n\
4559 @seealso{evalin}\n\ 4590 @seealso{evalin}\n\
4560 @end deftypefn") 4591 @end deftypefn")
4561 { 4592 {
4562 octave_value_list retval; 4593 octave_value_list retval;
4563 4594
4607 DEFUN (evalin, args, nargout, 4638 DEFUN (evalin, args, nargout,
4608 "-*- texinfo -*-\n\ 4639 "-*- texinfo -*-\n\
4609 @deftypefn {Built-in Function} {} evalin (@var{context}, @var{try})\n\ 4640 @deftypefn {Built-in Function} {} evalin (@var{context}, @var{try})\n\
4610 @deftypefnx {Built-in Function} {} evalin (@var{context}, @var{try}, @var{catch})\n\ 4641 @deftypefnx {Built-in Function} {} evalin (@var{context}, @var{try}, @var{catch})\n\
4611 Like @code{eval}, except that the expressions are evaluated in the\n\ 4642 Like @code{eval}, except that the expressions are evaluated in the\n\
4612 context @var{context}, which may be either @code{\"caller\"} or\n\ 4643 context @var{context}, which may be either @qcode{\"caller\"} or\n\
4613 @code{\"base\"}.\n\ 4644 @qcode{\"base\"}.\n\
4614 @seealso{eval, assignin}\n\ 4645 @seealso{eval, assignin}\n\
4615 @end deftypefn") 4646 @end deftypefn")
4616 { 4647 {
4617 octave_value_list retval; 4648 octave_value_list retval;
4618 4649
4691 4722
4692 octave_debug = debug_flag; 4723 octave_debug = debug_flag;
4693 4724
4694 return retval; 4725 return retval;
4695 } 4726 }
4727
4728 DEFUN (__parse_file__, args, ,
4729 "-*- texinfo -*-\n\
4730 @deftypefn {Built-in Function} {} __parse_file__ (@var{file}, @var{verbose})\n\
4731 Undocumented internal function.\n\
4732 @end deftypefn")
4733 {
4734 octave_value retval;
4735
4736 int nargin = args.length ();
4737
4738 if (nargin == 1 || nargin == 2)
4739 {
4740 std::string file = args(0).string_value ();
4741
4742 std::string full_file = octave_env::make_absolute (file);
4743
4744 size_t file_len = file.length ();
4745
4746 if ((file_len > 4 && file.substr (file_len-4) == ".oct")
4747 || (file_len > 4 && file.substr (file_len-4) == ".mex")
4748 || (file_len > 2 && file.substr (file_len-2) == ".m"))
4749 {
4750 file = octave_env::base_pathname (file);
4751 file = file.substr (0, file.find_last_of ('.'));
4752
4753 size_t pos = file.find_last_of (file_ops::dir_sep_str ());
4754 if (pos != std::string::npos)
4755 file = file.substr (pos+1);
4756 }
4757
4758 if (! error_state)
4759 {
4760 if (nargin == 2)
4761 octave_stdout << "parsing " << full_file << std::endl;
4762
4763 octave_function *fcn = parse_fcn_file (full_file, file, "", "",
4764 true, false, false,
4765 false, "__parse_file__");
4766
4767 if (fcn)
4768 delete fcn;
4769 }
4770 else
4771 error ("__parse_file__: expecting file name as argument");
4772 }
4773 else
4774 print_usage ();
4775
4776 return retval;
4777 }