From 8122ecfc9530ec4d26e653c1acaddd0e2f83d541 Mon Sep 17 00:00:00 2001 From: maix0 Date: Sat, 12 Oct 2024 16:13:02 +0200 Subject: [PATCH] normed: everything except yarn_cmd.c and token_name.c --- parser/Filelist.parser.mk | 1 + parser/src/token_utils.c | 6 +- parser/src/tokenizer_utils.c | 2 +- parser/src/yarn/ast_op.c | 26 ++--- parser/src/yarn/yarn.c | 179 +++++++++++++++++++---------------- parser/src/yarn/yarn_utils.c | 24 +++++ 6 files changed, 139 insertions(+), 99 deletions(-) create mode 100644 parser/src/yarn/yarn_utils.c diff --git a/parser/Filelist.parser.mk b/parser/Filelist.parser.mk index bb3b0f50..315c1a07 100644 --- a/parser/Filelist.parser.mk +++ b/parser/Filelist.parser.mk @@ -23,6 +23,7 @@ ts_print \ yarn/ast_cmd \ yarn/ast_op \ yarn/yarn \ +yarn/yarn_utils \ GEN_FILES = \ \ diff --git a/parser/src/token_utils.c b/parser/src/token_utils.c index 1f44f4c1..68b74ce1 100644 --- a/parser/src/token_utils.c +++ b/parser/src/token_utils.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/06 13:33:12 by maiboyer #+# #+# */ -/* Updated: 2024/10/08 14:51:41 by maiboyer ### ########.fr */ +/* Updated: 2024/10/12 15:54:49 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,7 +14,6 @@ #include "parser/token.h" #include - t_str token_name(t_token *token); t_token token_clone(t_token *tok) @@ -34,7 +33,8 @@ t_token token_clone(t_token *tok) ret.subtokens = vec_token_new(tok->subtokens.capacity, token_free); i = 0; while (i < tok->subtokens.len) - vec_token_push(&ret.subtokens, token_clone(&tok->subtokens.buffer[i++])); + vec_token_push(&ret.subtokens, token_clone(\ + &tok->subtokens.buffer[i++])); } return (ret); } diff --git a/parser/src/tokenizer_utils.c b/parser/src/tokenizer_utils.c index dd48b666..617b6f35 100644 --- a/parser/src/tokenizer_utils.c +++ b/parser/src/tokenizer_utils.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/03 22:07:25 by maiboyer #+# #+# */ -/* Updated: 2024/10/06 13:25:32 by maiboyer ### ########.fr */ +/* Updated: 2024/10/12 15:54:39 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/parser/src/yarn/ast_op.c b/parser/src/yarn/ast_op.c index a7dd0818..b4b10547 100644 --- a/parser/src/yarn/ast_op.c +++ b/parser/src/yarn/ast_op.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/09 12:44:53 by maiboyer #+# #+# */ -/* Updated: 2024/10/10 17:26:38 by maiboyer ### ########.fr */ +/* Updated: 2024/10/12 15:55:51 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,7 +16,7 @@ #include "me/vec/vec_token.h" #include "parser/token.h" -static enum e_ast_list_kind _ast_list_get_op(enum e_token ty) +static enum e_ast_list_kind _ast_list_get_op(enum e_token ty) { if (ty == TOK_AND) return (AST_LIST_AND); @@ -26,9 +26,10 @@ static enum e_ast_list_kind _ast_list_get_op(enum e_token ty) return (-1); } -static t_error _tok_pipeline(t_vec_ast *output_queue, t_ast_node rhs, t_ast_node lhs) +static inline t_error _tok_pipeline(\ + t_vec_ast *output_queue, t_ast_node rhs, t_ast_node lhs) { - t_ast_node ret; + t_ast_node ret; if (rhs->kind == AST_PIPELINE) { @@ -51,8 +52,10 @@ static t_error _tok_pipeline(t_vec_ast *output_queue, t_ast_node rhs, t_ast_node } /// en fonction de op, qui peut etre: TOK_AND TOK_PIPE TOK_OR -/// choisir le bon ast_node a faire (t_ast_node->data.list + set operator ou t_asdt_node->data.pipeline) -/// pop deux element de output_queue. pour l'instant la fonction doit print une error si il n'y as pas asser d'element +/// choisir le bon ast_node a faire (t_ast_node->data.list + set operator ou +/// t_asdt_node->data.pipeline) +/// pop deux element de output_queue. pour l'instant la fonction doit print une +/// error si il n'y as pas asser d'element /// utilise me_abort(MSG) pour faire un abort et print le msg + la stacktrace. /// /// a terme la fonction utilisera t_error et tt; @@ -62,13 +65,14 @@ static t_error _tok_pipeline(t_vec_ast *output_queue, t_ast_node rhs, t_ast_node /// `ast/include/ast/_raw_structs.h` /// /// -/// in the end we should change to using `t_error` and pushing the ast_node directly to output_queue in the function, +/// in the end we should change to using `t_error` and pushing the ast_node +/// directly to output_queue in the function, /// will change that later tho :) -t_error ast_from_op(t_token tok, t_vec_ast *output_queue) +t_error ast_from_op(t_token tok, t_vec_ast *output_queue) { - t_ast_node ret; - t_ast_node lhs; - t_ast_node rhs; + t_ast_node ret; + t_ast_node lhs; + t_ast_node rhs; if (!(tok.type == TOK_AND || tok.type == TOK_OR || tok.type == TOK_PIPE)) return (ERROR); diff --git a/parser/src/yarn/yarn.c b/parser/src/yarn/yarn.c index 7a3bac5e..8c7e3b22 100644 --- a/parser/src/yarn/yarn.c +++ b/parser/src/yarn/yarn.c @@ -6,108 +6,119 @@ /* By: rparodi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/07 18:04:13 by rparodi #+# #+# */ -/* Updated: 2024/10/10 17:28:21 by maiboyer ### ########.fr */ +/* Updated: 2024/10/12 16:11:10 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "ast/ast.h" +#include "me/printf/printf.h" +#include "me/printf/printf.h" #include "me/types.h" #include "me/vec/vec_token.h" #include "parser/token.h" #include -int _get_precedance(t_token *token) +int _get_prec(t_token *token); +t_str token_name(t_token *token); +t_error ast_from_cmd(t_token tok, t_vec_ast *output_queue); +t_error ast_from_op(t_token tok, t_vec_ast *output_queue); + +t_error _yarn_parenthesis(\ + t_token tok, t_vec_token *stack, t_vec_ast *output_queue) { - if (!token) - return (-1); - else if (token->type == TOK_PIPE) - return (2); - else if (token->type == TOK_AND || token->type == TOK_OR) - return (1); - return (0); -} -t_str token_name(t_token *token); - -/// la fonction doit prendre une t_token de type TOK_CMD qui contient que deux type de subtokens TOK_WORD ou TOK_REDIR -/// un TOK_WORD == un arguemnt -/// un TOK_REDIR == une redirection -/// les deux sont dans le bonne ordre. -/// il faut push les TOK_REDIR dans ast_node->data.command.prefix; -/// let TOK_WORD dans ast_node->data.command.arguements; -/// les noms peuvent etre different idk -/// a terme la fonction utilisera t_error et tt; -/// struct s_ast_command `ast/include/ast/_raw_structs.h` -t_error ast_from_cmd(t_token tok, t_vec_ast *output_queue); - -/// en fonction de op, qui peut etre: TOK_AND TOK_PIPE TOK_OR -/// choisir le bon ast_node a faire (t_ast_node->data.list + set operator ou t_asdt_node->data.pipeline) -/// pop deux element de output_queue. pour l'instant la fonction doit print une error si il n'y as pas asser d'element -/// utilise me_abort(MSG) pour faire un abort et print le msg + la stacktrace. -/// -/// a terme la fonction utilisera t_error et tt; -/// -/// struct s_ast_list if (tok.type == TOK_AND || tok.type == TOK_OR) -/// struct s_ast_pipeline if (tok.type == TOK_PIPE) -/// `ast/include/ast/_raw_structs.h` -t_error ast_from_op(t_token tok, t_vec_ast *output_queue); - -t_error yarn(t_vec_token ts, t_vec_ast *out) -{ - t_token tok; t_token op; - t_vec_ast output_queue; - t_vec_token stack; + t_ast_node snode; + t_ast_node tmp; - output_queue = vec_ast_new(16, ast_free); - stack = vec_token_new(16, token_free); - while (!vec_token_pop_front(&ts, &tok)) + token_free(tok); + while (vec_token_last(stack) != NULL && \ + vec_token_last(stack)->type != TOK_LPAREN) { - if (tok.type == TOK_CMD) - { - if (ast_from_cmd(tok, &output_queue)) - return (vec_token_free(stack), vec_ast_free(output_queue), token_free(tok), ERROR); - } - else if (tok.type == TOK_LPAREN) - vec_token_push(&stack, tok); - else if (tok.type == TOK_OR || tok.type == TOK_AND || tok.type == TOK_PIPE) - { - while (vec_token_last(&stack) != NULL && vec_token_last(&stack)->type != TOK_LPAREN && _get_precedance(vec_token_last(&stack)) > _get_precedance(&tok)) - { - vec_token_pop(&stack, &op); - if (ast_from_op(op, &output_queue)) - return (vec_token_free(stack), vec_ast_free(output_queue), token_free(tok), token_free(op), ERROR); - } - vec_token_push(&stack, tok); - } - else if (tok.type == TOK_RPAREN) - { - token_free(tok); - while (vec_token_last(&stack) != NULL && vec_token_last(&stack)->type != TOK_LPAREN) - { - vec_token_pop(&stack, &op); - if (ast_from_op(op, &output_queue)) - return (vec_token_free(stack), vec_ast_free(output_queue), token_free(op), ERROR); - } - if (!(vec_token_last(&stack) != NULL && vec_token_last(&stack)->type == TOK_LPAREN)) - return (vec_token_free(stack), vec_ast_free(output_queue), ERROR); - vec_token_pop(&stack, &tok); - token_free(tok); - t_ast_node snode; - t_ast_node tmp; - snode = ast_alloc(AST_SUBSHELL); - vec_ast_pop(&output_queue, &tmp); - vec_ast_push(&snode->data.subshell.body, tmp); - vec_ast_push(&output_queue, snode); - } + vec_token_pop(stack, &op); + if (ast_from_op(op, output_queue)) + return (token_free(op), ERROR); } + if (!(vec_token_last(stack) != NULL && \ + vec_token_last(stack)->type == TOK_LPAREN)) + return (ERROR); + vec_token_pop(stack, &tok); + token_free(tok); + snode = ast_alloc(AST_SUBSHELL); + vec_ast_pop(output_queue, &tmp); + vec_ast_push(&snode->data.subshell.body, tmp); + vec_ast_push(output_queue, snode); + return (NO_ERROR); +} + +t_error _yarn_operator(t_token tok, t_vec_token *stack, t_vec_ast *output_queue) +{ + t_token op; + + while (vec_token_last(stack) != NULL && vec_token_last(stack)->type \ + != TOK_LPAREN && _get_prec(vec_token_last(stack)) > _get_prec(&tok)) + { + vec_token_pop(stack, &op); + if (ast_from_op(op, output_queue)) + return (token_free(tok), token_free(op), ERROR); + } + vec_token_push(stack, tok); + return (NO_ERROR); +} + +t_error _yarn_final(t_vec_token stack, t_vec_ast output_q, t_vec_ast *out) +{ + t_token op; + while (!vec_token_pop(&stack, &op)) { if (op.type == TOK_LPAREN) return (token_free(op), ERROR); - if (ast_from_op(op, &output_queue)) - return (vec_token_free(stack), vec_ast_free(output_queue), token_free(op), ERROR); + if (ast_from_op(op, &output_q)) + return (vec_token_free(stack), vec_ast_free(output_q), \ + token_free(op), ERROR); + } + vec_token_free(stack); + return (*out = output_q, NO_ERROR); +} + +t_error _yarn_loop(t_token tok, t_vec_token *stack, t_vec_ast *output_q) +{ + if (tok.type == TOK_CMD) + { + if (ast_from_cmd(tok, output_q)) + return (ERROR); + } + else if (tok.type == TOK_OR \ + || tok.type == TOK_AND || tok.type == TOK_PIPE) + { + if (_yarn_operator(tok, stack, output_q)) + return (ERROR); + } + else if (tok.type == TOK_RPAREN) + { + if (_yarn_parenthesis(tok, stack, output_q)) + return (ERROR); + } + else if (tok.type == TOK_LPAREN) + vec_token_push(stack, tok); + else + return (me_eprintf("Syntax Error\n"), ERROR); + return (NO_ERROR); +} + +t_error yarn(t_vec_token ts, t_vec_ast *out) +{ + t_token tok; + t_vec_ast output_q; + t_vec_token stack; + + output_q = vec_ast_new(16, ast_free); + stack = vec_token_new(16, token_free); + while (!vec_token_pop_front(&ts, &tok)) + { + if (_yarn_loop(tok, &stack, &output_q)) + return (vec_token_free(stack), vec_ast_free(output_q), ERROR); } vec_token_free(ts); - vec_token_free(stack); - return (*out = output_queue, NO_ERROR); + return (_yarn_final(stack, output_q, out)); } diff --git a/parser/src/yarn/yarn_utils.c b/parser/src/yarn/yarn_utils.c new file mode 100644 index 00000000..e651da5f --- /dev/null +++ b/parser/src/yarn/yarn_utils.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* yarn_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/10/12 16:11:05 by maiboyer #+# #+# */ +/* Updated: 2024/10/12 16:11:19 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "parser/token.h" + +int _get_prec(t_token *token) +{ + if (!token) + return (-1); + else if (token->type == TOK_PIPE) + return (2); + else if (token->type == TOK_AND || token->type == TOK_OR) + return (1); + return (0); +}