From c54625e551a9efec79af4466bc528cdf787a6b50 Mon Sep 17 00:00:00 2001 From: zedin27 Date: Sat, 7 Apr 2018 17:19:14 -0700 Subject: [PATCH] MOD: normed what is needed --- ast/ast.c | 103 +++++++++++++++++++++----------------- ast/free.c | 0 ast/get.c | 33 ++++++++++++ ast/helper.c | 35 +++++++++++++ ast/lexer.c | 23 --------- ast/lexer.h | 9 ---- ast/main.c | 30 ++++++++--- ast/main.h | 9 ---- ast/parse.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++ ast/parse.h | 102 +++++++++++++++++++++++++++++++++++++ ast/print.c | 49 +++++++++++++++--- ast/print.h | 9 ---- ast/queue.c | 76 ---------------------------- ast/queue.h | 30 ----------- ast/validate.c | 23 +++++++++ 15 files changed, 448 insertions(+), 216 deletions(-) create mode 100644 ast/free.c create mode 100644 ast/get.c create mode 100644 ast/helper.c delete mode 100644 ast/lexer.c delete mode 100644 ast/lexer.h delete mode 100644 ast/main.h create mode 100644 ast/parse.c create mode 100644 ast/parse.h delete mode 100644 ast/print.h delete mode 100644 ast/queue.c delete mode 100644 ast/queue.h create mode 100644 ast/validate.c diff --git a/ast/ast.c b/ast/ast.c index 2095daa..be0ef11 100644 --- a/ast/ast.c +++ b/ast/ast.c @@ -1,56 +1,67 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* ast.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: ztisnes +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2018/03/30 14:51:27 by ztisnes #+# #+# */ -/* Updated: 2018/04/04 01:01:23 by ztisnes ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include -#include -#include -#include -#include -#include -#include - -/* -** -** TODO:execve function to run the command after parsing it -** -> Make execve be running in the leaves of the AST -** -*/ - -typedef struct s_ast +#include "parse.h" + +t_ast *ast_new(char *name, t_type type) { - void *data; - struct s_ast *left; - struct s_ast *right; -} t_ast; + t_ast *node; + + if (!name) + return (NULL); + if (!(node = (t_ast *)ft_memalloc(sizeof(t_ast)))) + return (NULL); + if (!(node->name = (char *)ft_memalloc(ft_strlen(name) + 1))) + return (NULL); + ft_strcpy(node->name, (const char*)name); + node->type = type; + node->next = NULL; + node->parent = NULL; + node->right = NULL; + return (node); +} -t_ast *create_node(int *value) +t_ast *ast_enast(t_ast *head, t_ast *node) { - t_ast *root; + t_ast *cursor; - root = malloc(sizeof(t_ast)); - root->data = value; - root->left = NULL; - root->right = NULL; - return (root); + if (!node) + return (head); + if (!head) + return (node); + cursor = head; + while (cursor->next) + cursor = cursor->next; + cursor->next = node; + return (head); } -t_ast *insert_left(t_ast *node, int *value) +t_ast *ast_deast(t_ast *head) { - node->left = create_node(value); - return (node->left); + t_ast *cpy; + + if (!head) + return (NULL); + if (!head->next) + { + ft_strdel(&head->name); + ft_memdel((void **)&head); + return (NULL); + } + cpy = head; + while (head->next->next) + head = head->next; + ft_strdel(&head->next->name); + ft_memdel((void **)head->next); + return (cpy); } -t_ast *insert_right(t_ast *node, int *value) +int ast_len(t_ast *head) { - node->right = create_node(value); - return (node->right); -} \ No newline at end of file + int i; + + i = 0; + while (head) + { + head = head->next; + i++; + } + return (i); +} diff --git a/ast/free.c b/ast/free.c new file mode 100644 index 0000000..e69de29 diff --git a/ast/get.c b/ast/get.c new file mode 100644 index 0000000..d04f6ad --- /dev/null +++ b/ast/get.c @@ -0,0 +1,33 @@ +#include "parse.h" + +t_type get_type(char *str) +{ + if (ft_strlen(str) == 1 && *str == ';') + return (SEP); + if (ft_strlen(str) == 1 && *str == '|') + return (RED_PIPE); + if (ft_strlen(str) == 2) + { + if (IS_OP_AND(str)) + return (OP_OR); + if (IS_OP_AND(str)) + return (OP_AND); + } + return (CMD); +} + +int get_nbr_instructions(t_ast *lex) +{ + int i; + + if (!lex) + return (0); + i = 1; + while (lex) + { + if (lex->type == SEP) + i++; + lex = lex->next; + } + return (i); +} diff --git a/ast/helper.c b/ast/helper.c new file mode 100644 index 0000000..352d73a --- /dev/null +++ b/ast/helper.c @@ -0,0 +1,35 @@ +#include "parse.h" + +char *contain_term(char *str) +{ + char *dest; + int i; + + i = 0; + if (str && *str && (*str == '|' || *str == ';' || / + (str[0] == '&' && str[1] && str[1] == '&'))) + { + if (!(dest = ft_memalloc(sizeof(char) * 3))) + return (NULL); + if (*str == ';' || *str == '|' || *str == '&') + dest[i++] = *str++; + if (*str == '|' || *str == '&') + dest[i++] = *str++; + dest[i] = '\0'; + return (dest); + } + return (NULL); +} + +char *remove_start_space(char *str) +{ + char *dest; + + if (!str) + return (NULL); + while (str && *str && *str == ' ') + str++; + if (!(dest = ft_memalloc(ft_strlen(str) + 1))) + return (NULL); + return (ft_strcpy(dest, str)); +} diff --git a/ast/lexer.c b/ast/lexer.c deleted file mode 100644 index 16f6380..0000000 --- a/ast/lexer.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "lexer.h" - -t_queue *get_lexer(char *str) -{ - t_queue *lex; - char *word; - - lex = NULL; - word = NULL; - int i = 0; - while (str && *str && (*str == ' ' || *str == '\t')) - str++; - while (str && *str && (word = ft_strword(str))) - { - if (!(lex = queue_enqueue(lex, queue_new(word)))) - return (NULL); - str = str + ft_strlen(word); - while (str && *str && (*str == ' ' || *str == '\t')) - str++; - } - return (lex); -} - diff --git a/ast/lexer.h b/ast/lexer.h deleted file mode 100644 index 99ea79b..0000000 --- a/ast/lexer.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef LEXER_H -# define LEXER_H - -# include "../header.h" -# include "queue.h" - -t_queue *get_lexer(char *str); - -#endif diff --git a/ast/main.c b/ast/main.c index e1eec13..3644811 100644 --- a/ast/main.c +++ b/ast/main.c @@ -1,10 +1,28 @@ -#include "main.h" +#include "parse.h" -int main(int argc, char **argv) +int main(int argc, char **argv) { - t_queue *lex; + t_ast *lex; + t_ast **ast; - lex = get_lexer("ls -la /doc ."); - print_queue(lex); - return (0); + //lex = parse_lexer("echo 'hello \" world' ; ls -la rep | grep \"repertoire 1\" && sed -a -b fichier2"); + lex = parse_lexer("echo 'hello \" world' ; ls -la rep ;grep \"repertoire 1\" && sed -a -b fichier2 ; "); + + if (!lex) + { + print_error_lexer(); + return (1); + } + if (!(ast = (t_ast **)ft_memalloc(sizeof(t_ast *) * / + get_nbr_instructions(lex) + 1))) + { + print_error_ast(); + return (1); + } + if (!(ast = parse_ast(ast, lex))) + print_error_ast(); + print_trees(ast); + free_ast(lex); + free_trees(ast); + return (0); } diff --git a/ast/main.h b/ast/main.h deleted file mode 100644 index bc8fcc9..0000000 --- a/ast/main.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef MAIN_H -# define MAIN_H - -# include "../header.h" -# include "queue.h" -# include "lexer.h" -# include "print.h" - -#endif \ No newline at end of file diff --git a/ast/parse.c b/ast/parse.c new file mode 100644 index 0000000..99bf574 --- /dev/null +++ b/ast/parse.c @@ -0,0 +1,133 @@ +#include "parse.h" + +/* +** Don't send space at the end of the string +*/ + +t_ast *parse_lexer(char *str) +{ + t_ast *lex; + char *word; + char *term; + t_ast *node; + + lex = NULL; + word = NULL; + term = NULL; + while (str && *str) + { + if (*str == '\'' || *str == '"') + { + str += parse_quote(&word, str); + continue ; + } + if (*str && (*str == '|' || *str == '&' || *str == ';') && / + (term = contain_term(str))) + { + node = ast_new(remove_start_space(word), CMD); + if (node && !(lex = ast_enast(lex, node))) + return (NULL); + ft_strdel(&word); + word = NULL; + if (!(lex = ast_enast(lex, ast_new(term, get_type(term))))) + return (NULL); + str += ft_strlen(term); + ft_strdel(&term); + term = NULL; + continue ; + } + word = ft_str_append(word, *str++); + } + if (ft_strlen(word)) + { + node = ast_new(remove_start_space(word), CMD); + if (node && !(lex = ast_enast(lex, node))) + return (NULL); + ft_strdel(&word); + word = NULL; + } + return (validate_lexer(lex)); +} + +int parse_quote(char **word, char *str) +{ + int i; + + i = 1; + if (*str == '\'' && str++) + { + if (str && *str && *str == '\'' && ++i) + return (i); + *word = ft_str_append(*word, '\''); + while (str && *str && ++i && *str != '\'') + *word = ft_str_append(*word, *str++); + if (str && *str == '\'' && ++i) + *word = ft_str_append(*word, '\''); + } + else if (*str == '"' && str++) + { + if (str && *str && *str == '"' && ++i) + return (i); + *word = ft_str_append(*word, '"'); + while (str && str[0] && str[0] == '"' && str[-1] != '\\' && ++i) + *word = ft_str_append(*word, *str++); + if (str && *str == '"' && ++i) + *word = ft_str_append(*word, '"'); + } + return (i); +} + +t_ast **parse_ast(t_ast **ast, t_ast *lex) +{ + int i; + + i = 0; + ast[i] = NULL; + while (lex) + { + if (lex->type == SEP) + ast[++i] = NULL; + else if (!(ast[i] = ast_enast(ast[i], ast_new(lex->name, lex->type)))) + return (NULL); + lex = lex->next; + } + ast[++i] = 0; + i = 0; + while (ast[i]) + { + if (!(ast[i] = parse_tree(ast[i]))) + return (NULL); + i++; + } + return (ast); +} + +t_ast *parse_tree(t_ast *lex) +{ + t_ast *ast; + t_ast *op; + t_ast *right; + t_ast *cpy; + + if (!lex || lex->type != CMD || !(ast = ast_new(lex->name, lex->type))) + return (NULL); + cpy = lex; + lex = lex->next; + while (lex) + { + if (lex->type == CMD || !(op = ast_new(lex->name, lex->type))) + return (NULL); + lex = lex->next; + if (!lex || lex->type != CMD || / + !(right = ast_new(lex->name, lex->type))) + return (NULL); + op->next = ast; + op->right = right; + right->parent = op; + ast->parent = op; + ast = op; + lex = lex->next; + } + free_ast(cpy); + return (validate_ast(ast)); +} diff --git a/ast/parse.h b/ast/parse.h new file mode 100644 index 0000000..562039f --- /dev/null +++ b/ast/parse.h @@ -0,0 +1,102 @@ +#ifndef PARSE_H +# define PARSE_H + +# define IS_RED_NEXT(x) (!ft_strcmp_withspace(x, ">")) +# define IS_RED_NNEXT(x) (!ft_strcmp_withspace(x, ">>")) +# define IS_RED_PREV(x) (!ft_strcmp_withspace(x, "<")) +# define IS_RED_PIPE(x) (!ft_strcmp_withspace(x, "|")) +# define IS_RED(x) (IS_RED_NEXT(x) || IS_RED_NNEXT(x) || / + IS_RED_PREV(x) || IS_RED_PIPE(x)) + +# define IS_OP_AND(x) (!ft_strcmp_withspace(x, "&&")) +# define IS_OP_OR(x) (!ft_strcmp_withspace(x, "||")) +# define IS_OP(x) (IS_OP_AND(x) || IS_OP_OR(x)) + +# define IS_SEP(x) (!ft_strcmp_withspace(x, ";")) + +# define IS_TERM(x) (IS_OP(x) || IS_SEP(x) || IS_RED_PIPE(x)) + +# include "../libft/libft.h" +# include "../ft_printf/ft_printf_header.h" +# include "../ft_ls/ft_ls.h" + +/* TODO to delete this shit before is too late*/ +# include +/* TODO to delete this shit before is too late*/ + +typedef enum e_type +{ + CMD, + + RED_NEXT, + RED_NNEXT, + RED_PREV, + + RED_PIPE, + OP_AND, + OP_OR, + SEP, + ROOT +} t_type; + +typedef struct s_ast +{ + char *name; + struct s_ast *parent; + struct s_ast *next; + struct s_ast *right; + t_type type; +} t_ast; + + +/* +** free.c +*/ +void free_ast(t_ast *head); +void free_trees(t_ast **ast); + +/* +** get.c +*/ +t_type get_type(char *str); +int get_nbr_instructions(t_ast *lex); + +/* +** helper.c +*/ +char *contain_term(char *str); +char *remove_start_space(char *str); + +/* +** lexer.c +*/ + t_ast **parse_ast(t_ast **ast, t_ast *lex); +t_ast *parse_lexer(char *str); +t_ast *parse_tree(t_ast *lex); +int parse_quote(char **word, char *str); + +/** + * print.c + */ +void print_ast(t_ast *node); +void print_trees(t_ast **ast); +void print_lexer_start_error(char *name); +void print_error_lexer(void); +void print_error_ast(void); + +/** + * ast.c + */ +t_ast *ast_new(char *name, t_type type); +t_ast *ast_enast(t_ast *head, t_ast *node); +t_ast *ast_deast(t_ast *head); +t_ast *ast_deast_front(t_ast *head); +int ast_len(t_ast *head); + +/* +** validate.c +*/ +t_ast *validate_lexer(t_ast *lex); +t_ast *validate_ast(t_ast *ast); + +#endif diff --git a/ast/print.c b/ast/print.c index a51535e..1b84b48 100644 --- a/ast/print.c +++ b/ast/print.c @@ -1,11 +1,44 @@ -#include "print.h" +#include "parse.h" -void print_queue(t_queue *node) +void print_ast(t_ast *node) { - while (node) - { - ft_putstr(node->name); - ft_putstr("\n"); - node = node->next; - } + while (node) + { + ft_putstr(node->name); + ft_putstr("["); + ft_putnbr(node->type); + ft_putstr("]"); + if (node->right) + { + ft_putstr("\t-> RIGHT["); + ft_putstr(node->right->name); + ft_putstr("]"); + ft_putstr("["); + ft_putnbr(node->right->type); + ft_putstr("]"); + } + ft_putstr("\n"); + node = node->next; + } +} + +void print_trees(t_ast **ast) +{ + while (ast && *ast) + { + printf("#\n"); + print_ast(*ast); + printf("*****\n"); + ast++; + } +} + +void print_error_lexer(void) +{ + ft_putstr("Parse error lexer [CMD invalid]\n"); +} + +void print_error_ast(void) +{ + ft_putstr("Parse error ast\n"); } diff --git a/ast/print.h b/ast/print.h deleted file mode 100644 index 224f9bd..0000000 --- a/ast/print.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef PRINT_H -# define PRINT_H - -# include "../header.h" -# include "queue.h" - -void print_queue(t_queue *node); - -#endif diff --git a/ast/queue.c b/ast/queue.c deleted file mode 100644 index 94b93bd..0000000 --- a/ast/queue.c +++ /dev/null @@ -1,76 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* queue.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: brabo-hi +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2018/03/13 23:15:58 by brabo-hi #+# #+# */ -/* Updated: 2018/03/22 19:07:16 by brabo-hi ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "queue.h" - -t_queue *queue_new(char *name) -{ - t_queue *node; - - if (!name) - return (NULL); - if (!(node = (t_queue *)ft_memalloc(sizeof(t_queue)))) - return (NULL); - if (!(node->name = (char *)ft_memalloc(ft_strlen(name) + 1))) - return (NULL); - ft_strcpy(node->name, (const char*)name); - node->next = NULL; - return (node); -} - -t_queue *queue_enqueue(t_queue *head, t_queue *node) -{ - t_queue *cursor; - - if (!node) - return (head); - if (!head) - return (node); - cursor = head; - while (cursor->next) - cursor = cursor->next; - cursor->next = node; - return (head); -} - -t_queue *queue_dequeue(t_queue *head) -{ - t_queue *cpy; - - if (!head) - return (NULL); - if (!head->next) - { - ft_strdel(&head->name); - ft_memdel((void **)&head); - return (NULL); - } - cpy = head; - while (head->next->next) - head = head->next; - ft_strdel(&head->next->name); - ft_memdel((void **)head->next); - return (cpy); -} - -int queue_len(t_queue *head) -{ - int i; - - i = 0; - while (head) - { - head = head->next; - i++; - } - return (i); -} diff --git a/ast/queue.h b/ast/queue.h deleted file mode 100644 index a47a9c2..0000000 --- a/ast/queue.h +++ /dev/null @@ -1,30 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* queue.h :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: brabo-hi +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2018/03/13 23:16:01 by brabo-hi #+# #+# */ -/* Updated: 2018/03/22 18:55:35 by brabo-hi ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#ifndef QUEUE_H -# define QUEUE_H - -# include "../header.h" - -typedef struct s_queue -{ - char *name; - struct s_queue *next; -} t_queue; - -t_queue *queue_new(char *name); -t_queue *queue_enqueue(t_queue *head, t_queue *node); -t_queue *queue_dequeue(t_queue *head); -t_queue *queue_dequeue_front(t_queue *head); -int queue_len(t_queue *head); - -#endif diff --git a/ast/validate.c b/ast/validate.c new file mode 100644 index 0000000..982aaee --- /dev/null +++ b/ast/validate.c @@ -0,0 +1,23 @@ +#include "parse.h" + +t_ast *validate_lexer(t_ast *lex) +{ + t_ast *cpy; + + cpy = lex; + while (lex) + { + if (!ft_strlen(lex->name) || lex->type != CMD) + return (NULL); + if ((lex = lex->next) && lex->type == CMD) + return (NULL); + lex = lex ? lex->next : lex; + } + return (cpy); +} + +// TODO implement method +t_ast *validate_ast(t_ast *ast) +{ + return (ast); +}