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