diff options
author | Oxore <oxore@protonmail.com> | 2023-06-25 15:31:25 +0300 |
---|---|---|
committer | Oxore <oxore@protonmail.com> | 2023-06-25 15:31:25 +0300 |
commit | 66bfe8a24d9b1ca83d45396a9f9c962379d1895e (patch) | |
tree | c70312c5f878778349fff4a6e3a0765f8e2218ce | |
parent | 5ccc7b6c240bd927305bbacf4fb0a102de8f1147 (diff) |
Fix parsing size specifier
-rw-r--r-- | main.c | 61 |
1 files changed, 29 insertions, 32 deletions
@@ -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, - "<stdin>:%lu:%lu: parsing error: expected %s, found '%s'\n", + "<stdin>:%lu:%lu: parsing error: expected %s, found '%.*s'\n", l.line_num + 1, l.column_num + 1, - "<TODO>", - 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( |