aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog11
-rw-r--r--gdb/c-exp.y75
-rw-r--r--gdb/ch-exp.y158
-rw-r--r--gdb/f-exp.y77
-rw-r--r--gdb/m2-exp.y80
-rw-r--r--gdb/parse.c91
-rw-r--r--gdb/scm-exp.c5
7 files changed, 123 insertions, 374 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 76ed885..8e203d7 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,14 @@
+Thu Oct 5 15:14:36 1995 Per Bothner <bothner@kalessin.cygnus.com>
+
+ * parse.c (write_dollar_variable): New function.
+ * c-exp.y (yylex): Replace code for recognizing '$' pseudo-variables
+ with a call to write_dollar_variable.
+ Simplify grammar correspondingly.
+ * f-exp.y: Likewise.
+ * m2-exp.y: Likewise.
+ * ch-exp.y: Likewise. (Remove function match_dollar_tokens.)
+ * scm-exp.c (scm_lreadr): Call write_dollar_variable to handle '$'.
+
Thu Oct 5 13:27:30 1995 steve chamberlain <sac@slash.cygnus.com>
* win32.c: New file; support for debugging on windows NT.
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 30ab99e..eae0794 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -184,9 +184,8 @@ parse_number PARAMS ((char *, int, int, YYSTYPE *));
/* Special type cases, put in to allow the parser to distinguish different
legal basetypes. */
%token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD
-%token <lval> LAST REGNAME
-%token <ivar> VARIABLE
+%token <voidval> VARIABLE
%token <opcode> ASSIGN_MODIFY
@@ -482,22 +481,8 @@ exp : FLOAT
exp : variable
;
-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 : VARIABLE
- { write_exp_elt_opcode (OP_INTERNALVAR);
- write_exp_elt_intern ($1);
- write_exp_elt_opcode (OP_INTERNALVAR); }
+ /* Already written by write_dollar_variable. */
;
exp : SIZEOF '(' type ')' %prec UNARY
@@ -1393,60 +1378,8 @@ yylex ()
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. */
-
tryname:
- 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])
- && STREQN (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)
- && STREQN (tokstart + 1, std_regs[c].name, namelen - 1))
- {
- yylval.lval = std_regs[c].regnum;
- return REGNAME;
- }
- }
/* Catch specific keywords. Should be done with a data structure. */
switch (namelen)
{
@@ -1506,11 +1439,9 @@ yylex ()
yylval.sval.ptr = tokstart;
yylval.sval.length = namelen;
- /* Any other names starting in $ are debugger internal variables. */
-
if (*tokstart == '$')
{
- yylval.ivar = lookup_internalvar (copy_name (yylval.sval) + 1);
+ write_dollar_variable (yylval.sval);
return VARIABLE;
}
diff --git a/gdb/ch-exp.y b/gdb/ch-exp.y
index f8e9717..87137c8 100644
--- a/gdb/ch-exp.y
+++ b/gdb/ch-exp.y
@@ -225,9 +225,7 @@ yyerror PARAMS ((char *));
specific things that we recognize in the same context as Chill tokens
(register names for example). */
-%token <lval> GDB_REGNAME /* Machine register name */
-%token <lval> GDB_LAST /* Value history */
-%token <ivar> GDB_VARIABLE /* Convenience variable */
+%token <voidval> GDB_VARIABLE /* Convenience variable */
%token <voidval> GDB_ASSIGNMENT /* Assign value to somewhere */
%type <voidval> access_name
@@ -291,24 +289,7 @@ access_name : LOCATION_NAME
write_exp_elt_sym ($1.sym);
write_exp_elt_opcode (OP_VAR_VALUE);
}
- | GDB_LAST /* gdb specific */
- {
- write_exp_elt_opcode (OP_LAST);
- write_exp_elt_longcst ($1);
- write_exp_elt_opcode (OP_LAST);
- }
- | GDB_REGNAME /* gdb specific */
- {
- write_exp_elt_opcode (OP_REGISTER);
- write_exp_elt_longcst ($1);
- write_exp_elt_opcode (OP_REGISTER);
- }
| GDB_VARIABLE /* gdb specific */
- {
- write_exp_elt_opcode (OP_INTERNALVAR);
- write_exp_elt_intern ($1);
- write_exp_elt_opcode (OP_INTERNALVAR);
- }
;
/* Z.200, 4.2.8 */
@@ -1382,131 +1363,6 @@ match_bitstring_literal ()
}
}
-/* Recognize tokens that start with '$'. These include:
-
- $regname A native register name or a "standard
- register name".
- Return token GDB_REGNAME.
-
- $variable A convenience variable with a name chosen
- by the user.
- Return token GDB_VARIABLE.
-
- $digits Value history with index <digits>, starting
- from the first value which has index 1.
- Return GDB_LAST.
-
- $$digits Value history with index <digits> relative
- to the last value. I.E. $$0 is the last
- value, $$1 is the one previous to that, $$2
- is the one previous to $$1, etc.
- Return token GDB_LAST.
-
- $ | $0 | $$0 The last value in the value history.
- Return token GDB_LAST.
-
- $$ An abbreviation for the second to the last
- value in the value history, I.E. $$1
- Return token GDB_LAST.
-
- Note that we currently assume that register names and convenience
- variables follow the convention of starting with a letter or '_'.
-
- */
-
-static int
-match_dollar_tokens ()
-{
- char *tokptr;
- int regno;
- int namelength;
- int negate;
- int ival;
-
- /* We will always have a successful match, even if it is just for
- a single '$', the abbreviation for $$0. So advance lexptr. */
-
- tokptr = ++lexptr;
-
- if (*tokptr == '_' || isalpha (*tokptr))
- {
- /* Look for a match with a native register name, usually something
- like "r0" for example. */
-
- for (regno = 0; regno < NUM_REGS; regno++)
- {
- namelength = strlen (reg_names[regno]);
- if (STREQN (tokptr, reg_names[regno], namelength)
- && !isalnum (tokptr[namelength]))
- {
- yylval.lval = regno;
- lexptr += namelength;
- return (GDB_REGNAME);
- }
- }
-
- /* Look for a match with a standard register name, usually something
- like "pc", which gdb always recognizes as the program counter
- regardless of what the native register name is. */
-
- for (regno = 0; regno < num_std_regs; regno++)
- {
- namelength = strlen (std_regs[regno].name);
- if (STREQN (tokptr, std_regs[regno].name, namelength)
- && !isalnum (tokptr[namelength]))
- {
- yylval.lval = std_regs[regno].regnum;
- lexptr += namelength;
- return (GDB_REGNAME);
- }
- }
-
- /* Attempt to match against a convenience variable. Note that
- this will always succeed, because if no variable of that name
- already exists, the lookup_internalvar will create one for us.
- Also note that both lexptr and tokptr currently point to the
- start of the input string we are trying to match, and that we
- have already tested the first character for non-numeric, so we
- don't have to treat it specially. */
-
- while (*tokptr == '_' || isalnum (*tokptr))
- {
- tokptr++;
- }
- yylval.sval.ptr = lexptr;
- yylval.sval.length = tokptr - lexptr;
- yylval.ivar = lookup_internalvar (copy_name (yylval.sval));
- lexptr = tokptr;
- return (GDB_VARIABLE);
- }
-
- /* Since we didn't match against a register name or convenience
- variable, our only choice left is a history value. */
-
- if (*tokptr == '$')
- {
- negate = 1;
- ival = 1;
- tokptr++;
- }
- else
- {
- negate = 0;
- ival = 0;
- }
-
- /* Attempt to decode more characters as an integer value giving
- the index in the history list. If successful, the value will
- overwrite ival (currently 0 or 1), and if not, ival will be
- left alone, which is good since it is currently correct for
- the '$' or '$$' case. */
-
- decode_integer_literal (&ival, &tokptr);
- yylval.lval = negate ? -ival : ival;
- lexptr = tokptr;
- return (GDB_LAST);
-}
-
struct token
{
char *operator;
@@ -1620,11 +1476,13 @@ yylex ()
}
break;
case '$':
- token = match_dollar_tokens ();
- if (token != 0)
- {
- return (token);
- }
+ yylval.sval.ptr = lexptr;
+ do {
+ lexptr++;
+ } while (isalnum (*lexptr) || (lexptr == '_'));
+ yylval.sval.length = lexptr - yylval.sval.ptr;
+ write_dollar_variable (yylval.sval);
+ return GDB_VARIABLE;
break;
}
/* See if it is a special token of length 2. */
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
index 4dd238c..ee97015 100644
--- a/gdb/f-exp.y
+++ b/gdb/f-exp.y
@@ -186,9 +186,9 @@ static int parse_number PARAMS ((char *, int, int, YYSTYPE *));
%token LOGICAL_KEYWORD REAL_KEYWORD REAL_S8_KEYWORD REAL_S16_KEYWORD
%token COMPLEX_S8_KEYWORD COMPLEX_S16_KEYWORD COMPLEX_S32_KEYWORD
%token BOOL_AND BOOL_OR BOOL_NOT
-%token <lval> LAST REGNAME CHARACTER
+%token <lval> CHARACTER
-%token <ivar> VARIABLE
+%token <voidval> VARIABLE
%token <opcode> ASSIGN_MODIFY
@@ -412,22 +412,7 @@ exp : FLOAT
exp : variable
;
-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 : VARIABLE
- { write_exp_elt_opcode (OP_INTERNALVAR);
- write_exp_elt_intern ($1);
- write_exp_elt_opcode (OP_INTERNALVAR); }
;
exp : SIZEOF '(' type ')' %prec UNARY
@@ -1110,60 +1095,6 @@ yylex ()
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])
- && STREQN (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)
- && STREQN (tokstart + 1, std_regs[c].name, namelen - 1))
- {
- yylval.lval = std_regs[c].regnum;
- return REGNAME;
- }
- }
/* Catch specific keywords. */
for (i = 0; f77_keywords[i].operator != NULL; i++)
@@ -1178,11 +1109,9 @@ yylex ()
yylval.sval.ptr = tokstart;
yylval.sval.length = namelen;
- /* Any other names starting in $ are debugger internal variables. */
-
if (*tokstart == '$')
{
- yylval.ivar = lookup_internalvar (copy_name (yylval.sval) + 1);
+ write_dollar_variable (yylval.sval);
return VARIABLE;
}
diff --git a/gdb/m2-exp.y b/gdb/m2-exp.y
index efcaab8..9ec896f 100644
--- a/gdb/m2-exp.y
+++ b/gdb/m2-exp.y
@@ -178,9 +178,7 @@ static struct block *modblock=0;
/* The GDB scope operator */
%token COLONCOLON
-%token <lval> LAST REGNAME
-
-%token <ivar> INTERNAL_VAR
+%token <voidval> INTERNAL_VAR
/* M2 tokens */
%left ','
@@ -519,19 +517,6 @@ exp : FLOAT
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);
@@ -580,9 +565,6 @@ variable: fblock
/* 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 */
@@ -1003,61 +985,6 @@ yylex ()
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])
- && STREQN (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)
- && STREQN (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) && STREQN(tokstart,keytab[i].keyw,namelen))
@@ -1066,15 +993,12 @@ yylex ()
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
diff --git a/gdb/parse.c b/gdb/parse.c
index fb8793f..7bbe0a8 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -399,6 +399,97 @@ write_exp_msymbol (msymbol, text_symbol_type, data_symbol_type)
write_exp_elt_opcode (UNOP_MEMVAL);
}
+/* Recognize tokens that start with '$'. These include:
+
+ $regname A native register name or a "standard
+ register name".
+
+ $variable A convenience variable with a name chosen
+ by the user.
+
+ $digits Value history with index <digits>, starting
+ from the first value which has index 1.
+
+ $$digits Value history with index <digits> relative
+ to the last value. I.E. $$0 is the last
+ value, $$1 is the one previous to that, $$2
+ is the one previous to $$1, etc.
+
+ $ | $0 | $$0 The last value in the value history.
+
+ $$ An abbreviation for the second to the last
+ value in the value history, I.E. $$1
+
+ */
+
+void
+write_dollar_variable (str)
+ struct stoken str;
+{
+ /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1)
+ and $$digits (equivalent to $<-digits> if you could type that). */
+
+ int negate = 0;
+ int i = 1;
+ /* Double dollar means negate the number and add -1 as well.
+ Thus $$ alone means -1. */
+ if (str.length >= 2 && str.ptr[1] == '$')
+ {
+ negate = 1;
+ i = 2;
+ }
+ if (i == str.length)
+ {
+ /* Just dollars (one or two) */
+ i = - negate;
+ goto handle_last;
+ }
+ /* Is the rest of the token digits? */
+ for (; i < str.length; i++)
+ if (!(str.ptr[i] >= '0' && str.ptr[i] <= '9'))
+ break;
+ if (i == str.length)
+ {
+ i = atoi (str.ptr + 1 + negate);
+ if (negate)
+ i = - i;
+ goto handle_last;
+ }
+
+ /* Handle tokens that refer to machine registers:
+ $ followed by a register name. */
+ for (i = 0; i < NUM_REGS; i++)
+ if (str.length - 1 == strlen (reg_names[i])
+ && STREQN (str.ptr + 1, reg_names[i], str.length - 1))
+ {
+ goto handle_register;
+ }
+ for (i = 0; i < num_std_regs; i++)
+ if (str.length - 1 == strlen (std_regs[i].name)
+ && STREQN (str.ptr + 1, std_regs[i].name, str.length - 1))
+ {
+ i = std_regs[i].regnum;
+ goto handle_register;
+ }
+
+ /* Any other names starting in $ are debugger internal variables. */
+
+ write_exp_elt_opcode (OP_INTERNALVAR);
+ write_exp_elt_intern (lookup_internalvar (copy_name (str) + 1));
+ write_exp_elt_opcode (OP_INTERNALVAR);
+ return;
+ handle_last:
+ write_exp_elt_opcode (OP_LAST);
+ write_exp_elt_longcst ((LONGEST) i);
+ write_exp_elt_opcode (OP_LAST);
+ return;
+ handle_register:
+ write_exp_elt_opcode (OP_REGISTER);
+ write_exp_elt_longcst (i);
+ write_exp_elt_opcode (OP_REGISTER);
+ return;
+}
+
/* Return a null-terminated temporary copy of the name
of a string token. */
diff --git a/gdb/scm-exp.c b/gdb/scm-exp.c
index 4c98d64..8df6803 100644
--- a/gdb/scm-exp.c
+++ b/gdb/scm-exp.c
@@ -373,6 +373,11 @@ scm_lreadr (skipping)
if (!skipping)
{
str.length = lexptr - str.ptr;
+ if (str.ptr[0] == '$')
+ {
+ write_dollar_variable (str);
+ return;
+ }
write_exp_elt_opcode (OP_NAME);
write_exp_string (str);
write_exp_elt_opcode (OP_NAME);