Add && and || parsing

This commit is contained in:
savalet
2025-04-16 23:14:33 +02:00
parent e83eb5cf10
commit 67dcfc2f41
3 changed files with 88 additions and 12 deletions

View File

@@ -102,14 +102,23 @@ typedef struct {
extern const tokens_list_t TOKENS_LIST[];
// Main funcs
ast_t *parse_expression(ast_ctx_t *ctx);
void print_ast(ast_ctx_t *ctx, ast_t *ast, size_t depth);
token_t get_next_token(ast_ctx_t *ctx);
int visitor(char *buffer, env_t *env, history_t *history);
// Utils funcs
ast_t *create_node(ast_ctx_t *ctx);
bool ensure_node_cap(ast_t *node);
bool ensure_list_cap(ast_t *node);
bool parser_eat(ast_ctx_t *ctx, token_type_t expected);
ast_t *parse_loop(ast_ctx_t *ctx);
void free_ast(ast_ctx_t *ctx);
void print_ast(ast_t *ast, ast_ctx_t *ctx, size_t depth);
// Outside needed parser
ast_t *parse_cmd(ast_ctx_t *ctx);
ast_t *parse_condition(ast_ctx_t *ctx);
ast_t *parse_and(ast_ctx_t *ctx, ast_t *l_node);
ast_t *parse_or(ast_ctx_t *ctx, ast_t *l_node);
#endif /* AST_H */

View File

@@ -49,12 +49,16 @@ ast_t *fill_cmd_node(ast_ctx_t *ctx)
return parse_arg(ctx, node);
}
static
/*
* Removed this check to do && || if, nothing has changed,
* to be seen in case of trouble,
* putting it back this may solve the problem but will break the && || if
* if (ctx->act_tok.type == T_EOF)
* return ctx->ast;
*/
ast_t *parse_cmd(ast_ctx_t *ctx)
{
if (ctx->act_tok.type == T_EOF)
return ctx->ast;
if (ctx->act_tok.type != T_ARG){
if (ctx->act_tok.type != T_ARG) {
if (ctx->act_tok.type & (T_WHILE | T_FOREACH))
return NULL;
if (!parser_eat(ctx, T_ARG))
@@ -75,7 +79,6 @@ bool parse_pipe_childs(ast_ctx_t *ctx, ast_t *node)
return true;
}
static
ast_t *parse_pipe(ast_ctx_t *ctx, ast_t *l_node)
{
ast_t *node = create_node(ctx);
@@ -98,17 +101,43 @@ ast_t *parse_pipe(ast_ctx_t *ctx, ast_t *l_node)
return node;
}
static
ast_t *parse_semi(ast_ctx_t *ctx)
ast_t *parse_condition(ast_ctx_t *ctx)
{
ast_t *l_node = parse_cmd(ctx);
if (l_node == NULL)
return NULL;
if (ctx->act_tok.type & (T_WHILE | T_FOREACH))
ctx->ast = parse_loop(ctx);
else if (ctx->act_tok.type == T_PIPE)
ctx->ast = parse_pipe(ctx, l_node);
else
return l_node;
else {
switch (ctx->act_tok.type) {
case T_PIPE:
ctx->ast = parse_pipe(ctx, l_node);
break;
default:
return l_node;
}
}
return ctx->ast;
}
static
ast_t *parse_semi(ast_ctx_t *ctx)
{
ast_t *l_node = parse_condition(ctx);
if (l_node == NULL)
return NULL;
switch (ctx->act_tok.type) {
case T_AND:
ctx->ast = parse_and(ctx, l_node);
break;
case T_OR:
ctx->ast = parse_or(ctx, l_node);
break;
default:
return l_node;
}
return ctx->ast;
}

38
src/ast/conditions.c Normal file
View File

@@ -0,0 +1,38 @@
/*
** EPITECH PROJECT, 2025
** __
** File description:
** _
*/
#include "ast.h"
ast_t *parse_and(ast_ctx_t *ctx, ast_t *l_node)
{
ast_t *node = create_node(ctx);
if (node == NULL || l_node == NULL)
return NULL;
node->tok = ctx->act_tok;
node->type = N_BIN;
node->binary.left = l_node;
node->binary.right = parse_condition(ctx);
if (node->binary.right == NULL)
return NULL;
return node;
}
ast_t *parse_or(ast_ctx_t *ctx, ast_t *l_node)
{
ast_t *node = create_node(ctx);
if (node == NULL || l_node == NULL)
return NULL;
node->tok = ctx->act_tok;
node->type = N_BIN;
node->binary.left = l_node;
node->binary.right = parse_condition(ctx);
if (node->binary.right == NULL)
return NULL;
return node;
}