X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fm2-exp.y;h=02e3cf1b4e7bd3486a5565dec5321d5b83cdccb5;hb=9cca177baec32a1ed1422a87a1f57cda2d2eb21a;hp=420c287ba7c0eca441aa35c0935a186422f5e385;hpb=aa59ba6b2707e2912437f780ffad25a897153f95;p=binutils-gdb.git
diff --git a/gdb/m2-exp.y b/gdb/m2-exp.y
index 420c287ba7c..02e3cf1b4e7 100644
--- a/gdb/m2-exp.y
+++ b/gdb/m2-exp.y
@@ -1,25 +1,22 @@
/* YACC grammar for Modula-2 expressions, for GDB.
- Copyright (C) 1986, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999,
- 2000, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 1986-2022 Free Software Foundation, Inc.
Generated from expread.y (now c-exp.y) and contributed by the Department
of Computer Science at the State University of New York at Buffalo, 1991.
-This file is part of GDB.
+ This file is part of GDB.
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
/* Parse a Modula-2 expression from text in a string,
and return the result as a struct expression pointer.
@@ -36,12 +33,11 @@ Boston, MA 02110-1301, USA. */
generator. Doing this with #defines and trying to control the interaction
with include files ( and for example) just became
too messy, particularly when such includes can be inserted at random
- times by the parser generator. */
+ times by the parser generator. */
%{
#include "defs.h"
-#include "gdb_string.h"
#include "expression.h"
#include "language.h"
#include "value.h"
@@ -51,82 +47,33 @@ Boston, MA 02110-1301, USA. */
#include "symfile.h" /* Required by objfiles.h. */
#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
#include "block.h"
+#include "m2-exp.h"
-/* 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 m2_maxdepth
-#define yyparse m2_parse
-#define yylex m2_lex
-#define yyerror m2_error
-#define yylval m2_lval
-#define yychar m2_char
-#define yydebug m2_debug
-#define yypact m2_pact
-#define yyr1 m2_r1
-#define yyr2 m2_r2
-#define yydef m2_def
-#define yychk m2_chk
-#define yypgo m2_pgo
-#define yyact m2_act
-#define yyexca m2_exca
-#define yyerrflag m2_errflag
-#define yynerrs m2_nerrs
-#define yyps m2_ps
-#define yypv m2_pv
-#define yys m2_s
-#define yy_yys m2_yys
-#define yystate m2_state
-#define yytmp m2_tmp
-#define yyv m2_v
-#define yy_yyv m2_yyv
-#define yyval m2_val
-#define yylloc m2_lloc
-#define yyreds m2_reds /* With YYDEBUG defined */
-#define yytoks m2_toks /* With YYDEBUG defined */
-#define yyname m2_name /* With YYDEBUG defined */
-#define yyrule m2_rule /* With YYDEBUG defined */
-#define yylhs m2_yylhs
-#define yylen m2_yylen
-#define yydefred m2_yydefred
-#define yydgoto m2_yydgoto
-#define yysindex m2_yysindex
-#define yyrindex m2_yyrindex
-#define yygindex m2_yygindex
-#define yytable m2_yytable
-#define yycheck m2_yycheck
-
-#ifndef YYDEBUG
-#define YYDEBUG 1 /* Default to yydebug support */
-#endif
-
-#define YYFPRINTF parser_fprintf
+#define parse_type(ps) builtin_type (ps->gdbarch ())
+#define parse_m2_type(ps) builtin_m2_type (ps->gdbarch ())
+
+/* Remap normal yacc parser interface names (yyparse, yylex, yyerror,
+ etc). */
+#define GDB_YY_REMAP_PREFIX m2_
+#include "yy-remap.h"
+
+/* The state of the parser, used internally when we are parsing the
+ expression. */
+
+static struct parser_state *pstate = NULL;
int yyparse (void);
static int yylex (void);
-void yyerror (char *);
-
-#if 0
-static char *make_qualname (char *, char *);
-#endif
+static void yyerror (const char *);
static int parse_number (int);
-/* The sign of the number being parsed. */
+/* The sign of the number being parsed. */
static int number_sign = 1;
-/* The block that the module specified by the qualifer on an identifer is
- contained in, */
-#if 0
-static struct block *modblock=0;
-#endif
-
+using namespace expr;
%}
/* Although the yacc "value" of an expression is not used,
@@ -137,12 +84,12 @@ static struct block *modblock=0;
{
LONGEST lval;
ULONGEST ulval;
- DOUBLEST dval;
+ gdb_byte val[16];
struct symbol *sym;
struct type *tval;
struct stoken sval;
int voidval;
- struct block *bval;
+ const struct block *bval;
enum exp_opcode opcode;
struct internalvar *ivar;
@@ -158,7 +105,7 @@ static struct block *modblock=0;
%token INT HEX ERROR
%token UINT M2_TRUE M2_FALSE CHAR
-%token FLOAT
+%token FLOAT
/* Both NAME and TYPENAME tokens represent symbols in the input,
and both convey their data as strings.
@@ -180,7 +127,7 @@ static struct block *modblock=0;
/* The GDB scope operator */
%token COLONCOLON
-%token INTERNAL_VAR
+%token DOLLAR_VARIABLE
/* M2 tokens */
%left ','
@@ -208,31 +155,28 @@ start : exp
;
type_exp: type
- { write_exp_elt_opcode(OP_TYPE);
- write_exp_elt_type($1);
- write_exp_elt_opcode(OP_TYPE);
- }
+ { pstate->push_new ($1); }
;
/* Expressions */
exp : exp '^' %prec UNARY
- { write_exp_elt_opcode (UNOP_IND); }
+ { pstate->wrap (); }
;
exp : '-'
{ number_sign = -1; }
exp %prec UNARY
{ number_sign = 1;
- write_exp_elt_opcode (UNOP_NEG); }
+ pstate->wrap (); }
;
exp : '+' exp %prec UNARY
- { write_exp_elt_opcode(UNOP_PLUS); }
+ { pstate->wrap (); }
;
exp : not_exp exp %prec UNARY
- { write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
+ { pstate->wrap (); }
;
not_exp : NOT
@@ -240,170 +184,176 @@ not_exp : NOT
;
exp : CAP '(' exp ')'
- { write_exp_elt_opcode (UNOP_CAP); }
+ { error (_("CAP function is not implemented")); }
;
exp : ORD '(' exp ')'
- { write_exp_elt_opcode (UNOP_ORD); }
+ { error (_("ORD function is not implemented")); }
;
exp : ABS '(' exp ')'
- { write_exp_elt_opcode (UNOP_ABS); }
+ { error (_("ABS function is not implemented")); }
;
exp : HIGH '(' exp ')'
- { write_exp_elt_opcode (UNOP_HIGH); }
+ { pstate->wrap (); }
;
exp : MIN_FUNC '(' type ')'
- { write_exp_elt_opcode (UNOP_MIN);
- write_exp_elt_type ($3);
- write_exp_elt_opcode (UNOP_MIN); }
+ { error (_("MIN function is not implemented")); }
;
exp : MAX_FUNC '(' type ')'
- { write_exp_elt_opcode (UNOP_MAX);
- write_exp_elt_type ($3);
- write_exp_elt_opcode (UNOP_MIN); }
+ { error (_("MAX function is not implemented")); }
;
exp : FLOAT_FUNC '(' exp ')'
- { write_exp_elt_opcode (UNOP_FLOAT); }
+ { error (_("FLOAT function is not implemented")); }
;
exp : VAL '(' type ',' exp ')'
- { write_exp_elt_opcode (BINOP_VAL);
- write_exp_elt_type ($3);
- write_exp_elt_opcode (BINOP_VAL); }
+ { error (_("VAL function is not implemented")); }
;
exp : CHR '(' exp ')'
- { write_exp_elt_opcode (UNOP_CHR); }
+ { error (_("CHR function is not implemented")); }
;
exp : ODD '(' exp ')'
- { write_exp_elt_opcode (UNOP_ODD); }
+ { error (_("ODD function is not implemented")); }
;
exp : TRUNC '(' exp ')'
- { write_exp_elt_opcode (UNOP_TRUNC); }
+ { error (_("TRUNC function is not implemented")); }
;
exp : TSIZE '(' exp ')'
- { write_exp_elt_opcode (UNOP_SIZEOF); }
+ { pstate->wrap (); }
;
exp : SIZE exp %prec UNARY
- { write_exp_elt_opcode (UNOP_SIZEOF); }
+ { pstate->wrap (); }
;
exp : INC '(' exp ')'
- { write_exp_elt_opcode(UNOP_PREINCREMENT); }
+ { pstate->wrap (); }
;
exp : INC '(' exp ',' exp ')'
- { write_exp_elt_opcode(BINOP_ASSIGN_MODIFY);
- write_exp_elt_opcode(BINOP_ADD);
- write_exp_elt_opcode(BINOP_ASSIGN_MODIFY); }
+ {
+ operation_up rhs = pstate->pop ();
+ operation_up lhs = pstate->pop ();
+ pstate->push_new
+ (BINOP_ADD, std::move (lhs), std::move (rhs));
+ }
;
exp : DEC '(' exp ')'
- { write_exp_elt_opcode(UNOP_PREDECREMENT);}
+ { pstate->wrap (); }
;
exp : DEC '(' exp ',' exp ')'
- { write_exp_elt_opcode(BINOP_ASSIGN_MODIFY);
- write_exp_elt_opcode(BINOP_SUB);
- write_exp_elt_opcode(BINOP_ASSIGN_MODIFY); }
+ {
+ operation_up rhs = pstate->pop ();
+ operation_up lhs = pstate->pop ();
+ pstate->push_new
+ (BINOP_SUB, std::move (lhs), std::move (rhs));
+ }
;
exp : exp DOT NAME
- { write_exp_elt_opcode (STRUCTOP_STRUCT);
- write_exp_string ($3);
- write_exp_elt_opcode (STRUCTOP_STRUCT); }
- ;
+ {
+ pstate->push_new
+ (pstate->pop (), copy_name ($3));
+ }
+;
exp : set
;
exp : exp IN set
- { error("Sets are not implemented.");}
+ { error (_("Sets are not implemented."));}
;
exp : INCL '(' exp ',' exp ')'
- { error("Sets are not implemented.");}
+ { error (_("Sets are not implemented."));}
;
exp : EXCL '(' exp ',' exp ')'
- { error("Sets are not implemented.");}
+ { error (_("Sets are not implemented."));}
;
set : '{' arglist '}'
- { error("Sets are not implemented.");}
+ { error (_("Sets are not implemented."));}
| type '{' arglist '}'
- { error("Sets are not implemented.");}
+ { error (_("Sets are not implemented."));}
;
-/* Modula-2 array subscript notation [a,b,c...] */
+/* Modula-2 array subscript notation [a,b,c...]. */
exp : exp '['
- /* This function just saves the number of arguments
+ /* This function just saves the number of arguments
that follow in the list. It is *not* specific to
function types */
- { start_arglist(); }
- non_empty_arglist ']' %prec DOT
- { write_exp_elt_opcode (MULTI_SUBSCRIPT);
- write_exp_elt_longcst ((LONGEST) end_arglist());
- write_exp_elt_opcode (MULTI_SUBSCRIPT); }
- ;
-
-exp : exp '[' exp ']'
- { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
+ { pstate->start_arglist(); }
+ non_empty_arglist ']' %prec DOT
+ {
+ gdb_assert (pstate->arglist_len > 0);
+ std::vector args
+ = pstate->pop_vector (pstate->end_arglist ());
+ pstate->push_new
+ (pstate->pop (), std::move (args));
+ }
;
exp : exp '('
/* This is to save the value of arglist_len
being accumulated by an outer function call. */
- { start_arglist (); }
+ { pstate->start_arglist (); }
arglist ')' %prec DOT
- { write_exp_elt_opcode (OP_FUNCALL);
- write_exp_elt_longcst ((LONGEST) end_arglist ());
- write_exp_elt_opcode (OP_FUNCALL); }
+ {
+ std::vector args
+ = pstate->pop_vector (pstate->end_arglist ());
+ pstate->push_new
+ (pstate->pop (), std::move (args));
+ }
;
arglist :
;
arglist : exp
- { arglist_len = 1; }
+ { pstate->arglist_len = 1; }
;
arglist : arglist ',' exp %prec ABOVE_COMMA
- { arglist_len++; }
+ { pstate->arglist_len++; }
;
non_empty_arglist
- : exp
- { arglist_len = 1; }
+ : exp
+ { pstate->arglist_len = 1; }
;
non_empty_arglist
- : non_empty_arglist ',' exp %prec ABOVE_COMMA
- { arglist_len++; }
+ : non_empty_arglist ',' exp %prec ABOVE_COMMA
+ { pstate->arglist_len++; }
;
/* GDB construct */
exp : '{' type '}' exp %prec UNARY
- { write_exp_elt_opcode (UNOP_MEMVAL);
- write_exp_elt_type ($2);
- write_exp_elt_opcode (UNOP_MEMVAL); }
+ {
+ pstate->push_new
+ (pstate->pop (), $2);
+ }
;
exp : type '(' exp ')' %prec UNARY
- { write_exp_elt_opcode (UNOP_CAST);
- write_exp_elt_type ($1);
- write_exp_elt_opcode (UNOP_CAST); }
+ {
+ pstate->push_new
+ (pstate->pop (), $1);
+ }
;
exp : '(' exp ')'
@@ -415,142 +365,139 @@ exp : '(' exp ')'
/* GDB construct */
exp : exp '@' exp
- { write_exp_elt_opcode (BINOP_REPEAT); }
+ { pstate->wrap2 (); }
;
exp : exp '*' exp
- { write_exp_elt_opcode (BINOP_MUL); }
+ { pstate->wrap2 (); }
;
exp : exp '/' exp
- { write_exp_elt_opcode (BINOP_DIV); }
+ { pstate->wrap2 (); }
;
exp : exp DIV exp
- { write_exp_elt_opcode (BINOP_INTDIV); }
- ;
+ { pstate->wrap2 (); }
+ ;
exp : exp MOD exp
- { write_exp_elt_opcode (BINOP_REM); }
+ { pstate->wrap2 (); }
;
exp : exp '+' exp
- { write_exp_elt_opcode (BINOP_ADD); }
+ { pstate->wrap2 (); }
;
exp : exp '-' exp
- { write_exp_elt_opcode (BINOP_SUB); }
+ { pstate->wrap2 (); }
;
exp : exp '=' exp
- { write_exp_elt_opcode (BINOP_EQUAL); }
+ { pstate->wrap2 (); }
;
exp : exp NOTEQUAL exp
- { write_exp_elt_opcode (BINOP_NOTEQUAL); }
- | exp '#' exp
- { write_exp_elt_opcode (BINOP_NOTEQUAL); }
+ { pstate->wrap2 (); }
+ | exp '#' exp
+ { pstate->wrap2 (); }
;
exp : exp LEQ exp
- { write_exp_elt_opcode (BINOP_LEQ); }
+ { pstate->wrap2 (); }
;
exp : exp GEQ exp
- { write_exp_elt_opcode (BINOP_GEQ); }
+ { pstate->wrap2 (); }
;
exp : exp '<' exp
- { write_exp_elt_opcode (BINOP_LESS); }
+ { pstate->wrap2 (); }
;
exp : exp '>' exp
- { write_exp_elt_opcode (BINOP_GTR); }
+ { pstate->wrap2 (); }
;
exp : exp LOGICAL_AND exp
- { write_exp_elt_opcode (BINOP_LOGICAL_AND); }
+ { pstate->wrap2 (); }
;
exp : exp OROR exp
- { write_exp_elt_opcode (BINOP_LOGICAL_OR); }
+ { pstate->wrap2 (); }
;
exp : exp ASSIGN exp
- { write_exp_elt_opcode (BINOP_ASSIGN); }
+ { pstate->wrap2 (); }
;
/* Constants */
exp : M2_TRUE
- { write_exp_elt_opcode (OP_BOOL);
- write_exp_elt_longcst ((LONGEST) $1);
- write_exp_elt_opcode (OP_BOOL); }
+ { pstate->push_new ($1); }
;
exp : M2_FALSE
- { write_exp_elt_opcode (OP_BOOL);
- write_exp_elt_longcst ((LONGEST) $1);
- write_exp_elt_opcode (OP_BOOL); }
+ { pstate->push_new ($1); }
;
exp : INT
- { write_exp_elt_opcode (OP_LONG);
- write_exp_elt_type (builtin_type_m2_int);
- write_exp_elt_longcst ((LONGEST) $1);
- write_exp_elt_opcode (OP_LONG); }
+ {
+ pstate->push_new
+ (parse_m2_type (pstate)->builtin_int, $1);
+ }
;
exp : UINT
{
- write_exp_elt_opcode (OP_LONG);
- write_exp_elt_type (builtin_type_m2_card);
- write_exp_elt_longcst ((LONGEST) $1);
- write_exp_elt_opcode (OP_LONG);
+ pstate->push_new
+ (parse_m2_type (pstate)->builtin_card, $1);
}
;
exp : CHAR
- { write_exp_elt_opcode (OP_LONG);
- write_exp_elt_type (builtin_type_m2_char);
- write_exp_elt_longcst ((LONGEST) $1);
- write_exp_elt_opcode (OP_LONG); }
+ {
+ pstate->push_new
+ (parse_m2_type (pstate)->builtin_char, $1);
+ }
;
exp : FLOAT
- { write_exp_elt_opcode (OP_DOUBLE);
- write_exp_elt_type (builtin_type_m2_real);
- write_exp_elt_dblcst ($1);
- write_exp_elt_opcode (OP_DOUBLE); }
+ {
+ float_data data;
+ std::copy (std::begin ($1), std::end ($1),
+ std::begin (data));
+ pstate->push_new
+ (parse_m2_type (pstate)->builtin_real, data);
+ }
;
exp : variable
;
exp : SIZE '(' type ')' %prec UNARY
- { write_exp_elt_opcode (OP_LONG);
- write_exp_elt_type (builtin_type_int);
- write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3));
- write_exp_elt_opcode (OP_LONG); }
+ {
+ pstate->push_new
+ (parse_m2_type (pstate)->builtin_int,
+ TYPE_LENGTH ($3));
+ }
;
exp : STRING
- { write_exp_elt_opcode (OP_M2_STRING);
- write_exp_string ($1);
- write_exp_elt_opcode (OP_M2_STRING); }
+ { error (_("strings are not implemented")); }
;
-/* This will be used for extensions later. Like adding modules. */
+/* This will be used for extensions later. Like adding modules. */
block : fblock
{ $$ = SYMBOL_BLOCK_VALUE($1); }
;
fblock : BLOCKNAME
{ struct symbol *sym
- = lookup_symbol (copy_name ($1), expression_context_block,
- VAR_DOMAIN, 0);
+ = lookup_symbol (copy_name ($1).c_str (),
+ pstate->expression_context_block,
+ VAR_DOMAIN, 0).symbol;
$$ = sym;}
;
@@ -558,118 +505,73 @@ fblock : BLOCKNAME
/* GDB scope operator */
fblock : block COLONCOLON BLOCKNAME
{ struct symbol *tem
- = lookup_symbol (copy_name ($3), $1,
- VAR_DOMAIN, 0);
- if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK)
- error ("No function \"%s\" in specified context.",
- copy_name ($3));
+ = lookup_symbol (copy_name ($3).c_str (), $1,
+ VAR_DOMAIN, 0).symbol;
+ if (!tem || tem->aclass () != LOC_BLOCK)
+ error (_("No function \"%s\" in specified context."),
+ copy_name ($3).c_str ());
$$ = tem;
}
;
/* Useful for assigning to PROCEDURE variables */
variable: fblock
- { write_exp_elt_opcode(OP_VAR_VALUE);
- write_exp_elt_block (NULL);
- write_exp_elt_sym ($1);
- write_exp_elt_opcode (OP_VAR_VALUE); }
+ {
+ block_symbol sym { $1, nullptr };
+ pstate->push_new (sym);
+ }
;
/* GDB internal ($foo) variable */
-variable: INTERNAL_VAR
+variable: DOLLAR_VARIABLE
+ { pstate->push_dollar ($1); }
;
/* GDB scope operator */
variable: block COLONCOLON NAME
- { struct symbol *sym;
- sym = lookup_symbol (copy_name ($3), $1,
- VAR_DOMAIN, 0);
- if (sym == 0)
- error ("No symbol \"%s\" in specified context.",
- copy_name ($3));
+ { struct block_symbol sym
+ = lookup_symbol (copy_name ($3).c_str (), $1,
+ VAR_DOMAIN, 0);
- write_exp_elt_opcode (OP_VAR_VALUE);
- /* block_found is set by lookup_symbol. */
- write_exp_elt_block (block_found);
- write_exp_elt_sym (sym);
- write_exp_elt_opcode (OP_VAR_VALUE); }
+ if (sym.symbol == 0)
+ error (_("No symbol \"%s\" in specified context."),
+ copy_name ($3).c_str ());
+ if (symbol_read_needs_frame (sym.symbol))
+ pstate->block_tracker->update (sym);
+
+ pstate->push_new (sym);
+ }
;
-/* Base case for variables. */
+/* Base case for variables. */
variable: NAME
- { struct symbol *sym;
- int is_a_field_of_this;
-
- sym = lookup_symbol (copy_name ($1),
- expression_context_block,
- VAR_DOMAIN,
- &is_a_field_of_this);
- if (sym)
- {
- if (symbol_read_needs_frame (sym))
- {
- if (innermost_block == 0 ||
- contained_in (block_found,
- innermost_block))
- innermost_block = block_found;
- }
-
- write_exp_elt_opcode (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 (NULL);
- write_exp_elt_sym (sym);
- write_exp_elt_opcode (OP_VAR_VALUE);
- }
- else
- {
- struct minimal_symbol *msymbol;
- char *arg = copy_name ($1);
-
- msymbol =
- lookup_minimal_symbol (arg, NULL, NULL);
- if (msymbol != NULL)
- {
- write_exp_msymbol
- (msymbol,
- lookup_function_type (builtin_type_int),
- builtin_type_int);
- }
- else if (!have_full_symbols () && !have_partial_symbols ())
- error ("No symbol table is loaded. Use the \"symbol-file\" command.");
- else
- error ("No symbol \"%s\" in current context.",
- copy_name ($1));
- }
+ { struct block_symbol sym;
+ struct field_of_this_result is_a_field_of_this;
+
+ std::string name = copy_name ($1);
+ sym
+ = lookup_symbol (name.c_str (),
+ pstate->expression_context_block,
+ VAR_DOMAIN,
+ &is_a_field_of_this);
+
+ pstate->push_symbol (name.c_str (), sym);
}
;
type
: TYPENAME
- { $$ = lookup_typename (copy_name ($1),
- expression_context_block, 0); }
+ { $$
+ = lookup_typename (pstate->language (),
+ copy_name ($1).c_str (),
+ pstate->expression_context_block,
+ 0);
+ }
;
%%
-#if 0 /* FIXME! */
-int
-overflow(a,b)
- long a,b;
-{
- return (MAX_OF_TYPE(builtin_type_m2_int) - b) < a;
-}
-
-int
-uoverflow(a,b)
- unsigned long a,b;
-{
- return (MAX_OF_TYPE(builtin_type_m2_card) - b) < a;
-}
-#endif /* FIXME */
-
/* Take care of parsing a number (anything that starts with a digit).
Set yylval and return the token type; update lexptr.
LEN is the number of characters in it. */
@@ -677,10 +579,9 @@ uoverflow(a,b)
/*** Needs some error checking for the float case ***/
static int
-parse_number (olen)
- int olen;
+parse_number (int olen)
{
- char *p = lexptr;
+ const char *p = pstate->lexptr;
LONGEST n = 0;
LONGEST prevn = 0;
int c,i,ischar=0;
@@ -706,14 +607,18 @@ parse_number (olen)
if (p[c] == '.' && base == 10)
{
/* It's a float since it contains a point. */
- yylval.dval = atof (p);
- lexptr += len;
+ if (!parse_float (p, len,
+ parse_m2_type (pstate)->builtin_real,
+ yylval.val))
+ return ERROR;
+
+ pstate->lexptr += len;
return FLOAT;
}
if (p[c] == '.' && base != 10)
- error("Floating point numbers must be base 10.");
+ error (_("Floating point numbers must be base 10."));
if (base == 10 && (p[c] < '0' || p[c] > '9'))
- error("Invalid digit \'%c\' in number.",p[c]);
+ error (_("Invalid digit \'%c\' in number."),p[c]);
}
while (len-- > 0)
@@ -721,7 +626,7 @@ parse_number (olen)
c = *p++;
n *= base;
if( base == 8 && (c == '8' || c == '9'))
- error("Invalid digit \'%c\' in octal number.",c);
+ error (_("Invalid digit \'%c\' in octal number."),c);
if (c >= '0' && c <= '9')
i = c - '0';
else
@@ -737,19 +642,19 @@ parse_number (olen)
if(!unsigned_p && number_sign == 1 && (prevn >= n))
unsigned_p=1; /* Try something unsigned */
/* Don't do the range check if n==i and i==0, since that special
- case will give an overflow error. */
+ case will give an overflow error. */
if(RANGE_CHECK && n!=i && i)
{
if((unsigned_p && (unsigned)prevn >= (unsigned)n) ||
((!unsigned_p && number_sign==-1) && -prevn <= -n))
- range_error("Overflow on numeric constant.");
+ range_error (_("Overflow on numeric constant."));
}
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)
{
@@ -762,7 +667,7 @@ parse_number (olen)
return UINT;
}
else if((unsigned_p && (n<0))) {
- range_error("Overflow on numeric constant -- number too large.");
+ range_error (_("Overflow on numeric constant -- number too large."));
/* But, this can return if range_check == range_warn. */
}
yylval.lval = n;
@@ -821,32 +726,35 @@ static struct keyword keytab[] =
};
+/* Depth of parentheses. */
+static int paren_depth;
+
/* Read one token, getting characters through lexptr. */
-/* This is where we will check to make sure that the language and the operators used are
- compatible */
+/* This is where we will check to make sure that the language and the
+ operators used are compatible */
static int
-yylex ()
+yylex (void)
{
int c;
int namelen;
int i;
- char *tokstart;
+ const char *tokstart;
char quote;
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;
}
@@ -858,34 +766,34 @@ yylex ()
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 (comma_terminates && paren_depth == 0)
+ 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;
}
@@ -906,7 +814,7 @@ yylex ()
case '@':
case '~':
case '&':
- lexptr++;
+ pstate->lexptr++;
return c;
case '\'' :
@@ -924,10 +832,10 @@ yylex ()
}
}
if(c != quote)
- error("Unterminated string or character constant.");
+ 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 */
{
@@ -945,7 +853,7 @@ yylex ()
{
/* It's a number. */
int got_dot = 0, got_e = 0;
- char *p = tokstart;
+ const char *p = tokstart;
int toktype;
for (++p ;; ++p)
@@ -965,22 +873,22 @@ yylex ()
break;
}
toktype = parse_number (p - tokstart);
- if (toktype == ERROR)
+ if (toktype == ERROR)
{
char *err_copy = (char *) alloca (p - tokstart + 1);
memcpy (err_copy, tokstart, p - tokstart);
err_copy[p - tokstart] = 0;
- error ("Invalid number \"%s\".", err_copy);
+ error (_("Invalid number \"%s\"."), err_copy);
}
- lexptr = p;
+ pstate->lexptr = p;
return toktype;
}
if (!(c == '_' || c == '$'
|| (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
/* We must have come across a bad character (e.g. ';'). */
- error ("Invalid character '%c' in expression.", c);
+ error (_("Invalid character '%c' in expression."), c);
/* It's a name. See how long it is. */
namelen = 0;
@@ -997,7 +905,7 @@ yylex ()
return 0;
}
- lexptr += namelen;
+ pstate->lexptr += namelen;
/* Lookup special keywords */
for(i = 0 ; i < (int) (sizeof(keytab) / sizeof(keytab[0])) ; i++)
@@ -1009,10 +917,7 @@ yylex ()
yylval.sval.length = namelen;
if (*tokstart == '$')
- {
- write_dollar_variable (yylval.sval);
- return INTERNAL_VAR;
- }
+ return DOLLAR_VARIABLE;
/* Use token-type BLOCKNAME for symbols that happen to be defined as
functions. If this is not so, then ...
@@ -1020,37 +925,33 @@ yylex ()
currently as names of types; NAME for other symbols.
The caller is not constrained to care about the distinction. */
{
-
-
- char *tmp = copy_name (yylval.sval);
+ std::string tmp = copy_name (yylval.sval);
struct symbol *sym;
- if (lookup_partial_symtab (tmp))
+ if (lookup_symtab (tmp.c_str ()))
return BLOCKNAME;
- sym = lookup_symbol (tmp, expression_context_block, VAR_DOMAIN, 0);
- if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
+ sym = lookup_symbol (tmp.c_str (), pstate->expression_context_block,
+ VAR_DOMAIN, 0).symbol;
+ if (sym && sym->aclass () == LOC_BLOCK)
return BLOCKNAME;
- if (lookup_typename (copy_name (yylval.sval), expression_context_block, 1))
+ if (lookup_typename (pstate->language (),
+ tmp.c_str (), pstate->expression_context_block, 1))
return TYPENAME;
if(sym)
{
- switch(sym->aclass)
+ switch(sym->aclass ())
{
case LOC_STATIC:
case LOC_REGISTER:
case LOC_ARG:
case LOC_REF_ARG:
- case LOC_REGPARM:
case LOC_REGPARM_ADDR:
case LOC_LOCAL:
- case LOC_BASEREG:
- case LOC_BASEREG_ARG:
case LOC_CONST:
case LOC_CONST_BYTES:
case LOC_OPTIMIZED_OUT:
case LOC_COMPUTED:
- case LOC_COMPUTED_ARG:
return NAME;
case LOC_TYPEDEF:
@@ -1060,57 +961,57 @@ yylex ()
return BLOCKNAME;
case LOC_UNDEF:
- error("internal: Undefined class in m2lex()");
+ error (_("internal: Undefined class in m2lex()"));
case LOC_LABEL:
case LOC_UNRESOLVED:
- error("internal: Unforseen case in m2lex()");
+ error (_("internal: Unforseen case in m2lex()"));
default:
- error ("unhandled token in m2lex()");
+ error (_("unhandled token in m2lex()"));
break;
}
}
else
{
- /* Built-in BOOLEAN type. This is sort of a hack. */
- if (strncmp (tokstart, "TRUE", 4) == 0)
+ /* Built-in BOOLEAN type. This is sort of a hack. */
+ if (startswith (tokstart, "TRUE"))
{
yylval.ulval = 1;
return M2_TRUE;
}
- else if (strncmp (tokstart, "FALSE", 5) == 0)
+ else if (startswith (tokstart, "FALSE"))
{
yylval.ulval = 0;
return M2_FALSE;
}
}
- /* Must be another type of name... */
+ /* Must be another type of name... */
return NAME;
}
}
-#if 0 /* Unused */
-static char *
-make_qualname(mod,ident)
- char *mod, *ident;
+int
+m2_language::parser (struct parser_state *par_state) const
{
- char *new = malloc(strlen(mod)+strlen(ident)+2);
-
- strcpy(new,mod);
- strcat(new,".");
- strcat(new,ident);
- return new;
+ /* Setting up the parser state. */
+ scoped_restore pstate_restore = make_scoped_restore (&pstate);
+ gdb_assert (par_state != NULL);
+ pstate = par_state;
+ paren_depth = 0;
+
+ int result = yyparse ();
+ if (!result)
+ pstate->set_operation (pstate->pop ());
+ return result;
}
-#endif /* 0 */
-void
-yyerror (msg)
- char *msg;
+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 ? msg : "error"), lexptr);
+ error (_("A %s in expression, near `%s'."), msg, pstate->lexptr);
}