fix: lot of fixes in parsing. Now code should be fully compliant with the doc grammar. WARNING: not tested yet

This commit is contained in:
Gu://em_ 2026-01-17 20:15:27 +01:00
parent f887c90ec5
commit 5d87e87f2e

View file

@ -59,18 +59,30 @@ struct ast *parse_list(void)
struct token *token = PEEK_TOKEN();
while (!is_end_of_list(token))
// and_or
current_node = parse_and_or();
if (current_node == NULL)
return NULL;
list_append(result_list, current_node);
// Following and_or commands
token = PEEK_TOKEN();
while (token->type == TOKEN_SEMICOLON)
{
if (token->type == TOKEN_SEMICOLON)
{
result_list = list_append(result_list, current_node);
}
else
token = POP_TOKEN();
if (!isterminator(token)) // Follow(list)
{
current_node = parse_and_or();
if (current_node == NULL)
{
//TODO free list
// There must be a function for that
return NULL;
}
list_append(result_list, current_node);
token = PEEK_TOKEN();
}
}
return ast_create_list(result_list);
}
@ -107,11 +119,17 @@ struct ast *parse_simple_command(void)
{
struct list *command_elements = NULL;
struct token *token = PEEK_TOKEN();
if (token->type != TOKEN_WORD)
{
puts("Expected a command but got a different token type");
return NULL;
}
while (token->type == TOKEN_WORD)
{
token = POP_TOKEN();
command_elements = list_append(command_elements, token->data);
char* word = strdup(token->data);
command_elements = list_append(command_elements, word);
token = PEEK_TOKEN();
}
@ -122,25 +140,13 @@ struct ast *parse_simple_command(void)
// TODO check compliance with the grammar
struct ast *parse_shell_command(void)
{
struct token *token = PEEK_TOKEN();
switch (token->type)
{
case TOKEN_IF:
return parse_if_rule();
default:
puts("I think it's not implemented yet");
return NULL;
}
}
// TODO check compliance with the grammar
struct ast *parse_if_rule(void)
{
// If condition
// If keyword
struct token *token = POP_TOKEN();
if (token->type != TOKEN_IF)
{
puts("Internal error: expected a if rule but token has different "
@ -148,27 +154,43 @@ struct ast *parse_if_rule(void)
return NULL;
}
// Condition content
struct ast *condition_content = parse_compound_list();
// Then content
// Then keyword
token = POP_TOKEN();
if (token->type != TOKEN_THEN)
{
ast_free(&condition_content);
puts("Expected the 'then' keyword but token has different type");
return NULL;
}
// Then content
struct ast *then_content = parse_compound_list();
if (then_content == NULL)
{
ast_free(&condition_content);
ast_free(&then_content);
return NULL;
}
// Eventual else/elif clause(s)
struct ast *else_content = parse_else_clause();
if (else_content == NULL)
{
ast_free(&condition_content);
ast_free(&then_content);
return NULL;
}
token = POP_TOKEN();
if (token->type != TOKEN_FI)
{
ast_free(&condition_content);
ast_free(&then_content);
ast_free(&else_content);
puts("Expected the 'fi' keyword but token has different type");
// TODO free previous asts
return NULL;
}
@ -176,44 +198,60 @@ struct ast *parse_if_rule(void)
ast_create_if(condition_content, then_content, else_content);
if (result == NULL)
{
ast_free(&condition_content);
ast_free(&then_content);
ast_free(&else_content);
puts("Internal error: could not create a new AST (AST_IF)");
// TODO free previous asts
return NULL;
}
return result;
}
// TODO comply with header's grammar
struct ast *parse_compound_list(void)
{
struct list *result_list = NULL; // ast* list
struct list *command_elements = NULL; // token* list
struct ast *current_cmd = NULL;
struct token *token = PEEK_TOKEN();
while (token->type != TOKEN_THEN || token->type != TOKEN_ELIF
|| token->type != TOKEN_ELSE)
{
// Parse simple command
if (token->type == TOKEN_SEMICOLON || token->type == TOKEN_NEWLINE)
{
// Stage (-> next command)
struct ast *command = ast_create_command(command_elements);
result_list = list_append(result_list, command);
command_elements = NULL;
}
if (token->type == TOKEN_EOF)
{
puts("Syntax error: Unexpected end of stream"); // TODO pas très
// bien dit
return NULL;
}
command_elements = list_append(command_elements, token->data);
// Skip newlines
while (token == TOKEN_NEWLINE)
token = POP_TOKEN();
// and_or
current_cmd = parse_and_or();
if (current_cmd == NULL)
return NULL;
list_append(result_list, current_cmd);
// Following commands
token = PEEK_TOKEN();
while (token->type == TOKEN_SEMICOLON || token->type TOKEN_NEWLINE)
{
POP_TOKEN();
// Skip newlines
while (token == TOKEN_NEWLINE)
token = POP_TOKEN();
// and_or
current_cmd = parse_and_or();
if (current_cmd == NULL)
return NULL;
list_append(result_list, current_cmd);
token = PEEK_TOKEN();
}
// Eventual semicolons
if (token->type == TOKEN_SEMICOLON)
token = POP_TOKEN();
// Skip newlines
while (token == TOKEN_NEWLINE)
token = POP_TOKEN();
struct ast *result = ast_create_list(result_list);
return result;
}
@ -222,7 +260,6 @@ struct ast *parse_else_clause(void)
{
struct token *token = PEEK_TOKEN();
// TODO handle ELIF
// Eventual elif content
while (token->type == TOKEN_ELIF)
{