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