merge parser into dev with ast loops
This commit is contained in:
commit
4d271981df
10 changed files with 343 additions and 26 deletions
|
|
@ -26,6 +26,29 @@ static enum ast_and_or_type and_or_tok_to_ast(enum token_type tok_type)
|
|||
}
|
||||
}
|
||||
|
||||
/* @brief: frees command_elements and redirections lists (helper func)
|
||||
* @return: NULL
|
||||
*/
|
||||
static void *err_simple_command(struct list *command_elements,
|
||||
struct list *redirections)
|
||||
{
|
||||
list_deep_destroy(command_elements);
|
||||
list_deep_destroy(redirections);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* @brief: frees all the arguments. (helper func)
|
||||
* @return: NULL.
|
||||
*/
|
||||
static void *err_if_rule(struct ast **cond, struct ast **then_clause,
|
||||
struct ast **else_clause)
|
||||
{
|
||||
ast_free(cond);
|
||||
ast_free(then_clause);
|
||||
ast_free(else_clause);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// === Functions
|
||||
|
||||
struct ast *parse_list(struct lexer_context *ctx)
|
||||
|
|
@ -73,16 +96,11 @@ struct ast *parse_and_or(struct lexer_context *ctx)
|
|||
|
||||
while (token->type == TOKEN_AND || token->type == TOKEN_OR)
|
||||
{
|
||||
// Set left part
|
||||
|
||||
// Build AST (left part)
|
||||
enum ast_and_or_type type = and_or_tok_to_ast(token->type);
|
||||
struct ast *left = result;
|
||||
|
||||
// eat and_or token
|
||||
token = POP_TOKEN();
|
||||
|
||||
// Set type
|
||||
enum ast_and_or_type type = and_or_tok_to_ast(token->type);
|
||||
|
||||
POP_TOKEN();
|
||||
token = PEEK_TOKEN();
|
||||
|
||||
// Skip newlines
|
||||
|
|
@ -94,6 +112,12 @@ struct ast *parse_and_or(struct lexer_context *ctx)
|
|||
|
||||
// Right part
|
||||
struct ast *right = parse_pipeline(ctx);
|
||||
if (right == NULL)
|
||||
{
|
||||
ast_free(&left);
|
||||
return NULL;
|
||||
}
|
||||
token = PEEK_TOKEN();
|
||||
|
||||
result = ast_create_and_or(left, right, type);
|
||||
if (result == NULL)
|
||||
|
|
@ -120,30 +144,33 @@ struct ast *parse_pipeline(struct lexer_context *ctx)
|
|||
token = PEEK_TOKEN();
|
||||
}
|
||||
|
||||
// command rule
|
||||
struct ast *left = parse_command(ctx);
|
||||
token = PEEK_TOKEN();
|
||||
if (negation)
|
||||
{
|
||||
left = ast_create_neg(negation, left);
|
||||
}
|
||||
|
||||
token = PEEK_TOKEN();
|
||||
// Pipes
|
||||
while (token->type == TOKEN_PIPE)
|
||||
{
|
||||
POP_TOKEN();
|
||||
token = PEEK_TOKEN();
|
||||
|
||||
// skip newlines
|
||||
token = PEEK_TOKEN();
|
||||
while (token->type == TOKEN_NEWLINE)
|
||||
{
|
||||
POP_TOKEN();
|
||||
token = PEEK_TOKEN();
|
||||
}
|
||||
|
||||
// command rule
|
||||
struct ast *right = parse_command(ctx);
|
||||
token = PEEK_TOKEN();
|
||||
|
||||
// Create AST
|
||||
left = ast_create_pipe(left, right);
|
||||
token = PEEK_TOKEN();
|
||||
}
|
||||
|
||||
return left;
|
||||
|
|
@ -162,6 +189,11 @@ struct ast *parse_command(struct lexer_context *ctx)
|
|||
{
|
||||
result = parse_shell_command(ctx);
|
||||
}
|
||||
// WARNING funcdec seems to require a LL(2) parser
|
||||
else if (is_first(*token, RULE_FUNCDEC))
|
||||
{
|
||||
result = parse_funcdec(ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("Syntax error: unexpected token");
|
||||
|
|
@ -336,19 +368,41 @@ struct ast *parse_element(struct lexer_context *ctx)
|
|||
|
||||
struct ast *parse_shell_command(struct lexer_context *ctx)
|
||||
{
|
||||
return parse_if_rule(ctx);
|
||||
}
|
||||
struct token *token = PEEK_TOKEN();
|
||||
struct ast *result = NULL;
|
||||
|
||||
/* @brief: frees all the arguments. (helper func)
|
||||
* @return: NULL.
|
||||
*/
|
||||
static void *err_if_rule(struct ast **cond, struct ast **then_clause,
|
||||
struct ast **else_clause)
|
||||
{
|
||||
ast_free(cond);
|
||||
ast_free(then_clause);
|
||||
ast_free(else_clause);
|
||||
return NULL;
|
||||
// Grouping
|
||||
// '(' or '{'
|
||||
if (token->type == TOKEN_LEFT_BRACKET || token->type == TOKEN_LEFT_PAREN)
|
||||
{
|
||||
POP_TOKEN();
|
||||
result = parse_compound_list(ctx);
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
|
||||
// ')' or '}'
|
||||
token = PEEK_TOKEN();
|
||||
if (token->type == TOKEN_LEFT_BRACKET
|
||||
|| token->type == TOKEN_LEFT_PAREN)
|
||||
{
|
||||
ast_free(&result);
|
||||
perror("Syntax error: bracket/parenthesis mismatch");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
POP_TOKEN();
|
||||
return result;
|
||||
}
|
||||
else if (is_first(*token, RULE_IF))
|
||||
{
|
||||
return parse_if_rule(ctx);
|
||||
}
|
||||
// TODO loops and case
|
||||
else
|
||||
{
|
||||
perror("Syntax error: unexpected token in parse_shell_command");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct ast *parse_if_rule(struct lexer_context *ctx)
|
||||
|
|
@ -497,7 +551,6 @@ struct ast *parse_else_clause(struct lexer_context *ctx)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// Then clause
|
||||
struct ast *then_content = parse_compound_list(ctx);
|
||||
|
||||
// Eventual else clause (recursive)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue