From 95a16d2d88c8628ab0ae76f3ae04dfebee566950 Mon Sep 17 00:00:00 2001 From: Charles Cabergs Date: Thu, 27 Aug 2020 19:13:28 +0200 Subject: Fising tok_lst_new uninitialized next, Added tok_lst_debug, Fixing parse_cmd --- include/ast.h | 88 ------------------------- include/error.h | 36 ++++++++++ include/eval.h | 4 +- include/lexer.h | 3 +- include/minishell.h | 20 +----- include/parser.h | 89 +++++++++++++++++++++++-- minishell_test | 2 +- src/ast.c | 4 +- src/debug.c | 10 ++- src/lexer/lexer.c | 6 +- src/lexer/tok_lst.c | 15 ++++- src/main.c | 15 +++-- src/parse/parse.c | 186 ---------------------------------------------------- src/parser/parsed.c | 40 +++++++++++ src/parser/parser.c | 154 +++++++++++++++++++++++++++++++++++++++++++ src/preprocess.c | 4 +- 16 files changed, 361 insertions(+), 315 deletions(-) delete mode 100644 include/ast.h create mode 100644 include/error.h delete mode 100644 src/parse/parse.c create mode 100644 src/parser/parsed.c create mode 100644 src/parser/parser.c diff --git a/include/ast.h b/include/ast.h deleted file mode 100644 index 8048dd2..0000000 --- a/include/ast.h +++ /dev/null @@ -1,88 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ast.h :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: charles +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/04/01 17:05:38 by charles #+# #+# */ -/* Updated: 2020/08/27 18:38:45 by charles ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#ifndef AST_H -# define AST_H - -/* -** \file ast.h -** \brief AST structs -*/ - -# include -# include -# include "libft_lst.h" -# include "lexer.h" - -struct s_ast; - -/* -** \brief Operation struct -** \param left AST to the left of separator -** \param right AST to the right of separator -** \param sep Type of separator -*/ - - -typedef struct s_op -{ - struct s_ast *left; - struct s_ast *right; - enum e_tok sep; -} t_op; - -/* -** \brief AST node tag (type) -** \param TAG_CMD Command AST node -** \param TAG_OP Operation AST node -*/ - -enum e_ast -{ - AST_CMD, - AST_OP, - AST_PARENT, -}; - -/* -** \brief AST node struct -** \param tag Node tag -** \param op Operation struct -** \param cmd_argv Array of string tokens -** \param in STDIN redirection string tokens -** \param out STDOUT redirection string tokens -** \param is_append True if out redirection is append to file -*/ - -typedef struct s_ast -{ - enum e_ast tag; - union - { - t_op op; - t_tok_lst *cmd_argv; - struct s_ast *parent_ast; - }; - t_tok_lst *redirs; -} t_ast; - -typedef struct s_parsed -{ - bool syntax_error; - t_ast *ast; - t_tok_lst *rest; -} t_parsed; - -t_ast *ast_new(enum e_ast tag); -void ast_destroy(t_ast *ast); - -#endif diff --git a/include/error.h b/include/error.h new file mode 100644 index 0000000..941f1b2 --- /dev/null +++ b/include/error.h @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* error.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: charles +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/08/27 20:34:25 by charles #+# #+# */ +/* Updated: 2020/08/27 20:38:52 by charles ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef ERROR_H +# define ERROR_H + +# include +# include "libft_io.h" + +/* +** error.c +*/ + +typedef enum +{ + ERR_FATAL = -1, + ERR_NONE = 0, + ERR_AMBIGUOUS_REDIR = 1, + ERR_OPEN = 1, + ERR_CMD_NOT_FOUND = 127, + ERR_SYNTAX = 2, +} t_err; + +void errorf(const char *format, ...); +void verrorf(const char *format, va_list ap); + +#endif diff --git a/include/eval.h b/include/eval.h index c9adf72..761c152 100644 --- a/include/eval.h +++ b/include/eval.h @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:05:30 by charles #+# #+# */ -/* Updated: 2020/08/27 17:15:19 by charles ### ########.fr */ +/* Updated: 2020/08/27 20:31:35 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,7 +20,7 @@ # include "minishell.h" # include "lexer.h" -# include "ast.h" +# include "parser.h" typedef struct { diff --git a/include/lexer.h b/include/lexer.h index bdb05da..f8e16bc 100644 --- a/include/lexer.h +++ b/include/lexer.h @@ -6,7 +6,7 @@ /* By: nahaddac +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/06/19 10:51:26 by nahaddac #+# #+# */ -/* Updated: 2020/08/27 18:44:17 by charles ### ########.fr */ +/* Updated: 2020/08/27 20:55:27 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -60,6 +60,7 @@ void tok_lst_push_back(t_tok_lst **tokens, t_tok_lst *pushed); t_tok_lst *tok_lst_push_front(t_tok_lst **tokens, t_tok_lst *pushed); void *tok_lst_destroy(t_tok_lst **tokens, void (*del)(void*)); t_tok_lst *tok_lst_last(t_tok_lst *tokens); +t_tok_lst *tok_lst_pop_front(t_tok_lst **tokens); /* ** lexer.c diff --git a/include/minishell.h b/include/minishell.h index 1b23952..4bcd681 100644 --- a/include/minishell.h +++ b/include/minishell.h @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/26 15:33:51 by cacharle #+# #+# */ -/* Updated: 2020/08/27 17:18:43 by charles ### ########.fr */ +/* Updated: 2020/08/27 20:34:44 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -38,6 +38,7 @@ # include "libft_dstr.h" # include "lexer.h" +# include "error.h" /* ** \brief Value of pipe entry if closed @@ -112,23 +113,6 @@ int builtin_exit(char **argv, t_env env); char **preprocess(t_tok_lst **tokens, t_env env); char *preprocess_filename(t_tok_lst **tokens, t_env env); -/* -** error.c -*/ - -typedef enum -{ - ERR_FATAL = -1, - ERR_NONE = 0, - ERR_AMBIGUOUS_REDIR = 1, - ERR_OPEN = 1, - ERR_CMD_NOT_FOUND = 127, - ERR_SYNTAX = 2, -} t_err; - -void errorf(const char *format, ...); -void verrorf(const char *format, va_list ap); - /* ** signal.c */ diff --git a/include/parser.h b/include/parser.h index 7103d0b..061d8f2 100644 --- a/include/parser.h +++ b/include/parser.h @@ -6,19 +6,15 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 09:00:00 by cacharle #+# #+# */ -/* Updated: 2020/08/27 18:40:55 by charles ### ########.fr */ +/* Updated: 2020/08/27 20:38:13 by charles ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef PARSE_H # define PARSE_H -# include "minishell.h" -#include "libft_str.h" -# include "ast.h" - /* -** \file parse.h +** \file parser.h ** \brief Input parsing and AST manipulation ** ** Context free grammar: @@ -34,6 +30,86 @@ ** ``` */ +# include +# include +# include "libft_lst.h" +# include "lexer.h" +# include "error.h" + +struct s_ast; + +/* +** \brief Operation struct +** \param left AST to the left of separator +** \param right AST to the right of separator +** \param sep Type of separator +*/ + + +typedef struct s_op +{ + struct s_ast *left; + struct s_ast *right; + enum e_tok sep; +} t_op; + +/* +** \brief AST node tag (type) +** \param TAG_CMD Command AST node +** \param TAG_OP Operation AST node +** \param TAG_PARENT Parenthesis AST node +*/ + +enum e_ast +{ + AST_CMD, + AST_OP, + AST_PARENT, +}; + +/* +** \brief AST node struct +** \param tag Node tag +** \param op Operation struct +** \param cmd_argv Command argv tokens +** \param parend_ast AST inside parenthesis +** \param redirs Redirections tokens +*/ + +typedef struct s_ast +{ + enum e_ast tag; + union + { + t_op op; + t_tok_lst *cmd_argv; + struct s_ast *parent_ast; + }; + t_tok_lst *redirs; +} t_ast; + +/* +** ast.c +*/ + +t_ast *ast_new(enum e_ast tag); +void ast_destroy(t_ast *ast); + +/* +** parsed.c +*/ + +typedef struct s_parsed +{ + bool syntax_error; + t_ast *ast; + t_tok_lst *rest; +} t_parsed; + +t_parsed *parsed_new(t_ast *ast, t_tok_lst *rest); +t_parsed *parsed_error(const char *format, ...); + + /* ** parse.c */ @@ -43,4 +119,5 @@ t_parsed *parse_op(t_tok_lst *input); t_parsed *parse_expr(t_tok_lst *input); t_parsed *parse_cmd(t_tok_lst *input); + #endif diff --git a/minishell_test b/minishell_test index aacf088..cbc2c50 160000 --- a/minishell_test +++ b/minishell_test @@ -1 +1 @@ -Subproject commit aacf088db4d9d3e0b450247abe1d8f258d07d862 +Subproject commit cbc2c50efaf06f5b925bb87c445994e9db6e1719 diff --git a/src/ast.c b/src/ast.c index e2c4017..2bb90d9 100644 --- a/src/ast.c +++ b/src/ast.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/01 17:05:42 by charles #+# #+# */ -/* Updated: 2020/08/27 18:39:31 by charles ### ########.fr */ +/* Updated: 2020/08/27 20:31:48 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,7 +15,7 @@ ** \brief AST functions */ -#include "ast.h" +#include "parser.h" /* ** \brief Create a new AST node according to `tag` diff --git a/src/debug.c b/src/debug.c index 8255016..8759252 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1,7 +1,15 @@ #include #include "lexer.h" -#include "ast.h" + +void tok_lst_debug(t_tok_lst *tokens) +{ + while (tokens != NULL) + { + printf("[%#06x] |%s|%s\n", tokens->tag, tokens->content, tokens->tag & TAG_STICK ? " STICK" : ""); + tokens = tokens->next; + } +} /* void token_debug(void *v) */ /* { */ diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index e6aeb80..7f49431 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -6,7 +6,7 @@ /* By: nahaddac +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/07/16 08:18:25 by nahaddac #+# #+# */ -/* Updated: 2020/08/27 17:34:53 by charles ### ########.fr */ +/* Updated: 2020/08/27 20:45:59 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -58,6 +58,10 @@ int check_input(char *input) } if (lexer_sep(input[i])) { + /* src/lexer/lexer.c:62:12: warning: Although the value stored to 'i' is used in the enclosing expression, the value is never actually read from 'i' */ + /* return (i += lexer_space(&input[i + 1]) + 1); */ + /* ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + if (input[i] == ';') return (i += lexer_space(&input[i + 1]) + 1); while(input[i] == input[i + 1] && op < 2) diff --git a/src/lexer/tok_lst.c b/src/lexer/tok_lst.c index 8d29bb5..a620aa5 100644 --- a/src/lexer/tok_lst.c +++ b/src/lexer/tok_lst.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/08/27 09:32:58 by charles #+# #+# */ -/* Updated: 2020/08/27 18:40:05 by charles ### ########.fr */ +/* Updated: 2020/08/27 20:54:35 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -31,6 +31,7 @@ t_tok_lst *tok_lst_new_until(enum e_tok tag, char *content, size_t n) return (NULL); } ret->tag = tag; + ret->next = NULL; return (ret); } @@ -57,3 +58,15 @@ t_tok_lst *tok_lst_last(t_tok_lst *tokens) { return ((t_tok_lst*)ft_lstlast((t_ftlst*)tokens)); } + +t_tok_lst *tok_lst_pop_front(t_tok_lst **tokens) +{ + t_tok_lst *poped; + + if (tokens == NULL || *tokens == NULL) + return (NULL); + poped = *tokens; + *tokens = poped->next; + poped->next = NULL; + return (poped); +} diff --git a/src/main.c b/src/main.c index b02c68b..41a4967 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 11:45:44 by cacharle #+# #+# */ -/* Updated: 2020/08/27 18:41:53 by charles ### ########.fr */ +/* Updated: 2020/08/27 20:44:44 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,15 +16,15 @@ */ #include "minishell.h" -#include "ast.h" #include "lexer.h" #include "parser.h" #include "eval.h" -void token_debug(void *v); -void token_put(void *v); -void print_level(int level); -void ast_print(int level, t_ast *ast); +/* void token_debug(void *v); */ +/* void token_put(void *v); */ +/* void print_level(int level); */ +/* void ast_print(int level, t_ast *ast); */ +void tok_lst_debug(t_tok_lst *tokens); /* ** TODO @@ -90,6 +90,7 @@ int main(int argc, char **argv, char **envp) t_tok_lst *lex_out = lexer(ft_strdup(argv[2])); if (lex_out == NULL) return (1); + tok_lst_debug(lex_out); /* ft_lstiter((t_ftlst*)lex_out, token_debug); */ } else if (argc == 3 && ft_strcmp(argv[1], "-c") == 0) @@ -145,6 +146,8 @@ int main(int argc, char **argv, char **envp) (void)eval_out; print_prompt(); } + if (ret != FTGL_EOF) + return (1); } ft_htdestroy(path, free); diff --git a/src/parse/parse.c b/src/parse/parse.c deleted file mode 100644 index df39cd0..0000000 --- a/src/parse/parse.c +++ /dev/null @@ -1,186 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* parse.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: nahaddac +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2020/06/17 18:09:04 by nahaddac #+# #+# */ -/* Updated: 2020/08/27 11:02:33 by charles ### ########.fr */ -/* */ -/* ************************************************************************** */ - -/* -** \file parse.c -** \brief Parser -*/ - -#include "parser.h" -#include "lexer.h" - -t_parsed *parsed_new(t_ast *ast, t_tok_lst *rest) -{ - t_parsed *ret; - - if ((ret = malloc(sizeof(t_parsed))) == NULL) - return (NULL); - ret->syntax_error = false; - ret->rest = rest; - ret->ast = ast; - return ret; -} - -t_parsed *parsed_error(const char *format, ...) -{ - t_parsed *err; - va_list ap; - - if ((err = parsed_new(NULL, NULL)) == NULL) - return (NULL); - err->syntax_error = true; - va_start(ap, format); - verrorf(format, ap); - va_end(ap); - return (err); -} - -t_parsed *parse_redir(t_tok_lst *input, t_tok_lst **redirs) -{ - tok_lst_push_back(redirs, input); - input = input->next; - if (input == NULL) - return (parsed_error("syntax error near unexpected token `newline'\n")); - while(input != NULL - && input->next != NULL - && input->next->tag & TAG_IS_STR - && input->tag & TAG_IS_STR && input->tag & TAG_STICK) - { - tok_lst_push_back(redirs, input); - input = input->next; - } - if (!(input->tag & TAG_IS_STR)) - return (parsed_error("syntax error near unexpected token `%s'\n", input->content)); - tok_lst_push_back(redirs, input); - return (parsed_new(NULL, input)); -} - -t_parsed *parse_cmd(t_tok_lst *input) -{ - enum e_tok tag; - t_ast *ast; - t_parsed *tmp; - - tag = input->tag; - if (tag & TAG_IS_SEP) - return (parsed_error("syntax error near unexpected token `%s'\n", input->content)); - ast = ast_new(AST_CMD); - while (input != NULL) - { - tag = input->tag; - if (tag & TAG_IS_STR) - tok_lst_push_back(&ast->cmd_argv, input); - else if (tag & TAG_IS_REDIR) - { - tmp = parse_redir(input, &ast->redirs); - if (tmp == NULL || tmp->syntax_error) - return tmp; - input = tmp->rest; - } - else - break; - if (input == NULL) - break; - input = input->next; - } - return parsed_new(ast, input); -} - -// ::= ( | )+ -// ::= | -// ::= '(' ')' | - -t_parsed *parse_op(t_tok_lst *input) -{ - t_ast *ast; - t_parsed *left_parsed; - t_parsed *right_parsed; - enum e_tok tag; - - left_parsed = parse_expr(input); - if (left_parsed == NULL || left_parsed->syntax_error) - return left_parsed; - input = left_parsed->rest; - if (input == NULL || input->tag & TAG_PARENT_CLOSE) - return parsed_new(left_parsed->ast, input); - - tag = input->tag; - if (!(tag & TAG_IS_SEP)) - return (parsed_error("syntax error near unexpected token `%s'\n", input->content)); - input = input->next; - if (input == NULL) - return (parsed_error("syntax error expected token\n")); - right_parsed = parse_op(input); - if (right_parsed == NULL || right_parsed->syntax_error) - return right_parsed; - ast = ast_new(AST_OP); - ast->op.left = left_parsed->ast; - ast->op.right = right_parsed->ast; - ast->op.sep = tag; - return parsed_new(ast, right_parsed->rest); -} - -t_parsed *parse_expr(t_tok_lst *input) -{ - t_parsed *tmp; - enum e_tok tag; - t_ast *new_ast; - - tag = input->tag; - if (tag & TAG_PARENT_OPEN) - { - if (!(tmp = parse_op(input->next)) || tmp->syntax_error) - return tmp; - input = tmp->rest; - if (input == NULL) - return (parsed_error("syntax error expected token\n")); - tag = input->tag; - if (!(tag & TAG_PARENT_CLOSE)) - return (parsed_error("syntax error expected token\n")); - input = input->next; - new_ast = ast_new(AST_PARENT); - new_ast->parent_ast = tmp->ast; - tmp->ast = new_ast; - if (input == NULL) - return tmp; - // could reuse parse_redir instead - tag = input->tag; - while (tag & TAG_IS_REDIR) - { - while(input != NULL) - { - tag = input->tag; - tok_lst_push_back(&tmp->ast->redirs, input); - if (tag & TAG_IS_STR && tag & TAG_STICK) - input = input->next; - else if (tag & TAG_IS_REDIR) - input = input->next; - else - break; - } - input = input->next; - if (input == NULL) - break; - tag = input->tag; - } - tmp->rest = input; - return tmp; - } - return parse_cmd(input); -} - -t_parsed *parse(t_tok_lst *input) -{ - if (input == NULL) - return NULL; - return (parse_op(input)); -} diff --git a/src/parser/parsed.c b/src/parser/parsed.c new file mode 100644 index 0000000..0c8eba6 --- /dev/null +++ b/src/parser/parsed.c @@ -0,0 +1,40 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parsed.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: charles +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/08/27 20:27:42 by charles #+# #+# */ +/* Updated: 2020/08/27 20:31:11 by charles ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "parser.h" + +t_parsed *parsed_new(t_ast *ast, t_tok_lst *rest) +{ + t_parsed *ret; + + if ((ret = malloc(sizeof(t_parsed))) == NULL) + return (NULL); + ret->syntax_error = false; + ret->rest = rest; + ret->ast = ast; + return ret; +} + +t_parsed *parsed_error(const char *format, ...) +{ + t_parsed *err; + va_list ap; + + if ((err = parsed_new(NULL, NULL)) == NULL) + return (NULL); + err->syntax_error = true; + va_start(ap, format); + verrorf(format, ap); + va_end(ap); + return (err); +} + diff --git a/src/parser/parser.c b/src/parser/parser.c new file mode 100644 index 0000000..ae484ac --- /dev/null +++ b/src/parser/parser.c @@ -0,0 +1,154 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: nahaddac +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/06/17 18:09:04 by nahaddac #+# #+# */ +/* Updated: 2020/08/27 21:12:21 by charles ### ########.fr */ +/* */ +/* ************************************************************************** */ + +/* +** \file parse.c +** \brief Parser +*/ + +#include "parser.h" + +t_parsed *parse_redir(t_tok_lst *input, t_tok_lst **redirs) +{ + tok_lst_push_back(redirs, tok_lst_pop_front(&input)); + /* input = input->next; */ + if (input == NULL) + return (parsed_error("syntax error near unexpected token `newline'\n")); + while(input != NULL + && input->next != NULL + && input->next->tag & TAG_IS_STR + && input->tag & TAG_IS_STR && input->tag & TAG_STICK) + { + tok_lst_push_back(redirs, tok_lst_pop_front(&input)); + /* input = input->next; */ + } + if (input != NULL && !(input->tag & TAG_IS_STR)) + return (parsed_error("syntax error near unexpected token `%s'\n", input->content)); + tok_lst_push_back(redirs, tok_lst_pop_front(&input)); + return (parsed_new(NULL, input)); +} + +t_parsed *parse_cmd(t_tok_lst *input) +{ + t_ast *ast; + t_parsed *tmp; + + if (input->tag & TAG_IS_SEP) + return (parsed_error("syntax error near unexpected token `%s'\n", input->content)); + if ((ast = ast_new(AST_CMD)) == NULL) + return (NULL); + while (input != NULL) + { + if (input->tag & TAG_IS_STR) + tok_lst_push_back(&ast->cmd_argv, tok_lst_pop_front(&input)); + else if (input->tag & TAG_IS_REDIR) + { + tmp = parse_redir(input, &ast->redirs); + if (tmp == NULL || tmp->syntax_error) + return (tmp); + input = tmp->rest; + } + else + break; + } + return parsed_new(ast, input); +} + +// ::= ( | )+ +// ::= | +// ::= '(' ')' | + +t_parsed *parse_op(t_tok_lst *input) +{ + t_ast *ast; + t_parsed *left_parsed; + t_parsed *right_parsed; + enum e_tok tag; + + left_parsed = parse_expr(input); + if (left_parsed == NULL || left_parsed->syntax_error) + return left_parsed; + input = left_parsed->rest; + if (input == NULL || input->tag & TAG_PARENT_CLOSE) + return parsed_new(left_parsed->ast, input); + + tag = input->tag; + if (!(tag & TAG_IS_SEP)) + return (parsed_error("syntax error near unexpected token `%s'\n", input->content)); + input = input->next; + if (input == NULL) + return (parsed_error("syntax error expected token\n")); + right_parsed = parse_op(input); + if (right_parsed == NULL || right_parsed->syntax_error) + return right_parsed; + ast = ast_new(AST_OP); + ast->op.left = left_parsed->ast; + ast->op.right = right_parsed->ast; + ast->op.sep = tag; + return parsed_new(ast, right_parsed->rest); +} + +t_parsed *parse_expr(t_tok_lst *input) +{ + t_parsed *tmp; + enum e_tok tag; + t_ast *new_ast; + + tag = input->tag; + if (tag & TAG_PARENT_OPEN) + { + if (!(tmp = parse_op(input->next)) || tmp->syntax_error) + return tmp; + input = tmp->rest; + if (input == NULL) + return (parsed_error("syntax error expected token\n")); + tag = input->tag; + if (!(tag & TAG_PARENT_CLOSE)) + return (parsed_error("syntax error expected token\n")); + input = input->next; + new_ast = ast_new(AST_PARENT); + new_ast->parent_ast = tmp->ast; + tmp->ast = new_ast; + if (input == NULL) + return tmp; + // could reuse parse_redir instead + tag = input->tag; + while (tag & TAG_IS_REDIR) + { + while(input != NULL) + { + tag = input->tag; + tok_lst_push_back(&tmp->ast->redirs, tok_lst_pop_front(&input)); + if (tag & TAG_IS_STR && tag & TAG_STICK) + input = input->next; + else if (tag & TAG_IS_REDIR) + input = input->next; + else + break; + } + if (input == NULL) + break; + input = input->next; + tag = input->tag; + } + tmp->rest = input; + return tmp; + } + return parse_cmd(input); +} + +t_parsed *parse(t_tok_lst *input) +{ + if (input == NULL) + return NULL; + return (parse_op(input)); +} diff --git a/src/preprocess.c b/src/preprocess.c index 2e477d0..f4eb104 100644 --- a/src/preprocess.c +++ b/src/preprocess.c @@ -6,7 +6,7 @@ /* By: charles +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/03 08:58:49 by charles #+# #+# */ -/* Updated: 2020/08/27 17:33:55 by charles ### ########.fr */ +/* Updated: 2020/08/27 20:43:22 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -48,7 +48,7 @@ t_tok_lst *st_stick_tokens(t_tok_lst *tokens) while (curr != NULL) { // curr->next shouldn't be null - if (curr->tag & TAG_STICK) + if (curr->tag & TAG_STICK && curr->next != NULL) { curr->content = ft_strjoinf_fst(curr->content, curr->next->content); t_tok_lst *tmp = curr->next->next; -- cgit