OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [ada-lex.l] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.