aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--include/ast.h11
-rw-r--r--include/eval.h4
-rw-r--r--include/lexer.h1
-rw-r--r--include/parser.h16
-rw-r--r--src/ast.c4
-rw-r--r--src/lexer/lexer.c6
-rw-r--r--src/lexer/lexer_utils.c11
-rw-r--r--src/main.c51
-rwxr-xr-xsrc/parse/cmd_parse.c3
-rwxr-xr-xsrc/parse/parse.c143
-rwxr-xr-xsrc/parse/redir_parse.c1
12 files changed, 189 insertions, 63 deletions
diff --git a/.gitignore b/.gitignore
index b30589d..afd864a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,4 @@ tmp/*
.DS_Store
a.out
vgcore.*
+*.orig
diff --git a/include/ast.h b/include/ast.h
index cbbe061..53221fa 100644
--- a/include/ast.h
+++ b/include/ast.h
@@ -3,10 +3,10 @@
/* ::: :::::::: */
/* ast.h :+: :+: :+: */
/* +:+ +:+ +:+ */
-/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
+/* By: charles <charles@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/04/01 17:05:38 by charles #+# #+# */
-/* Updated: 2020/06/17 16:34:45 by charles ### ########.fr */
+/* Updated: 2020/06/18 13:35:38 by charles ### ########.fr */
/* */
/* ************************************************************************** */
@@ -50,6 +50,7 @@ enum e_ast_tag
{
AST_CMD,
AST_OP,
+ AST_OP_PARENT,
};
/*
@@ -65,11 +66,11 @@ enum e_ast_tag
typedef struct s_ast
{
enum e_ast_tag tag;
- // union
- // {
+ union
+ {
t_op op;
t_ftlst *cmd_argv;
- // };
+ };
t_ftlst *redirs;
} t_ast;
diff --git a/include/eval.h b/include/eval.h
index 79ebfeb..60d6f23 100644
--- a/include/eval.h
+++ b/include/eval.h
@@ -3,10 +3,10 @@
/* ::: :::::::: */
/* eval.h :+: :+: :+: */
/* +:+ +:+ +:+ */
-/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
+/* By: charles <charles@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/04/01 17:05:30 by charles #+# #+# */
-/* Updated: 2020/06/17 16:41:58 by charles ### ########.fr */
+/* Updated: 2020/06/18 13:38:53 by charles ### ########.fr */
/* */
/* ************************************************************************** */
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/include/parser.h b/include/parser.h
index 2bfa9d5..302c45f 100644
--- a/include/parser.h
+++ b/include/parser.h
@@ -3,10 +3,10 @@
/* ::: :::::::: */
/* parser.h :+: :+: :+: */
/* +:+ +:+ +:+ */
-/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
+/* By: cacharle <cacharle@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/02/28 09:00:00 by cacharle #+# #+# */
-/* Updated: 2020/06/14 10:31:20 by charles ### ########.fr */
+/* Updated: 2020/06/18 13:18:13 by charles ### ########.fr */
/* */
/* ************************************************************************** */
@@ -37,10 +37,20 @@
** parse.c
*/
+
t_ret *parse(t_ftlst *input);
+t_ret *parse_op(t_ftlst *input);
+t_ret *parse_expr(t_ftlst *input);
+t_ret *parse_cmd(t_ftlst *input);
+
+// utils
+t_ret *ret_wrap_ast(t_ast *ast, t_ftlst *rest);
+t_ftlst *push_token(t_ftlst **tokens, t_token *pushed);
+
+
+
t_ast *push_cmd(t_ast *ast, t_ftlst *ret);
t_ast *push_redir(t_ast *ast, t_ftlst *rest);
-
int parse_cmd_str_true_false(enum e_token_tag tag);
int parse_redir_true_false(enum e_token_tag tag);
diff --git a/src/ast.c b/src/ast.c
index 5b4c3c6..c878062 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -3,10 +3,10 @@
/* ::: :::::::: */
/* ast.c :+: :+: :+: */
/* +:+ +:+ +:+ */
-/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
+/* By: charles <charles@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/04/01 17:05:42 by charles #+# #+# */
-/* Updated: 2020/06/17 16:00:58 by charles ### ########.fr */
+/* Updated: 2020/06/18 13:39:30 by charles ### ########.fr */
/* */
/* ************************************************************************** */
diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c
index 2b1bdce..9b43616 100644
--- a/src/lexer/lexer.c
+++ b/src/lexer/lexer.c
@@ -9,9 +9,9 @@ int len_is_not_sep(char *input)
{
if (lexer_sep(input[i]))
{
- if (input[i + 1] == ' ')
- while(input[++i] == ' ')
- ;
+ //if (input[i + 1] == ' ')
+ // while(input[++i] == ' ')
+ // ;
return(i);
}
if (input[i] == '\'' || input[i] == '"')
diff --git a/src/lexer/lexer_utils.c b/src/lexer/lexer_utils.c
index 616c0d3..3ee41ff 100644
--- a/src/lexer/lexer_utils.c
+++ b/src/lexer/lexer_utils.c
@@ -1,5 +1,6 @@
#include "lexer.h"
+// check for append tag
enum e_token_tag ret_token_sep_redir_append(char *input, int i)
{
if (input[i + 1] == '>')
@@ -8,13 +9,14 @@ enum e_token_tag ret_token_sep_redir_append(char *input, int i)
}
+// return token tag corresponding to string id
enum e_token_tag ret_token(char *input, int i)
{
if (input[i] == ';')
- return(TAG_AND);
- if (input[i] == '&')
return(TAG_END);
- if (input[i] == '|' && input[i + 1] == '|')
+ if (input[i] == '&')
+ return(TAG_AND);
+ if (input[i] == '|' && input[i + 1] == '|')
return(TAG_OR);
if(input[i] == '|')
return(TAG_PIPE);
@@ -30,6 +32,8 @@ enum e_token_tag ret_token(char *input, int i)
}
+// check is char is separator
+// ft_strchr(";&|><()", input)
int lexer_sep(char input)
{
char *sep;
@@ -46,6 +50,7 @@ int lexer_sep(char input)
return (0);
}
+// skip spaces
int lexe_space(char *input)
{
int i;
diff --git a/src/main.c b/src/main.c
index f6555ad..76caea7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -3,10 +3,10 @@
/* ::: :::::::: */
/* main.c :+: :+: :+: */
/* +:+ +:+ +:+ */
-/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
+/* By: cacharle <cacharle@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/02/28 11:45:44 by cacharle #+# #+# */
-/* Updated: 2020/06/17 17:10:08 by charles ### ########.fr */
+/* Updated: 2020/06/18 13:43:58 by charles ### ########.fr */
/* */
/* ************************************************************************** */
@@ -62,6 +62,53 @@
/* return (0); */
/* } */
+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);
+ printf("cmd: [ ");
+ ft_lstiter(ast->cmd_argv, token_put);
+ printf(" ] redirs: [");
+ ft_lstiter(ast->redirs, token_put);
+ printf(" ]");
+ }
+ else
+ {
+ /* print_level(level); */
+ /* printf("SEP: %d\n", ast->op.sep); */
+ print_level(level);
+ printf("{\n");
+
+ 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);
+
+ printf("\n");
+ print_level(level);
+ printf("}\n");
+ }
+}
+
int main(int argc, char **argv, char **envp)
{
(void)argc;
diff --git a/src/parse/cmd_parse.c b/src/parse/cmd_parse.c
index c655c5c..25802c1 100755
--- a/src/parse/cmd_parse.c
+++ b/src/parse/cmd_parse.c
@@ -2,7 +2,6 @@
#include "parser.h"
-
int parse_cmd_str_true_false(enum e_token_tag tag)
{
if (tag & TAG_STR || tag & TAG_STR_DOUBLE || tag & TAG_STR_SINGLE)
@@ -10,12 +9,10 @@ int parse_cmd_str_true_false(enum e_token_tag tag)
return(0);
}
-
t_ast *push_cmd(t_ast *ast, t_ftlst *rest)
{
t_ftlst *new;
- /* new = rest->data; */
if (ast == NULL)
{
ast = ast_new(AST_CMD);
diff --git a/src/parse/parse.c b/src/parse/parse.c
index 37192b0..198ac65 100755
--- a/src/parse/parse.c
+++ b/src/parse/parse.c
@@ -1,3 +1,15 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* parse.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: nahaddac <nahaddac@student.42.fr> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2020/06/17 18:09:04 by nahaddac #+# #+# */
+/* Updated: 2020/06/18 12:48:20 by nahaddac ### ########.fr */
+/* */
+/* ************************************************************************** */
+
/*
** \file parse.c
** \brief Parser
@@ -5,61 +17,114 @@
#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)
+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 *parse(t_ftlst *input)
+t_ret *ret_wrap_ast(t_ast *ast, t_ftlst *rest)
{
- t_ret *ret;
- t_ret *first;
- enum e_token_tag tag;
-
- if(!(ret = malloc(sizeof(t_ret) * 1)))
- return(NULL);
- ret->rest = input;
- ret->ast = NULL;
+ t_ret *ret;
+
+ if ((ret = malloc(sizeof(t_ret))) == NULL)
+ return (NULL);
ret->unexpected = NULL;
- first = ret;
+ ret->rest = rest;
+ ret->ast = ast;
+ return ret;
+}
- while (ret->rest != NULL)
+t_ret *parse_cmd(t_ftlst *input)
+{
+ enum e_token_tag tag;
+ t_ast *ast;
+
+ ast = ast_new(AST_CMD);
+ while (input != NULL)
{
- tag = ((t_token *)ret->rest->data)->tag;
- if (parse_cmd_str_true_false(tag))
+ tag = ((t_token *)input->data)->tag;
+ if (tag & TAG_IS_STR)
{
- ret->ast = push_cmd(ret->ast, ret->rest);
+ push_token(&ast->cmd_argv, input->data);
}
- else if (parse_redir_true_false(tag))
+ else if (tag & TAG_IS_REDIR)
{
- while(ret->rest != NULL)
+ while(input != NULL)
{
- ret->ast = push_redir(ret->ast, ret->rest);
+ push_token(&ast->redirs, input->data);
if (tag & TAG_IS_STR && tag & TAG_STICK)
- ret->rest = ret->rest->next;
+ input = input->next;
else if (tag & TAG_IS_REDIR)
- ret->rest = ret->rest->next;
+ input = input->next;
else
- {
- //ret->rest = ret->rest->next;
break;
- }
- tag = ((t_token *)ret->rest->data)->tag;
+ tag = ((t_token *)input->data)->tag;
}
}
- ret->rest = ret->rest->next;
+ else
+ return ret_wrap_ast(ast, input);
+ input = input->next;
+ }
+ return ret_wrap_ast(ast, input);
+}
+
+// <cmd> ::= (<string> | <redir>)+
+// <op> ::= <expr> <sep> <op> | <expr>
+// <expr> ::= '(' <op> ')' | <cmd>
+
+t_ret *parse_op(t_ftlst *input)
+{
+ t_ast *ast;
+ t_ret *left_ret;
+ t_ret *right_ret;
+ enum e_token_tag sep_tag;
+
+ left_ret = parse_expr(input);
+ input = left_ret->rest;
+
+ if (input == NULL || ((t_token*)input->data)->tag == TAG_PARENT_CLOSE)
+ 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_expr(t_ftlst *input)
+{
+ t_ret *tmp;
+ enum e_token_tag tag;
+
+ tag = ((t_token*)input->data)->tag;
+ if (tag == TAG_PARENT_OPEN)
+ {
+ tmp = parse_op(input->next);
+ input = tmp->rest;
+ tag = ((t_token*)input->data)->tag;
+ if (tag != TAG_PARENT_CLOSE)
+ return (NULL);
+ input = input->next;
+ tmp->rest = input;
+ return tmp;
}
- /* 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;
+ return parse_cmd(input);
+}
+
+t_ret *parse(t_ftlst *input)
+{
+ return parse_op(input);
}
diff --git a/src/parse/redir_parse.c b/src/parse/redir_parse.c
index 839e37c..768506e 100755
--- a/src/parse/redir_parse.c
+++ b/src/parse/redir_parse.c
@@ -12,7 +12,6 @@ t_ast *push_redir(t_ast *ast, t_ftlst *rest)
{
t_ftlst *new;
- /* new = rest->data; */
if (ast == NULL)
{
ast = ast_new(AST_CMD);