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

2
libft

Submodule libft updated: f86c2cf5cb...b64ede50af

View File

@@ -1,27 +1,38 @@
#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:
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;
msg = error_messages[err];
}
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);
exit(err);

View File

@@ -1,15 +1,16 @@
#include "parser.h"
/**
TOKEN_VARIABLE, // x, y, etc.
TOKEN_NUMBER_INT, // int
TOKEN_NUMBER_DOUBLE, // double
TOKEN_POWER, // ^ or **
TOKEN_SIGN, // + or -
TOKEN_MULTIPLICATION, // *
TOKEN_DIVISION, // /
TOKEN_EQUAL, // =
TOKEN_END // null (end of input)
TOKEN_VARIABLE, // x, y, etc.
TOKEN_NUMBER_INT, // int
TOKEN_NUMBER_DOUBLE, // double
TOKEN_POWER, // ^ or **
TOKEN_SIGN_PLUS, // +
TOKEN_SIGN_MINUS, // -
TOKEN_FACTOR_MULT, // *
TOKEN_FACTOR_DIV, // / or :
TOKEN_EQUAL, // =
TOKEN_END // null (end of input)
1. VAR | NUMBER_I | NUMBER_D | ! POW | SIGN_P | SIGN_M | ! FACTOR_MUL | ! FACTOR_DIV | ! EQUAL | END
NT | NUMBER | NT | SIGN | ! FACTOR | NT | NT
@@ -17,8 +18,8 @@
2. VAR | NUMBER_I | NUMBER_D | ! POW | ! SIGN_P | ! SIGN_M | ! FACTOR_MUL | ! FACTOR_DIV | ! EQUAL | END
NT | NUMBER | NT | ! SIGN | ! FACTOR | NT | NT
3. VAR | NUMBER_I | NUMBER_D | ! POW | SIGN_P | SIGN_M | FACTOR_MUL | FACTOR_DIV | EQUAL | END
NT | NUMBER | NT | SIGN | FACTOR | NT | NT
3. VAR | ! NUMBER_I | ! NUMBER_D | ! POW | ! SIGN_P | ! SIGN_M | FACTOR_MUL | ! FACTOR_DIV | ! EQUAL | END
NT | ! NUMBER | NT | ! SIGN | FACTOR | NT | NT
term_position position;
term_sign sign;
@@ -32,15 +33,15 @@ static term_sign get_sign(token *tokens, int i, int *token_count)
// forbidden tokens
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)
{
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)
{
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
@@ -60,7 +61,7 @@ static term_sign get_sign(token *tokens, int i, int *token_count)
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)
@@ -72,19 +73,19 @@ static double get_coefficient(token *tokens, int i, int *token_count)
// forbidden tokens
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)
{
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)
{
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)
{
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
@@ -128,9 +129,41 @@ static double get_coefficient(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
return 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
}
int parse(token *tokens, term *terms, int terms_count_max)
@@ -139,13 +172,29 @@ int parse(token *tokens, term *terms, int terms_count_max)
int terms_count;
int token_count;
term_position term_position;
char var;
terms_count = 0;
token_count = 0;
i = 0;
term_position = TERM_LEFT;
var = 0;
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)
{
term_position = TERM_RIGHT;