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