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