#include "../syntax.h" bool peek_statement(struct bshell_parse_ctx *ctx) { if (peek_keyword_expr(ctx)) { return true; } if (peek_arith_expr(ctx)) { return true; } if (peek_command(ctx)) { return true; } return false; } bool parse_statement(struct bshell_parse_ctx *ctx, struct bshell_ast_node **out) { if (!peek_token(ctx)) { /* error, or EOF */ return false; } bool unknown = true; bool ok = false; if (peek_keyword_expr(ctx)) { unknown = false; ok = parse_keyword_expr(ctx, out); } if (!ok && peek_arith_expr(ctx)) { unknown = false; ok = parse_arith_expr(ctx, BSHELL_PRECEDENCE_MINIMUM, out); } if (!ok && peek_command(ctx)) { unknown = false; ok = parse_command(ctx, out); } if (!ok && unknown) { report_error( ctx, "encountered unknown token while parsing statement"); return false; } return ok; } static struct bshell_ast_node *convert_single_statement( struct bshell_stmt_list_ast_node *list) { fx_queue_entry *first_entry = fx_queue_first(&list->n_statements); if (!first_entry || fx_queue_next(first_entry)) { return (struct bshell_ast_node *)list; } fx_queue_delete(&list->n_statements, first_entry); struct bshell_ast_node *first = fx_unbox(struct bshell_ast_node, first_entry, n_entry); bshell_ast_node_destroy((struct bshell_ast_node *)list); return first; } bool parse_statement_list(struct bshell_parse_ctx *ctx, struct bshell_ast_node **out) { struct bshell_stmt_list_ast_node *stmt_list = (struct bshell_stmt_list_ast_node *)bshell_ast_node_create( BSHELL_AST_STMT_LIST); bool ok = true; while (ok) { parse_linefeed(ctx); struct bshell_ast_node *stmt = NULL; if (!parse_statement(ctx, &stmt)) { ok = false; break; } fx_queue_push_back(&stmt_list->n_statements, &stmt->n_entry); if (!parse_symbol(ctx, BSHELL_SYM_SEMICOLON)) { break; } } if (!ok) { bshell_ast_node_destroy((struct bshell_ast_node *)stmt_list); return false; } *out = convert_single_statement(stmt_list); return true; }