2022-01-08 22:20:29 +00:00
|
|
|
#include <stdio.h>
|
2021-12-10 20:22:16 +00:00
|
|
|
|
|
|
|
|
#include "apfl.h"
|
|
|
|
|
|
|
|
|
|
#define POSFMT "%d:%d"
|
|
|
|
|
#define POSARGS error.position.line, error.position.col
|
|
|
|
|
#define POS2ARGS error.position2.line, error.position2.col
|
|
|
|
|
|
2021-12-18 23:27:34 +00:00
|
|
|
const char *
|
|
|
|
|
apfl_error_type_name(enum apfl_error_type type)
|
|
|
|
|
{
|
|
|
|
|
switch (type) {
|
|
|
|
|
case APFL_ERR_MALLOC_FAILED:
|
|
|
|
|
return "APFL_ERR_MALLOC_FAILED";
|
|
|
|
|
case APFL_ERR_INPUT_ERROR:
|
|
|
|
|
return "APFL_ERR_INPUT_ERROR";
|
|
|
|
|
case APFL_ERR_UNEXPECTED_EOF:
|
|
|
|
|
return "APFL_ERR_UNEXPECTED_EOF";
|
|
|
|
|
case APFL_ERR_EXPECTED_EQ_AFTER_COLON:
|
|
|
|
|
return "APFL_ERR_EXPECTED_EQ_AFTER_COLON";
|
2022-01-07 22:39:06 +00:00
|
|
|
case APFL_ERR_UNEXPECTED_BYTE:
|
|
|
|
|
return "APFL_ERR_UNEXPECTED_BYTE";
|
2021-12-18 23:27:34 +00:00
|
|
|
case APFL_ERR_UNEXPECTED_BYTE_IN_NUMBER:
|
|
|
|
|
return "APFL_ERR_UNEXPECTED_BYTE_IN_NUMBER";
|
|
|
|
|
case APFL_ERR_EXPECTED_DIGIT:
|
|
|
|
|
return "APFL_ERR_EXPECTED_DIGIT";
|
|
|
|
|
case APFL_ERR_EXPECTED_HEX_IN_HEX_ESCAPE:
|
|
|
|
|
return "APFL_ERR_EXPECTED_HEX_IN_HEX_ESCAPE";
|
|
|
|
|
case APFL_ERR_INVALID_ESCAPE_SEQUENCE:
|
|
|
|
|
return "APFL_ERR_INVALID_ESCAPE_SEQUENCE";
|
|
|
|
|
case APFL_ERR_NO_LINEBREAK_AFTER_CONTINUE_LINE:
|
|
|
|
|
return "APFL_ERR_NO_LINEBREAK_AFTER_CONTINUE_LINE";
|
|
|
|
|
case APFL_ERR_UNEXPECTED_TOKEN:
|
|
|
|
|
return "APFL_ERR_UNEXPECTED_TOKEN";
|
|
|
|
|
case APFL_ERR_MISMATCHING_CLOSING_BRACKET:
|
|
|
|
|
return "APFL_ERR_MISMATCHING_CLOSING_BRACKET";
|
|
|
|
|
case APFL_ERR_UNEXPECTED_EOF_AFTER_TOKEN:
|
|
|
|
|
return "APFL_ERR_UNEXPECTED_EOF_AFTER_TOKEN";
|
|
|
|
|
case APFL_ERR_STATEMENTS_BEFORE_PARAMETERS:
|
|
|
|
|
return "APFL_ERR_STATEMENTS_BEFORE_PARAMETERS";
|
|
|
|
|
case APFL_ERR_EMPTY_ASSIGNMENT_BEFORE_PARAMETERS:
|
|
|
|
|
return "APFL_ERR_EMPTY_ASSIGNMENT_BEFORE_PARAMETERS";
|
|
|
|
|
case APFL_ERR_UNEXPECTED_EXPRESSION:
|
|
|
|
|
return "APFL_ERR_UNEXPECTED_EXPRESSION";
|
|
|
|
|
case APFL_ERR_INVALID_ASSIGNMENT_LHS:
|
|
|
|
|
return "APFL_ERR_INVALID_ASSIGNMENT_LHS";
|
|
|
|
|
case APFL_ERR_EMPTY_ASSIGNMENT:
|
|
|
|
|
return "APFL_ERR_EMPTY_ASSIGNMENT";
|
2022-01-07 22:08:25 +00:00
|
|
|
case APFL_ERR_ONLY_ONE_EXPAND_ALLOWED:
|
|
|
|
|
return "APFL_ERR_ONLY_ONE_EXPAND_ALLOWED";
|
2022-01-08 21:55:24 +00:00
|
|
|
case APFL_ERR_UNEXPECTED_CONSTANT_IN_MEMBER_ACCESS:
|
|
|
|
|
return "APFL_ERR_UNEXPECTED_CONSTANT_IN_MEMBER_ACCESS";
|
|
|
|
|
case APFL_ERR_UNEXPECTED_EXPR_IN_MEMBER_ACCESS:
|
|
|
|
|
return "APFL_ERR_UNEXPECTED_EXPR_IN_MEMBER_ACCESS";
|
2022-01-08 22:20:29 +00:00
|
|
|
case APFL_ERR_UNEXPECTED_BLANK_IN_MEMBER_ACCESS:
|
|
|
|
|
return "APFL_ERR_UNEXPECTED_BLANK_IN_MEMBER_ACCESS";
|
2021-12-18 23:27:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return "<unknown error>";
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-10 20:22:16 +00:00
|
|
|
void
|
|
|
|
|
apfl_error_print(struct apfl_error error, FILE *file)
|
|
|
|
|
{
|
|
|
|
|
switch (error.type) {
|
|
|
|
|
case APFL_ERR_MALLOC_FAILED:
|
|
|
|
|
fprintf(file, "Could not allocate memory\n");
|
|
|
|
|
return;
|
|
|
|
|
case APFL_ERR_INPUT_ERROR:
|
|
|
|
|
fprintf(file, "Input error while parsing\n");
|
|
|
|
|
return;
|
|
|
|
|
case APFL_ERR_UNEXPECTED_EOF:
|
|
|
|
|
fprintf(file, "Unexpected end of file\n");
|
|
|
|
|
return;
|
|
|
|
|
case APFL_ERR_EXPECTED_EQ_AFTER_COLON:
|
|
|
|
|
fprintf(file, "Expected '=' after ':' at " POSFMT "\n", POSARGS);
|
2022-01-07 22:39:06 +00:00
|
|
|
return;
|
|
|
|
|
case APFL_ERR_UNEXPECTED_BYTE:
|
|
|
|
|
fprintf(file, "Unexpected byte '%c' (0x%X) at " POSFMT "\n", error.byte, (unsigned)error.byte, POSARGS);
|
2021-12-10 20:22:16 +00:00
|
|
|
return;
|
|
|
|
|
case APFL_ERR_UNEXPECTED_BYTE_IN_NUMBER:
|
|
|
|
|
fprintf(file, "Unexpected byte '%c' while parsing number at " POSFMT "\n", error.byte, POSARGS);
|
|
|
|
|
return;
|
|
|
|
|
case APFL_ERR_EXPECTED_DIGIT:
|
|
|
|
|
fprintf(file, "Expected a digit at " POSFMT "\n", POSARGS);
|
|
|
|
|
return;
|
|
|
|
|
case APFL_ERR_EXPECTED_HEX_IN_HEX_ESCAPE:
|
|
|
|
|
fprintf(file, "Expected a hex-digit in hex escape at " POSFMT "\n", POSARGS);
|
|
|
|
|
return;
|
|
|
|
|
case APFL_ERR_INVALID_ESCAPE_SEQUENCE:
|
|
|
|
|
fprintf(file, "Invalid escape sequence \\%c at " POSFMT "\n", error.byte, POSARGS);
|
|
|
|
|
return;
|
|
|
|
|
case APFL_ERR_NO_LINEBREAK_AFTER_CONTINUE_LINE:
|
|
|
|
|
fprintf(file, "No line break (after optional comments) after \\ at " POSFMT "\n", POSARGS);
|
|
|
|
|
return;
|
|
|
|
|
case APFL_ERR_UNEXPECTED_TOKEN:
|
|
|
|
|
fprintf(file, "Unexpected `%s` token at " POSFMT "\n", apfl_token_type_name(error.token_type), POSARGS);
|
|
|
|
|
return;
|
|
|
|
|
case APFL_ERR_MISMATCHING_CLOSING_BRACKET:
|
|
|
|
|
fprintf(
|
|
|
|
|
file,
|
|
|
|
|
"Closing `%s` token at " POSFMT " does not match opening `%s` at " POSFMT "\n",
|
|
|
|
|
apfl_token_type_name(error.token_type),
|
|
|
|
|
POSARGS,
|
|
|
|
|
apfl_token_type_name(error.token_type2),
|
|
|
|
|
POS2ARGS
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
case APFL_ERR_UNEXPECTED_EOF_AFTER_TOKEN:
|
|
|
|
|
fprintf(
|
|
|
|
|
file,
|
|
|
|
|
"Unexpected end of file after `%s` token at " POSFMT "\n",
|
|
|
|
|
apfl_token_type_name(error.token_type),
|
|
|
|
|
POSARGS
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
case APFL_ERR_STATEMENTS_BEFORE_PARAMETERS:
|
|
|
|
|
fprintf(
|
|
|
|
|
file,
|
|
|
|
|
"Unexpected statements before parameters near " POSFMT "\n",
|
|
|
|
|
POSARGS
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
case APFL_ERR_EMPTY_ASSIGNMENT_BEFORE_PARAMETERS:
|
|
|
|
|
fprintf(
|
|
|
|
|
file,
|
|
|
|
|
"Unexpected empty assignment before parameters near " POSFMT "\n",
|
|
|
|
|
POSARGS
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
case APFL_ERR_UNEXPECTED_EXPRESSION:
|
|
|
|
|
fprintf(
|
|
|
|
|
file,
|
|
|
|
|
"Unexpected expression near " POSFMT "\n",
|
|
|
|
|
POSARGS
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
case APFL_ERR_INVALID_ASSIGNMENT_LHS:
|
|
|
|
|
fprintf(
|
|
|
|
|
file,
|
|
|
|
|
"Invalid left hand side of assignment near " POSFMT "\n",
|
|
|
|
|
POSARGS
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
case APFL_ERR_EMPTY_ASSIGNMENT:
|
|
|
|
|
fprintf(
|
|
|
|
|
file,
|
|
|
|
|
"Empty assignment at " POSFMT "\n",
|
|
|
|
|
POSARGS
|
|
|
|
|
);
|
|
|
|
|
return;
|
2022-01-07 22:08:25 +00:00
|
|
|
case APFL_ERR_ONLY_ONE_EXPAND_ALLOWED:
|
|
|
|
|
fprintf(
|
|
|
|
|
file,
|
|
|
|
|
"Only one expansion (~) is allowed per level, near " POSFMT "\n",
|
|
|
|
|
POSARGS
|
|
|
|
|
);
|
2022-01-08 21:55:24 +00:00
|
|
|
break;
|
|
|
|
|
case APFL_ERR_UNEXPECTED_CONSTANT_IN_MEMBER_ACCESS:
|
|
|
|
|
fprintf(
|
|
|
|
|
file,
|
|
|
|
|
"Unexpected constant in member access near " POSFMT "\n",
|
|
|
|
|
POSARGS
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case APFL_ERR_UNEXPECTED_EXPR_IN_MEMBER_ACCESS:
|
|
|
|
|
fprintf(
|
|
|
|
|
file,
|
|
|
|
|
"Unexpected expression in member access near " POSFMT "\n",
|
|
|
|
|
POSARGS
|
|
|
|
|
);
|
|
|
|
|
break;
|
2022-01-08 22:20:29 +00:00
|
|
|
case APFL_ERR_UNEXPECTED_BLANK_IN_MEMBER_ACCESS:
|
|
|
|
|
fprintf(
|
|
|
|
|
file,
|
|
|
|
|
"Unexpected blank (\"_\") in member access near " POSFMT "\n",
|
|
|
|
|
POSARGS
|
|
|
|
|
);
|
|
|
|
|
break;
|
2021-12-10 20:22:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf(file, "Unknown error %d\n", (int)error.type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct apfl_error
|
|
|
|
|
apfl_error_simple(enum apfl_error_type type)
|
|
|
|
|
{
|
|
|
|
|
return (struct apfl_error) { .type = type };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
apfl_error_is_fatal_type(enum apfl_error_type type)
|
|
|
|
|
{
|
|
|
|
|
switch (type) {
|
|
|
|
|
case APFL_ERR_MALLOC_FAILED:
|
|
|
|
|
case APFL_ERR_INPUT_ERROR:
|
|
|
|
|
return true;
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|