From 66bfe8a24d9b1ca83d45396a9f9c962379d1895e Mon Sep 17 00:00:00 2001 From: Oxore Date: Sun, 25 Jun 2023 15:31:25 +0300 Subject: Fix parsing size specifier --- main.c | 61 +++++++++++++++++++++++++++++-------------------------------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/main.c b/main.c index dee5171..77df6cb 100644 --- a/main.c +++ b/main.c @@ -1344,21 +1344,22 @@ static size_t find_line_length(const char *const str) } static int pars_yield_error_str( - struct pars *const self, const struct line_pos_info l, char *const str) + struct pars *const self, + const struct line_pos_info l, + const char *const found, + const size_t found_length) { fprintf( stderr, - ":%lu:%lu: parsing error: expected %s, found '%s'\n", + ":%lu:%lu: parsing error: expected %s, found '%.*s'\n", l.line_num + 1, l.column_num + 1, - "", - str); - free(str); - const size_t line_length = find_line_length(self->lex->input + l.line_offset); - char *const line = calloc(1, line_length + 1); - memcpy(line, self->lex->input + l.line_offset, line_length); - fprintf(stderr, "%5lu | %s\n", l.line_num + 1, line); - free(line); + "<_unspecified_token_list>", + (int)found_length, + found); + const char *const line = self->lex->input + l.line_offset; + const size_t line_length = find_line_length(line); + fprintf( stderr, "%5lu | %.*s\n", l.line_num, (int)line_length, line); fputs(" | ", stderr); for (size_t i = 0; i < l.column_num; i++) { if (self->lex->input[l.line_offset + i] == '\t') { @@ -1376,9 +1377,8 @@ static int pars_yield_error(struct pars *const self, const size_t token_id) const struct token token = self->lex->tokbuf[token_id]; const struct line_pos_info l = lex_get_line_pos_info(self->lex, token.offset); - char *const found = calloc(1, token.length + 10); - snprintf(found, token.length + 1, "%s", self->lex->input + token.offset); - return pars_yield_error_str(self, l, found); + const char *const found = self->lex->input + token.offset; + return pars_yield_error_str(self, l, found, token.length); } static int pars_yield_error_nesting( @@ -1451,19 +1451,27 @@ static int pars_parse_arg( (sizeof *self->lex->tokbuf); const size_t first_token_id = self->cur_tok_id; int nesting = 0; + int commas = 0; enum arg_type arg_type = ARG_EXPR; while (self->cur_tok_id < tokens_count) { const size_t token_id = self->cur_tok_id; // Peek const struct token token = self->lex->tokbuf[token_id]; - if (token.type == TT_LPAREN) { + if (nesting == 1 && token.type == TT_COMMA) { + if (commas >= 2) { + return pars_yield_error(self, self->cur_tok_id); + } else { + commas++; + } + } else if (token.type == TT_LPAREN) { nesting++; } else if (token.type == TT_RPAREN) { nesting--; } else if (is_expression_token(token.type)) { // TODO parse expression - } else if (nesting > 0 && token.type == TT_COMMA) { - // Comma inside parentheses is allowed } else { + if (nesting > 0) { + return pars_yield_error(self, self->cur_tok_id); + } break; } self->cur_tok_id++; // Commit @@ -1644,30 +1652,19 @@ static int pars_parse_instruction( if (pars_is_eof_reached(self)) { return pars_yield_error_eof(self); } - const size_t token2_id = self->cur_tok_id; // Peek - const struct token token2 = self->lex->tokbuf[token2_id]; - if (token2.type == TT_DOT) { + const size_t size_spec_id = self->cur_tok_id; // Peek + const struct token size_spec = self->lex->tokbuf[size_spec_id]; + if (size_spec.type == TT_DOT_ID) { self->cur_tok_id++; // Commit - if (pars_is_eof_reached(self)) { - return pars_yield_error_eof(self); - } - const size_t size_spec_id = self->cur_tok_id++; - const struct token size_spec = self->lex->tokbuf[size_spec_id]; - if (size_spec.type != TT_ID) { - return pars_yield_error(self, size_spec_id); - } // Size specifier - if (size_spec.length != 1) { + if (size_spec.length != 2) { return pars_yield_error(self, size_spec_id); } const size_t opsize = - get_opsize_from_specifier(self->lex->input[size_spec.offset]); + get_opsize_from_specifier(self->lex->input[size_spec.offset + 1]); if (opsize == OPSIZE_NONE) { return pars_yield_error(self, size_spec_id); } - if (pars_is_eof_reached(self)) { - return pars_yield_error_eof(self); - } return pars_parse_instruction_args(self, label_id, mnemonic_id, opsize); } return pars_parse_instruction_args( -- cgit v1.2.3