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

Parserexec part2 #51

Merged
merged 3 commits into from
Jan 16, 2024
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
24 changes: 24 additions & 0 deletions src/ast/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,26 @@ char *ast_type_to_string(enum ast_type type)
return "AST_WORD";
case AST_EMPTY:
return "AST_EMPTY";
case AST_FOR:
return "AST_FOR";
case AST_WHILE:
return "AST_WHILE";
case AST_UNTIL:
return "AST_UNTIL";
case AST_AND_OR:
return "AST_AND_OR";
case AST_NEGATE:
return "AST_NEGATE";
case AST_PIPELINE:
return "AST_PIPELINE";
case AST_REDIRECTION:
return "AST_REDIRECTION";
case AST_AND:
return "AST_AND";
case AST_OR:
return "AST_OR";
case AST_COMMAND:
return "AST_COMMAND";
default:
return "UNKNOWN";
}
Expand All @@ -81,6 +101,10 @@ void print_ast(struct ast_node *node, int depth, bool logger_enabled)
for (int i = 0; i < depth; i++)
printf(" ");
printf("%s\n", ast_type_to_string(node->type));
if (node->type == AST_WORD)
{
printf("%s:\n", node->value);
}
logger(node->value, LOGGER_PARSER, logger_enabled);
for (int i = 0; i < node->children_count; i++)
print_ast(node->children[i], depth + 1, logger_enabled);
Expand Down
11 changes: 11 additions & 0 deletions src/ast/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ enum ast_type
AST_WORD,
AST_EMPTY,
AST_UNEXPECTED,
AST_REDIRECTION,
AST_PIPELINE,
AST_WHILE,
AST_UNTIL,
AST_FOR,
AST_AND_OR,
AST_NEGATE,
AST_AND,
AST_OR,
AST_COMMAND,
AST_WORD_ASSIGNMENT
};

/**
Expand Down
2 changes: 1 addition & 1 deletion src/execute/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
lib_LIBRARIES = libexecute.a

libexecute_a_SOURCES = ast_eval.c ast_eval.h ../parser/parser.h \
libexecute_a_SOURCES = pipeline.c loop.c ast_eval.c ast_eval.h ../parser/parser.h \
builtin.c builtin.h \
../ast/ast.h

Expand Down
10 changes: 10 additions & 0 deletions src/execute/ast_eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,16 @@ int match_ast(struct ast_node *node, bool logger_enabled)
return ast_eval_command_list(node, logger_enabled);
case AST_EMPTY:
return 0;
case AST_WHILE:
return while_loop(node, logger_enabled);
case AST_UNTIL:
return until_loop(node, logger_enabled);
case AST_FOR:
return for_loop(node, logger_enabled);
case AST_AND_OR:
return ast_and_or(node, logger_enabled);
case AST_PIPELINE:
return pipeline_eval(node, logger_enabled);
default:
return -1;
}
Expand Down
5 changes: 5 additions & 0 deletions src/execute/ast_eval.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,10 @@
* logger is enabled or not. \return The exit status of the last command.
*/
int match_ast(struct ast_node *node, bool logger_enabled);
int while_loop(struct ast_node *node, bool logger_enabled);
int until_loop(struct ast_node *node, bool logger_enabled);
int for_loop(struct ast_node *node, bool logger_enabled);
int pipeline_eval(struct ast_node *node, bool logger_enabled);
int ast_and_or(struct ast_node *node, bool logger_enabled);

#endif /* AST_EVAL_H */
42 changes: 42 additions & 0 deletions src/execute/loop.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include "../ast/ast.h"
#include "ast_eval.h"

int while_loop(struct ast_node *node, bool logger_enabled)
{
int status = 0;
while (match_ast(node->children[0], logger_enabled) == 0)
{
if (logger_enabled)
{
printf("while loop\n");
}
status = match_ast(node->children[1], logger_enabled);
}
return status;
}

int until_loop(struct ast_node *node, bool logger_enabled)
{
int status = 0;
while (match_ast(node->children[0], logger_enabled) != 0)
{
if (logger_enabled)
{
printf("until loop\n");
}
status = match_ast(node->children[1], logger_enabled);
}
return status;
}
int for_loop(struct ast_node *node, bool logger_enabled)
{
if (logger_enabled)
{
printf("for loop\n");
}
if (node == NULL)
{
return -1;
}
return 0;
}
88 changes: 88 additions & 0 deletions src/execute/pipeline.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include "../ast/ast.h"
#include "ast_eval.h"

#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h>

int pipeline_eval(struct ast_node *node, bool logger_enabled)
{
if (logger_enabled)
{
printf("pipeline\n");
}
int start = 0;
int stat = 0;
if (node->children_count > 0 && node->children[0]->type == AST_NEGATE)
{
start = 1;
}
int input_fd = STDIN_FILENO;
for (int i = start; i < node->children_count; i++)
{
int pipes[2];
if (i != node->children_count)
{
if (pipe(pipes) == -1)
{
return -1;
}
}
pid_t pid = fork();
if (pid == 0)
{
if (i != start)
{
dup2(input_fd, STDIN_FILENO);
close(input_fd);
}
if (i != node->children_count - 1)
{
dup2(pipes[1], STDOUT_FILENO);
close(pipes[0]);
close(pipes[1]);
}
stat = match_ast(node->children[i], logger_enabled);
exit(stat);
}
if (i != start)
close(input_fd);
if (i != node->children_count)
{
close(pipes[1]);
input_fd = pipes[0];
}
int status;
waitpid(pid, &status, 0);
stat = WEXITSTATUS(status);
}
if (start == 1)
{
stat = !stat;
}

return stat;
}

int ast_and_or(struct ast_node *node, bool logger_enabled)
{
int status = 0;
for (int i = 0; i < node->children_count; i++)
{
if (node->children[i]->type == AST_AND && status == 1)
{
printf("and\n");
i++;
}
else if (node->children[i]->type == AST_OR && status == 0)
{
i++;
}
else
{
status = match_ast(node->children[i], logger_enabled);
}
}
return status;
}
1 change: 1 addition & 0 deletions src/lexer/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct lex_match lex_match[] = {
{ "&&", TOKEN_AND }, { "||", TOKEN_OR }, { "|", TOKEN_PIPE },
{ "!", TOKEN_NEGATE }, { "<", TOKEN_REDIR }, { ">", TOKEN_REDIR },
{ ">>", TOKEN_REDIR }, { "<&", TOKEN_REDIR }, { ">&", TOKEN_REDIR },
{ "done", TOKEN_DONE},
{ ">|", TOKEN_REDIR }, { "<>", TOKEN_REDIR }
};

Expand Down
3 changes: 2 additions & 1 deletion src/lexer/token.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ enum token_type
TOKEN_NEGATE, // \!
TOKEN_REDIR, // >, <, >>, >&, <&, >|, <>
TOKEN_DOUBLE_QUOTE, // "
TOKEN_WORD_ASSIGNMENT // variable=
TOKEN_WORD_ASSIGNMENT, // variable=
TOKEN_DONE
};

/**
Expand Down
2 changes: 1 addition & 1 deletion src/parser/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ lib_LIBRARIES = libparser.a
libparser_a_SOURCES = parser.c parser.h \
parser_condition.c parser_element.c \
../ast/ast.c ../ast/ast.h \
../lexer/lexer.c ../lexer/lexer.h
../lexer/lexer.c ../lexer/lexer.h parser_functionnal.c

libparser_a_CFLAGS = -Wall -Wextra -Werror -std=c99 -pedantic
libparser_a_CPPFLAGS =-I$(top_srcdir)
2 changes: 2 additions & 0 deletions src/parser/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ int parser_loop(struct lexer *lexer, bool logger_enabled,
{
return 2;
}
//print_ast(ast, 0, logger_enabled);
if (pretty_print_enabled)
{
// print_ast(ast, 0, logger_enabled);
Expand All @@ -85,6 +86,7 @@ int parser_loop(struct lexer *lexer, bool logger_enabled,
return_value = match_ast(ast, logger_enabled);
if (return_value != 0 && return_value != 1)
{
printf("%d\n", return_value);
fprintf(stderr, "Error while executing\n");
// ast_free(ast);
// return return_value;
Expand Down
38 changes: 37 additions & 1 deletion src/parser/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "../lexer/lexer.h"
#include "../lexer/token.h"

#include <string.h>

/**
* \brief Parse loop the given lexer
* \param lexer The lexer to parse.
Expand Down Expand Up @@ -88,6 +90,7 @@ struct ast_node *pipeline(struct lexer *lexer);

/**
* \brief command = simple_command | shell_command ;
* \brief IMPORTANT !!! AST_COMMAND CAN HANDLE REDIRECTION !!
* \param lexer The lexer to parse.
* \return A pointer to the AST.
*/
Expand All @@ -107,6 +110,39 @@ struct ast_node *simple_command(struct lexer *lexer);
*/
struct ast_node *element(struct lexer *lexer);

/**
* \brief redirection = [IONUMBER] ( '>' | '<' | '>>' | '>&' | '<&' | '>|' | '<>' ) WORD ;
* \param lexer The lexer to parse.
* \return A pointer to the AST.
*/
struct ast_node *redirection(struct lexer *lexer);

/**
* \brief rule_while = 'while' compound_list 'do' compound_list 'done' ;
* \param lexer The lexer to parse.
* \return A pointer to the AST.
*/
struct ast_node *rule_while(struct lexer *lexer);

/**
* \brief rule_until = 'until' compound_list 'do' compound_list 'done' ;
* \param lexer The lexer to parse.
* \return A pointer to the AST.
*/
struct ast_node *rule_until(struct lexer *lexer);

/**
* \brief rule_for = 'for' WORD [in WORD {',' WORD}] 'do' compound_list 'done' ;
* \param lexer The lexer to parse.
* \return A pointer to the AST.
*/
struct ast_node *rule_for(struct lexer *lexer);
/**
* \brief redirection;
* \param lexer The lexer to parse.
* \return A pointer to the AST.
*/
struct ast_node *prefix(struct lexer *lexer);
/**
* \brief Return the next token type without consuming it.
* \param lexer The lexer to parse.
Expand All @@ -121,4 +157,4 @@ enum token_type parser_peek(struct lexer *lexer);
*/
enum token_type parser_pop(struct lexer *lexer);

#endif /* ! PARSER_H*/
#endif /* ! PARSER_H */
Loading
Loading