From 45fe3db4ede57e944e8a780ffdfbaafcfe5bd996 Mon Sep 17 00:00:00 2001 From: Fred Fish Date: Thu, 31 Dec 1992 04:05:05 +0000 Subject: [PATCH 1/1] * c-exp.y, m2-exp.y (yyreds, yytoks): Remap like other yy* names. * c-exp.y, m2-exp.y (YYDEBUG): Define if MAINTENANCE_CMDS is defined and YYDEBUG is not already defined. * c-exp.y (strncmp): Replace throughout with STREQN, missed them during the previous replacements. * printcmd.c (_initialize_printcmd): Update internal documentation for "set" command to note that the assignment syntax is language dependent. **** start-sanitize-chill **** * ch-exp.y (yyreds, yytoks): Remap like other yy* names. * ch-exp.y (YYDEBUG): Define if MAINTENANCE_CMDS is defined and YYDEBUG is not already defined. * ch-exp.y (GDB_REGNAME, GDB_LAST, GDB_VARIABLE, GDB_ASSIGNMENT, single_assignment_action): New terminals and nonterminal for gdb extensions to chill expression grammer. * ch-exp.y (match_dollar_tokens): Lexer routine to match all tokens that start with '$' (register names, convenience vars, etc). * ch-exp.y (tokentab2): Add GDB_ASSIGNMENT. * ch-exp.y (yylex): Call match_dollar_tokens. **** end-sanitize-chill **** --- gdb/ChangeLog | 23 ++++++ gdb/c-exp.y | 42 ++++++----- gdb/ch-exp.y | 196 ++++++++++++++++++++++++++++++++++++++++++++++--- gdb/m2-exp.y | 19 +++-- gdb/printcmd.c | 18 +++-- 5 files changed, 255 insertions(+), 43 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5d535a626b..72c8e197c1 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,26 @@ +Wed Dec 30 19:47:13 1992 Fred Fish (fnf@cygnus.com) + + * c-exp.y, m2-exp.y (yyreds, yytoks): Remap like other yy* names. + * c-exp.y, m2-exp.y (YYDEBUG): Define if MAINTENANCE_CMDS is defined + and YYDEBUG is not already defined. + * c-exp.y (strncmp): Replace throughout with STREQN, missed + them during the previous replacements. + * printcmd.c (_initialize_printcmd): Update internal documentation + for "set" command to note that the assignment syntax is language + dependent. + **** start-sanitize-chill **** + * ch-exp.y (yyreds, yytoks): Remap like other yy* names. + * ch-exp.y (YYDEBUG): Define if MAINTENANCE_CMDS is defined + and YYDEBUG is not already defined. + * ch-exp.y (GDB_REGNAME, GDB_LAST, GDB_VARIABLE, GDB_ASSIGNMENT, + single_assignment_action): New terminals and nonterminal for gdb + extensions to chill expression grammer. + * ch-exp.y (match_dollar_tokens): Lexer routine to match all + tokens that start with '$' (register names, convenience vars, etc). + * ch-exp.y (tokentab2): Add GDB_ASSIGNMENT. + * ch-exp.y (yylex): Call match_dollar_tokens. + **** end-sanitize-chill **** + Mon Dec 28 15:00:01 1992 Stu Grossman (grossman at cygnus.com) * hppah-tdep.c (skip_trampoline_code): Use new macros for diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 1129cf60f5..b77200ea0c 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -73,6 +73,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define yy_yyv c_yyv #define yyval c_val #define yylloc c_lloc +#define yyreds c_reds /* With YYDEBUG defined */ +#define yytoks c_toks /* With YYDEBUG defined */ #define yyss c_yyss /* byacc */ #define yyssp c_yysp /* byacc */ #define yyvs c_yyvs /* byacc */ @@ -87,7 +89,9 @@ yylex PARAMS ((void)); void yyerror PARAMS ((char *)); -/* #define YYDEBUG 1 */ +#if MAINTENANCE_CMDS +#define YYDEBUG 1 +#endif %} @@ -1094,7 +1098,7 @@ yylex () tokstart = lexptr; /* See if it is a special token of length 3. */ for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++) - if (!strncmp (tokstart, tokentab3[i].operator, 3)) + if (STREQN (tokstart, tokentab3[i].operator, 3)) { lexptr += 3; yylval.opcode = tokentab3[i].opcode; @@ -1103,7 +1107,7 @@ yylex () /* See if it is a special token of length 2. */ for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++) - if (!strncmp (tokstart, tokentab2[i].operator, 2)) + if (STREQN (tokstart, tokentab2[i].operator, 2)) { lexptr += 2; yylval.opcode = tokentab2[i].opcode; @@ -1369,14 +1373,14 @@ yylex () if (*tokstart == '$') { for (c = 0; c < NUM_REGS; c++) if (namelen - 1 == strlen (reg_names[c]) - && !strncmp (tokstart + 1, reg_names[c], namelen - 1)) + && 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) - && !strncmp (tokstart + 1, std_regs[c].name, namelen - 1)) + && STREQN (tokstart + 1, std_regs[c].name, namelen - 1)) { yylval.lval = std_regs[c].regnum; return REGNAME; @@ -1386,40 +1390,40 @@ yylex () switch (namelen) { case 8: - if (!strncmp (tokstart, "unsigned", 8)) + if (STREQN (tokstart, "unsigned", 8)) return UNSIGNED; if (current_language->la_language == language_cplus - && !strncmp (tokstart, "template", 8)) + && STREQN (tokstart, "template", 8)) return TEMPLATE; - if (!strncmp (tokstart, "volatile", 8)) + if (STREQN (tokstart, "volatile", 8)) return VOLATILE_KEYWORD; break; case 6: - if (!strncmp (tokstart, "struct", 6)) + if (STREQN (tokstart, "struct", 6)) return STRUCT; - if (!strncmp (tokstart, "signed", 6)) + if (STREQN (tokstart, "signed", 6)) return SIGNED_KEYWORD; - if (!strncmp (tokstart, "sizeof", 6)) + if (STREQN (tokstart, "sizeof", 6)) return SIZEOF; break; case 5: if (current_language->la_language == language_cplus - && !strncmp (tokstart, "class", 5)) + && STREQN (tokstart, "class", 5)) return CLASS; - if (!strncmp (tokstart, "union", 5)) + if (STREQN (tokstart, "union", 5)) return UNION; - if (!strncmp (tokstart, "short", 5)) + if (STREQN (tokstart, "short", 5)) return SHORT; - if (!strncmp (tokstart, "const", 5)) + if (STREQN (tokstart, "const", 5)) return CONST_KEYWORD; break; case 4: - if (!strncmp (tokstart, "enum", 4)) + if (STREQN (tokstart, "enum", 4)) return ENUM; - if (!strncmp (tokstart, "long", 4)) + if (STREQN (tokstart, "long", 4)) return LONG; if (current_language->la_language == language_cplus - && !strncmp (tokstart, "this", 4)) + && STREQN (tokstart, "this", 4)) { static const char this_name[] = { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' }; @@ -1430,7 +1434,7 @@ yylex () } break; case 3: - if (!strncmp (tokstart, "int", 3)) + if (STREQN (tokstart, "int", 3)) return INT_KEYWORD; break; default: diff --git a/gdb/ch-exp.y b/gdb/ch-exp.y index 141463d7b4..2f6376a3be 100644 --- a/gdb/ch-exp.y +++ b/gdb/ch-exp.y @@ -90,6 +90,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define yy_yyv chill_yyv #define yyval chill_val #define yylloc chill_lloc +#define yyreds chill_reds /* With YYDEBUG defined */ +#define yytoks chill_toks /* With YYDEBUG defined */ #define yyss chill_yyss /* byacc */ #define yyssp chill_yysp /* byacc */ #define yyvs chill_yyvs /* byacc */ @@ -104,7 +106,9 @@ yyerror PARAMS ((char *)); int yyparse PARAMS ((void)); -/* #define YYDEBUG 1 */ +#if MAINTENANCE_CMDS +#define YYDEBUG 1 +#endif %} @@ -190,6 +194,15 @@ yyparse PARAMS ((void)); %token ELSIF %token ILLEGAL_TOKEN +/* Tokens which are not Chill tokens used in expressions, but rather GDB + 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_ASSIGNMENT /* Assign value to somewhere */ + %type location %type access_name %type primitive_value @@ -247,6 +260,8 @@ yyparse PARAMS ((void)); %type case_label_specification %type buffer_location +%type single_assignment_action + %% /* Z.200, 5.3.1 */ @@ -287,6 +302,24 @@ 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); + } | FIXME { $$ = 0; /* FIXME */ @@ -604,6 +637,10 @@ operand_0 : operand_1 { write_exp_elt_opcode (BINOP_BITWISE_XOR); } + | single_assignment_action + { + $$ = 0; /* FIXME */ + } ; /* Z.200, 5.3.4 */ @@ -740,6 +777,13 @@ operand_6 : POINTER location ; +/* Z.200, 6.2 */ + +single_assignment_action : location GDB_ASSIGNMENT value + { + write_exp_elt_opcode (BINOP_ASSIGN); + } + /* Z.200, 12.4.3 */ /* FIXME: For now we just accept only a single integer literal. */ @@ -1036,6 +1080,131 @@ match_integer_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 + 1; + 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); +} + #if 0 static void convert_float () { @@ -1103,6 +1272,7 @@ static const struct token tokentab3[] = static const struct token tokentab2[] = { + { ":=", GDB_ASSIGNMENT }, { "//", SLASH_SLASH }, { "/=", NOTEQUAL }, { "<=", LEQ }, @@ -1136,7 +1306,6 @@ yylex () return (0); case '.': case '=': - case ':': case ';': case '!': case '+': @@ -1150,7 +1319,8 @@ yylex () return (*lexptr++); } /* Look for characters which start a particular kind of multicharacter - token, such as a character literal. */ + token, such as a character literal, register name, convenience + variable name, etc. */ switch (*lexptr) { case 'C': @@ -1162,11 +1332,18 @@ yylex () return (token); } break; + case '$': + token = match_dollar_tokens (); + if (token != 0) + { + return (token); + } + break; } /* See if it is a special token of length 5. */ for (i = 0; i < sizeof (tokentab5) / sizeof (tokentab5[0]); i++) { - if (strncmp (lexptr, tokentab5[i].operator, 5) == 0) + if (STREQN (lexptr, tokentab5[i].operator, 5)) { lexptr += 5; return (tokentab5[i].token); @@ -1175,7 +1352,7 @@ yylex () /* See if it is a special token of length 4. */ for (i = 0; i < sizeof (tokentab4) / sizeof (tokentab4[0]); i++) { - if (strncmp (lexptr, tokentab4[i].operator, 4) == 0) + if (STREQN (lexptr, tokentab4[i].operator, 4)) { lexptr += 4; return (tokentab4[i].token); @@ -1184,7 +1361,7 @@ yylex () /* See if it is a special token of length 3. */ for (i = 0; i < sizeof (tokentab3) / sizeof (tokentab3[0]); i++) { - if (strncmp (lexptr, tokentab3[i].operator, 3) == 0) + if (STREQN (lexptr, tokentab3[i].operator, 3)) { lexptr += 3; return (tokentab3[i].token); @@ -1193,7 +1370,7 @@ yylex () /* See if it is a special token of length 2. */ for (i = 0; i < sizeof (tokentab2) / sizeof (tokentab2[0]); i++) { - if (strncmp (lexptr, tokentab2[i].operator, 2) == 0) + if (STREQN (lexptr, tokentab2[i].operator, 2)) { lexptr += 2; return (tokentab2[i].token); @@ -1204,19 +1381,20 @@ yylex () would already have found it. */ switch (*lexptr) { + case ':': case '/': case '<': case '>': return (*lexptr++); } /* Look for other special tokens. */ - if (strncmp (lexptr, "TRUE", 4) == 0) /* FIXME: What about lowercase? */ + if (STREQN (lexptr, "TRUE", 4)) /* FIXME: What about lowercase? */ { yylval.ulval = 1; lexptr += 4; return (BOOLEAN_LITERAL); } - if (strncmp (lexptr, "FALSE", 5) == 0) /* FIXME: What about lowercase? */ + if (STREQN (lexptr, "FALSE", 5)) /* FIXME: What about lowercase? */ { yylval.ulval = 0; lexptr += 5; diff --git a/gdb/m2-exp.y b/gdb/m2-exp.y index 037a07419b..2bee7380ae 100644 --- a/gdb/m2-exp.y +++ b/gdb/m2-exp.y @@ -75,6 +75,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #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 yyss m2_yyss /* byacc */ #define yyssp m2_yysp /* byacc */ #define yyvs m2_yyvs /* byacc */ @@ -106,7 +108,10 @@ static int number_sign = 1; static struct block *modblock=0; #endif -/* #define YYDEBUG 1 */ +#if MAINTENANCE_CMDS +#define YYDEBUG 1 +#endif + %} /* Although the yacc "value" of an expression is not used, @@ -848,7 +853,7 @@ yylex () /* 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)) + if(STREQN(tokentab2[i].name, tokstart, 2)) { lexptr += 2; return tokentab2[i].token; @@ -1043,14 +1048,14 @@ yylex () if (*tokstart == '$') { for (c = 0; c < NUM_REGS; c++) if (namelen - 1 == strlen (reg_names[c]) - && !strncmp (tokstart + 1, reg_names[c], namelen - 1)) + && 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) - && !strncmp (tokstart + 1, std_regs[c].name, namelen - 1)) + && STREQN (tokstart + 1, std_regs[c].name, namelen - 1)) { yylval.lval = std_regs[c].regnum; return REGNAME; @@ -1060,7 +1065,7 @@ yylex () /* 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)) + if(namelen == strlen(keytab[i].keyw) && STREQN(tokstart,keytab[i].keyw,namelen)) return keytab[i].token; yylval.sval.ptr = tokstart; @@ -1126,12 +1131,12 @@ yylex () 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; diff --git a/gdb/printcmd.c b/gdb/printcmd.c index aecd57c263..d8bc20f7f3 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -1960,10 +1960,11 @@ This is useful for formatted output in user-defined commands."); This is useful in user-defined commands."); add_prefix_cmd ("set", class_vars, set_command, -"Perform an assignment VAR = EXP.\n\ -You must type the \"=\". VAR may be a debugger \"convenience\" variable\n\ -(names starting with $), a register (a few standard names starting with $),\n\ -or an actual variable in the program being debugged. EXP is any expression.\n\ +"Evaluate expression EXP and assign result to variable VAR, using assignment\n\ +syntax appropriate for the current language (VAR = EXP or VAR := EXP for\n\ +example). VAR may be a debugger \"convenience\" variable (names starting\n\ +with $), a register (a few standard names starting with $), or an actual\n\ +variable in the program being debugged. EXP is any valid expression.\n\ Use \"set variable\" for variables with names identical to set subcommands.\n\ \nWith a subcommand, this command modifies parts of the gdb environment.\n\ You can see these environment settings with the \"show\" command.", @@ -1977,10 +1978,11 @@ current working language. The result is printed and saved in the value\n\ history, if it is not void."); add_cmd ("variable", class_vars, set_command, - "Perform an assignment VAR = EXP.\n\ -You must type the \"=\". VAR may be a debugger \"convenience\" variable\n\ -(names starting with $), a register (a few standard names starting with $),\n\ -or an actual variable in the program being debugged. EXP is any expression.\n\ +"Evaluate expression EXP and assign result to variable VAR, using assignment\n\ +syntax appropriate for the current language (VAR = EXP or VAR := EXP for\n\ +example). VAR may be a debugger \"convenience\" variable (names starting\n\ +with $), a register (a few standard names starting with $), or an actual\n\ +variable in the program being debugged. EXP is any valid expression.\n\ This may usually be abbreviated to simply \"set\".", &setlist); -- 2.34.1