From 6da801675a7c2b3f3269bbc4e6ace5487847e139 Mon Sep 17 00:00:00 2001 From: matteo Date: Thu, 29 Jan 2026 11:18:56 +0100 Subject: [PATCH] feat(lexer): implementing assignements --- src/lexer/lexer.c | 18 +++++++++++++++++- src/lexer/lexer_utils.h | 15 +++++++++++---- src/parser/grammar_advanced.c | 14 +++++++++++++- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c index ff7f351..21f362b 100644 --- a/src/lexer/lexer.c +++ b/src/lexer/lexer.c @@ -78,6 +78,21 @@ static bool update_lexing_mode(char *stream, ssize_t i, return *lexing_mode != mode_before_update; } +/* @brief: updates the flags only_digits and equal_count + * according to the character at stream[i]. + */ +static void update_flags(char *stream, ssize_t i, struct lexer_context *ctx) +{ + if (stream[i] == '=') + { + ctx->equal_count++; + } + else if (!isdigit(stream[i]) && ctx->only_digits) + { + ctx->only_digits = false; + } +} + struct token *peek_token(struct lexer_context *ctx) { // we already created the upcoming token during the previous call to peek() @@ -100,6 +115,7 @@ struct token *peek_token(struct lexer_context *ctx) if (!update_lexing_mode(stream, i, &lexing_mode) && lexing_mode == LEXER_NORMAL) { + update_flags(stream, i, ctx); if (is_special_char(stream, i)) { if (i == 0) // where we create spe_char token @@ -121,7 +137,7 @@ struct token *peek_token(struct lexer_context *ctx) i++; } - struct token *tok = new_token(stream, i, ctx->only_digits); + struct token *tok = new_token(stream, i, ctx->only_digits, ctx->equal_count); // if token is comment, we don't want it if (tok->type == TOKEN_COMMENT) diff --git a/src/lexer/lexer_utils.h b/src/lexer/lexer_utils.h index c6c26c9..2708662 100644 --- a/src/lexer/lexer_utils.h +++ b/src/lexer/lexer_utils.h @@ -14,6 +14,9 @@ struct lexer_context // tells us if we only lexed digits in current token. bool only_digits; + // usefull to detect assignments, and syntax errors with '='. + int equal_count; + struct token *previous_token; struct token *current_token; }; @@ -34,10 +37,13 @@ enum token_type // Blanks TOKEN_NULL = 0, TOKEN_EOF, - TOKEN_WORD, TOKEN_NEWLINE, - // SPecial characters + // words + TOKEN_WORD, + TOKEN_ASSIGNMENT_WORD, + + // Special characters TOKEN_GRAVE, TOKEN_SEMICOLON, TOKEN_COMMENT, @@ -87,12 +93,13 @@ struct token */ bool is_special_char(char *stream, ssize_t i); -/* @brief: return a newly allocated token, with the corresponding type. +/* @brief: return a newly allocated token, with the type corresponding + * to the context given in arguments. * The data contains [size] char, starting from [begin]. * * @return: NULL on error, a token otherwise. */ -struct token *new_token(char *begin, ssize_t size, bool only_digits); +struct token *new_token(char *begin, ssize_t size, bool only_digits, int equal_count); /* @brief: frees the token given in argument */ diff --git a/src/parser/grammar_advanced.c b/src/parser/grammar_advanced.c index 8c4b68c..1964f49 100644 --- a/src/parser/grammar_advanced.c +++ b/src/parser/grammar_advanced.c @@ -66,5 +66,17 @@ struct ast *parse_redirection(struct lexer_context *ctx) struct ast *parse_prefix(struct lexer_context *ctx) { - return parse_redirection(ctx); + struct token *token = TOKEN_PEEK(); + if (token->type == TOKEN_ASSIGNMENT_WORD) + { + token = TOKEN_POP(); + return ast_create_assignment_word(token->data); + } + else if (is_first(*token, RULE_REDIRECTION)) + return parse_redirection(ctx); + else + { + perror("Syntax error: expected a prefix (redirection or assignment)"); + return NULL; + } }