]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ada-lex.l
* dwarf2read.c (read_str_index): Delete arg cu. All callers updated.
[thirdparty/binutils-gdb.git] / gdb / ada-lex.l
CommitLineData
14f9c5c9 1/* FLEX lexer for Ada expressions, for GDB.
ecd75fc8 2 Copyright (C) 1994-2014 Free Software Foundation, Inc.
14f9c5c9 3
5b1ba0e5
NS
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
14f9c5c9
AS
18
19/*----------------------------------------------------------------------*/
20
21/* The converted version of this file is to be included in ada-exp.y, */
22/* the Ada parser for gdb. The function yylex obtains characters from */
23/* the global pointer lexptr. It returns a syntactic category for */
24/* each successive token and places a semantic value into yylval */
25/* (ada-lval), defined by the parser. */
26
14f9c5c9
AS
27DIG [0-9]
28NUM10 ({DIG}({DIG}|_)*)
29HEXDIG [0-9a-f]
30NUM16 ({HEXDIG}({HEXDIG}|_)*)
31OCTDIG [0-7]
32LETTER [a-z_]
33ID ({LETTER}({LETTER}|{DIG})*|"<"{LETTER}({LETTER}|{DIG})*">")
34WHITE [ \t\n]
35TICK ("'"{WHITE}*)
36GRAPHIC [a-z0-9 #&'()*+,-./:;<>=_|!$%?@\[\]\\^`{}~]
37OPER ([-+*/=<>&]|"<="|">="|"**"|"/="|"and"|"or"|"xor"|"not"|"mod"|"rem"|"abs")
38
39EXP (e[+-]{NUM10})
40POSEXP (e"+"?{NUM10})
41
42%{
4c4b4cd2 43
14f9c5c9
AS
44#define NUMERAL_WIDTH 256
45#define LONGEST_SIGN ((ULONGEST) 1 << (sizeof(LONGEST) * HOST_CHAR_BIT - 1))
46
4c4b4cd2
PH
47/* Temporary staging for numeric literals. */
48static char numbuf[NUMERAL_WIDTH];
49 static void canonicalizeNumeral (char *s1, const char *);
52ce6436 50static struct stoken processString (const char*, int);
4c4b4cd2
PH
51static int processInt (const char *, const char *, const char *);
52static int processReal (const char *);
52ce6436 53static struct stoken processId (const char *, int);
4c4b4cd2
PH
54static int processAttribute (const char *);
55static int find_dot_all (const char *);
82d049ab 56static void rewind_to_char (int);
14f9c5c9
AS
57
58#undef YY_DECL
4c4b4cd2 59#define YY_DECL static int yylex ( void )
14f9c5c9 60
0ec6cd0c
JB
61/* Flex generates a static function "input" which is not used.
62 Defining YY_NO_INPUT comments it out. */
63#define YY_NO_INPUT
64
14f9c5c9
AS
65#undef YY_INPUT
66#define YY_INPUT(BUF, RESULT, MAX_SIZE) \
67 if ( *lexptr == '\000' ) \
68 (RESULT) = YY_NULL; \
69 else \
70 { \
71 *(BUF) = *lexptr; \
72 (RESULT) = 1; \
73 lexptr += 1; \
74 }
75
4c4b4cd2 76static int find_dot_all (const char *);
14f9c5c9
AS
77
78%}
79
7dc1ef8d
PH
80%option case-insensitive interactive nodefault
81
52ce6436 82%s BEFORE_QUAL_QUOTE
14f9c5c9
AS
83
84%%
85
86{WHITE} { }
87
88"--".* { yyterminate(); }
89
4c4b4cd2
PH
90{NUM10}{POSEXP} {
91 canonicalizeNumeral (numbuf, yytext);
14f9c5c9
AS
92 return processInt (NULL, numbuf, strrchr(numbuf, 'e')+1);
93 }
94
4c4b4cd2
PH
95{NUM10} {
96 canonicalizeNumeral (numbuf, yytext);
14f9c5c9
AS
97 return processInt (NULL, numbuf, NULL);
98 }
99
100{NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#"{POSEXP} {
101 canonicalizeNumeral (numbuf, yytext);
102 return processInt (numbuf,
4c4b4cd2 103 strchr (numbuf, '#') + 1,
14f9c5c9
AS
104 strrchr(numbuf, '#') + 1);
105 }
106
107{NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#" {
108 canonicalizeNumeral (numbuf, yytext);
109 return processInt (numbuf, strchr (numbuf, '#') + 1, NULL);
110 }
111
112"0x"{HEXDIG}+ {
113 canonicalizeNumeral (numbuf, yytext+2);
114 return processInt ("16#", numbuf, NULL);
115 }
116
117
118{NUM10}"."{NUM10}{EXP} {
4c4b4cd2 119 canonicalizeNumeral (numbuf, yytext);
14f9c5c9
AS
120 return processReal (numbuf);
121 }
122
123{NUM10}"."{NUM10} {
4c4b4cd2 124 canonicalizeNumeral (numbuf, yytext);
14f9c5c9
AS
125 return processReal (numbuf);
126 }
127
128{NUM10}"#"{NUM16}"."{NUM16}"#"{EXP} {
e1d5a0d2 129 error (_("Based real literals not implemented yet."));
14f9c5c9
AS
130 }
131
132{NUM10}"#"{NUM16}"."{NUM16}"#" {
e1d5a0d2 133 error (_("Based real literals not implemented yet."));
14f9c5c9
AS
134 }
135
136<INITIAL>"'"({GRAPHIC}|\")"'" {
72d5681a 137 yylval.typed_val.type = type_char ();
14f9c5c9
AS
138 yylval.typed_val.val = yytext[1];
139 return CHARLIT;
140 }
141
142<INITIAL>"'[\""{HEXDIG}{2}"\"]'" {
143 int v;
72d5681a 144 yylval.typed_val.type = type_char ();
14f9c5c9
AS
145 sscanf (yytext+3, "%2x", &v);
146 yylval.typed_val.val = v;
147 return CHARLIT;
148 }
149
52ce6436
PH
150\"({GRAPHIC}|"[\""({HEXDIG}{2}|\")"\"]")*\" {
151 yylval.sval = processString (yytext+1, yyleng-2);
14f9c5c9
AS
152 return STRING;
153 }
154
52ce6436 155\" {
e1d5a0d2 156 error (_("ill-formed or non-terminated string literal"));
14f9c5c9
AS
157 }
158
14f9c5c9 159
4c4b4cd2 160if {
82d049ab 161 rewind_to_char ('i');
14f9c5c9
AS
162 return 0;
163 }
164
82d049ab
PH
165task {
166 rewind_to_char ('t');
167 return 0;
168 }
169
170thread{WHITE}+{DIG} {
b9ee2233
JB
171 /* This keyword signals the end of the expression and
172 will be processed separately. */
82d049ab 173 rewind_to_char ('t');
70575d34
JB
174 return 0;
175 }
176
14f9c5c9
AS
177 /* ADA KEYWORDS */
178
179abs { return ABS; }
180and { return _AND_; }
181else { return ELSE; }
182in { return IN; }
183mod { return MOD; }
184new { return NEW; }
185not { return NOT; }
186null { return NULL_PTR; }
187or { return OR; }
52ce6436 188others { return OTHERS; }
14f9c5c9
AS
189rem { return REM; }
190then { return THEN; }
191xor { return XOR; }
192
690cc4eb
PH
193 /* BOOLEAN "KEYWORDS" */
194
195 /* True and False are not keywords in Ada, but rather enumeration constants.
196 However, the boolean type is no longer represented as an enum, so True
197 and False are no longer defined in symbol tables. We compromise by
198 making them keywords (when bare). */
199
200true { return TRUEKEYWORD; }
201false { return FALSEKEYWORD; }
202
14f9c5c9
AS
203 /* ATTRIBUTES */
204
205{TICK}[a-zA-Z][a-zA-Z]+ { return processAttribute (yytext+1); }
206
207 /* PUNCTUATION */
208
209"=>" { return ARROW; }
210".." { return DOTDOT; }
211"**" { return STARSTAR; }
212":=" { return ASSIGN; }
213"/=" { return NOTEQUAL; }
214"<=" { return LEQ; }
215">=" { return GEQ; }
216
217<BEFORE_QUAL_QUOTE>"'" { BEGIN INITIAL; return '\''; }
218
219[-&*+./:<>=|;\[\]] { return yytext[0]; }
220
221"," { if (paren_depth == 0 && comma_terminates)
222 {
82d049ab 223 rewind_to_char (',');
14f9c5c9
AS
224 return 0;
225 }
4c4b4cd2 226 else
14f9c5c9
AS
227 return ',';
228 }
229
230"(" { paren_depth += 1; return '('; }
4c4b4cd2 231")" { if (paren_depth == 0)
14f9c5c9 232 {
82d049ab 233 rewind_to_char (')');
14f9c5c9
AS
234 return 0;
235 }
4c4b4cd2 236 else
14f9c5c9 237 {
4c4b4cd2 238 paren_depth -= 1;
14f9c5c9
AS
239 return ')';
240 }
241 }
242
243"."{WHITE}*all { return DOT_ALL; }
244
4c4b4cd2 245"."{WHITE}*{ID} {
52ce6436 246 yylval.sval = processId (yytext+1, yyleng-1);
4c4b4cd2 247 return DOT_ID;
14f9c5c9
AS
248 }
249
4c4b4cd2 250{ID}({WHITE}*"."{WHITE}*({ID}|\"{OPER}\"))*(" "*"'")? {
14f9c5c9 251 int all_posn = find_dot_all (yytext);
14f9c5c9 252
4c4b4cd2 253 if (all_posn == -1 && yytext[yyleng-1] == '\'')
14f9c5c9 254 {
52ce6436
PH
255 BEGIN BEFORE_QUAL_QUOTE;
256 yyless (yyleng-1);
14f9c5c9 257 }
52ce6436 258 else if (all_posn >= 0)
14f9c5c9 259 yyless (all_posn);
52ce6436
PH
260 yylval.sval = processId (yytext, yyleng);
261 return NAME;
262 }
14f9c5c9 263
14f9c5c9 264
52ce6436 265 /* GDB EXPRESSION CONSTRUCTS */
14f9c5c9
AS
266
267"'"[^']+"'"{WHITE}*:: {
52ce6436
PH
268 yyless (yyleng - 2);
269 yylval.sval = processId (yytext, yyleng);
270 return NAME;
14f9c5c9
AS
271 }
272
52ce6436 273"::" { return COLONCOLON; }
14f9c5c9
AS
274
275[{}@] { return yytext[0]; }
276
14f9c5c9
AS
277 /* REGISTERS AND GDB CONVENIENCE VARIABLES */
278
4c4b4cd2 279"$"({LETTER}|{DIG}|"$")* {
14f9c5c9
AS
280 yylval.sval.ptr = yytext;
281 yylval.sval.length = yyleng;
4c4b4cd2 282 return SPECIAL_VARIABLE;
14f9c5c9
AS
283 }
284
285 /* CATCH-ALL ERROR CASE */
286
e1d5a0d2 287. { error (_("Invalid character '%s' in expression."), yytext); }
14f9c5c9
AS
288%%
289
290#include <ctype.h>
0e9f083f 291#include <string.h>
14f9c5c9 292
52ce6436
PH
293/* Initialize the lexer for processing new expression. */
294
e3084549 295static void
4c4b4cd2 296lexer_init (FILE *inp)
14f9c5c9
AS
297{
298 BEGIN INITIAL;
299 yyrestart (inp);
300}
301
302
4c4b4cd2 303/* Copy S2 to S1, removing all underscores, and downcasing all letters. */
14f9c5c9
AS
304
305static void
4c4b4cd2 306canonicalizeNumeral (char *s1, const char *s2)
14f9c5c9 307{
4c4b4cd2 308 for (; *s2 != '\000'; s2 += 1)
14f9c5c9
AS
309 {
310 if (*s2 != '_')
311 {
312 *s1 = tolower(*s2);
313 s1 += 1;
314 }
315 }
316 s1[0] = '\000';
317}
318
14f9c5c9
AS
319/* Interprets the prefix of NUM that consists of digits of the given BASE
320 as an integer of that BASE, with the string EXP as an exponent.
321 Puts value in yylval, and returns INT, if the string is valid. Causes
4c4b4cd2 322 an error if the number is improperly formated. BASE, if NULL, defaults
52ce6436
PH
323 to "10", and EXP to "1". The EXP does not contain a leading 'e' or 'E'.
324 */
14f9c5c9
AS
325
326static int
4c4b4cd2 327processInt (const char *base0, const char *num0, const char *exp0)
14f9c5c9
AS
328{
329 ULONGEST result;
330 long exp;
331 int base;
a0bcdaa7 332 const char *trailer;
14f9c5c9
AS
333
334 if (base0 == NULL)
335 base = 10;
336 else
4c4b4cd2
PH
337 {
338 base = strtol (base0, (char **) NULL, 10);
14f9c5c9 339 if (base < 2 || base > 16)
e1d5a0d2 340 error (_("Invalid base: %d."), base);
14f9c5c9
AS
341 }
342
343 if (exp0 == NULL)
344 exp = 0;
345 else
4c4b4cd2 346 exp = strtol(exp0, (char **) NULL, 10);
14f9c5c9
AS
347
348 errno = 0;
a0bcdaa7 349 result = strtoulst (num0, &trailer, base);
14f9c5c9 350 if (errno == ERANGE)
e1d5a0d2 351 error (_("Integer literal out of range"));
14f9c5c9 352 if (isxdigit(*trailer))
e1d5a0d2 353 error (_("Invalid digit `%c' in based literal"), *trailer);
14f9c5c9 354
4c4b4cd2 355 while (exp > 0)
14f9c5c9
AS
356 {
357 if (result > (ULONG_MAX / base))
e1d5a0d2 358 error (_("Integer literal out of range"));
14f9c5c9
AS
359 result *= base;
360 exp -= 1;
361 }
4c4b4cd2 362
3e79cecf 363 if ((result >> (gdbarch_int_bit (parse_gdbarch)-1)) == 0)
72d5681a 364 yylval.typed_val.type = type_int ();
3e79cecf 365 else if ((result >> (gdbarch_long_bit (parse_gdbarch)-1)) == 0)
72d5681a 366 yylval.typed_val.type = type_long ();
3e79cecf 367 else if (((result >> (gdbarch_long_bit (parse_gdbarch)-1)) >> 1) == 0)
14f9c5c9
AS
368 {
369 /* We have a number representable as an unsigned integer quantity.
4c4b4cd2 370 For consistency with the C treatment, we will treat it as an
14f9c5c9 371 anonymous modular (unsigned) quantity. Alas, the types are such
4c4b4cd2 372 that we need to store .val as a signed quantity. Sorry
14f9c5c9
AS
373 for the mess, but C doesn't officially guarantee that a simple
374 assignment does the trick (no, it doesn't; read the reference manual).
375 */
3e79cecf
UW
376 yylval.typed_val.type
377 = builtin_type (parse_gdbarch)->builtin_unsigned_long;
14f9c5c9 378 if (result & LONGEST_SIGN)
4c4b4cd2
PH
379 yylval.typed_val.val =
380 (LONGEST) (result & ~LONGEST_SIGN)
14f9c5c9
AS
381 - (LONGEST_SIGN>>1) - (LONGEST_SIGN>>1);
382 else
383 yylval.typed_val.val = (LONGEST) result;
384 return INT;
385 }
4c4b4cd2 386 else
72d5681a 387 yylval.typed_val.type = type_long_long ();
14f9c5c9
AS
388
389 yylval.typed_val.val = (LONGEST) result;
390 return INT;
391}
392
393static int
4c4b4cd2 394processReal (const char *num0)
14f9c5c9 395{
689e4e2d 396 sscanf (num0, "%" DOUBLEST_SCAN_FORMAT, &yylval.typed_val_float.dval);
14f9c5c9 397
72d5681a 398 yylval.typed_val_float.type = type_float ();
3e79cecf 399 if (sizeof(DOUBLEST) >= gdbarch_double_bit (parse_gdbarch)
ea06eb3d 400 / TARGET_CHAR_BIT)
72d5681a 401 yylval.typed_val_float.type = type_double ();
3e79cecf 402 if (sizeof(DOUBLEST) >= gdbarch_long_double_bit (parse_gdbarch)
ea06eb3d 403 / TARGET_CHAR_BIT)
72d5681a 404 yylval.typed_val_float.type = type_long_double ();
14f9c5c9
AS
405
406 return FLOAT;
407}
408
52ce6436
PH
409
410/* Store a canonicalized version of NAME0[0..LEN-1] in yylval.ssym. The
718cb7da
JB
411 resulting string is valid until the next call to ada_parse. If
412 NAME0 contains the substring "___", it is assumed to be already
413 encoded and the resulting name is equal to it. Otherwise, it differs
52ce6436
PH
414 from NAME0 in that:
415 + Characters between '...' or <...> are transfered verbatim to
416 yylval.ssym.
417 + <, >, and trailing "'" characters in quoted sequences are removed
418 (a leading quote is preserved to indicate that the name is not to be
419 GNAT-encoded).
420 + Unquoted whitespace is removed.
421 + Unquoted alphabetic characters are mapped to lower case.
422 Result is returned as a struct stoken, but for convenience, the string
423 is also null-terminated. Result string valid until the next call of
424 ada_parse.
425 */
426static struct stoken
4c4b4cd2 427processId (const char *name0, int len)
14f9c5c9 428{
4c4b4cd2 429 char *name = obstack_alloc (&temp_parse_space, len + 11);
14f9c5c9 430 int i0, i;
52ce6436 431 struct stoken result;
4c4b4cd2 432
718cb7da 433 result.ptr = name;
14f9c5c9
AS
434 while (len > 0 && isspace (name0[len-1]))
435 len -= 1;
718cb7da
JB
436
437 if (strstr (name0, "___") != NULL)
438 {
439 strncpy (name, name0, len);
440 name[len] = '\000';
441 result.length = len;
442 return result;
443 }
444
14f9c5c9 445 i = i0 = 0;
4c4b4cd2 446 while (i0 < len)
14f9c5c9
AS
447 {
448 if (isalnum (name0[i0]))
449 {
450 name[i] = tolower (name0[i0]);
451 i += 1; i0 += 1;
452 }
4c4b4cd2 453 else switch (name0[i0])
14f9c5c9
AS
454 {
455 default:
456 name[i] = name0[i0];
457 i += 1; i0 += 1;
458 break;
459 case ' ': case '\t':
460 i0 += 1;
461 break;
462 case '\'':
52ce6436 463 do
14f9c5c9
AS
464 {
465 name[i] = name0[i0];
466 i += 1; i0 += 1;
467 }
52ce6436 468 while (i0 < len && name0[i0] != '\'');
14f9c5c9
AS
469 i0 += 1;
470 break;
471 case '<':
472 i0 += 1;
473 while (i0 < len && name0[i0] != '>')
474 {
475 name[i] = name0[i0];
476 i += 1; i0 += 1;
477 }
478 i0 += 1;
479 break;
480 }
481 }
482 name[i] = '\000';
483
52ce6436
PH
484 result.length = i;
485 return result;
14f9c5c9
AS
486}
487
52ce6436
PH
488/* Return TEXT[0..LEN-1], a string literal without surrounding quotes,
489 with special hex character notations replaced with characters.
490 Result valid until the next call to ada_parse. */
14f9c5c9 491
52ce6436
PH
492static struct stoken
493processString (const char *text, int len)
14f9c5c9 494{
52ce6436
PH
495 const char *p;
496 char *q;
497 const char *lim = text + len;
498 struct stoken result;
499
d7561cbb
KS
500 q = obstack_alloc (&temp_parse_space, len);
501 result.ptr = q;
52ce6436
PH
502 p = text;
503 while (p < lim)
14f9c5c9 504 {
52ce6436
PH
505 if (p[0] == '[' && p[1] == '"' && p+2 < lim)
506 {
507 if (p[2] == '"') /* "...["""]... */
508 {
509 *q = '"';
510 p += 4;
511 }
512 else
513 {
514 int chr;
515 sscanf (p+2, "%2x", &chr);
516 *q = (char) chr;
517 p += 5;
518 }
519 }
520 else
521 *q = *p;
522 q += 1;
523 p += 1;
524 }
525 result.length = q - result.ptr;
526 return result;
14f9c5c9
AS
527}
528
529/* Returns the position within STR of the '.' in a
52ce6436
PH
530 '.{WHITE}*all' component of a dotted name, or -1 if there is none.
531 Note: we actually don't need this routine, since 'all' can never be an
532 Ada identifier. Thus, looking up foo.all or foo.all.x as a name
533 must fail, and will eventually be interpreted as (foo).all or
534 (foo).all.x. However, this does avoid an extraneous lookup. */
535
14f9c5c9 536static int
4c4b4cd2 537find_dot_all (const char *str)
14f9c5c9
AS
538{
539 int i;
a5e619ec
JB
540
541 for (i = 0; str[i] != '\000'; i++)
542 if (str[i] == '.')
543 {
544 int i0 = i;
545
546 do
547 i += 1;
548 while (isspace (str[i]));
549
550 if (strncasecmp (str + i, "all", 3) == 0
551 && !isalnum (str[i + 3]) && str[i + 3] != '_')
552 return i0;
553 }
14f9c5c9 554 return -1;
4c4b4cd2 555}
14f9c5c9
AS
556
557/* Returns non-zero iff string SUBSEQ matches a subsequence of STR, ignoring
4c4b4cd2 558 case. */
14f9c5c9
AS
559
560static int
4c4b4cd2 561subseqMatch (const char *subseq, const char *str)
14f9c5c9
AS
562{
563 if (subseq[0] == '\0')
564 return 1;
565 else if (str[0] == '\0')
566 return 0;
567 else if (tolower (subseq[0]) == tolower (str[0]))
568 return subseqMatch (subseq+1, str+1) || subseqMatch (subseq, str+1);
569 else
570 return subseqMatch (subseq, str+1);
571}
14f9c5c9 572
4c4b4cd2
PH
573
574static struct { const char *name; int code; }
14f9c5c9
AS
575attributes[] = {
576 { "address", TICK_ADDRESS },
577 { "unchecked_access", TICK_ACCESS },
578 { "unrestricted_access", TICK_ACCESS },
579 { "access", TICK_ACCESS },
580 { "first", TICK_FIRST },
581 { "last", TICK_LAST },
582 { "length", TICK_LENGTH },
583 { "max", TICK_MAX },
584 { "min", TICK_MIN },
585 { "modulus", TICK_MODULUS },
586 { "pos", TICK_POS },
587 { "range", TICK_RANGE },
588 { "size", TICK_SIZE },
589 { "tag", TICK_TAG },
590 { "val", TICK_VAL },
591 { NULL, -1 }
592};
593
594/* Return the syntactic code corresponding to the attribute name or
595 abbreviation STR. */
596
597static int
4c4b4cd2 598processAttribute (const char *str)
14f9c5c9
AS
599{
600 int i, k;
601
602 for (i = 0; attributes[i].code != -1; i += 1)
603 if (strcasecmp (str, attributes[i].name) == 0)
604 return attributes[i].code;
605
606 for (i = 0, k = -1; attributes[i].code != -1; i += 1)
4c4b4cd2 607 if (subseqMatch (str, attributes[i].name))
14f9c5c9
AS
608 {
609 if (k == -1)
610 k = i;
4c4b4cd2 611 else
e1d5a0d2 612 error (_("ambiguous attribute name: `%s'"), str);
14f9c5c9
AS
613 }
614 if (k == -1)
e1d5a0d2 615 error (_("unrecognized attribute: `%s'"), str);
14f9c5c9
AS
616
617 return attributes[k].code;
618}
619
82d049ab
PH
620/* Back up lexptr by yyleng and then to the rightmost occurrence of
621 character CH, case-folded (there must be one). WARNING: since
622 lexptr points to the next input character that Flex has not yet
623 transferred to its internal buffer, the use of this function
624 depends on the assumption that Flex calls YY_INPUT only when it is
625 logically necessary to do so (thus, there is no reading ahead
626 farther than needed to identify the next token.) */
627
628static void
629rewind_to_char (int ch)
630{
631 lexptr -= yyleng;
632 while (toupper (*lexptr) != toupper (ch))
633 lexptr -= 1;
634 yyrestart (NULL);
635}
636
14f9c5c9 637int
4c4b4cd2 638yywrap(void)
14f9c5c9
AS
639{
640 return 1;
641}
23485554
PH
642
643/* Dummy definition to suppress warnings about unused static definitions. */
644typedef void (*dummy_function) ();
645dummy_function ada_flex_use[] =
646{
375c0479 647 (dummy_function) yyunput
23485554 648};