Mercurial > hg > octave-nkf
changeset 16924:aebb54d99dba
improve compatibility of parsing of matrices and cell arrays
* oct-parse.in.yy (matrix_rows1, cell_rows1): Delete non-terminals.
(matrix, matrix_rows, cell, cell_rows): Ignore empty elements.
(cell_or_matrix_row): Handle leading and trailing commas.
(octave_base_parser::finish_matrix, octave_base_parser::finish_cell):
Handle null matrix and cell objects.
* pt-mat.cc: New tests.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Mon, 08 Jul 2013 12:20:04 -0400 |
parents | 5d08a2ec7edb |
children | 5c25f7ed080c |
files | libinterp/parse-tree/oct-parse.in.yy libinterp/parse-tree/pt-mat.cc |
diffstat | 2 files changed, 75 insertions(+), 40 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/parse-tree/oct-parse.in.yy +++ b/libinterp/parse-tree/oct-parse.in.yy @@ -235,8 +235,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 @@ -426,59 +426,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 @@ -3069,7 +3072,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. @@ -3077,7 +3082,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
--- a/libinterp/parse-tree/pt-mat.cc +++ b/libinterp/parse-tree/pt-mat.cc @@ -1336,6 +1336,34 @@ %!assert (class ([cell(1), struct("foo", "bar")]), "cell") %!error [struct("foo", "bar"), cell(1)] + +%!assert ([,1], 1) +%!assert ([1,], 1) +%!assert ([,1,], 1) +%!assert ([,1,;;], 1) +%!assert ([,1,;,;], 1) + +%!assert ([1,1], ones (1, 2)) +%!assert ([,1,1], ones (1, 2)) +%!assert ([1,1,], ones (1, 2)) +%!assert ([,1,1,], ones (1, 2)) +%!assert ([,1,1,;;], ones (1, 2)) +%!assert ([,1,1,;,;], ones (1, 2)) +%!assert ([,;,1,1], ones (1, 2)) + +%!assert ([1;1], ones (2, 1)) +%!assert ([1,;1], ones (2, 1)) +%!assert ([1,;,;1], ones (2, 1)) + +%!error eval ("[,,]") +%!error eval ("[,,;,]") +%!error eval ("[,;,,;,]") + +%!assert (isnull ([,])) +%!assert (isnull ([;])) +%!assert (isnull ([;;])) +%!assert (isnull ([;,;])) +%!assert (isnull ([,;,;,])) */ DEFUN (string_fill_char, args, nargout,