X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fm2-exp.y;h=02e3cf1b4e7bd3486a5565dec5321d5b83cdccb5;hb=9cca177baec32a1ed1422a87a1f57cda2d2eb21a;hp=6230c206af9d8fe4c008a6c830de5475ca1049d6;hpb=712f90be028d481f1d2151824f2b4e3f75263c00;p=binutils-gdb.git diff --git a/gdb/m2-exp.y b/gdb/m2-exp.y index 6230c206af9..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,85 +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" -#define parse_type builtin_type (parse_gdbarch) -#define parse_m2_type builtin_m2_type (parse_gdbarch) - -/* 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, @@ -140,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; @@ -161,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. @@ -183,7 +127,7 @@ static struct block *modblock=0; /* The GDB scope operator */ %token COLONCOLON -%token INTERNAL_VAR +%token DOLLAR_VARIABLE /* M2 tokens */ %left ',' @@ -211,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 @@ -243,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 ')' @@ -418,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 (parse_m2_type->builtin_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 (parse_m2_type->builtin_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 (parse_m2_type->builtin_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 (parse_m2_type->builtin_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 (parse_type->builtin_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;} ; @@ -561,113 +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); - 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(parse_m2_type->builtin_int) - b) < a; -} - -int -uoverflow(a,b) - unsigned long a,b; -{ - return (MAX_OF_TYPE(parse_m2_type->builtin_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. */ @@ -675,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; @@ -704,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) @@ -719,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 @@ -735,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) { @@ -760,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; @@ -819,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; } @@ -856,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; } @@ -904,7 +814,7 @@ yylex () case '@': case '~': case '&': - lexptr++; + pstate->lexptr++; return c; case '\'' : @@ -922,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 */ { @@ -943,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) @@ -963,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; @@ -995,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++) @@ -1007,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 ... @@ -1018,22 +925,22 @@ 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(SYMBOL_CLASS (sym)) + switch(sym->aclass ()) { case LOC_STATIC: case LOC_REGISTER: @@ -1054,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); }