expected tokens vararg

This commit is contained in:
tovjemam 2024-12-23 14:52:28 +01:00
parent 6e155817dd
commit 5742e9af6b

View File

@ -1,5 +1,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h>
#include "parser.h" #include "parser.h"
/* Vrátí ukazatel na aktuální token */ /* Vrátí ukazatel na aktuální token */
@ -42,8 +43,9 @@ static void error_bad_alloc(struct parser *parser) {
error_printf(&parser->eb, "Out of memory\n"); error_printf(&parser->eb, "Out of memory\n");
} }
static void error_expected_one_of(struct parser *parser, const int expected[]) { static void error_expected_tokens(struct parser *parser, size_t num_tokens, ...) {
size_t i; size_t i;
va_list ap;
enum token_type got = get_token(parser)->type; enum token_type got = get_token(parser)->type;
@ -56,24 +58,22 @@ static void error_expected_one_of(struct parser *parser, const int expected[]) {
error_set(&parser->eb, ERR_INVALID_FUNCTION); error_set(&parser->eb, ERR_INVALID_FUNCTION);
error_printf(&parser->eb, "Syntax error - expected "); error_printf(&parser->eb, "Syntax error - expected ");
for (i = 0; expected[i] >= 0; ++i) { va_start(ap, num_tokens);
for (i = 0; i < num_tokens; ++i) {
enum token_type tok = va_arg(ap, enum token_type);
if (i > 0) if (i > 0)
error_printf(&parser->eb, ", "); error_printf(&parser->eb, ", ");
error_printf(&parser->eb, "%s", lex_token_str(expected[i])); error_printf(&parser->eb, "%s", lex_token_str(tok));
} }
va_end(ap);
error_printf(&parser->eb, " - but got %s\n", lex_token_str(got)); error_printf(&parser->eb, " - but got %s\n", lex_token_str(got));
lex_print_position(&parser->lexer, &parser->eb); lex_print_position(&parser->lexer, &parser->eb);
} }
static void error_expected_single(struct parser *parser, enum token_type expected) {
static int expected_arr[] = { -1, -1 };
expected_arr[0] = expected;
error_expected_one_of(parser, expected_arr);
}
static struct expr_node* parse_subexpression(struct parser *parser); static struct expr_node* parse_subexpression(struct parser *parser);
int parse_n_expressions(struct parser *parser, struct expr_node **out_nodes, size_t n); int parse_n_expressions(struct parser *parser, struct expr_node **out_nodes, size_t n);
@ -81,7 +81,7 @@ static struct expr_node* parse_bracketed(struct parser *parser) {
struct expr_node* node; struct expr_node* node;
if (!accept_token(parser, TOK_LEFT_PAREN)) { if (!accept_token(parser, TOK_LEFT_PAREN)) {
error_expected_single(parser, TOK_LEFT_PAREN); error_expected_tokens(parser, 1, TOK_LEFT_PAREN);
return NULL; return NULL;
} }
@ -89,7 +89,7 @@ static struct expr_node* parse_bracketed(struct parser *parser) {
return NULL; return NULL;
if (!accept_token(parser, TOK_RIGHT_PAREN)) { if (!accept_token(parser, TOK_RIGHT_PAREN)) {
error_expected_single(parser, TOK_RIGHT_PAREN); error_expected_tokens(parser, 1, TOK_RIGHT_PAREN);
node_free(node); node_free(node);
return NULL; return NULL;
} }
@ -128,7 +128,7 @@ static struct expr_node *parse_base(struct parser *parser) {
next_token(parser); next_token(parser);
if (!accept_token(parser, TOK_LEFT_PAREN)) { if (!accept_token(parser, TOK_LEFT_PAREN)) {
error_expected_single(parser, TOK_LEFT_PAREN); error_expected_tokens(parser, 1, TOK_LEFT_PAREN);
return NULL; return NULL;
} }
@ -145,7 +145,7 @@ static struct expr_node *parse_base(struct parser *parser) {
} }
if (!accept_token(parser, TOK_RIGHT_PAREN)) { if (!accept_token(parser, TOK_RIGHT_PAREN)) {
error_expected_single(parser, TOK_RIGHT_PAREN); error_expected_tokens(parser, 1, TOK_RIGHT_PAREN);
node_free(node); node_free(node);
return NULL; return NULL;
} }
@ -157,11 +157,7 @@ static struct expr_node *parse_base(struct parser *parser) {
return parse_bracketed(parser); return parse_bracketed(parser);
} }
{ error_expected_tokens(parser, 4, TOK_NUMBER, TOK_VARIABLE, TOK_FUNCTION, TOK_LEFT_PAREN);
static const int expected[] = { TOK_NUMBER, TOK_VARIABLE, TOK_FUNCTION, TOK_LEFT_PAREN, -1 };
error_expected_one_of(parser, expected);
}
return NULL; return NULL;
} }
@ -317,7 +313,7 @@ int parser_parse_n(struct parser *parser, const char *str, const char *variable_
if (!token_is(parser, TOK_EOF)) { if (!token_is(parser, TOK_EOF)) {
size_t i; size_t i;
error_expected_single(parser, TOK_EOF); error_expected_tokens(parser, 1, TOK_EOF);
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
node_free(out_nodes[i]); node_free(out_nodes[i]);