parse: update parser to support new lexer behaviour

This commit is contained in:
2026-05-10 14:19:06 +01:00
parent 5ea41fcc6e
commit ba8a2111eb
5 changed files with 57 additions and 32 deletions
+1 -1
View File
@@ -24,7 +24,7 @@ void parse_ctx_cleanup(struct parse_ctx *ctx)
struct ast_node *parse_ctx_read_node(struct parse_ctx *ctx)
{
struct ast_node *result = NULL;
bool ok = parse_expr(ctx, &result);
bool ok = parse_statement(ctx, &result);
return ok ? result : NULL;
}
+3 -5
View File
@@ -16,22 +16,20 @@ extern struct lex_token *peek_token(struct parse_ctx *ctx);
extern enum token_type peek_token_type(struct parse_ctx *ctx);
extern enum token_keyword peek_unknown_keyword(struct parse_ctx *ctx);
extern enum token_symbol peek_unknown_symbol(struct parse_ctx *ctx);
extern bool peek_int(struct parse_ctx *ctx);
extern struct lex_token *claim_token(struct parse_ctx *ctx);
extern struct lex_token *claim_glob_word(struct parse_ctx *ctx);
extern void discard_token(struct parse_ctx *ctx);
extern bool peek_linefeed(struct parse_ctx *ctx);
extern bool peek_symbol(struct parse_ctx *ctx, enum token_symbol sym);
extern struct lex_token *peek_glob_word(struct parse_ctx *ctx);
extern bool peek_word(struct parse_ctx *ctx, struct lex_token **out);
extern bool peek_int(struct parse_ctx *ctx);
extern bool parse_linefeed(struct parse_ctx *ctx);
extern bool parse_symbol(struct parse_ctx *ctx, enum token_symbol sym);
extern bool parse_keyword(struct parse_ctx *ctx, enum token_keyword kw);
extern bool parse_int(struct parse_ctx *ctx, long long *out);
extern bool parse_flag(struct parse_ctx *ctx, struct lex_token **out);
extern struct lex_token *parse_glob_word(struct parse_ctx *ctx);
extern bool peek_arith_expr(struct parse_ctx *ctx);
extern bool parse_arith_expr(struct parse_ctx *ctx, struct ast_node **out);
@@ -40,7 +38,7 @@ extern bool parse_operand(
enum parse_operand_flags flags,
struct ast_node **out);
extern bool parse_expr(struct parse_ctx *ctx, struct ast_node **out);
extern bool parse_statement(struct parse_ctx *ctx, struct ast_node **out);
extern bool peek_command(struct parse_ctx *ctx);
extern bool parse_command(struct parse_ctx *ctx, struct ast_node **out);
+40 -20
View File
@@ -4,6 +4,10 @@
static bool parse_cmdcall_arg(struct parse_ctx *ctx, struct ast_node **out)
{
if (ctx->p_status != BSHELL_SUCCESS) {
return false;
}
struct lex_token *tok = peek_token(ctx);
if (!tok) {
return false;
@@ -80,19 +84,7 @@ static bool parse_cmdcall_arg(struct parse_ctx *ctx, struct ast_node **out)
return true;
}
default: {
struct word_ast_node *n
= (struct word_ast_node *)ast_node_create(AST_WORD);
if (!n) {
ctx->p_status = BSHELL_ERR_NO_MEMORY;
return false;
}
n->n_value = claim_glob_word(ctx);
*out = (struct ast_node *)n;
return true;
}
default:
return false;
}
@@ -105,6 +97,10 @@ static bool parse_redirect_to_fd(
bool append,
struct ast_node **out)
{
if (ctx->p_status != BSHELL_SUCCESS) {
return false;
}
struct redirection_ast_node *redirect
= (struct redirection_ast_node *)ast_node_create(
AST_REDIRECTION);
@@ -117,18 +113,34 @@ static bool parse_redirect_to_fd(
return false;
}
long long out_fd = 0;
if (!parse_int(ctx, &out_fd)) {
ctx->p_status = BSHELL_ERR_BAD_SYNTAX;
ast_node_destroy((struct ast_node *)redirect);
struct lex_token *out_tok = NULL;
struct ast_node *out_expr = NULL;
long long out_fd = -1;
if (peek_word(ctx, &out_tok)) {
const char *s = out_tok->tok_str;
char *ep;
out_fd = strtoll(s, &ep, 10);
if (*ep == '\0') {
discard_token(ctx);
out_tok = NULL;
} else {
out_fd = -1;
}
} else if (!parse_cmdcall_arg(ctx, &out_expr)) {
return false;
}
redirect->n_out_is_fd = true;
redirect->n_out_is_expr = false;
redirect->n_out_is_fd = (out_fd >= 0) || out_expr;
redirect->n_out_is_expr = out_expr != NULL;
redirect->n_out = (unsigned int)out_fd;
*out = (struct ast_node *)redirect;
redirect->n_out_path_expr = out_expr;
if (out_tok) {
redirect->n_out_tok = claim_token(ctx);
redirect->n_out_path = out_tok->tok_str;
}
*out = (struct ast_node *)redirect;
return true;
}
@@ -139,6 +151,10 @@ static bool parse_redirect_to_file_squashed(
const char *str,
struct ast_node **out)
{
if (ctx->p_status != BSHELL_SUCCESS) {
return false;
}
struct lex_token *tok = peek_token(ctx);
if (*str == '\0') {
return false;
@@ -166,6 +182,10 @@ static bool parse_redirect_to_file_separate(
bool append,
struct ast_node **out)
{
if (ctx->p_status != BSHELL_SUCCESS) {
return false;
}
struct ast_node *out_path = NULL;
if (!parse_cmdcall_arg(ctx, &out_path)) {
ctx->p_status = BSHELL_ERR_BAD_SYNTAX;
+11 -5
View File
@@ -8,11 +8,6 @@ struct lex_token *claim_token(struct parse_ctx *ctx)
return lex_ctx_claim(ctx->p_src);
}
struct lex_token *claim_glob_word(struct parse_ctx *ctx)
{
return lex_ctx_claim_word(ctx->p_src);
}
void discard_token(struct parse_ctx *ctx)
{
return lex_ctx_discard(ctx->p_src);
@@ -43,6 +38,17 @@ enum token_keyword peek_unknown_keyword(struct parse_ctx *ctx)
: KW_NONE;
}
bool peek_word(struct parse_ctx *ctx, struct lex_token **out)
{
struct lex_token *tok = peek_token(ctx);
if (tok && tok->tok_type == TOK_WORD) {
*out = tok;
return true;
}
return false;
}
bool peek_linefeed(struct parse_ctx *ctx)
{
struct lex_token *tok = peek_token(ctx);
@@ -1,11 +1,12 @@
#include "../syntax.h"
bool parse_expr(struct parse_ctx *ctx, struct ast_node **out)
bool parse_statement(struct parse_ctx *ctx, struct ast_node **out)
{
bool ok = false;
if (peek_arith_expr(ctx)) {
ok = parse_arith_expr(ctx, out);
}
if (!ok && peek_command(ctx)) {
ok = parse_command(ctx, out);
}