parse: make multi-line structure parsing more robust
This commit is contained in:
@@ -848,6 +848,7 @@ bool parse_arith_expr(
|
||||
case SYM_DOLLAR_LEFT_PAREN:
|
||||
case SYM_AT_LEFT_PAREN:
|
||||
case SYM_AT_LEFT_BRACE:
|
||||
case SYM_LEFT_BRACE:
|
||||
expr.expr_fail = !parse_operand(ctx, &expr);
|
||||
break;
|
||||
default: {
|
||||
|
||||
@@ -6,23 +6,44 @@ bool parse_block(struct parse_ctx *ctx, struct ast_node **out)
|
||||
return false;
|
||||
}
|
||||
|
||||
parse_linefeed(ctx);
|
||||
|
||||
struct block_ast_node *block
|
||||
= (struct block_ast_node *)ast_node_create(AST_BLOCK);
|
||||
|
||||
bool ok = true;
|
||||
while (1) {
|
||||
if (parse_symbol(ctx, SYM_RIGHT_BRACE)) {
|
||||
break;
|
||||
}
|
||||
|
||||
parse_linefeed(ctx);
|
||||
|
||||
struct ast_node *stmt = NULL;
|
||||
if (!parse_statement(ctx, &stmt)) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
fx_queue_push_back(&block->n_statements, &stmt->n_entry);
|
||||
|
||||
if (parse_symbol(ctx, SYM_RIGHT_BRACE)) {
|
||||
break;
|
||||
}
|
||||
|
||||
struct ast_node *stmt = NULL;
|
||||
if (!parse_statement(ctx, &stmt)) {
|
||||
ast_node_destroy((struct ast_node *)block);
|
||||
return false;
|
||||
if (!parse_linefeed(ctx) && !parse_symbol(ctx, SYM_SEMICOLON)) {
|
||||
report_error(
|
||||
ctx,
|
||||
"expected `;`, `}`, or linefeed after "
|
||||
"statement");
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fx_queue_push_back(&block->n_statements, &stmt->n_entry);
|
||||
if (!ok) {
|
||||
ast_node_destroy((struct ast_node *)block);
|
||||
block = NULL;
|
||||
}
|
||||
|
||||
*out = (struct ast_node *)block;
|
||||
|
||||
@@ -5,8 +5,8 @@ static bool add_branch(
|
||||
struct ast_node *cond,
|
||||
struct ast_node *body)
|
||||
{
|
||||
struct if_branch_ast_node *branch
|
||||
= (struct if_branch_ast_node *)ast_node_create(AST_IF_BRANCH);
|
||||
struct if_branch_ast_node *branch = (struct if_branch_ast_node *)
|
||||
ast_node_create(AST_IF_BRANCH);
|
||||
if (!branch) {
|
||||
return false;
|
||||
}
|
||||
@@ -47,8 +47,8 @@ bool parse_if(struct parse_ctx *ctx, struct ast_node **out)
|
||||
return false;
|
||||
}
|
||||
|
||||
struct if_ast_node *if_group
|
||||
= (struct if_ast_node *)ast_node_create(AST_IF);
|
||||
struct if_ast_node *if_group = (struct if_ast_node *)ast_node_create(
|
||||
AST_IF);
|
||||
if (!if_group) {
|
||||
ctx->p_status = BSHELL_ERR_NO_MEMORY;
|
||||
ast_node_destroy(if_cond);
|
||||
@@ -70,6 +70,13 @@ bool parse_if(struct parse_ctx *ctx, struct ast_node **out)
|
||||
if (parse_keyword(ctx, KW_ELSE)) {
|
||||
done = true;
|
||||
} else if (parse_keyword(ctx, KW_ELSEIF)) {
|
||||
if (!parse_symbol(ctx, SYM_LEFT_PAREN)) {
|
||||
report_error(
|
||||
ctx,
|
||||
"expected `(` after `elseif`");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parse_expr(ctx, &cond)) {
|
||||
report_error(
|
||||
ctx,
|
||||
@@ -77,6 +84,14 @@ bool parse_if(struct parse_ctx *ctx, struct ast_node **out)
|
||||
ast_node_destroy((struct ast_node *)if_group);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parse_symbol(ctx, SYM_RIGHT_PAREN)) {
|
||||
report_error(
|
||||
ctx,
|
||||
"expected `)` after elseif-condition");
|
||||
ast_node_destroy(if_cond);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
done = true;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user