/* YACC parser for Fortran expressions, for GDB.
- Copyright (C) 1986-2015 Free Software Foundation, Inc.
+ Copyright (C) 1986-2018 Free Software Foundation, Inc.
Contributed by Motorola. Adapted from the C parser by Farooq Butt
(fmbutt@engage.sps.mot.com).
#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
#include "block.h"
#include <ctype.h>
+#include <algorithm>
#define parse_type(ps) builtin_type (parse_gdbarch (ps))
#define parse_f_type(ps) builtin_f_type (parse_gdbarch (ps))
-/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
- as well as gratuitiously global symbol names, so we can have multiple
- yacc generated parsers in gdb. Note that these are only the variables
- produced by yacc. If other parser generators (bison, byacc, etc) produce
- additional global names that conflict at link time, then those parser
- generators need to be fixed instead of adding those names to this list. */
-
-#define yymaxdepth f_maxdepth
-#define yyparse f_parse_internal
-#define yylex f_lex
-#define yyerror f_error
-#define yylval f_lval
-#define yychar f_char
-#define yydebug f_debug
-#define yypact f_pact
-#define yyr1 f_r1
-#define yyr2 f_r2
-#define yydef f_def
-#define yychk f_chk
-#define yypgo f_pgo
-#define yyact f_act
-#define yyexca f_exca
-#define yyerrflag f_errflag
-#define yynerrs f_nerrs
-#define yyps f_ps
-#define yypv f_pv
-#define yys f_s
-#define yy_yys f_yys
-#define yystate f_state
-#define yytmp f_tmp
-#define yyv f_v
-#define yy_yyv f_yyv
-#define yyval f_val
-#define yylloc f_lloc
-#define yyreds f_reds /* With YYDEBUG defined */
-#define yytoks f_toks /* With YYDEBUG defined */
-#define yyname f_name /* With YYDEBUG defined */
-#define yyrule f_rule /* With YYDEBUG defined */
-#define yylhs f_yylhs
-#define yylen f_yylen
-#define yydefred f_yydefred
-#define yydgoto f_yydgoto
-#define yysindex f_yysindex
-#define yyrindex f_yyrindex
-#define yygindex f_yygindex
-#define yytable f_yytable
-#define yycheck f_yycheck
-#define yyss f_yyss
-#define yysslim f_yysslim
-#define yyssp f_yyssp
-#define yystacksize f_yystacksize
-#define yyvs f_yyvs
-#define yyvsp f_yyvsp
-
-#ifndef YYDEBUG
-#define YYDEBUG 1 /* Default to yydebug support */
-#endif
-
-#define YYFPRINTF parser_fprintf
+/* Remap normal yacc parser interface names (yyparse, yylex, yyerror,
+ etc). */
+#define GDB_YY_REMAP_PREFIX f_
+#include "yy-remap.h"
/* The state of the parser, used internally when we are parsing the
expression. */
static int yylex (void);
-void yyerror (char *);
+static void yyerror (const char *);
static void growbuf_by_size (int);
LONGEST val;
struct type *type;
} typed_val;
- DOUBLEST dval;
+ struct {
+ gdb_byte val[16];
+ struct type *type;
+ } typed_val_float;
struct symbol *sym;
struct type *tval;
struct stoken sval;
%type <tval> ptype
%token <typed_val> INT
-%token <dval> FLOAT
+%token <typed_val_float> FLOAT
/* Both NAME and TYPENAME tokens represent symbols in the input,
and both convey their data as strings.
/* There are four sorts of subrange types in F90. */
subrange: exp ':' exp %prec ABOVE_COMMA
- { write_exp_elt_opcode (pstate, OP_F90_RANGE);
+ { write_exp_elt_opcode (pstate, OP_RANGE);
write_exp_elt_longcst (pstate, NONE_BOUND_DEFAULT);
- write_exp_elt_opcode (pstate, OP_F90_RANGE); }
+ write_exp_elt_opcode (pstate, OP_RANGE); }
;
subrange: exp ':' %prec ABOVE_COMMA
- { write_exp_elt_opcode (pstate, OP_F90_RANGE);
+ { write_exp_elt_opcode (pstate, OP_RANGE);
write_exp_elt_longcst (pstate, HIGH_BOUND_DEFAULT);
- write_exp_elt_opcode (pstate, OP_F90_RANGE); }
+ write_exp_elt_opcode (pstate, OP_RANGE); }
;
subrange: ':' exp %prec ABOVE_COMMA
- { write_exp_elt_opcode (pstate, OP_F90_RANGE);
+ { write_exp_elt_opcode (pstate, OP_RANGE);
write_exp_elt_longcst (pstate, LOW_BOUND_DEFAULT);
- write_exp_elt_opcode (pstate, OP_F90_RANGE); }
+ write_exp_elt_opcode (pstate, OP_RANGE); }
;
subrange: ':' %prec ABOVE_COMMA
- { write_exp_elt_opcode (pstate, OP_F90_RANGE);
+ { write_exp_elt_opcode (pstate, OP_RANGE);
write_exp_elt_longcst (pstate, BOTH_BOUND_DEFAULT);
- write_exp_elt_opcode (pstate, OP_F90_RANGE); }
+ write_exp_elt_opcode (pstate, OP_RANGE); }
;
complexnum: exp ',' exp
;
exp : FLOAT
- { write_exp_elt_opcode (pstate, OP_DOUBLE);
- write_exp_elt_type (pstate,
- parse_f_type (pstate)
- ->builtin_real_s8);
- write_exp_elt_dblcst (pstate, $1);
- write_exp_elt_opcode (pstate, OP_DOUBLE); }
+ { write_exp_elt_opcode (pstate, OP_FLOAT);
+ write_exp_elt_type (pstate, $1.type);
+ write_exp_elt_floatcst (pstate, $1.val);
+ write_exp_elt_opcode (pstate, OP_FLOAT); }
;
exp : variable
;
variable: name_not_typename
- { struct symbol *sym = $1.sym;
+ { struct block_symbol sym = $1.sym;
- if (sym)
+ if (sym.symbol)
{
- if (symbol_read_needs_frame (sym))
- {
- if (innermost_block == 0
- || contained_in (block_found,
- innermost_block))
- innermost_block = block_found;
- }
+ if (symbol_read_needs_frame (sym.symbol))
+ innermost_block.update (sym);
write_exp_elt_opcode (pstate, OP_VAR_VALUE);
- /* We want to use the selected frame, not
- another more inner frame which happens to
- be in the same block. */
- write_exp_elt_block (pstate, NULL);
- write_exp_elt_sym (pstate, sym);
+ write_exp_elt_block (pstate, sym.block);
+ write_exp_elt_sym (pstate, sym.symbol);
write_exp_elt_opcode (pstate, OP_VAR_VALUE);
break;
}
follow_type = lookup_pointer_type (follow_type);
break;
case tp_reference:
- follow_type = lookup_reference_type (follow_type);
+ follow_type = lookup_lvalue_reference_type (follow_type);
break;
case tp_array:
array_size = pop_type_int ();
if (parsed_float)
{
/* It's a float since it contains a point or an exponent. */
- /* [dD] is not understood as an exponent by atof, change it to 'e'. */
+ /* [dD] is not understood as an exponent by parse_float,
+ change it to 'e'. */
char *tmp, *tmp2;
tmp = xstrdup (p);
for (tmp2 = tmp; *tmp2; ++tmp2)
if (*tmp2 == 'd' || *tmp2 == 'D')
*tmp2 = 'e';
- putithere->dval = atof (tmp);
+
+ /* FIXME: Should this use different types? */
+ putithere->typed_val_float.type = parse_f_type (pstate)->builtin_real_s8;
+ bool parsed = parse_float (tmp, len,
+ putithere->typed_val_float.type,
+ putithere->typed_val_float.val);
free (tmp);
- return FLOAT;
+ return parsed? FLOAT : ERROR;
}
/* Handle base-switching prefixes 0x, 0t, 0d, 0 */
struct token
{
- char *oper;
+ const char *oper;
int token;
enum exp_opcode opcode;
};
{ ".GT.", GREATERTHAN, BINOP_END },
{ ".lt.", LESSTHAN, BINOP_END },
{ ".LT.", LESSTHAN, BINOP_END },
- { NULL, 0, 0 }
+ { NULL, 0, BINOP_END }
};
struct f77_boolean_val
{
- char *name;
+ const char *name;
int value;
};
{ "sizeof", SIZEOF, BINOP_END },
{ "real_8", REAL_S8_KEYWORD, BINOP_END },
{ "real", REAL_KEYWORD, BINOP_END },
- { NULL, 0, 0 }
+ { NULL, 0, BINOP_END }
};
/* Implementation of a dynamically expandable buffer for processing input
{
int growby;
- growby = max (count, GROWBY_MIN_SIZE);
+ growby = std::max (count, GROWBY_MIN_SIZE);
tempbufsize += growby;
if (tempbuf == NULL)
tempbuf = (char *) malloc (tempbufsize);
/* Might be a floating point number. */
if (lexptr[1] < '0' || lexptr[1] > '9')
goto symbol; /* Nope, must be a symbol. */
- /* FALL THRU into number case. */
+ /* FALL THRU. */
case '0':
case '1':
The caller is not constrained to care about the distinction. */
{
char *tmp = copy_name (yylval.sval);
- struct symbol *sym;
+ struct block_symbol result;
struct field_of_this_result is_a_field_of_this;
enum domain_enum_tag lookup_domains[] =
{
way we can refer to it unconditionally below. */
memset (&is_a_field_of_this, 0, sizeof (is_a_field_of_this));
- sym = lookup_symbol (tmp, expression_context_block,
- lookup_domains[i],
- parse_language (pstate)->la_language
- == language_cplus ? &is_a_field_of_this : NULL);
- if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+ result = lookup_symbol (tmp, expression_context_block,
+ lookup_domains[i],
+ parse_language (pstate)->la_language
+ == language_cplus
+ ? &is_a_field_of_this : NULL);
+ if (result.symbol && SYMBOL_CLASS (result.symbol) == LOC_TYPEDEF)
{
- yylval.tsym.type = SYMBOL_TYPE (sym);
+ yylval.tsym.type = SYMBOL_TYPE (result.symbol);
return TYPENAME;
}
- if (sym)
+ if (result.symbol)
break;
}
/* Input names that aren't symbols but ARE valid hex numbers,
when the input radix permits them, can be names or numbers
depending on the parse. Note we support radixes > 16 here. */
- if (!sym
+ if (!result.symbol
&& ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10)
|| (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
{
hextype = parse_number (pstate, tokstart, namelen, 0, &newlval);
if (hextype == INT)
{
- yylval.ssym.sym = sym;
+ yylval.ssym.sym = result;
yylval.ssym.is_a_field_of_this = is_a_field_of_this.type != NULL;
return NAME_OR_INT;
}
}
/* Any other kind of symbol */
- yylval.ssym.sym = sym;
+ yylval.ssym.sym = result;
yylval.ssym.is_a_field_of_this = is_a_field_of_this.type != NULL;
return NAME;
}
int
f_parse (struct parser_state *par_state)
{
- int result;
- struct cleanup *c = make_cleanup_clear_parser_state (&pstate);
-
/* Setting up the parser state. */
+ scoped_restore pstate_restore = make_scoped_restore (&pstate);
gdb_assert (par_state != NULL);
pstate = par_state;
- result = yyparse ();
- do_cleanups (c);
- return result;
+ return yyparse ();
}
-void
-yyerror (char *msg)
+static void
+yyerror (const char *msg)
{
if (prev_lexptr)
lexptr = prev_lexptr;
- error (_("A %s in expression, near `%s'."), (msg ? msg : "error"), lexptr);
+ error (_("A %s in expression, near `%s'."), msg, lexptr);
}