+2019-04-04 Tom Tromey <tom@tromey.com>
+
+ * rust-exp.y (struct rust_parser) <lex_hex, lex_escape,
+ lex_operator, push_back>: New methods.
+ Update all rules.
+ (rust_parser::lex_hex, lex_escape): Rename and update.
+ (rust_parser::lex_string, rust_parser::lex_identifier): Update.
+ (rust_parser::lex_operator): Rename and update.
+ (rust_parser::lex_number, rustyylex, rustyyerror)
+ (rust_lex_test_init, rust_lex_test_sequence)
+ (rust_lex_test_push_back, rust_lex_tests): Update.
+ * parser-defs.h (struct parser_state) <parser_state>: Add "input"
+ parameter.
+ <lexptr, prev_lexptr>: New members.
+ (lexptr, prev_lexptr): Don't declare.
+ * parse.c (lexptr, prev_lexptr): Remove globals.
+ (parse_exp_in_context): Update.
+ * p-exp.y (yylex, yyerror): Update.
+ * m2-exp.y (parse_number, yylex, yyerror): Update.
+ * go-exp.y (lex_one_token, yyerror): Update.
+ * f-exp.y (match_string_literal, yylex, yyerror): Update.
+ * d-exp.y (lex_one_token, yyerror): Update.
+ * c-exp.y (scan_macro_expansion, finished_macro_expansion)
+ (lex_one_token, yyerror): Update.
+ * ada-lex.l (YY_INPUT): Update.
+ (rewind_to_char): Update.
+ * ada-exp.y (yyerror): Update.
+
2019-04-04 Tom Tromey <tom@tromey.com>
* rust-exp.y (rustyylex, rust_lex_tests): Update.
static void
yyerror (const char *msg)
{
- error (_("Error in expression, near `%s'."), lexptr);
+ error (_("Error in expression, near `%s'."), pstate->lexptr);
}
/* Emit expression to access an instance of SYM, in block BLOCK (if
#undef YY_INPUT
#define YY_INPUT(BUF, RESULT, MAX_SIZE) \
- if ( *lexptr == '\000' ) \
+ if ( *pstate->lexptr == '\000' ) \
(RESULT) = YY_NULL; \
else \
{ \
- *(BUF) = *lexptr; \
+ *(BUF) = *pstate->lexptr; \
(RESULT) = 1; \
- lexptr += 1; \
+ pstate->lexptr += 1; \
}
static int find_dot_all (const char *);
static void
rewind_to_char (int ch)
{
- lexptr -= yyleng;
- while (toupper (*lexptr) != toupper (ch))
- lexptr -= 1;
+ pstate->lexptr -= yyleng;
+ while (toupper (*pstate->lexptr) != toupper (ch))
+ pstate->lexptr -= 1;
yyrestart (NULL);
}
/* Save the old lexptr value, so we can return to it when we're done
parsing the expanded text. */
- cpstate->macro_original_text = lexptr;
- lexptr = copy;
+ cpstate->macro_original_text = pstate->lexptr;
+ pstate->lexptr = copy;
}
static int
gdb_assert (cpstate->macro_original_text);
/* Pop back to the original text. */
- lexptr = cpstate->macro_original_text;
+ pstate->lexptr = cpstate->macro_original_text;
cpstate->macro_original_text = 0;
}
/* Check if this is a macro invocation that we need to expand. */
if (! scanning_macro_expansion ())
{
- char *expanded = macro_expand_next (&lexptr,
+ char *expanded = macro_expand_next (&pstate->lexptr,
standard_macro_lookup,
expression_macro_scope);
scan_macro_expansion (expanded);
}
- prev_lexptr = lexptr;
+ pstate->prev_lexptr = pstate->lexptr;
- tokstart = lexptr;
+ tokstart = pstate->lexptr;
/* See if it is a special token of length 3. */
for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
if (strncmp (tokstart, tokentab3[i].oper, 3) == 0)
&& par_state->language ()->la_language != language_cplus)
break;
- lexptr += 3;
+ pstate->lexptr += 3;
yylval.opcode = tokentab3[i].opcode;
return tokentab3[i].token;
}
&& par_state->language ()->la_language != language_cplus)
break;
- lexptr += 2;
+ pstate->lexptr += 2;
yylval.opcode = tokentab2[i].opcode;
if (tokentab2[i].token == ARROW)
last_was_structop = 1;
case ' ':
case '\t':
case '\n':
- lexptr++;
+ pstate->lexptr++;
goto retry;
case '[':
case '(':
paren_depth++;
- lexptr++;
+ pstate->lexptr++;
if (par_state->language ()->la_language == language_objc
&& c == '[')
return OBJC_LBRAC;
if (paren_depth == 0)
return 0;
paren_depth--;
- lexptr++;
+ pstate->lexptr++;
return c;
case ',':
&& paren_depth == 0
&& ! scanning_macro_expansion ())
return 0;
- lexptr++;
+ pstate->lexptr++;
return c;
case '.':
/* Might be a floating point number. */
- if (lexptr[1] < '0' || lexptr[1] > '9')
+ if (pstate->lexptr[1] < '0' || pstate->lexptr[1] > '9')
{
last_was_structop = true;
goto symbol; /* Nope, must be a symbol. */
err_copy[p - tokstart] = 0;
error (_("Invalid number \"%s\"."), err_copy);
}
- lexptr = p;
+ pstate->lexptr = p;
return toktype;
}
if (strncmp (p, "selector", len) == 0
&& (p[len] == '\0' || ISSPACE (p[len])))
{
- lexptr = p + len;
+ pstate->lexptr = p + len;
return SELECTOR;
}
else if (*p == '"')
if (strncmp (p, "entry", len) == 0 && !c_ident_is_alnum (p[len])
&& p[len] != '_')
{
- lexptr = &p[len];
+ pstate->lexptr = &p[len];
return ENTRY;
}
}
case '{':
case '}':
symbol:
- lexptr++;
+ pstate->lexptr++;
return c;
case 'L':
parse_string:
{
int host_len;
- int result = parse_string_or_char (tokstart, &lexptr, &yylval.tsval,
- &host_len);
+ int result = parse_string_or_char (tokstart, &pstate->lexptr,
+ &yylval.tsval, &host_len);
if (result == CHAR)
{
if (host_len == 0)
else if (host_len > 2 && c == '\'')
{
++tokstart;
- namelen = lexptr - tokstart - 1;
+ namelen = pstate->lexptr - tokstart - 1;
*is_quoted_name = true;
goto tryname;
return 0;
}
- lexptr += namelen;
+ pstate->lexptr += namelen;
tryname:
if (*tokstart == '$')
return DOLLAR_VARIABLE;
- if (parse_completion && *lexptr == '\0')
+ if (parse_completion && *pstate->lexptr == '\0')
saw_name_at_eof = 1;
yylval.ssym.stoken = yylval.sval;
static void
yyerror (const char *msg)
{
- if (prev_lexptr)
- lexptr = prev_lexptr;
+ if (pstate->prev_lexptr)
+ pstate->lexptr = pstate->prev_lexptr;
- error (_("A %s in expression, near `%s'."), msg, lexptr);
+ error (_("A %s in expression, near `%s'."), msg, pstate->lexptr);
}
retry:
- prev_lexptr = lexptr;
+ pstate->prev_lexptr = pstate->lexptr;
- tokstart = lexptr;
+ tokstart = pstate->lexptr;
/* See if it is a special token of length 3. */
for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
if (strncmp (tokstart, tokentab3[i].oper, 3) == 0)
{
- lexptr += 3;
+ pstate->lexptr += 3;
yylval.opcode = tokentab3[i].opcode;
return tokentab3[i].token;
}
for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
if (strncmp (tokstart, tokentab2[i].oper, 2) == 0)
{
- lexptr += 2;
+ pstate->lexptr += 2;
yylval.opcode = tokentab2[i].opcode;
return tokentab2[i].token;
}
case ' ':
case '\t':
case '\n':
- lexptr++;
+ pstate->lexptr++;
goto retry;
case '[':
case '(':
paren_depth++;
- lexptr++;
+ pstate->lexptr++;
return c;
case ']':
if (paren_depth == 0)
return 0;
paren_depth--;
- lexptr++;
+ pstate->lexptr++;
return c;
case ',':
if (pstate->comma_terminates && paren_depth == 0)
return 0;
- lexptr++;
+ pstate->lexptr++;
return c;
case '.':
/* Might be a floating point number. */
- if (lexptr[1] < '0' || lexptr[1] > '9')
+ if (pstate->lexptr[1] < '0' || pstate->lexptr[1] > '9')
{
if (parse_completion)
last_was_structop = 1;
err_copy[p - tokstart] = 0;
error (_("Invalid number \"%s\"."), err_copy);
}
- lexptr = p;
+ pstate->lexptr = p;
return toktype;
}
if (strncmp (p, "entry", len) == 0 && !isalnum (p[len])
&& p[len] != '_')
{
- lexptr = &p[len];
+ pstate->lexptr = &p[len];
return ENTRY;
}
}
case '{':
case '}':
symbol:
- lexptr++;
+ pstate->lexptr++;
return c;
case '\'':
case '`':
{
int host_len;
- int result = parse_string_or_char (tokstart, &lexptr, &yylval.tsval,
- &host_len);
+ int result = parse_string_or_char (tokstart, &pstate->lexptr,
+ &yylval.tsval, &host_len);
if (result == CHARACTER_LITERAL)
{
if (host_len == 0)
else if (host_len > 2 && c == '\'')
{
++tokstart;
- namelen = lexptr - tokstart - 1;
+ namelen = pstate->lexptr - tokstart - 1;
goto tryname;
}
else if (host_len > 1)
return 0;
}
- lexptr += namelen;
+ pstate->lexptr += namelen;
tryname:
return NAME_OR_INT;
}
- if (parse_completion && *lexptr == '\0')
+ if (parse_completion && *pstate->lexptr == '\0')
saw_name_at_eof = 1;
return IDENTIFIER;
static void
yyerror (const char *msg)
{
- if (prev_lexptr)
- lexptr = prev_lexptr;
+ if (pstate->prev_lexptr)
+ pstate->lexptr = pstate->prev_lexptr;
- error (_("A %s in expression, near `%s'."), msg, lexptr);
+ error (_("A %s in expression, near `%s'."), msg, pstate->lexptr);
}
static int
match_string_literal (void)
{
- const char *tokptr = lexptr;
+ const char *tokptr = pstate->lexptr;
for (tempbufindex = 0, tokptr++; *tokptr != '\0'; tokptr++)
{
CHECKBUF (1);
- if (*tokptr == *lexptr)
+ if (*tokptr == *pstate->lexptr)
{
- if (*(tokptr + 1) == *lexptr)
+ if (*(tokptr + 1) == *pstate->lexptr)
tokptr++;
else
break;
tempbuf[tempbufindex] = '\0';
yylval.sval.ptr = tempbuf;
yylval.sval.length = tempbufindex;
- lexptr = ++tokptr;
+ pstate->lexptr = ++tokptr;
return STRING_LITERAL;
}
}
retry:
- prev_lexptr = lexptr;
+ pstate->prev_lexptr = pstate->lexptr;
- tokstart = lexptr;
+ tokstart = pstate->lexptr;
/* First of all, let us make sure we are not dealing with the
special tokens .true. and .false. which evaluate to 1 and 0. */
- if (*lexptr == '.')
+ if (*pstate->lexptr == '.')
{
for (int i = 0; i < ARRAY_SIZE (boolean_values); i++)
{
if (strncasecmp (tokstart, boolean_values[i].name,
strlen (boolean_values[i].name)) == 0)
{
- lexptr += strlen (boolean_values[i].name);
+ pstate->lexptr += strlen (boolean_values[i].name);
yylval.lval = boolean_values[i].value;
return BOOLEAN_LITERAL;
}
strlen (dot_ops[i].oper)) == 0)
{
gdb_assert (!dot_ops[i].case_sensitive);
- lexptr += strlen (dot_ops[i].oper);
+ pstate->lexptr += strlen (dot_ops[i].oper);
yylval.opcode = dot_ops[i].opcode;
return dot_ops[i].token;
}
if (strncmp (tokstart, "**", 2) == 0)
{
- lexptr += 2;
+ pstate->lexptr += 2;
yylval.opcode = BINOP_EXP;
return STARSTAR;
}
case ' ':
case '\t':
case '\n':
- lexptr++;
+ pstate->lexptr++;
goto retry;
case '\'':
case '(':
paren_depth++;
- lexptr++;
+ pstate->lexptr++;
return c;
case ')':
if (paren_depth == 0)
return 0;
paren_depth--;
- lexptr++;
+ pstate->lexptr++;
return c;
case ',':
if (pstate->comma_terminates && paren_depth == 0)
return 0;
- lexptr++;
+ pstate->lexptr++;
return c;
case '.':
/* Might be a floating point number. */
- if (lexptr[1] < '0' || lexptr[1] > '9')
+ if (pstate->lexptr[1] < '0' || pstate->lexptr[1] > '9')
goto symbol; /* Nope, must be a symbol. */
/* FALL THRU. */
err_copy[p - tokstart] = 0;
error (_("Invalid number \"%s\"."), err_copy);
}
- lexptr = p;
+ pstate->lexptr = p;
return toktype;
}
case '{':
case '}':
symbol:
- lexptr++;
+ pstate->lexptr++;
return c;
}
if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
return 0;
- lexptr += namelen;
+ pstate->lexptr += namelen;
/* Catch specific keywords. */
static void
yyerror (const char *msg)
{
- if (prev_lexptr)
- lexptr = prev_lexptr;
+ if (pstate->prev_lexptr)
+ pstate->lexptr = pstate->prev_lexptr;
- error (_("A %s in expression, near `%s'."), msg, lexptr);
+ error (_("A %s in expression, near `%s'."), msg, pstate->lexptr);
}
retry:
- prev_lexptr = lexptr;
+ par_state->prev_lexptr = par_state->lexptr;
- tokstart = lexptr;
+ tokstart = par_state->lexptr;
/* See if it is a special token of length 3. */
for (i = 0; i < sizeof (tokentab3) / sizeof (tokentab3[0]); i++)
if (strncmp (tokstart, tokentab3[i].oper, 3) == 0)
{
- lexptr += 3;
+ par_state->lexptr += 3;
yylval.opcode = tokentab3[i].opcode;
return tokentab3[i].token;
}
for (i = 0; i < sizeof (tokentab2) / sizeof (tokentab2[0]); i++)
if (strncmp (tokstart, tokentab2[i].oper, 2) == 0)
{
- lexptr += 2;
+ par_state->lexptr += 2;
yylval.opcode = tokentab2[i].opcode;
/* NOTE: -> doesn't exist in Go, so we don't need to watch for
setting last_was_structop here. */
case ' ':
case '\t':
case '\n':
- lexptr++;
+ par_state->lexptr++;
goto retry;
case '[':
case '(':
paren_depth++;
- lexptr++;
+ par_state->lexptr++;
return c;
case ']':
if (paren_depth == 0)
return 0;
paren_depth--;
- lexptr++;
+ par_state->lexptr++;
return c;
case ',':
if (pstate->comma_terminates
&& paren_depth == 0)
return 0;
- lexptr++;
+ par_state->lexptr++;
return c;
case '.':
/* Might be a floating point number. */
- if (lexptr[1] < '0' || lexptr[1] > '9')
+ if (par_state->lexptr[1] < '0' || par_state->lexptr[1] > '9')
{
if (parse_completion)
last_was_structop = 1;
err_copy[p - tokstart] = 0;
error (_("Invalid number \"%s\"."), err_copy);
}
- lexptr = p;
+ par_state->lexptr = p;
return toktype;
}
if (strncmp (p, "entry", len) == 0 && !isalnum (p[len])
&& p[len] != '_')
{
- lexptr = &p[len];
+ par_state->lexptr = &p[len];
return ENTRY;
}
}
case '{':
case '}':
symbol:
- lexptr++;
+ par_state->lexptr++;
return c;
case '\'':
case '`':
{
int host_len;
- int result = parse_string_or_char (tokstart, &lexptr, &yylval.tsval,
- &host_len);
+ int result = parse_string_or_char (tokstart, &par_state->lexptr,
+ &yylval.tsval, &host_len);
if (result == CHAR)
{
if (host_len == 0)
else if (host_len > 2 && c == '\'')
{
++tokstart;
- namelen = lexptr - tokstart - 1;
+ namelen = par_state->lexptr - tokstart - 1;
goto tryname;
}
else if (host_len > 1)
return 0;
}
- lexptr += namelen;
+ par_state->lexptr += namelen;
tryname:
if (*tokstart == '$')
return DOLLAR_VARIABLE;
- if (parse_completion && *lexptr == '\0')
+ if (parse_completion && *par_state->lexptr == '\0')
saw_name_at_eof = 1;
return NAME;
}
static void
yyerror (const char *msg)
{
- if (prev_lexptr)
- lexptr = prev_lexptr;
+ if (pstate->prev_lexptr)
+ pstate->lexptr = pstate->prev_lexptr;
- error (_("A %s in expression, near `%s'."), msg, lexptr);
+ error (_("A %s in expression, near `%s'."), msg, pstate->lexptr);
}
static int
parse_number (int olen)
{
- const char *p = lexptr;
+ const char *p = pstate->lexptr;
LONGEST n = 0;
LONGEST prevn = 0;
int c,i,ischar=0;
yylval.val))
return ERROR;
- lexptr += len;
+ pstate->lexptr += len;
return FLOAT;
}
if (p[c] == '.' && base != 10)
prevn=n;
}
- lexptr = p;
+ pstate->lexptr = p;
if(*p == 'B' || *p == 'C' || *p == 'H')
- lexptr++; /* Advance past B,C or H */
+ pstate->lexptr++; /* Advance past B,C or H */
if (ischar)
{
retry:
- prev_lexptr = lexptr;
+ pstate->prev_lexptr = pstate->lexptr;
- tokstart = lexptr;
+ tokstart = pstate->lexptr;
/* See if it is a special token of length 2 */
for( i = 0 ; i < (int) (sizeof tokentab2 / sizeof tokentab2[0]) ; i++)
if (strncmp (tokentab2[i].name, tokstart, 2) == 0)
{
- lexptr += 2;
+ pstate->lexptr += 2;
return tokentab2[i].token;
}
case ' ':
case '\t':
case '\n':
- lexptr++;
+ pstate->lexptr++;
goto retry;
case '(':
paren_depth++;
- lexptr++;
+ pstate->lexptr++;
return c;
case ')':
if (paren_depth == 0)
return 0;
paren_depth--;
- lexptr++;
+ pstate->lexptr++;
return c;
case ',':
if (pstate->comma_terminates && paren_depth == 0)
return 0;
- lexptr++;
+ pstate->lexptr++;
return c;
case '.':
/* Might be a floating point number. */
- if (lexptr[1] >= '0' && lexptr[1] <= '9')
+ if (pstate->lexptr[1] >= '0' && pstate->lexptr[1] <= '9')
break; /* Falls into number code. */
else
{
- lexptr++;
+ pstate->lexptr++;
return DOT;
}
case '@':
case '~':
case '&':
- lexptr++;
+ pstate->lexptr++;
return c;
case '\'' :
error (_("Unterminated string or character constant."));
yylval.sval.ptr = tokstart + 1;
yylval.sval.length = namelen - 1;
- lexptr += namelen + 1;
+ pstate->lexptr += namelen + 1;
if(namelen == 2) /* Single character */
{
err_copy[p - tokstart] = 0;
error (_("Invalid number \"%s\"."), err_copy);
}
- lexptr = p;
+ pstate->lexptr = p;
return toktype;
}
return 0;
}
- lexptr += namelen;
+ pstate->lexptr += namelen;
/* Lookup special keywords */
for(i = 0 ; i < (int) (sizeof(keytab) / sizeof(keytab[0])) ; i++)
static void
yyerror (const char *msg)
{
- if (prev_lexptr)
- lexptr = prev_lexptr;
+ if (pstate->prev_lexptr)
+ pstate->lexptr = pstate->prev_lexptr;
- error (_("A %s in expression, near `%s'."), msg, lexptr);
+ error (_("A %s in expression, near `%s'."), msg, pstate->lexptr);
}
retry:
- prev_lexptr = lexptr;
+ pstate->prev_lexptr = pstate->lexptr;
- tokstart = lexptr;
- explen = strlen (lexptr);
+ tokstart = pstate->lexptr;
+ explen = strlen (pstate->lexptr);
/* See if it is a special token of length 3. */
if (explen > 2)
|| (!isalpha (tokstart[3])
&& !isdigit (tokstart[3]) && tokstart[3] != '_')))
{
- lexptr += 3;
+ pstate->lexptr += 3;
yylval.opcode = tokentab3[i].opcode;
return tokentab3[i].token;
}
|| (!isalpha (tokstart[2])
&& !isdigit (tokstart[2]) && tokstart[2] != '_')))
{
- lexptr += 2;
+ pstate->lexptr += 2;
yylval.opcode = tokentab2[i].opcode;
return tokentab2[i].token;
}
case ' ':
case '\t':
case '\n':
- lexptr++;
+ pstate->lexptr++;
goto retry;
case '\'':
/* We either have a character constant ('0' or '\177' for example)
or we have a quoted symbol reference ('foo(int,int)' in object pascal
for example). */
- lexptr++;
- c = *lexptr++;
+ pstate->lexptr++;
+ c = *pstate->lexptr++;
if (c == '\\')
- c = parse_escape (pstate->gdbarch (), &lexptr);
+ c = parse_escape (pstate->gdbarch (), &pstate->lexptr);
else if (c == '\'')
error (_("Empty character constant."));
yylval.typed_val_int.val = c;
yylval.typed_val_int.type = parse_type (pstate)->builtin_char;
- c = *lexptr++;
+ c = *pstate->lexptr++;
if (c != '\'')
{
namelen = skip_quoted (tokstart) - tokstart;
if (namelen > 2)
{
- lexptr = tokstart + namelen;
- if (lexptr[-1] != '\'')
+ pstate->lexptr = tokstart + namelen;
+ if (pstate->lexptr[-1] != '\'')
error (_("Unmatched single quote."));
namelen -= 2;
tokstart++;
case '(':
paren_depth++;
- lexptr++;
+ pstate->lexptr++;
return c;
case ')':
if (paren_depth == 0)
return 0;
paren_depth--;
- lexptr++;
+ pstate->lexptr++;
return c;
case ',':
if (pstate->comma_terminates && paren_depth == 0)
return 0;
- lexptr++;
+ pstate->lexptr++;
return c;
case '.':
/* Might be a floating point number. */
- if (lexptr[1] < '0' || lexptr[1] > '9')
+ if (pstate->lexptr[1] < '0' || pstate->lexptr[1] > '9')
{
goto symbol; /* Nope, must be a symbol. */
}
err_copy[p - tokstart] = 0;
error (_("Invalid number \"%s\"."), err_copy);
}
- lexptr = p;
+ pstate->lexptr = p;
return toktype;
}
case '{':
case '}':
symbol:
- lexptr++;
+ pstate->lexptr++;
return c;
case '"':
tempbuf[tempbufindex] = '\0'; /* See note above. */
yylval.sval.ptr = tempbuf;
yylval.sval.length = tempbufindex;
- lexptr = tokptr;
+ pstate->lexptr = tokptr;
return (STRING);
}
return 0;
}
- lexptr += namelen;
+ pstate->lexptr += namelen;
tryname:
us whether a type is nested), we just ignore the
containing type. */
- p = lexptr;
+ p = pstate->lexptr;
best_sym = sym;
while (1)
{
if (SYMBOL_CLASS (cur_sym) == LOC_TYPEDEF)
{
best_sym = cur_sym;
- lexptr = p;
+ pstate->lexptr = p;
}
else
break;
static void
yyerror (const char *msg)
{
- if (prev_lexptr)
- lexptr = prev_lexptr;
+ if (pstate->prev_lexptr)
+ pstate->lexptr = pstate->prev_lexptr;
- error (_("A %s in expression, near `%s'."), msg, lexptr);
+ error (_("A %s in expression, near `%s'."), msg, pstate->lexptr);
}
innermost_block_tracker innermost_block;
int arglist_len;
static struct type_stack type_stack;
-const char *lexptr;
-const char *prev_lexptr;
/* True if parsing an expression to attempt completion. */
int parse_completion;
const struct language_defn *lang = NULL;
int subexp;
- lexptr = *stringptr;
- prev_lexptr = NULL;
-
type_stack.elements.clear ();
expout_last_struct = -1;
expout_tag_completion_type = TYPE_CODE_UNDEF;
expout_completion_name.reset ();
innermost_block.reset (tracker_types);
- if (lexptr == 0 || *lexptr == 0)
+ if (*stringptr == 0 || **stringptr == 0)
error_no_arg (_("expression to compute"));
std::vector<int> funcalls;
to the value matching SELECTED_FRAME as set by get_current_arch. */
parser_state ps (lang, get_current_arch (), expression_context_block,
- expression_context_pc, comma);
+ expression_context_pc, comma, *stringptr);
scoped_restore_current_language lang_saver;
set_language (lang->la_language);
if (expressiondebug)
dump_prefix_expression (result.get (), gdb_stdlog);
- *stringptr = lexptr;
+ *stringptr = ps.lexptr;
return result;
}
struct gdbarch *gdbarch,
const struct block *context_block,
CORE_ADDR context_pc,
- int comma)
+ int comma,
+ const char *input)
: expr_builder (lang, gdbarch),
expression_context_block (context_block),
expression_context_pc (context_pc),
- comma_terminates (comma)
+ comma_terminates (comma),
+ lexptr (input)
{
}
/* Nonzero means stop parsing on first comma (if not within parentheses). */
int comma_terminates;
+
+ /* During parsing of a C expression, the pointer to the next character
+ is in this variable. */
+
+ const char *lexptr;
+
+ /* After a token has been recognized, this variable points to it.
+ Currently used only for error reporting. */
+ const char *prev_lexptr = nullptr;
};
/* When parsing expressions we track the innermost block that was
extern bool parse_float (const char *p, int len,
const struct type *type, gdb_byte *data);
-
-/* During parsing of a C expression, the pointer to the next character
- is in this variable. */
-
-extern const char *lexptr;
-
-/* After a token has been recognized, this variable points to it.
- Currently used only for error reporting. */
-extern const char *prev_lexptr;
\f
/* These codes indicate operator precedences for expression printing,
least tightly binding first. */
static int rustyylex (YYSTYPE *, rust_parser *);
static void rustyyerror (rust_parser *parser, const char *msg);
-static void rust_push_back (char c);
static struct stoken make_stoken (const char *);
static struct block_symbol rust_lookup_symbol (const char *name,
const struct block *block,
int lex_number (YYSTYPE *lvalp);
int lex_string (YYSTYPE *lvalp);
int lex_identifier (YYSTYPE *lvalp);
+ uint32_t lex_hex (int min, int max);
+ uint32_t lex_escape (int is_byte);
+ int lex_operator (YYSTYPE *lvalp);
+ void push_back (char c);
struct type *rust_lookup_type (const char *name, const struct block *block);
std::vector<struct type *> convert_params_to_types (rust_op_vector *params);
| identifier_path_for_expr COLONCOLON '<' type_list RSH
{
$$ = parser->ast_path ($1->left.sval, $4);
- rust_push_back ('>');
+ parser->push_back ('>');
}
;
| just_identifiers_for_type '<' type_list RSH
{
$$ = parser->ast_path ($1->left.sval, $3);
- rust_push_back ('>');
+ parser->push_back ('>');
}
;
/* Lex a hex number with at least MIN digits and at most MAX
digits. */
-static uint32_t
-lex_hex (int min, int max)
+uint32_t
+rust_parser::lex_hex (int min, int max)
{
uint32_t result = 0;
int len = 0;
int check_max = min == max;
while ((check_max ? len <= max : 1)
- && ((lexptr[0] >= 'a' && lexptr[0] <= 'f')
- || (lexptr[0] >= 'A' && lexptr[0] <= 'F')
- || (lexptr[0] >= '0' && lexptr[0] <= '9')))
+ && ((pstate->lexptr[0] >= 'a' && pstate->lexptr[0] <= 'f')
+ || (pstate->lexptr[0] >= 'A' && pstate->lexptr[0] <= 'F')
+ || (pstate->lexptr[0] >= '0' && pstate->lexptr[0] <= '9')))
{
result *= 16;
- if (lexptr[0] >= 'a' && lexptr[0] <= 'f')
- result = result + 10 + lexptr[0] - 'a';
- else if (lexptr[0] >= 'A' && lexptr[0] <= 'F')
- result = result + 10 + lexptr[0] - 'A';
+ if (pstate->lexptr[0] >= 'a' && pstate->lexptr[0] <= 'f')
+ result = result + 10 + pstate->lexptr[0] - 'a';
+ else if (pstate->lexptr[0] >= 'A' && pstate->lexptr[0] <= 'F')
+ result = result + 10 + pstate->lexptr[0] - 'A';
else
- result = result + lexptr[0] - '0';
- ++lexptr;
+ result = result + pstate->lexptr[0] - '0';
+ ++pstate->lexptr;
++len;
}
/* Lex an escape. IS_BYTE is true if we're lexing a byte escape;
otherwise we're lexing a character escape. */
-static uint32_t
-lex_escape (int is_byte)
+uint32_t
+rust_parser::lex_escape (int is_byte)
{
uint32_t result;
- gdb_assert (lexptr[0] == '\\');
- ++lexptr;
- switch (lexptr[0])
+ gdb_assert (pstate->lexptr[0] == '\\');
+ ++pstate->lexptr;
+ switch (pstate->lexptr[0])
{
case 'x':
- ++lexptr;
+ ++pstate->lexptr;
result = lex_hex (2, 2);
break;
case 'u':
if (is_byte)
error (_("Unicode escape in byte literal"));
- ++lexptr;
- if (lexptr[0] != '{')
+ ++pstate->lexptr;
+ if (pstate->lexptr[0] != '{')
error (_("Missing '{' in Unicode escape"));
- ++lexptr;
+ ++pstate->lexptr;
result = lex_hex (1, 6);
/* Could do range checks here. */
- if (lexptr[0] != '}')
+ if (pstate->lexptr[0] != '}')
error (_("Missing '}' in Unicode escape"));
- ++lexptr;
+ ++pstate->lexptr;
break;
case 'n':
result = '\n';
- ++lexptr;
+ ++pstate->lexptr;
break;
case 'r':
result = '\r';
- ++lexptr;
+ ++pstate->lexptr;
break;
case 't':
result = '\t';
- ++lexptr;
+ ++pstate->lexptr;
break;
case '\\':
result = '\\';
- ++lexptr;
+ ++pstate->lexptr;
break;
case '0':
result = '\0';
- ++lexptr;
+ ++pstate->lexptr;
break;
case '\'':
result = '\'';
- ++lexptr;
+ ++pstate->lexptr;
break;
case '"':
result = '"';
- ++lexptr;
+ ++pstate->lexptr;
break;
default:
- error (_("Invalid escape \\%c in literal"), lexptr[0]);
+ error (_("Invalid escape \\%c in literal"), pstate->lexptr[0]);
}
return result;
int is_byte = 0;
uint32_t value;
- if (lexptr[0] == 'b')
+ if (pstate->lexptr[0] == 'b')
{
is_byte = 1;
- ++lexptr;
+ ++pstate->lexptr;
}
- gdb_assert (lexptr[0] == '\'');
- ++lexptr;
+ gdb_assert (pstate->lexptr[0] == '\'');
+ ++pstate->lexptr;
/* This should handle UTF-8 here. */
- if (lexptr[0] == '\\')
+ if (pstate->lexptr[0] == '\\')
value = lex_escape (is_byte);
else
{
- value = lexptr[0] & 0xff;
- ++lexptr;
+ value = pstate->lexptr[0] & 0xff;
+ ++pstate->lexptr;
}
- if (lexptr[0] != '\'')
+ if (pstate->lexptr[0] != '\'')
error (_("Unterminated character literal"));
- ++lexptr;
+ ++pstate->lexptr;
lvalp->typed_val_int.val = value;
lvalp->typed_val_int.type = get_type (is_byte ? "u8" : "char");
int
rust_parser::lex_string (YYSTYPE *lvalp)
{
- int is_byte = lexptr[0] == 'b';
+ int is_byte = pstate->lexptr[0] == 'b';
int raw_length;
if (is_byte)
- ++lexptr;
- raw_length = starts_raw_string (lexptr);
- lexptr += raw_length;
- gdb_assert (lexptr[0] == '"');
- ++lexptr;
+ ++pstate->lexptr;
+ raw_length = starts_raw_string (pstate->lexptr);
+ pstate->lexptr += raw_length;
+ gdb_assert (pstate->lexptr[0] == '"');
+ ++pstate->lexptr;
while (1)
{
if (raw_length > 0)
{
- if (lexptr[0] == '"' && ends_raw_string (lexptr, raw_length - 1))
+ if (pstate->lexptr[0] == '"' && ends_raw_string (pstate->lexptr,
+ raw_length - 1))
{
/* Exit with lexptr pointing after the final "#". */
- lexptr += raw_length;
+ pstate->lexptr += raw_length;
break;
}
- else if (lexptr[0] == '\0')
+ else if (pstate->lexptr[0] == '\0')
error (_("Unexpected EOF in string"));
- value = lexptr[0] & 0xff;
+ value = pstate->lexptr[0] & 0xff;
if (is_byte && value > 127)
error (_("Non-ASCII value in raw byte string"));
obstack_1grow (&obstack, value);
- ++lexptr;
+ ++pstate->lexptr;
}
- else if (lexptr[0] == '"')
+ else if (pstate->lexptr[0] == '"')
{
/* Make sure to skip the quote. */
- ++lexptr;
+ ++pstate->lexptr;
break;
}
- else if (lexptr[0] == '\\')
+ else if (pstate->lexptr[0] == '\\')
{
value = lex_escape (is_byte);
sizeof (value), sizeof (value),
&obstack, translit_none);
}
- else if (lexptr[0] == '\0')
+ else if (pstate->lexptr[0] == '\0')
error (_("Unexpected EOF in string"));
else
{
- value = lexptr[0] & 0xff;
+ value = pstate->lexptr[0] & 0xff;
if (is_byte && value > 127)
error (_("Non-ASCII value in byte string"));
obstack_1grow (&obstack, value);
- ++lexptr;
+ ++pstate->lexptr;
}
}
int
rust_parser::lex_identifier (YYSTYPE *lvalp)
{
- const char *start = lexptr;
+ const char *start = pstate->lexptr;
unsigned int length;
const struct token_info *token;
int i;
- int is_gdb_var = lexptr[0] == '$';
+ int is_gdb_var = pstate->lexptr[0] == '$';
- gdb_assert (rust_identifier_start_p (lexptr[0]));
+ gdb_assert (rust_identifier_start_p (pstate->lexptr[0]));
- ++lexptr;
+ ++pstate->lexptr;
/* For the time being this doesn't handle Unicode rules. Non-ASCII
identifiers are gated anyway. */
- while ((lexptr[0] >= 'a' && lexptr[0] <= 'z')
- || (lexptr[0] >= 'A' && lexptr[0] <= 'Z')
- || lexptr[0] == '_'
- || (is_gdb_var && lexptr[0] == '$')
- || (lexptr[0] >= '0' && lexptr[0] <= '9'))
- ++lexptr;
+ while ((pstate->lexptr[0] >= 'a' && pstate->lexptr[0] <= 'z')
+ || (pstate->lexptr[0] >= 'A' && pstate->lexptr[0] <= 'Z')
+ || pstate->lexptr[0] == '_'
+ || (is_gdb_var && pstate->lexptr[0] == '$')
+ || (pstate->lexptr[0] >= '0' && pstate->lexptr[0] <= '9'))
+ ++pstate->lexptr;
- length = lexptr - start;
+ length = pstate->lexptr - start;
token = NULL;
for (i = 0; i < ARRAY_SIZE (identifier_tokens); ++i)
{
if (token->value == 0)
{
/* Leave the terminating token alone. */
- lexptr = start;
+ pstate->lexptr = start;
return 0;
}
}
else if (token == NULL
&& (strncmp (start, "thread", length) == 0
|| strncmp (start, "task", length) == 0)
- && space_then_number (lexptr))
+ && space_then_number (pstate->lexptr))
{
/* "task" or "thread" followed by a number terminates the
parse, per gdb rules. */
- lexptr = start;
+ pstate->lexptr = start;
return 0;
}
- if (token == NULL || (parse_completion && lexptr[0] == '\0'))
+ if (token == NULL || (parse_completion && pstate->lexptr[0] == '\0'))
lvalp->sval = make_stoken (copy_name (start, length));
- if (parse_completion && lexptr[0] == '\0')
+ if (parse_completion && pstate->lexptr[0] == '\0')
{
/* Prevent rustyylex from returning two COMPLETE tokens. */
- prev_lexptr = lexptr;
+ pstate->prev_lexptr = pstate->lexptr;
return COMPLETE;
}
/* Lex an operator. */
-static int
-lex_operator (YYSTYPE *lvalp)
+int
+rust_parser::lex_operator (YYSTYPE *lvalp)
{
const struct token_info *token = NULL;
int i;
for (i = 0; i < ARRAY_SIZE (operator_tokens); ++i)
{
- if (strncmp (operator_tokens[i].name, lexptr,
+ if (strncmp (operator_tokens[i].name, pstate->lexptr,
strlen (operator_tokens[i].name)) == 0)
{
- lexptr += strlen (operator_tokens[i].name);
+ pstate->lexptr += strlen (operator_tokens[i].name);
token = &operator_tokens[i];
break;
}
return token->value;
}
- return *lexptr++;
+ return *pstate->lexptr++;
}
/* Lex a number. */
int type_index = -1;
int i;
- match = regexec (&number_regex, lexptr, ARRAY_SIZE (subexps), subexps, 0);
+ match = regexec (&number_regex, pstate->lexptr, ARRAY_SIZE (subexps),
+ subexps, 0);
/* Failure means the regexp is broken. */
gdb_assert (match == 0);
a request for a trait method call, not a syntax error involving
the floating point number "23.". */
gdb_assert (subexps[0].rm_eo > 0);
- if (lexptr[subexps[0].rm_eo - 1] == '.')
+ if (pstate->lexptr[subexps[0].rm_eo - 1] == '.')
{
- const char *next = skip_spaces (&lexptr[subexps[0].rm_eo]);
+ const char *next = skip_spaces (&pstate->lexptr[subexps[0].rm_eo]);
if (rust_identifier_start_p (*next) || *next == '.')
{
if (type_name == NULL)
{
gdb_assert (type_index != -1);
- type_name_holder = std::string (lexptr + subexps[type_index].rm_so,
+ type_name_holder = std::string ((pstate->lexptr
+ + subexps[type_index].rm_so),
(subexps[type_index].rm_eo
- subexps[type_index].rm_so));
type_name = type_name_holder.c_str ();
/* Copy the text of the number and remove the "_"s. */
std::string number;
- for (i = 0; i < end_index && lexptr[i]; ++i)
+ for (i = 0; i < end_index && pstate->lexptr[i]; ++i)
{
- if (lexptr[i] == '_')
+ if (pstate->lexptr[i] == '_')
could_be_decimal = 0;
else
- number.push_back (lexptr[i]);
+ number.push_back (pstate->lexptr[i]);
}
/* Advance past the match. */
- lexptr += subexps[0].rm_eo;
+ pstate->lexptr += subexps[0].rm_eo;
/* Parse the number. */
if (is_integer)
static int
rustyylex (YYSTYPE *lvalp, rust_parser *parser)
{
+ struct parser_state *pstate = parser->pstate;
+
/* Skip all leading whitespace. */
- while (lexptr[0] == ' ' || lexptr[0] == '\t' || lexptr[0] == '\r'
- || lexptr[0] == '\n')
- ++lexptr;
+ while (pstate->lexptr[0] == ' '
+ || pstate->lexptr[0] == '\t'
+ || pstate->lexptr[0] == '\r'
+ || pstate->lexptr[0] == '\n')
+ ++pstate->lexptr;
/* If we hit EOF and we're completing, then return COMPLETE -- maybe
we're completing an empty string at the end of a field_expr.
But, we don't want to return two COMPLETE tokens in a row. */
- if (lexptr[0] == '\0' && lexptr == prev_lexptr)
+ if (pstate->lexptr[0] == '\0' && pstate->lexptr == pstate->prev_lexptr)
return 0;
- prev_lexptr = lexptr;
- if (lexptr[0] == '\0')
+ pstate->prev_lexptr = pstate->lexptr;
+ if (pstate->lexptr[0] == '\0')
{
if (parse_completion)
{
return 0;
}
- if (lexptr[0] >= '0' && lexptr[0] <= '9')
+ if (pstate->lexptr[0] >= '0' && pstate->lexptr[0] <= '9')
return parser->lex_number (lvalp);
- else if (lexptr[0] == 'b' && lexptr[1] == '\'')
+ else if (pstate->lexptr[0] == 'b' && pstate->lexptr[1] == '\'')
return parser->lex_character (lvalp);
- else if (lexptr[0] == 'b' && lexptr[1] == '"')
+ else if (pstate->lexptr[0] == 'b' && pstate->lexptr[1] == '"')
return parser->lex_string (lvalp);
- else if (lexptr[0] == 'b' && starts_raw_string (lexptr + 1))
+ else if (pstate->lexptr[0] == 'b' && starts_raw_string (pstate->lexptr + 1))
return parser->lex_string (lvalp);
- else if (starts_raw_string (lexptr))
+ else if (starts_raw_string (pstate->lexptr))
return parser->lex_string (lvalp);
- else if (rust_identifier_start_p (lexptr[0]))
+ else if (rust_identifier_start_p (pstate->lexptr[0]))
return parser->lex_identifier (lvalp);
- else if (lexptr[0] == '"')
+ else if (pstate->lexptr[0] == '"')
return parser->lex_string (lvalp);
- else if (lexptr[0] == '\'')
+ else if (pstate->lexptr[0] == '\'')
return parser->lex_character (lvalp);
- else if (lexptr[0] == '}' || lexptr[0] == ']')
+ else if (pstate->lexptr[0] == '}' || pstate->lexptr[0] == ']')
{
/* Falls through to lex_operator. */
--parser->paren_depth;
}
- else if (lexptr[0] == '(' || lexptr[0] == '{')
+ else if (pstate->lexptr[0] == '(' || pstate->lexptr[0] == '{')
{
/* Falls through to lex_operator. */
++parser->paren_depth;
}
- else if (lexptr[0] == ',' && parser->pstate->comma_terminates
+ else if (pstate->lexptr[0] == ',' && pstate->comma_terminates
&& parser->paren_depth == 0)
return 0;
- return lex_operator (lvalp);
+ return parser->lex_operator (lvalp);
}
/* Push back a single character to be re-lexed. */
-static void
-rust_push_back (char c)
+void
+rust_parser::push_back (char c)
{
/* Can't be called before any lexing. */
- gdb_assert (prev_lexptr != NULL);
+ gdb_assert (pstate->prev_lexptr != NULL);
- --lexptr;
- gdb_assert (*lexptr == c);
+ --pstate->lexptr;
+ gdb_assert (*pstate->lexptr == c);
}
\f
static void
rustyyerror (rust_parser *parser, const char *msg)
{
- const char *where = prev_lexptr ? prev_lexptr : lexptr;
+ const char *where = (parser->pstate->prev_lexptr
+ ? parser->pstate->prev_lexptr
+ : parser->pstate->lexptr);
error (_("%s in expression, near `%s'."), msg, where);
}
static void
rust_lex_test_init (rust_parser *parser, const char *input)
{
- prev_lexptr = NULL;
- lexptr = input;
+ parser->pstate->prev_lexptr = NULL;
+ parser->pstate->lexptr = input;
parser->paren_depth = 0;
}
{
int i;
- lexptr = input;
+ parser->pstate->lexptr = input;
parser->paren_depth = 0;
for (i = 0; i < len; ++i)
SELF_CHECK (token == COMPOUND_ASSIGN);
SELF_CHECK (lval.opcode == BINOP_RSH);
- rust_push_back ('=');
+ parser->push_back ('=');
token = rustyylex (&lval, parser);
SELF_CHECK (token == '=');
// Set up dummy "parser", so that rust_type works.
struct parser_state ps (&rust_language_defn, target_gdbarch (),
- nullptr, 0, 0);
+ nullptr, 0, 0, nullptr);
rust_parser parser (&ps);
rust_lex_test_one (&parser, "", 0);