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