Compare commits
2 Commits
7f06d505d1
...
93647b56b5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93647b56b5 | ||
|
|
8a479c3c3b |
16
Makefile
16
Makefile
@@ -96,16 +96,16 @@ $(NAME): $(OBJS)
|
|||||||
$(CC) $(OBJS) -o $@ $(LFLAGS)
|
$(CC) $(OBJS) -o $@ $(LFLAGS)
|
||||||
|
|
||||||
run: $(NAME)
|
run: $(NAME)
|
||||||
@echo $(BLUE)"\n -> run \n"$(RESET)
|
@echo $(B_PURPLE)"\n---------------------------------------------\n1. run with flag '-d' as last \n"$(RESET)
|
||||||
./$(NAME) -d "3.4 * x^2 + 1 * x^1 - 2.0 * x^0 = 5.123 * x^1"
|
./$(NAME) "3.4 * x^2 + 1 * x^1 - 2.0 * x^0 = 5.123 * x^1" -d
|
||||||
@echo $(BLUE)"\n -> run \n"$(RESET)
|
@echo $(B_PURPLE)"\n---------------------------------------------\n2. run without flag \n"$(RESET)
|
||||||
./$(NAME) -d "3 * x^2 + 5 * x^1 - 2 * x^0 = 5 * x^1"
|
./$(NAME) "3 * x^2 + 5 * x^1 - 2 * x^0 = 5 * x^1"
|
||||||
@echo $(BLUE)"\n -> run \n"$(RESET)
|
@echo $(B_PURPLE)"\n---------------------------------------------\n3. run with flag '-d' as first \n"$(RESET)
|
||||||
./$(NAME) -d "3*x^2 + 2*x = 0"
|
./$(NAME) -d "3*x^2 + 2*x = 0"
|
||||||
@echo $(BLUE)"\n -> run \n"$(RESET)
|
@echo $(B_PURPLE)"\n---------------------------------------------\n4. run with wrong flag '-e' \n"$(RESET)
|
||||||
|
-./$(NAME) -d -e "3*x^2 + 2*x -7x^4 = x^4"
|
||||||
|
@echo $(B_PURPLE)"\n---------------------------------------------\n5. run \n"$(RESET)
|
||||||
./$(NAME) -d "3*x^2 + 2*x -7x^3 = x^3"
|
./$(NAME) -d "3*x^2 + 2*x -7x^3 = x^3"
|
||||||
@echo $(BLUE)"\n -> run \n"$(RESET)
|
|
||||||
./$(NAME) -d "3*x^2 + 2*x -7x^4 = x^4"
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM_OBJS)
|
$(RM_OBJS)
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
#include <stdio.h> // tmp for printf, for float debug
|
#include <stdio.h> // tmp for printf, for float debug
|
||||||
#include <stdarg.h> // for va_list
|
#include <stdarg.h> // for va_list
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <errno.h> // for errno
|
||||||
|
#include <string.h> // for strerror
|
||||||
|
|
||||||
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
* COMPUTORV1.C
|
* COMPUTORV1.C
|
||||||
@@ -96,22 +98,8 @@ void reduce(s_term *terms, double *polynom);
|
|||||||
* UTILS/ERRORS.C
|
* UTILS/ERRORS.C
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
ERROR_BASE = 1, // start at 1 to avoid exit(0) for errors
|
|
||||||
ARGUMENTS_ERROR,
|
|
||||||
ERROR_TOKEN_COUNT,
|
|
||||||
ERROR_UNKNOWN_TOKEN,
|
|
||||||
ERROR_NUMBER_TOO_BIG,
|
|
||||||
ERROR_PARSING,
|
|
||||||
ERROR_TERM_COUNT,
|
|
||||||
ERROR_TOKEN_POSITION,
|
|
||||||
ERROR_VAR_DIFF,
|
|
||||||
ERROR_SENTINEL, // last token not used, only for enum count
|
|
||||||
} e_program_error;
|
|
||||||
|
|
||||||
void print_state();
|
void print_state();
|
||||||
int stop_errors(e_program_error err, const char *format, ...);
|
int stop_errors(const char *format, ...);
|
||||||
|
|
||||||
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
* UTILS/PRINT_ENUMS.C
|
* UTILS/PRINT_ENUMS.C
|
||||||
@@ -131,6 +119,7 @@ extern s_token *tokens_g_err;
|
|||||||
extern s_term *terms_g_err;
|
extern s_term *terms_g_err;
|
||||||
extern double *polynom_g_err;
|
extern double *polynom_g_err;
|
||||||
extern int polynom_len_g_err;
|
extern int polynom_len_g_err;
|
||||||
extern bool debug_mode;
|
extern bool flag_debug_mode;
|
||||||
|
extern bool flag_loop_mode;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -6,7 +6,8 @@
|
|||||||
* GLOBALS
|
* GLOBALS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool debug_mode;
|
bool flag_debug_mode;
|
||||||
|
bool flag_loop_mode;
|
||||||
char *input_g_err;
|
char *input_g_err;
|
||||||
s_token *tokens_g_err;
|
s_token *tokens_g_err;
|
||||||
s_term *terms_g_err;
|
s_term *terms_g_err;
|
||||||
@@ -133,7 +134,7 @@ static void launch_argv(char *input)
|
|||||||
ret = lexerize(input, tokens);
|
ret = lexerize(input, tokens);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
stop_errors(ERROR_TOKEN_COUNT, "lexer returned 0 token");
|
stop_errors("lexer returned 0 token");
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse
|
// parse
|
||||||
@@ -145,7 +146,7 @@ static void launch_argv(char *input)
|
|||||||
ret = parse(tokens, terms, terms_count_prediction);
|
ret = parse(tokens, terms, terms_count_prediction);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
stop_errors(ERROR_TERM_COUNT, "parser returned 0 term");
|
stop_errors("parser returned 0 term");
|
||||||
}
|
}
|
||||||
|
|
||||||
// reduce
|
// reduce
|
||||||
@@ -231,50 +232,51 @@ static void launch_stdin()
|
|||||||
|
|
||||||
int main(int ac, char **av)
|
int main(int ac, char **av)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
char *input;
|
char *input;
|
||||||
e_program_mode program_mode;
|
e_program_mode program_mode;
|
||||||
|
|
||||||
debug_mode = false;
|
// init flags
|
||||||
|
flag_debug_mode = false;
|
||||||
|
flag_loop_mode = false;
|
||||||
|
|
||||||
// check arguments
|
// check arguments
|
||||||
program_mode = MODE_ARGV;
|
program_mode = MODE_ARGV;
|
||||||
if (ac > 3)
|
if (ac == 1)
|
||||||
{
|
{
|
||||||
stop_errors(ARGUMENTS_ERROR, "too many arguments");
|
program_mode = MODE_STDIN;
|
||||||
}
|
}
|
||||||
else if (ac == 3)
|
else if (ac > 1)
|
||||||
{
|
{
|
||||||
if ((ft_strcmp(av[1], "-d") == 0))
|
// get flags
|
||||||
|
input = NULL;
|
||||||
|
i = 1;
|
||||||
|
while (i < ac)
|
||||||
{
|
{
|
||||||
debug_mode = true;
|
if ((ft_strcmp(av[i], "-d") == 0))
|
||||||
input = av[2];
|
{
|
||||||
|
flag_debug_mode = true;
|
||||||
}
|
}
|
||||||
else if ((ft_strcmp(av[2], "-d") == 0))
|
else if ((ft_strcmp(av[i], "-l") == 0))
|
||||||
{
|
{
|
||||||
debug_mode = true;
|
flag_loop_mode = true;
|
||||||
input = av[1];
|
}
|
||||||
|
else if (ft_strlen(av[i]) == 2 && av[i][0] == '-')
|
||||||
|
{
|
||||||
|
stop_errors("unknwon flag '%s'", av[i]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stop_errors(ARGUMENTS_ERROR, "3rd argument is not a valid flag: '%s'", av[2]);
|
input = av[i];
|
||||||
}
|
}
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
else if (ac == 2)
|
// if input was not set, it means interactiv mode
|
||||||
{
|
if (input == NULL)
|
||||||
if ((ft_strcmp(av[1], "-d") == 0))
|
|
||||||
{
|
|
||||||
debug_mode = true;
|
|
||||||
program_mode = MODE_STDIN;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
input = av[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (ac < 2)
|
|
||||||
{
|
{
|
||||||
program_mode = MODE_STDIN;
|
program_mode = MODE_STDIN;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// launch calculator
|
// launch calculator
|
||||||
if (program_mode == MODE_ARGV)
|
if (program_mode == MODE_ARGV)
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ static bool token_is_number_int(const char *input, int input_pos, int *token_siz
|
|||||||
}
|
}
|
||||||
if (number_size > max_number_size)
|
if (number_size > max_number_size)
|
||||||
{
|
{
|
||||||
stop_errors(ERROR_NUMBER_TOO_BIG, &input[input_pos]);
|
stop_errors(&input[input_pos]);
|
||||||
}
|
}
|
||||||
*token_size = number_size;
|
*token_size = number_size;
|
||||||
return true;
|
return true;
|
||||||
@@ -94,7 +94,7 @@ static bool token_is_number_double(const char *input, int input_pos, int *token_
|
|||||||
}
|
}
|
||||||
if (number_size > max_number_size)
|
if (number_size > max_number_size)
|
||||||
{
|
{
|
||||||
stop_errors(ERROR_NUMBER_TOO_BIG, &input[input_pos]);
|
stop_errors(&input[input_pos]);
|
||||||
}
|
}
|
||||||
*token_size = number_size;
|
*token_size = number_size;
|
||||||
return true;
|
return true;
|
||||||
@@ -252,13 +252,13 @@ int lexerize(const char *input, s_token *tokens)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stop_errors(ERROR_UNKNOWN_TOKEN, &input[input_pos]);
|
stop_errors(&input[input_pos]);
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens_count++;
|
tokens_count++;
|
||||||
if (token_size == 0)
|
if (token_size == 0)
|
||||||
{
|
{
|
||||||
stop_errors(ERROR_UNKNOWN_TOKEN, &input[input_pos]);
|
stop_errors(&input[input_pos]);
|
||||||
}
|
}
|
||||||
input_pos += token_size;
|
input_pos += token_size;
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/parser.c
12
src/parser.c
@@ -34,7 +34,7 @@ static e_term_sign get_sign(s_token *tokens, int i, int *token_count)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stop_errors(ERROR_TOKEN_POSITION, "at begining of term, we should have a token 'sign', not '%s' (token[%i])", token_type_to_str(tokens[i].type), i);
|
stop_errors("at begining of term, we should have a token 'sign', not '%s' (token[%i])", token_type_to_str(tokens[i].type), i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tokens[i].type == TOKEN_SIGN_PLUS ? TERM_PLUS : TERM_MINUS;
|
return tokens[i].type == TOKEN_SIGN_PLUS ? TERM_PLUS : TERM_MINUS;
|
||||||
@@ -44,7 +44,7 @@ static double get_double_value(s_token token)
|
|||||||
{
|
{
|
||||||
if (token.tag != TOKEN_NUMBER)
|
if (token.tag != TOKEN_NUMBER)
|
||||||
{
|
{
|
||||||
stop_errors(ERROR_UNKNOWN_TOKEN, "this was suppose to be a number, instead got a %s", token_type_to_str(token.type));
|
stop_errors("this was suppose to be a number, instead got a %s", token_type_to_str(token.type));
|
||||||
}
|
}
|
||||||
if (token.type == TOKEN_NUMBER_DOUBLE)
|
if (token.type == TOKEN_NUMBER_DOUBLE)
|
||||||
{
|
{
|
||||||
@@ -131,7 +131,7 @@ static int get_exponent(s_token *tokens, int i, int *token_count)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stop_errors(ERROR_TOKEN_POSITION, "at exponent place, after a '*' we should have a 'var', but instead got : '%c' (token number %i)", tokens[i].value_char, i);
|
stop_errors("at exponent place, after a '*' we should have a 'var', but instead got : '%s' (token number %i)", token_type_to_str(tokens[i].type), i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -160,7 +160,7 @@ static int get_exponent(s_token *tokens, int i, int *token_count)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stop_errors(ERROR_TOKEN_POSITION, "at exponent place, we should have an int, but instead got : '%c' (token number %i)", tokens[i].value_char, i);
|
stop_errors("at exponent place, we should have an int, but instead got : '%s' (token number %i)", token_type_to_str(tokens[i].type), i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tokens[i].value_int;
|
return tokens[i].value_int;
|
||||||
@@ -184,7 +184,7 @@ static void check_variables(s_token *tokens)
|
|||||||
}
|
}
|
||||||
else if (var != tokens[i].value_char)
|
else if (var != tokens[i].value_char)
|
||||||
{
|
{
|
||||||
stop_errors(ERROR_VAR_DIFF, "old var : '%c' - new var : '%c' (token number %i)", var, tokens[i].value_char, i);
|
stop_errors("old var : '%c' - new var : '%c' (token number %i)", var, tokens[i].value_char, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
@@ -256,7 +256,7 @@ int parse(s_token *tokens, s_term *terms, int terms_count_max)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stop_errors(ERROR_PARSING, "terms_count: %i, terms_count_max: %i, tokens[%i].type: %s", terms_count, terms_count_max, i, token_type_to_str(tokens[i].type));
|
stop_errors("terms_count: %i, terms_count_max: %i, tokens[%i].type: %s", terms_count, terms_count_max, i, token_type_to_str(tokens[i].type));
|
||||||
}
|
}
|
||||||
|
|
||||||
return terms_count;
|
return terms_count;
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ static void print_context_polynom()
|
|||||||
|
|
||||||
void print_state()
|
void print_state()
|
||||||
{
|
{
|
||||||
if (!debug_mode)
|
if (!flag_debug_mode)
|
||||||
return;
|
return;
|
||||||
ft_dprintf(STDERR_FILENO, "\nSTATE :\n");
|
ft_dprintf(STDERR_FILENO, "\nSTATE :\n");
|
||||||
if (input_g_err)
|
if (input_g_err)
|
||||||
@@ -121,43 +121,21 @@ void print_state()
|
|||||||
print_context_polynom();
|
print_context_polynom();
|
||||||
}
|
}
|
||||||
|
|
||||||
int stop_errors(e_program_error err, const char *details, ...)
|
int stop_errors(const char *description, ...)
|
||||||
{
|
{
|
||||||
// the base error message
|
// print context (if debug mode)
|
||||||
const char *msg = "error: error type is out of range";
|
|
||||||
|
|
||||||
// map error codes to messages
|
|
||||||
const char *error_messages[ERROR_SENTINEL] = {
|
|
||||||
[ERROR_BASE] = "undefined error",
|
|
||||||
[ARGUMENTS_ERROR] = "arguments error",
|
|
||||||
[ERROR_UNKNOWN_TOKEN] = "LEXER - unknown token",
|
|
||||||
[ERROR_NUMBER_TOO_BIG] = "LEXER - number is too big",
|
|
||||||
[ERROR_PARSING] = "PARSER - too much terms to parse",
|
|
||||||
[ERROR_TOKEN_POSITION] = "PARSER - token position is not good in grammar",
|
|
||||||
[ERROR_VAR_DIFF] = "PARSER - expression must only contain one variable",
|
|
||||||
[ERROR_TOKEN_COUNT] = "LEXER - token count error",
|
|
||||||
[ERROR_TERM_COUNT] = "PARSER - term count error",
|
|
||||||
};
|
|
||||||
|
|
||||||
// override msg if err is in the error_messages array
|
|
||||||
if (err >= ERROR_BASE && err < ERROR_SENTINEL)
|
|
||||||
{
|
|
||||||
msg = error_messages[err];
|
|
||||||
}
|
|
||||||
|
|
||||||
// print context
|
|
||||||
print_state();
|
print_state();
|
||||||
|
|
||||||
// print the base message
|
ft_putstr_fd("\e[1;31mERROR:\e[0m ", STDERR_FILENO);
|
||||||
ft_dprintf(STDERR_FILENO, "error: (%i) %s - details: ", err, msg);
|
|
||||||
|
|
||||||
// print the formatted details
|
// print the formatted description
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, details);
|
va_start(args, description);
|
||||||
ft_vdprintf(STDERR_FILENO, details, args);
|
ft_vdprintf(STDERR_FILENO, description, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
ft_putchar_fd('\n', STDERR_FILENO);
|
// print the base message
|
||||||
|
ft_dprintf(STDERR_FILENO, " (errno[%d] : %s)\n", errno, strerror(errno));
|
||||||
|
|
||||||
exit(err);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user