Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【軽PR】x_mallocの使用 & ファイル構成の変更 #112

Merged
merged 3 commits into from
Oct 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ EXECUTE_PATH = execute
WRAPPER_PATH = wrapper
EXPANDER_PATH = expander
PARSER_PATH = parser
PARSER_INT_PATH = parser/internal
LEXER_PATH = lexer
AST_PATH = ast
UTILS_PATH = utils
BUILTIN_PATH = builtin
ENV_PATH = env

SRC_PATHS = $(CURRENT_PATH) $(EXPANDER_PATH) $(WRAPPER_PATH) $(BUILTIN_PATH) $(EXECUTE_PATH) $(PARSER_PATH) $(LEXER_PATH) $(AST_PATH) $(UTILS_PATH) $(ENV_PATH)
SRC_PATHS = $(CURRENT_PATH) $(EXPANDER_PATH) $(WRAPPER_PATH) $(BUILTIN_PATH) $(EXECUTE_PATH) $(PARSER_PATH) $(PARSER_INT_PATH) $(LEXER_PATH) $(AST_PATH) $(UTILS_PATH) $(ENV_PATH)
SRCS = $(foreach path, $(SRC_PATHS), $(wildcard $(path)/*.c))

VPATH = $(CURRENT_PATH):$(BUILTIN_PATH):$(EXECUTE_PATH):$(WRAPPER_PATH):$(PARSER_PATH):$(LEXER_PATH):$(AST_PATH):$(UTILS_PATH):$(ENV_PATH):$(EXPANDER_PATH)
VPATH = $(CURRENT_PATH):$(BUILTIN_PATH):$(EXECUTE_PATH):$(WRAPPER_PATH):$(PARSER_PATH):$(PARSER_INT_PATH):$(LEXER_PATH):$(AST_PATH):$(UTILS_PATH):$(ENV_PATH):$(EXPANDER_PATH)

OBJDIR = ./obj
OBJS = $(addprefix $(OBJDIR)/, $(notdir $(SRCS:.c=.o)))
Expand Down
8 changes: 3 additions & 5 deletions ast/ast.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <stdlib.h>
#include "ast.h"
#include "../wrapper/x.h"

void set_ast_nodes(t_ast_node *root, t_ast_node *left, t_ast_node *right)
{
Expand All @@ -20,16 +21,13 @@ void *delete_ast_nodes(t_ast_node *node1, t_ast_node *node2)
return (NULL);
}

bool new_ast_node(t_ast_node **node)
void new_ast_node(t_ast_node **node)
{
*node = (t_ast_node *)malloc(sizeof(**node));
if (!*node)
return (false);
*node = x_malloc(sizeof(**node));
(*node)->left = NULL;
(*node)->right = NULL;
(*node)->data = NULL;
(*node)->type = UNSET_NODE;
return (true);
}

bool assign_ast_node(t_ast_node **dst, t_ast_node *src)
Expand Down
3 changes: 1 addition & 2 deletions ast/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ typedef enum e_node_type {
REDIRECT_IN_NODE,
REDIRECT_APPEND_NODE,
HEREDOC_NODE,
REDIRECT_OPERAND_NODE,
SUBSHELL_NODE,
SUBSHELL_NEWLINE_MS_NODE,
} t_node_type;
Expand All @@ -30,7 +29,7 @@ struct s_ast_node {
};
void set_ast_nodes(t_ast_node *root, t_ast_node *left, t_ast_node *right);
void *delete_ast_nodes(t_ast_node *node1, t_ast_node *node2);
bool new_ast_node(t_ast_node **node);
void new_ast_node(t_ast_node **node);
bool assign_ast_node(t_ast_node **dst, t_ast_node *src);
void attach_ast_nodes(t_ast_node *root, t_ast_node *left, t_ast_node *right);

Expand Down
14 changes: 7 additions & 7 deletions execute/execute_init.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#include "execute.h"
#include "exit_status.h"

static int command_line(t_executor *e, t_ast_node *node);
static int init_command_line(t_executor *e, t_ast_node *node);
static void pipeline(t_executor *e, t_pipeline **pipeline, t_ast_node *node);
static void subshell(t_executor *e, t_subshell **ss, t_ast_node *node);
static void simple_command(t_executor *e, t_simple_command **sc, t_ast_node *node);
static void init_simple_command(t_executor *e, t_simple_command **sc, t_ast_node *node);

int execute(t_ast_node *root, t_env_var **env_vars)
{
Expand All @@ -17,13 +17,13 @@ int execute(t_ast_node *root, t_env_var **env_vars)
return (ES_SYNTAX_ERROR);
}
new_executor(&e, root, env_vars);
exit_status = command_line(e, root);
exit_status = init_command_line(e, root);
delete_ast_nodes(e->root, NULL);
free(e);
return (exit_status);
}

int command_line(t_executor *e, t_ast_node *node)
int init_command_line(t_executor *e, t_ast_node *node)
{
if (node->type == AND_IF_NODE || node->type == OR_IF_NODE)
{
Expand All @@ -38,7 +38,7 @@ int command_line(t_executor *e, t_ast_node *node)
e->condition = CONDITION_AND_IF;
else if (node->type == OR_IF_NODE)
e->condition = CONDITION_OR_IF;
return (command_line(e, node->right));
return (init_command_line(e, node->right));
}
else
{
Expand Down Expand Up @@ -72,7 +72,7 @@ void pipeline(t_executor *e, t_pipeline **pipeline_, t_ast_node *node)
}
else
{
simple_command(e, (t_simple_command **)&(*pipeline_)->command, node);
init_simple_command(e, (t_simple_command **)&(*pipeline_)->command, node);
(*pipeline_)->type = T_SIMPLE_COMMAND;
}
if (pipeline_next)
Expand Down Expand Up @@ -111,7 +111,7 @@ void init_compound_list(t_executor *e, t_compound_list **cl, t_ast_node *node)
}

// expected node: COMMAND_ARG_NODE, REDIRECT*
void simple_command(t_executor *e, t_simple_command **sc, t_ast_node *node)
void init_simple_command(t_executor *e, t_simple_command **sc, t_ast_node *node)
{
new_t_simple_command(sc);
(*sc)->root = node;
Expand Down
4 changes: 2 additions & 2 deletions expander/expander.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <dirent.h>
#include "expander.h"

t_ast_node *search_command_arg_node(t_expander *e, t_ast_node *node);
Expand Down Expand Up @@ -176,8 +177,7 @@ t_ast_node *word_splitting(t_ast_node *node, t_expander *e, char *original_data)
}
else
{
if (!new_ast_node(&result))
exit(expand_perror(e, "malloc"));
new_ast_node(&result);
result->data = remove_quotes(split[i], e);
result->type = COMMAND_ARG_NODE;
node->right = result;
Expand Down
2 changes: 1 addition & 1 deletion expander/expander.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# include "../token/token.h"
# include "../lexer/lexer.h"
# include "../ast/ast.h"
# include "../parser/parser.h"
# include "../parser/internal/internal.h"
# include "../libft/libft.h"
# include "../utils/utils.h"
# include "../execute/execute.h"
Expand Down
2 changes: 1 addition & 1 deletion minishell.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <sys/ioctl.h>

#include "libft/libft.h"
#include "parser/parser.h"
#include "parser/parse.h"
#include "lexer/lexer.h"
#include "expander/expander.h"
#include "execute/execute.h"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ディレクトリとヘッダ名は[verb-er]/[verb]の形で統一します?

Copy link
Owner Author

@takumihara takumihara Oct 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parse.hで宣言する関数がparse()だけだったので、parse.hにしました!
それで大丈夫でそうですか?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

個人的には、ディレクトリ名とヘッダ名を同じにした方が見やすい感はありますね

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

関数名は動詞の方がいいですよね?lex()``parse()みたいな

Expand Down
149 changes: 149 additions & 0 deletions parser/internal/command_line.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#include "internal.h"

//<pipeline> '&&' <newline> <command_line>
//<pipeline> '||' <newline> <command_line>
//<pipeline>
t_ast_node *command_line(t_parser *p);

//<command> '|' <newline> <pipeline>
//<command>
static t_ast_node *pipeline(t_parser *p);

//<subshell>
//<simple_command>
static t_ast_node *command(t_parser *p);

//'(' <compound_list> ')' <redirection_list>
//'(' <compound_list> ')'
static t_ast_node *subshell(t_parser *p);

//<pipeline> '&&' <compound_list>
//<pipeline> '||' <compound_list>
//<pipeline> '\n' <compound_list>
//<pipeline>
static t_ast_node *compound_list(t_parser *p);

t_ast_node *command_line(t_parser *p)
{
t_ast_node *result;
t_ast_node *pipeline_;
t_ast_node *commandline_;

if (!assign_ast_node(&pipeline_, pipeline(p)))
return (NULL);
new_ast_node(&result);
if (consume_token(p, AND_IF, NULL))
result->type = AND_IF_NODE;
else if (consume_token(p, OR_IF, NULL))
result->type = OR_IF_NODE;
else if (p->token->type == EOL)
{
free(result);
return (pipeline_);
}
else
{
p->err = ERR_UNEXPECTED_TOKEN;
return (delete_ast_nodes(pipeline_, result));
}
if (!assign_ast_node(&commandline_, command_line(p)))
{
p->err = ERR_UNEXPECTED_EOF;
return (delete_ast_nodes(pipeline_, result));
}
set_ast_nodes(result, pipeline_, commandline_);
return (result);
}

t_ast_node *pipeline(t_parser *p)
{
t_ast_node *result;
t_ast_node *command_;
t_ast_node *pipeline_;

if (!assign_ast_node(&command_, command(p)))
return (NULL);
if (!consume_token(p, PIPE, NULL))
return (command_);
if (!assign_ast_node(&pipeline_, pipeline(p)))
{
if (!p->err)
p->err = ERR_UNEXPECTED_EOF;
return (delete_ast_nodes(command_, NULL));
}
new_ast_node(&result);
result->type = PIPE_NODE;
set_ast_nodes(result, command_, pipeline_);
return (result);
}

t_ast_node *command(t_parser *p)
{
const t_token *tmp = p->token;
t_ast_node *node;

if (assign_ast_node(&node, subshell(p)))
return (node);
if (p->err)
return (NULL);
p->token = (t_token *)tmp;
if (assign_ast_node(&node, simple_command(p)))
return (node);
return (NULL);
}

t_ast_node *subshell(t_parser *p)
{
t_ast_node *result;
t_ast_node *compound_list_;

if (!consume_token(p, LPAREN, NULL))
return (NULL);
p->is_subshell = true;
consume_token(p, SUBSHELL_NEWLINE_MS, NULL);
if (!assign_ast_node(&compound_list_, compound_list(p)))
{
if (!p->err)
p->err = ERR_UNEXPECTED_TOKEN;
return (NULL);
}
if (!consume_token(p, RPAREN, NULL))
{
p->err = ERR_UNEXPECTED_EOF;
return (delete_ast_nodes(compound_list_, NULL));
}
p->is_subshell = false;
new_ast_node(&result);
result->type = SUBSHELL_NODE;
set_ast_nodes(result, compound_list_, NULL);
return (result);
}

t_ast_node *compound_list(t_parser *p)
{
t_ast_node *result;
t_ast_node *pipeline_;
t_ast_node *compound_list_;

if (!assign_ast_node(&pipeline_, pipeline(p)))
return (NULL);
new_ast_node(&result);
if (consume_token(p, AND_IF, NULL))
result->type = AND_IF_NODE;
else if (consume_token(p, OR_IF, NULL))
result->type = OR_IF_NODE;
else if (consume_token(p, SUBSHELL_NEWLINE_MS, NULL))
result->type = SUBSHELL_NEWLINE_MS_NODE;
else
{
free(result);
return (pipeline_);
}
if (!assign_ast_node(&compound_list_, compound_list(p)))
{
p->err = ERR_UNEXPECTED_EOF;
return (delete_ast_nodes(pipeline_, result));
}
set_ast_nodes(result, pipeline_, compound_list_);
return (result);
}
37 changes: 37 additions & 0 deletions parser/internal/internal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef INTERNAL_H
# define INTERNAL_H

# include <stdbool.h>
# include <unistd.h>

# include "../../token/token.h"
# include "../../lexer/lexer.h"
# include "../../ast/ast.h"
# include "../../libft/libft.h"
# include "../../utils/utils.h"

# define ERR_UNEXPECTED_TOKEN 1
# define ERR_UNEXPECTED_EOF 2

//# define TEST

typedef struct t_parser {
t_token *token;
int err;
bool is_subshell;
} t_parser;

// parser_utils.c
t_parser *new_parser(t_token *token);
bool consume_token(t_parser *p, t_token_type expected, t_ast_node *node);

# ifdef TEST
char *handle_err(t_parser *p);
# else
bool handle_err(t_parser *p);
# endif

t_ast_node *command_line(t_parser *p);
t_ast_node *simple_command(t_parser *p);

#endif //INTERNAL_H
Loading