feat: toujours les mêmes qui font les pipes. Plus de assert dans ASTs (pour des raisons évidentes de stabilité du code) et nouveaux types (AST_PIPE et AST_NEG), + modifs random dans le parser
This commit is contained in:
parent
07e7d83c60
commit
96626d9850
27 changed files with 238 additions and 86 deletions
|
|
@ -4,8 +4,8 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "grammar_basic.h"
|
||||
#include "../lexer/lexer.h"
|
||||
#include "grammar_basic.h"
|
||||
|
||||
// === Static variables
|
||||
|
||||
|
|
@ -34,8 +34,8 @@ static bool add_first(enum rule rule, enum token_type token)
|
|||
|
||||
// Append
|
||||
item->list_length++;
|
||||
item->tokens = realloc(
|
||||
item->tokens, (item->list_length) * sizeof(enum token_type));
|
||||
item->tokens = realloc(item->tokens,
|
||||
(item->list_length) * sizeof(enum token_type));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -91,24 +91,6 @@ static void add_first_redir(enum rule rule)
|
|||
|
||||
// === Functions
|
||||
|
||||
bool is_token_redir(struct token *token)
|
||||
{
|
||||
switch (token->type)
|
||||
{
|
||||
case TOKEN_REDIR_LEFT:
|
||||
case TOKEN_REDIR_RIGHT:
|
||||
case TOKEN_REDIR_LEFT_RIGHT:
|
||||
case TOKEN_REDIR_DOUBLE_RIGHT:
|
||||
case TOKEN_REDIR_LEFT_AMP:
|
||||
case TOKEN_REDIR_RIGHT_AMP:
|
||||
case TOKEN_REDIR_RIGHT_PIPE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool grammar_init(void)
|
||||
{
|
||||
// Initialize the firsts map
|
||||
|
|
@ -119,17 +101,21 @@ bool grammar_init(void)
|
|||
// Populate the firsts map
|
||||
add_first(RULE_INPUT, TOKEN_WORD);
|
||||
add_first(RULE_INPUT, TOKEN_IF);
|
||||
add_first(RULE_COMMAND, TOKEN_NEGATION);
|
||||
add_first(RULE_INPUT, TOKEN_NEWLINE);
|
||||
add_first(RULE_INPUT, TOKEN_EOF);
|
||||
|
||||
add_first(RULE_LIST, TOKEN_WORD);
|
||||
add_first(RULE_LIST, TOKEN_IF);
|
||||
add_first(RULE_COMMAND, TOKEN_NEGATION);
|
||||
|
||||
add_first(RULE_AND_OR, TOKEN_WORD);
|
||||
add_first(RULE_AND_OR, TOKEN_IF);
|
||||
add_first(RULE_COMMAND, TOKEN_NEGATION);
|
||||
|
||||
add_first(RULE_PIPELINE, TOKEN_WORD);
|
||||
add_first(RULE_PIPELINE, TOKEN_IF);
|
||||
add_first(RULE_COMMAND, TOKEN_NEGATION);
|
||||
|
||||
add_first(RULE_COMMAND, TOKEN_WORD);
|
||||
add_first(RULE_COMMAND, TOKEN_IF);
|
||||
|
|
|
|||
|
|
@ -50,10 +50,6 @@ struct firsts_list {
|
|||
|
||||
// === Functions
|
||||
|
||||
/* @brief: returns true if token has a type redirection (not pipe or IONUMBER).
|
||||
*/
|
||||
bool is_token_redir(struct token *token);
|
||||
|
||||
/*
|
||||
* @brief Initializes the grammar submodule
|
||||
* @return PARSER_INIT_SUCCESS on success PARSER_INIT_ERROR on error
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
#include <stdbool.h>
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include "grammar_basic.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../utils/lists/lists.h"
|
||||
#include "grammar.h"
|
||||
#include "grammar_advanced.h"
|
||||
#include "grammar_basic.h"
|
||||
|
||||
// === Static functions
|
||||
|
||||
|
|
@ -108,7 +108,42 @@ struct ast *parse_and_or(struct lexer_context *ctx)
|
|||
|
||||
struct ast *parse_pipeline(struct lexer_context *ctx)
|
||||
{
|
||||
return parse_command(ctx);
|
||||
bool negation = false;
|
||||
struct token *token = PEEK_TOKEN();
|
||||
|
||||
// Eventual '!'
|
||||
if (token->type == TOKEN_NEGATION)
|
||||
{
|
||||
negation = true;
|
||||
POP_TOKEN();
|
||||
token = PEEK_TOKEN();
|
||||
}
|
||||
|
||||
// TODO handle negation (new AST type)
|
||||
|
||||
struct ast *left = parse_command(ctx);
|
||||
|
||||
token = PEEK_TOKEN();
|
||||
while (token->type == TOKEN_PIPE)
|
||||
{
|
||||
POP_TOKEN();
|
||||
|
||||
// skip newlines
|
||||
token = PEEK_TOKEN();
|
||||
while (token->type == TOKEN_NEWLINE)
|
||||
{
|
||||
POP_TOKEN();
|
||||
token = PEEK_TOKEN();
|
||||
}
|
||||
|
||||
struct ast *right = parse_command(ctx);
|
||||
|
||||
// Create AST
|
||||
left = ast_create_pipe(left, right);
|
||||
token = PEEK_TOKEN();
|
||||
}
|
||||
|
||||
return left;
|
||||
}
|
||||
|
||||
struct ast *parse_command(struct lexer_context *ctx)
|
||||
|
|
@ -125,7 +160,7 @@ struct ast *parse_command(struct lexer_context *ctx)
|
|||
}
|
||||
else
|
||||
{
|
||||
puts("Syntax error: expected command");
|
||||
puts("Syntax error: unexpected token");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -324,7 +359,7 @@ struct ast *parse_compound_list(struct lexer_context *ctx)
|
|||
return NULL;
|
||||
result_list = list_append(result_list, current_cmd);
|
||||
}
|
||||
|
||||
|
||||
token = PEEK_TOKEN();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,9 +28,9 @@ struct ast *parse_and_or(struct lexer_context *ctx);
|
|||
/*
|
||||
* @brief Only parses a command rule for the moment
|
||||
*
|
||||
* @code pipeline = command ;
|
||||
* @code pipeline = ['!'] command { '|' {'\n'} command } ;
|
||||
*
|
||||
* @first first(command)
|
||||
* @first '!', first(command)
|
||||
*/
|
||||
struct ast *parse_pipeline(struct lexer_context *ctx);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue