/* YACC grammar for Modula-2 expressions, for GDB.
- Copyright (C) 1986, 1989, 1990, 1991 Free Software Foundation, Inc.
+ Copyright (C) 1986, 1989, 1990, 1991, 1993, 1994, 1995
+ 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.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Parse a Modula-2 expression from text in a string,
and return the result as a struct expression pointer.
%{
-#include <stdio.h>
-#include <string.h>
#include "defs.h"
-#include "symtab.h"
-#include "gdbtypes.h"
-#include "frame.h"
+#include "gdb_string.h"
#include "expression.h"
#include "language.h"
#include "value.h"
#include "parser-defs.h"
-#include "bfd.h"
-#include "symfile.h"
-#include "objfiles.h"
+#include "m2-lang.h"
+#include "bfd.h" /* Required by objfiles.h. */
+#include "symfile.h" /* Required by objfiles.h. */
+#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
+
+/* 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. */
-/* These MUST be included in any grammar file!!!! Please choose unique names!
- Note that this are a combined list of variables that can be produced
- by any one of bison, byacc, or yacc. */
#define yymaxdepth m2_maxdepth
#define yyparse m2_parse
#define yylex m2_lex
#define yypgo m2_pgo
#define yyact m2_act
#define yyexca m2_exca
-#define yyerrflag m2_errflag
-#define yynerrs m2_nerrs
+#define yyerrflag m2_errflag
+#define yynerrs m2_nerrs
#define yyps m2_ps
#define yypv m2_pv
#define yys m2_s
#define yy_yyv m2_yyv
#define yyval m2_val
#define yylloc m2_lloc
-#define yyss m2_yyss /* byacc */
-#define yyssp m2_yysp /* byacc */
-#define yyvs m2_yyvs /* byacc */
-#define yyvsp m2_yyvsp /* byacc */
-
-#if 0
-static char *
-make_qualname PARAMS ((char *, char *));
+#define yyreds m2_reds /* With YYDEBUG defined */
+#define yytoks m2_toks /* 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 0 /* Default to no yydebug support */
#endif
-static int
-parse_number PARAMS ((int));
+int
+yyparse PARAMS ((void));
static int
yylex PARAMS ((void));
-static void
+void
yyerror PARAMS ((char *));
-int
-yyparse PARAMS ((void));
+#if 0
+static char *
+make_qualname PARAMS ((char *, char *));
+#endif
+
+static int
+parse_number PARAMS ((int));
/* The sign of the number being parsed. */
static int number_sign = 1;
static struct block *modblock=0;
#endif
-/* #define YYDEBUG 1 */
%}
/* Although the yacc "value" of an expression is not used,
{
LONGEST lval;
unsigned LONGEST ulval;
- double dval;
+ DOUBLEST dval;
struct symbol *sym;
struct type *tval;
struct stoken sval;
/* The GDB scope operator */
%token COLONCOLON
-%token <lval> LAST REGNAME
-
-%token <ivar> INTERNAL_VAR
+%token <voidval> INTERNAL_VAR
/* M2 tokens */
%left ','
function types */
{ start_arglist(); }
non_empty_arglist ']' %prec DOT
- { write_exp_elt_opcode (BINOP_MULTI_SUBSCRIPT);
+ { write_exp_elt_opcode (MULTI_SUBSCRIPT);
write_exp_elt_longcst ((LONGEST) end_arglist());
- write_exp_elt_opcode (BINOP_MULTI_SUBSCRIPT); }
+ write_exp_elt_opcode (MULTI_SUBSCRIPT); }
;
exp : exp '('
exp : variable
;
-/* The GDB internal variable $$, et al. */
-exp : LAST
- { write_exp_elt_opcode (OP_LAST);
- write_exp_elt_longcst ((LONGEST) $1);
- write_exp_elt_opcode (OP_LAST); }
- ;
-
-exp : REGNAME
- { write_exp_elt_opcode (OP_REGISTER);
- write_exp_elt_longcst ((LONGEST) $1);
- write_exp_elt_opcode (OP_REGISTER); }
- ;
-
exp : SIZE '(' type ')' %prec UNARY
{ write_exp_elt_opcode (OP_LONG);
write_exp_elt_type (builtin_type_int);
/* 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); }
;
/* GDB internal ($foo) variable */
variable: INTERNAL_VAR
- { write_exp_elt_opcode (OP_INTERNALVAR);
- write_exp_elt_intern ($1);
- write_exp_elt_opcode (OP_INTERNALVAR); }
;
/* GDB scope operator */
copy_name ($3));
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); }
;
NULL);
if (sym)
{
- switch (sym->class)
+ if (symbol_read_needs_frame (sym))
{
- case LOC_REGISTER:
- case LOC_ARG:
- case LOC_LOCAL:
- case LOC_REF_ARG:
- case LOC_REGPARM:
- case LOC_LOCAL_ARG:
if (innermost_block == 0 ||
- contained_in (block_found,
+ contained_in (block_found,
innermost_block))
innermost_block = block_found;
- break;
-
- case LOC_UNDEF:
- case LOC_CONST:
- case LOC_STATIC:
- case LOC_TYPEDEF:
- case LOC_LABEL: /* maybe should go above? */
- case LOC_BLOCK:
- case LOC_CONST_BYTES:
- /* These are listed so gcc -Wall will reveal
- un-handled cases. */
- break;
}
+
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);
}
struct minimal_symbol *msymbol;
register char *arg = copy_name ($1);
- msymbol = lookup_minimal_symbol (arg,
- (struct objfile *) NULL);
+ msymbol =
+ lookup_minimal_symbol (arg, NULL, NULL);
if (msymbol != NULL)
{
- write_exp_elt_opcode (OP_LONG);
- write_exp_elt_type (builtin_type_int);
- write_exp_elt_longcst ((LONGEST) msymbol -> address);
- write_exp_elt_opcode (OP_LONG);
- write_exp_elt_opcode (UNOP_MEMVAL);
- if (msymbol -> type == mst_data ||
- msymbol -> type == mst_bss)
- write_exp_elt_type (builtin_type_int);
- else if (msymbol -> type == mst_text)
- write_exp_elt_type (lookup_function_type (builtin_type_int));
- else
- write_exp_elt_type (builtin_type_char);
- write_exp_elt_opcode (UNOP_MEMVAL);
+ 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.");
/* See if it is a special token of length 2 */
- for( i = 0 ; i < sizeof tokentab2 / sizeof tokentab2[0] ; i++)
- if(!strncmp(tokentab2[i].name, tokstart, 2))
+ for( i = 0 ; i < (int) (sizeof tokentab2 / sizeof tokentab2[0]) ; i++)
+ if(STREQN(tokentab2[i].name, tokstart, 2))
{
lexptr += 2;
return tokentab2[i].token;
lexptr += namelen;
- /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1)
- and $$digits (equivalent to $<-digits> if you could type that).
- Make token type LAST, and put the number (the digits) in yylval. */
-
- if (*tokstart == '$')
- {
- register int negate = 0;
- c = 1;
- /* Double dollar means negate the number and add -1 as well.
- Thus $$ alone means -1. */
- if (namelen >= 2 && tokstart[1] == '$')
- {
- negate = 1;
- c = 2;
- }
- if (c == namelen)
- {
- /* Just dollars (one or two) */
- yylval.lval = - negate;
- return LAST;
- }
- /* Is the rest of the token digits? */
- for (; c < namelen; c++)
- if (!(tokstart[c] >= '0' && tokstart[c] <= '9'))
- break;
- if (c == namelen)
- {
- yylval.lval = atoi (tokstart + 1 + negate);
- if (negate)
- yylval.lval = - yylval.lval;
- return LAST;
- }
- }
-
- /* Handle tokens that refer to machine registers:
- $ followed by a register name. */
-
- if (*tokstart == '$') {
- for (c = 0; c < NUM_REGS; c++)
- if (namelen - 1 == strlen (reg_names[c])
- && !strncmp (tokstart + 1, reg_names[c], namelen - 1))
- {
- yylval.lval = c;
- return REGNAME;
- }
- for (c = 0; c < num_std_regs; c++)
- if (namelen - 1 == strlen (std_regs[c].name)
- && !strncmp (tokstart + 1, std_regs[c].name, namelen - 1))
- {
- yylval.lval = std_regs[c].regnum;
- return REGNAME;
- }
- }
-
-
/* Lookup special keywords */
- for(i = 0 ; i < sizeof(keytab) / sizeof(keytab[0]) ; i++)
- if(namelen == strlen(keytab[i].keyw) && !strncmp(tokstart,keytab[i].keyw,namelen))
+ for(i = 0 ; i < (int) (sizeof(keytab) / sizeof(keytab[0])) ; i++)
+ if(namelen == strlen(keytab[i].keyw) && STREQN(tokstart,keytab[i].keyw,namelen))
return keytab[i].token;
yylval.sval.ptr = tokstart;
yylval.sval.length = namelen;
- /* Any other names starting in $ are debugger internal variables. */
-
if (*tokstart == '$')
{
- yylval.ivar = (struct internalvar *) lookup_internalvar (copy_name (yylval.sval) + 1);
+ write_dollar_variable (yylval.sval);
return INTERNAL_VAR;
}
-
/* Use token-type BLOCKNAME for symbols that happen to be defined as
functions. If this is not so, then ...
Use token-type TYPENAME for symbols that happen to be defined
if(sym)
{
- switch(sym->class)
+ 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_LOCAL_ARG:
+ case LOC_BASEREG:
+ case LOC_BASEREG_ARG:
case LOC_CONST:
case LOC_CONST_BYTES:
+ case LOC_OPTIMIZED_OUT:
return NAME;
case LOC_TYPEDEF:
error("internal: Undefined class in m2lex()");
case LOC_LABEL:
+ case LOC_UNRESOLVED:
error("internal: Unforseen case in m2lex()");
}
}
else
{
/* Built-in BOOLEAN type. This is sort of a hack. */
- if(!strncmp(tokstart,"TRUE",4))
+ if(STREQN(tokstart,"TRUE",4))
{
yylval.ulval = 1;
return M2_TRUE;
}
- else if(!strncmp(tokstart,"FALSE",5))
+ else if(STREQN(tokstart,"FALSE",5))
{
yylval.ulval = 0;
return M2_FALSE;
}
#endif /* 0 */
-static void
-yyerror(msg)
- char *msg; /* unused */
-{
- printf("Parsing: %s\n",lexptr);
- if (yychar < 256)
- error("Invalid syntax in expression near character '%c'.",yychar);
- else
- error("Invalid syntax in expression");
-}
-
-\f
-/* Print the character C on STREAM as part of the contents of a literal
- string whose delimiter is QUOTER. Note that that format for printing
- characters and strings is language specific.
- FIXME: This is a copy of the same function from c-exp.y. It should
- be replaced with a true Modula version.
- */
-
-static void
-emit_char (c, stream, quoter)
- register int c;
- FILE *stream;
- int quoter;
-{
-
- c &= 0xFF; /* Avoid sign bit follies */
-
- if ( c < 0x20 || /* Low control chars */
- (c >= 0x7F && c < 0xA0) || /* DEL, High controls */
- (sevenbit_strings && c >= 0x80)) { /* high order bit set */
- switch (c)
- {
- case '\n':
- fputs_filtered ("\\n", stream);
- break;
- case '\b':
- fputs_filtered ("\\b", stream);
- break;
- case '\t':
- fputs_filtered ("\\t", stream);
- break;
- case '\f':
- fputs_filtered ("\\f", stream);
- break;
- case '\r':
- fputs_filtered ("\\r", stream);
- break;
- case '\033':
- fputs_filtered ("\\e", stream);
- break;
- case '\007':
- fputs_filtered ("\\a", stream);
- break;
- default:
- fprintf_filtered (stream, "\\%.3o", (unsigned int) c);
- break;
- }
- } else {
- if (c == '\\' || c == quoter)
- {
- fputs_filtered ("\\", stream);
- }
- fprintf_filtered (stream, "%c", c);
- }
-}
-
-/* FIXME: This is a copy of the same function from c-exp.y. It should
- be replaced with a true Modula version. */
-
-static void
-m2_printchar (c, stream)
- int c;
- FILE *stream;
-{
- fputs_filtered ("'", stream);
- emit_char (c, stream, '\'');
- fputs_filtered ("'", stream);
-}
-
-/* Print the character string STRING, printing at most LENGTH characters.
- Printing stops early if the number hits print_max; repeat counts
- are printed as appropriate. Print ellipses at the end if we
- had to stop before printing LENGTH characters, or if FORCE_ELLIPSES.
- FIXME: This is a copy of the same function from c-exp.y. It should
- be replaced with a true Modula version. */
-
-static void
-m2_printstr (stream, string, length, force_ellipses)
- FILE *stream;
- char *string;
- unsigned int length;
- int force_ellipses;
-{
- register unsigned int i;
- unsigned int things_printed = 0;
- int in_quotes = 0;
- int need_comma = 0;
- extern int inspect_it;
- extern int repeat_count_threshold;
- extern int print_max;
-
- if (length == 0)
- {
- fputs_filtered ("\"\"", stdout);
- return;
- }
-
- for (i = 0; i < length && things_printed < print_max; ++i)
- {
- /* Position of the character we are examining
- to see whether it is repeated. */
- unsigned int rep1;
- /* Number of repetitions we have detected so far. */
- unsigned int reps;
-
- QUIT;
-
- if (need_comma)
- {
- fputs_filtered (", ", stream);
- need_comma = 0;
- }
-
- rep1 = i + 1;
- reps = 1;
- while (rep1 < length && string[rep1] == string[i])
- {
- ++rep1;
- ++reps;
- }
-
- if (reps > repeat_count_threshold)
- {
- if (in_quotes)
- {
- if (inspect_it)
- fputs_filtered ("\\\", ", stream);
- else
- fputs_filtered ("\", ", stream);
- in_quotes = 0;
- }
- c_printchar (string[i], stream);
- fprintf_filtered (stream, " <repeats %u times>", reps);
- i = rep1 - 1;
- things_printed += repeat_count_threshold;
- need_comma = 1;
- }
- else
- {
- if (!in_quotes)
- {
- if (inspect_it)
- fputs_filtered ("\\\"", stream);
- else
- fputs_filtered ("\"", stream);
- in_quotes = 1;
- }
- emit_char (string[i], stream, '"');
- ++things_printed;
- }
- }
-
- /* Terminate the quotes if necessary. */
- if (in_quotes)
- {
- if (inspect_it)
- fputs_filtered ("\\\"", stream);
- else
- fputs_filtered ("\"", stream);
- }
-
- if (force_ellipses || i < length)
- fputs_filtered ("...", stream);
-}
-
-\f
-/* Table of operators and their precedences for printing expressions. */
-
-const static struct op_print m2_op_print_tab[] = {
- {"+", BINOP_ADD, PREC_ADD, 0},
- {"+", UNOP_PLUS, PREC_PREFIX, 0},
- {"-", BINOP_SUB, PREC_ADD, 0},
- {"-", UNOP_NEG, PREC_PREFIX, 0},
- {"*", BINOP_MUL, PREC_MUL, 0},
- {"/", BINOP_DIV, PREC_MUL, 0},
- {"DIV", BINOP_INTDIV, PREC_MUL, 0},
- {"MOD", BINOP_REM, PREC_MUL, 0},
- {":=", BINOP_ASSIGN, PREC_ASSIGN, 1},
- {"OR", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
- {"AND", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
- {"NOT", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
- {"=", BINOP_EQUAL, PREC_EQUAL, 0},
- {"<>", BINOP_NOTEQUAL, PREC_EQUAL, 0},
- {"<=", BINOP_LEQ, PREC_ORDER, 0},
- {">=", BINOP_GEQ, PREC_ORDER, 0},
- {">", BINOP_GTR, PREC_ORDER, 0},
- {"<", BINOP_LESS, PREC_ORDER, 0},
- {"^", UNOP_IND, PREC_PREFIX, 0},
- {"@", BINOP_REPEAT, PREC_REPEAT, 0},
- {NULL, 0, 0, 0}
-};
-\f
-/* The built-in types of Modula-2. */
-
-struct type *builtin_type_m2_char;
-struct type *builtin_type_m2_int;
-struct type *builtin_type_m2_card;
-struct type *builtin_type_m2_real;
-struct type *builtin_type_m2_bool;
-
-struct type ** const (m2_builtin_types[]) =
-{
- &builtin_type_m2_char,
- &builtin_type_m2_int,
- &builtin_type_m2_card,
- &builtin_type_m2_real,
- &builtin_type_m2_bool,
- 0
-};
-
-const struct language_defn m2_language_defn = {
- "modula-2",
- language_m2,
- m2_builtin_types,
- range_check_on,
- type_check_on,
- m2_parse, /* parser */
- m2_error, /* parser error function */
- m2_printchar, /* Print character constant */
- m2_printstr, /* function to print string constant */
- &builtin_type_m2_int, /* longest signed integral type */
- &builtin_type_m2_card, /* longest unsigned integral type */
- &builtin_type_m2_real, /* longest floating point type */
- {"", "", "", ""}, /* Binary format info */
- {"%oB", "", "o", "B"}, /* Octal format info */
- {"%d", "", "d", ""}, /* Decimal format info */
- {"0%XH", "0", "X", "H"}, /* Hex format info */
- m2_op_print_tab, /* expression operators for printing */
- LANG_MAGIC
-};
-
-/* Initialization for Modula-2 */
-
void
-_initialize_m2_exp ()
+yyerror (msg)
+ char *msg;
{
- /* Modula-2 "pervasive" types. NOTE: these can be redefined!!! */
- builtin_type_m2_int =
- init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
- 0,
- "INTEGER", (struct objfile *) NULL);
- builtin_type_m2_card =
- init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
- TYPE_FLAG_UNSIGNED,
- "CARDINAL", (struct objfile *) NULL);
- builtin_type_m2_real =
- init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
- 0,
- "REAL", (struct objfile *) NULL);
- builtin_type_m2_char =
- init_type (TYPE_CODE_CHAR, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
- TYPE_FLAG_UNSIGNED,
- "CHAR", (struct objfile *) NULL);
- builtin_type_m2_bool =
- init_type (TYPE_CODE_BOOL, TARGET_INT_BIT / TARGET_CHAR_BIT,
- TYPE_FLAG_UNSIGNED,
- "BOOLEAN", (struct objfile *) NULL);
-
- TYPE_NFIELDS(builtin_type_m2_bool) = 2;
- TYPE_FIELDS(builtin_type_m2_bool) =
- (struct field *) malloc (sizeof (struct field) * 2);
- TYPE_FIELD_BITPOS(builtin_type_m2_bool,0) = 0;
- TYPE_FIELD_NAME(builtin_type_m2_bool,0) = (char *)malloc(6);
- strcpy(TYPE_FIELD_NAME(builtin_type_m2_bool,0),"FALSE");
- TYPE_FIELD_BITPOS(builtin_type_m2_bool,1) = 1;
- TYPE_FIELD_NAME(builtin_type_m2_bool,1) = (char *)malloc(5);
- strcpy(TYPE_FIELD_NAME(builtin_type_m2_bool,1),"TRUE");
-
- add_language (&m2_language_defn);
+ error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
}