v850 files that weren't being removed if !keep-v850
[deliverable/binutils-gdb.git] / gdb / jv-exp.y
1 /* YACC parser for Java expressions, for GDB.
2 Copyright (C) 1997.
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., 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 "jv-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
102 int
103 yyparse PARAMS ((void));
104
105 static int
106 yylex PARAMS ((void));
107
108 void
109 yyerror PARAMS ((char *));
110
111 static struct type * java_type_from_name PARAMS ((struct stoken));
112 static void push_expression_name PARAMS ((struct stoken));
113 static void push_fieldnames PARAMS ((struct stoken));
114
115 %}
116
117 /* Although the yacc "value" of an expression is not used,
118 since the result is stored in the structure being created,
119 other node types do have values. */
120
121 %union
122 {
123 LONGEST lval;
124 struct {
125 LONGEST val;
126 struct type *type;
127 } typed_val_int;
128 struct {
129 DOUBLEST dval;
130 struct type *type;
131 } typed_val_float;
132 struct symbol *sym;
133 struct type *tval;
134 struct stoken sval;
135 struct ttype tsym;
136 struct symtoken ssym;
137 struct block *bval;
138 enum exp_opcode opcode;
139 struct internalvar *ivar;
140 int *ivec;
141 }
142
143 %{
144 /* YYSTYPE gets defined by %union */
145 static int
146 parse_number PARAMS ((char *, int, int, YYSTYPE *));
147 %}
148
149 %type <lval> rcurly Dims Dims_opt
150 %type <tval> ClassOrInterfaceType ClassType /* ReferenceType Type ArrayType */
151 %type <tval> IntegralType FloatingPointType NumericType PrimitiveType
152
153 %token <typed_val_int> INTEGER_LITERAL
154 %token <typed_val_float> FLOATING_POINT_LITERAL
155
156 %token <sval> IDENTIFIER
157 %token <sval> STRING_LITERAL
158 %token <lval> BOOLEAN_LITERAL
159 %token <tsym> TYPENAME
160 %type <sval> Name SimpleName QualifiedName ForcedName
161
162 /* A NAME_OR_INT is a symbol which is not known in the symbol table,
163 but which would parse as a valid number in the current input radix.
164 E.g. "c" when input_radix==16. Depending on the parse, it will be
165 turned into a name or into a number. */
166
167 %token <sval> NAME_OR_INT
168
169 %token ERROR
170
171 /* Special type cases, put in to allow the parser to distinguish different
172 legal basetypes. */
173 %token LONG SHORT BYTE INT CHAR BOOLEAN DOUBLE FLOAT
174
175 %token VARIABLE
176
177 %token <opcode> ASSIGN_MODIFY
178
179 %token THIS SUPER NEW
180
181 %left ','
182 %right '=' ASSIGN_MODIFY
183 %right '?'
184 %left OROR
185 %left ANDAND
186 %left '|'
187 %left '^'
188 %left '&'
189 %left EQUAL NOTEQUAL
190 %left '<' '>' LEQ GEQ
191 %left LSH RSH
192 %left '+' '-'
193 %left '*' '/' '%'
194 %right INCREMENT DECREMENT
195 %right '.' '[' '('
196
197 \f
198 %%
199
200 start : exp1
201 /* | type_exp FIXME */
202 ;
203
204 StringLiteral:
205 STRING_LITERAL
206 {
207 write_exp_elt_opcode (OP_STRING);
208 write_exp_string ($1);
209 write_exp_elt_opcode (OP_STRING);
210 }
211 ;
212
213 Literal :
214 INTEGER_LITERAL
215 { write_exp_elt_opcode (OP_LONG);
216 write_exp_elt_type ($1.type);
217 write_exp_elt_longcst ((LONGEST)($1.val));
218 write_exp_elt_opcode (OP_LONG); }
219 | NAME_OR_INT
220 { YYSTYPE val;
221 parse_number ($1.ptr, $1.length, 0, &val);
222 write_exp_elt_opcode (OP_LONG);
223 write_exp_elt_type (val.typed_val_int.type);
224 write_exp_elt_longcst ((LONGEST)val.typed_val_int.val);
225 write_exp_elt_opcode (OP_LONG);
226 }
227 | FLOATING_POINT_LITERAL
228 { write_exp_elt_opcode (OP_DOUBLE);
229 write_exp_elt_type ($1.type);
230 write_exp_elt_dblcst ($1.dval);
231 write_exp_elt_opcode (OP_DOUBLE); }
232 | BOOLEAN_LITERAL
233 { write_exp_elt_opcode (OP_LONG);
234 write_exp_elt_type (java_boolean_type);
235 write_exp_elt_longcst ((LONGEST)$1);
236 write_exp_elt_opcode (OP_LONG); }
237 | StringLiteral
238 ;
239
240 /* UNUSED:
241 Type:
242 PrimitiveType
243 | ReferenceType
244 ;
245 */
246
247 PrimitiveType:
248 NumericType
249 | BOOLEAN
250 { $$ = java_boolean_type; }
251 ;
252
253 NumericType:
254 IntegralType
255 | FloatingPointType
256 ;
257
258 IntegralType:
259 BYTE
260 { $$ = java_byte_type; }
261 | SHORT
262 { $$ = java_short_type; }
263 | INT
264 { $$ = java_int_type; }
265 | LONG
266 { $$ = java_long_type; }
267 | CHAR
268 { $$ = java_char_type; }
269 ;
270
271 FloatingPointType:
272 FLOAT
273 { $$ = java_float_type; }
274 | DOUBLE
275 { $$ = java_double_type; }
276 ;
277
278 /* UNUSED:
279 ReferenceType:
280 ClassOrInterfaceType
281 | ArrayType
282 ;
283 */
284
285 ClassOrInterfaceType:
286 Name
287 { $$ = java_type_from_name ($1); }
288 ;
289
290 ClassType:
291 ClassOrInterfaceType
292 ;
293
294 /* UNUSED:
295 ArrayType:
296 PrimitiveType Dims
297 { $$ = java_array_type ($1, $2); }
298 | Name Dims
299 { $$ = java_array_type (java_type_from_name ($1), $2); }
300 ;
301 */
302
303 Name:
304 IDENTIFIER
305 | QualifiedName
306 ;
307
308 ForcedName:
309 SimpleName
310 | QualifiedName
311 ;
312
313 SimpleName:
314 IDENTIFIER
315 | NAME_OR_INT
316 ;
317
318 QualifiedName:
319 Name '.' SimpleName
320 { $$.length = $1.length + $3.length + 1;
321 if ($1.ptr + $1.length + 1 == $3.ptr
322 && $1.ptr[$1.length] == '.')
323 $$.ptr = $1.ptr; /* Optimization. */
324 else
325 {
326 $$.ptr = (char *) malloc ($$.length + 1);
327 make_cleanup (free, $$.ptr);
328 sprintf ($$.ptr, "%.*s.%.*s",
329 $1.length, $1.ptr, $3.length, $3.ptr);
330 } }
331 ;
332
333 /*
334 type_exp: type
335 { write_exp_elt_opcode(OP_TYPE);
336 write_exp_elt_type($1);
337 write_exp_elt_opcode(OP_TYPE);}
338 ;
339 */
340
341 /* Expressions, including the comma operator. */
342 exp1 : Expression
343 | exp1 ',' Expression
344 { write_exp_elt_opcode (BINOP_COMMA); }
345 ;
346
347 Primary:
348 PrimaryNoNewArray
349 | ArrayCreationExpression
350 ;
351
352 PrimaryNoNewArray:
353 Literal
354 | THIS
355 { write_exp_elt_opcode (OP_THIS);
356 write_exp_elt_opcode (OP_THIS); }
357 | '(' Expression ')'
358 | ClassInstanceCreationExpression
359 | FieldAccess
360 | MethodInvocation
361 | ArrayAccess
362 | lcurly ArgumentList rcurly
363 { write_exp_elt_opcode (OP_ARRAY);
364 write_exp_elt_longcst ((LONGEST) 0);
365 write_exp_elt_longcst ((LONGEST) $3);
366 write_exp_elt_opcode (OP_ARRAY); }
367 ;
368
369 lcurly:
370 '{'
371 { start_arglist (); }
372 ;
373
374 rcurly:
375 '}'
376 { $$ = end_arglist () - 1; }
377 ;
378
379 ClassInstanceCreationExpression:
380 NEW ClassType '(' ArgumentList_opt ')'
381 { error ("FIXME - ClassInstanceCreationExpression"); }
382 ;
383
384 ArgumentList:
385 Expression
386 { arglist_len = 1; }
387 | ArgumentList ',' Expression
388 { arglist_len++; }
389 ;
390
391 ArgumentList_opt:
392 /* EMPTY */
393 { arglist_len = 0; }
394 | ArgumentList
395 ;
396
397 ArrayCreationExpression:
398 NEW PrimitiveType DimExprs Dims_opt
399 { error ("FIXME - ArrayCreatiionExpression"); }
400 | NEW ClassOrInterfaceType DimExprs Dims_opt
401 { error ("FIXME - ArrayCreatiionExpression"); }
402 ;
403
404 DimExprs:
405 DimExpr
406 | DimExprs DimExpr
407 ;
408
409 DimExpr:
410 '[' Expression ']'
411 ;
412
413 Dims:
414 '[' ']'
415 { $$ = 1; }
416 | Dims '[' ']'
417 { $$ = $1 + 1; }
418 ;
419
420 Dims_opt:
421 Dims
422 | /* EMPTY */
423 { $$ = 0; }
424 ;
425
426 FieldAccess:
427 Primary '.' SimpleName
428 { push_fieldnames ($3); }
429 /*| SUPER '.' SimpleName { FIXME } */
430 ;
431
432 MethodInvocation:
433 Name '(' ArgumentList_opt ')'
434 { error ("method invocation not implemented"); }
435 | Primary '.' SimpleName '(' ArgumentList_opt ')'
436 { error ("method invocation not implemented"); }
437 | SUPER '.' SimpleName '(' ArgumentList_opt ')'
438 { error ("method invocation not implemented"); }
439 ;
440
441 ArrayAccess:
442 Name '[' Expression ']'
443 /* FIXME - This is nasty - need to shuffle expr stack. */
444 { error ("`Name[Expr]' not implemented yet - try `(Name)[Expr]'"); }
445 | PrimaryNoNewArray '[' Expression ']'
446 {
447 warning("array subscripts not implemented for Java");
448 write_exp_elt_opcode (BINOP_SUBSCRIPT); }
449 ;
450
451 PostfixExpression:
452 Primary
453 | Name
454 { push_expression_name ($1); }
455 | VARIABLE
456 /* Already written by write_dollar_variable. */
457 | PostIncrementExpression
458 | PostDecrementExpression
459 ;
460
461 PostIncrementExpression:
462 PostfixExpression INCREMENT
463 { write_exp_elt_opcode (UNOP_POSTINCREMENT); }
464 ;
465
466 PostDecrementExpression:
467 PostfixExpression DECREMENT
468 { write_exp_elt_opcode (UNOP_POSTDECREMENT); }
469 ;
470
471 UnaryExpression:
472 PreIncrementExpression
473 | PreDecrementExpression
474 | '+' UnaryExpression
475 | '-' UnaryExpression
476 { write_exp_elt_opcode (UNOP_NEG); }
477 | '*' UnaryExpression
478 { write_exp_elt_opcode (UNOP_IND); } /*FIXME not in Java */
479 | UnaryExpressionNotPlusMinus
480 ;
481
482 PreIncrementExpression:
483 INCREMENT UnaryExpression
484 { write_exp_elt_opcode (UNOP_PREINCREMENT); }
485 ;
486
487 PreDecrementExpression:
488 DECREMENT UnaryExpression
489 { write_exp_elt_opcode (UNOP_PREDECREMENT); }
490 ;
491
492 UnaryExpressionNotPlusMinus:
493 PostfixExpression
494 | '~' UnaryExpression
495 { write_exp_elt_opcode (UNOP_COMPLEMENT); }
496 | '!' UnaryExpression
497 { write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
498 | CastExpression
499 ;
500
501 CastExpression:
502 '(' PrimitiveType Dims_opt ')' UnaryExpression
503 { write_exp_elt_opcode (UNOP_CAST);
504 write_exp_elt_type (java_array_type ($2, $3));
505 write_exp_elt_opcode (UNOP_CAST); }
506 | '(' Expression ')' UnaryExpressionNotPlusMinus /* FIXME */
507 | '(' Name Dims ')' UnaryExpressionNotPlusMinus
508 { write_exp_elt_opcode (UNOP_CAST);
509 write_exp_elt_type (java_array_type (java_type_from_name ($2), $3));
510 write_exp_elt_opcode (UNOP_CAST); }
511 ;
512
513
514 MultiplicativeExpression:
515 UnaryExpression
516 | MultiplicativeExpression '*' UnaryExpression
517 { write_exp_elt_opcode (BINOP_MUL); }
518 | MultiplicativeExpression '/' UnaryExpression
519 { write_exp_elt_opcode (BINOP_DIV); }
520 | MultiplicativeExpression '%' UnaryExpression
521 { write_exp_elt_opcode (BINOP_REM); }
522 ;
523
524 AdditiveExpression:
525 MultiplicativeExpression
526 | AdditiveExpression '+' MultiplicativeExpression
527 { write_exp_elt_opcode (BINOP_ADD); }
528 | AdditiveExpression '-' MultiplicativeExpression
529 { write_exp_elt_opcode (BINOP_SUB); }
530 ;
531
532 ShiftExpression:
533 AdditiveExpression
534 | ShiftExpression LSH AdditiveExpression
535 { write_exp_elt_opcode (BINOP_LSH); }
536 | ShiftExpression RSH AdditiveExpression
537 { write_exp_elt_opcode (BINOP_RSH); }
538 /* | ShiftExpression >>> AdditiveExpression { FIXME } */
539 ;
540
541 RelationalExpression:
542 ShiftExpression
543 | RelationalExpression '<' ShiftExpression
544 { write_exp_elt_opcode (BINOP_LESS); }
545 | RelationalExpression '>' ShiftExpression
546 { write_exp_elt_opcode (BINOP_GTR); }
547 | RelationalExpression LEQ ShiftExpression
548 { write_exp_elt_opcode (BINOP_LEQ); }
549 | RelationalExpression GEQ ShiftExpression
550 { write_exp_elt_opcode (BINOP_GEQ); }
551 /* | RelationalExpresion INSTANCEOF ReferenceType { FIXME } */
552 ;
553
554 EqualityExpression:
555 RelationalExpression
556 | EqualityExpression EQUAL RelationalExpression
557 { write_exp_elt_opcode (BINOP_EQUAL); }
558 | EqualityExpression NOTEQUAL RelationalExpression
559 { write_exp_elt_opcode (BINOP_NOTEQUAL); }
560 ;
561
562 AndExpression:
563 EqualityExpression
564 | AndExpression '&' EqualityExpression
565 { write_exp_elt_opcode (BINOP_BITWISE_AND); }
566 ;
567
568 ExclusiveOrExpression:
569 AndExpression
570 | ExclusiveOrExpression '^' AndExpression
571 { write_exp_elt_opcode (BINOP_BITWISE_XOR); }
572 ;
573 InclusiveOrExpression:
574 ExclusiveOrExpression
575 | InclusiveOrExpression '|' ExclusiveOrExpression
576 { write_exp_elt_opcode (BINOP_BITWISE_IOR); }
577 ;
578
579 ConditionalAndExpression:
580 InclusiveOrExpression
581 | ConditionalAndExpression ANDAND InclusiveOrExpression
582 { write_exp_elt_opcode (BINOP_LOGICAL_AND); }
583 ;
584
585 ConditionalOrExpression:
586 ConditionalAndExpression
587 | ConditionalOrExpression OROR ConditionalAndExpression
588 { write_exp_elt_opcode (BINOP_LOGICAL_OR); }
589 ;
590
591 ConditionalExpression:
592 ConditionalOrExpression
593 | ConditionalOrExpression '?' Expression ':' ConditionalExpression
594 { write_exp_elt_opcode (TERNOP_COND); }
595 ;
596
597 AssignmentExpression:
598 ConditionalExpression
599 | Assignment
600 ;
601
602 Assignment:
603 LeftHandSide '=' ConditionalExpression
604 { write_exp_elt_opcode (BINOP_ASSIGN); }
605 | LeftHandSide ASSIGN_MODIFY ConditionalExpression
606 { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
607 write_exp_elt_opcode ($2);
608 write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); }
609 ;
610
611 LeftHandSide:
612 ForcedName
613 { push_expression_name ($1); }
614 | VARIABLE
615 /* Already written by write_dollar_variable. */
616 | FieldAccess
617 | ArrayAccess
618 ;
619
620
621 Expression:
622 AssignmentExpression
623 ;
624
625 %%
626 /* Take care of parsing a number (anything that starts with a digit).
627 Set yylval and return the token type; update lexptr.
628 LEN is the number of characters in it. */
629
630 /*** Needs some error checking for the float case ***/
631
632 static int
633 parse_number (p, len, parsed_float, putithere)
634 register char *p;
635 register int len;
636 int parsed_float;
637 YYSTYPE *putithere;
638 {
639 register ULONGEST n = 0;
640 ULONGEST limit, limit_div_base;
641
642 register int c;
643 register int base = input_radix;
644
645 struct type *type;
646
647 if (parsed_float)
648 {
649 /* It's a float since it contains a point or an exponent. */
650 char c;
651 int num = 0; /* number of tokens scanned by scanf */
652 char saved_char = p[len];
653
654 p[len] = 0; /* null-terminate the token */
655 if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
656 num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval, &c);
657 else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
658 num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval, &c);
659 else
660 {
661 #ifdef PRINTF_HAS_LONG_DOUBLE
662 num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval, &c);
663 #else
664 /* Scan it into a double, then assign it to the long double.
665 This at least wins with values representable in the range
666 of doubles. */
667 double temp;
668 num = sscanf (p, "%lg%c", &temp, &c);
669 putithere->typed_val_float.dval = temp;
670 #endif
671 }
672 p[len] = saved_char; /* restore the input stream */
673 if (num != 1) /* check scanf found ONLY a float ... */
674 return ERROR;
675 /* See if it has `f' or `d' suffix (float or double). */
676
677 c = tolower (p[len - 1]);
678
679 if (c == 'f' || c == 'F')
680 putithere->typed_val_float.type = builtin_type_float;
681 else if (isdigit (c) || c == '.' || c == 'd' || c == 'D')
682 putithere->typed_val_float.type = builtin_type_double;
683 else
684 return ERROR;
685
686 return FLOATING_POINT_LITERAL;
687 }
688
689 /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
690 if (p[0] == '0')
691 switch (p[1])
692 {
693 case 'x':
694 case 'X':
695 if (len >= 3)
696 {
697 p += 2;
698 base = 16;
699 len -= 2;
700 }
701 break;
702
703 case 't':
704 case 'T':
705 case 'd':
706 case 'D':
707 if (len >= 3)
708 {
709 p += 2;
710 base = 10;
711 len -= 2;
712 }
713 break;
714
715 default:
716 base = 8;
717 break;
718 }
719
720 c = p[len-1];
721 limit = (ULONGEST)0xffffffff;
722 if (c == 'l' || c == 'L')
723 {
724 type = java_long_type;
725 len--;
726 /* A paranoid calculation of (1<<64)-1. */
727 limit = ((limit << 16) << 16) | limit;
728 }
729 else
730 {
731 type = java_int_type;
732 }
733 limit_div_base = limit / (ULONGEST) base;
734
735 while (--len >= 0)
736 {
737 c = *p++;
738 if (c >= '0' && c <= '9')
739 c -= '0';
740 else if (c >= 'A' && c <= 'Z')
741 c -= 'A' - 10;
742 else if (c >= 'a' && c <= 'z')
743 c -= 'a' - 10;
744 else
745 return ERROR; /* Char not a digit */
746 if (c >= base)
747 return ERROR;
748 if (n > limit_div_base
749 || (n *= base) > limit - c)
750 error ("Numeric constant too large.");
751 n += c;
752 }
753
754 putithere->typed_val_int.val = n;
755 putithere->typed_val_int.type = type;
756 return INTEGER_LITERAL;
757 }
758
759 struct token
760 {
761 char *operator;
762 int token;
763 enum exp_opcode opcode;
764 };
765
766 static const struct token tokentab3[] =
767 {
768 {">>=", ASSIGN_MODIFY, BINOP_RSH},
769 {"<<=", ASSIGN_MODIFY, BINOP_LSH}
770 };
771
772 static const struct token tokentab2[] =
773 {
774 {"+=", ASSIGN_MODIFY, BINOP_ADD},
775 {"-=", ASSIGN_MODIFY, BINOP_SUB},
776 {"*=", ASSIGN_MODIFY, BINOP_MUL},
777 {"/=", ASSIGN_MODIFY, BINOP_DIV},
778 {"%=", ASSIGN_MODIFY, BINOP_REM},
779 {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR},
780 {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND},
781 {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR},
782 {"++", INCREMENT, BINOP_END},
783 {"--", DECREMENT, BINOP_END},
784 {"&&", ANDAND, BINOP_END},
785 {"||", OROR, BINOP_END},
786 {"<<", LSH, BINOP_END},
787 {">>", RSH, BINOP_END},
788 {"==", EQUAL, BINOP_END},
789 {"!=", NOTEQUAL, BINOP_END},
790 {"<=", LEQ, BINOP_END},
791 {">=", GEQ, BINOP_END}
792 };
793
794 /* Read one token, getting characters through lexptr. */
795
796 static int
797 yylex ()
798 {
799 int c;
800 int namelen;
801 unsigned int i;
802 char *tokstart;
803 char *tokptr;
804 int tempbufindex;
805 static char *tempbuf;
806 static int tempbufsize;
807
808 retry:
809
810 tokstart = lexptr;
811 /* See if it is a special token of length 3. */
812 for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
813 if (STREQN (tokstart, tokentab3[i].operator, 3))
814 {
815 lexptr += 3;
816 yylval.opcode = tokentab3[i].opcode;
817 return tokentab3[i].token;
818 }
819
820 /* See if it is a special token of length 2. */
821 for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
822 if (STREQN (tokstart, tokentab2[i].operator, 2))
823 {
824 lexptr += 2;
825 yylval.opcode = tokentab2[i].opcode;
826 return tokentab2[i].token;
827 }
828
829 switch (c = *tokstart)
830 {
831 case 0:
832 return 0;
833
834 case ' ':
835 case '\t':
836 case '\n':
837 lexptr++;
838 goto retry;
839
840 case '\'':
841 /* We either have a character constant ('0' or '\177' for example)
842 or we have a quoted symbol reference ('foo(int,int)' in C++
843 for example). */
844 lexptr++;
845 c = *lexptr++;
846 if (c == '\\')
847 c = parse_escape (&lexptr);
848 else if (c == '\'')
849 error ("Empty character constant.");
850
851 yylval.typed_val_int.val = c;
852 yylval.typed_val_int.type = builtin_type_char;
853
854 c = *lexptr++;
855 if (c != '\'')
856 {
857 namelen = skip_quoted (tokstart) - tokstart;
858 if (namelen > 2)
859 {
860 lexptr = tokstart + namelen;
861 if (lexptr[-1] != '\'')
862 error ("Unmatched single quote.");
863 namelen -= 2;
864 tokstart++;
865 goto tryname;
866 }
867 error ("Invalid character constant.");
868 }
869 return INTEGER_LITERAL;
870
871 case '(':
872 paren_depth++;
873 lexptr++;
874 return c;
875
876 case ')':
877 if (paren_depth == 0)
878 return 0;
879 paren_depth--;
880 lexptr++;
881 return c;
882
883 case ',':
884 if (comma_terminates && paren_depth == 0)
885 return 0;
886 lexptr++;
887 return c;
888
889 case '.':
890 /* Might be a floating point number. */
891 if (lexptr[1] < '0' || lexptr[1] > '9')
892 goto symbol; /* Nope, must be a symbol. */
893 /* FALL THRU into number case. */
894
895 case '0':
896 case '1':
897 case '2':
898 case '3':
899 case '4':
900 case '5':
901 case '6':
902 case '7':
903 case '8':
904 case '9':
905 {
906 /* It's a number. */
907 int got_dot = 0, got_e = 0, toktype;
908 register char *p = tokstart;
909 int hex = input_radix > 10;
910
911 if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
912 {
913 p += 2;
914 hex = 1;
915 }
916 else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
917 {
918 p += 2;
919 hex = 0;
920 }
921
922 for (;; ++p)
923 {
924 /* This test includes !hex because 'e' is a valid hex digit
925 and thus does not indicate a floating point number when
926 the radix is hex. */
927 if (!hex && !got_e && (*p == 'e' || *p == 'E'))
928 got_dot = got_e = 1;
929 /* This test does not include !hex, because a '.' always indicates
930 a decimal floating point number regardless of the radix. */
931 else if (!got_dot && *p == '.')
932 got_dot = 1;
933 else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
934 && (*p == '-' || *p == '+'))
935 /* This is the sign of the exponent, not the end of the
936 number. */
937 continue;
938 /* We will take any letters or digits. parse_number will
939 complain if past the radix, or if L or U are not final. */
940 else if ((*p < '0' || *p > '9')
941 && ((*p < 'a' || *p > 'z')
942 && (*p < 'A' || *p > 'Z')))
943 break;
944 }
945 toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
946 if (toktype == ERROR)
947 {
948 char *err_copy = (char *) alloca (p - tokstart + 1);
949
950 memcpy (err_copy, tokstart, p - tokstart);
951 err_copy[p - tokstart] = 0;
952 error ("Invalid number \"%s\".", err_copy);
953 }
954 lexptr = p;
955 return toktype;
956 }
957
958 case '+':
959 case '-':
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 symbol:
978 lexptr++;
979 return c;
980
981 case '"':
982
983 /* Build the gdb internal form of the input string in tempbuf,
984 translating any standard C escape forms seen. Note that the
985 buffer is null byte terminated *only* for the convenience of
986 debugging gdb itself and printing the buffer contents when
987 the buffer contains no embedded nulls. Gdb does not depend
988 upon the buffer being null byte terminated, it uses the length
989 string instead. This allows gdb to handle C strings (as well
990 as strings in other languages) with embedded null bytes */
991
992 tokptr = ++tokstart;
993 tempbufindex = 0;
994
995 do {
996 /* Grow the static temp buffer if necessary, including allocating
997 the first one on demand. */
998 if (tempbufindex + 1 >= tempbufsize)
999 {
1000 tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
1001 }
1002 switch (*tokptr)
1003 {
1004 case '\0':
1005 case '"':
1006 /* Do nothing, loop will terminate. */
1007 break;
1008 case '\\':
1009 tokptr++;
1010 c = parse_escape (&tokptr);
1011 if (c == -1)
1012 {
1013 continue;
1014 }
1015 tempbuf[tempbufindex++] = c;
1016 break;
1017 default:
1018 tempbuf[tempbufindex++] = *tokptr++;
1019 break;
1020 }
1021 } while ((*tokptr != '"') && (*tokptr != '\0'));
1022 if (*tokptr++ != '"')
1023 {
1024 error ("Unterminated string in expression.");
1025 }
1026 tempbuf[tempbufindex] = '\0'; /* See note above */
1027 yylval.sval.ptr = tempbuf;
1028 yylval.sval.length = tempbufindex;
1029 lexptr = tokptr;
1030 return (STRING_LITERAL);
1031 }
1032
1033 if (!(c == '_' || c == '$'
1034 || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
1035 /* We must have come across a bad character (e.g. ';'). */
1036 error ("Invalid character '%c' in expression.", c);
1037
1038 /* It's a name. See how long it is. */
1039 namelen = 0;
1040 for (c = tokstart[namelen];
1041 (c == '_' || c == '$' || (c >= '0' && c <= '9')
1042 || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');)
1043 {
1044 if (c == '<')
1045 {
1046 int i = namelen;
1047 while (tokstart[++i] && tokstart[i] != '>');
1048 if (tokstart[i] == '>')
1049 namelen = i;
1050 }
1051 c = tokstart[++namelen];
1052 }
1053
1054 /* The token "if" terminates the expression and is NOT
1055 removed from the input stream. */
1056 if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
1057 {
1058 return 0;
1059 }
1060
1061 lexptr += namelen;
1062
1063 tryname:
1064
1065 /* Catch specific keywords. Should be done with a data structure. */
1066 switch (namelen)
1067 {
1068 case 7:
1069 if (STREQN (tokstart, "boolean", 7))
1070 return BOOLEAN;
1071 break;
1072 case 6:
1073 if (STREQN (tokstart, "double", 6))
1074 return DOUBLE;
1075 break;
1076 case 5:
1077 if (STREQN (tokstart, "short", 5))
1078 return SHORT;
1079 if (STREQN (tokstart, "false", 5))
1080 {
1081 yylval.lval = 0;
1082 return BOOLEAN_LITERAL;
1083 }
1084 if (STREQN (tokstart, "super", 5))
1085 return SUPER;
1086 if (STREQN (tokstart, "float", 5))
1087 return FLOAT;
1088 break;
1089 case 4:
1090 if (STREQN (tokstart, "long", 4))
1091 return LONG;
1092 if (STREQN (tokstart, "byte", 4))
1093 return BYTE;
1094 if (STREQN (tokstart, "char", 4))
1095 return CHAR;
1096 if (STREQN (tokstart, "true", 4))
1097 {
1098 yylval.lval = 1;
1099 return BOOLEAN_LITERAL;
1100 }
1101 if (current_language->la_language == language_cplus
1102 && STREQN (tokstart, "this", 4))
1103 {
1104 static const char this_name[] =
1105 { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
1106
1107 if (lookup_symbol (this_name, expression_context_block,
1108 VAR_NAMESPACE, (int *) NULL,
1109 (struct symtab **) NULL))
1110 return THIS;
1111 }
1112 break;
1113 case 3:
1114 if (STREQN (tokstart, "int", 3))
1115 return INT;
1116 if (STREQN (tokstart, "new", 3))
1117 return NEW;
1118 break;
1119 default:
1120 break;
1121 }
1122
1123 yylval.sval.ptr = tokstart;
1124 yylval.sval.length = namelen;
1125
1126 if (*tokstart == '$')
1127 {
1128 write_dollar_variable (yylval.sval);
1129 return VARIABLE;
1130 }
1131
1132 /* Input names that aren't symbols but ARE valid hex numbers,
1133 when the input radix permits them, can be names or numbers
1134 depending on the parse. Note we support radixes > 16 here. */
1135 if (((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) ||
1136 (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
1137 {
1138 YYSTYPE newlval; /* Its value is ignored. */
1139 int hextype = parse_number (tokstart, namelen, 0, &newlval);
1140 if (hextype == INTEGER_LITERAL)
1141 return NAME_OR_INT;
1142 }
1143 return IDENTIFIER;
1144 }
1145
1146 void
1147 yyerror (msg)
1148 char *msg;
1149 {
1150 error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
1151 }
1152
1153 static struct type *
1154 java_type_from_name (name)
1155 struct stoken name;
1156
1157 {
1158 char *tmp = copy_name (name);
1159 struct type *typ = java_lookup_class (tmp);
1160 if (typ == NULL || TYPE_CODE (typ) != TYPE_CODE_STRUCT)
1161 error ("No class named %s.", tmp);
1162 return typ;
1163 }
1164
1165 /* If NAME is a valid variable name in this scope, push it and return 1.
1166 Otherwise, return 0. */
1167
1168 static int
1169 push_variable (name)
1170 struct stoken name;
1171
1172 {
1173 char *tmp = copy_name (name);
1174 int is_a_field_of_this = 0;
1175 struct symbol *sym;
1176 sym = lookup_symbol (tmp, expression_context_block, VAR_NAMESPACE,
1177 &is_a_field_of_this, (struct symtab **) NULL);
1178 if (sym && SYMBOL_CLASS (sym) != LOC_TYPEDEF)
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 1;
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 1;
1208 }
1209 return 0;
1210 }
1211
1212 /* Assuming a reference expression has been pushed, emit the
1213 STRUCTOP_STRUCT ops to access the field named NAME. If NAME is a
1214 qualified name (has '.'), generate a field access for each part. */
1215
1216 static void
1217 push_fieldnames (name)
1218 struct stoken name;
1219 {
1220 int i;
1221 struct stoken token;
1222 token.ptr = name.ptr;
1223 for (i = 0; ; i++)
1224 {
1225 if (i == name.length || name.ptr[i] == '.')
1226 {
1227 /* token.ptr is start of current field name. */
1228 token.length = &name.ptr[i] - token.ptr;
1229 write_exp_elt_opcode (STRUCTOP_STRUCT);
1230 write_exp_string (token);
1231 write_exp_elt_opcode (STRUCTOP_STRUCT);
1232 token.ptr += token.length + 1;
1233 }
1234 if (i >= name.length)
1235 break;
1236 }
1237 }
1238
1239 /* Helper routine for push_expression_name.
1240 Handle a qualified name, where DOT_INDEX is the index of the first '.' */
1241
1242 static void
1243 push_qualified_expression_name (name, dot_index)
1244 struct stoken name;
1245 int dot_index;
1246 {
1247 struct stoken token;
1248 char *tmp;
1249 struct type *typ;
1250
1251 token.ptr = name.ptr;
1252 token.length = dot_index;
1253
1254 if (push_variable (token))
1255 {
1256 token.ptr = name.ptr + dot_index + 1;
1257 token.length = name.length - dot_index - 1;
1258 push_fieldnames (token);
1259 return;
1260 }
1261
1262 token.ptr = name.ptr;
1263 for (;;)
1264 {
1265 token.length = dot_index;
1266 tmp = copy_name (token);
1267 typ = java_lookup_class (tmp);
1268 if (typ != NULL)
1269 {
1270 if (dot_index == name.length)
1271 {
1272 write_exp_elt_opcode(OP_TYPE);
1273 write_exp_elt_type(typ);
1274 write_exp_elt_opcode(OP_TYPE);
1275 return;
1276 }
1277 dot_index++; /* Skip '.' */
1278 name.ptr += dot_index;
1279 name.length -= dot_index;
1280 while (dot_index < name.length && name.ptr[dot_index] != '.')
1281 dot_index++;
1282 token.ptr = name.ptr;
1283 token.length = dot_index;
1284 write_exp_elt_opcode (OP_SCOPE);
1285 write_exp_elt_type (typ);
1286 write_exp_string (token);
1287 write_exp_elt_opcode (OP_SCOPE);
1288 if (dot_index < name.length)
1289 {
1290 dot_index++;
1291 name.ptr += dot_index;
1292 name.length -= dot_index;
1293 push_fieldnames (name);
1294 }
1295 return;
1296 }
1297 else if (dot_index >= name.length)
1298 break;
1299 dot_index++; /* Skip '.' */
1300 while (dot_index < name.length && name.ptr[dot_index] != '.')
1301 dot_index++;
1302 }
1303 error ("unknown type `%.*s'", name.length, name.ptr);
1304 }
1305
1306 /* Handle Name in an expression (or LHS).
1307 Handle VAR, TYPE, TYPE.FIELD1....FIELDN and VAR.FIELD1....FIELDN. */
1308
1309 static void
1310 push_expression_name (name)
1311 struct stoken name;
1312 {
1313 char *tmp;
1314 struct type *typ;
1315 char *ptr;
1316 int i;
1317
1318 for (i = 0; i < name.length; i++)
1319 {
1320 if (name.ptr[i] == '.')
1321 {
1322 /* It's a Qualified Expression Name. */
1323 push_qualified_expression_name (name, i);
1324 return;
1325 }
1326 }
1327
1328 /* It's a Simple Expression Name. */
1329
1330 if (push_variable (name))
1331 return;
1332 tmp = copy_name (name);
1333 typ = java_lookup_class (tmp);
1334 if (typ != NULL)
1335 {
1336 write_exp_elt_opcode(OP_TYPE);
1337 write_exp_elt_type(typ);
1338 write_exp_elt_opcode(OP_TYPE);
1339 }
1340 else
1341 {
1342 struct minimal_symbol *msymbol;
1343
1344 msymbol = lookup_minimal_symbol (tmp, NULL, NULL);
1345 if (msymbol != NULL)
1346 {
1347 write_exp_msymbol (msymbol,
1348 lookup_function_type (builtin_type_int),
1349 builtin_type_int);
1350 }
1351 else if (!have_full_symbols () && !have_partial_symbols ())
1352 error ("No symbol table is loaded. Use the \"file\" command.");
1353 else
1354 error ("No symbol \"%s\" in current context.", tmp);
1355 }
1356
1357 }
This page took 0.056669 seconds and 4 git commands to generate.