improved errors
This commit is contained in:
@@ -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
2
libft
Submodule libft updated: f86c2cf5cb...b64ede50af
47
src/errors.c
47
src/errors.c
@@ -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);
|
||||
|
||||
93
src/parser.c
93
src/parser.c
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user