# HG changeset patch # User John W. Eaton # Date 1712988872 14400 # Node ID 29c07704f1200ff27482dcb17c1b35c52a780615 # Parent 6714a426f48466c452d7b031395a91b88b2c3e2b refactor parse rules for function/script and classdef files * lex.ll (base_lexer::handle_token): Also conditionally set m_arguments_is_keyword to false. * oct-parse.yy (arguments_block_list): Rename from function_body1. (file): Use statement_list instead of "opt_nl opt_list" in ordinary function/script rule and "opt_sep" instead of "opt_nl" in classdef rule. (function): Eliminate opt_sep from rules. (function_body): Eliminate at_first_executable_stmt from rules. (at_first_executable_stmt, opt_nl, nl): Delete now unused nonterminal type declarations and rules. diff -r 6714a426f484 -r 29c07704f120 libinterp/parse-tree/lex.ll --- a/libinterp/parse-tree/lex.ll Fri Apr 12 14:52:31 2024 -0400 +++ b/libinterp/parse-tree/lex.ll Sat Apr 13 02:14:32 2024 -0400 @@ -3944,7 +3944,13 @@ { push_token (tok); - return count_token_internal (tok->token_id ()); + int tok_id = tok->token_id (); + + if (m_arguments_is_keyword + && ! (tok_id == ';' || tok_id == ',' || tok_id == '\n')) + m_arguments_is_keyword = false; + + return count_token_internal (tok_id); } int diff -r 6714a426f484 -r 29c07704f120 libinterp/parse-tree/oct-parse.yy --- a/libinterp/parse-tree/oct-parse.yy Fri Apr 12 14:52:31 2024 -0400 +++ b/libinterp/parse-tree/oct-parse.yy Sat Apr 13 02:14:32 2024 -0400 @@ -246,11 +246,11 @@ // Nonterminals we construct. %type push_fcn_symtab push_script_symtab begin_file %type stmt_begin anon_fcn_begin -%type parsing_local_fcns parse_error at_first_executable_stmt +%type parsing_local_fcns parse_error %type param_list_beg param_list_end %type function_beg classdef_beg arguments_beg indirect_ref_op %type properties_beg methods_beg events_beg enumeration_beg -%type sep_no_nl opt_sep_no_nl nl opt_nl sep opt_sep +%type sep_no_nl opt_sep_no_nl sep opt_sep %type input %type string constant magic_colon %type anon_fcn_handle @@ -285,9 +285,9 @@ %type decl_init_list %type declaration %type statement function_end -%type statement_list %type simple_list simple_list1 list list1 -%type opt_list function_body function_body1 +%type statement_list opt_list +%type arguments_block_list function_body %type opt_fcn_list fcn_list fcn_list1 %type attr %type attr_list attr_list1 @@ -473,6 +473,7 @@ $$ = $2; } ; + opt_list : // empty { $$ = nullptr; } | list @@ -1405,12 +1406,8 @@ { $$ = 0; } ; -file : begin_file opt_nl opt_list END_OF_INPUT +file : begin_file statement_list END_OF_INPUT { - // FIXME: Need to capture separator list here. - // For now, delete the unused list. - delete $2; - if (lexer.m_reading_fcn_file) { // Delete the dummy statement_list we created @@ -1422,13 +1419,13 @@ // Unused symbol table context. lexer.m_symtab_context.pop (); - delete $3; + delete $2; } else { - octave::tree_statement *end_of_script = parser.make_end ("endscript", true, $4); - - parser.make_script ($3, end_of_script); + octave::tree_statement *end_of_script = parser.make_end ("endscript", true, $3); + + parser.make_script ($2, end_of_script); } if (! parser.validate_primary_fcn ()) @@ -1436,8 +1433,17 @@ $$ = nullptr; } - | begin_file opt_nl classdef parsing_local_fcns opt_sep opt_fcn_list END_OF_INPUT + | begin_file opt_sep classdef parsing_local_fcns opt_sep opt_fcn_list END_OF_INPUT { + // We need to skip whitespace before the classdef + // keyword. The opt_sep rule is more liberal than + // we need to be because it accepts ';' and ',' in + // addition to '\n', but we need to use it to avoid + // creating a reduce/reduce conflict with the rule + // above. Matching the extra ';' and ',' characters + // doesn't cause trouble because the lexer ensures + // that classdef is the first token in the file. + // FIXME: Need to capture separator lists here. // For now, delete the unused lists. delete $2; @@ -1542,48 +1548,34 @@ } ; -function : function_beg fcn_name opt_param_list opt_sep function_body function_end +function : function_beg fcn_name opt_param_list function_body function_end { - // FIXME: Need to capture separator list here. - // For now, delete the unused list. - delete $4; - - $$ = parser.make_function ($1, nullptr, nullptr, $2, $3, $5, $6); + $$ = parser.make_function ($1, nullptr, nullptr, $2, $3, $4, $5); } - | function_beg return_list '=' fcn_name opt_param_list opt_sep function_body function_end + | function_beg return_list '=' fcn_name opt_param_list function_body function_end { - // FIXME: Need to capture separator list here. - // For now, delete the unused list. - delete $6; - - $$ = parser.make_function ($1, $2, $3, $4, $5, $7, $8); + $$ = parser.make_function ($1, $2, $3, $4, $5, $6, $7); } ; -function_body : at_first_executable_stmt opt_list - { $$ = $2; } - | function_body1 opt_sep at_first_executable_stmt opt_list +function_body : statement_list { - // FIXME: Need to capture separator list here. - // For now, delete the unused list. - delete $2; - - $$ = parser.append_function_body ($1, $4); + $$ = $1; + } + | opt_sep arguments_block_list statement_list + { + $$ = parser.append_function_body ($2, $3); } ; -at_first_executable_stmt - : // empty - { lexer.m_arguments_is_keyword = false; } - ; - -function_body1 : arguments_block +arguments_block_list + : arguments_block { octave::tree_statement *stmt = parser.make_statement ($1); $$ = parser.make_statement_list (stmt); } - | function_body1 opt_sep arguments_block + | arguments_block_list opt_sep arguments_block { octave::tree_statement *stmt = parser.make_statement ($3); @@ -1611,6 +1603,7 @@ arguments_beg : ARGUMENTS { $$ = $1; + lexer.m_arguments_is_keyword = false; } ; @@ -2173,18 +2166,6 @@ { $$ = $1; } ; -opt_nl : // empty - { $$ = 0; } - | nl - { $$ = $1; } - ; - -nl : '\n' - { $$ = new octave::separator_list (*($1)); } - | nl '\n' - { $$ = $1->append (*($2)); } - ; - sep : ',' { $$ = new octave::separator_list (*($1)); } | ';'