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