Mercurial > octave
changeset 23673:1d1ce4df5255
refactor bison rules for parsing functions
* parse.h, oct-parse.in.yy: Expect 9 shift/reduce errors.
(base_parser::make_function): New function.
(function1, function1): Combine non-terminal rules with function rule.
(opt_param_list): New non-terminal.
(function): Combine rules as much as possible. Move all processing to
make_function.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 21 Jun 2017 14:23:47 -0400 |
parents | 3037e865dee1 |
children | 81b141d265a3 |
files | libinterp/parse-tree/oct-parse.in.yy libinterp/parse-tree/parse.h |
diffstat | 2 files changed, 87 insertions(+), 73 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/parse-tree/oct-parse.in.yy Wed Jun 21 11:46:31 2017 -0400 +++ b/libinterp/parse-tree/oct-parse.in.yy Wed Jun 21 14:23:47 2017 -0400 @@ -111,10 +111,10 @@ // Bison declarations. -// The grammar currently has 8 shift/reduce conflicts. Ensure that +// The grammar currently has 9 shift/reduce conflicts. Ensure that // we notice if that number changes. -%expect 8 +%expect 9 %API_PREFIX_DECL% @@ -248,11 +248,11 @@ %type <tree_expression_type> simple_expr colon_expr assign_expr expression %type <tree_identifier_type> identifier fcn_name magic_tilde %type <tree_funcall_type> superclass_identifier meta_identifier -%type <octave_user_function_type> function1 function2 %type <tree_index_expression_type> word_list_cmd %type <tree_argument_list_type> arg_list word_list assign_lhs %type <tree_argument_list_type> cell_or_matrix_row -%type <tree_parameter_list_type> param_list param_list1 param_list2 +%type <tree_parameter_list_type> opt_param_list param_list +%type <tree_parameter_list_type> param_list1 param_list2 %type <tree_parameter_list_type> return_list return_list1 %type <tree_command_type> command select_command loop_command %type <tree_command_type> jump_command except_command @@ -1320,6 +1320,12 @@ } ; +opt_param_list : // empty + { $$ = 0; } + | param_list + { $$ = $1; } + ; + param_list : param_list_beg param_list1 param_list_end { if ($2) @@ -1484,22 +1490,6 @@ } ; -function : function_beg stash_comment function1 - { - $$ = parser.finish_function (0, $3, $2, $1->line (), - $1->column ()); - parser.recover_from_parsing_function (); - } - | function_beg stash_comment return_list '=' function1 - { - YYUSE ($4); - - $$ = parser.finish_function ($3, $5, $2, $1->line (), - $1->column ()); - parser.recover_from_parsing_function (); - } - ; - fcn_name : identifier { std::string id = $1->name (); @@ -1543,38 +1533,6 @@ } ; -function1 : fcn_name function2 - { - std::string fname = $1->name (); - - delete $1; - - if (lexer.parsing_classdef_get_method) - fname.insert (0, "get."); - else if (lexer.parsing_classdef_set_method) - fname.insert (0, "set."); - - lexer.parsing_classdef_get_method = false; - lexer.parsing_classdef_set_method = false; - - $$ = parser.frob_function (fname, $2); - } - ; - -function2 : param_list opt_sep opt_list function_end - { - YYUSE ($2); - - $$ = parser.start_function ($1, $3, $4); - } - | opt_sep opt_list function_end - { - YYUSE ($1); - - $$ = parser.start_function (0, $2, $3); - } - ; - function_end : END { parser.endfunction_found = true; @@ -1624,6 +1582,23 @@ } ; +function : function_beg stash_comment fcn_name + opt_param_list opt_sep opt_list function_end + { + YYUSE ($5); + + $$ = parser.make_function ($1, 0, $3, $4, $6, $7, $2); + } + | function_beg stash_comment return_list '=' fcn_name + opt_param_list opt_sep opt_list function_end + { + YYUSE ($4); + YYUSE ($7); + + $$ = parser.make_function ($1, $3, $5, $6, $8, $9, $2); + } + ; + // ======== // Classdef // ======== @@ -3246,15 +3221,58 @@ primary_fcn_ptr = script; } + // Define a function. + + // FIXME: combining start_function, finish_function, and + // recover_from_parsing_function should be possible, but it makes + // for a large mess. Maybe this could be a bit better organized? + + tree_function_def * + base_parser::make_function (token *fcn_tok, + tree_parameter_list *ret_list, + tree_identifier *id, + tree_parameter_list *param_list, + tree_statement_list *body, + tree_statement *end_fcn_stmt, + octave_comment_list *lc) + { + tree_function_def *retval = 0; + + int l = fcn_tok->line (); + int c = fcn_tok->column (); + + octave_user_function *tmp_fcn + = start_function (id, param_list, body, end_fcn_stmt); + + retval = finish_function (ret_list, tmp_fcn, lc, l, c); + + recover_from_parsing_function (); + + return retval; + } + // Begin defining a function. octave_user_function * - base_parser::start_function (tree_parameter_list *param_list, + base_parser::start_function (tree_identifier *id, + tree_parameter_list *param_list, tree_statement_list *body, tree_statement *end_fcn_stmt) { // We'll fill in the return list later. + std::string id_name = id->name (); + + delete id; + + if (lexer.parsing_classdef_get_method) + id_name.insert (0, "get."); + else if (lexer.parsing_classdef_set_method) + id_name.insert (0, "set."); + + lexer.parsing_classdef_get_method = false; + lexer.parsing_classdef_set_method = false; + if (! body) body = new tree_statement_list (); @@ -3273,23 +3291,6 @@ end_fcn_stmt->column ()); } - return fcn; - } - - tree_statement * - base_parser::make_end (const std::string& type, bool eof, int l, int c) - { - return make_statement (new tree_no_op_command (type, eof, l, c)); - } - - // Do most of the work for defining a function. - - octave_user_function * - base_parser::frob_function (const std::string& fname, - octave_user_function *fcn) - { - std::string id_name = fname; - // If input is coming from a file, issue a warning if the name of // the file does not match the name of the function stated in the // file. Matlab doesn't provide a diagnostic (it ignores the stated @@ -3386,6 +3387,12 @@ return fcn; } + tree_statement * + base_parser::make_end (const std::string& type, bool eof, int l, int c) + { + return make_statement (new tree_no_op_command (type, eof, l, c)); + } + tree_function_def * base_parser::finish_function (tree_parameter_list *ret_list, octave_user_function *fcn,
--- a/libinterp/parse-tree/parse.h Wed Jun 21 11:46:31 2017 -0400 +++ b/libinterp/parse-tree/parse.h Wed Jun 21 14:23:47 2017 -0400 @@ -276,17 +276,24 @@ // Define a script. void make_script (tree_statement_list *cmds, tree_statement *end_script); + // Define a function. + tree_function_def * + make_function (token *fcn_tok, tree_parameter_list *ret_list, + tree_identifier *id, tree_parameter_list *param_list, + tree_statement_list *body, tree_statement *end_fcn_stmt, + octave_comment_list *lc); + // Begin defining a function. octave_user_function * - start_function (tree_parameter_list *param_list, tree_statement_list *body, - tree_statement *end_function); + start_function (tree_identifier *id, tree_parameter_list *param_list, + tree_statement_list *body, tree_statement *end_function); // Create a no-op statement for end_function. tree_statement * make_end (const std::string& type, bool eof, int l, int c); // Do most of the work for defining a function. octave_user_function * - frob_function (const std::string& fname, octave_user_function *fcn); + frob_function (tree_identifier *id, octave_user_function *fcn); // Finish defining a function. tree_function_def *