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