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