2003-11-23 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / ada-lex.l
1 /* 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 <INITIAL>"'"({GRAPHIC}|\")"'" {
144 yylval.typed_val.type = builtin_type_ada_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 = 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 <INITIAL>\" {
160 tempbuf_len = 0;
161 BEGIN IN_STRING;
162 }
163
164 <IN_STRING>{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 <IN_STRING>{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 <IN_STRING>{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 <BEFORE_QUAL_QUOTE>"'" { 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 <ctype.h>
345 #include <string.h>
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_DOMAIN, &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_DOMAIN,
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_DOMAIN, &syms, &blocks);
689 else
690 nsyms = ada_lookup_symbol_list (name, left_block_context,
691 VAR_DOMAIN, &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 && DEPRECATED_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 }
This page took 0.049646 seconds and 5 git commands to generate.