From 9a11d78abf7dc8fb8c8f3430538e80622a7854d3 Mon Sep 17 00:00:00 2001 From: Charles Date: Wed, 17 Jun 2020 20:47:59 +0200 Subject: Show nass the power of parser combinator --- include/lexer.h | 1 + minishell_test | 2 +- src/main.c | 40 +++++++++++- src/parse/parse.c | 191 +++++++++++++++++++++++++++++++++++++++--------------- 4 files changed, 181 insertions(+), 53 deletions(-) diff --git a/include/lexer.h b/include/lexer.h index b0e7f65..43c3821 100644 --- a/include/lexer.h +++ b/include/lexer.h @@ -24,6 +24,7 @@ enum e_token_tag TAG_IS_STR = TAG_STR | TAG_STR_SINGLE | TAG_STR_DOUBLE, TAG_IS_REDIR = TAG_REDIR_IN | TAG_REDIR_OUT | TAG_REDIR_APPEND, + TAG_IS_SEP = TAG_AND | TAG_END | TAG_OR | TAG_PIPE, }; typedef struct diff --git a/minishell_test b/minishell_test index f36a8cc..d845a68 160000 --- a/minishell_test +++ b/minishell_test @@ -1 +1 @@ -Subproject commit f36a8ccb91cb71c1e4f15dc12cdecf3167eb1420 +Subproject commit d845a683e67a89c699109dab660f6ec0eb74a2c4 diff --git a/src/main.c b/src/main.c index 9b902b8..4420f9d 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/06/17 15:50:33 by nahaddac ### ########.fr */ +/* Updated: 2020/06/17 20:46:39 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -29,6 +29,43 @@ void token_debug(void *v) printf("[%4d %d] (%s)\n", t->tag, !!(t->tag & TAG_STICK), t->content); } +void token_put(void *v) +{ + t_token *t; + + t= v; + printf("%s ", t->content); +} + +void print_level(int level) +{ + while (level-- > 0) + printf(" "); +} + +void ast_print(int level, t_ast *ast) +{ + if (ast->tag == AST_CMD) + { + print_level(level); + ft_lstiter(ast->cmd_argv, token_put); + } + else + { + print_level(level); + printf("SEP: %d\n", ast->op.sep); + + print_level(level); + printf("left:\n"); + ast_print(level + 1, ast->op.left); + + printf("\n"); + print_level(level); + printf("right:\n"); + ast_print(level + 1, ast->op.right); + } +} + int main(int argc, char **argv, char **envp) { t_path path; @@ -46,6 +83,7 @@ int main(int argc, char **argv, char **envp) //ft_lstiter(lex_out, token_debug); t_ret *parser_out = parse(lex_out); + ast_print(0, parser_out->ast); /* printf("===cmd_argv===\n"); */ /* ft_lstiter(parser_out->ast->cmd_argv, token_debug); */ diff --git a/src/parse/parse.c b/src/parse/parse.c index b9bb156..6a80e37 100755 --- a/src/parse/parse.c +++ b/src/parse/parse.c @@ -6,7 +6,7 @@ /* By: nahaddac +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/06/17 18:09:04 by nahaddac #+# #+# */ -/* Updated: 2020/06/17 18:36:54 by nahaddac ### ########.fr */ +/* Updated: 2020/06/17 20:39:25 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,75 +17,164 @@ #include "parser.h" #include "lexer.h" -// stdio.h est deja include dans minishell.h temporairement -// (comme ca on doit le retirer a un seul endroit a la fin) -// oui je sais maintenant tu peux effacer se petit commantaire ;) +t_ftlst *push_token(t_ftlst **tokens, t_token *pushed) +{ + t_ftlst *tmp; + + if ((tmp = ft_lstnew(pushed)) == NULL) + return (NULL); + ft_lstpush_back(tokens, tmp); + return (tmp); +} + +t_ret *ret_wrap_ast(t_ast *ast, t_ftlst *rest) +{ + t_ret *ret; + + if ((ret = malloc(sizeof(t_ret))) == NULL) + return (NULL); + ret->unexpected = NULL; + ret->rest = rest; + ret->ast = ast; + return ret; +} -t_ast *cmd_push_ast(t_ftlst *rest) +t_ret *parse_cmd(t_ftlst *input) { - enum e_token_tag tag; - t_ast *ast; + enum e_token_tag tag; + t_ast *ast; - ast = NULL; - while (rest != NULL) + ast = ast_new(AST_CMD); + while (input != NULL) { - tag = ((t_token *)rest->data)->tag; - if (parse_cmd_str_true_false(tag)) + tag = ((t_token *)input->data)->tag; + if (tag & TAG_IS_STR) { - ast = push_cmd(ast, rest); + push_token(&ast->cmd_argv, input->data); } - else if (parse_redir_true_false(tag)) + else if (tag & TAG_IS_REDIR) { - while(rest != NULL) + while(input != NULL) { - ast = push_redir(ast, rest); + push_token(&ast->redirs, input->data); if (tag & TAG_IS_STR && tag & TAG_STICK) - rest = rest->next; + input = input->next; else if (tag & TAG_IS_REDIR) - rest = rest->next; + input = input->next; else break; - tag = ((t_token *)rest->data)->tag; + tag = ((t_token *)input->data)->tag; } } - rest = rest->next; + else + return ret_wrap_ast(ast, input); + input = input->next; } - return ast; + return ret_wrap_ast(ast, input); } -t_ret *parse(t_ftlst *input) +// ::= ... +// ::= | + +t_ret *parse_op(t_ftlst *input) { - t_ret *ret; - t_ret *first; - t_ast *new_ast; - - if(!(ret = malloc(sizeof(t_ret) * 1))) - return(NULL); - ret->rest = input; - ret->ast = NULL; - ret->unexpected = NULL; - first = ret; + t_ast *ast; + t_ret *left_ret; + t_ret *right_ret; + enum e_token_tag sep_tag; - if(!(new_ast = malloc(sizeof(t_ast) * 1))) - return(0); - new_ast = cmd_push_ast(ret->rest); - printf("%s\n",((t_token *)ret->rest->data)->content); - if (ret->ast) - { - while(ret->ast->cmd_argv != NULL) - { - printf("[%s]\n", ((t_token *)ret->ast->cmd_argv->data)->content); - ret->ast->cmd_argv = ret->ast->cmd_argv->next; - } - while(ret->ast->redirs != NULL) - { - printf("[%s]\n", ((t_token *)ret->ast->redirs->data)->content); - ret->ast->redirs = ret->ast->redirs->next; - } - } - ast_destroy(ret->ast); - ft_lstdestroy(&ret->rest, (void (*)(void*))token_destroy); - return first; + left_ret = parse_cmd(input); + input = left_ret->rest; + + if (input == NULL)//((t_token*)input->data)->tag & TAG_IS_SEP) + return ret_wrap_ast(left_ret->ast, input); + + sep_tag = ((t_token*)input->data)->tag; + input = input->next; + + right_ret = parse_op(input); + + ast = ast_new(AST_OP); + ast->op.left = left_ret->ast; + ast->op.right = right_ret->ast; + ast->op.sep = sep_tag; + return ret_wrap_ast(ast, right_ret->rest); } + +t_ret *parse(t_ftlst *input) +{ + return parse_op(input); +} + +//////////////////////////////////////////////////////////////// +// saved +//////////////////////////////////////////////////////////////// + +/* t_ast *cmd_push_ast(t_ftlst *rest) */ +/* { */ +/* enum e_token_tag tag; */ +/* t_ast *ast; */ +/* */ +/* ast = NULL; */ +/* while (rest != NULL) */ +/* { */ +/* tag = ((t_token *)rest->data)->tag; */ +/* if (parse_cmd_str_true_false(tag)) */ +/* { */ +/* ast = push_cmd(ast, rest); */ +/* } */ +/* else if (parse_redir_true_false(tag)) */ +/* { */ +/* while(rest != NULL) */ +/* { */ +/* ast = push_redir(ast, rest); */ +/* if (tag & TAG_IS_STR && tag & TAG_STICK) */ +/* rest = rest->next; */ +/* else if (tag & TAG_IS_REDIR) */ +/* rest = rest->next; */ +/* else */ +/* break; */ +/* tag = ((t_token *)rest->data)->tag; */ +/* } */ +/* } */ +/* rest = rest->next; */ +/* } */ +/* return ast; */ +/* } */ +/* */ +/* t_ret *parse(t_ftlst *input) */ +/* { */ +/* t_ret *ret; */ +/* t_ret *first; */ +/* t_ast *new_ast; */ +/* */ +/* if(!(ret = malloc(sizeof(t_ret) * 1))) */ +/* return(NULL); */ +/* ret->rest = input; */ +/* ret->ast = NULL; */ +/* ret->unexpected = NULL; */ +/* first = ret; */ +/* */ +/* if(!(new_ast = malloc(sizeof(t_ast) * 1))) */ +/* return(0); */ +/* new_ast = cmd_push_ast(ret->rest); */ +/* printf("%s\n",((t_token *)ret->rest->data)->content); */ +/* if (ret->ast) */ +/* { */ +/* while(ret->ast->cmd_argv != NULL) */ +/* { */ +/* printf("[%s]\n", ((t_token *)ret->ast->cmd_argv->data)->content); */ +/* ret->ast->cmd_argv = ret->ast->cmd_argv->next; */ +/* } */ +/* while(ret->ast->redirs != NULL) */ +/* { */ +/* printf("[%s]\n", ((t_token *)ret->ast->redirs->data)->content); */ +/* ret->ast->redirs = ret->ast->redirs->next; */ +/* } */ +/* } */ +/* ast_destroy(ret->ast); */ +/* ft_lstdestroy(&ret->rest, (void (*)(void*))token_destroy); */ +/* return first; */ +/* } */ -- cgit