1 /* FLEX lexer for Ada expressions, for GDB.
2 Copyright (C) 1994, 1997, 2000
3 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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. */
21 /*----------------------------------------------------------------------*/
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. */
29 /* Run flex with (at least) the -i option (case-insensitive), and the -I */
30 /* option (interactive---no unnecessary lookahead). */
33 NUM10 ({DIG}({DIG}|_)*)
35 NUM16 ({HEXDIG}({HEXDIG}|_)*)
38 ID ({LETTER}({LETTER}|{DIG})*|"<"{LETTER}({LETTER}|{DIG})*">")
41 GRAPHIC [a-z0-9 #&'()*+,-./:;<>=_|!$%?@\[\]\\^`{}~]
42 OPER ([-+*/=<>&]|"<="|">="|"**"|"/="|"and"|"or"|"xor"|"not"|"mod"|"rem"|"abs")
48 #define NUMERAL_WIDTH 256
49 #define LONGEST_SIGN ((ULONGEST) 1 << (sizeof(LONGEST) * HOST_CHAR_BIT - 1))
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*);
61 #define YY_DECL static int yylex ( void )
64 #define YY_INPUT(BUF, RESULT, MAX_SIZE) \
65 if ( *lexptr == '\000' ) \
74 static char *tempbuf = NULL;
75 static int tempbufsize = 0;
76 static int tempbuf_len;
77 static struct block* left_block_context;
79 static void resize_tempbuf (unsigned int);
81 static void block_lookup (char*, char*);
83 static int name_lookup (char*, char*, int*);
85 static int find_dot_all (const char*);
89 %s IN_STRING BEFORE_QUAL_QUOTE
95 "--".* { yyterminate(); }
98 canonicalizeNumeral (numbuf, yytext);
99 return processInt (NULL, numbuf, strrchr(numbuf, 'e')+1);
103 canonicalizeNumeral (numbuf, yytext);
104 return processInt (NULL, numbuf, NULL);
107 {NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#"{POSEXP} {
108 canonicalizeNumeral (numbuf, yytext);
109 return processInt (numbuf,
110 strchr (numbuf, '#') + 1,
111 strrchr(numbuf, '#') + 1);
114 {NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#" {
115 canonicalizeNumeral (numbuf, yytext);
116 return processInt (numbuf, strchr (numbuf, '#') + 1, NULL);
120 canonicalizeNumeral (numbuf, yytext+2);
121 return processInt ("16#", numbuf, NULL);
125 {NUM10}"."{NUM10}{EXP} {
126 canonicalizeNumeral (numbuf, yytext);
127 return processReal (numbuf);
131 canonicalizeNumeral (numbuf, yytext);
132 return processReal (numbuf);
135 {NUM10}"#"{NUM16}"."{NUM16}"#"{EXP} {
136 error ("Based real literals not implemented yet.");
139 {NUM10}"#"{NUM16}"."{NUM16}"#" {
140 error ("Based real literals not implemented yet.");
143 <INITIAL>"'"({GRAPHIC}|\")"'" {
144 yylval.typed_val.type = builtin_type_ada_char;
145 yylval.typed_val.val = yytext[1];
149 <INITIAL>"'[\""{HEXDIG}{2}"\"]'" {
151 yylval.typed_val.type = builtin_type_ada_char;
152 sscanf (yytext+3, "%2x", &v);
153 yylval.typed_val.val = v;
157 \"{OPER}\"/{WHITE}*"(" { return processId (yytext, yyleng); }
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;
174 <IN_STRING>{GRAPHIC}*"[\""{HEXDIG}{2}"\"]" {
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;
183 <IN_STRING>{GRAPHIC}*"[\"\"\"]" {
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;
192 while (*lexptr != 'i' && *lexptr != 'I')
201 and { return _AND_; }
202 else { return ELSE; }
207 null { return NULL_PTR; }
210 then { return THEN; }
215 {TICK}[a-zA-Z][a-zA-Z]+ { return processAttribute (yytext+1); }
219 "=>" { return ARROW; }
220 ".." { return DOTDOT; }
221 "**" { return STARSTAR; }
222 ":=" { return ASSIGN; }
223 "/=" { return NOTEQUAL; }
227 <BEFORE_QUAL_QUOTE>"'" { BEGIN INITIAL; return '\''; }
229 [-&*+./:<>=|;\[\]] { return yytext[0]; }
231 "," { if (paren_depth == 0 && comma_terminates)
241 "(" { paren_depth += 1; return '('; }
242 ")" { if (paren_depth == 0)
255 "."{WHITE}*all { return DOT_ALL; }
258 processId (yytext+1, yyleng-1);
262 {ID}({WHITE}*"."{WHITE}*({ID}|\"{OPER}\"))*(" "*"'")? {
263 int all_posn = find_dot_all (yytext);
264 int token_type, segments, k;
267 if (all_posn == -1 && yytext[yyleng-1] == '\'')
272 } while (yytext[yyleng-1] == ' ');
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)
285 if (yytext[k-1] == '.')
290 error ("confused by name %s", yytext);
293 BEGIN BEFORE_QUAL_QUOTE;
297 /* GDB EXPRESSION CONSTRUCTS */
300 "'"[^']+"'"{WHITE}*:: {
301 processId(yytext, yyleng-2);
302 block_lookup (yylval.ssym.stoken.ptr, yylval.ssym.stoken.ptr);
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);
313 [{}@] { return yytext[0]; }
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; }
321 /* REGISTERS AND GDB CONVENIENCE VARIABLES */
323 "$"({LETTER}|{DIG}|"$")+ {
325 for (c = 0; c < NUM_REGS; c++)
326 if (REGISTER_NAME (c) &&
327 strcmp (yytext + 1, REGISTER_NAME (c)) == 0)
332 yylval.sval.ptr = yytext;
333 yylval.sval.length = yyleng;
335 lookup_internalvar (copy_name (yylval.sval) + 1);
336 return INTERNAL_VARIABLE;
339 /* CATCH-ALL ERROR CASE */
341 . { error ("Invalid character '%s' in expression.", yytext); }
347 /* Initialize the lexer for processing new expression */
349 lexer_init (FILE* inp)
356 /* Make sure that tempbuf points at an array at least N characters long. */
364 tempbufsize = (n+63) & ~63;
365 tempbuf = (char*) xrealloc (tempbuf, tempbufsize);
369 /* Copy S2 to S1, removing all underscores, and downcasing all letters. */
372 canonicalizeNumeral (s1,s2)
376 for (; *s2 != '\000'; s2 += 1)
387 #define HIGH_BYTE_POSN ((sizeof (ULONGEST) - 1) * HOST_CHAR_BIT)
389 /* True (non-zero) iff DIGIT is a valid digit in radix BASE,
390 where 2 <= BASE <= 16. */
393 is_digit_in_base (digit, base)
397 if (!isxdigit (digit))
400 return (isdigit (digit) && digit < base + '0');
402 return (isdigit (digit) || tolower (digit) < base - 10 + 'a');
412 return tolower (c) - 'a' + 10;
415 /* As for strtoul, but for ULONGEST results. */
417 strtoulst (num, trailer, base)
419 const char **trailer;
422 unsigned int high_part;
427 if (base < 2 || base > 16)
432 lim = base - 1 + '0';
434 result = high_part = 0;
435 for (i = 0; is_digit_in_base (num[i], base); i += 1)
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)
443 result = high_part = 0;
451 return result + ((ULONGEST) high_part << HIGH_BYTE_POSN);
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'. */
463 processInt (base0, num0, exp0)
478 base = strtol (base0, (char**) NULL, 10);
479 if (base < 2 || base > 16)
480 error ("Invalid base: %d.", base);
486 exp = strtol(exp0, (char**) NULL, 10);
489 result = strtoulst (num0, &trailer, base);
491 error ("Integer literal out of range");
492 if (isxdigit(*trailer))
493 error ("Invalid digit `%c' in based literal", *trailer);
497 if (result > (ULONG_MAX / base))
498 error ("Integer literal out of range");
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)
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).
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);
522 yylval.typed_val.val = (LONGEST) result;
526 yylval.typed_val.type = builtin_type_ada_long_long;
528 yylval.typed_val.val = (LONGEST) result;
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);
542 #ifdef PRINTF_HAS_LONG_DOUBLE
543 sscanf (num0, "%Lg", &yylval.typed_val_float.dval);
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. */
549 sscanf (num0, "%lg", &temp);
550 yylval.typed_val_float.dval = temp;
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;
564 processId (name0, len)
568 char* name = xmalloc (len + 11);
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]))
578 if (isalnum (name0[i0]))
580 name[i] = tolower (name0[i0]);
583 else switch (name0[i0])
594 while (i0 < len && name0[i0] != '\'')
603 while (i0 < len && name0[i0] != '>')
614 yylval.ssym.sym = NULL;
615 yylval.ssym.stoken.ptr = name;
616 yylval.ssym.stoken.length = i;
621 block_lookup (name, err_name)
625 struct symbol** syms;
626 struct block** blocks;
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);
638 left_block_context = yylval.bval =
639 BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
640 else if (nsyms == 0 || SYMBOL_CLASS (syms[0]) != LOC_BLOCK)
642 if (left_block_context == NULL)
643 error ("No file or function \"%s\".", err_name);
645 error ("No function \"%s\" in specified context.", err_name);
649 left_block_context = yylval.bval = SYMBOL_BLOCK_VALUE (syms[0]);
651 warning ("Function name \"%s\" ambiguous here", err_name);
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. */
664 name_lookup (name0, err_name, token_type)
669 struct symbol** syms;
670 struct block** blocks;
672 int len0 = strlen (name0);
673 char* name = savestring (name0, len0);
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)
683 struct type* preferred_type;
684 int i, preferred_index;
686 if (left_block_context == NULL)
687 nsyms = ada_lookup_symbol_list (name, expression_context_block,
688 VAR_NAMESPACE, &syms, &blocks);
690 nsyms = ada_lookup_symbol_list (name, left_block_context,
691 VAR_NAMESPACE, &syms, &blocks);
693 /* Check for a type definition. */
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]))
702 if (ada_prefer_type (SYMBOL_TYPE (syms[i]), preferred_type))
705 preferred_type = SYMBOL_TYPE (syms[i]);
712 case LOC_REGPARM_ADDR:
716 case LOC_BASEREG_ARG:
721 if (preferred_type != NULL)
723 /* if (TYPE_CODE (preferred_type) == TYPE_CODE_VOID)
724 error ("`%s' matches only void type name(s)",
725 ada_demangle (name));
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]))
730 yylval.ssym.sym = syms[preferred_index];
731 *token_type = OBJECT_RENAMING;
734 else if (ada_renaming_type (SYMBOL_TYPE (syms[preferred_index]))
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.");
751 else if (segments == 0)
753 yylval.tval = preferred_type;
754 *token_type = TYPENAME;
761 type = lookup_primitive_typename (name);
762 if (type == NULL && STREQ ("system__address", name))
763 type = builtin_type_ada_system_address;
767 *token_type = TYPENAME;
776 yylval.ssym.sym = syms[0];
777 yylval.ssym.msym = NULL;
778 yylval.ssym.block = blocks[0];
781 else if (nsyms == 0) {
783 yylval.ssym.msym = ada_lookup_minimal_symbol (name);
784 if (yylval.ssym.msym != NULL)
786 yylval.ssym.sym = NULL;
787 yylval.ssym.block = NULL;
792 for (i = yylval.ssym.stoken.length - 1; i > 0; i -= 1)
797 yylval.ssym.stoken.length = i;
800 else if (name[i] == '_' && name[i-1] == '_')
804 yylval.ssym.stoken.length = i;
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.",
817 error ("No definition of \"%s\" in specified context.",
824 yylval.ssym.sym = NULL;
825 yylval.ssym.msym = NULL;
826 if (left_block_context == NULL)
827 yylval.ssym.block = expression_context_block;
829 yylval.ssym.block = left_block_context;
835 /* Returns the position within STR of the '.' in a
836 '.{WHITE}*all' component of a dotted name, or -1 if there is none. */
842 for (i = 0; str[i] != '\000'; i += 1)
849 while (isspace (str[i]));
850 if (strcmp (str+i, "all") == 0
851 && ! isalnum (str[i+3]) && str[i+3] != '_')
858 /* Returns non-zero iff string SUBSEQ matches a subsequence of STR, ignoring
862 subseqMatch (subseq, str)
866 if (subseq[0] == '\0')
868 else if (str[0] == '\0')
870 else if (tolower (subseq[0]) == tolower (str[0]))
871 return subseqMatch (subseq+1, str+1) || subseqMatch (subseq, str+1);
873 return subseqMatch (subseq, str+1);
877 static struct { const char* name; int code; }
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 },
888 { "modulus", TICK_MODULUS },
890 { "range", TICK_RANGE },
891 { "size", TICK_SIZE },
897 /* Return the syntactic code corresponding to the attribute name or
901 processAttribute (str)
906 for (i = 0; attributes[i].code != -1; i += 1)
907 if (strcasecmp (str, attributes[i].name) == 0)
908 return attributes[i].code;
910 for (i = 0, k = -1; attributes[i].code != -1; i += 1)
911 if (subseqMatch (str, attributes[i].name))
916 error ("ambiguous attribute name: `%s'", str);
919 error ("unrecognized attribute: `%s'", str);
921 return attributes[k].code;