diff --git a/parse_execution.cpp b/parse_execution.cpp index 2b43ccc45..eb162ccdd 100644 --- a/parse_execution.cpp +++ b/parse_execution.cpp @@ -413,7 +413,7 @@ parse_execution_result_t parse_execution_context_t::run_block_statement(const pa const parse_node_t &block_header = *get_child(statement, 0, symbol_block_header); //block header const parse_node_t &header = *get_child(block_header, 0); //specific header type (e.g. for loop) - const parse_node_t &contents = *get_child(statement, 2, symbol_job_list); //block contents + const parse_node_t &contents = *get_child(statement, 1, symbol_job_list); //block contents parse_execution_result_t ret = parse_execution_success; switch (header.type) @@ -428,7 +428,7 @@ parse_execution_result_t parse_execution_context_t::run_block_statement(const pa case symbol_function_header: { - const parse_node_t &function_end = *get_child(statement, 3, symbol_end_command); //the 'end' associated with the block + const parse_node_t &function_end = *get_child(statement, 2, symbol_end_command); //the 'end' associated with the block ret = run_function_statement(header, function_end); break; } diff --git a/parse_productions.cpp b/parse_productions.cpp index 1dd0ab7fb..6ef03f50b 100644 --- a/parse_productions.cpp +++ b/parse_productions.cpp @@ -298,7 +298,7 @@ RESOLVE(freestanding_argument_list) PRODUCTIONS(block_statement) = { - {symbol_block_header, parse_token_type_end, symbol_job_list, symbol_end_command, symbol_arguments_or_redirections_list} + {symbol_block_header, symbol_job_list, symbol_end_command, symbol_arguments_or_redirections_list} }; RESOLVE_ONLY(block_statement) @@ -328,25 +328,35 @@ RESOLVE(block_header) PRODUCTIONS(for_header) = { - {KEYWORD(parse_keyword_for), parse_token_type_string, KEYWORD(parse_keyword_in), symbol_argument_list} + {KEYWORD(parse_keyword_for), parse_token_type_string, KEYWORD + (parse_keyword_in), symbol_argument_list, parse_token_type_end} }; RESOLVE_ONLY(for_header) PRODUCTIONS(while_header) = { - {KEYWORD(parse_keyword_while), symbol_job} + {KEYWORD(parse_keyword_while), symbol_job, parse_token_type_end} }; RESOLVE_ONLY(while_header) PRODUCTIONS(begin_header) = { + {KEYWORD(parse_keyword_begin), parse_token_type_end}, {KEYWORD(parse_keyword_begin)} }; -RESOLVE_ONLY(begin_header) +RESOLVE(begin_header) +{ + switch (token2.type) { + case parse_token_type_end: + return 0; + default: + return 1; + } +} PRODUCTIONS(function_header) = { - {KEYWORD(parse_keyword_function), symbol_argument, symbol_argument_list} + {KEYWORD(parse_keyword_function), symbol_argument, symbol_argument_list, parse_token_type_end} }; RESOLVE_ONLY(function_header) diff --git a/parse_tree.h b/parse_tree.h index 74e9d4360..ff44d8627 100644 --- a/parse_tree.h +++ b/parse_tree.h @@ -249,14 +249,14 @@ bool parse_tree_from_string(const wcstring &str, parse_tree_flags_t flags, parse case_item = CASE argument_list job_list - block_statement = block_header job_list end_command arguments_or_redirections_list - block_header = for_header | while_header | function_header | begin_header - for_header = FOR var_name IN argument_list - while_header = WHILE job - begin_header = BEGIN + block_statement = block_header job_list end_command arguments_or_redirections_list + block_header = for_header | while_header | function_header | begin_header + for_header = FOR var_name IN argument_list + while_header = WHILE job + begin_header = BEGIN | BEGIN # Functions take arguments, and require at least one (the name). No redirections allowed. - function_header = FUNCTION argument argument_list + function_header = FUNCTION argument argument_list # A boolean statement is AND or OR or NOT