* serial.c (serial_log_command): Fix fputs_unfiltered calls.
[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
148%type <lval> rcurly BooleanLiteral Dims Dims_opt
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
157%token <tsym> TYPENAME
158%type <sval> Name SimpleName QualifiedName ForcedName
159
160/* A NAME_OR_INT is a symbol which is not known in the symbol table,
161 but which would parse as a valid number in the current input radix.
162 E.g. "c" when input_radix==16. Depending on the parse, it will be
163 turned into a name or into a number. */
164
165%token <sval> NAME_OR_INT
166
167%token ERROR
168
169/* Special type cases, put in to allow the parser to distinguish different
170 legal basetypes. */
171%token LONG SHORT BYTE INT CHAR BOOLEAN DOUBLE FLOAT
172
173%token VARIABLE
174
175%token <opcode> ASSIGN_MODIFY
176
177%token THIS SUPER TRUE FALSE NEW
178
179%left ','
180%right '=' ASSIGN_MODIFY
181%right '?'
182%left OROR
183%left ANDAND
184%left '|'
185%left '^'
186%left '&'
187%left EQUAL NOTEQUAL
188%left '<' '>' LEQ GEQ
189%left LSH RSH
190%left '+' '-'
191%left '*' '/' '%'
192%right INCREMENT DECREMENT
193%right '.' '[' '('
194
195\f
196%%
197
198start : exp1
199/* | type_exp FIXME */
200 ;
201
202StringLiteral:
203 STRING_LITERAL
204 {
205 write_exp_elt_opcode (OP_STRING);
206 write_exp_string ($1);
207 write_exp_elt_opcode (OP_STRING);
208 }
209;
210
211BooleanLiteral:
212 FALSE
213 { $$ = 0; }
214| TRUE
215 { $$ = 1; }
216;
217
218Literal :
219 INTEGER_LITERAL
220 { write_exp_elt_opcode (OP_LONG);
221 write_exp_elt_type ($1.type);
222 write_exp_elt_longcst ((LONGEST)($1.val));
223 write_exp_elt_opcode (OP_LONG); }
224| NAME_OR_INT
225 { YYSTYPE val;
226 parse_number ($1.ptr, $1.length, 0, &val);
227 write_exp_elt_opcode (OP_LONG);
228 write_exp_elt_type (val.typed_val_int.type);
229 write_exp_elt_longcst ((LONGEST)val.typed_val_int.val);
230 write_exp_elt_opcode (OP_LONG);
231 }
232| FLOATING_POINT_LITERAL
233 { write_exp_elt_opcode (OP_DOUBLE);
234 write_exp_elt_type ($1.type);
235 write_exp_elt_dblcst ($1.dval);
236 write_exp_elt_opcode (OP_DOUBLE); }
237| BooleanLiteral
238 { write_exp_elt_opcode (OP_LONG);
239 write_exp_elt_type (java_boolean_type);
240 write_exp_elt_longcst ((LONGEST)$1);
241 write_exp_elt_opcode (OP_LONG); }
242| StringLiteral
243 ;
244
245/* UNUSED:
246Type:
247 PrimitiveType
248| ReferenceType
249;
250*/
251
252PrimitiveType:
253 NumericType
254| BOOLEAN
255 { $$ = java_boolean_type; }
256;
257
258NumericType:
259 IntegralType
260| FloatingPointType
261;
262
263IntegralType:
264 BYTE
265 { $$ = java_byte_type; }
266| SHORT
267 { $$ = java_short_type; }
268| INT
269 { $$ = java_int_type; }
270| LONG
271 { $$ = java_long_type; }
272| CHAR
273 { $$ = java_char_type; }
274;
275
276FloatingPointType:
277 FLOAT
278 { $$ = java_float_type; }
279| DOUBLE
280 { $$ = java_double_type; }
281;
282
283/* UNUSED:
284ReferenceType:
285 ClassOrInterfaceType
286| ArrayType
287;
288*/
289
290ClassOrInterfaceType:
291 Name
292 { $$ = java_type_from_name ($1); }
293;
294
295ClassType:
296 ClassOrInterfaceType
297;
298
299/* UNUSED:
300ArrayType:
301 PrimitiveType Dims
302 { $$ = java_array_type ($1, $2); }
303| Name Dims
304 { $$ = java_array_type (java_type_from_name ($1), $2); }
305;
306*/
307
308Name:
309 IDENTIFIER
310| QualifiedName
311;
312
313ForcedName:
314 SimpleName
315| QualifiedName
316;
317
318SimpleName:
319 IDENTIFIER
320| NAME_OR_INT
321;
322
323QualifiedName:
324 Name '.' SimpleName
325 { $$.length = $1.length + $3.length + 1;
326 if ($1.ptr + $1.length + 1 == $3.ptr
327 && $1.ptr[$1.length] == '.')
328 $$.ptr = $1.ptr; /* Optimization. */
329 else
330 {
331 $$.ptr = (char *) malloc ($$.length + 1);
332 make_cleanup (free, $$.ptr);
333 sprintf ($$.ptr, "%.*s.%.*s",
334 $1.length, $1.ptr, $3.length, $3.ptr);
335 } }
336;
337
338/*
339type_exp: type
340 { write_exp_elt_opcode(OP_TYPE);
341 write_exp_elt_type($1);
342 write_exp_elt_opcode(OP_TYPE);}
343 ;
344 */
345
346/* Expressions, including the comma operator. */
347exp1 : Expression
348 | exp1 ',' Expression
349 { write_exp_elt_opcode (BINOP_COMMA); }
350 ;
351
352Primary:
353 PrimaryNoNewArray
354| ArrayCreationExpression
355;
356
357PrimaryNoNewArray:
358 Literal
359| THIS
360 { write_exp_elt_opcode (OP_THIS);
361 write_exp_elt_opcode (OP_THIS); }
362| '(' Expression ')'
363| ClassInstanceCreationExpression
364| FieldAccess
365| MethodInvocation
366| ArrayAccess
367| lcurly ArgumentList rcurly
368 { write_exp_elt_opcode (OP_ARRAY);
369 write_exp_elt_longcst ((LONGEST) 0);
370 write_exp_elt_longcst ((LONGEST) $3);
371 write_exp_elt_opcode (OP_ARRAY); }
372;
373
374lcurly:
375 '{'
376 { start_arglist (); }
377;
378
379rcurly:
380 '}'
381 { $$ = end_arglist () - 1; }
382;
383
384ClassInstanceCreationExpression:
385 NEW ClassType '(' ArgumentList_opt ')'
386 { error ("FIXME - ClassInstanceCreationExpression"); }
387;
388
389ArgumentList:
390 Expression
391 { arglist_len = 1; }
392| ArgumentList ',' Expression
393 { arglist_len++; }
394;
395
396ArgumentList_opt:
397 /* EMPTY */
398 { arglist_len = 0; }
399| ArgumentList
400;
401
402ArrayCreationExpression:
403 NEW PrimitiveType DimExprs Dims_opt
404 { error ("FIXME - ArrayCreatiionExpression"); }
405| NEW ClassOrInterfaceType DimExprs Dims_opt
406 { error ("FIXME - ArrayCreatiionExpression"); }
407;
408
409DimExprs:
410 DimExpr
411| DimExprs DimExpr
412;
413
414DimExpr:
415 '[' Expression ']'
416;
417
418Dims:
419 '[' ']'
420 { $$ = 1; }
421| Dims '[' ']'
422 { $$ = $1 + 1; }
423;
424
425Dims_opt:
426 Dims
427| /* EMPTY */
428 { $$ = 0; }
429;
430
431FieldAccess:
432 Primary '.' SimpleName
433 { write_exp_elt_opcode (STRUCTOP_STRUCT);
434 write_exp_string ($3);
435 write_exp_elt_opcode (STRUCTOP_STRUCT); }
436/*| SUPER '.' SimpleName { FIXME } */
437;
438
439MethodInvocation:
440 Name '(' ArgumentList_opt ')'
441 { error ("method invocation not implemented"); }
442| Primary '.' SimpleName '(' ArgumentList_opt ')'
443 { error ("method invocation not implemented"); }
444| SUPER '.' SimpleName '(' ArgumentList_opt ')'
445 { error ("method invocation not implemented"); }
446;
447
448ArrayAccess:
449 Name '[' Expression ']'
450 { error ("ArrayAccess"); } /* FIXME - NASTY */
451| PrimaryNoNewArray '[' Expression ']'
452 { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
453;
454
455PostfixExpression:
456 Primary
457| Name
458 { push_variable ($1); }
459| VARIABLE
460 /* Already written by write_dollar_variable. */
461| PostIncrementExpression
462| PostDecrementExpression
463;
464
465PostIncrementExpression:
466 PostfixExpression INCREMENT
467 { write_exp_elt_opcode (UNOP_POSTINCREMENT); }
468;
469
470PostDecrementExpression:
471 PostfixExpression DECREMENT
472 { write_exp_elt_opcode (UNOP_POSTDECREMENT); }
473;
474
475UnaryExpression:
476 PreIncrementExpression
477| PreDecrementExpression
478| '+' UnaryExpression
479| '-' UnaryExpression
480 { write_exp_elt_opcode (UNOP_NEG); }
481| '*' UnaryExpression
482 { write_exp_elt_opcode (UNOP_IND); } /*FIXME not in Java */
483| UnaryExpressionNotPlusMinus
484;
485
486PreIncrementExpression:
487 INCREMENT UnaryExpression
488 { write_exp_elt_opcode (UNOP_PREINCREMENT); }
489;
490
491PreDecrementExpression:
492 DECREMENT UnaryExpression
493 { write_exp_elt_opcode (UNOP_PREDECREMENT); }
494;
495
496UnaryExpressionNotPlusMinus:
497 PostfixExpression
498| '~' UnaryExpression
499 { write_exp_elt_opcode (UNOP_COMPLEMENT); }
500| '!' UnaryExpression
501 { write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
502| CastExpression
503 ;
504
505CastExpression:
506 '(' PrimitiveType Dims_opt ')' UnaryExpression
507 { write_exp_elt_opcode (UNOP_CAST);
508 write_exp_elt_type (java_array_type ($2, $3));
509 write_exp_elt_opcode (UNOP_CAST); }
510| '(' Expression ')' UnaryExpressionNotPlusMinus /* FIXME */
511| '(' Name Dims ')' UnaryExpressionNotPlusMinus
512 { write_exp_elt_opcode (UNOP_CAST);
513 write_exp_elt_type (java_array_type (java_type_from_name ($2), $3));
514 write_exp_elt_opcode (UNOP_CAST); }
515;
516
517
518MultiplicativeExpression:
519 UnaryExpression
520| MultiplicativeExpression '*' UnaryExpression
521 { write_exp_elt_opcode (BINOP_MUL); }
522| MultiplicativeExpression '/' UnaryExpression
523 { write_exp_elt_opcode (BINOP_DIV); }
524| MultiplicativeExpression '%' UnaryExpression
525 { write_exp_elt_opcode (BINOP_REM); }
526;
527
528AdditiveExpression:
529 MultiplicativeExpression
530| AdditiveExpression '+' MultiplicativeExpression
531 { write_exp_elt_opcode (BINOP_ADD); }
532| AdditiveExpression '-' MultiplicativeExpression
533 { write_exp_elt_opcode (BINOP_SUB); }
534;
535
536ShiftExpression:
537 AdditiveExpression
538| ShiftExpression LSH AdditiveExpression
539 { write_exp_elt_opcode (BINOP_LSH); }
540| ShiftExpression RSH AdditiveExpression
541 { write_exp_elt_opcode (BINOP_RSH); }
542/* | ShiftExpression >>> AdditiveExpression { FIXME } */
543;
544
545RelationalExpression:
546 ShiftExpression
547| RelationalExpression '<' ShiftExpression
548 { write_exp_elt_opcode (BINOP_LESS); }
549| RelationalExpression '>' ShiftExpression
550 { write_exp_elt_opcode (BINOP_GTR); }
551| RelationalExpression LEQ ShiftExpression
552 { write_exp_elt_opcode (BINOP_LEQ); }
553| RelationalExpression GEQ ShiftExpression
554 { write_exp_elt_opcode (BINOP_GEQ); }
555/* | RelationalExpresion INSTANCEOF ReferenceType { FIXME } */
556;
557
558EqualityExpression:
559 RelationalExpression
560| EqualityExpression EQUAL RelationalExpression
561 { write_exp_elt_opcode (BINOP_EQUAL); }
562| EqualityExpression NOTEQUAL RelationalExpression
563 { write_exp_elt_opcode (BINOP_NOTEQUAL); }
564;
565
566AndExpression:
567 EqualityExpression
568| AndExpression '&' EqualityExpression
569 { write_exp_elt_opcode (BINOP_BITWISE_AND); }
570;
571
572ExclusiveOrExpression:
573 AndExpression
574| ExclusiveOrExpression '^' AndExpression
575 { write_exp_elt_opcode (BINOP_BITWISE_XOR); }
576;
577InclusiveOrExpression:
578 ExclusiveOrExpression
579| InclusiveOrExpression '|' ExclusiveOrExpression
580 { write_exp_elt_opcode (BINOP_BITWISE_IOR); }
581;
582
583ConditionalAndExpression:
584 InclusiveOrExpression
585| ConditionalAndExpression ANDAND InclusiveOrExpression
586 { write_exp_elt_opcode (BINOP_LOGICAL_AND); }
587;
588
589ConditionalOrExpression:
590 ConditionalAndExpression
591| ConditionalOrExpression OROR ConditionalAndExpression
592 { write_exp_elt_opcode (BINOP_LOGICAL_OR); }
593;
594
595ConditionalExpression:
596 ConditionalOrExpression
597| ConditionalOrExpression '?' Expression ':' ConditionalExpression
598 { write_exp_elt_opcode (TERNOP_COND); }
599;
600
601AssignmentExpression:
602 ConditionalExpression
603| Assignment
604;
605
606Assignment:
607 LeftHandSide '=' ConditionalExpression
608 { write_exp_elt_opcode (BINOP_ASSIGN); }
609| LeftHandSide ASSIGN_MODIFY ConditionalExpression
610 { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
611 write_exp_elt_opcode ($2);
612 write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); }
613;
614
615LeftHandSide:
616 ForcedName
617 { push_variable ($1); }
618| VARIABLE
619 /* Already written by write_dollar_variable. */
620| FieldAccess
621| ArrayAccess
622;
623
624
625Expression:
626 AssignmentExpression
627;
628
629%%
630/* Take care of parsing a number (anything that starts with a digit).
631 Set yylval and return the token type; update lexptr.
632 LEN is the number of characters in it. */
633
634/*** Needs some error checking for the float case ***/
635
636static int
637parse_number (p, len, parsed_float, putithere)
638 register char *p;
639 register int len;
640 int parsed_float;
641 YYSTYPE *putithere;
642{
643 register ULONGEST n = 0;
644 ULONGEST limit, limit_div_base;
645
646 register int c;
647 register int base = input_radix;
648 int unsigned_p = 0;
649
650 struct type *type;
651
652 if (parsed_float)
653 {
654 /* It's a float since it contains a point or an exponent. */
655
656 if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
657 sscanf (p, "%g", &putithere->typed_val_float.dval);
658 else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
659 sscanf (p, "%lg", &putithere->typed_val_float.dval);
660 else
661 {
662#ifdef PRINTF_HAS_LONG_DOUBLE
663 sscanf (p, "%Lg", &putithere->typed_val_float.dval);
664#else
665 /* Scan it into a double, then assign it to the long double.
666 This at least wins with values representable in the range
667 of doubles. */
668 double temp;
669 sscanf (p, "%lg", &temp);
670 putithere->typed_val_float.dval = temp;
671#endif
672 }
673
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))
1082 return FALSE;
1083 if (STREQN (tokstart, "super", 5))
1084 return SUPER;
1085 if (STREQN (tokstart, "float", 5))
1086 return FLOAT;
1087 break;
1088 case 4:
1089 if (STREQN (tokstart, "long", 4))
1090 return LONG;
1091 if (STREQN (tokstart, "byte", 4))
1092 return BYTE;
1093 if (STREQN (tokstart, "char", 4))
1094 return CHAR;
1095 if (STREQN (tokstart, "true", 4))
1096 return TRUE;
1097 if (current_language->la_language == language_cplus
1098 && STREQN (tokstart, "this", 4))
1099 {
1100 static const char this_name[] =
1101 { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
1102
1103 if (lookup_symbol (this_name, expression_context_block,
1104 VAR_NAMESPACE, (int *) NULL,
1105 (struct symtab **) NULL))
1106 return THIS;
1107 }
1108 break;
1109 case 3:
1110 if (STREQN (tokstart, "int", 3))
1111 return INT;
1112 if (STREQN (tokstart, "new", 3))
1113 return NEW;
1114 break;
1115 default:
1116 break;
1117 }
1118
1119 yylval.sval.ptr = tokstart;
1120 yylval.sval.length = namelen;
1121
1122 if (*tokstart == '$')
1123 {
1124 write_dollar_variable (yylval.sval);
1125 return VARIABLE;
1126 }
1127
1128 /* Input names that aren't symbols but ARE valid hex numbers,
1129 when the input radix permits them, can be names or numbers
1130 depending on the parse. Note we support radixes > 16 here. */
1131 if (((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) ||
1132 (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
1133 {
1134 YYSTYPE newlval; /* Its value is ignored. */
1135 int hextype = parse_number (tokstart, namelen, 0, &newlval);
1136 if (hextype == INTEGER_LITERAL)
1137 return NAME_OR_INT;
1138 }
1139 return IDENTIFIER;
1140}
1141
1142void
1143yyerror (msg)
1144 char *msg;
1145{
1146 error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
1147}
1148
1149static struct type *
1150java_type_from_name (name)
1151 struct stoken name;
1152
1153{
1154 char *tmp = copy_name (name);
1155 struct type *typ = java_lookup_class (tmp);
1156 if (typ == NULL || TYPE_CODE (typ) != TYPE_CODE_STRUCT)
1157 error ("No class named %s.", tmp);
1158 return typ;
1159}
1160
1161static void
1162push_variable (name)
1163 struct stoken name;
1164
1165{
1166 char *tmp = copy_name (name);
1167 int is_a_field_of_this = 0;
1168 struct symbol *sym;
1169 struct type *typ;
1170 sym = lookup_symbol (tmp, expression_context_block, VAR_NAMESPACE,
1171 &is_a_field_of_this, (struct symtab **) NULL);
1172 if (sym)
1173 {
1174 if (symbol_read_needs_frame (sym))
1175 {
1176 if (innermost_block == 0 ||
1177 contained_in (block_found, innermost_block))
1178 innermost_block = block_found;
1179 }
1180
1181 write_exp_elt_opcode (OP_VAR_VALUE);
1182 /* We want to use the selected frame, not another more inner frame
1183 which happens to be in the same block. */
1184 write_exp_elt_block (NULL);
1185 write_exp_elt_sym (sym);
1186 write_exp_elt_opcode (OP_VAR_VALUE);
1187 return;
1188 }
1189 if (is_a_field_of_this)
1190 {
1191 /* it hangs off of `this'. Must not inadvertently convert from a
1192 method call to data ref. */
1193 if (innermost_block == 0 ||
1194 contained_in (block_found, innermost_block))
1195 innermost_block = block_found;
1196 write_exp_elt_opcode (OP_THIS);
1197 write_exp_elt_opcode (OP_THIS);
1198 write_exp_elt_opcode (STRUCTOP_PTR);
1199 write_exp_string (name);
1200 write_exp_elt_opcode (STRUCTOP_PTR);
1201 return;
1202 }
1203
1204 typ = java_lookup_class (tmp);
1205 if (typ != NULL)
1206 {
1207 write_exp_elt_opcode(OP_TYPE);
1208 write_exp_elt_type(typ);
1209 write_exp_elt_opcode(OP_TYPE);
1210 }
1211 else
1212 {
1213 struct minimal_symbol *msymbol;
1214
1215 msymbol = lookup_minimal_symbol (tmp, NULL, NULL);
1216 if (msymbol != NULL)
1217 {
1218 write_exp_msymbol (msymbol,
1219 lookup_function_type (builtin_type_int),
1220 builtin_type_int);
1221 }
1222 else if (!have_full_symbols () && !have_partial_symbols ())
1223 error ("No symbol table is loaded. Use the \"file\" command.");
1224 else
1225 error ("No symbol \"%s\" in current context.", tmp);
1226 }
1227
1228}
This page took 0.065218 seconds and 4 git commands to generate.