diff options
Diffstat (limited to 'gdb/rust-parse.c')
-rw-r--r-- | gdb/rust-parse.c | 131 |
1 files changed, 67 insertions, 64 deletions
diff --git a/gdb/rust-parse.c b/gdb/rust-parse.c index 9300e17..b428b97 100644 --- a/gdb/rust-parse.c +++ b/gdb/rust-parse.c @@ -1,6 +1,6 @@ /* Rust expression parsing for GDB, the GNU debugger. - Copyright (C) 2016-2024 Free Software Foundation, Inc. + Copyright (C) 2016-2025 Free Software Foundation, Inc. This file is part of GDB. @@ -235,27 +235,31 @@ struct rust_parser std::string super_name (const std::string &ident, unsigned int n_supers); int lex_character (); + int lex_decimal_integer (); int lex_number (); int lex_string (); int lex_identifier (); uint32_t lex_hex (int min, int max); - uint32_t lex_escape (int is_byte); + uint32_t lex_escape (bool is_byte); int lex_operator (); - int lex_one_token (); + int lex_one_token (bool decimal_only); void push_back (char c); /* The main interface to lexing. Lexes one token and updates the - internal state. */ - void lex () + internal state. DECIMAL_ONLY is true in the special case where + we want to tell the lexer not to parse a number as a float, but + instead only as a decimal integer. See parse_field. */ + void lex (bool decimal_only = false) { - current_token = lex_one_token (); + current_token = lex_one_token (decimal_only); } - /* Assuming the current token is TYPE, lex the next token. */ - void assume (int type) + /* Assuming the current token is TYPE, lex the next token. + DECIMAL_ONLY is passed to 'lex', which see. */ + void assume (int type, bool decimal_only = false) { gdb_assert (current_token == type); - lex (); + lex (decimal_only); } /* Require the single-character token C, and lex the next token; or @@ -519,7 +523,7 @@ rust_parser::lex_hex (int min, int max) otherwise we're lexing a character escape. */ uint32_t -rust_parser::lex_escape (int is_byte) +rust_parser::lex_escape (bool is_byte) { uint32_t result; @@ -617,12 +621,12 @@ lex_multibyte_char (const char *text, int *len) int rust_parser::lex_character () { - int is_byte = 0; + bool is_byte = false; uint32_t value; if (pstate->lexptr[0] == 'b') { - is_byte = 1; + is_byte = true; ++pstate->lexptr; } gdb_assert (pstate->lexptr[0] == '\''); @@ -672,10 +676,8 @@ starts_raw_string (const char *str) static bool ends_raw_string (const char *str, int n) { - int i; - gdb_assert (str[0] == '"'); - for (i = 0; i < n; ++i) + for (int i = 0; i < n; ++i) if (str[i + 1] != '#') return false; return true; @@ -900,6 +902,26 @@ rust_parser::lex_operator () return *pstate->lexptr++; } +/* Lex a decimal integer. */ + +int +rust_parser::lex_decimal_integer () +{ + gdb_assert (pstate->lexptr[0] >= '0' && pstate->lexptr[0] <= '9'); + + std::string copy; + while (pstate->lexptr[0] >= '0' && pstate->lexptr[0] <= '9') + { + copy.push_back (pstate->lexptr[0]); + ++pstate->lexptr; + } + + /* No need to set the value's type in this situation. */ + current_int_val.val.set (copy.c_str (), 10); + + return DECIMAL_INTEGER; +} + /* Lex a number. */ int @@ -907,14 +929,12 @@ rust_parser::lex_number () { regmatch_t subexps[NUM_SUBEXPRESSIONS]; int match; - int is_integer = 0; - int could_be_decimal = 1; - int implicit_i32 = 0; + bool is_integer = false; + bool implicit_i32 = false; const char *type_name = NULL; struct type *type; int end_index; int type_index = -1; - int i; match = regexec (&number_regex, pstate->lexptr, ARRAY_SIZE (subexps), subexps, 0); @@ -924,18 +944,15 @@ rust_parser::lex_number () if (subexps[INT_TEXT].rm_so != -1) { /* Integer part matched. */ - is_integer = 1; + is_integer = true; end_index = subexps[INT_TEXT].rm_eo; if (subexps[INT_TYPE].rm_so == -1) { type_name = "i32"; - implicit_i32 = 1; + implicit_i32 = true; } else - { - type_index = INT_TYPE; - could_be_decimal = 0; - } + type_index = INT_TYPE; } else if (subexps[FLOAT_TYPE1].rm_so != -1) { @@ -968,11 +985,10 @@ rust_parser::lex_number () if (rust_identifier_start_p (*next) || *next == '.') { --subexps[0].rm_eo; - is_integer = 1; + is_integer = true; end_index = subexps[0].rm_eo; type_name = "i32"; - could_be_decimal = 1; - implicit_i32 = 1; + implicit_i32 = true; } } @@ -993,11 +1009,9 @@ rust_parser::lex_number () /* Copy the text of the number and remove the "_"s. */ std::string number; - for (i = 0; i < end_index && pstate->lexptr[i]; ++i) + for (int i = 0; i < end_index && pstate->lexptr[i]; ++i) { - if (pstate->lexptr[i] == '_') - could_be_decimal = 0; - else + if (pstate->lexptr[i] != '_') number.push_back (pstate->lexptr[i]); } @@ -1019,10 +1033,7 @@ rust_parser::lex_number () else if (number[1] == 'b') radix = 2; if (radix != 10) - { - offset = 2; - could_be_decimal = 0; - } + offset = 2; } if (!current_int_val.val.set (number.c_str () + offset, radix)) @@ -1052,13 +1063,13 @@ rust_parser::lex_number () gdb_assert (parsed); } - return is_integer ? (could_be_decimal ? DECIMAL_INTEGER : INTEGER) : FLOAT; + return is_integer ? INTEGER : FLOAT; } /* The lexer. */ int -rust_parser::lex_one_token () +rust_parser::lex_one_token (bool decimal_only) { /* Skip all leading whitespace. */ while (pstate->lexptr[0] == ' ' @@ -1085,7 +1096,7 @@ rust_parser::lex_one_token () } if (pstate->lexptr[0] >= '0' && pstate->lexptr[0] <= '9') - return lex_number (); + return decimal_only ? lex_decimal_integer () : lex_number (); else if (pstate->lexptr[0] == 'b' && pstate->lexptr[1] == '\'') return lex_character (); else if (pstate->lexptr[0] == 'b' && pstate->lexptr[1] == '"') @@ -1540,7 +1551,7 @@ rust_parser::parse_addr () operation_up rust_parser::parse_field (operation_up &&lhs) { - assume ('.'); + assume ('.', true); operation_up result; switch (current_token) @@ -1570,9 +1581,6 @@ rust_parser::parse_field (operation_up &&lhs) } break; - case INTEGER: - error (_("'_' not allowed in integers in anonymous field references")); - default: error (_("field name expected")); } @@ -1666,7 +1674,7 @@ rust_parser::parse_array_type () struct type *elt_type = parse_type (); require (';'); - if (current_token != INTEGER && current_token != DECIMAL_INTEGER) + if (current_token != INTEGER) error (_("integer expected")); ULONGEST val = current_int_val.val.as_integer<ULONGEST> (); lex (); @@ -1765,7 +1773,7 @@ rust_parser::parse_tuple_type () std::string type_name = type_to_string (types[i]); if (i > 0) - obstack_1grow (&obstack, ','); + obstack_grow_str (&obstack, ", "); obstack_grow_str (&obstack, type_name.c_str ()); } @@ -2039,7 +2047,6 @@ rust_parser::parse_atom (bool required) break; case INTEGER: - case DECIMAL_INTEGER: result = make_operation<long_const_operation> (current_int_val.type, current_int_val.val); lex (); @@ -2180,12 +2187,12 @@ rust_lex_test_one (rust_parser *parser, const char *input, int expected) parser->reset (input); - token = parser->lex_one_token (); + token = parser->lex_one_token (false); SELF_CHECK (token == expected); if (token) { - token = parser->lex_one_token (); + token = parser->lex_one_token (false); SELF_CHECK (token == 0); } } @@ -2235,13 +2242,11 @@ static void rust_lex_test_sequence (rust_parser *parser, const char *input, int len, const int expected[]) { - int i; - parser->reset (input); - for (i = 0; i < len; ++i) + for (int i = 0; i < len; ++i) { - int token = parser->lex_one_token (); + int token = parser->lex_one_token (false); SELF_CHECK (token == expected[i]); } } @@ -2251,10 +2256,10 @@ rust_lex_test_sequence (rust_parser *parser, const char *input, int len, static void rust_lex_test_trailing_dot (rust_parser *parser) { - const int expected1[] = { DECIMAL_INTEGER, '.', IDENT, '(', ')', 0 }; + const int expected1[] = { INTEGER, '.', IDENT, '(', ')', 0 }; const int expected2[] = { INTEGER, '.', IDENT, '(', ')', 0 }; const int expected3[] = { FLOAT, EQEQ, '(', ')', 0 }; - const int expected4[] = { DECIMAL_INTEGER, DOTDOT, DECIMAL_INTEGER, 0 }; + const int expected4[] = { INTEGER, DOTDOT, INTEGER, 0 }; rust_lex_test_sequence (parser, "23.g()", ARRAY_SIZE (expected1), expected1); rust_lex_test_sequence (parser, "23_0.g()", ARRAY_SIZE (expected2), @@ -2271,14 +2276,14 @@ rust_lex_test_completion (rust_parser *parser) { const int expected[] = { IDENT, '.', COMPLETE, 0 }; - parser->pstate->parse_completion = 1; + parser->pstate->parse_completion = true; rust_lex_test_sequence (parser, "something.wha", ARRAY_SIZE (expected), expected); rust_lex_test_sequence (parser, "something.", ARRAY_SIZE (expected), expected); - parser->pstate->parse_completion = 0; + parser->pstate->parse_completion = false; } /* Test pushback. */ @@ -2290,16 +2295,16 @@ rust_lex_test_push_back (rust_parser *parser) parser->reset (">>="); - token = parser->lex_one_token (); + token = parser->lex_one_token (false); SELF_CHECK (token == COMPOUND_ASSIGN); SELF_CHECK (parser->current_opcode == BINOP_RSH); parser->push_back ('='); - token = parser->lex_one_token (); + token = parser->lex_one_token (false); SELF_CHECK (token == '='); - token = parser->lex_one_token (); + token = parser->lex_one_token (false); SELF_CHECK (token == 0); } @@ -2357,7 +2362,7 @@ rust_lex_tests (void) rust_lex_exception_test (&parser, "'\\Q'", "Invalid escape \\Q in literal"); rust_lex_exception_test (&parser, "b'\\Q'", "Invalid escape \\Q in literal"); - rust_lex_int_test (&parser, "23", 23, DECIMAL_INTEGER); + rust_lex_int_test (&parser, "23", 23, INTEGER); rust_lex_int_test (&parser, "2_344__29", 234429, INTEGER); rust_lex_int_test (&parser, "0x1f", 0x1f, INTEGER); rust_lex_int_test (&parser, "23usize", 23, INTEGER); @@ -2382,7 +2387,7 @@ rust_lex_tests (void) rust_lex_stringish_test (&parser, "thread", "thread", IDENT); rust_lex_stringish_test (&parser, "r#true", "true", IDENT); - const int expected1[] = { IDENT, DECIMAL_INTEGER, 0 }; + const int expected1[] = { IDENT, INTEGER, 0 }; rust_lex_test_sequence (&parser, "r#thread 23", ARRAY_SIZE (expected1), expected1); const int expected2[] = { IDENT, '#', 0 }; @@ -2416,9 +2421,7 @@ rust_lex_tests (void) -void _initialize_rust_exp (); -void -_initialize_rust_exp () +INIT_GDB_FILE (rust_exp) { int code = regcomp (&number_regex, number_regex_text, REG_EXTENDED); /* If the regular expression was incorrect, it was a programming |