1/* FLEX lexer for Ada expressions, for GDB.
2   Copyright (C) 1994, 1997, 1998, 2000, 2001, 2002, 2003
3   Free Software Foundation, Inc.
4
5This file is part of GDB.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, 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
29DIG	[0-9]
30NUM10	({DIG}({DIG}|_)*)
31HEXDIG	[0-9a-f]
32NUM16	({HEXDIG}({HEXDIG}|_)*)
33OCTDIG	[0-7]
34LETTER	[a-z_]
35ID	({LETTER}({LETTER}|{DIG})*|"<"{LETTER}({LETTER}|{DIG})*">")
36WHITE	[ \t\n]
37TICK	("'"{WHITE}*)
38GRAPHIC [a-z0-9 #&'()*+,-./:;<>=_|!$%?@\[\]\\^`{}~]
39OPER    ([-+*/=<>&]|"<="|">="|"**"|"/="|"and"|"or"|"xor"|"not"|"mod"|"rem"|"abs")
40
41EXP	(e[+-]{NUM10})
42POSEXP  (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.  */
50static char numbuf[NUMERAL_WIDTH];
51 static void canonicalizeNumeral (char *s1, const char *);
52static int processInt (const char *, const char *, const char *);
53static int processReal (const char *);
54static int processId (const char *, int);
55static int processAttribute (const char *);
56static 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
72static char *tempbuf = NULL;
73static int tempbufsize = 0;
74static int tempbuf_len;
75static struct block *left_block_context;
76
77static void resize_tempbuf (unsigned int);
78
79static void block_lookup (char *, char *);
80
81static int name_lookup (char *, char *, int *, int);
82
83static 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
189if		{
190		  while (*lexptr != 'i' && *lexptr != 'I')
191		    lexptr -= 1;
192		  yyrestart(NULL);
193		  return 0;
194		}
195
196	/* ADA KEYWORDS */
197
198abs		{ return ABS; }
199and		{ return _AND_; }
200else		{ return ELSE; }
201in		{ return IN; }
202mod		{ return MOD; }
203new		{ return NEW; }
204not		{ return NOT; }
205null		{ return NULL_PTR; }
206or		{ return OR; }
207rem		{ return REM; }
208then		{ return THEN; }
209xor		{ 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 */
332void
333lexer_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
342static void
343resize_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
354static void
355canonicalizeNumeral (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
373static int
374is_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
384static int
385digit_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.  */
394ULONGEST
395strtoulst (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
437static int
438processInt (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
511static int
512processReal (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
534static int
535processId (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
587static void
588block_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
630static int
631name_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.  */
834static int
835find_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
857static int
858subseqMatch (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
871static struct { const char *name; int code; }
872attributes[] = {
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
894static int
895processAttribute (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
917int
918yywrap(void)
919{
920  return 1;
921}
922
923/* Dummy definition to suppress warnings about unused static definitions. */
924typedef void (*dummy_function) ();
925dummy_function ada_flex_use[] =
926{
927  (dummy_function) yyunput
928};
929