feat(parser): parse_command version with prefixes and elements
This commit is contained in:
parent
9d586402df
commit
51fc8a3330
1 changed files with 50 additions and 19 deletions
|
|
@ -153,11 +153,11 @@ struct ast *parse_command(struct lexer_context *ctx)
|
||||||
{
|
{
|
||||||
struct token *token = PEEK_TOKEN();
|
struct token *token = PEEK_TOKEN();
|
||||||
|
|
||||||
if (token->type == TOKEN_WORD)
|
if (is_first(*token, RULE_SIMPLE_COMMAND))
|
||||||
{
|
{
|
||||||
return parse_simple_command(ctx);
|
return parse_simple_command(ctx);
|
||||||
}
|
}
|
||||||
else if (token->type == TOKEN_IF)
|
else if (is_first(*token, RULE_SHELL_COMMAND))
|
||||||
{
|
{
|
||||||
return parse_shell_command(ctx);
|
return parse_shell_command(ctx);
|
||||||
}
|
}
|
||||||
|
|
@ -168,23 +168,54 @@ struct ast *parse_command(struct lexer_context *ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* @brief: frees command_elements and redirections lists
|
||||||
|
* @return: NULL
|
||||||
|
*/
|
||||||
|
static err_simple_command(struct list *command_elements,
|
||||||
|
struct list *redirections)
|
||||||
|
{
|
||||||
|
list_deep_destroy(command_elements);
|
||||||
|
list_deep_destroy(redirections);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
struct ast *parse_simple_command(struct lexer_context *ctx)
|
struct ast *parse_simple_command(struct lexer_context *ctx)
|
||||||
{
|
{
|
||||||
struct list *command_elements = NULL;
|
struct list *command_elements = NULL;
|
||||||
struct list *redirections = NULL; // list of redirection ASTs
|
struct list *redirections = NULL; // list of redirection ASTs
|
||||||
|
|
||||||
// WORD
|
bool has_prefix = false;
|
||||||
struct token *token = POP_TOKEN();
|
struct token *token = PEEK_TOKEN();
|
||||||
if (token->type != TOKEN_WORD)
|
if (is_first(*token, RULE_PREFIX))
|
||||||
|
{
|
||||||
|
has_prefix = true;
|
||||||
|
while (is_first(*token, RULE_PREFIX))
|
||||||
|
{
|
||||||
|
struct ast *redir = parse_prefix(ctx);
|
||||||
|
if (redir == NULL)
|
||||||
|
{
|
||||||
|
return err_simple_command(command_elements, redirections);
|
||||||
|
}
|
||||||
|
redirections = list_append(redirections, redir);
|
||||||
|
token = PEEK_TOKEN();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token->type != TOKEN_WORD && !has_prefix)
|
||||||
{
|
{
|
||||||
perror("Expected a command but got a different token type");
|
perror("Expected a command but got a different token type");
|
||||||
return NULL;
|
return err_simple_command(command_elements, redirections);
|
||||||
}
|
}
|
||||||
char *command = strdup(token->data);
|
|
||||||
command_elements = list_append(command_elements, command);
|
|
||||||
|
|
||||||
token = PEEK_TOKEN();
|
// we can have only prefixes askip
|
||||||
|
if (token->type == TOKEN_WORD)
|
||||||
|
{
|
||||||
|
char *command = strdup(token->data);
|
||||||
|
command_elements = list_append(command_elements, command);
|
||||||
|
|
||||||
|
POP_TOKEN();
|
||||||
|
token = PEEK_TOKEN();
|
||||||
|
}
|
||||||
// Eventual elements
|
// Eventual elements
|
||||||
while (is_first(*token, RULE_ELEMENT))
|
while (is_first(*token, RULE_ELEMENT))
|
||||||
{
|
{
|
||||||
|
|
@ -192,16 +223,20 @@ struct ast *parse_simple_command(struct lexer_context *ctx)
|
||||||
struct ast *element = parse_element(ctx);
|
struct ast *element = parse_element(ctx);
|
||||||
if (element == NULL)
|
if (element == NULL)
|
||||||
{
|
{
|
||||||
list_deep_destroy(command_elements);
|
return err_simple_command(command_elements, redirections);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get element type
|
// Get element type
|
||||||
if (ast_is_word(element))
|
if (ast_is_word(element))
|
||||||
{
|
{
|
||||||
struct ast_word *element_word = ast_get_word(element);
|
struct ast_word *element_word = ast_get_word(element);
|
||||||
|
|
||||||
|
// TODO test this fix for the memory leaks
|
||||||
|
char *word = strdup(element_word->word);
|
||||||
|
ast_free(element_word);
|
||||||
command_elements =
|
command_elements =
|
||||||
list_append(command_elements, element_word->word);
|
list_append(command_elements, word);
|
||||||
|
// end of fix
|
||||||
}
|
}
|
||||||
else if (ast_is_redir(element))
|
else if (ast_is_redir(element))
|
||||||
{
|
{
|
||||||
|
|
@ -212,9 +247,7 @@ struct ast *parse_simple_command(struct lexer_context *ctx)
|
||||||
{
|
{
|
||||||
perror("Internal error: unexpected return value from parse_element "
|
perror("Internal error: unexpected return value from parse_element "
|
||||||
"in parse_simple_command");
|
"in parse_simple_command");
|
||||||
list_deep_destroy(command_elements);
|
return err_simple_command(command_elements, redirections);
|
||||||
list_deep_destroy(redirections);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward
|
// Forward
|
||||||
|
|
@ -225,9 +258,7 @@ struct ast *parse_simple_command(struct lexer_context *ctx)
|
||||||
struct ast *result = ast_create_command(command_elements, redirections);
|
struct ast *result = ast_create_command(command_elements, redirections);
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
{
|
{
|
||||||
list_deep_destroy(command_elements);
|
return err_simple_command(command_elements, redirections);
|
||||||
list_deep_destroy(redirections);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue