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