Allow 'thread' to be used as a variable name in expressions.

GDB treats the identifiers 'if', 'thread', and 'task' unconditionally
as expression delimiters in Ada mode, which is correct for 'if' and 'task',
but wrong for 'thread' in cases such as

      print thread

Borrowing from c-exp.y, we observe that 'thread' must be followed by
numerals, whereas identifiers never are and treat them as delimiters
only in that case.

In the process, the current also refactors and incidentally fixes the
code for rewinding the input to before the delimiting tokens.  For
example, the code

      watch expr if i > 2

fails because the input is only rewound to just before the 'i',
leaving the 'if' as part of the expression (and thus making the
rest look like trailing junk rather than a conditional clause).

gdb/ChangeLog:

    * ada-lex.l (rules): Only recognize 'thread' as a
    delimiter when followed by numerals, as for c-exp.y.
    Use new rewind_to_char function to rewind the input for
    expression-delimiting tokens.
    (rewind_to_char): New function.

gdb/testsuite/ChangeLog:

    * gdb.ada/expr_delims.exp: New file.
    * gdb.ada/expr_delims/foo.adb: New file.
    * gdb.ada/expr_delims/pck.ads: New file.
    * gdb.ada/expr_delims/pck.adb: New file.
This commit is contained in:
Paul N. Hilfinger
2013-03-12 09:03:11 +00:00
parent dad60f8e13
commit 82d049abf1
7 changed files with 176 additions and 11 deletions

View File

@@ -53,6 +53,7 @@ static int processReal (const char *);
static struct stoken processId (const char *, int);
static int processAttribute (const char *);
static int find_dot_all (const char *);
static void rewind_to_char (int);
#undef YY_DECL
#define YY_DECL static int yylex ( void )
@@ -157,18 +158,19 @@ static int find_dot_all (const char *);
if {
while (*lexptr != 'i' && *lexptr != 'I')
lexptr -= 1;
yyrestart(NULL);
rewind_to_char ('i');
return 0;
}
(task|thread) {
task {
rewind_to_char ('t');
return 0;
}
thread{WHITE}+{DIG} {
/* This keyword signals the end of the expression and
will be processed separately. */
while (*lexptr != 't' && *lexptr != 'T')
lexptr--;
yyrestart(NULL);
rewind_to_char ('t');
return 0;
}
@@ -218,8 +220,7 @@ false { return FALSEKEYWORD; }
"," { if (paren_depth == 0 && comma_terminates)
{
lexptr -= 1;
yyrestart(NULL);
rewind_to_char (',');
return 0;
}
else
@@ -229,8 +230,7 @@ false { return FALSEKEYWORD; }
"(" { paren_depth += 1; return '('; }
")" { if (paren_depth == 0)
{
lexptr -= 1;
yyrestart(NULL);
rewind_to_char (')');
return 0;
}
else
@@ -616,6 +616,23 @@ processAttribute (const char *str)
return attributes[k].code;
}
/* Back up lexptr by yyleng and then to the rightmost occurrence of
character CH, case-folded (there must be one). WARNING: since
lexptr points to the next input character that Flex has not yet
transferred to its internal buffer, the use of this function
depends on the assumption that Flex calls YY_INPUT only when it is
logically necessary to do so (thus, there is no reading ahead
farther than needed to identify the next token.) */
static void
rewind_to_char (int ch)
{
lexptr -= yyleng;
while (toupper (*lexptr) != toupper (ch))
lexptr -= 1;
yyrestart (NULL);
}
int
yywrap(void)
{