From 0fbfee7d786b4838f7074af56d9e065dfb822dfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kha=C3=AFs=20COLIN?= Date: Thu, 20 Mar 2025 12:17:54 +0100 Subject: [PATCH] cmdgroup parsing: parse cmdlist surrounded by parentheses --- Makefile | 3 +- src/parser/cmdgroup/cmdgroup.c | 19 ++++++- src/parser/cmdgroup/cmdgroup_builder.c | 22 +++++++- src/parser/cmdgroup/cmdgroup_builder.h | 11 +++- src/parser/cmdgroup/paren.c | 23 +++++++++ src/parser/cmdgroup/paren.h | 25 +++++++++ test.sh | 71 ++++++++++++++++++++++++++ 7 files changed, 169 insertions(+), 5 deletions(-) create mode 100644 src/parser/cmdgroup/paren.c create mode 100644 src/parser/cmdgroup/paren.h diff --git a/Makefile b/Makefile index 501c262..c59fd89 100644 --- a/Makefile +++ b/Makefile @@ -30,8 +30,9 @@ srcs = \ src/executing/here_doc/strip_newline.c \ src/ft_errno.c \ src/get_command.c \ - src/parser/cmdgroup/cmdgroup_builder.c \ src/parser/cmdgroup/cmdgroup.c \ + src/parser/cmdgroup/cmdgroup_builder.c \ + src/parser/cmdgroup/paren.c \ src/parser/cmdlist/cmdlist.c \ src/parser/cmdlist/cmdlist_builder.c \ src/parser/cmdlist/cmdlist_debug.c \ diff --git a/src/parser/cmdgroup/cmdgroup.c b/src/parser/cmdgroup/cmdgroup.c index d02412c..8e25436 100644 --- a/src/parser/cmdgroup/cmdgroup.c +++ b/src/parser/cmdgroup/cmdgroup.c @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/11 15:18:02 by khais #+# #+# */ -/* Updated: 2025/03/20 12:27:57 by khais ### ########.fr */ +/* Updated: 2025/03/20 14:46:25 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,14 +14,25 @@ #include "cmdgroup_builder.h" #include #include "libft.h" +#include "paren.h" #include "../../treedrawing.h" #include "../../postprocess/redirections/redirection_list.h" #include "libft/libft.h" +/* +** Recursively parse a cmdgroup +** +** This is responsible for parsing one optional set of parentheses surrounding a +** cmdlist. +** +** If parentheses are present, also parse redirections, which may only occur +** after the closing parenthesis. +*/ t_cmdgroup *cmdgroup_from_wordlist(t_wordlist *wordlist) { t_cmdgroup_builder builder; t_wordlist *words; + t_paren paren; words = wordlist_copy(wordlist); if (words == NULL) @@ -30,7 +41,11 @@ t_cmdgroup *cmdgroup_from_wordlist(t_wordlist *wordlist) return (wordlist_destroy(words), NULL); while (builder.error == false && builder.current_word != NULL) { - cmdgroup_builder_next_word(&builder, &words); + paren = match_paren(builder.current_word->word); + if (paren == PAREN_INVALID) + cmdgroup_builder_next_word(&builder, &words); + else + cmdgroup_builder_paren(&builder, &words, paren); } if (builder.current_wordlist != NULL) cmdgroup_builder_delimit(&builder, &words); diff --git a/src/parser/cmdgroup/cmdgroup_builder.c b/src/parser/cmdgroup/cmdgroup_builder.c index 46c8394..3b9d843 100644 --- a/src/parser/cmdgroup/cmdgroup_builder.c +++ b/src/parser/cmdgroup/cmdgroup_builder.c @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/20 12:32:14 by khais #+# #+# */ -/* Updated: 2025/03/20 12:49:37 by khais ### ########.fr */ +/* Updated: 2025/03/20 17:19:55 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -51,3 +51,23 @@ void cmdgroup_builder_delimit(t_cmdgroup_builder *builder, builder->current_wordlist = NULL; (void)words; } + +/* +** discard the current word +*/ +void cmdgroup_builder_discard_word(t_cmdgroup_builder *builder, + t_wordlist **words) +{ + worddesc_destroy(builder->current_word); + builder->current_word = wordlist_pop(words); +} + +/* +** Handle encountering a parenthesis token +*/ +void cmdgroup_builder_paren(t_cmdgroup_builder *builder, + t_wordlist **words, t_paren paren) +{ + cmdgroup_builder_discard_word(builder, words); + (void)paren; +} diff --git a/src/parser/cmdgroup/cmdgroup_builder.h b/src/parser/cmdgroup/cmdgroup_builder.h index 8ff0676..b3120a8 100644 --- a/src/parser/cmdgroup/cmdgroup_builder.h +++ b/src/parser/cmdgroup/cmdgroup_builder.h @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/20 12:27:20 by khais #+# #+# */ -/* Updated: 2025/03/20 12:50:09 by khais ### ########.fr */ +/* Updated: 2025/03/20 17:12:52 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,6 +15,7 @@ # include "../wordlist/wordlist.h" # include "cmdgroup.h" +# include "paren.h" typedef struct s_cmdgroup_builder { @@ -34,6 +35,12 @@ typedef struct s_cmdgroup_builder ** cmdgroup that is being constructed */ t_cmdgroup *cmdgroup; + /* + ** count of parenthesis tokens + ** + ** +1 for each opening parenthesis, -1 for each closing + */ + int paren; } t_cmdgroup_builder; t_cmdgroup_builder *setup_cmdgroup_builder(t_cmdgroup_builder *builder, @@ -42,5 +49,7 @@ void cmdgroup_builder_next_word(t_cmdgroup_builder *builder, t_wordlist **words); void cmdgroup_builder_delimit(t_cmdgroup_builder *builder, t_wordlist **words); +void cmdgroup_builder_paren(t_cmdgroup_builder *builder, + t_wordlist **words, t_paren paren); #endif // CMDGROUP_BUILDER_H diff --git a/src/parser/cmdgroup/paren.c b/src/parser/cmdgroup/paren.c new file mode 100644 index 0000000..c3597ca --- /dev/null +++ b/src/parser/cmdgroup/paren.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* paren.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: khais +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/20 14:48:55 by khais #+# #+# */ +/* Updated: 2025/03/20 14:49:46 by khais ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "paren.h" +#include "libft.h" + +t_paren match_paren(char *word) +{ + if (ft_strcmp("(", word) == 0) + return (PAREN_OPEN); + if (ft_strcmp(")", word) == 0) + return (PAREN_CLOSE); + return (PAREN_INVALID); +} diff --git a/src/parser/cmdgroup/paren.h b/src/parser/cmdgroup/paren.h new file mode 100644 index 0000000..7e15a6a --- /dev/null +++ b/src/parser/cmdgroup/paren.h @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* paren.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: khais +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/20 14:45:48 by khais #+# #+# */ +/* Updated: 2025/03/20 14:48:00 by khais ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef PAREN_H +# define PAREN_H + +typedef enum e_paren +{ + PAREN_INVALID, + PAREN_OPEN, + PAREN_CLOSE, +} t_paren; + +t_paren match_paren(char *word); + +#endif // PAREN_H diff --git a/test.sh b/test.sh index 99fb800..5293964 100755 --- a/test.sh +++ b/test.sh @@ -192,4 +192,75 @@ expecting <> append | echo < infile bye && echo hello > outfile) +EOF +expecting <