From f43778fb9a68d86528d1c4831e57555ba5fa0874 Mon Sep 17 00:00:00 2001 From: Lukas Jiriste Date: Fri, 3 May 2024 16:11:26 +0200 Subject: [PATCH] Create the structure for input handling Create prototypes of some needed types (token, parse tree) and create the structure of the input processing with empty functions. Also add a grammar for minishell inside a comment in parsing.h. This is a simplification of the grammar of Shell programming language as it is laid out inside The Open Group Base Specifications Issue 7, 2018 edition Chapter 2. Shell Command Language found on site https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html --- Makefile | 8 +- inc/minishell.h | 4 +- inc/parsing.h | 199 +++++++++++++++++++++++++++++++++++++++++++ src/execution.c | 19 +++++ src/input_handling.c | 60 +++++++++++++ src/main.c | 7 +- src/parsing.c | 19 +++++ src/tree.c | 25 ++++++ 8 files changed, 332 insertions(+), 9 deletions(-) create mode 100644 inc/parsing.h create mode 100644 src/execution.c create mode 100644 src/input_handling.c create mode 100644 src/parsing.c create mode 100644 src/tree.c diff --git a/Makefile b/Makefile index 48ae981..0430610 100644 --- a/Makefile +++ b/Makefile @@ -14,8 +14,12 @@ INCLUDE := $(addprefix -I, $(INCDIR)) SRCDIR := src -SOURCES := main.c \ - vars.c \ +SOURCES := main.c \ + vars.c \ + input_handling.c \ + tree.c \ + parsing.c \ + execution.c \ SOURCES := $(addprefix $(SRCDIR)/, $(SOURCES)) diff --git a/inc/minishell.h b/inc/minishell.h index 06a02cc..68727cf 100644 --- a/inc/minishell.h +++ b/inc/minishell.h @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/02 13:22:57 by ljiriste #+# #+# */ -/* Updated: 2024/05/02 13:25:41 by ljiriste ### ########.fr */ +/* Updated: 2024/05/03 13:01:59 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,4 +26,6 @@ int add_var_line(t_vec *vec, const char *line); int add_var(t_vec *vec, const char *key, const char *value); void clean_vars(t_vars *vars); +void handle_input(const char *line, t_vars *vars); + #endif // MINISHELL_H diff --git a/inc/parsing.h b/inc/parsing.h new file mode 100644 index 0000000..b96937f --- /dev/null +++ b/inc/parsing.h @@ -0,0 +1,199 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parsing.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/05/03 15:24:31 by ljiriste #+# #+# */ +/* Updated: 2024/05/03 16:20:14 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef PARSING_H +# define PARSING_H + +# include "minishell.h" +# include "libft.h" + +/* +// As this is a minishell I used the +// The Open Group Base Specifications Issue 7, 2018 edition +// chapter 2. Shell Command Language as a main source. +// which can be found at the address +// https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html +// Because minishell is mini, I trim the grammar quite a bit, +// so I think it appropriate to include the grammar here: + +Grammar Rules: + 2. Redirection to or from file + Variable expansion and quote removal + 3. Redirection from here-document + Quote removal + 7. Assignment preceding command name + a. First word + If the TOKEN contains the character '=', a WORD is returned + otherwise use rule 7b. + b. Not the first word + If TOKEN contaion unqouted '=' character: + - if characters before '=' form valid name* + an ASSIGNMENT_WORD is returned + - otherwise a WORD is returned + +* A valid name consists solely of underscores, digits and alphabetics + from the porable character set. The first character of a valid name + is not a digit. + + +Grammar symbols: + + WORD + ASSIGNMENT_WORD + IO_NUMBER + + AND_IF '&&' + OR_IF '||' + + LESS '<' + GREAT '>' + DLESS '<<' + DGREAT '>>' + + PIPE '|' + + LPARA '(' + RPARA ')' + +The grammar: + +filename : WORD // Rule 2 + ; +io_file : LESS filename + | GREAT filename + | DGREAT filename + ; +here_end : WORD // Rule 3 + ; +io_here : DLESS here_end + ; +io_redirect : io_file + | IO_NUMBER io_file + | io_here + | IO_NUMBER io_here + ; +cmd_name : WORD // Rule 7a + ; +cmd_word : WORD // Rule 7b + ; +cmd_prefix : io_redirect + | cmd_prefix io_redirect + | ASSIGNMENT_WORD + | cmd_prefix ASSIGNMENT_WORD + ; +cmd_suffix : io_redirect + | cmd_suffix io_redirect + | WORD + | cmd_suffix WORD + ; +simple_command : cmd_prefix cmd_word cmd_suffix + | cmd_prefix cmd_word + | cmd_prefix + | cmd_name cmd_suffix + | cmd_name + ; +comp_command : LPARA program RPARA + ; +command : simple_command + | comp_command + ; +pipeline : command + | pipeline PIPE command + ; +program : pipeline + | program AND_IF pipeline + | program OR_IF pipeline + ; + + +Form for parse table generator: + +program -> program && pipeline +program -> program || pipeline +program -> pipeline +pipeline -> command +pipeline -> pipeline | command +command -> simple_command +command -> comp_command +comp_command -> ( program ) +simple_command -> cmd_prefix cmd_word cmd_suffix +simple_command -> cmd_prefix cmd_word +simple_command -> cmd_prefix +simple_command -> cmd_name cmd_suffix +simple_command -> cmd_name +cmd_suffix -> io_redirect +cmd_suffix -> cmd_suffix io_redirect +cmd_suffix -> WORD +cmd_suffix -> cmd_suffix WORD +cmd_prefix -> io_redirect +cmd_prefix -> cmd_prefix io_redirect +cmd_prefix -> ASSIGNMENT_WORD +cmd_prefix -> cmd_prefix ASSIGNMENT_WORD +cmd_word -> WORD +cmd_name -> WORD +io_redirect -> io_file +io_redirect -> IO_NUMBER io_file +io_redirect -> io_here +io_redirect -> IO_NUMBER io_here +io_here -> << here_end +here_end -> WORD +io_file -> < filename +io_file -> > filename +io_file -> >> filename +filename -> WORD + +*/ + +// Common type for WORD, ASSIGNMENT_WORD and IO_NUMBER is TOKEN. +// The TOKEN type is identifies as WORD, ASSIGNMENT_WORD or IO_NUMBER +// after tokenization itself +typedef enum e_token_type +{ + TOKEN, + WORD, + ASSIGNMENT_WORD, + IO_NUMBER, + AND_IF, + OR_IF, + LESS, + GREAT, + DLESS, + DGREAT, + PIPE, + LPARA, + RPARA, +} t_token_type; + +// Only TOKEN (WORD, ASSIGNMENT_WORD, IO_NUMBER) type tokens +// have the str member non-empty +typedef struct s_token +{ + t_token_type type; + t_vec str; +} t_token; + +typedef struct s_tree_node +{ + t_token token; + struct s_tree_node *children[3]; +} t_tree_node; + +typedef t_tree_node t_tree; + +void handle_input(const char *input, t_vars *vars); +int parse(t_vec *tokens, t_tree_node *parse_tree, t_vars *vars); +int execute(t_tree *parse_tree, t_vars *vars); + +int init_tree(t_tree *tree); +void free_tree(t_tree *tree); + +#endif // PARSING_H diff --git a/src/execution.c b/src/execution.c new file mode 100644 index 0000000..d350ec0 --- /dev/null +++ b/src/execution.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* execution.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/05/03 15:59:58 by ljiriste #+# #+# */ +/* Updated: 2024/05/03 16:21:02 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "parsing.h" + +int execute(__attribute__((unused))t_tree *parse_tree, __attribute__((unused))t_vars *vars) +{ + ft_printf("Function execute has to be implemented.\n"); + return (0); +} diff --git a/src/input_handling.c b/src/input_handling.c new file mode 100644 index 0000000..cf91b3d --- /dev/null +++ b/src/input_handling.c @@ -0,0 +1,60 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* input_handling.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/05/03 09:00:00 by ljiriste #+# #+# */ +/* Updated: 2024/05/03 16:06:16 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "parsing.h" +#include "minishell.h" +#include "libft.h" + +static void free_token(void *token) +{ + ft_vec_free(&((t_token *)token)->str, NULL); + return ; +} + +static int delimit(__attribute__((unused))const char *line, __attribute__((unused))t_vec *tokens) +{ + ft_printf("Function delimit has to be implemented.\n"); + return (0); +} + +static int identify(__attribute__((unused))t_vec *tokens) +{ + ft_printf("Function identify has to be implemented.\n"); + return (0); +} + +static int tokenize(const char *line, t_vec *tokens) +{ + if (delimit(line, tokens)) + return (1); + if (identify(tokens)) + return (1); + return (0); +} + +void handle_input(const char *input, t_vars *vars) +{ + int res; + t_vec tokens; + t_tree parse_tree; + + ft_vec_init(&tokens, sizeof(t_token)); + init_tree(&parse_tree); + res = tokenize(input, &tokens); + res = res || parse(&tokens, &parse_tree, vars); + res = res || execute(&parse_tree, vars); + ft_vec_free(&tokens, free_token); + free_tree(&parse_tree); + if (res != 0) + ft_printf("An error has occured.\n"); + return ; +} diff --git a/src/main.c b/src/main.c index 135ec54..4182246 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/26 13:11:47 by ljiriste #+# #+# */ -/* Updated: 2024/05/02 15:02:14 by ljiriste ### ########.fr */ +/* Updated: 2024/05/03 08:59:30 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,11 +21,6 @@ # include // readline #endif // NOLEAKS -void handle_input(__attribute__((unused)) const char *input, __attribute__((unused)) t_vars *vars) -{ - return ; -} - void print_help(void) { ft_printf("Minishell should be used without any arguments.\n"); diff --git a/src/parsing.c b/src/parsing.c new file mode 100644 index 0000000..9fa2128 --- /dev/null +++ b/src/parsing.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parsing.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/05/03 15:58:55 by ljiriste #+# #+# */ +/* Updated: 2024/05/03 16:20:45 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "parsing.h" + +int parse(__attribute__((unused))t_vec *tokens, __attribute__((unused))t_tree_node *parse_tree, __attribute__((unused))t_vars *vars) +{ + ft_printf("Function parse has to be implemented.\n"); + return (0); +} diff --git a/src/tree.c b/src/tree.c new file mode 100644 index 0000000..c06af96 --- /dev/null +++ b/src/tree.c @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tree.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ljiriste +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/05/03 15:56:55 by ljiriste #+# #+# */ +/* Updated: 2024/05/03 16:03:37 by ljiriste ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "parsing.h" + +int init_tree(__attribute__((unused))t_tree *tree) +{ + ft_printf("Function init_tree has to be implemented.\n"); + return (0); +} + +void free_tree(__attribute__((unused))t_tree *tree) +{ + ft_printf("Function free_tree has to by implemented.\n"); + return ; +} -- 2.30.2