From: Per Bothner Date: Thu, 5 Oct 1995 22:15:49 +0000 (+0000) Subject: * parse.c (write_dollar_variable): New function. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c700638ca7c1c0d0dd2fac7983b2d59ca7217099;p=binutils-gdb.git * 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 '$'. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 76ed88557ec..8e203d7a779 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,14 @@ +Thu Oct 5 15:14:36 1995 Per Bothner + + * 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 * win32.c: New file; support for debugging on windows NT. diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 30ab99e3e63..eae0794766c 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 LAST REGNAME -%token VARIABLE +%token VARIABLE %token 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 f8e9717ce9e..87137c8aeb7 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 GDB_REGNAME /* Machine register name */ -%token GDB_LAST /* Value history */ -%token GDB_VARIABLE /* Convenience variable */ +%token GDB_VARIABLE /* Convenience variable */ %token GDB_ASSIGNMENT /* Assign value to somewhere */ %type 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 , starting - from the first value which has index 1. - Return GDB_LAST. - - $$digits Value history with index 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 4dd238cbfc5..ee97015ef6b 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 LAST REGNAME CHARACTER +%token CHARACTER -%token VARIABLE +%token VARIABLE %token 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 efcaab800b7..9ec896f2864 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 LAST REGNAME - -%token INTERNAL_VAR +%token 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 fb8793fbb07..7bbe0a8f8ff 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 , starting + from the first value which has index 1. + + $$digits Value history with index 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 4c98d64d927..8df68035350 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);