Address complaints from gdb_ari.sh:
[deliverable/binutils-gdb.git] / gdb / ada-lex.l
1 /* FLEX lexer for Ada expressions, for GDB.
2 Copyright (C) 1994, 1997, 1998, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
4
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 2 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, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 /*----------------------------------------------------------------------*/
22
23 /* The converted version of this file is to be included in ada-exp.y, */
24 /* the Ada parser for gdb. The function yylex obtains characters from */
25 /* the global pointer lexptr. It returns a syntactic category for */
26 /* each successive token and places a semantic value into yylval */
27 /* (ada-lval), defined by the parser. */
28
29 /* Run flex with (at least) the -i option (case-insensitive), and the -I */
30 /* option (interactive---no unnecessary lookahead). */
31
32 DIG [0-9]
33 NUM10 ({DIG}({DIG}|_)*)
34 HEXDIG [0-9a-f]
35 NUM16 ({HEXDIG}({HEXDIG}|_)*)
36 OCTDIG [0-7]
37 LETTER [a-z_]
38 ID ({LETTER}({LETTER}|{DIG})*|"<"{LETTER}({LETTER}|{DIG})*">")
39 WHITE [ \t\n]
40 TICK ("'"{WHITE}*)
41 GRAPHIC [a-z0-9 #&'()*+,-./:;<>=_|!$%?@\[\]\\^`{}~]
42 OPER ([-+*/=<>&]|"<="|">="|"**"|"/="|"and"|"or"|"xor"|"not"|"mod"|"rem"|"abs")
43
44 EXP (e[+-]{NUM10})
45 POSEXP (e"+"?{NUM10})
46
47 %{
48 #define malloc xmalloc
49 #define free xfree
50
51 #define NUMERAL_WIDTH 256
52 #define LONGEST_SIGN ((ULONGEST) 1 << (sizeof(LONGEST) * HOST_CHAR_BIT - 1))
53
54 /* Temporary staging for numeric literals. */
55 static char numbuf[NUMERAL_WIDTH];
56 static void canonicalizeNumeral (char *s1, const char *);
57 static int processInt (const char *, const char *, const char *);
58 static int processReal (const char *);
59 static int processId (const char *, int);
60 static int processAttribute (const char *);
61 static int find_dot_all (const char *);
62
63 #undef YY_DECL
64 #define YY_DECL static int yylex ( void )
65
66 #undef YY_INPUT
67 #define YY_INPUT(BUF, RESULT, MAX_SIZE) \
68 if ( *lexptr == '\000' ) \
69 (RESULT) = YY_NULL; \
70 else \
71 { \
72 *(BUF) = *lexptr; \
73 (RESULT) = 1; \
74 lexptr += 1; \
75 }
76
77 static char *tempbuf = NULL;
78 static int tempbufsize = 0;
79 static int tempbuf_len;
80 static struct block *left_block_context;
81
82 static void resize_tempbuf (unsigned int);
83
84 static void block_lookup (char *, char *);
85
86 static int name_lookup (char *, char *, int *, int);
87
88 static int find_dot_all (const char *);
89
90 %}
91
92 %s IN_STRING BEFORE_QUAL_QUOTE
93
94 %%
95
96 {WHITE} { }
97
98 "--".* { yyterminate(); }
99
100 {NUM10}{POSEXP} {
101 canonicalizeNumeral (numbuf, yytext);
102 return processInt (NULL, numbuf, strrchr(numbuf, 'e')+1);
103 }
104
105 {NUM10} {
106 canonicalizeNumeral (numbuf, yytext);
107 return processInt (NULL, numbuf, NULL);
108 }
109
110 {NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#"{POSEXP} {
111 canonicalizeNumeral (numbuf, yytext);
112 return processInt (numbuf,
113 strchr (numbuf, '#') + 1,
114 strrchr(numbuf, '#') + 1);
115 }
116
117 {NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#" {
118 canonicalizeNumeral (numbuf, yytext);
119 return processInt (numbuf, strchr (numbuf, '#') + 1, NULL);
120 }
121
122 "0x"{HEXDIG}+ {
123 canonicalizeNumeral (numbuf, yytext+2);
124 return processInt ("16#", numbuf, NULL);
125 }
126
127
128 {NUM10}"."{NUM10}{EXP} {
129 canonicalizeNumeral (numbuf, yytext);
130 return processReal (numbuf);
131 }
132
133 {NUM10}"."{NUM10} {
134 canonicalizeNumeral (numbuf, yytext);
135 return processReal (numbuf);
136 }
137
138 {NUM10}"#"{NUM16}"."{NUM16}"#"{EXP} {
139 error ("Based real literals not implemented yet.");
140 }
141
142 {NUM10}"#"{NUM16}"."{NUM16}"#" {
143 error ("Based real literals not implemented yet.");
144 }
145
146 <INITIAL>"'"({GRAPHIC}|\")"'" {
147 yylval.typed_val.type = builtin_type_ada_char;
148 yylval.typed_val.val = yytext[1];
149 return CHARLIT;
150 }
151
152 <INITIAL>"'[\""{HEXDIG}{2}"\"]'" {
153 int v;
154 yylval.typed_val.type = builtin_type_ada_char;
155 sscanf (yytext+3, "%2x", &v);
156 yylval.typed_val.val = v;
157 return CHARLIT;
158 }
159
160 \"{OPER}\"/{WHITE}*"(" { return processId (yytext, yyleng); }
161
162 <INITIAL>\" {
163 tempbuf_len = 0;
164 BEGIN IN_STRING;
165 }
166
167 <IN_STRING>{GRAPHIC}*\" {
168 resize_tempbuf (yyleng+tempbuf_len);
169 strncpy (tempbuf+tempbuf_len, yytext, yyleng-1);
170 tempbuf_len += yyleng-1;
171 yylval.sval.ptr = tempbuf;
172 yylval.sval.length = tempbuf_len;
173 BEGIN INITIAL;
174 return STRING;
175 }
176
177 <IN_STRING>{GRAPHIC}*"[\""{HEXDIG}{2}"\"]" {
178 int n;
179 resize_tempbuf (yyleng-5+tempbuf_len+1);
180 strncpy (tempbuf+tempbuf_len, yytext, yyleng-6);
181 sscanf(yytext+yyleng-4, "%2x", &n);
182 tempbuf[yyleng-6+tempbuf_len] = (char) n;
183 tempbuf_len += yyleng-5;
184 }
185
186 <IN_STRING>{GRAPHIC}*"[\"\"\"]" {
187 int n;
188 resize_tempbuf (yyleng-4+tempbuf_len+1);
189 strncpy (tempbuf+tempbuf_len, yytext, yyleng-6);
190 tempbuf[yyleng-5+tempbuf_len] = '"';
191 tempbuf_len += yyleng-4;
192 }
193
194 if {
195 while (*lexptr != 'i' && *lexptr != 'I')
196 lexptr -= 1;
197 yyrestart(NULL);
198 return 0;
199 }
200
201 /* ADA KEYWORDS */
202
203 abs { return ABS; }
204 and { return _AND_; }
205 else { return ELSE; }
206 in { return IN; }
207 mod { return MOD; }
208 new { return NEW; }
209 not { return NOT; }
210 null { return NULL_PTR; }
211 or { return OR; }
212 rem { return REM; }
213 then { return THEN; }
214 xor { return XOR; }
215
216 /* ATTRIBUTES */
217
218 {TICK}[a-zA-Z][a-zA-Z]+ { return processAttribute (yytext+1); }
219
220 /* PUNCTUATION */
221
222 "=>" { return ARROW; }
223 ".." { return DOTDOT; }
224 "**" { return STARSTAR; }
225 ":=" { return ASSIGN; }
226 "/=" { return NOTEQUAL; }
227 "<=" { return LEQ; }
228 ">=" { return GEQ; }
229
230 <BEFORE_QUAL_QUOTE>"'" { BEGIN INITIAL; return '\''; }
231
232 [-&*+./:<>=|;\[\]] { return yytext[0]; }
233
234 "," { if (paren_depth == 0 && comma_terminates)
235 {
236 lexptr -= 1;
237 yyrestart(NULL);
238 return 0;
239 }
240 else
241 return ',';
242 }
243
244 "(" { paren_depth += 1; return '('; }
245 ")" { if (paren_depth == 0)
246 {
247 lexptr -= 1;
248 yyrestart(NULL);
249 return 0;
250 }
251 else
252 {
253 paren_depth -= 1;
254 return ')';
255 }
256 }
257
258 "."{WHITE}*all { return DOT_ALL; }
259
260 "."{WHITE}*{ID} {
261 processId (yytext+1, yyleng-1);
262 return DOT_ID;
263 }
264
265 {ID}({WHITE}*"."{WHITE}*({ID}|\"{OPER}\"))*(" "*"'")? {
266 int all_posn = find_dot_all (yytext);
267 int token_type, segments, k;
268 int quote_follows;
269
270 if (all_posn == -1 && yytext[yyleng-1] == '\'')
271 {
272 quote_follows = 1;
273 do {
274 yyless (yyleng-1);
275 } while (yytext[yyleng-1] == ' ');
276 }
277 else
278 quote_follows = 0;
279
280 if (all_posn >= 0)
281 yyless (all_posn);
282 processId(yytext, yyleng);
283 segments = name_lookup (ada_encode (yylval.ssym.stoken.ptr),
284 yylval.ssym.stoken.ptr,
285 &token_type,
286 MAX_RENAMING_CHAIN_LENGTH);
287 left_block_context = NULL;
288 for (k = yyleng; segments > 0 && k > 0; k -= 1)
289 {
290 if (yytext[k-1] == '.')
291 segments -= 1;
292 quote_follows = 0;
293 }
294 if (k <= 0)
295 error ("confused by name %s", yytext);
296 yyless (k);
297 if (quote_follows)
298 BEGIN BEFORE_QUAL_QUOTE;
299 return token_type;
300 }
301
302 /* GDB EXPRESSION CONSTRUCTS */
303
304
305 "'"[^']+"'"{WHITE}*:: {
306 processId(yytext, yyleng-2);
307 block_lookup (yylval.ssym.stoken.ptr, yylval.ssym.stoken.ptr);
308 return BLOCKNAME;
309 }
310
311 {ID}({WHITE}*"."{WHITE}*({ID}|\"{OPER}\"))*{WHITE}*:: {
312 processId(yytext, yyleng-2);
313 block_lookup (ada_encode (yylval.ssym.stoken.ptr),
314 yylval.ssym.stoken.ptr);
315 return BLOCKNAME;
316 }
317
318 [{}@] { return yytext[0]; }
319
320 /* REGISTERS AND GDB CONVENIENCE VARIABLES */
321
322 "$"({LETTER}|{DIG}|"$")* {
323 yylval.sval.ptr = yytext;
324 yylval.sval.length = yyleng;
325 return SPECIAL_VARIABLE;
326 }
327
328 /* CATCH-ALL ERROR CASE */
329
330 . { error ("Invalid character '%s' in expression.", yytext); }
331 %%
332
333 #include <ctype.h>
334 #include "gdb_string.h"
335
336 /* Initialize the lexer for processing new expression */
337 void
338 lexer_init (FILE *inp)
339 {
340 BEGIN INITIAL;
341 yyrestart (inp);
342 }
343
344
345 /* Make sure that tempbuf points at an array at least N characters long. */
346
347 static void
348 resize_tempbuf (unsigned int n)
349 {
350 if (tempbufsize < n)
351 {
352 tempbufsize = (n+63) & ~63;
353 tempbuf = (char *) xrealloc (tempbuf, tempbufsize);
354 }
355 }
356
357 /* Copy S2 to S1, removing all underscores, and downcasing all letters. */
358
359 static void
360 canonicalizeNumeral (char *s1, const char *s2)
361 {
362 for (; *s2 != '\000'; s2 += 1)
363 {
364 if (*s2 != '_')
365 {
366 *s1 = tolower(*s2);
367 s1 += 1;
368 }
369 }
370 s1[0] = '\000';
371 }
372
373 #define HIGH_BYTE_POSN ((sizeof (ULONGEST) - 1) * HOST_CHAR_BIT)
374
375 /* True (non-zero) iff DIGIT is a valid digit in radix BASE,
376 where 2 <= BASE <= 16. */
377
378 static int
379 is_digit_in_base (unsigned char digit, int base)
380 {
381 if (!isxdigit (digit))
382 return 0;
383 if (base <= 10)
384 return (isdigit (digit) && digit < base + '0');
385 else
386 return (isdigit (digit) || tolower (digit) < base - 10 + 'a');
387 }
388
389 static int
390 digit_to_int (unsigned char c)
391 {
392 if (isdigit (c))
393 return c - '0';
394 else
395 return tolower (c) - 'a' + 10;
396 }
397
398 /* As for strtoul, but for ULONGEST results. */
399 ULONGEST
400 strtoulst (const char *num, const char **trailer, int base)
401 {
402 unsigned int high_part;
403 ULONGEST result;
404 int i;
405 unsigned char lim;
406
407 if (base < 2 || base > 16)
408 {
409 errno = EINVAL;
410 return 0;
411 }
412 lim = base - 1 + '0';
413
414 result = high_part = 0;
415 for (i = 0; is_digit_in_base (num[i], base); i += 1)
416 {
417 result = result*base + digit_to_int (num[i]);
418 high_part = high_part*base + (unsigned int) (result >> HIGH_BYTE_POSN);
419 result &= ((ULONGEST) 1 << HIGH_BYTE_POSN) - 1;
420 if (high_part > 0xff)
421 {
422 errno = ERANGE;
423 result = high_part = 0;
424 break;
425 }
426 }
427
428 if (trailer != NULL)
429 *trailer = &num[i];
430
431 return result + ((ULONGEST) high_part << HIGH_BYTE_POSN);
432 }
433
434
435
436 /* Interprets the prefix of NUM that consists of digits of the given BASE
437 as an integer of that BASE, with the string EXP as an exponent.
438 Puts value in yylval, and returns INT, if the string is valid. Causes
439 an error if the number is improperly formated. BASE, if NULL, defaults
440 to "10", and EXP to "1". The EXP does not contain a leading 'e' or 'E'. */
441
442 static int
443 processInt (const char *base0, const char *num0, const char *exp0)
444 {
445 ULONGEST result;
446 long exp;
447 int base;
448
449 char *trailer;
450
451 if (base0 == NULL)
452 base = 10;
453 else
454 {
455 base = strtol (base0, (char **) NULL, 10);
456 if (base < 2 || base > 16)
457 error ("Invalid base: %d.", base);
458 }
459
460 if (exp0 == NULL)
461 exp = 0;
462 else
463 exp = strtol(exp0, (char **) NULL, 10);
464
465 errno = 0;
466 result = strtoulst (num0, (const char **) &trailer, base);
467 if (errno == ERANGE)
468 error ("Integer literal out of range");
469 if (isxdigit(*trailer))
470 error ("Invalid digit `%c' in based literal", *trailer);
471
472 while (exp > 0)
473 {
474 if (result > (ULONG_MAX / base))
475 error ("Integer literal out of range");
476 result *= base;
477 exp -= 1;
478 }
479
480 if ((result >> (TARGET_INT_BIT-1)) == 0)
481 yylval.typed_val.type = builtin_type_ada_int;
482 else if ((result >> (TARGET_LONG_BIT-1)) == 0)
483 yylval.typed_val.type = builtin_type_ada_long;
484 else if (((result >> (TARGET_LONG_BIT-1)) >> 1) == 0)
485 {
486 /* We have a number representable as an unsigned integer quantity.
487 For consistency with the C treatment, we will treat it as an
488 anonymous modular (unsigned) quantity. Alas, the types are such
489 that we need to store .val as a signed quantity. Sorry
490 for the mess, but C doesn't officially guarantee that a simple
491 assignment does the trick (no, it doesn't; read the reference manual).
492 */
493 yylval.typed_val.type = builtin_type_unsigned_long;
494 if (result & LONGEST_SIGN)
495 yylval.typed_val.val =
496 (LONGEST) (result & ~LONGEST_SIGN)
497 - (LONGEST_SIGN>>1) - (LONGEST_SIGN>>1);
498 else
499 yylval.typed_val.val = (LONGEST) result;
500 return INT;
501 }
502 else
503 yylval.typed_val.type = builtin_type_ada_long_long;
504
505 yylval.typed_val.val = (LONGEST) result;
506 return INT;
507 }
508
509 #if defined (PRINTF_HAS_LONG_DOUBLE)
510 # undef PRINTF_HAS_LONG_DOUBLE
511 # define PRINTF_HAS_LONG_DOUBLE 1
512 #else
513 # define PRINTF_HAS_LONG_DOUBLE 0
514 #endif
515
516 static int
517 processReal (const char *num0)
518 {
519 #if defined (PRINTF_HAS_LONG_DOUBLE)
520 if (sizeof (DOUBLEST) > sizeof (double))
521 sscanf (num0, "%Lg", &yylval.typed_val_float.dval);
522 else
523 #endif
524 {
525 double temp;
526 sscanf (num0, "%lg", &temp);
527 yylval.typed_val_float.dval = temp;
528 }
529
530 yylval.typed_val_float.type = builtin_type_ada_float;
531 if (sizeof(DOUBLEST) >= TARGET_DOUBLE_BIT / TARGET_CHAR_BIT)
532 yylval.typed_val_float.type = builtin_type_ada_double;
533 if (sizeof(DOUBLEST) >= TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT)
534 yylval.typed_val_float.type = builtin_type_ada_long_double;
535
536 return FLOAT;
537 }
538
539 static int
540 processId (const char *name0, int len)
541 {
542 char *name = obstack_alloc (&temp_parse_space, len + 11);
543 int i0, i;
544
545 while (len > 0 && isspace (name0[len-1]))
546 len -= 1;
547 i = i0 = 0;
548 while (i0 < len)
549 {
550 if (isalnum (name0[i0]))
551 {
552 name[i] = tolower (name0[i0]);
553 i += 1; i0 += 1;
554 }
555 else switch (name0[i0])
556 {
557 default:
558 name[i] = name0[i0];
559 i += 1; i0 += 1;
560 break;
561 case ' ': case '\t':
562 i0 += 1;
563 break;
564 case '\'':
565 i0 += 1;
566 while (i0 < len && name0[i0] != '\'')
567 {
568 name[i] = name0[i0];
569 i += 1; i0 += 1;
570 }
571 i0 += 1;
572 break;
573 case '<':
574 i0 += 1;
575 while (i0 < len && name0[i0] != '>')
576 {
577 name[i] = name0[i0];
578 i += 1; i0 += 1;
579 }
580 i0 += 1;
581 break;
582 }
583 }
584 name[i] = '\000';
585
586 yylval.ssym.sym = NULL;
587 yylval.ssym.stoken.ptr = name;
588 yylval.ssym.stoken.length = i;
589 return NAME;
590 }
591
592 static void
593 block_lookup (char *name, char *err_name)
594 {
595 struct ada_symbol_info *syms;
596 int nsyms;
597 struct symtab *symtab;
598 nsyms = ada_lookup_symbol_list (name, left_block_context,
599 VAR_DOMAIN, &syms);
600 if (left_block_context == NULL &&
601 (nsyms == 0 || SYMBOL_CLASS (syms[0].sym) != LOC_BLOCK))
602 symtab = lookup_symtab (name);
603 else
604 symtab = NULL;
605
606 if (symtab != NULL)
607 left_block_context = yylval.bval =
608 BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
609 else if (nsyms == 0 || SYMBOL_CLASS (syms[0].sym) != LOC_BLOCK)
610 {
611 if (left_block_context == NULL)
612 error ("No file or function \"%s\".", err_name);
613 else
614 error ("No function \"%s\" in specified context.", err_name);
615 }
616 else
617 {
618 left_block_context = yylval.bval = SYMBOL_BLOCK_VALUE (syms[0].sym);
619 if (nsyms > 1)
620 warning ("Function name \"%s\" ambiguous here", err_name);
621 }
622 }
623
624 /* Look up NAME0 (assumed to be encoded) as a name in VAR_DOMAIN,
625 setting *TOKEN_TYPE to NAME or TYPENAME, depending on what is
626 found. Try first the entire name, then the name without the last
627 segment (i.e., after the last .id), etc., and return the number of
628 segments that had to be removed to get a match. Try only the full
629 name if it starts with "standard__". Calls error if no
630 matches are found, using ERR_NAME in any error message. When
631 exactly one symbol match is found, it is placed in yylval. When
632 the symbol is a renaming, follow at most DEPTH steps to find the
633 ultimate definition; cause error if depth exceeded. */
634
635 static int
636 name_lookup (char *name0, char *err_name, int *token_type, int depth)
637 {
638 struct ada_symbol_info *syms;
639 struct type *type;
640 int len0 = strlen (name0);
641 char *name = obsavestring (name0, len0, &temp_parse_space);
642 int nsyms;
643 int segments;
644
645 if (depth <= 0)
646 error ("Could not find renamed symbol \"%s\"", err_name);
647
648 yylval.ssym.stoken.ptr = name;
649 yylval.ssym.stoken.length = strlen (name);
650 for (segments = 0; ; segments += 1)
651 {
652 struct type *preferred_type;
653 int i, preferred_index;
654
655 if (left_block_context == NULL)
656 nsyms = ada_lookup_symbol_list (name, expression_context_block,
657 VAR_DOMAIN, &syms);
658 else
659 nsyms = ada_lookup_symbol_list (name, left_block_context,
660 VAR_DOMAIN, &syms);
661
662
663 /* Check for a type renaming. */
664
665 if (nsyms == 1 && !ada_is_object_renaming (syms[0].sym))
666 {
667 struct symbol *renaming_sym =
668 ada_find_renaming_symbol (SYMBOL_LINKAGE_NAME (syms[0].sym),
669 syms[0].block);
670
671 if (renaming_sym != NULL)
672 syms[0].sym = renaming_sym;
673 }
674
675 /* Check for a type definition. */
676
677 /* Look for a symbol that doesn't denote void. This is (I think) a */
678 /* temporary kludge to get around problems in GNAT output. */
679 preferred_index = -1; preferred_type = NULL;
680 for (i = 0; i < nsyms; i += 1)
681 switch (SYMBOL_CLASS (syms[i].sym))
682 {
683 case LOC_TYPEDEF:
684 if (ada_prefer_type (SYMBOL_TYPE (syms[i].sym), preferred_type))
685 {
686 preferred_index = i;
687 preferred_type = SYMBOL_TYPE (syms[i].sym);
688 }
689 break;
690 case LOC_REGISTER:
691 case LOC_ARG:
692 case LOC_REF_ARG:
693 case LOC_REGPARM:
694 case LOC_REGPARM_ADDR:
695 case LOC_LOCAL:
696 case LOC_LOCAL_ARG:
697 case LOC_BASEREG:
698 case LOC_BASEREG_ARG:
699 case LOC_COMPUTED:
700 case LOC_COMPUTED_ARG:
701 goto NotType;
702 default:
703 break;
704 }
705 if (preferred_type != NULL)
706 {
707 if (TYPE_CODE (preferred_type) == TYPE_CODE_VOID)
708 error ("`%s' matches only void type name(s)",
709 ada_decode (name));
710 else if (ada_is_object_renaming (syms[preferred_index].sym))
711 {
712 yylval.ssym.sym = syms[preferred_index].sym;
713 *token_type = OBJECT_RENAMING;
714 return segments;
715 }
716 else if (ada_renaming_type (SYMBOL_TYPE (syms[preferred_index].sym))
717 != NULL)
718 {
719 int result;
720 char *renaming
721 = ada_simple_renamed_entity (syms[preferred_index].sym);
722 char *new_name
723 = (char *) obstack_alloc (&temp_parse_space,
724 strlen (renaming) + len0
725 - yylval.ssym.stoken.length + 1);
726 strcpy (new_name, renaming);
727 xfree (renaming);
728 strcat (new_name, name0 + yylval.ssym.stoken.length);
729 result = name_lookup (new_name, err_name, token_type, depth - 1);
730 if (result > segments)
731 error ("Confused by renamed symbol.");
732 return result;
733 }
734 else if (segments == 0)
735 {
736 yylval.tval = preferred_type;
737 *token_type = TYPENAME;
738 return 0;
739 }
740 }
741
742 if (segments == 0)
743 {
744 type = lookup_primitive_typename (name);
745 if (type == NULL && strcmp ("system__address", name) == 0)
746 type = builtin_type_ada_system_address;
747 if (type != NULL)
748 {
749 /* First check to see if we have a regular definition of this
750 type that just didn't happen to have been read yet. */
751 int ntypes;
752 struct symbol *sym;
753 char *expanded_name =
754 (char *) alloca (strlen (name) + sizeof ("standard__"));
755 strcpy (expanded_name, "standard__");
756 strcat (expanded_name, name);
757 sym = ada_lookup_symbol (expanded_name, NULL,
758 VAR_DOMAIN, NULL, NULL);
759 if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
760 type = SYMBOL_TYPE (sym);
761
762 yylval.tval = type;
763 *token_type = TYPENAME;
764 return 0;
765 }
766 }
767
768 NotType:
769 if (nsyms == 1)
770 {
771 *token_type = NAME;
772 yylval.ssym.sym = syms[0].sym;
773 yylval.ssym.msym = NULL;
774 yylval.ssym.block = syms[0].block;
775 return segments;
776 }
777 else if (nsyms == 0) {
778 int i;
779 yylval.ssym.msym = ada_lookup_simple_minsym (name);
780 if (yylval.ssym.msym != NULL)
781 {
782 yylval.ssym.sym = NULL;
783 yylval.ssym.block = NULL;
784 *token_type = NAME;
785 return segments;
786 }
787
788 if (segments == 0
789 && strncmp (name, "standard__", sizeof ("standard__") - 1) == 0)
790 error ("No definition of \"%s\" found.", err_name);
791
792 for (i = yylval.ssym.stoken.length - 1; i > 0; i -= 1)
793 {
794 if (name[i] == '.')
795 {
796 name[i] = '\0';
797 yylval.ssym.stoken.length = i;
798 break;
799 }
800 else if (name[i] == '_' && name[i-1] == '_')
801 {
802 i -= 1;
803 name[i] = '\0';
804 yylval.ssym.stoken.length = i;
805 break;
806 }
807 }
808 if (i <= 0)
809 {
810 if (!have_full_symbols () && !have_partial_symbols ()
811 && left_block_context == NULL)
812 error ("No symbol table is loaded. Use the \"file\" command.");
813 if (left_block_context == NULL)
814 error ("No definition of \"%s\" in current context.",
815 err_name);
816 else
817 error ("No definition of \"%s\" in specified context.",
818 err_name);
819 }
820 }
821 else
822 {
823 *token_type = NAME;
824 yylval.ssym.sym = NULL;
825 yylval.ssym.msym = NULL;
826 if (left_block_context == NULL)
827 yylval.ssym.block = expression_context_block;
828 else
829 yylval.ssym.block = left_block_context;
830 return segments;
831 }
832 }
833 }
834
835 /* Returns the position within STR of the '.' in a
836 '.{WHITE}*all' component of a dotted name, or -1 if there is none. */
837 static int
838 find_dot_all (const char *str)
839 {
840 int i;
841 for (i = 0; str[i] != '\000'; i += 1)
842 {
843 if (str[i] == '.')
844 {
845 int i0 = i;
846 do
847 i += 1;
848 while (isspace (str[i]));
849 if (strcmp (str+i, "all") == 0
850 && ! isalnum (str[i+3]) && str[i+3] != '_')
851 return i0;
852 }
853 }
854 return -1;
855 }
856
857 /* Returns non-zero iff string SUBSEQ matches a subsequence of STR, ignoring
858 case. */
859
860 static int
861 subseqMatch (const char *subseq, const char *str)
862 {
863 if (subseq[0] == '\0')
864 return 1;
865 else if (str[0] == '\0')
866 return 0;
867 else if (tolower (subseq[0]) == tolower (str[0]))
868 return subseqMatch (subseq+1, str+1) || subseqMatch (subseq, str+1);
869 else
870 return subseqMatch (subseq, str+1);
871 }
872
873
874 static struct { const char *name; int code; }
875 attributes[] = {
876 { "address", TICK_ADDRESS },
877 { "unchecked_access", TICK_ACCESS },
878 { "unrestricted_access", TICK_ACCESS },
879 { "access", TICK_ACCESS },
880 { "first", TICK_FIRST },
881 { "last", TICK_LAST },
882 { "length", TICK_LENGTH },
883 { "max", TICK_MAX },
884 { "min", TICK_MIN },
885 { "modulus", TICK_MODULUS },
886 { "pos", TICK_POS },
887 { "range", TICK_RANGE },
888 { "size", TICK_SIZE },
889 { "tag", TICK_TAG },
890 { "val", TICK_VAL },
891 { NULL, -1 }
892 };
893
894 /* Return the syntactic code corresponding to the attribute name or
895 abbreviation STR. */
896
897 static int
898 processAttribute (const char *str)
899 {
900 int i, k;
901
902 for (i = 0; attributes[i].code != -1; i += 1)
903 if (strcasecmp (str, attributes[i].name) == 0)
904 return attributes[i].code;
905
906 for (i = 0, k = -1; attributes[i].code != -1; i += 1)
907 if (subseqMatch (str, attributes[i].name))
908 {
909 if (k == -1)
910 k = i;
911 else
912 error ("ambiguous attribute name: `%s'", str);
913 }
914 if (k == -1)
915 error ("unrecognized attribute: `%s'", str);
916
917 return attributes[k].code;
918 }
919
920 int
921 yywrap(void)
922 {
923 return 1;
924 }
This page took 0.112721 seconds and 5 git commands to generate.