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