* configure.in (targargs): Pass --build if we're doing
[deliverable/binutils-gdb.git] / gdb / java-exp.y
CommitLineData
7a9eb4c4
PB
1/* YACC parser for Java expressions, for GDB.
2 Copyright (C) 1997.
3 Free Software Foundation, Inc.
4
5This file is part of GDB.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21/* Parse a C expression from text in a string,
22 and return the result as a struct expression pointer.
23 That structure contains arithmetic operations in reverse polish,
24 with constants represented by operations that are followed by special data.
25 See expression.h for the details of the format.
26 What is important here is that it can be built up sequentially
27 during the process of parsing; the lower levels of the tree always
28 come first in the result.
29
30 Note that malloc's and realloc's in this file are transformed to
31 xmalloc and xrealloc respectively by the same sed command in the
32 makefile that remaps any other malloc/realloc inserted by the parser
33 generator. Doing this with #defines and trying to control the interaction
34 with include files (<malloc.h> and <stdlib.h> for example) just became
35 too messy, particularly when such includes can be inserted at random
36 times by the parser generator. */
37
38%{
39
40#include "defs.h"
41#include "gdb_string.h"
42#include <ctype.h>
43#include "expression.h"
44#include "value.h"
45#include "parser-defs.h"
46#include "language.h"
47#include "java-lang.h"
48#include "bfd.h" /* Required by objfiles.h. */
49#include "symfile.h" /* Required by objfiles.h. */
50#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
51
52/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
53 as well as gratuitiously global symbol names, so we can have multiple
54 yacc generated parsers in gdb. Note that these are only the variables
55 produced by yacc. If other parser generators (bison, byacc, etc) produce
56 additional global names that conflict at link time, then those parser
57 generators need to be fixed instead of adding those names to this list. */
58
59#define yymaxdepth java_maxdepth
60#define yyparse java_parse
61#define yylex java_lex
62#define yyerror java_error
63#define yylval java_lval
64#define yychar java_char
65#define yydebug java_debug
66#define yypact java_pact
67#define yyr1 java_r1
68#define yyr2 java_r2
69#define yydef java_def
70#define yychk java_chk
71#define yypgo java_pgo
72#define yyact java_act
73#define yyexca java_exca
74#define yyerrflag java_errflag
75#define yynerrs java_nerrs
76#define yyps java_ps
77#define yypv java_pv
78#define yys java_s
79#define yy_yys java_yys
80#define yystate java_state
81#define yytmp java_tmp
82#define yyv java_v
83#define yy_yyv java_yyv
84#define yyval java_val
85#define yylloc java_lloc
86#define yyreds java_reds /* With YYDEBUG defined */
87#define yytoks java_toks /* With YYDEBUG defined */
88#define yylhs java_yylhs
89#define yylen java_yylen
90#define yydefred java_yydefred
91#define yydgoto java_yydgoto
92#define yysindex java_yysindex
93#define yyrindex java_yyrindex
94#define yygindex java_yygindex
95#define yytable java_yytable
96#define yycheck java_yycheck
97
98#ifndef YYDEBUG
99#define YYDEBUG 0 /* Default to no yydebug support */
100#endif
101
102int
103yyparse PARAMS ((void));
104
105static int
106yylex PARAMS ((void));
107
108void
109yyerror PARAMS ((char *));
110
111static struct type * java_type_from_name PARAMS ((struct stoken));
112static void push_variable PARAMS ((struct stoken));
113
114%}
115
116/* Although the yacc "value" of an expression is not used,
117 since the result is stored in the structure being created,
118 other node types do have values. */
119
120%union
121 {
122 LONGEST lval;
123 struct {
124 LONGEST val;
125 struct type *type;
126 } typed_val_int;
127 struct {
128 DOUBLEST dval;
129 struct type *type;
130 } typed_val_float;
131 struct symbol *sym;
132 struct type *tval;
133 struct stoken sval;
134 struct ttype tsym;
135 struct symtoken ssym;
136 struct block *bval;
137 enum exp_opcode opcode;
138 struct internalvar *ivar;
139 int *ivec;
140 }
141
142%{
143/* YYSTYPE gets defined by %union */
144static int
145parse_number PARAMS ((char *, int, int, YYSTYPE *));
146%}
147
75a947c6 148%type <lval> rcurly Dims Dims_opt
7a9eb4c4
PB
149%type <tval> ClassOrInterfaceType ClassType /* ReferenceType Type ArrayType */
150%type <tval> IntegralType FloatingPointType NumericType PrimitiveType
151
152%token <typed_val_int> INTEGER_LITERAL
153%token <typed_val_float> FLOATING_POINT_LITERAL
154
155%token <sval> IDENTIFIER
156%token <sval> STRING_LITERAL
75a947c6 157%token <lval> BOOLEAN_LITERAL
7a9eb4c4
PB
158%token <tsym> TYPENAME
159%type <sval> Name SimpleName QualifiedName ForcedName
160
161/* A NAME_OR_INT is a symbol which is not known in the symbol table,
162 but which would parse as a valid number in the current input radix.
163 E.g. "c" when input_radix==16. Depending on the parse, it will be
164 turned into a name or into a number. */
165
166%token <sval> NAME_OR_INT
167
168%token ERROR
169
170/* Special type cases, put in to allow the parser to distinguish different
171 legal basetypes. */
172%token LONG SHORT BYTE INT CHAR BOOLEAN DOUBLE FLOAT
173
174%token VARIABLE
175
176%token <opcode> ASSIGN_MODIFY
177
75a947c6 178%token THIS SUPER NEW
7a9eb4c4
PB
179
180%left ','
181%right '=' ASSIGN_MODIFY
182%right '?'
183%left OROR
184%left ANDAND
185%left '|'
186%left '^'
187%left '&'
188%left EQUAL NOTEQUAL
189%left '<' '>' LEQ GEQ
190%left LSH RSH
191%left '+' '-'
192%left '*' '/' '%'
193%right INCREMENT DECREMENT
194%right '.' '[' '('
195
196\f
197%%
198
199start : exp1
200/* | type_exp FIXME */
201 ;
202
203StringLiteral:
204 STRING_LITERAL
205 {
206 write_exp_elt_opcode (OP_STRING);
207 write_exp_string ($1);
208 write_exp_elt_opcode (OP_STRING);
209 }
210;
211
7a9eb4c4
PB
212Literal :
213 INTEGER_LITERAL
214 { write_exp_elt_opcode (OP_LONG);
215 write_exp_elt_type ($1.type);
216 write_exp_elt_longcst ((LONGEST)($1.val));
217 write_exp_elt_opcode (OP_LONG); }
218| NAME_OR_INT
219 { YYSTYPE val;
220 parse_number ($1.ptr, $1.length, 0, &val);
221 write_exp_elt_opcode (OP_LONG);
222 write_exp_elt_type (val.typed_val_int.type);
223 write_exp_elt_longcst ((LONGEST)val.typed_val_int.val);
224 write_exp_elt_opcode (OP_LONG);
225 }
226| FLOATING_POINT_LITERAL
227 { write_exp_elt_opcode (OP_DOUBLE);
228 write_exp_elt_type ($1.type);
229 write_exp_elt_dblcst ($1.dval);
230 write_exp_elt_opcode (OP_DOUBLE); }
75a947c6 231| BOOLEAN_LITERAL
7a9eb4c4
PB
232 { write_exp_elt_opcode (OP_LONG);
233 write_exp_elt_type (java_boolean_type);
234 write_exp_elt_longcst ((LONGEST)$1);
235 write_exp_elt_opcode (OP_LONG); }
236| StringLiteral
237 ;
238
239/* UNUSED:
240Type:
241 PrimitiveType
242| ReferenceType
243;
244*/
245
246PrimitiveType:
247 NumericType
248| BOOLEAN
249 { $$ = java_boolean_type; }
250;
251
252NumericType:
253 IntegralType
254| FloatingPointType
255;
256
257IntegralType:
258 BYTE
259 { $$ = java_byte_type; }
260| SHORT
261 { $$ = java_short_type; }
262| INT
263 { $$ = java_int_type; }
264| LONG
265 { $$ = java_long_type; }
266| CHAR
267 { $$ = java_char_type; }
268;
269
270FloatingPointType:
271 FLOAT
272 { $$ = java_float_type; }
273| DOUBLE
274 { $$ = java_double_type; }
275;
276
277/* UNUSED:
278ReferenceType:
279 ClassOrInterfaceType
280| ArrayType
281;
282*/
283
284ClassOrInterfaceType:
285 Name
286 { $$ = java_type_from_name ($1); }
287;
288
289ClassType:
290 ClassOrInterfaceType
291;
292
293/* UNUSED:
294ArrayType:
295 PrimitiveType Dims
296 { $$ = java_array_type ($1, $2); }
297| Name Dims
298 { $$ = java_array_type (java_type_from_name ($1), $2); }
299;
300*/
301
302Name:
303 IDENTIFIER
304| QualifiedName
305;
306
307ForcedName:
308 SimpleName
309| QualifiedName
310;
311
312SimpleName:
313 IDENTIFIER
314| NAME_OR_INT
315;
316
317QualifiedName:
318 Name '.' SimpleName
319 { $$.length = $1.length + $3.length + 1;
320 if ($1.ptr + $1.length + 1 == $3.ptr
321 && $1.ptr[$1.length] == '.')
322 $$.ptr = $1.ptr; /* Optimization. */
323 else
324 {
325 $$.ptr = (char *) malloc ($$.length + 1);
326 make_cleanup (free, $$.ptr);
327 sprintf ($$.ptr, "%.*s.%.*s",
328 $1.length, $1.ptr, $3.length, $3.ptr);
329 } }
330;
331
332/*
333type_exp: type
334 { write_exp_elt_opcode(OP_TYPE);
335 write_exp_elt_type($1);
336 write_exp_elt_opcode(OP_TYPE);}
337 ;
338 */
339
340/* Expressions, including the comma operator. */
341exp1 : Expression
342 | exp1 ',' Expression
343 { write_exp_elt_opcode (BINOP_COMMA); }
344 ;
345
346Primary:
347 PrimaryNoNewArray
348| ArrayCreationExpression
349;
350
351PrimaryNoNewArray:
352 Literal
353| THIS
354 { write_exp_elt_opcode (OP_THIS);
355 write_exp_elt_opcode (OP_THIS); }
356| '(' Expression ')'
357| ClassInstanceCreationExpression
358| FieldAccess
359| MethodInvocation
360| ArrayAccess
361| lcurly ArgumentList rcurly
362 { write_exp_elt_opcode (OP_ARRAY);
363 write_exp_elt_longcst ((LONGEST) 0);
364 write_exp_elt_longcst ((LONGEST) $3);
365 write_exp_elt_opcode (OP_ARRAY); }
366;
367
368lcurly:
369 '{'
370 { start_arglist (); }
371;
372
373rcurly:
374 '}'
375 { $$ = end_arglist () - 1; }
376;
377
378ClassInstanceCreationExpression:
379 NEW ClassType '(' ArgumentList_opt ')'
380 { error ("FIXME - ClassInstanceCreationExpression"); }
381;
382
383ArgumentList:
384 Expression
385 { arglist_len = 1; }
386| ArgumentList ',' Expression
387 { arglist_len++; }
388;
389
390ArgumentList_opt:
391 /* EMPTY */
392 { arglist_len = 0; }
393| ArgumentList
394;
395
396ArrayCreationExpression:
397 NEW PrimitiveType DimExprs Dims_opt
398 { error ("FIXME - ArrayCreatiionExpression"); }
399| NEW ClassOrInterfaceType DimExprs Dims_opt
400 { error ("FIXME - ArrayCreatiionExpression"); }
401;
402
403DimExprs:
404 DimExpr
405| DimExprs DimExpr
406;
407
408DimExpr:
409 '[' Expression ']'
410;
411
412Dims:
413 '[' ']'
414 { $$ = 1; }
415| Dims '[' ']'
416 { $$ = $1 + 1; }
417;
418
419Dims_opt:
420 Dims
421| /* EMPTY */
422 { $$ = 0; }
423;
424
425FieldAccess:
426 Primary '.' SimpleName
427 { write_exp_elt_opcode (STRUCTOP_STRUCT);
428 write_exp_string ($3);
429 write_exp_elt_opcode (STRUCTOP_STRUCT); }
430/*| SUPER '.' SimpleName { FIXME } */
431;
432
433MethodInvocation:
434 Name '(' ArgumentList_opt ')'
435 { error ("method invocation not implemented"); }
436| Primary '.' SimpleName '(' ArgumentList_opt ')'
437 { error ("method invocation not implemented"); }
438| SUPER '.' SimpleName '(' ArgumentList_opt ')'
439 { error ("method invocation not implemented"); }
440;
441
442ArrayAccess:
443 Name '[' Expression ']'
444 { error ("ArrayAccess"); } /* FIXME - NASTY */
445| PrimaryNoNewArray '[' Expression ']'
446 { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
447;
448
449PostfixExpression:
450 Primary
451| Name
452 { push_variable ($1); }
453| VARIABLE
454 /* Already written by write_dollar_variable. */
455| PostIncrementExpression
456| PostDecrementExpression
457;
458
459PostIncrementExpression:
460 PostfixExpression INCREMENT
461 { write_exp_elt_opcode (UNOP_POSTINCREMENT); }
462;
463
464PostDecrementExpression:
465 PostfixExpression DECREMENT
466 { write_exp_elt_opcode (UNOP_POSTDECREMENT); }
467;
468
469UnaryExpression:
470 PreIncrementExpression
471| PreDecrementExpression
472| '+' UnaryExpression
473| '-' UnaryExpression
474 { write_exp_elt_opcode (UNOP_NEG); }
475| '*' UnaryExpression
476 { write_exp_elt_opcode (UNOP_IND); } /*FIXME not in Java */
477| UnaryExpressionNotPlusMinus
478;
479
480PreIncrementExpression:
481 INCREMENT UnaryExpression
482 { write_exp_elt_opcode (UNOP_PREINCREMENT); }
483;
484
485PreDecrementExpression:
486 DECREMENT UnaryExpression
487 { write_exp_elt_opcode (UNOP_PREDECREMENT); }
488;
489
490UnaryExpressionNotPlusMinus:
491 PostfixExpression
492| '~' UnaryExpression
493 { write_exp_elt_opcode (UNOP_COMPLEMENT); }
494| '!' UnaryExpression
495 { write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
496| CastExpression
497 ;
498
499CastExpression:
500 '(' PrimitiveType Dims_opt ')' UnaryExpression
501 { write_exp_elt_opcode (UNOP_CAST);
502 write_exp_elt_type (java_array_type ($2, $3));
503 write_exp_elt_opcode (UNOP_CAST); }
504| '(' Expression ')' UnaryExpressionNotPlusMinus /* FIXME */
505| '(' Name Dims ')' UnaryExpressionNotPlusMinus
506 { write_exp_elt_opcode (UNOP_CAST);
507 write_exp_elt_type (java_array_type (java_type_from_name ($2), $3));
508 write_exp_elt_opcode (UNOP_CAST); }
509;
510
511
512MultiplicativeExpression:
513 UnaryExpression
514| MultiplicativeExpression '*' UnaryExpression
515 { write_exp_elt_opcode (BINOP_MUL); }
516| MultiplicativeExpression '/' UnaryExpression
517 { write_exp_elt_opcode (BINOP_DIV); }
518| MultiplicativeExpression '%' UnaryExpression
519 { write_exp_elt_opcode (BINOP_REM); }
520;
521
522AdditiveExpression:
523 MultiplicativeExpression
524| AdditiveExpression '+' MultiplicativeExpression
525 { write_exp_elt_opcode (BINOP_ADD); }
526| AdditiveExpression '-' MultiplicativeExpression
527 { write_exp_elt_opcode (BINOP_SUB); }
528;
529
530ShiftExpression:
531 AdditiveExpression
532| ShiftExpression LSH AdditiveExpression
533 { write_exp_elt_opcode (BINOP_LSH); }
534| ShiftExpression RSH AdditiveExpression
535 { write_exp_elt_opcode (BINOP_RSH); }
536/* | ShiftExpression >>> AdditiveExpression { FIXME } */
537;
538
539RelationalExpression:
540 ShiftExpression
541| RelationalExpression '<' ShiftExpression
542 { write_exp_elt_opcode (BINOP_LESS); }
543| RelationalExpression '>' ShiftExpression
544 { write_exp_elt_opcode (BINOP_GTR); }
545| RelationalExpression LEQ ShiftExpression
546 { write_exp_elt_opcode (BINOP_LEQ); }
547| RelationalExpression GEQ ShiftExpression
548 { write_exp_elt_opcode (BINOP_GEQ); }
549/* | RelationalExpresion INSTANCEOF ReferenceType { FIXME } */
550;
551
552EqualityExpression:
553 RelationalExpression
554| EqualityExpression EQUAL RelationalExpression
555 { write_exp_elt_opcode (BINOP_EQUAL); }
556| EqualityExpression NOTEQUAL RelationalExpression
557 { write_exp_elt_opcode (BINOP_NOTEQUAL); }
558;
559
560AndExpression:
561 EqualityExpression
562| AndExpression '&' EqualityExpression
563 { write_exp_elt_opcode (BINOP_BITWISE_AND); }
564;
565
566ExclusiveOrExpression:
567 AndExpression
568| ExclusiveOrExpression '^' AndExpression
569 { write_exp_elt_opcode (BINOP_BITWISE_XOR); }
570;
571InclusiveOrExpression:
572 ExclusiveOrExpression
573| InclusiveOrExpression '|' ExclusiveOrExpression
574 { write_exp_elt_opcode (BINOP_BITWISE_IOR); }
575;
576
577ConditionalAndExpression:
578 InclusiveOrExpression
579| ConditionalAndExpression ANDAND InclusiveOrExpression
580 { write_exp_elt_opcode (BINOP_LOGICAL_AND); }
581;
582
583ConditionalOrExpression:
584 ConditionalAndExpression
585| ConditionalOrExpression OROR ConditionalAndExpression
586 { write_exp_elt_opcode (BINOP_LOGICAL_OR); }
587;
588
589ConditionalExpression:
590 ConditionalOrExpression
591| ConditionalOrExpression '?' Expression ':' ConditionalExpression
592 { write_exp_elt_opcode (TERNOP_COND); }
593;
594
595AssignmentExpression:
596 ConditionalExpression
597| Assignment
598;
599
600Assignment:
601 LeftHandSide '=' ConditionalExpression
602 { write_exp_elt_opcode (BINOP_ASSIGN); }
603| LeftHandSide ASSIGN_MODIFY ConditionalExpression
604 { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
605 write_exp_elt_opcode ($2);
606 write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); }
607;
608
609LeftHandSide:
610 ForcedName
611 { push_variable ($1); }
612| VARIABLE
613 /* Already written by write_dollar_variable. */
614| FieldAccess
615| ArrayAccess
616;
617
618
619Expression:
620 AssignmentExpression
621;
622
623%%
624/* Take care of parsing a number (anything that starts with a digit).
625 Set yylval and return the token type; update lexptr.
626 LEN is the number of characters in it. */
627
628/*** Needs some error checking for the float case ***/
629
630static int
631parse_number (p, len, parsed_float, putithere)
632 register char *p;
633 register int len;
634 int parsed_float;
635 YYSTYPE *putithere;
636{
637 register ULONGEST n = 0;
638 ULONGEST limit, limit_div_base;
639
640 register int c;
641 register int base = input_radix;
642 int unsigned_p = 0;
643
644 struct type *type;
645
646 if (parsed_float)
647 {
648 /* It's a float since it contains a point or an exponent. */
d030f469
MS
649 char c;
650 int num = 0; /* number of tokens scanned by scanf */
651 char saved_char = p[len];
7a9eb4c4 652
d030f469 653 p[len] = 0; /* null-terminate the token */
7a9eb4c4 654 if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
d030f469 655 num = sscanf (p, "%g%c", &putithere->typed_val_float.dval, &c);
7a9eb4c4 656 else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
d030f469 657 num = sscanf (p, "%lg%c", &putithere->typed_val_float.dval, &c);
7a9eb4c4
PB
658 else
659 {
660#ifdef PRINTF_HAS_LONG_DOUBLE
d030f469 661 num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval, &c);
7a9eb4c4
PB
662#else
663 /* Scan it into a double, then assign it to the long double.
664 This at least wins with values representable in the range
665 of doubles. */
666 double temp;
d030f469 667 num = sscanf (p, "%lg%c", &temp, &c);
7a9eb4c4
PB
668 putithere->typed_val_float.dval = temp;
669#endif
670 }
d030f469
MS
671 p[len] = saved_char; /* restore the input stream */
672 if (num != 1) /* check scanf found ONLY a float ... */
673 return ERROR;
7a9eb4c4
PB
674 /* See if it has `f' or `d' suffix (float or double). */
675
676 c = tolower (p[len - 1]);
677
678 if (c == 'f' || c == 'F')
679 putithere->typed_val_float.type = builtin_type_float;
680 else if (isdigit (c) || c == '.' || c == 'd' || c == 'D')
681 putithere->typed_val_float.type = builtin_type_double;
682 else
683 return ERROR;
684
685 return FLOATING_POINT_LITERAL;
686}
687
688 /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
689 if (p[0] == '0')
690 switch (p[1])
691 {
692 case 'x':
693 case 'X':
694 if (len >= 3)
695 {
696 p += 2;
697 base = 16;
698 len -= 2;
699 }
700 break;
701
702 case 't':
703 case 'T':
704 case 'd':
705 case 'D':
706 if (len >= 3)
707 {
708 p += 2;
709 base = 10;
710 len -= 2;
711 }
712 break;
713
714 default:
715 base = 8;
716 break;
717 }
718
719 c = p[len-1];
720 limit = (ULONGEST)0xffffffff;
721 if (c == 'l' || c == 'L')
722 {
723 type = java_long_type;
724 len--;
725 /* A paranoid calculation of (1<<64)-1. */
726 limit = ((limit << 16) << 16) | limit;
727 }
728 else
729 {
730 type = java_int_type;
731 }
732 limit_div_base = limit / (ULONGEST) base;
733
734 while (--len >= 0)
735 {
736 c = *p++;
737 if (c >= '0' && c <= '9')
738 c -= '0';
739 else
740 {
741 if (c >= 'A' && c <= 'Z')
742 c += 'a' - 'A';
743 if (c >= 'a' && c - 'a' + 10 < base)
744 c -= 'a' + 10;
745 else
746 return ERROR; /* Char not a digit */
747 }
748 if (c >= base)
749 return ERROR;
750 if (n > limit_div_base
751 || (n *= base) > limit - c)
752 error ("Numeric constant too large.");
753 n += c;
754 }
755
756 putithere->typed_val_int.val = n;
757 putithere->typed_val_int.type = type;
758 return INTEGER_LITERAL;
759}
760
761struct token
762{
763 char *operator;
764 int token;
765 enum exp_opcode opcode;
766};
767
768static const struct token tokentab3[] =
769 {
770 {">>=", ASSIGN_MODIFY, BINOP_RSH},
771 {"<<=", ASSIGN_MODIFY, BINOP_LSH}
772 };
773
774static const struct token tokentab2[] =
775 {
776 {"+=", ASSIGN_MODIFY, BINOP_ADD},
777 {"-=", ASSIGN_MODIFY, BINOP_SUB},
778 {"*=", ASSIGN_MODIFY, BINOP_MUL},
779 {"/=", ASSIGN_MODIFY, BINOP_DIV},
780 {"%=", ASSIGN_MODIFY, BINOP_REM},
781 {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR},
782 {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND},
783 {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR},
784 {"++", INCREMENT, BINOP_END},
785 {"--", DECREMENT, BINOP_END},
786 {"&&", ANDAND, BINOP_END},
787 {"||", OROR, BINOP_END},
788 {"<<", LSH, BINOP_END},
789 {">>", RSH, BINOP_END},
790 {"==", EQUAL, BINOP_END},
791 {"!=", NOTEQUAL, BINOP_END},
792 {"<=", LEQ, BINOP_END},
793 {">=", GEQ, BINOP_END}
794 };
795
796/* Read one token, getting characters through lexptr. */
797
798static int
799yylex ()
800{
801 int c;
802 int namelen;
803 unsigned int i;
804 char *tokstart;
805 char *tokptr;
806 int tempbufindex;
807 static char *tempbuf;
808 static int tempbufsize;
809
810 retry:
811
812 tokstart = lexptr;
813 /* See if it is a special token of length 3. */
814 for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
815 if (STREQN (tokstart, tokentab3[i].operator, 3))
816 {
817 lexptr += 3;
818 yylval.opcode = tokentab3[i].opcode;
819 return tokentab3[i].token;
820 }
821
822 /* See if it is a special token of length 2. */
823 for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
824 if (STREQN (tokstart, tokentab2[i].operator, 2))
825 {
826 lexptr += 2;
827 yylval.opcode = tokentab2[i].opcode;
828 return tokentab2[i].token;
829 }
830
831 switch (c = *tokstart)
832 {
833 case 0:
834 return 0;
835
836 case ' ':
837 case '\t':
838 case '\n':
839 lexptr++;
840 goto retry;
841
842 case '\'':
843 /* We either have a character constant ('0' or '\177' for example)
844 or we have a quoted symbol reference ('foo(int,int)' in C++
845 for example). */
846 lexptr++;
847 c = *lexptr++;
848 if (c == '\\')
849 c = parse_escape (&lexptr);
850 else if (c == '\'')
851 error ("Empty character constant.");
852
853 yylval.typed_val_int.val = c;
854 yylval.typed_val_int.type = builtin_type_char;
855
856 c = *lexptr++;
857 if (c != '\'')
858 {
859 namelen = skip_quoted (tokstart) - tokstart;
860 if (namelen > 2)
861 {
862 lexptr = tokstart + namelen;
863 if (lexptr[-1] != '\'')
864 error ("Unmatched single quote.");
865 namelen -= 2;
866 tokstart++;
867 goto tryname;
868 }
869 error ("Invalid character constant.");
870 }
871 return INTEGER_LITERAL;
872
873 case '(':
874 paren_depth++;
875 lexptr++;
876 return c;
877
878 case ')':
879 if (paren_depth == 0)
880 return 0;
881 paren_depth--;
882 lexptr++;
883 return c;
884
885 case ',':
886 if (comma_terminates && paren_depth == 0)
887 return 0;
888 lexptr++;
889 return c;
890
891 case '.':
892 /* Might be a floating point number. */
893 if (lexptr[1] < '0' || lexptr[1] > '9')
894 goto symbol; /* Nope, must be a symbol. */
895 /* FALL THRU into number case. */
896
897 case '0':
898 case '1':
899 case '2':
900 case '3':
901 case '4':
902 case '5':
903 case '6':
904 case '7':
905 case '8':
906 case '9':
907 {
908 /* It's a number. */
909 int got_dot = 0, got_e = 0, toktype;
910 register char *p = tokstart;
911 int hex = input_radix > 10;
912
913 if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
914 {
915 p += 2;
916 hex = 1;
917 }
918 else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
919 {
920 p += 2;
921 hex = 0;
922 }
923
924 for (;; ++p)
925 {
926 /* This test includes !hex because 'e' is a valid hex digit
927 and thus does not indicate a floating point number when
928 the radix is hex. */
929 if (!hex && !got_e && (*p == 'e' || *p == 'E'))
930 got_dot = got_e = 1;
931 /* This test does not include !hex, because a '.' always indicates
932 a decimal floating point number regardless of the radix. */
933 else if (!got_dot && *p == '.')
934 got_dot = 1;
935 else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
936 && (*p == '-' || *p == '+'))
937 /* This is the sign of the exponent, not the end of the
938 number. */
939 continue;
940 /* We will take any letters or digits. parse_number will
941 complain if past the radix, or if L or U are not final. */
942 else if ((*p < '0' || *p > '9')
943 && ((*p < 'a' || *p > 'z')
944 && (*p < 'A' || *p > 'Z')))
945 break;
946 }
947 toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
948 if (toktype == ERROR)
949 {
950 char *err_copy = (char *) alloca (p - tokstart + 1);
951
952 memcpy (err_copy, tokstart, p - tokstart);
953 err_copy[p - tokstart] = 0;
954 error ("Invalid number \"%s\".", err_copy);
955 }
956 lexptr = p;
957 return toktype;
958 }
959
960 case '+':
961 case '-':
962 case '*':
963 case '/':
964 case '%':
965 case '|':
966 case '&':
967 case '^':
968 case '~':
969 case '!':
970 case '<':
971 case '>':
972 case '[':
973 case ']':
974 case '?':
975 case ':':
976 case '=':
977 case '{':
978 case '}':
979 symbol:
980 lexptr++;
981 return c;
982
983 case '"':
984
985 /* Build the gdb internal form of the input string in tempbuf,
986 translating any standard C escape forms seen. Note that the
987 buffer is null byte terminated *only* for the convenience of
988 debugging gdb itself and printing the buffer contents when
989 the buffer contains no embedded nulls. Gdb does not depend
990 upon the buffer being null byte terminated, it uses the length
991 string instead. This allows gdb to handle C strings (as well
992 as strings in other languages) with embedded null bytes */
993
994 tokptr = ++tokstart;
995 tempbufindex = 0;
996
997 do {
998 /* Grow the static temp buffer if necessary, including allocating
999 the first one on demand. */
1000 if (tempbufindex + 1 >= tempbufsize)
1001 {
1002 tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
1003 }
1004 switch (*tokptr)
1005 {
1006 case '\0':
1007 case '"':
1008 /* Do nothing, loop will terminate. */
1009 break;
1010 case '\\':
1011 tokptr++;
1012 c = parse_escape (&tokptr);
1013 if (c == -1)
1014 {
1015 continue;
1016 }
1017 tempbuf[tempbufindex++] = c;
1018 break;
1019 default:
1020 tempbuf[tempbufindex++] = *tokptr++;
1021 break;
1022 }
1023 } while ((*tokptr != '"') && (*tokptr != '\0'));
1024 if (*tokptr++ != '"')
1025 {
1026 error ("Unterminated string in expression.");
1027 }
1028 tempbuf[tempbufindex] = '\0'; /* See note above */
1029 yylval.sval.ptr = tempbuf;
1030 yylval.sval.length = tempbufindex;
1031 lexptr = tokptr;
1032 return (STRING_LITERAL);
1033 }
1034
1035 if (!(c == '_' || c == '$'
1036 || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
1037 /* We must have come across a bad character (e.g. ';'). */
1038 error ("Invalid character '%c' in expression.", c);
1039
1040 /* It's a name. See how long it is. */
1041 namelen = 0;
1042 for (c = tokstart[namelen];
1043 (c == '_' || c == '$' || (c >= '0' && c <= '9')
1044 || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');)
1045 {
1046 if (c == '<')
1047 {
1048 int i = namelen;
1049 while (tokstart[++i] && tokstart[i] != '>');
1050 if (tokstart[i] == '>')
1051 namelen = i;
1052 }
1053 c = tokstart[++namelen];
1054 }
1055
1056 /* The token "if" terminates the expression and is NOT
1057 removed from the input stream. */
1058 if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
1059 {
1060 return 0;
1061 }
1062
1063 lexptr += namelen;
1064
1065 tryname:
1066
1067 /* Catch specific keywords. Should be done with a data structure. */
1068 switch (namelen)
1069 {
1070 case 7:
1071 if (STREQN (tokstart, "boolean", 7))
1072 return BOOLEAN;
1073 break;
1074 case 6:
1075 if (STREQN (tokstart, "double", 6))
1076 return DOUBLE;
1077 break;
1078 case 5:
1079 if (STREQN (tokstart, "short", 5))
1080 return SHORT;
1081 if (STREQN (tokstart, "false", 5))
75a947c6
PB
1082 {
1083 yylval.lval = 0;
1084 return BOOLEAN_LITERAL;
1085 }
7a9eb4c4
PB
1086 if (STREQN (tokstart, "super", 5))
1087 return SUPER;
1088 if (STREQN (tokstart, "float", 5))
1089 return FLOAT;
1090 break;
1091 case 4:
1092 if (STREQN (tokstart, "long", 4))
1093 return LONG;
1094 if (STREQN (tokstart, "byte", 4))
1095 return BYTE;
1096 if (STREQN (tokstart, "char", 4))
1097 return CHAR;
1098 if (STREQN (tokstart, "true", 4))
75a947c6
PB
1099 {
1100 yylval.lval = 1;
1101 return BOOLEAN_LITERAL;
1102 }
7a9eb4c4
PB
1103 if (current_language->la_language == language_cplus
1104 && STREQN (tokstart, "this", 4))
1105 {
1106 static const char this_name[] =
1107 { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
1108
1109 if (lookup_symbol (this_name, expression_context_block,
1110 VAR_NAMESPACE, (int *) NULL,
1111 (struct symtab **) NULL))
1112 return THIS;
1113 }
1114 break;
1115 case 3:
1116 if (STREQN (tokstart, "int", 3))
1117 return INT;
1118 if (STREQN (tokstart, "new", 3))
1119 return NEW;
1120 break;
1121 default:
1122 break;
1123 }
1124
1125 yylval.sval.ptr = tokstart;
1126 yylval.sval.length = namelen;
1127
1128 if (*tokstart == '$')
1129 {
1130 write_dollar_variable (yylval.sval);
1131 return VARIABLE;
1132 }
1133
1134 /* Input names that aren't symbols but ARE valid hex numbers,
1135 when the input radix permits them, can be names or numbers
1136 depending on the parse. Note we support radixes > 16 here. */
1137 if (((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) ||
1138 (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
1139 {
1140 YYSTYPE newlval; /* Its value is ignored. */
1141 int hextype = parse_number (tokstart, namelen, 0, &newlval);
1142 if (hextype == INTEGER_LITERAL)
1143 return NAME_OR_INT;
1144 }
1145 return IDENTIFIER;
1146}
1147
1148void
1149yyerror (msg)
1150 char *msg;
1151{
1152 error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
1153}
1154
1155static struct type *
1156java_type_from_name (name)
1157 struct stoken name;
1158
1159{
1160 char *tmp = copy_name (name);
1161 struct type *typ = java_lookup_class (tmp);
1162 if (typ == NULL || TYPE_CODE (typ) != TYPE_CODE_STRUCT)
1163 error ("No class named %s.", tmp);
1164 return typ;
1165}
1166
1167static void
1168push_variable (name)
1169 struct stoken name;
1170
1171{
1172 char *tmp = copy_name (name);
1173 int is_a_field_of_this = 0;
1174 struct symbol *sym;
1175 struct type *typ;
1176 sym = lookup_symbol (tmp, expression_context_block, VAR_NAMESPACE,
1177 &is_a_field_of_this, (struct symtab **) NULL);
1178 if (sym)
1179 {
1180 if (symbol_read_needs_frame (sym))
1181 {
1182 if (innermost_block == 0 ||
1183 contained_in (block_found, innermost_block))
1184 innermost_block = block_found;
1185 }
1186
1187 write_exp_elt_opcode (OP_VAR_VALUE);
1188 /* We want to use the selected frame, not another more inner frame
1189 which happens to be in the same block. */
1190 write_exp_elt_block (NULL);
1191 write_exp_elt_sym (sym);
1192 write_exp_elt_opcode (OP_VAR_VALUE);
1193 return;
1194 }
1195 if (is_a_field_of_this)
1196 {
1197 /* it hangs off of `this'. Must not inadvertently convert from a
1198 method call to data ref. */
1199 if (innermost_block == 0 ||
1200 contained_in (block_found, innermost_block))
1201 innermost_block = block_found;
1202 write_exp_elt_opcode (OP_THIS);
1203 write_exp_elt_opcode (OP_THIS);
1204 write_exp_elt_opcode (STRUCTOP_PTR);
1205 write_exp_string (name);
1206 write_exp_elt_opcode (STRUCTOP_PTR);
1207 return;
1208 }
1209
1210 typ = java_lookup_class (tmp);
1211 if (typ != NULL)
1212 {
1213 write_exp_elt_opcode(OP_TYPE);
1214 write_exp_elt_type(typ);
1215 write_exp_elt_opcode(OP_TYPE);
1216 }
1217 else
1218 {
1219 struct minimal_symbol *msymbol;
1220
1221 msymbol = lookup_minimal_symbol (tmp, NULL, NULL);
1222 if (msymbol != NULL)
1223 {
1224 write_exp_msymbol (msymbol,
1225 lookup_function_type (builtin_type_int),
1226 builtin_type_int);
1227 }
1228 else if (!have_full_symbols () && !have_partial_symbols ())
1229 error ("No symbol table is loaded. Use the \"file\" command.");
1230 else
1231 error ("No symbol \"%s\" in current context.", tmp);
1232 }
1233
1234}
This page took 0.072218 seconds and 4 git commands to generate.