X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fada-lex.l;h=35db478baaa30654ac1d6b78b0982565523dd97a;hb=1d29ab86cb5145cac5045c1a4113d8b8fbd4d9c6;hp=e4713a23d2267699a27162276aa5297500b0a4ff;hpb=690cc4ebad2e274c2a3fa2720bccbc7f7c4cbdc7;p=deliverable%2Fbinutils-gdb.git
diff --git a/gdb/ada-lex.l b/gdb/ada-lex.l
index e4713a23d2..35db478baa 100644
--- a/gdb/ada-lex.l
+++ b/gdb/ada-lex.l
@@ -1,23 +1,20 @@
/* FLEX lexer for Ada expressions, for GDB.
- Copyright (C) 1994, 1997, 1998, 2000, 2001, 2002, 2003, 2007, 2008
- Free Software Foundation, Inc.
+ Copyright (C) 1994-2019 Free Software Foundation, Inc.
-This file is part of GDB.
+ This file is part of GDB.
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-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., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
/*----------------------------------------------------------------------*/
@@ -44,6 +41,14 @@ POSEXP (e"+"?{NUM10})
%{
+#include "diagnostics.h"
+
+/* Some old versions of flex generate code that uses the "register" keyword,
+ which clang warns about. This was observed for example with flex 2.5.35,
+ as shipped with macOS 10.12. */
+DIAGNOSTIC_PUSH
+DIAGNOSTIC_IGNORE_DEPRECATED_REGISTER
+
#define NUMERAL_WIDTH 256
#define LONGEST_SIGN ((ULONGEST) 1 << (sizeof(LONGEST) * HOST_CHAR_BIT - 1))
@@ -51,31 +56,40 @@ POSEXP (e"+"?{NUM10})
static char numbuf[NUMERAL_WIDTH];
static void canonicalizeNumeral (char *s1, const char *);
static struct stoken processString (const char*, int);
-static int processInt (const char *, const char *, const char *);
-static int processReal (const char *);
+static int processInt (struct parser_state *, const char *, const char *,
+ const char *);
+static int processReal (struct parser_state *, 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 )
+/* Flex generates a static function "input" which is not used.
+ Defining YY_NO_INPUT comments it out. */
+#define YY_NO_INPUT
+
#undef YY_INPUT
#define YY_INPUT(BUF, RESULT, MAX_SIZE) \
- if ( *lexptr == '\000' ) \
+ if ( *pstate->lexptr == '\000' ) \
(RESULT) = YY_NULL; \
else \
{ \
- *(BUF) = *lexptr; \
+ *(BUF) = *pstate->lexptr; \
(RESULT) = 1; \
- lexptr += 1; \
+ pstate->lexptr += 1; \
}
static int find_dot_all (const char *);
+/* Depth of parentheses. */
+static int paren_depth;
+
%}
-%option case-insensitive interactive nodefault
+%option case-insensitive interactive nodefault noyywrap
%s BEFORE_QUAL_QUOTE
@@ -87,40 +101,42 @@ static int find_dot_all (const char *);
{NUM10}{POSEXP} {
canonicalizeNumeral (numbuf, yytext);
- return processInt (NULL, numbuf, strrchr(numbuf, 'e')+1);
+ return processInt (pstate, NULL, numbuf,
+ strrchr (numbuf, 'e') + 1);
}
{NUM10} {
canonicalizeNumeral (numbuf, yytext);
- return processInt (NULL, numbuf, NULL);
+ return processInt (pstate, NULL, numbuf, NULL);
}
{NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#"{POSEXP} {
canonicalizeNumeral (numbuf, yytext);
- return processInt (numbuf,
+ return processInt (pstate, numbuf,
strchr (numbuf, '#') + 1,
strrchr(numbuf, '#') + 1);
}
{NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#" {
canonicalizeNumeral (numbuf, yytext);
- return processInt (numbuf, strchr (numbuf, '#') + 1, NULL);
+ return processInt (pstate, numbuf, strchr (numbuf, '#') + 1,
+ NULL);
}
"0x"{HEXDIG}+ {
canonicalizeNumeral (numbuf, yytext+2);
- return processInt ("16#", numbuf, NULL);
+ return processInt (pstate, "16#", numbuf, NULL);
}
{NUM10}"."{NUM10}{EXP} {
canonicalizeNumeral (numbuf, yytext);
- return processReal (numbuf);
+ return processReal (pstate, numbuf);
}
{NUM10}"."{NUM10} {
canonicalizeNumeral (numbuf, yytext);
- return processReal (numbuf);
+ return processReal (pstate, numbuf);
}
{NUM10}"#"{NUM16}"."{NUM16}"#"{EXP} {
@@ -132,14 +148,14 @@ static int find_dot_all (const char *);
}
"'"({GRAPHIC}|\")"'" {
- yylval.typed_val.type = type_char ();
+ yylval.typed_val.type = type_char (pstate);
yylval.typed_val.val = yytext[1];
return CHARLIT;
}
"'[\""{HEXDIG}{2}"\"]'" {
int v;
- yylval.typed_val.type = type_char ();
+ yylval.typed_val.type = type_char (pstate);
sscanf (yytext+3, "%2x", &v);
yylval.typed_val.val = v;
return CHARLIT;
@@ -156,9 +172,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 {
+ rewind_to_char ('t');
+ return 0;
+ }
+
+thread{WHITE}+{DIG} {
+ /* This keyword signals the end of the expression and
+ will be processed separately. */
+ rewind_to_char ('t');
return 0;
}
@@ -190,7 +216,7 @@ false { return FALSEKEYWORD; }
/* ATTRIBUTES */
-{TICK}[a-zA-Z][a-zA-Z]+ { return processAttribute (yytext+1); }
+{TICK}[a-zA-Z][a-zA-Z_]+ { BEGIN INITIAL; return processAttribute (yytext+1); }
/* PUNCTUATION */
@@ -206,10 +232,9 @@ false { return FALSEKEYWORD; }
[-&*+./:<>=|;\[\]] { return yytext[0]; }
-"," { if (paren_depth == 0 && comma_terminates)
+"," { if (paren_depth == 0 && pstate->comma_terminates)
{
- lexptr -= 1;
- yyrestart(NULL);
+ rewind_to_char (',');
return 0;
}
else
@@ -219,8 +244,7 @@ false { return FALSEKEYWORD; }
"(" { paren_depth += 1; return '('; }
")" { if (paren_depth == 0)
{
- lexptr -= 1;
- yyrestart(NULL);
+ rewind_to_char (')');
return 0;
}
else
@@ -269,7 +293,7 @@ false { return FALSEKEYWORD; }
"$"({LETTER}|{DIG}|"$")* {
yylval.sval.ptr = yytext;
yylval.sval.length = yyleng;
- return SPECIAL_VARIABLE;
+ return DOLLAR_VARIABLE;
}
/* CATCH-ALL ERROR CASE */
@@ -278,14 +302,13 @@ false { return FALSEKEYWORD; }
%%
#include
-#include "gdb_string.h"
-
/* Initialize the lexer for processing new expression. */
-void
+static void
lexer_init (FILE *inp)
{
BEGIN INITIAL;
+ paren_depth = 0;
yyrestart (inp);
}
@@ -314,13 +337,13 @@ canonicalizeNumeral (char *s1, const char *s2)
*/
static int
-processInt (const char *base0, const char *num0, const char *exp0)
+processInt (struct parser_state *par_state, const char *base0,
+ const char *num0, const char *exp0)
{
ULONGEST result;
long exp;
int base;
-
- char *trailer;
+ const char *trailer;
if (base0 == NULL)
base = 10;
@@ -337,7 +360,7 @@ processInt (const char *base0, const char *num0, const char *exp0)
exp = strtol(exp0, (char **) NULL, 10);
errno = 0;
- result = strtoulst (num0, (const char **) &trailer, base);
+ result = strtoulst (num0, &trailer, base);
if (errno == ERANGE)
error (_("Integer literal out of range"));
if (isxdigit(*trailer))
@@ -351,11 +374,11 @@ processInt (const char *base0, const char *num0, const char *exp0)
exp -= 1;
}
- if ((result >> (gdbarch_int_bit (current_gdbarch)-1)) == 0)
- yylval.typed_val.type = type_int ();
- else if ((result >> (gdbarch_long_bit (current_gdbarch)-1)) == 0)
- yylval.typed_val.type = type_long ();
- else if (((result >> (gdbarch_long_bit (current_gdbarch)-1)) >> 1) == 0)
+ if ((result >> (gdbarch_int_bit (par_state->gdbarch ())-1)) == 0)
+ yylval.typed_val.type = type_int (par_state);
+ else if ((result >> (gdbarch_long_bit (par_state->gdbarch ())-1)) == 0)
+ yylval.typed_val.type = type_long (par_state);
+ else if (((result >> (gdbarch_long_bit (par_state->gdbarch ())-1)) >> 1) == 0)
{
/* We have a number representable as an unsigned integer quantity.
For consistency with the C treatment, we will treat it as an
@@ -364,7 +387,8 @@ processInt (const char *base0, const char *num0, const char *exp0)
for the mess, but C doesn't officially guarantee that a simple
assignment does the trick (no, it doesn't; read the reference manual).
*/
- yylval.typed_val.type = builtin_type_unsigned_long;
+ yylval.typed_val.type
+ = builtin_type (par_state->gdbarch ())->builtin_unsigned_long;
if (result & LONGEST_SIGN)
yylval.typed_val.val =
(LONGEST) (result & ~LONGEST_SIGN)
@@ -374,37 +398,34 @@ processInt (const char *base0, const char *num0, const char *exp0)
return INT;
}
else
- yylval.typed_val.type = type_long_long ();
+ yylval.typed_val.type = type_long_long (par_state);
yylval.typed_val.val = (LONGEST) result;
return INT;
}
static int
-processReal (const char *num0)
+processReal (struct parser_state *par_state, const char *num0)
{
- sscanf (num0, "%" DOUBLEST_SCAN_FORMAT, &yylval.typed_val_float.dval);
-
- yylval.typed_val_float.type = type_float ();
- if (sizeof(DOUBLEST) >= gdbarch_double_bit (current_gdbarch)
- / TARGET_CHAR_BIT)
- yylval.typed_val_float.type = type_double ();
- if (sizeof(DOUBLEST) >= gdbarch_long_double_bit (current_gdbarch)
- / TARGET_CHAR_BIT)
- yylval.typed_val_float.type = type_long_double ();
+ yylval.typed_val_float.type = type_long_double (par_state);
+ bool parsed = parse_float (num0, strlen (num0),
+ yylval.typed_val_float.type,
+ yylval.typed_val_float.val);
+ gdb_assert (parsed);
return FLOAT;
}
/* Store a canonicalized version of NAME0[0..LEN-1] in yylval.ssym. The
- resulting string is valid until the next call to ada_parse. It differs
+ resulting string is valid until the next call to ada_parse. If
+ NAME0 contains the substring "___", it is assumed to be already
+ encoded and the resulting name is equal to it. Similarly, if the name
+ starts with '<', it is copied verbatim. Otherwise, it differs
from NAME0 in that:
- + Characters between '...' or <...> are transfered verbatim to
- yylval.ssym.
- + <, >, and trailing "'" characters in quoted sequences are removed
- (a leading quote is preserved to indicate that the name is not to be
- GNAT-encoded).
+ + Characters between '...' are transfered verbatim to yylval.ssym.
+ + Trailing "'" characters in quoted sequences are removed (a leading quote is
+ preserved to indicate that the name is not to be GNAT-encoded).
+ Unquoted whitespace is removed.
+ Unquoted alphabetic characters are mapped to lower case.
Result is returned as a struct stoken, but for convenience, the string
@@ -414,12 +435,22 @@ processReal (const char *num0)
static struct stoken
processId (const char *name0, int len)
{
- char *name = obstack_alloc (&temp_parse_space, len + 11);
+ char *name = (char *) obstack_alloc (&temp_parse_space, len + 11);
int i0, i;
struct stoken result;
+ result.ptr = name;
while (len > 0 && isspace (name0[len-1]))
len -= 1;
+
+ if (name0[0] == '<' || strstr (name0, "___") != NULL)
+ {
+ strncpy (name, name0, len);
+ name[len] = '\000';
+ result.length = len;
+ return result;
+ }
+
i = i0 = 0;
while (i0 < len)
{
@@ -446,20 +477,10 @@ processId (const char *name0, int len)
while (i0 < len && name0[i0] != '\'');
i0 += 1;
break;
- case '<':
- i0 += 1;
- while (i0 < len && name0[i0] != '>')
- {
- name[i] = name0[i0];
- i += 1; i0 += 1;
- }
- i0 += 1;
- break;
}
}
name[i] = '\000';
- result.ptr = name;
result.length = i;
return result;
}
@@ -476,7 +497,8 @@ processString (const char *text, int len)
const char *lim = text + len;
struct stoken result;
- q = result.ptr = obstack_alloc (&temp_parse_space, len);
+ q = (char *) obstack_alloc (&temp_parse_space, len);
+ result.ptr = q;
p = text;
while (p < lim)
{
@@ -515,19 +537,20 @@ static int
find_dot_all (const char *str)
{
int i;
- for (i = 0; str[i] != '\000'; i += 1)
- {
- if (str[i] == '.')
- {
- int i0 = i;
- do
- i += 1;
- while (isspace (str[i]));
- if (strncmp (str+i, "all", 3) == 0
- && ! isalnum (str[i+3]) && str[i+3] != '_')
- return i0;
- }
- }
+
+ for (i = 0; str[i] != '\000'; i++)
+ if (str[i] == '.')
+ {
+ int i0 = i;
+
+ do
+ i += 1;
+ while (isspace (str[i]));
+
+ if (strncasecmp (str + i, "all", 3) == 0
+ && !isalnum (str[i + 3]) && str[i + 3] != '_')
+ return i0;
+ }
return -1;
}
@@ -594,10 +617,21 @@ processAttribute (const char *str)
return attributes[k].code;
}
-int
-yywrap(void)
+/* 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)
{
- return 1;
+ pstate->lexptr -= yyleng;
+ while (toupper (*pstate->lexptr) != toupper (ch))
+ pstate->lexptr -= 1;
+ yyrestart (NULL);
}
/* Dummy definition to suppress warnings about unused static definitions. */
@@ -606,3 +640,5 @@ dummy_function ada_flex_use[] =
{
(dummy_function) yyunput
};
+
+DIAGNOSTIC_POP