Mercurial > hg > octave-nkf
diff 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 |
line wrap: on
line diff
--- a/libinterp/parse-tree/oct-parse.in.yy +++ b/libinterp/parse-tree/oct-parse.in.yy @@ -257,8 +257,8 @@ %type <tree_constant_type> string constant magic_colon %type <tree_anon_fcn_handle_type> anon_fcn_handle %type <tree_fcn_handle_type> fcn_handle -%type <tree_matrix_type> matrix_rows matrix_rows1 -%type <tree_cell_type> cell_rows cell_rows1 +%type <tree_matrix_type> matrix_rows +%type <tree_cell_type> cell_rows %type <tree_expression_type> matrix cell %type <tree_expression_type> primary_expr oper_expr %type <tree_expression_type> simple_expr colon_expr assign_expr expression @@ -282,13 +282,12 @@ %type <tree_switch_command_type> switch_command %type <tree_switch_case_type> switch_case default_case %type <tree_switch_case_list_type> case_list1 case_list -%type <tree_decl_elt_type> decl2 +%type <tree_decl_elt_type> decl2 param_list_elt %type <tree_decl_init_list_type> decl1 %type <tree_decl_command_type> declaration %type <tree_statement_type> statement function_end %type <tree_statement_list_type> simple_list simple_list1 list list1 -%type <tree_statement_list_type> opt_list input1 - +%type <tree_statement_list_type> opt_list %type <tree_classdef_attribute_type> attr %type <tree_classdef_attribute_list_type> attr_list opt_attr_list %type <tree_classdef_superclass_type> superclass @@ -331,33 +330,24 @@ // Statements and statement lists // ============================== -input : input1 +input : simple_list '\n' { parser.stmt_list = $1; YYACCEPT; } - | simple_list parse_error - { ABORT_PARSE; } + | simple_list END_OF_INPUT + { + lexer.end_of_input = true; + parser.stmt_list = $1; + YYACCEPT; + } | parse_error { ABORT_PARSE; } ; -input1 : '\n' +simple_list : opt_sep_no_nl { $$ = 0; } - | END_OF_INPUT - { - lexer.end_of_input = true; - $$ = 0; - } - | simple_list - { $$ = $1; } - | simple_list '\n' - { $$ = $1; } - | simple_list END_OF_INPUT - { $$ = $1; } - ; - -simple_list : simple_list1 opt_sep_no_nl + | simple_list1 opt_sep_no_nl { $$ = parser.set_stmt_print_flag ($1, $2, false); } ; @@ -465,59 +455,62 @@ { $$ = $1; } ; -matrix : '[' ']' - { $$ = new tree_constant (octave_null_matrix::instance); } - | '[' ';' ']' - { $$ = new tree_constant (octave_null_matrix::instance); } - | '[' ',' ']' - { $$ = new tree_constant (octave_null_matrix::instance); } - | '[' matrix_rows ']' +matrix : '[' matrix_rows ']' { $$ = parser.finish_matrix ($2); } ; -matrix_rows : matrix_rows1 - { $$ = $1; } - | matrix_rows1 ';' // Ignore trailing semicolon. - { $$ = $1; } - ; - -matrix_rows1 : cell_or_matrix_row - { $$ = new tree_matrix ($1); } - | matrix_rows1 ';' cell_or_matrix_row +matrix_rows : cell_or_matrix_row + { $$ = $1 ? new tree_matrix ($1) : 0; } + | matrix_rows ';' cell_or_matrix_row { - $1->append ($3); - $$ = $1; + if ($1) + { + if ($3) + $1->append ($3); + + $$ = $1; + } + else + $$ = $3 ? new tree_matrix ($3) : 0; } ; -cell : '{' '}' - { $$ = new tree_constant (octave_value (Cell ())); } - | '{' ';' '}' - { $$ = new tree_constant (octave_value (Cell ())); } - | '{' cell_rows '}' +cell : '{' cell_rows '}' { $$ = parser.finish_cell ($2); } ; -cell_rows : cell_rows1 - { $$ = $1; } - | cell_rows1 ';' // Ignore trailing semicolon. - { $$ = $1; } - ; - -cell_rows1 : cell_or_matrix_row - { $$ = new tree_cell ($1); } - | cell_rows1 ';' cell_or_matrix_row +cell_rows : cell_or_matrix_row + { $$ = $1 ? new tree_cell ($1) : 0; } + | cell_rows ';' cell_or_matrix_row { - $1->append ($3); - $$ = $1; + if ($1) + { + if ($3) + $1->append ($3); + + $$ = $1; + } + else + $$ = $3 ? new tree_cell ($3) : 0; } ; +// tree_argument_list objects can't be empty or have leading or trailing +// commas, but those are all allowed in matrix and cell array rows. + cell_or_matrix_row - : arg_list + : // empty + { $$ = 0; } + | ',' + { $$ = 0; } + | arg_list { $$ = $1; } - | arg_list ',' // Ignore trailing comma. + | arg_list ',' { $$ = $1; } + | ',' arg_list + { $$ = $2; } + | ',' arg_list ',' + { $$ = $2; } ; fcn_handle : '@' FCN_HANDLE @@ -832,10 +825,6 @@ lexer.looking_at_initializer_expression = false; $$ = new tree_decl_elt ($1, $4); } - | magic_tilde - { - $$ = new tree_decl_elt ($1); - } ; // ==================== @@ -1009,15 +998,15 @@ if (! ($$ = parser.make_unwind_command ($1, $4, $8, $9, $2, $6))) ABORT_PARSE; } - | TRY stash_comment opt_sep opt_list CATCH - stash_comment opt_sep opt_list END + | TRY stash_comment opt_sep opt_list CATCH stash_comment + opt_sep opt_list END { - if (! ($$ = parser.make_try_command ($1, $4, $8, $9, $2, $6))) + if (! ($$ = parser.make_try_command ($1, $4, $7, $8, $9, $2, $6))) ABORT_PARSE; } | TRY stash_comment opt_sep opt_list END { - if (! ($$ = parser.make_try_command ($1, $4, 0, $5, $2, 0))) + if (! ($$ = parser.make_try_command ($1, $4, 0, 0, $5, $2, 0))) ABORT_PARSE; } ; @@ -1104,15 +1093,21 @@ } ; -param_list2 : decl2 +param_list2 : param_list_elt { $$ = new tree_parameter_list ($1); } - | param_list2 ',' decl2 + | param_list2 ',' param_list_elt { $1->append ($3); $$ = $1; } ; +param_list_elt : decl2 + { $$ = $1; } + | magic_tilde + { $$ = new tree_decl_elt ($1); } + ; + // =================================== // List of function return value names // =================================== @@ -1120,19 +1115,31 @@ return_list : '[' ']' { lexer.looking_at_return_list = false; + $$ = new tree_parameter_list (); } - | return_list1 + | identifier { lexer.looking_at_return_list = false; - if ($1->validate (tree_parameter_list::out)) - $$ = $1; + + tree_parameter_list *tmp = new tree_parameter_list ($1); + + // Even though this parameter list can contain only + // a single identifier, we still need to validate it + // to check for varargin or varargout. + + if (tmp->validate (tree_parameter_list::out)) + $$ = tmp; else ABORT_PARSE; } | '[' return_list1 ']' { lexer.looking_at_return_list = false; + + // Check for duplicate parameter names, varargin, + // or varargout. + if ($2->validate (tree_parameter_list::out)) $$ = $2; else @@ -2283,6 +2290,7 @@ tree_command * octave_base_parser::make_try_command (token *try_tok, tree_statement_list *body, + char catch_sep, tree_statement_list *cleanup_stmts, token *end_tok, octave_comment_list *lc, @@ -2297,7 +2305,26 @@ int l = try_tok->line (); int c = try_tok->column (); - retval = new tree_try_catch_command (body, cleanup_stmts, + tree_identifier *id = 0; + + if (! catch_sep && cleanup_stmts && ! cleanup_stmts->empty ()) + { + tree_statement *stmt = cleanup_stmts->front (); + + if (stmt) + { + tree_expression *expr = stmt->expression (); + + if (expr && expr->is_identifier ()) + { + id = dynamic_cast<tree_identifier *> (expr); + + cleanup_stmts->pop_front (); + } + } + } + + retval = new tree_try_catch_command (body, cleanup_stmts, id, lc, mc, tc, l, c); } @@ -3340,7 +3367,9 @@ tree_expression * octave_base_parser::finish_matrix (tree_matrix *m) { - return finish_array_list (m); + return (m + ? finish_array_list (m) + : new tree_constant (octave_null_matrix::instance)); } // Finish building a cell list. @@ -3348,7 +3377,9 @@ tree_expression * octave_base_parser::finish_cell (tree_cell *c) { - return finish_array_list (c); + return (c + ? finish_array_list (c) + : new tree_constant (octave_value (Cell ()))); } void @@ -3804,7 +3835,7 @@ DEFUN (autoload, args, , "-*- texinfo -*-\n\ -@deftypefn {Built-in Function} {} autoload (@var{function}, @var{file})\n\ +@deftypefn {Built-in Function} {} autoload (@var{function}, @var{file})\n\ @deftypefnx {Built-in Function} {} autoload (@dots{}, @asis{\"remove\"})\n\ Define @var{function} to autoload from @var{file}.\n\ \n\ @@ -4034,9 +4065,9 @@ @deftypefnx {Built-in Function} {} mfilename (\"fullpath\")\n\ @deftypefnx {Built-in Function} {} mfilename (\"fullpathext\")\n\ Return the name of the currently executing file. At the top-level,\n\ -return the empty string. Given the argument @code{\"fullpath\"},\n\ +return the empty string. Given the argument @qcode{\"fullpath\"},\n\ include the directory part of the file name, but not the extension.\n\ -Given the argument @code{\"fullpathext\"}, include the directory part\n\ +Given the argument @qcode{\"fullpathext\"}, include the directory part\n\ of the file name and the extension.\n\ @end deftypefn") { @@ -4555,7 +4586,7 @@ "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} assignin (@var{context}, @var{varname}, @var{value})\n\ Assign @var{value} to @var{varname} in context @var{context}, which\n\ -may be either @code{\"base\"} or @code{\"caller\"}.\n\ +may be either @qcode{\"base\"} or @qcode{\"caller\"}.\n\ @seealso{evalin}\n\ @end deftypefn") { @@ -4609,8 +4640,8 @@ @deftypefn {Built-in Function} {} evalin (@var{context}, @var{try})\n\ @deftypefnx {Built-in Function} {} evalin (@var{context}, @var{try}, @var{catch})\n\ Like @code{eval}, except that the expressions are evaluated in the\n\ -context @var{context}, which may be either @code{\"caller\"} or\n\ -@code{\"base\"}.\n\ +context @var{context}, which may be either @qcode{\"caller\"} or\n\ +@qcode{\"base\"}.\n\ @seealso{eval, assignin}\n\ @end deftypefn") { @@ -4693,3 +4724,54 @@ return retval; } + +DEFUN (__parse_file__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Built-in Function} {} __parse_file__ (@var{file}, @var{verbose})\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value retval; + + int nargin = args.length (); + + if (nargin == 1 || nargin == 2) + { + std::string file = args(0).string_value (); + + std::string full_file = octave_env::make_absolute (file); + + size_t file_len = file.length (); + + if ((file_len > 4 && file.substr (file_len-4) == ".oct") + || (file_len > 4 && file.substr (file_len-4) == ".mex") + || (file_len > 2 && file.substr (file_len-2) == ".m")) + { + file = octave_env::base_pathname (file); + file = file.substr (0, file.find_last_of ('.')); + + size_t pos = file.find_last_of (file_ops::dir_sep_str ()); + if (pos != std::string::npos) + file = file.substr (pos+1); + } + + if (! error_state) + { + if (nargin == 2) + octave_stdout << "parsing " << full_file << std::endl; + + octave_function *fcn = parse_fcn_file (full_file, file, "", "", + true, false, false, + false, "__parse_file__"); + + if (fcn) + delete fcn; + } + else + error ("__parse_file__: expecting file name as argument"); + } + else + print_usage (); + + return retval; +}