]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ada-lex.l
Fix break *FUN'address task NUM.
[thirdparty/binutils-gdb.git] / gdb / ada-lex.l
CommitLineData
14f9c5c9 1/* FLEX lexer for Ada expressions, for GDB.
0fb0cc75 2 Copyright (C) 1994, 1997, 1998, 2000, 2001, 2002, 2003, 2007, 2008, 2009
14f9c5c9
AS
3 Free Software Foundation, Inc.
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
70575d34
JB
163task {
164 while (*lexptr != 't' && *lexptr != 'T')
165 lexptr--;
166 yyrestart(NULL);
167 return 0;
168 }
169
14f9c5c9
AS
170 /* ADA KEYWORDS */
171
172abs { return ABS; }
173and { return _AND_; }
174else { return ELSE; }
175in { return IN; }
176mod { return MOD; }
177new { return NEW; }
178not { return NOT; }
179null { return NULL_PTR; }
180or { return OR; }
52ce6436 181others { return OTHERS; }
14f9c5c9
AS
182rem { return REM; }
183then { return THEN; }
184xor { return XOR; }
185
690cc4eb
PH
186 /* BOOLEAN "KEYWORDS" */
187
188 /* True and False are not keywords in Ada, but rather enumeration constants.
189 However, the boolean type is no longer represented as an enum, so True
190 and False are no longer defined in symbol tables. We compromise by
191 making them keywords (when bare). */
192
193true { return TRUEKEYWORD; }
194false { return FALSEKEYWORD; }
195
14f9c5c9
AS
196 /* ATTRIBUTES */
197
198{TICK}[a-zA-Z][a-zA-Z]+ { return processAttribute (yytext+1); }
199
200 /* PUNCTUATION */
201
202"=>" { return ARROW; }
203".." { return DOTDOT; }
204"**" { return STARSTAR; }
205":=" { return ASSIGN; }
206"/=" { return NOTEQUAL; }
207"<=" { return LEQ; }
208">=" { return GEQ; }
209
210<BEFORE_QUAL_QUOTE>"'" { BEGIN INITIAL; return '\''; }
211
212[-&*+./:<>=|;\[\]] { return yytext[0]; }
213
214"," { if (paren_depth == 0 && comma_terminates)
215 {
216 lexptr -= 1;
217 yyrestart(NULL);
218 return 0;
219 }
4c4b4cd2 220 else
14f9c5c9
AS
221 return ',';
222 }
223
224"(" { paren_depth += 1; return '('; }
4c4b4cd2 225")" { if (paren_depth == 0)
14f9c5c9
AS
226 {
227 lexptr -= 1;
228 yyrestart(NULL);
229 return 0;
230 }
4c4b4cd2 231 else
14f9c5c9 232 {
4c4b4cd2 233 paren_depth -= 1;
14f9c5c9
AS
234 return ')';
235 }
236 }
237
238"."{WHITE}*all { return DOT_ALL; }
239
4c4b4cd2 240"."{WHITE}*{ID} {
52ce6436 241 yylval.sval = processId (yytext+1, yyleng-1);
4c4b4cd2 242 return DOT_ID;
14f9c5c9
AS
243 }
244
4c4b4cd2 245{ID}({WHITE}*"."{WHITE}*({ID}|\"{OPER}\"))*(" "*"'")? {
14f9c5c9 246 int all_posn = find_dot_all (yytext);
14f9c5c9 247
4c4b4cd2 248 if (all_posn == -1 && yytext[yyleng-1] == '\'')
14f9c5c9 249 {
52ce6436
PH
250 BEGIN BEFORE_QUAL_QUOTE;
251 yyless (yyleng-1);
14f9c5c9 252 }
52ce6436 253 else if (all_posn >= 0)
14f9c5c9 254 yyless (all_posn);
52ce6436
PH
255 yylval.sval = processId (yytext, yyleng);
256 return NAME;
257 }
14f9c5c9 258
14f9c5c9 259
52ce6436 260 /* GDB EXPRESSION CONSTRUCTS */
14f9c5c9
AS
261
262"'"[^']+"'"{WHITE}*:: {
52ce6436
PH
263 yyless (yyleng - 2);
264 yylval.sval = processId (yytext, yyleng);
265 return NAME;
14f9c5c9
AS
266 }
267
52ce6436 268"::" { return COLONCOLON; }
14f9c5c9
AS
269
270[{}@] { return yytext[0]; }
271
14f9c5c9
AS
272 /* REGISTERS AND GDB CONVENIENCE VARIABLES */
273
4c4b4cd2 274"$"({LETTER}|{DIG}|"$")* {
14f9c5c9
AS
275 yylval.sval.ptr = yytext;
276 yylval.sval.length = yyleng;
4c4b4cd2 277 return SPECIAL_VARIABLE;
14f9c5c9
AS
278 }
279
280 /* CATCH-ALL ERROR CASE */
281
e1d5a0d2 282. { error (_("Invalid character '%s' in expression."), yytext); }
14f9c5c9
AS
283%%
284
285#include <ctype.h>
19c1ef65 286#include "gdb_string.h"
14f9c5c9 287
52ce6436
PH
288/* Initialize the lexer for processing new expression. */
289
14f9c5c9 290void
4c4b4cd2 291lexer_init (FILE *inp)
14f9c5c9
AS
292{
293 BEGIN INITIAL;
294 yyrestart (inp);
295}
296
297
4c4b4cd2 298/* Copy S2 to S1, removing all underscores, and downcasing all letters. */
14f9c5c9
AS
299
300static void
4c4b4cd2 301canonicalizeNumeral (char *s1, const char *s2)
14f9c5c9 302{
4c4b4cd2 303 for (; *s2 != '\000'; s2 += 1)
14f9c5c9
AS
304 {
305 if (*s2 != '_')
306 {
307 *s1 = tolower(*s2);
308 s1 += 1;
309 }
310 }
311 s1[0] = '\000';
312}
313
14f9c5c9
AS
314/* Interprets the prefix of NUM that consists of digits of the given BASE
315 as an integer of that BASE, with the string EXP as an exponent.
316 Puts value in yylval, and returns INT, if the string is valid. Causes
4c4b4cd2 317 an error if the number is improperly formated. BASE, if NULL, defaults
52ce6436
PH
318 to "10", and EXP to "1". The EXP does not contain a leading 'e' or 'E'.
319 */
14f9c5c9
AS
320
321static int
4c4b4cd2 322processInt (const char *base0, const char *num0, const char *exp0)
14f9c5c9
AS
323{
324 ULONGEST result;
325 long exp;
326 int base;
327
4c4b4cd2 328 char *trailer;
14f9c5c9
AS
329
330 if (base0 == NULL)
331 base = 10;
332 else
4c4b4cd2
PH
333 {
334 base = strtol (base0, (char **) NULL, 10);
14f9c5c9 335 if (base < 2 || base > 16)
e1d5a0d2 336 error (_("Invalid base: %d."), base);
14f9c5c9
AS
337 }
338
339 if (exp0 == NULL)
340 exp = 0;
341 else
4c4b4cd2 342 exp = strtol(exp0, (char **) NULL, 10);
14f9c5c9
AS
343
344 errno = 0;
4c4b4cd2 345 result = strtoulst (num0, (const char **) &trailer, base);
14f9c5c9 346 if (errno == ERANGE)
e1d5a0d2 347 error (_("Integer literal out of range"));
14f9c5c9 348 if (isxdigit(*trailer))
e1d5a0d2 349 error (_("Invalid digit `%c' in based literal"), *trailer);
14f9c5c9 350
4c4b4cd2 351 while (exp > 0)
14f9c5c9
AS
352 {
353 if (result > (ULONG_MAX / base))
e1d5a0d2 354 error (_("Integer literal out of range"));
14f9c5c9
AS
355 result *= base;
356 exp -= 1;
357 }
4c4b4cd2 358
3e79cecf 359 if ((result >> (gdbarch_int_bit (parse_gdbarch)-1)) == 0)
72d5681a 360 yylval.typed_val.type = type_int ();
3e79cecf 361 else if ((result >> (gdbarch_long_bit (parse_gdbarch)-1)) == 0)
72d5681a 362 yylval.typed_val.type = type_long ();
3e79cecf 363 else if (((result >> (gdbarch_long_bit (parse_gdbarch)-1)) >> 1) == 0)
14f9c5c9
AS
364 {
365 /* We have a number representable as an unsigned integer quantity.
4c4b4cd2 366 For consistency with the C treatment, we will treat it as an
14f9c5c9 367 anonymous modular (unsigned) quantity. Alas, the types are such
4c4b4cd2 368 that we need to store .val as a signed quantity. Sorry
14f9c5c9
AS
369 for the mess, but C doesn't officially guarantee that a simple
370 assignment does the trick (no, it doesn't; read the reference manual).
371 */
3e79cecf
UW
372 yylval.typed_val.type
373 = builtin_type (parse_gdbarch)->builtin_unsigned_long;
14f9c5c9 374 if (result & LONGEST_SIGN)
4c4b4cd2
PH
375 yylval.typed_val.val =
376 (LONGEST) (result & ~LONGEST_SIGN)
14f9c5c9
AS
377 - (LONGEST_SIGN>>1) - (LONGEST_SIGN>>1);
378 else
379 yylval.typed_val.val = (LONGEST) result;
380 return INT;
381 }
4c4b4cd2 382 else
72d5681a 383 yylval.typed_val.type = type_long_long ();
14f9c5c9
AS
384
385 yylval.typed_val.val = (LONGEST) result;
386 return INT;
387}
388
389static int
4c4b4cd2 390processReal (const char *num0)
14f9c5c9 391{
689e4e2d 392 sscanf (num0, "%" DOUBLEST_SCAN_FORMAT, &yylval.typed_val_float.dval);
14f9c5c9 393
72d5681a 394 yylval.typed_val_float.type = type_float ();
3e79cecf 395 if (sizeof(DOUBLEST) >= gdbarch_double_bit (parse_gdbarch)
ea06eb3d 396 / TARGET_CHAR_BIT)
72d5681a 397 yylval.typed_val_float.type = type_double ();
3e79cecf 398 if (sizeof(DOUBLEST) >= gdbarch_long_double_bit (parse_gdbarch)
ea06eb3d 399 / TARGET_CHAR_BIT)
72d5681a 400 yylval.typed_val_float.type = type_long_double ();
14f9c5c9
AS
401
402 return FLOAT;
403}
404
52ce6436
PH
405
406/* Store a canonicalized version of NAME0[0..LEN-1] in yylval.ssym. The
407 resulting string is valid until the next call to ada_parse. It differs
408 from NAME0 in that:
409 + Characters between '...' or <...> are transfered verbatim to
410 yylval.ssym.
411 + <, >, and trailing "'" characters in quoted sequences are removed
412 (a leading quote is preserved to indicate that the name is not to be
413 GNAT-encoded).
414 + Unquoted whitespace is removed.
415 + Unquoted alphabetic characters are mapped to lower case.
416 Result is returned as a struct stoken, but for convenience, the string
417 is also null-terminated. Result string valid until the next call of
418 ada_parse.
419 */
420static struct stoken
4c4b4cd2 421processId (const char *name0, int len)
14f9c5c9 422{
4c4b4cd2 423 char *name = obstack_alloc (&temp_parse_space, len + 11);
14f9c5c9 424 int i0, i;
52ce6436 425 struct stoken result;
4c4b4cd2 426
14f9c5c9
AS
427 while (len > 0 && isspace (name0[len-1]))
428 len -= 1;
429 i = i0 = 0;
4c4b4cd2 430 while (i0 < len)
14f9c5c9
AS
431 {
432 if (isalnum (name0[i0]))
433 {
434 name[i] = tolower (name0[i0]);
435 i += 1; i0 += 1;
436 }
4c4b4cd2 437 else switch (name0[i0])
14f9c5c9
AS
438 {
439 default:
440 name[i] = name0[i0];
441 i += 1; i0 += 1;
442 break;
443 case ' ': case '\t':
444 i0 += 1;
445 break;
446 case '\'':
52ce6436 447 do
14f9c5c9
AS
448 {
449 name[i] = name0[i0];
450 i += 1; i0 += 1;
451 }
52ce6436 452 while (i0 < len && name0[i0] != '\'');
14f9c5c9
AS
453 i0 += 1;
454 break;
455 case '<':
456 i0 += 1;
457 while (i0 < len && name0[i0] != '>')
458 {
459 name[i] = name0[i0];
460 i += 1; i0 += 1;
461 }
462 i0 += 1;
463 break;
464 }
465 }
466 name[i] = '\000';
467
52ce6436
PH
468 result.ptr = name;
469 result.length = i;
470 return result;
14f9c5c9
AS
471}
472
52ce6436
PH
473/* Return TEXT[0..LEN-1], a string literal without surrounding quotes,
474 with special hex character notations replaced with characters.
475 Result valid until the next call to ada_parse. */
14f9c5c9 476
52ce6436
PH
477static struct stoken
478processString (const char *text, int len)
14f9c5c9 479{
52ce6436
PH
480 const char *p;
481 char *q;
482 const char *lim = text + len;
483 struct stoken result;
484
485 q = result.ptr = obstack_alloc (&temp_parse_space, len);
486 p = text;
487 while (p < lim)
14f9c5c9 488 {
52ce6436
PH
489 if (p[0] == '[' && p[1] == '"' && p+2 < lim)
490 {
491 if (p[2] == '"') /* "...["""]... */
492 {
493 *q = '"';
494 p += 4;
495 }
496 else
497 {
498 int chr;
499 sscanf (p+2, "%2x", &chr);
500 *q = (char) chr;
501 p += 5;
502 }
503 }
504 else
505 *q = *p;
506 q += 1;
507 p += 1;
508 }
509 result.length = q - result.ptr;
510 return result;
14f9c5c9
AS
511}
512
513/* Returns the position within STR of the '.' in a
52ce6436
PH
514 '.{WHITE}*all' component of a dotted name, or -1 if there is none.
515 Note: we actually don't need this routine, since 'all' can never be an
516 Ada identifier. Thus, looking up foo.all or foo.all.x as a name
517 must fail, and will eventually be interpreted as (foo).all or
518 (foo).all.x. However, this does avoid an extraneous lookup. */
519
14f9c5c9 520static int
4c4b4cd2 521find_dot_all (const char *str)
14f9c5c9
AS
522{
523 int i;
524 for (i = 0; str[i] != '\000'; i += 1)
525 {
526 if (str[i] == '.')
527 {
528 int i0 = i;
4c4b4cd2 529 do
14f9c5c9
AS
530 i += 1;
531 while (isspace (str[i]));
52ce6436 532 if (strncmp (str+i, "all", 3) == 0
14f9c5c9
AS
533 && ! isalnum (str[i+3]) && str[i+3] != '_')
534 return i0;
535 }
536 }
537 return -1;
4c4b4cd2 538}
14f9c5c9
AS
539
540/* Returns non-zero iff string SUBSEQ matches a subsequence of STR, ignoring
4c4b4cd2 541 case. */
14f9c5c9
AS
542
543static int
4c4b4cd2 544subseqMatch (const char *subseq, const char *str)
14f9c5c9
AS
545{
546 if (subseq[0] == '\0')
547 return 1;
548 else if (str[0] == '\0')
549 return 0;
550 else if (tolower (subseq[0]) == tolower (str[0]))
551 return subseqMatch (subseq+1, str+1) || subseqMatch (subseq, str+1);
552 else
553 return subseqMatch (subseq, str+1);
554}
14f9c5c9 555
4c4b4cd2
PH
556
557static struct { const char *name; int code; }
14f9c5c9
AS
558attributes[] = {
559 { "address", TICK_ADDRESS },
560 { "unchecked_access", TICK_ACCESS },
561 { "unrestricted_access", TICK_ACCESS },
562 { "access", TICK_ACCESS },
563 { "first", TICK_FIRST },
564 { "last", TICK_LAST },
565 { "length", TICK_LENGTH },
566 { "max", TICK_MAX },
567 { "min", TICK_MIN },
568 { "modulus", TICK_MODULUS },
569 { "pos", TICK_POS },
570 { "range", TICK_RANGE },
571 { "size", TICK_SIZE },
572 { "tag", TICK_TAG },
573 { "val", TICK_VAL },
574 { NULL, -1 }
575};
576
577/* Return the syntactic code corresponding to the attribute name or
578 abbreviation STR. */
579
580static int
4c4b4cd2 581processAttribute (const char *str)
14f9c5c9
AS
582{
583 int i, k;
584
585 for (i = 0; attributes[i].code != -1; i += 1)
586 if (strcasecmp (str, attributes[i].name) == 0)
587 return attributes[i].code;
588
589 for (i = 0, k = -1; attributes[i].code != -1; i += 1)
4c4b4cd2 590 if (subseqMatch (str, attributes[i].name))
14f9c5c9
AS
591 {
592 if (k == -1)
593 k = i;
4c4b4cd2 594 else
e1d5a0d2 595 error (_("ambiguous attribute name: `%s'"), str);
14f9c5c9
AS
596 }
597 if (k == -1)
e1d5a0d2 598 error (_("unrecognized attribute: `%s'"), str);
14f9c5c9
AS
599
600 return attributes[k].code;
601}
602
603int
4c4b4cd2 604yywrap(void)
14f9c5c9
AS
605{
606 return 1;
607}
23485554
PH
608
609/* Dummy definition to suppress warnings about unused static definitions. */
610typedef void (*dummy_function) ();
611dummy_function ada_flex_use[] =
612{
375c0479 613 (dummy_function) yyunput
23485554 614};