improved errors

This commit is contained in:
hugogogo
2026-05-02 22:30:31 +02:00
parent 3977e6a6bb
commit c24461cb33
4 changed files with 109 additions and 49 deletions

View File

@@ -1,17 +1,17 @@
#ifndef ERRORS_H #ifndef ERRORS_H
#define ERRORS_H #define ERRORS_H
#include "../libft/includes/libft.h"
typedef enum typedef enum
{ {
ERROR_BASIC = 0, ERROR_BASE = 1, // Start at 1 to avoid exit(0) for errors
ERROR_UNKNOWN_TOKEN = -1, ERROR_UNKNOWN_TOKEN,
ERROR_NUMBER_TOO_BIG = -2, ERROR_NUMBER_TOO_BIG,
ERROR_PARSING = -3, ERROR_PARSING,
ERROR_TOKEN_POSITION = -4, ERROR_TOKEN_POSITION,
ERROR_VAR_DIFF,
ERROR_SENTINEL,
} program_error; } program_error;
int stop_errors(program_error err, const char *details); int stop_errors(program_error err, const char *format, ...);
#endif #endif

2
libft

Submodule libft updated: f86c2cf5cb...b64ede50af

View File

@@ -1,27 +1,38 @@
#include "errors.h" #include "errors.h"
#include "libft.h"
#include <stdarg.h>
int stop_errors(program_error err, const char *details) int stop_errors(program_error err, const char *details, ...)
{ {
switch (err) // the base error message
const char *msg = "error: error type is out of range";
// Map error codes to messages
const char *error_messages[] = {
[ERROR_BASE] = "error: undefined error, details :",
[ERROR_UNKNOWN_TOKEN] = "error: unknown token, details :",
[ERROR_NUMBER_TOO_BIG] = "error: number is too big, details :",
[ERROR_PARSING] = "error: too much terms to parse, details :",
[ERROR_TOKEN_POSITION] = "error: token position is not good in grammar, details :",
[ERROR_VAR_DIFF] = "error: expression must only contain one variable, details :",
// ⚠️ Add new error messages here when adding new error codes!
};
// Override msg if err is in the error_messages array
if (err >= ERROR_BASE && err < ERROR_SENTINEL)
{ {
case ERROR_UNKNOWN_TOKEN: msg = error_messages[err];
ft_putstr_fd("error: unknown token, details : ", STDERR_FILENO);
break;
case ERROR_NUMBER_TOO_BIG:
ft_putstr_fd("error: number is too big, details : ", STDERR_FILENO);
break;
case ERROR_PARSING:
ft_putstr_fd("error: too much terms to parse, details : ", STDERR_FILENO);
break;
case ERROR_TOKEN_POSITION:
ft_putstr_fd("error: token position is not good in grammar, details : ", STDERR_FILENO);
break;
default:
ft_putstr_fd("unknown error, details : ", STDERR_FILENO);
break;
} }
ft_putstr_fd(details, STDERR_FILENO); // Print the base message
ft_dprintf(STDERR_FILENO, "%s (%i) - ", msg, err);
// Print the formatted details directly
va_list args;
va_start(args, details);
ft_vdprintf(STDERR_FILENO, details, args);
va_end(args);
ft_putchar_fd('\n', STDERR_FILENO); ft_putchar_fd('\n', STDERR_FILENO);
exit(err); exit(err);

View File

@@ -5,9 +5,10 @@
TOKEN_NUMBER_INT, // int TOKEN_NUMBER_INT, // int
TOKEN_NUMBER_DOUBLE, // double TOKEN_NUMBER_DOUBLE, // double
TOKEN_POWER, // ^ or ** TOKEN_POWER, // ^ or **
TOKEN_SIGN, // + or - TOKEN_SIGN_PLUS, // +
TOKEN_MULTIPLICATION, // * TOKEN_SIGN_MINUS, // -
TOKEN_DIVISION, // / TOKEN_FACTOR_MULT, // *
TOKEN_FACTOR_DIV, // / or :
TOKEN_EQUAL, // = TOKEN_EQUAL, // =
TOKEN_END // null (end of input) TOKEN_END // null (end of input)
@@ -17,8 +18,8 @@
2. VAR | NUMBER_I | NUMBER_D | ! POW | ! SIGN_P | ! SIGN_M | ! FACTOR_MUL | ! FACTOR_DIV | ! EQUAL | END 2. VAR | NUMBER_I | NUMBER_D | ! POW | ! SIGN_P | ! SIGN_M | ! FACTOR_MUL | ! FACTOR_DIV | ! EQUAL | END
NT | NUMBER | NT | ! SIGN | ! FACTOR | NT | NT NT | NUMBER | NT | ! SIGN | ! FACTOR | NT | NT
3. VAR | NUMBER_I | NUMBER_D | ! POW | SIGN_P | SIGN_M | FACTOR_MUL | FACTOR_DIV | EQUAL | END 3. VAR | ! NUMBER_I | ! NUMBER_D | ! POW | ! SIGN_P | ! SIGN_M | FACTOR_MUL | ! FACTOR_DIV | ! EQUAL | END
NT | NUMBER | NT | SIGN | FACTOR | NT | NT NT | ! NUMBER | NT | ! SIGN | FACTOR | NT | NT
term_position position; term_position position;
term_sign sign; term_sign sign;
@@ -32,15 +33,15 @@ static term_sign get_sign(token *tokens, int i, int *token_count)
// forbidden tokens // forbidden tokens
if (tokens[i].type == TOKEN_POWER) if (tokens[i].type == TOKEN_POWER)
{ {
stop_errors(ERROR_TOKEN_POSITION, "at begining of term, we should not have a power token : " + tokens[i].value_char); stop_errors(ERROR_TOKEN_POSITION, "at sign place, we should not have a token 'power' : %c", tokens[i].value_char);
} }
if (tokens[i].tag == TOKEN_FACTOR) if (tokens[i].tag == TOKEN_FACTOR)
{ {
stop_errors(ERROR_TOKEN_POSITION, "at begining of term, we should not have a factor token : " + tokens[i].value_char); stop_errors(ERROR_TOKEN_POSITION, "at sign place, we should not have a token 'factor' : %c", tokens[i].value_char);
} }
if (tokens[i].type == TOKEN_EQUAL) if (tokens[i].type == TOKEN_EQUAL)
{ {
stop_errors(ERROR_TOKEN_POSITION, "at begining of term, we should not have an equal token : " + tokens[i].value_char); stop_errors(ERROR_TOKEN_POSITION, "at sign place, we should not have a token 'equal' : %c", tokens[i].value_char);
} }
// sign // sign
@@ -60,7 +61,7 @@ static term_sign get_sign(token *tokens, int i, int *token_count)
return '+'; return '+';
} }
return stop_errors(ERROR_TOKEN_POSITION, "at begining of term, we should have a sign token " + tokens[i].value_char); return stop_errors(ERROR_TOKEN_POSITION, "at begining of term, we should have a token 'sign' : %c", tokens[i].value_char);
} }
static double get_coefficient(token *tokens, int i, int *token_count) static double get_coefficient(token *tokens, int i, int *token_count)
@@ -72,19 +73,19 @@ static double get_coefficient(token *tokens, int i, int *token_count)
// forbidden tokens // forbidden tokens
if (tokens[i].type == TOKEN_POWER) if (tokens[i].type == TOKEN_POWER)
{ {
stop_errors(ERROR_TOKEN_POSITION, "at coefficient place, we should not have a power token : " + tokens[i].value_char); stop_errors(ERROR_TOKEN_POSITION, "at coefficient place, we should not have a token 'power' : %c", tokens[i].value_char);
} }
if (tokens[i].tag == TOKEN_FACTOR) if (tokens[i].tag == TOKEN_FACTOR)
{ {
stop_errors(ERROR_TOKEN_POSITION, "at coefficient place, we should not have a factor token : " + tokens[i].value_char); stop_errors(ERROR_TOKEN_POSITION, "at coefficient place, we should not have a token 'factor' : %c", tokens[i].value_char);
} }
if (tokens[i].type == TOKEN_EQUAL) if (tokens[i].type == TOKEN_EQUAL)
{ {
stop_errors(ERROR_TOKEN_POSITION, "at coefficient place, we should not have an equal token : " + tokens[i].value_char); stop_errors(ERROR_TOKEN_POSITION, "at coefficient place, we should not have a token 'equal' : %c", tokens[i].value_char);
} }
if (tokens[i].tag == TOKEN_SIGN) if (tokens[i].tag == TOKEN_SIGN)
{ {
stop_errors(ERROR_TOKEN_POSITION, "at coefficient place, we should not have a sign token : " + tokens[i].value_char); stop_errors(ERROR_TOKEN_POSITION, "at coefficient place, we should not have a token 'sign' : %c", tokens[i].value_char);
} }
// if not coefficient token // if not coefficient token
@@ -128,8 +129,40 @@ static double get_coefficient(token *tokens, int i, int *token_count)
static int get_exponent(token *tokens, int i, int *token_count) static int get_exponent(token *tokens, int i, int *token_count)
{ {
if (tokens[i].type) // placeholder /**
*token_count = 1; // placeholder * power
* number
* sign
* equal
* factor_div
*/
// forbidden tokens
if (tokens[i].type == TOKEN_POWER)
{
stop_errors(ERROR_TOKEN_POSITION, "at exponent place, we should not have a token 'power' : %c", tokens[i].value_char);
}
if (tokens[i].tag == TOKEN_NUMBER)
{
stop_errors(ERROR_TOKEN_POSITION, "at exponent place, we should not have a token 'number' : %c", tokens[i].value_char);
}
if (tokens[i].tag == TOKEN_SIGN)
{
stop_errors(ERROR_TOKEN_POSITION, "at exponent place, we should not have a token 'sign' : %c", tokens[i].value_char);
}
if (tokens[i].type == TOKEN_EQUAL)
{
stop_errors(ERROR_TOKEN_POSITION, "at exponent place, we should not have a token 'equal' : %c", tokens[i].value_char);
}
if (tokens[i].type == TOKEN_FACTOR_DIV)
{
stop_errors(ERROR_TOKEN_POSITION, "at exponent place, we should not have a token 'division' : %c", tokens[i].value_char);
}
// if 'var' -> token_count + 1
// else if '*' + 'var' -> token_count + 2
token_count += 0; // placeholder
return 1; // placeholder return 1; // placeholder
} }
@@ -139,13 +172,29 @@ int parse(token *tokens, term *terms, int terms_count_max)
int terms_count; int terms_count;
int token_count; int token_count;
term_position term_position; term_position term_position;
char var;
terms_count = 0; terms_count = 0;
token_count = 0; token_count = 0;
i = 0; i = 0;
term_position = TERM_LEFT; term_position = TERM_LEFT;
var = 0;
while (tokens[i].type != TOKEN_END && terms_count < terms_count_max) while (tokens[i].type != TOKEN_END && terms_count < terms_count_max)
{ {
// variable -> all variables must be the same
if (tokens[i].type == TOKEN_VARIABLE)
{
if (!var)
{
var = tokens[i].value_char;
}
else if (var != tokens[i].value_char)
{
stop_errors(ERROR_VAR_DIFF, "old var : '%c' - new var : '%c'", var, tokens[i].value_char);
}
}
// equal
if (tokens[i].type == TOKEN_EQUAL) if (tokens[i].type == TOKEN_EQUAL)
{ {
term_position = TERM_RIGHT; term_position = TERM_RIGHT;