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 (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
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
regmatch_t subexps[NUM_SUBEXPRESSIONS];
int match;
bool is_integer = false;
- bool could_be_decimal = true;
bool implicit_i32 = false;
const char *type_name = NULL;
struct type *type;
implicit_i32 = true;
}
else
- {
- type_index = INT_TYPE;
- could_be_decimal = false;
- }
+ type_index = INT_TYPE;
}
else if (subexps[FLOAT_TYPE1].rm_so != -1)
{
is_integer = true;
end_index = subexps[0].rm_eo;
type_name = "i32";
- could_be_decimal = true;
implicit_i32 = true;
}
}
std::string number;
for (int i = 0; i < end_index && pstate->lexptr[i]; ++i)
{
- if (pstate->lexptr[i] == '_')
- could_be_decimal = false;
- else
+ if (pstate->lexptr[i] != '_')
number.push_back (pstate->lexptr[i]);
}
else if (number[1] == 'b')
radix = 2;
if (radix != 10)
- {
- offset = 2;
- could_be_decimal = false;
- }
+ offset = 2;
}
if (!current_int_val.val.set (number.c_str () + offset, radix))
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] == ' '
}
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] == '"')
operation_up
rust_parser::parse_field (operation_up &&lhs)
{
- assume ('.');
+ assume ('.', true);
operation_up result;
switch (current_token)
}
break;
- case INTEGER:
- error (_("'_' not allowed in integers in anonymous field references"));
-
default:
error (_("field name expected"));
}
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 ();
break;
case INTEGER:
- case DECIMAL_INTEGER:
result = make_operation<long_const_operation> (current_int_val.type,
current_int_val.val);
lex ();
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);
}
}
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]);
}
}
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),
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);
}
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);
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 };