]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ada-lex.l
Delete free_named_symtabs and associated cleanup.
[thirdparty/binutils-gdb.git] / gdb / ada-lex.l
CommitLineData
14f9c5c9 1/* FLEX lexer for Ada expressions, for GDB.
4c38e0a4
JB
2 Copyright (C) 1994, 1997, 1998, 2000, 2001, 2002, 2003, 2007, 2008, 2009,
3 2010 Free Software Foundation, Inc.
14f9c5c9 4
5b1ba0e5
NS
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
14f9c5c9
AS
19
20/*----------------------------------------------------------------------*/
21
22/* The converted version of this file is to be included in ada-exp.y, */
23/* the Ada parser for gdb. The function yylex obtains characters from */
24/* the global pointer lexptr. It returns a syntactic category for */
25/* each successive token and places a semantic value into yylval */
26/* (ada-lval), defined by the parser. */
27
14f9c5c9
AS
28DIG [0-9]
29NUM10 ({DIG}({DIG}|_)*)
30HEXDIG [0-9a-f]
31NUM16 ({HEXDIG}({HEXDIG}|_)*)
32OCTDIG [0-7]
33LETTER [a-z_]
34ID ({LETTER}({LETTER}|{DIG})*|"<"{LETTER}({LETTER}|{DIG})*">")
35WHITE [ \t\n]
36TICK ("'"{WHITE}*)
37GRAPHIC [a-z0-9 #&'()*+,-./:;<>=_|!$%?@\[\]\\^`{}~]
38OPER ([-+*/=<>&]|"<="|">="|"**"|"/="|"and"|"or"|"xor"|"not"|"mod"|"rem"|"abs")
39
40EXP (e[+-]{NUM10})
41POSEXP (e"+"?{NUM10})
42
43%{
4c4b4cd2 44
14f9c5c9
AS
45#define NUMERAL_WIDTH 256
46#define LONGEST_SIGN ((ULONGEST) 1 << (sizeof(LONGEST) * HOST_CHAR_BIT - 1))
47
4c4b4cd2
PH
48/* Temporary staging for numeric literals. */
49static char numbuf[NUMERAL_WIDTH];
50 static void canonicalizeNumeral (char *s1, const char *);
52ce6436 51static struct stoken processString (const char*, int);
4c4b4cd2
PH
52static int processInt (const char *, const char *, const char *);
53static int processReal (const char *);
52ce6436 54static struct stoken processId (const char *, int);
4c4b4cd2
PH
55static int processAttribute (const char *);
56static int find_dot_all (const char *);
14f9c5c9
AS
57
58#undef YY_DECL
4c4b4cd2 59#define YY_DECL static int yylex ( void )
14f9c5c9
AS
60
61#undef YY_INPUT
62#define YY_INPUT(BUF, RESULT, MAX_SIZE) \
63 if ( *lexptr == '\000' ) \
64 (RESULT) = YY_NULL; \
65 else \
66 { \
67 *(BUF) = *lexptr; \
68 (RESULT) = 1; \
69 lexptr += 1; \
70 }
71
4c4b4cd2 72static int find_dot_all (const char *);
14f9c5c9
AS
73
74%}
75
7dc1ef8d
PH
76%option case-insensitive interactive nodefault
77
52ce6436 78%s BEFORE_QUAL_QUOTE
14f9c5c9
AS
79
80%%
81
82{WHITE} { }
83
84"--".* { yyterminate(); }
85
4c4b4cd2
PH
86{NUM10}{POSEXP} {
87 canonicalizeNumeral (numbuf, yytext);
14f9c5c9
AS
88 return processInt (NULL, numbuf, strrchr(numbuf, 'e')+1);
89 }
90
4c4b4cd2
PH
91{NUM10} {
92 canonicalizeNumeral (numbuf, yytext);
14f9c5c9
AS
93 return processInt (NULL, numbuf, NULL);
94 }
95
96{NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#"{POSEXP} {
97 canonicalizeNumeral (numbuf, yytext);
98 return processInt (numbuf,
4c4b4cd2 99 strchr (numbuf, '#') + 1,
14f9c5c9
AS
100 strrchr(numbuf, '#') + 1);
101 }
102
103{NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#" {
104 canonicalizeNumeral (numbuf, yytext);
105 return processInt (numbuf, strchr (numbuf, '#') + 1, NULL);
106 }
107
108"0x"{HEXDIG}+ {
109 canonicalizeNumeral (numbuf, yytext+2);
110 return processInt ("16#", numbuf, NULL);
111 }
112
113
114{NUM10}"."{NUM10}{EXP} {
4c4b4cd2 115 canonicalizeNumeral (numbuf, yytext);
14f9c5c9
AS
116 return processReal (numbuf);
117 }
118
119{NUM10}"."{NUM10} {
4c4b4cd2 120 canonicalizeNumeral (numbuf, yytext);
14f9c5c9
AS
121 return processReal (numbuf);
122 }
123
124{NUM10}"#"{NUM16}"."{NUM16}"#"{EXP} {
e1d5a0d2 125 error (_("Based real literals not implemented yet."));
14f9c5c9
AS
126 }
127
128{NUM10}"#"{NUM16}"."{NUM16}"#" {
e1d5a0d2 129 error (_("Based real literals not implemented yet."));
14f9c5c9
AS
130 }
131
132<INITIAL>"'"({GRAPHIC}|\")"'" {
72d5681a 133 yylval.typed_val.type = type_char ();
14f9c5c9
AS
134 yylval.typed_val.val = yytext[1];
135 return CHARLIT;
136 }
137
138<INITIAL>"'[\""{HEXDIG}{2}"\"]'" {
139 int v;
72d5681a 140 yylval.typed_val.type = type_char ();
14f9c5c9
AS
141 sscanf (yytext+3, "%2x", &v);
142 yylval.typed_val.val = v;
143 return CHARLIT;
144 }
145
52ce6436
PH
146\"({GRAPHIC}|"[\""({HEXDIG}{2}|\")"\"]")*\" {
147 yylval.sval = processString (yytext+1, yyleng-2);
14f9c5c9
AS
148 return STRING;
149 }
150
52ce6436 151\" {
e1d5a0d2 152 error (_("ill-formed or non-terminated string literal"));
14f9c5c9
AS
153 }
154
14f9c5c9 155
4c4b4cd2
PH
156if {
157 while (*lexptr != 'i' && *lexptr != 'I')
158 lexptr -= 1;
159 yyrestart(NULL);
14f9c5c9
AS
160 return 0;
161 }
162
b9ee2233
JB
163(task|thread) {
164 /* This keyword signals the end of the expression and
165 will be processed separately. */
70575d34
JB
166 while (*lexptr != 't' && *lexptr != 'T')
167 lexptr--;
168 yyrestart(NULL);
169 return 0;
170 }
171
14f9c5c9
AS
172 /* ADA KEYWORDS */
173
174abs { return ABS; }
175and { return _AND_; }
176else { return ELSE; }
177in { return IN; }
178mod { return MOD; }
179new { return NEW; }
180not { return NOT; }
181null { return NULL_PTR; }
182or { return OR; }
52ce6436 183others { return OTHERS; }
14f9c5c9
AS
184rem { return REM; }
185then { return THEN; }
186xor { return XOR; }
187
690cc4eb
PH
188 /* BOOLEAN "KEYWORDS" */
189
190 /* True and False are not keywords in Ada, but rather enumeration constants.
191 However, the boolean type is no longer represented as an enum, so True
192 and False are no longer defined in symbol tables. We compromise by
193 making them keywords (when bare). */
194
195true { return TRUEKEYWORD; }
196false { return FALSEKEYWORD; }
197
14f9c5c9
AS
198 /* ATTRIBUTES */
199
200{TICK}[a-zA-Z][a-zA-Z]+ { return processAttribute (yytext+1); }
201
202 /* PUNCTUATION */
203
204"=>" { return ARROW; }
205".." { return DOTDOT; }
206"**" { return STARSTAR; }
207":=" { return ASSIGN; }
208"/=" { return NOTEQUAL; }
209"<=" { return LEQ; }
210">=" { return GEQ; }
211
212<BEFORE_QUAL_QUOTE>"'" { BEGIN INITIAL; return '\''; }
213
214[-&*+./:<>=|;\[\]] { return yytext[0]; }
215
216"," { if (paren_depth == 0 && comma_terminates)
217 {
218 lexptr -= 1;
219 yyrestart(NULL);
220 return 0;
221 }
4c4b4cd2 222 else
14f9c5c9
AS
223 return ',';
224 }
225
226"(" { paren_depth += 1; return '('; }
4c4b4cd2 227")" { if (paren_depth == 0)
14f9c5c9
AS
228 {
229 lexptr -= 1;
230 yyrestart(NULL);
231 return 0;
232 }
4c4b4cd2 233 else
14f9c5c9 234 {
4c4b4cd2 235 paren_depth -= 1;
14f9c5c9
AS
236 return ')';
237 }
238 }
239
240"."{WHITE}*all { return DOT_ALL; }
241
4c4b4cd2 242"."{WHITE}*{ID} {
52ce6436 243 yylval.sval = processId (yytext+1, yyleng-1);
4c4b4cd2 244 return DOT_ID;
14f9c5c9
AS
245 }
246
4c4b4cd2 247{ID}({WHITE}*"."{WHITE}*({ID}|\"{OPER}\"))*(" "*"'")? {
14f9c5c9 248 int all_posn = find_dot_all (yytext);
14f9c5c9 249
4c4b4cd2 250 if (all_posn == -1 && yytext[yyleng-1] == '\'')
14f9c5c9 251 {
52ce6436
PH
252 BEGIN BEFORE_QUAL_QUOTE;
253 yyless (yyleng-1);
14f9c5c9 254 }
52ce6436 255 else if (all_posn >= 0)
14f9c5c9 256 yyless (all_posn);
52ce6436
PH
257 yylval.sval = processId (yytext, yyleng);
258 return NAME;
259 }
14f9c5c9 260
14f9c5c9 261
52ce6436 262 /* GDB EXPRESSION CONSTRUCTS */
14f9c5c9
AS
263
264"'"[^']+"'"{WHITE}*:: {
52ce6436
PH
265 yyless (yyleng - 2);
266 yylval.sval = processId (yytext, yyleng);
267 return NAME;
14f9c5c9
AS
268 }
269
52ce6436 270"::" { return COLONCOLON; }
14f9c5c9
AS
271
272[{}@] { return yytext[0]; }
273
14f9c5c9
AS
274 /* REGISTERS AND GDB CONVENIENCE VARIABLES */
275
4c4b4cd2 276"$"({LETTER}|{DIG}|"$")* {
14f9c5c9
AS
277 yylval.sval.ptr = yytext;
278 yylval.sval.length = yyleng;
4c4b4cd2 279 return SPECIAL_VARIABLE;
14f9c5c9
AS
280 }
281
282 /* CATCH-ALL ERROR CASE */
283
e1d5a0d2 284. { error (_("Invalid character '%s' in expression."), yytext); }
14f9c5c9
AS
285%%
286
287#include <ctype.h>
19c1ef65 288#include "gdb_string.h"
14f9c5c9 289
52ce6436
PH
290/* Initialize the lexer for processing new expression. */
291
14f9c5c9 292void
4c4b4cd2 293lexer_init (FILE *inp)
14f9c5c9
AS
294{
295 BEGIN INITIAL;
296 yyrestart (inp);
297}
298
299
4c4b4cd2 300/* Copy S2 to S1, removing all underscores, and downcasing all letters. */
14f9c5c9
AS
301
302static void
4c4b4cd2 303canonicalizeNumeral (char *s1, const char *s2)
14f9c5c9 304{
4c4b4cd2 305 for (; *s2 != '\000'; s2 += 1)
14f9c5c9
AS
306 {
307 if (*s2 != '_')
308 {
309 *s1 = tolower(*s2);
310 s1 += 1;
311 }
312 }
313 s1[0] = '\000';
314}
315
14f9c5c9
AS
316/* Interprets the prefix of NUM that consists of digits of the given BASE
317 as an integer of that BASE, with the string EXP as an exponent.
318 Puts value in yylval, and returns INT, if the string is valid. Causes
4c4b4cd2 319 an error if the number is improperly formated. BASE, if NULL, defaults
52ce6436
PH
320 to "10", and EXP to "1". The EXP does not contain a leading 'e' or 'E'.
321 */
14f9c5c9
AS
322
323static int
4c4b4cd2 324processInt (const char *base0, const char *num0, const char *exp0)
14f9c5c9
AS
325{
326 ULONGEST result;
327 long exp;
328 int base;
329
4c4b4cd2 330 char *trailer;
14f9c5c9
AS
331
332 if (base0 == NULL)
333 base = 10;
334 else
4c4b4cd2
PH
335 {
336 base = strtol (base0, (char **) NULL, 10);
14f9c5c9 337 if (base < 2 || base > 16)
e1d5a0d2 338 error (_("Invalid base: %d."), base);
14f9c5c9
AS
339 }
340
341 if (exp0 == NULL)
342 exp = 0;
343 else
4c4b4cd2 344 exp = strtol(exp0, (char **) NULL, 10);
14f9c5c9
AS
345
346 errno = 0;
4c4b4cd2 347 result = strtoulst (num0, (const char **) &trailer, base);
14f9c5c9 348 if (errno == ERANGE)
e1d5a0d2 349 error (_("Integer literal out of range"));
14f9c5c9 350 if (isxdigit(*trailer))
e1d5a0d2 351 error (_("Invalid digit `%c' in based literal"), *trailer);
14f9c5c9 352
4c4b4cd2 353 while (exp > 0)
14f9c5c9
AS
354 {
355 if (result > (ULONG_MAX / base))
e1d5a0d2 356 error (_("Integer literal out of range"));
14f9c5c9
AS
357 result *= base;
358 exp -= 1;
359 }
4c4b4cd2 360
3e79cecf 361 if ((result >> (gdbarch_int_bit (parse_gdbarch)-1)) == 0)
72d5681a 362 yylval.typed_val.type = type_int ();
3e79cecf 363 else if ((result >> (gdbarch_long_bit (parse_gdbarch)-1)) == 0)
72d5681a 364 yylval.typed_val.type = type_long ();
3e79cecf 365 else if (((result >> (gdbarch_long_bit (parse_gdbarch)-1)) >> 1) == 0)
14f9c5c9
AS
366 {
367 /* We have a number representable as an unsigned integer quantity.
4c4b4cd2 368 For consistency with the C treatment, we will treat it as an
14f9c5c9 369 anonymous modular (unsigned) quantity. Alas, the types are such
4c4b4cd2 370 that we need to store .val as a signed quantity. Sorry
14f9c5c9
AS
371 for the mess, but C doesn't officially guarantee that a simple
372 assignment does the trick (no, it doesn't; read the reference manual).
373 */
3e79cecf
UW
374 yylval.typed_val.type
375 = builtin_type (parse_gdbarch)->builtin_unsigned_long;
14f9c5c9 376 if (result & LONGEST_SIGN)
4c4b4cd2
PH
377 yylval.typed_val.val =
378 (LONGEST) (result & ~LONGEST_SIGN)
14f9c5c9
AS
379 - (LONGEST_SIGN>>1) - (LONGEST_SIGN>>1);
380 else
381 yylval.typed_val.val = (LONGEST) result;
382 return INT;
383 }
4c4b4cd2 384 else
72d5681a 385 yylval.typed_val.type = type_long_long ();
14f9c5c9
AS
386
387 yylval.typed_val.val = (LONGEST) result;
388 return INT;
389}
390
391static int
4c4b4cd2 392processReal (const char *num0)
14f9c5c9 393{
689e4e2d 394 sscanf (num0, "%" DOUBLEST_SCAN_FORMAT, &yylval.typed_val_float.dval);
14f9c5c9 395
72d5681a 396 yylval.typed_val_float.type = type_float ();
3e79cecf 397 if (sizeof(DOUBLEST) >= gdbarch_double_bit (parse_gdbarch)
ea06eb3d 398 / TARGET_CHAR_BIT)
72d5681a 399 yylval.typed_val_float.type = type_double ();
3e79cecf 400 if (sizeof(DOUBLEST) >= gdbarch_long_double_bit (parse_gdbarch)
ea06eb3d 401 / TARGET_CHAR_BIT)
72d5681a 402 yylval.typed_val_float.type = type_long_double ();
14f9c5c9
AS
403
404 return FLOAT;
405}
406
52ce6436
PH
407
408/* Store a canonicalized version of NAME0[0..LEN-1] in yylval.ssym. The
409 resulting string is valid until the next call to ada_parse. It differs
410 from NAME0 in that:
411 + Characters between '...' or <...> are transfered verbatim to
412 yylval.ssym.
413 + <, >, and trailing "'" characters in quoted sequences are removed
414 (a leading quote is preserved to indicate that the name is not to be
415 GNAT-encoded).
416 + Unquoted whitespace is removed.
417 + Unquoted alphabetic characters are mapped to lower case.
418 Result is returned as a struct stoken, but for convenience, the string
419 is also null-terminated. Result string valid until the next call of
420 ada_parse.
421 */
422static struct stoken
4c4b4cd2 423processId (const char *name0, int len)
14f9c5c9 424{
4c4b4cd2 425 char *name = obstack_alloc (&temp_parse_space, len + 11);
14f9c5c9 426 int i0, i;
52ce6436 427 struct stoken result;
4c4b4cd2 428
14f9c5c9
AS
429 while (len > 0 && isspace (name0[len-1]))
430 len -= 1;
431 i = i0 = 0;
4c4b4cd2 432 while (i0 < len)
14f9c5c9
AS
433 {
434 if (isalnum (name0[i0]))
435 {
436 name[i] = tolower (name0[i0]);
437 i += 1; i0 += 1;
438 }
4c4b4cd2 439 else switch (name0[i0])
14f9c5c9
AS
440 {
441 default:
442 name[i] = name0[i0];
443 i += 1; i0 += 1;
444 break;
445 case ' ': case '\t':
446 i0 += 1;
447 break;
448 case '\'':
52ce6436 449 do
14f9c5c9
AS
450 {
451 name[i] = name0[i0];
452 i += 1; i0 += 1;
453 }
52ce6436 454 while (i0 < len && name0[i0] != '\'');
14f9c5c9
AS
455 i0 += 1;
456 break;
457 case '<':
458 i0 += 1;
459 while (i0 < len && name0[i0] != '>')
460 {
461 name[i] = name0[i0];
462 i += 1; i0 += 1;
463 }
464 i0 += 1;
465 break;
466 }
467 }
468 name[i] = '\000';
469
52ce6436
PH
470 result.ptr = name;
471 result.length = i;
472 return result;
14f9c5c9
AS
473}
474
52ce6436
PH
475/* Return TEXT[0..LEN-1], a string literal without surrounding quotes,
476 with special hex character notations replaced with characters.
477 Result valid until the next call to ada_parse. */
14f9c5c9 478
52ce6436
PH
479static struct stoken
480processString (const char *text, int len)
14f9c5c9 481{
52ce6436
PH
482 const char *p;
483 char *q;
484 const char *lim = text + len;
485 struct stoken result;
486
487 q = result.ptr = obstack_alloc (&temp_parse_space, len);
488 p = text;
489 while (p < lim)
14f9c5c9 490 {
52ce6436
PH
491 if (p[0] == '[' && p[1] == '"' && p+2 < lim)
492 {
493 if (p[2] == '"') /* "...["""]... */
494 {
495 *q = '"';
496 p += 4;
497 }
498 else
499 {
500 int chr;
501 sscanf (p+2, "%2x", &chr);
502 *q = (char) chr;
503 p += 5;
504 }
505 }
506 else
507 *q = *p;
508 q += 1;
509 p += 1;
510 }
511 result.length = q - result.ptr;
512 return result;
14f9c5c9
AS
513}
514
515/* Returns the position within STR of the '.' in a
52ce6436
PH
516 '.{WHITE}*all' component of a dotted name, or -1 if there is none.
517 Note: we actually don't need this routine, since 'all' can never be an
518 Ada identifier. Thus, looking up foo.all or foo.all.x as a name
519 must fail, and will eventually be interpreted as (foo).all or
520 (foo).all.x. However, this does avoid an extraneous lookup. */
521
14f9c5c9 522static int
4c4b4cd2 523find_dot_all (const char *str)
14f9c5c9
AS
524{
525 int i;
526 for (i = 0; str[i] != '\000'; i += 1)
527 {
528 if (str[i] == '.')
529 {
530 int i0 = i;
4c4b4cd2 531 do
14f9c5c9
AS
532 i += 1;
533 while (isspace (str[i]));
52ce6436 534 if (strncmp (str+i, "all", 3) == 0
14f9c5c9
AS
535 && ! isalnum (str[i+3]) && str[i+3] != '_')
536 return i0;
537 }
538 }
539 return -1;
4c4b4cd2 540}
14f9c5c9
AS
541
542/* Returns non-zero iff string SUBSEQ matches a subsequence of STR, ignoring
4c4b4cd2 543 case. */
14f9c5c9
AS
544
545static int
4c4b4cd2 546subseqMatch (const char *subseq, const char *str)
14f9c5c9
AS
547{
548 if (subseq[0] == '\0')
549 return 1;
550 else if (str[0] == '\0')
551 return 0;
552 else if (tolower (subseq[0]) == tolower (str[0]))
553 return subseqMatch (subseq+1, str+1) || subseqMatch (subseq, str+1);
554 else
555 return subseqMatch (subseq, str+1);
556}
14f9c5c9 557
4c4b4cd2
PH
558
559static struct { const char *name; int code; }
14f9c5c9
AS
560attributes[] = {
561 { "address", TICK_ADDRESS },
562 { "unchecked_access", TICK_ACCESS },
563 { "unrestricted_access", TICK_ACCESS },
564 { "access", TICK_ACCESS },
565 { "first", TICK_FIRST },
566 { "last", TICK_LAST },
567 { "length", TICK_LENGTH },
568 { "max", TICK_MAX },
569 { "min", TICK_MIN },
570 { "modulus", TICK_MODULUS },
571 { "pos", TICK_POS },
572 { "range", TICK_RANGE },
573 { "size", TICK_SIZE },
574 { "tag", TICK_TAG },
575 { "val", TICK_VAL },
576 { NULL, -1 }
577};
578
579/* Return the syntactic code corresponding to the attribute name or
580 abbreviation STR. */
581
582static int
4c4b4cd2 583processAttribute (const char *str)
14f9c5c9
AS
584{
585 int i, k;
586
587 for (i = 0; attributes[i].code != -1; i += 1)
588 if (strcasecmp (str, attributes[i].name) == 0)
589 return attributes[i].code;
590
591 for (i = 0, k = -1; attributes[i].code != -1; i += 1)
4c4b4cd2 592 if (subseqMatch (str, attributes[i].name))
14f9c5c9
AS
593 {
594 if (k == -1)
595 k = i;
4c4b4cd2 596 else
e1d5a0d2 597 error (_("ambiguous attribute name: `%s'"), str);
14f9c5c9
AS
598 }
599 if (k == -1)
e1d5a0d2 600 error (_("unrecognized attribute: `%s'"), str);
14f9c5c9
AS
601
602 return attributes[k].code;
603}
604
605int
4c4b4cd2 606yywrap(void)
14f9c5c9
AS
607{
608 return 1;
609}
23485554
PH
610
611/* Dummy definition to suppress warnings about unused static definitions. */
612typedef void (*dummy_function) ();
613dummy_function ada_flex_use[] =
614{
375c0479 615 (dummy_function) yyunput
23485554 616};