xref: /dflybsd-src/contrib/gdb-7/gdb/jv-exp.y (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* YACC parser for Java expressions, for GDB.
2*ef5ccd6cSJohn Marino    Copyright (C) 1997-2013 Free Software Foundation, Inc.
35796c8dcSSimon Schubert 
45796c8dcSSimon Schubert    This file is part of GDB.
55796c8dcSSimon Schubert 
65796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
75796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
85796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
95796c8dcSSimon Schubert    (at your option) any later version.
105796c8dcSSimon Schubert 
115796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
125796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
135796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
145796c8dcSSimon Schubert    GNU General Public License for more details.
155796c8dcSSimon Schubert 
165796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
175796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
185796c8dcSSimon Schubert 
195796c8dcSSimon Schubert /* Parse a Java expression from text in a string,
205796c8dcSSimon Schubert    and return the result as a  struct expression  pointer.
215796c8dcSSimon Schubert    That structure contains arithmetic operations in reverse polish,
225796c8dcSSimon Schubert    with constants represented by operations that are followed by special data.
235796c8dcSSimon Schubert    See expression.h for the details of the format.
245796c8dcSSimon Schubert    What is important here is that it can be built up sequentially
255796c8dcSSimon Schubert    during the process of parsing; the lower levels of the tree always
265796c8dcSSimon Schubert    come first in the result.  Well, almost always; see ArrayAccess.
275796c8dcSSimon Schubert 
285796c8dcSSimon Schubert    Note that malloc's and realloc's in this file are transformed to
295796c8dcSSimon Schubert    xmalloc and xrealloc respectively by the same sed command in the
305796c8dcSSimon Schubert    makefile that remaps any other malloc/realloc inserted by the parser
315796c8dcSSimon Schubert    generator.  Doing this with #defines and trying to control the interaction
325796c8dcSSimon Schubert    with include files (<malloc.h> and <stdlib.h> for example) just became
335796c8dcSSimon Schubert    too messy, particularly when such includes can be inserted at random
345796c8dcSSimon Schubert    times by the parser generator.  */
355796c8dcSSimon Schubert 
365796c8dcSSimon Schubert %{
375796c8dcSSimon Schubert 
385796c8dcSSimon Schubert #include "defs.h"
395796c8dcSSimon Schubert #include "gdb_string.h"
405796c8dcSSimon Schubert #include <ctype.h>
415796c8dcSSimon Schubert #include "expression.h"
425796c8dcSSimon Schubert #include "value.h"
435796c8dcSSimon Schubert #include "parser-defs.h"
445796c8dcSSimon Schubert #include "language.h"
455796c8dcSSimon Schubert #include "jv-lang.h"
465796c8dcSSimon Schubert #include "bfd.h" /* Required by objfiles.h.  */
475796c8dcSSimon Schubert #include "symfile.h" /* Required by objfiles.h.  */
485796c8dcSSimon Schubert #include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
495796c8dcSSimon Schubert #include "block.h"
505796c8dcSSimon Schubert 
515796c8dcSSimon Schubert #define parse_type builtin_type (parse_gdbarch)
525796c8dcSSimon Schubert #define parse_java_type builtin_java_type (parse_gdbarch)
535796c8dcSSimon Schubert 
545796c8dcSSimon Schubert /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
555796c8dcSSimon Schubert    as well as gratuitiously global symbol names, so we can have multiple
565796c8dcSSimon Schubert    yacc generated parsers in gdb.  Note that these are only the variables
575796c8dcSSimon Schubert    produced by yacc.  If other parser generators (bison, byacc, etc) produce
585796c8dcSSimon Schubert    additional global names that conflict at link time, then those parser
595796c8dcSSimon Schubert    generators need to be fixed instead of adding those names to this list.  */
605796c8dcSSimon Schubert 
615796c8dcSSimon Schubert #define	yymaxdepth java_maxdepth
625796c8dcSSimon Schubert #define	yyparse	java_parse
635796c8dcSSimon Schubert #define	yylex	java_lex
645796c8dcSSimon Schubert #define	yyerror	java_error
655796c8dcSSimon Schubert #define	yylval	java_lval
665796c8dcSSimon Schubert #define	yychar	java_char
675796c8dcSSimon Schubert #define	yydebug	java_debug
685796c8dcSSimon Schubert #define	yypact	java_pact
695796c8dcSSimon Schubert #define	yyr1	java_r1
705796c8dcSSimon Schubert #define	yyr2	java_r2
715796c8dcSSimon Schubert #define	yydef	java_def
725796c8dcSSimon Schubert #define	yychk	java_chk
735796c8dcSSimon Schubert #define	yypgo	java_pgo
745796c8dcSSimon Schubert #define	yyact	java_act
755796c8dcSSimon Schubert #define	yyexca	java_exca
765796c8dcSSimon Schubert #define yyerrflag java_errflag
775796c8dcSSimon Schubert #define yynerrs	java_nerrs
785796c8dcSSimon Schubert #define	yyps	java_ps
795796c8dcSSimon Schubert #define	yypv	java_pv
805796c8dcSSimon Schubert #define	yys	java_s
815796c8dcSSimon Schubert #define	yy_yys	java_yys
825796c8dcSSimon Schubert #define	yystate	java_state
835796c8dcSSimon Schubert #define	yytmp	java_tmp
845796c8dcSSimon Schubert #define	yyv	java_v
855796c8dcSSimon Schubert #define	yy_yyv	java_yyv
865796c8dcSSimon Schubert #define	yyval	java_val
875796c8dcSSimon Schubert #define	yylloc	java_lloc
885796c8dcSSimon Schubert #define yyreds	java_reds		/* With YYDEBUG defined */
895796c8dcSSimon Schubert #define yytoks	java_toks		/* With YYDEBUG defined */
905796c8dcSSimon Schubert #define yyname	java_name		/* With YYDEBUG defined */
915796c8dcSSimon Schubert #define yyrule	java_rule		/* With YYDEBUG defined */
925796c8dcSSimon Schubert #define yylhs	java_yylhs
935796c8dcSSimon Schubert #define yylen	java_yylen
945796c8dcSSimon Schubert #define yydefred java_yydefred
955796c8dcSSimon Schubert #define yydgoto	java_yydgoto
965796c8dcSSimon Schubert #define yysindex java_yysindex
975796c8dcSSimon Schubert #define yyrindex java_yyrindex
985796c8dcSSimon Schubert #define yygindex java_yygindex
995796c8dcSSimon Schubert #define yytable	 java_yytable
1005796c8dcSSimon Schubert #define yycheck	 java_yycheck
101*ef5ccd6cSJohn Marino #define yyss	java_yyss
102*ef5ccd6cSJohn Marino #define yysslim	java_yysslim
103*ef5ccd6cSJohn Marino #define yyssp	java_yyssp
104*ef5ccd6cSJohn Marino #define yystacksize java_yystacksize
105*ef5ccd6cSJohn Marino #define yyvs	java_yyvs
106*ef5ccd6cSJohn Marino #define yyvsp	java_yyvsp
1075796c8dcSSimon Schubert 
1085796c8dcSSimon Schubert #ifndef YYDEBUG
1095796c8dcSSimon Schubert #define	YYDEBUG 1		/* Default to yydebug support */
1105796c8dcSSimon Schubert #endif
1115796c8dcSSimon Schubert 
1125796c8dcSSimon Schubert #define YYFPRINTF parser_fprintf
1135796c8dcSSimon Schubert 
1145796c8dcSSimon Schubert int yyparse (void);
1155796c8dcSSimon Schubert 
1165796c8dcSSimon Schubert static int yylex (void);
1175796c8dcSSimon Schubert 
1185796c8dcSSimon Schubert void yyerror (char *);
1195796c8dcSSimon Schubert 
1205796c8dcSSimon Schubert static struct type *java_type_from_name (struct stoken);
1215796c8dcSSimon Schubert static void push_expression_name (struct stoken);
1225796c8dcSSimon Schubert static void push_fieldnames (struct stoken);
1235796c8dcSSimon Schubert 
1245796c8dcSSimon Schubert static struct expression *copy_exp (struct expression *, int);
1255796c8dcSSimon Schubert static void insert_exp (int, struct expression *);
1265796c8dcSSimon Schubert 
1275796c8dcSSimon Schubert %}
1285796c8dcSSimon Schubert 
1295796c8dcSSimon Schubert /* Although the yacc "value" of an expression is not used,
1305796c8dcSSimon Schubert    since the result is stored in the structure being created,
1315796c8dcSSimon Schubert    other node types do have values.  */
1325796c8dcSSimon Schubert 
1335796c8dcSSimon Schubert %union
1345796c8dcSSimon Schubert   {
1355796c8dcSSimon Schubert     LONGEST lval;
1365796c8dcSSimon Schubert     struct {
1375796c8dcSSimon Schubert       LONGEST val;
1385796c8dcSSimon Schubert       struct type *type;
1395796c8dcSSimon Schubert     } typed_val_int;
1405796c8dcSSimon Schubert     struct {
1415796c8dcSSimon Schubert       DOUBLEST dval;
1425796c8dcSSimon Schubert       struct type *type;
1435796c8dcSSimon Schubert     } typed_val_float;
1445796c8dcSSimon Schubert     struct symbol *sym;
1455796c8dcSSimon Schubert     struct type *tval;
1465796c8dcSSimon Schubert     struct stoken sval;
1475796c8dcSSimon Schubert     struct ttype tsym;
1485796c8dcSSimon Schubert     struct symtoken ssym;
1495796c8dcSSimon Schubert     struct block *bval;
1505796c8dcSSimon Schubert     enum exp_opcode opcode;
1515796c8dcSSimon Schubert     struct internalvar *ivar;
1525796c8dcSSimon Schubert     int *ivec;
1535796c8dcSSimon Schubert   }
1545796c8dcSSimon Schubert 
1555796c8dcSSimon Schubert %{
1565796c8dcSSimon Schubert /* YYSTYPE gets defined by %union */
1575796c8dcSSimon Schubert static int parse_number (char *, int, int, YYSTYPE *);
1585796c8dcSSimon Schubert %}
1595796c8dcSSimon Schubert 
1605796c8dcSSimon Schubert %type <lval> rcurly Dims Dims_opt
1615796c8dcSSimon Schubert %type <tval> ClassOrInterfaceType ClassType /* ReferenceType Type ArrayType */
1625796c8dcSSimon Schubert %type <tval> IntegralType FloatingPointType NumericType PrimitiveType ArrayType PrimitiveOrArrayType
1635796c8dcSSimon Schubert 
1645796c8dcSSimon Schubert %token <typed_val_int> INTEGER_LITERAL
1655796c8dcSSimon Schubert %token <typed_val_float> FLOATING_POINT_LITERAL
1665796c8dcSSimon Schubert 
1675796c8dcSSimon Schubert %token <sval> IDENTIFIER
1685796c8dcSSimon Schubert %token <sval> STRING_LITERAL
1695796c8dcSSimon Schubert %token <lval> BOOLEAN_LITERAL
1705796c8dcSSimon Schubert %token <tsym> TYPENAME
1715796c8dcSSimon Schubert %type <sval> Name SimpleName QualifiedName ForcedName
1725796c8dcSSimon Schubert 
1735796c8dcSSimon Schubert /* A NAME_OR_INT is a symbol which is not known in the symbol table,
1745796c8dcSSimon Schubert    but which would parse as a valid number in the current input radix.
1755796c8dcSSimon Schubert    E.g. "c" when input_radix==16.  Depending on the parse, it will be
1765796c8dcSSimon Schubert    turned into a name or into a number.  */
1775796c8dcSSimon Schubert 
1785796c8dcSSimon Schubert %token <sval> NAME_OR_INT
1795796c8dcSSimon Schubert 
1805796c8dcSSimon Schubert %token ERROR
1815796c8dcSSimon Schubert 
1825796c8dcSSimon Schubert /* Special type cases, put in to allow the parser to distinguish different
1835796c8dcSSimon Schubert    legal basetypes.  */
1845796c8dcSSimon Schubert %token LONG SHORT BYTE INT CHAR BOOLEAN DOUBLE FLOAT
1855796c8dcSSimon Schubert 
1865796c8dcSSimon Schubert %token VARIABLE
1875796c8dcSSimon Schubert 
1885796c8dcSSimon Schubert %token <opcode> ASSIGN_MODIFY
1895796c8dcSSimon Schubert 
1905796c8dcSSimon Schubert %token SUPER NEW
1915796c8dcSSimon Schubert 
1925796c8dcSSimon Schubert %left ','
1935796c8dcSSimon Schubert %right '=' ASSIGN_MODIFY
1945796c8dcSSimon Schubert %right '?'
1955796c8dcSSimon Schubert %left OROR
1965796c8dcSSimon Schubert %left ANDAND
1975796c8dcSSimon Schubert %left '|'
1985796c8dcSSimon Schubert %left '^'
1995796c8dcSSimon Schubert %left '&'
2005796c8dcSSimon Schubert %left EQUAL NOTEQUAL
2015796c8dcSSimon Schubert %left '<' '>' LEQ GEQ
2025796c8dcSSimon Schubert %left LSH RSH
2035796c8dcSSimon Schubert %left '+' '-'
2045796c8dcSSimon Schubert %left '*' '/' '%'
2055796c8dcSSimon Schubert %right INCREMENT DECREMENT
2065796c8dcSSimon Schubert %right '.' '[' '('
2075796c8dcSSimon Schubert 
2085796c8dcSSimon Schubert 
2095796c8dcSSimon Schubert %%
2105796c8dcSSimon Schubert 
2115796c8dcSSimon Schubert start   :	exp1
2125796c8dcSSimon Schubert 	|	type_exp
2135796c8dcSSimon Schubert 	;
2145796c8dcSSimon Schubert 
2155796c8dcSSimon Schubert type_exp:	PrimitiveOrArrayType
2165796c8dcSSimon Schubert 		{
2175796c8dcSSimon Schubert 		  write_exp_elt_opcode(OP_TYPE);
2185796c8dcSSimon Schubert 		  write_exp_elt_type($1);
2195796c8dcSSimon Schubert 		  write_exp_elt_opcode(OP_TYPE);
2205796c8dcSSimon Schubert 		}
2215796c8dcSSimon Schubert 	;
2225796c8dcSSimon Schubert 
2235796c8dcSSimon Schubert PrimitiveOrArrayType:
2245796c8dcSSimon Schubert 		PrimitiveType
2255796c8dcSSimon Schubert 	|	ArrayType
2265796c8dcSSimon Schubert 	;
2275796c8dcSSimon Schubert 
2285796c8dcSSimon Schubert StringLiteral:
2295796c8dcSSimon Schubert 	STRING_LITERAL
2305796c8dcSSimon Schubert 		{
2315796c8dcSSimon Schubert 		  write_exp_elt_opcode (OP_STRING);
2325796c8dcSSimon Schubert 		  write_exp_string ($1);
2335796c8dcSSimon Schubert 		  write_exp_elt_opcode (OP_STRING);
2345796c8dcSSimon Schubert 		}
2355796c8dcSSimon Schubert ;
2365796c8dcSSimon Schubert 
2375796c8dcSSimon Schubert Literal:
2385796c8dcSSimon Schubert 	INTEGER_LITERAL
2395796c8dcSSimon Schubert 		{ write_exp_elt_opcode (OP_LONG);
2405796c8dcSSimon Schubert 		  write_exp_elt_type ($1.type);
2415796c8dcSSimon Schubert 		  write_exp_elt_longcst ((LONGEST)($1.val));
2425796c8dcSSimon Schubert 		  write_exp_elt_opcode (OP_LONG); }
2435796c8dcSSimon Schubert |	NAME_OR_INT
2445796c8dcSSimon Schubert 		{ YYSTYPE val;
2455796c8dcSSimon Schubert 		  parse_number ($1.ptr, $1.length, 0, &val);
2465796c8dcSSimon Schubert 		  write_exp_elt_opcode (OP_LONG);
2475796c8dcSSimon Schubert 		  write_exp_elt_type (val.typed_val_int.type);
2485796c8dcSSimon Schubert 		  write_exp_elt_longcst ((LONGEST)val.typed_val_int.val);
2495796c8dcSSimon Schubert 		  write_exp_elt_opcode (OP_LONG);
2505796c8dcSSimon Schubert 		}
2515796c8dcSSimon Schubert |	FLOATING_POINT_LITERAL
2525796c8dcSSimon Schubert 		{ write_exp_elt_opcode (OP_DOUBLE);
2535796c8dcSSimon Schubert 		  write_exp_elt_type ($1.type);
2545796c8dcSSimon Schubert 		  write_exp_elt_dblcst ($1.dval);
2555796c8dcSSimon Schubert 		  write_exp_elt_opcode (OP_DOUBLE); }
2565796c8dcSSimon Schubert |	BOOLEAN_LITERAL
2575796c8dcSSimon Schubert 		{ write_exp_elt_opcode (OP_LONG);
2585796c8dcSSimon Schubert 		  write_exp_elt_type (parse_java_type->builtin_boolean);
2595796c8dcSSimon Schubert 		  write_exp_elt_longcst ((LONGEST)$1);
2605796c8dcSSimon Schubert 		  write_exp_elt_opcode (OP_LONG); }
2615796c8dcSSimon Schubert |	StringLiteral
2625796c8dcSSimon Schubert 	;
2635796c8dcSSimon Schubert 
2645796c8dcSSimon Schubert /* UNUSED:
2655796c8dcSSimon Schubert Type:
2665796c8dcSSimon Schubert 	PrimitiveType
2675796c8dcSSimon Schubert |	ReferenceType
2685796c8dcSSimon Schubert ;
2695796c8dcSSimon Schubert */
2705796c8dcSSimon Schubert 
2715796c8dcSSimon Schubert PrimitiveType:
2725796c8dcSSimon Schubert 	NumericType
2735796c8dcSSimon Schubert |	BOOLEAN
2745796c8dcSSimon Schubert 		{ $$ = parse_java_type->builtin_boolean; }
2755796c8dcSSimon Schubert ;
2765796c8dcSSimon Schubert 
2775796c8dcSSimon Schubert NumericType:
2785796c8dcSSimon Schubert 	IntegralType
2795796c8dcSSimon Schubert |	FloatingPointType
2805796c8dcSSimon Schubert ;
2815796c8dcSSimon Schubert 
2825796c8dcSSimon Schubert IntegralType:
2835796c8dcSSimon Schubert 	BYTE
2845796c8dcSSimon Schubert 		{ $$ = parse_java_type->builtin_byte; }
2855796c8dcSSimon Schubert |	SHORT
2865796c8dcSSimon Schubert 		{ $$ = parse_java_type->builtin_short; }
2875796c8dcSSimon Schubert |	INT
2885796c8dcSSimon Schubert 		{ $$ = parse_java_type->builtin_int; }
2895796c8dcSSimon Schubert |	LONG
2905796c8dcSSimon Schubert 		{ $$ = parse_java_type->builtin_long; }
2915796c8dcSSimon Schubert |	CHAR
2925796c8dcSSimon Schubert 		{ $$ = parse_java_type->builtin_char; }
2935796c8dcSSimon Schubert ;
2945796c8dcSSimon Schubert 
2955796c8dcSSimon Schubert FloatingPointType:
2965796c8dcSSimon Schubert 	FLOAT
2975796c8dcSSimon Schubert 		{ $$ = parse_java_type->builtin_float; }
2985796c8dcSSimon Schubert |	DOUBLE
2995796c8dcSSimon Schubert 		{ $$ = parse_java_type->builtin_double; }
3005796c8dcSSimon Schubert ;
3015796c8dcSSimon Schubert 
3025796c8dcSSimon Schubert /* UNUSED:
3035796c8dcSSimon Schubert ReferenceType:
3045796c8dcSSimon Schubert 	ClassOrInterfaceType
3055796c8dcSSimon Schubert |	ArrayType
3065796c8dcSSimon Schubert ;
3075796c8dcSSimon Schubert */
3085796c8dcSSimon Schubert 
3095796c8dcSSimon Schubert ClassOrInterfaceType:
3105796c8dcSSimon Schubert 	Name
3115796c8dcSSimon Schubert 		{ $$ = java_type_from_name ($1); }
3125796c8dcSSimon Schubert ;
3135796c8dcSSimon Schubert 
3145796c8dcSSimon Schubert ClassType:
3155796c8dcSSimon Schubert 	ClassOrInterfaceType
3165796c8dcSSimon Schubert ;
3175796c8dcSSimon Schubert 
3185796c8dcSSimon Schubert ArrayType:
3195796c8dcSSimon Schubert 	PrimitiveType Dims
3205796c8dcSSimon Schubert 		{ $$ = java_array_type ($1, $2); }
3215796c8dcSSimon Schubert |	Name Dims
3225796c8dcSSimon Schubert 		{ $$ = java_array_type (java_type_from_name ($1), $2); }
3235796c8dcSSimon Schubert ;
3245796c8dcSSimon Schubert 
3255796c8dcSSimon Schubert Name:
3265796c8dcSSimon Schubert 	IDENTIFIER
3275796c8dcSSimon Schubert |	QualifiedName
3285796c8dcSSimon Schubert ;
3295796c8dcSSimon Schubert 
3305796c8dcSSimon Schubert ForcedName:
3315796c8dcSSimon Schubert 	SimpleName
3325796c8dcSSimon Schubert |	QualifiedName
3335796c8dcSSimon Schubert ;
3345796c8dcSSimon Schubert 
3355796c8dcSSimon Schubert SimpleName:
3365796c8dcSSimon Schubert 	IDENTIFIER
3375796c8dcSSimon Schubert |	NAME_OR_INT
3385796c8dcSSimon Schubert ;
3395796c8dcSSimon Schubert 
3405796c8dcSSimon Schubert QualifiedName:
3415796c8dcSSimon Schubert 	Name '.' SimpleName
3425796c8dcSSimon Schubert 		{ $$.length = $1.length + $3.length + 1;
3435796c8dcSSimon Schubert 		  if ($1.ptr + $1.length + 1 == $3.ptr
3445796c8dcSSimon Schubert 		      && $1.ptr[$1.length] == '.')
3455796c8dcSSimon Schubert 		    $$.ptr = $1.ptr;  /* Optimization.  */
3465796c8dcSSimon Schubert 		  else
3475796c8dcSSimon Schubert 		    {
3485796c8dcSSimon Schubert 		      $$.ptr = (char *) malloc ($$.length + 1);
3495796c8dcSSimon Schubert 		      make_cleanup (free, $$.ptr);
3505796c8dcSSimon Schubert 		      sprintf ($$.ptr, "%.*s.%.*s",
3515796c8dcSSimon Schubert 			       $1.length, $1.ptr, $3.length, $3.ptr);
3525796c8dcSSimon Schubert 		} }
3535796c8dcSSimon Schubert ;
3545796c8dcSSimon Schubert 
3555796c8dcSSimon Schubert /*
3565796c8dcSSimon Schubert type_exp:	type
3575796c8dcSSimon Schubert 			{ write_exp_elt_opcode(OP_TYPE);
3585796c8dcSSimon Schubert 			  write_exp_elt_type($1);
3595796c8dcSSimon Schubert 			  write_exp_elt_opcode(OP_TYPE);}
3605796c8dcSSimon Schubert 	;
3615796c8dcSSimon Schubert 	*/
3625796c8dcSSimon Schubert 
3635796c8dcSSimon Schubert /* Expressions, including the comma operator.  */
3645796c8dcSSimon Schubert exp1	:	Expression
3655796c8dcSSimon Schubert 	|	exp1 ',' Expression
3665796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_COMMA); }
3675796c8dcSSimon Schubert 	;
3685796c8dcSSimon Schubert 
3695796c8dcSSimon Schubert Primary:
3705796c8dcSSimon Schubert 	PrimaryNoNewArray
3715796c8dcSSimon Schubert |	ArrayCreationExpression
3725796c8dcSSimon Schubert ;
3735796c8dcSSimon Schubert 
3745796c8dcSSimon Schubert PrimaryNoNewArray:
3755796c8dcSSimon Schubert 	Literal
3765796c8dcSSimon Schubert |	'(' Expression ')'
3775796c8dcSSimon Schubert |	ClassInstanceCreationExpression
3785796c8dcSSimon Schubert |	FieldAccess
3795796c8dcSSimon Schubert |	MethodInvocation
3805796c8dcSSimon Schubert |	ArrayAccess
3815796c8dcSSimon Schubert |	lcurly ArgumentList rcurly
3825796c8dcSSimon Schubert 		{ write_exp_elt_opcode (OP_ARRAY);
3835796c8dcSSimon Schubert 		  write_exp_elt_longcst ((LONGEST) 0);
3845796c8dcSSimon Schubert 		  write_exp_elt_longcst ((LONGEST) $3);
3855796c8dcSSimon Schubert 		  write_exp_elt_opcode (OP_ARRAY); }
3865796c8dcSSimon Schubert ;
3875796c8dcSSimon Schubert 
3885796c8dcSSimon Schubert lcurly:
3895796c8dcSSimon Schubert 	'{'
3905796c8dcSSimon Schubert 		{ start_arglist (); }
3915796c8dcSSimon Schubert ;
3925796c8dcSSimon Schubert 
3935796c8dcSSimon Schubert rcurly:
3945796c8dcSSimon Schubert 	'}'
3955796c8dcSSimon Schubert 		{ $$ = end_arglist () - 1; }
3965796c8dcSSimon Schubert ;
3975796c8dcSSimon Schubert 
3985796c8dcSSimon Schubert ClassInstanceCreationExpression:
3995796c8dcSSimon Schubert 	NEW ClassType '(' ArgumentList_opt ')'
4005796c8dcSSimon Schubert 		{ internal_error (__FILE__, __LINE__,
4015796c8dcSSimon Schubert 				  _("FIXME - ClassInstanceCreationExpression")); }
4025796c8dcSSimon Schubert ;
4035796c8dcSSimon Schubert 
4045796c8dcSSimon Schubert ArgumentList:
4055796c8dcSSimon Schubert 	Expression
4065796c8dcSSimon Schubert 		{ arglist_len = 1; }
4075796c8dcSSimon Schubert |	ArgumentList ',' Expression
4085796c8dcSSimon Schubert 		{ arglist_len++; }
4095796c8dcSSimon Schubert ;
4105796c8dcSSimon Schubert 
4115796c8dcSSimon Schubert ArgumentList_opt:
4125796c8dcSSimon Schubert 	/* EMPTY */
4135796c8dcSSimon Schubert 		{ arglist_len = 0; }
4145796c8dcSSimon Schubert | ArgumentList
4155796c8dcSSimon Schubert ;
4165796c8dcSSimon Schubert 
4175796c8dcSSimon Schubert ArrayCreationExpression:
4185796c8dcSSimon Schubert 	NEW PrimitiveType DimExprs Dims_opt
4195796c8dcSSimon Schubert 		{ internal_error (__FILE__, __LINE__,
4205796c8dcSSimon Schubert 				  _("FIXME - ArrayCreationExpression")); }
4215796c8dcSSimon Schubert |	NEW ClassOrInterfaceType DimExprs Dims_opt
4225796c8dcSSimon Schubert 		{ internal_error (__FILE__, __LINE__,
4235796c8dcSSimon Schubert 				  _("FIXME - ArrayCreationExpression")); }
4245796c8dcSSimon Schubert ;
4255796c8dcSSimon Schubert 
4265796c8dcSSimon Schubert DimExprs:
4275796c8dcSSimon Schubert 	DimExpr
4285796c8dcSSimon Schubert |	DimExprs DimExpr
4295796c8dcSSimon Schubert ;
4305796c8dcSSimon Schubert 
4315796c8dcSSimon Schubert DimExpr:
4325796c8dcSSimon Schubert 	'[' Expression ']'
4335796c8dcSSimon Schubert ;
4345796c8dcSSimon Schubert 
4355796c8dcSSimon Schubert Dims:
4365796c8dcSSimon Schubert 	'[' ']'
4375796c8dcSSimon Schubert 		{ $$ = 1; }
4385796c8dcSSimon Schubert |	Dims '[' ']'
4395796c8dcSSimon Schubert 	{ $$ = $1 + 1; }
4405796c8dcSSimon Schubert ;
4415796c8dcSSimon Schubert 
4425796c8dcSSimon Schubert Dims_opt:
4435796c8dcSSimon Schubert 	Dims
4445796c8dcSSimon Schubert |	/* EMPTY */
4455796c8dcSSimon Schubert 		{ $$ = 0; }
4465796c8dcSSimon Schubert ;
4475796c8dcSSimon Schubert 
4485796c8dcSSimon Schubert FieldAccess:
4495796c8dcSSimon Schubert 	Primary '.' SimpleName
4505796c8dcSSimon Schubert 		{ push_fieldnames ($3); }
4515796c8dcSSimon Schubert |	VARIABLE '.' SimpleName
4525796c8dcSSimon Schubert 		{ push_fieldnames ($3); }
4535796c8dcSSimon Schubert /*|	SUPER '.' SimpleName { FIXME } */
4545796c8dcSSimon Schubert ;
4555796c8dcSSimon Schubert 
4565796c8dcSSimon Schubert FuncStart:
4575796c8dcSSimon Schubert 	Name '('
4585796c8dcSSimon Schubert                 { push_expression_name ($1); }
4595796c8dcSSimon Schubert ;
4605796c8dcSSimon Schubert 
4615796c8dcSSimon Schubert MethodInvocation:
4625796c8dcSSimon Schubert 	FuncStart
4635796c8dcSSimon Schubert                 { start_arglist(); }
4645796c8dcSSimon Schubert 	ArgumentList_opt ')'
4655796c8dcSSimon Schubert                 { write_exp_elt_opcode (OP_FUNCALL);
4665796c8dcSSimon Schubert 		  write_exp_elt_longcst ((LONGEST) end_arglist ());
4675796c8dcSSimon Schubert 		  write_exp_elt_opcode (OP_FUNCALL); }
4685796c8dcSSimon Schubert |	Primary '.' SimpleName '(' ArgumentList_opt ')'
4695796c8dcSSimon Schubert 		{ error (_("Form of method invocation not implemented")); }
4705796c8dcSSimon Schubert |	SUPER '.' SimpleName '(' ArgumentList_opt ')'
4715796c8dcSSimon Schubert 		{ error (_("Form of method invocation not implemented")); }
4725796c8dcSSimon Schubert ;
4735796c8dcSSimon Schubert 
4745796c8dcSSimon Schubert ArrayAccess:
4755796c8dcSSimon Schubert 	Name '[' Expression ']'
4765796c8dcSSimon Schubert                 {
4775796c8dcSSimon Schubert                   /* Emit code for the Name now, then exchange it in the
4785796c8dcSSimon Schubert 		     expout array with the Expression's code.  We could
4795796c8dcSSimon Schubert 		     introduce a OP_SWAP code or a reversed version of
4805796c8dcSSimon Schubert 		     BINOP_SUBSCRIPT, but that makes the rest of GDB pay
4815796c8dcSSimon Schubert 		     for our parsing kludges.  */
4825796c8dcSSimon Schubert 		  struct expression *name_expr;
4835796c8dcSSimon Schubert 
4845796c8dcSSimon Schubert 		  push_expression_name ($1);
4855796c8dcSSimon Schubert 		  name_expr = copy_exp (expout, expout_ptr);
4865796c8dcSSimon Schubert 		  expout_ptr -= name_expr->nelts;
4875796c8dcSSimon Schubert 		  insert_exp (expout_ptr-length_of_subexp (expout, expout_ptr),
4885796c8dcSSimon Schubert 			      name_expr);
4895796c8dcSSimon Schubert 		  free (name_expr);
4905796c8dcSSimon Schubert 		  write_exp_elt_opcode (BINOP_SUBSCRIPT);
4915796c8dcSSimon Schubert 		}
4925796c8dcSSimon Schubert |	VARIABLE '[' Expression ']'
4935796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_SUBSCRIPT); }
4945796c8dcSSimon Schubert |	PrimaryNoNewArray '[' Expression ']'
4955796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_SUBSCRIPT); }
4965796c8dcSSimon Schubert ;
4975796c8dcSSimon Schubert 
4985796c8dcSSimon Schubert PostfixExpression:
4995796c8dcSSimon Schubert 	Primary
5005796c8dcSSimon Schubert |	Name
5015796c8dcSSimon Schubert 		{ push_expression_name ($1); }
5025796c8dcSSimon Schubert |	VARIABLE
5035796c8dcSSimon Schubert 		/* Already written by write_dollar_variable.  */
5045796c8dcSSimon Schubert |	PostIncrementExpression
5055796c8dcSSimon Schubert |	PostDecrementExpression
5065796c8dcSSimon Schubert ;
5075796c8dcSSimon Schubert 
5085796c8dcSSimon Schubert PostIncrementExpression:
5095796c8dcSSimon Schubert 	PostfixExpression INCREMENT
5105796c8dcSSimon Schubert 		{ write_exp_elt_opcode (UNOP_POSTINCREMENT); }
5115796c8dcSSimon Schubert ;
5125796c8dcSSimon Schubert 
5135796c8dcSSimon Schubert PostDecrementExpression:
5145796c8dcSSimon Schubert 	PostfixExpression DECREMENT
5155796c8dcSSimon Schubert 		{ write_exp_elt_opcode (UNOP_POSTDECREMENT); }
5165796c8dcSSimon Schubert ;
5175796c8dcSSimon Schubert 
5185796c8dcSSimon Schubert UnaryExpression:
5195796c8dcSSimon Schubert 	PreIncrementExpression
5205796c8dcSSimon Schubert |	PreDecrementExpression
5215796c8dcSSimon Schubert |	'+' UnaryExpression
5225796c8dcSSimon Schubert |	'-' UnaryExpression
5235796c8dcSSimon Schubert 		{ write_exp_elt_opcode (UNOP_NEG); }
5245796c8dcSSimon Schubert |	'*' UnaryExpression
5255796c8dcSSimon Schubert 		{ write_exp_elt_opcode (UNOP_IND); } /*FIXME not in Java  */
5265796c8dcSSimon Schubert |	UnaryExpressionNotPlusMinus
5275796c8dcSSimon Schubert ;
5285796c8dcSSimon Schubert 
5295796c8dcSSimon Schubert PreIncrementExpression:
5305796c8dcSSimon Schubert 	INCREMENT UnaryExpression
5315796c8dcSSimon Schubert 		{ write_exp_elt_opcode (UNOP_PREINCREMENT); }
5325796c8dcSSimon Schubert ;
5335796c8dcSSimon Schubert 
5345796c8dcSSimon Schubert PreDecrementExpression:
5355796c8dcSSimon Schubert 	DECREMENT UnaryExpression
5365796c8dcSSimon Schubert 		{ write_exp_elt_opcode (UNOP_PREDECREMENT); }
5375796c8dcSSimon Schubert ;
5385796c8dcSSimon Schubert 
5395796c8dcSSimon Schubert UnaryExpressionNotPlusMinus:
5405796c8dcSSimon Schubert 	PostfixExpression
5415796c8dcSSimon Schubert |	'~' UnaryExpression
5425796c8dcSSimon Schubert 		{ write_exp_elt_opcode (UNOP_COMPLEMENT); }
5435796c8dcSSimon Schubert |	'!' UnaryExpression
5445796c8dcSSimon Schubert 		{ write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
5455796c8dcSSimon Schubert |	CastExpression
5465796c8dcSSimon Schubert 	;
5475796c8dcSSimon Schubert 
5485796c8dcSSimon Schubert CastExpression:
5495796c8dcSSimon Schubert 	'(' PrimitiveType Dims_opt ')' UnaryExpression
5505796c8dcSSimon Schubert 		{ write_exp_elt_opcode (UNOP_CAST);
5515796c8dcSSimon Schubert 		  write_exp_elt_type (java_array_type ($2, $3));
5525796c8dcSSimon Schubert 		  write_exp_elt_opcode (UNOP_CAST); }
5535796c8dcSSimon Schubert |	'(' Expression ')' UnaryExpressionNotPlusMinus
5545796c8dcSSimon Schubert 		{
5555796c8dcSSimon Schubert 		  int last_exp_size = length_of_subexp(expout, expout_ptr);
5565796c8dcSSimon Schubert 		  struct type *type;
5575796c8dcSSimon Schubert 		  int i;
5585796c8dcSSimon Schubert 		  int base = expout_ptr - last_exp_size - 3;
5595796c8dcSSimon Schubert 		  if (base < 0 || expout->elts[base+2].opcode != OP_TYPE)
5605796c8dcSSimon Schubert 		    error (_("Invalid cast expression"));
5615796c8dcSSimon Schubert 		  type = expout->elts[base+1].type;
5625796c8dcSSimon Schubert 		  /* Remove the 'Expression' and slide the
5635796c8dcSSimon Schubert 		     UnaryExpressionNotPlusMinus down to replace it.  */
5645796c8dcSSimon Schubert 		  for (i = 0;  i < last_exp_size;  i++)
5655796c8dcSSimon Schubert 		    expout->elts[base + i] = expout->elts[base + i + 3];
5665796c8dcSSimon Schubert 		  expout_ptr -= 3;
5675796c8dcSSimon Schubert 		  if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
5685796c8dcSSimon Schubert 		    type = lookup_pointer_type (type);
5695796c8dcSSimon Schubert 		  write_exp_elt_opcode (UNOP_CAST);
5705796c8dcSSimon Schubert 		  write_exp_elt_type (type);
5715796c8dcSSimon Schubert 		  write_exp_elt_opcode (UNOP_CAST);
5725796c8dcSSimon Schubert 		}
5735796c8dcSSimon Schubert |	'(' Name Dims ')' UnaryExpressionNotPlusMinus
5745796c8dcSSimon Schubert 		{ write_exp_elt_opcode (UNOP_CAST);
5755796c8dcSSimon Schubert 		  write_exp_elt_type (java_array_type (java_type_from_name ($2), $3));
5765796c8dcSSimon Schubert 		  write_exp_elt_opcode (UNOP_CAST); }
5775796c8dcSSimon Schubert ;
5785796c8dcSSimon Schubert 
5795796c8dcSSimon Schubert 
5805796c8dcSSimon Schubert MultiplicativeExpression:
5815796c8dcSSimon Schubert 	UnaryExpression
5825796c8dcSSimon Schubert |	MultiplicativeExpression '*' UnaryExpression
5835796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_MUL); }
5845796c8dcSSimon Schubert |	MultiplicativeExpression '/' UnaryExpression
5855796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_DIV); }
5865796c8dcSSimon Schubert |	MultiplicativeExpression '%' UnaryExpression
5875796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_REM); }
5885796c8dcSSimon Schubert ;
5895796c8dcSSimon Schubert 
5905796c8dcSSimon Schubert AdditiveExpression:
5915796c8dcSSimon Schubert 	MultiplicativeExpression
5925796c8dcSSimon Schubert |	AdditiveExpression '+' MultiplicativeExpression
5935796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_ADD); }
5945796c8dcSSimon Schubert |	AdditiveExpression '-' MultiplicativeExpression
5955796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_SUB); }
5965796c8dcSSimon Schubert ;
5975796c8dcSSimon Schubert 
5985796c8dcSSimon Schubert ShiftExpression:
5995796c8dcSSimon Schubert 	AdditiveExpression
6005796c8dcSSimon Schubert |	ShiftExpression LSH AdditiveExpression
6015796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_LSH); }
6025796c8dcSSimon Schubert |	ShiftExpression RSH AdditiveExpression
6035796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_RSH); }
6045796c8dcSSimon Schubert /* |	ShiftExpression >>> AdditiveExpression { FIXME } */
6055796c8dcSSimon Schubert ;
6065796c8dcSSimon Schubert 
6075796c8dcSSimon Schubert RelationalExpression:
6085796c8dcSSimon Schubert 	ShiftExpression
6095796c8dcSSimon Schubert |	RelationalExpression '<' ShiftExpression
6105796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_LESS); }
6115796c8dcSSimon Schubert |	RelationalExpression '>' ShiftExpression
6125796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_GTR); }
6135796c8dcSSimon Schubert |	RelationalExpression LEQ ShiftExpression
6145796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_LEQ); }
6155796c8dcSSimon Schubert |	RelationalExpression GEQ ShiftExpression
6165796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_GEQ); }
6175796c8dcSSimon Schubert /* | RelationalExpresion INSTANCEOF ReferenceType { FIXME } */
6185796c8dcSSimon Schubert ;
6195796c8dcSSimon Schubert 
6205796c8dcSSimon Schubert EqualityExpression:
6215796c8dcSSimon Schubert 	RelationalExpression
6225796c8dcSSimon Schubert |	EqualityExpression EQUAL RelationalExpression
6235796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_EQUAL); }
6245796c8dcSSimon Schubert |	EqualityExpression NOTEQUAL RelationalExpression
6255796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_NOTEQUAL); }
6265796c8dcSSimon Schubert ;
6275796c8dcSSimon Schubert 
6285796c8dcSSimon Schubert AndExpression:
6295796c8dcSSimon Schubert 	EqualityExpression
6305796c8dcSSimon Schubert |	AndExpression '&' EqualityExpression
6315796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_BITWISE_AND); }
6325796c8dcSSimon Schubert ;
6335796c8dcSSimon Schubert 
6345796c8dcSSimon Schubert ExclusiveOrExpression:
6355796c8dcSSimon Schubert 	AndExpression
6365796c8dcSSimon Schubert |	ExclusiveOrExpression '^' AndExpression
6375796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_BITWISE_XOR); }
6385796c8dcSSimon Schubert ;
6395796c8dcSSimon Schubert InclusiveOrExpression:
6405796c8dcSSimon Schubert 	ExclusiveOrExpression
6415796c8dcSSimon Schubert |	InclusiveOrExpression '|' ExclusiveOrExpression
6425796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_BITWISE_IOR); }
6435796c8dcSSimon Schubert ;
6445796c8dcSSimon Schubert 
6455796c8dcSSimon Schubert ConditionalAndExpression:
6465796c8dcSSimon Schubert 	InclusiveOrExpression
6475796c8dcSSimon Schubert |	ConditionalAndExpression ANDAND InclusiveOrExpression
6485796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_LOGICAL_AND); }
6495796c8dcSSimon Schubert ;
6505796c8dcSSimon Schubert 
6515796c8dcSSimon Schubert ConditionalOrExpression:
6525796c8dcSSimon Schubert 	ConditionalAndExpression
6535796c8dcSSimon Schubert |	ConditionalOrExpression OROR ConditionalAndExpression
6545796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_LOGICAL_OR); }
6555796c8dcSSimon Schubert ;
6565796c8dcSSimon Schubert 
6575796c8dcSSimon Schubert ConditionalExpression:
6585796c8dcSSimon Schubert 	ConditionalOrExpression
6595796c8dcSSimon Schubert |	ConditionalOrExpression '?' Expression ':' ConditionalExpression
6605796c8dcSSimon Schubert 		{ write_exp_elt_opcode (TERNOP_COND); }
6615796c8dcSSimon Schubert ;
6625796c8dcSSimon Schubert 
6635796c8dcSSimon Schubert AssignmentExpression:
6645796c8dcSSimon Schubert 	ConditionalExpression
6655796c8dcSSimon Schubert |	Assignment
6665796c8dcSSimon Schubert ;
6675796c8dcSSimon Schubert 
6685796c8dcSSimon Schubert Assignment:
6695796c8dcSSimon Schubert 	LeftHandSide '=' ConditionalExpression
6705796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_ASSIGN); }
6715796c8dcSSimon Schubert |	LeftHandSide ASSIGN_MODIFY ConditionalExpression
6725796c8dcSSimon Schubert 		{ write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
6735796c8dcSSimon Schubert 		  write_exp_elt_opcode ($2);
6745796c8dcSSimon Schubert 		  write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); }
6755796c8dcSSimon Schubert ;
6765796c8dcSSimon Schubert 
6775796c8dcSSimon Schubert LeftHandSide:
6785796c8dcSSimon Schubert 	ForcedName
6795796c8dcSSimon Schubert 		{ push_expression_name ($1); }
6805796c8dcSSimon Schubert |	VARIABLE
6815796c8dcSSimon Schubert 		/* Already written by write_dollar_variable.  */
6825796c8dcSSimon Schubert |	FieldAccess
6835796c8dcSSimon Schubert |	ArrayAccess
6845796c8dcSSimon Schubert ;
6855796c8dcSSimon Schubert 
6865796c8dcSSimon Schubert 
6875796c8dcSSimon Schubert Expression:
6885796c8dcSSimon Schubert 	AssignmentExpression
6895796c8dcSSimon Schubert ;
6905796c8dcSSimon Schubert 
6915796c8dcSSimon Schubert %%
6925796c8dcSSimon Schubert /* Take care of parsing a number (anything that starts with a digit).
6935796c8dcSSimon Schubert    Set yylval and return the token type; update lexptr.
6945796c8dcSSimon Schubert    LEN is the number of characters in it.  */
6955796c8dcSSimon Schubert 
6965796c8dcSSimon Schubert /*** Needs some error checking for the float case ***/
6975796c8dcSSimon Schubert 
6985796c8dcSSimon Schubert static int
6995796c8dcSSimon Schubert parse_number (char *p, int len, int parsed_float, YYSTYPE *putithere)
7005796c8dcSSimon Schubert {
7015796c8dcSSimon Schubert   ULONGEST n = 0;
7025796c8dcSSimon Schubert   ULONGEST limit, limit_div_base;
7035796c8dcSSimon Schubert 
7045796c8dcSSimon Schubert   int c;
7055796c8dcSSimon Schubert   int base = input_radix;
7065796c8dcSSimon Schubert 
7075796c8dcSSimon Schubert   struct type *type;
7085796c8dcSSimon Schubert 
7095796c8dcSSimon Schubert   if (parsed_float)
7105796c8dcSSimon Schubert     {
711c50c785cSJohn Marino       const char *suffix;
712c50c785cSJohn Marino       int suffix_len;
7135796c8dcSSimon Schubert 
714c50c785cSJohn Marino       if (! parse_float (p, len, &putithere->typed_val_float.dval, &suffix))
7155796c8dcSSimon Schubert 	return ERROR;
7165796c8dcSSimon Schubert 
717c50c785cSJohn Marino       suffix_len = p + len - suffix;
7185796c8dcSSimon Schubert 
719c50c785cSJohn Marino       if (suffix_len == 0)
7205796c8dcSSimon Schubert 	putithere->typed_val_float.type = parse_type->builtin_double;
721c50c785cSJohn Marino       else if (suffix_len == 1)
722c50c785cSJohn Marino 	{
723c50c785cSJohn Marino 	  /* See if it has `f' or `d' suffix (float or double).  */
724c50c785cSJohn Marino 	  if (tolower (*suffix) == 'f')
725c50c785cSJohn Marino 	    putithere->typed_val_float.type =
726c50c785cSJohn Marino 	      parse_type->builtin_float;
727c50c785cSJohn Marino 	  else if (tolower (*suffix) == 'd')
728c50c785cSJohn Marino 	    putithere->typed_val_float.type =
729c50c785cSJohn Marino 	      parse_type->builtin_double;
730c50c785cSJohn Marino 	  else
731c50c785cSJohn Marino 	    return ERROR;
732c50c785cSJohn Marino 	}
7335796c8dcSSimon Schubert       else
7345796c8dcSSimon Schubert 	return ERROR;
7355796c8dcSSimon Schubert 
7365796c8dcSSimon Schubert       return FLOATING_POINT_LITERAL;
7375796c8dcSSimon Schubert     }
7385796c8dcSSimon Schubert 
7395796c8dcSSimon Schubert   /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
7405796c8dcSSimon Schubert   if (p[0] == '0')
7415796c8dcSSimon Schubert     switch (p[1])
7425796c8dcSSimon Schubert       {
7435796c8dcSSimon Schubert       case 'x':
7445796c8dcSSimon Schubert       case 'X':
7455796c8dcSSimon Schubert 	if (len >= 3)
7465796c8dcSSimon Schubert 	  {
7475796c8dcSSimon Schubert 	    p += 2;
7485796c8dcSSimon Schubert 	    base = 16;
7495796c8dcSSimon Schubert 	    len -= 2;
7505796c8dcSSimon Schubert 	  }
7515796c8dcSSimon Schubert 	break;
7525796c8dcSSimon Schubert 
7535796c8dcSSimon Schubert       case 't':
7545796c8dcSSimon Schubert       case 'T':
7555796c8dcSSimon Schubert       case 'd':
7565796c8dcSSimon Schubert       case 'D':
7575796c8dcSSimon Schubert 	if (len >= 3)
7585796c8dcSSimon Schubert 	  {
7595796c8dcSSimon Schubert 	    p += 2;
7605796c8dcSSimon Schubert 	    base = 10;
7615796c8dcSSimon Schubert 	    len -= 2;
7625796c8dcSSimon Schubert 	  }
7635796c8dcSSimon Schubert 	break;
7645796c8dcSSimon Schubert 
7655796c8dcSSimon Schubert       default:
7665796c8dcSSimon Schubert 	base = 8;
7675796c8dcSSimon Schubert 	break;
7685796c8dcSSimon Schubert       }
7695796c8dcSSimon Schubert 
7705796c8dcSSimon Schubert   c = p[len-1];
7715796c8dcSSimon Schubert   /* A paranoid calculation of (1<<64)-1.  */
7725796c8dcSSimon Schubert   limit = (ULONGEST)0xffffffff;
7735796c8dcSSimon Schubert   limit = ((limit << 16) << 16) | limit;
7745796c8dcSSimon Schubert   if (c == 'l' || c == 'L')
7755796c8dcSSimon Schubert     {
7765796c8dcSSimon Schubert       type = parse_java_type->builtin_long;
7775796c8dcSSimon Schubert       len--;
7785796c8dcSSimon Schubert     }
7795796c8dcSSimon Schubert   else
7805796c8dcSSimon Schubert     {
7815796c8dcSSimon Schubert       type = parse_java_type->builtin_int;
7825796c8dcSSimon Schubert     }
7835796c8dcSSimon Schubert   limit_div_base = limit / (ULONGEST) base;
7845796c8dcSSimon Schubert 
7855796c8dcSSimon Schubert   while (--len >= 0)
7865796c8dcSSimon Schubert     {
7875796c8dcSSimon Schubert       c = *p++;
7885796c8dcSSimon Schubert       if (c >= '0' && c <= '9')
7895796c8dcSSimon Schubert 	c -= '0';
7905796c8dcSSimon Schubert       else if (c >= 'A' && c <= 'Z')
7915796c8dcSSimon Schubert 	c -= 'A' - 10;
7925796c8dcSSimon Schubert       else if (c >= 'a' && c <= 'z')
7935796c8dcSSimon Schubert 	c -= 'a' - 10;
7945796c8dcSSimon Schubert       else
7955796c8dcSSimon Schubert 	return ERROR;	/* Char not a digit */
7965796c8dcSSimon Schubert       if (c >= base)
7975796c8dcSSimon Schubert 	return ERROR;
7985796c8dcSSimon Schubert       if (n > limit_div_base
7995796c8dcSSimon Schubert 	  || (n *= base) > limit - c)
8005796c8dcSSimon Schubert 	error (_("Numeric constant too large"));
8015796c8dcSSimon Schubert       n += c;
8025796c8dcSSimon Schubert 	}
8035796c8dcSSimon Schubert 
8045796c8dcSSimon Schubert   /* If the type is bigger than a 32-bit signed integer can be, implicitly
8055796c8dcSSimon Schubert      promote to long.  Java does not do this, so mark it as
8065796c8dcSSimon Schubert      parse_type->builtin_uint64 rather than parse_java_type->builtin_long.
8075796c8dcSSimon Schubert      0x80000000 will become -0x80000000 instead of 0x80000000L, because we
8085796c8dcSSimon Schubert      don't know the sign at this point.  */
8095796c8dcSSimon Schubert   if (type == parse_java_type->builtin_int && n > (ULONGEST)0x80000000)
8105796c8dcSSimon Schubert     type = parse_type->builtin_uint64;
8115796c8dcSSimon Schubert 
8125796c8dcSSimon Schubert   putithere->typed_val_int.val = n;
8135796c8dcSSimon Schubert   putithere->typed_val_int.type = type;
8145796c8dcSSimon Schubert 
8155796c8dcSSimon Schubert   return INTEGER_LITERAL;
8165796c8dcSSimon Schubert }
8175796c8dcSSimon Schubert 
8185796c8dcSSimon Schubert struct token
8195796c8dcSSimon Schubert {
8205796c8dcSSimon Schubert   char *operator;
8215796c8dcSSimon Schubert   int token;
8225796c8dcSSimon Schubert   enum exp_opcode opcode;
8235796c8dcSSimon Schubert };
8245796c8dcSSimon Schubert 
8255796c8dcSSimon Schubert static const struct token tokentab3[] =
8265796c8dcSSimon Schubert   {
8275796c8dcSSimon Schubert     {">>=", ASSIGN_MODIFY, BINOP_RSH},
8285796c8dcSSimon Schubert     {"<<=", ASSIGN_MODIFY, BINOP_LSH}
8295796c8dcSSimon Schubert   };
8305796c8dcSSimon Schubert 
8315796c8dcSSimon Schubert static const struct token tokentab2[] =
8325796c8dcSSimon Schubert   {
8335796c8dcSSimon Schubert     {"+=", ASSIGN_MODIFY, BINOP_ADD},
8345796c8dcSSimon Schubert     {"-=", ASSIGN_MODIFY, BINOP_SUB},
8355796c8dcSSimon Schubert     {"*=", ASSIGN_MODIFY, BINOP_MUL},
8365796c8dcSSimon Schubert     {"/=", ASSIGN_MODIFY, BINOP_DIV},
8375796c8dcSSimon Schubert     {"%=", ASSIGN_MODIFY, BINOP_REM},
8385796c8dcSSimon Schubert     {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR},
8395796c8dcSSimon Schubert     {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND},
8405796c8dcSSimon Schubert     {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR},
8415796c8dcSSimon Schubert     {"++", INCREMENT, BINOP_END},
8425796c8dcSSimon Schubert     {"--", DECREMENT, BINOP_END},
8435796c8dcSSimon Schubert     {"&&", ANDAND, BINOP_END},
8445796c8dcSSimon Schubert     {"||", OROR, BINOP_END},
8455796c8dcSSimon Schubert     {"<<", LSH, BINOP_END},
8465796c8dcSSimon Schubert     {">>", RSH, BINOP_END},
8475796c8dcSSimon Schubert     {"==", EQUAL, BINOP_END},
8485796c8dcSSimon Schubert     {"!=", NOTEQUAL, BINOP_END},
8495796c8dcSSimon Schubert     {"<=", LEQ, BINOP_END},
8505796c8dcSSimon Schubert     {">=", GEQ, BINOP_END}
8515796c8dcSSimon Schubert   };
8525796c8dcSSimon Schubert 
8535796c8dcSSimon Schubert /* Read one token, getting characters through lexptr.  */
8545796c8dcSSimon Schubert 
8555796c8dcSSimon Schubert static int
yylex(void)8565796c8dcSSimon Schubert yylex (void)
8575796c8dcSSimon Schubert {
8585796c8dcSSimon Schubert   int c;
8595796c8dcSSimon Schubert   int namelen;
8605796c8dcSSimon Schubert   unsigned int i;
8615796c8dcSSimon Schubert   char *tokstart;
8625796c8dcSSimon Schubert   char *tokptr;
8635796c8dcSSimon Schubert   int tempbufindex;
8645796c8dcSSimon Schubert   static char *tempbuf;
8655796c8dcSSimon Schubert   static int tempbufsize;
8665796c8dcSSimon Schubert 
8675796c8dcSSimon Schubert  retry:
8685796c8dcSSimon Schubert 
8695796c8dcSSimon Schubert   prev_lexptr = lexptr;
8705796c8dcSSimon Schubert 
8715796c8dcSSimon Schubert   tokstart = lexptr;
8725796c8dcSSimon Schubert   /* See if it is a special token of length 3.  */
8735796c8dcSSimon Schubert   for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
8745796c8dcSSimon Schubert     if (strncmp (tokstart, tokentab3[i].operator, 3) == 0)
8755796c8dcSSimon Schubert       {
8765796c8dcSSimon Schubert 	lexptr += 3;
8775796c8dcSSimon Schubert 	yylval.opcode = tokentab3[i].opcode;
8785796c8dcSSimon Schubert 	return tokentab3[i].token;
8795796c8dcSSimon Schubert       }
8805796c8dcSSimon Schubert 
8815796c8dcSSimon Schubert   /* See if it is a special token of length 2.  */
8825796c8dcSSimon Schubert   for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
8835796c8dcSSimon Schubert     if (strncmp (tokstart, tokentab2[i].operator, 2) == 0)
8845796c8dcSSimon Schubert       {
8855796c8dcSSimon Schubert 	lexptr += 2;
8865796c8dcSSimon Schubert 	yylval.opcode = tokentab2[i].opcode;
8875796c8dcSSimon Schubert 	return tokentab2[i].token;
8885796c8dcSSimon Schubert       }
8895796c8dcSSimon Schubert 
8905796c8dcSSimon Schubert   switch (c = *tokstart)
8915796c8dcSSimon Schubert     {
8925796c8dcSSimon Schubert     case 0:
8935796c8dcSSimon Schubert       return 0;
8945796c8dcSSimon Schubert 
8955796c8dcSSimon Schubert     case ' ':
8965796c8dcSSimon Schubert     case '\t':
8975796c8dcSSimon Schubert     case '\n':
8985796c8dcSSimon Schubert       lexptr++;
8995796c8dcSSimon Schubert       goto retry;
9005796c8dcSSimon Schubert 
9015796c8dcSSimon Schubert     case '\'':
9025796c8dcSSimon Schubert       /* We either have a character constant ('0' or '\177' for example)
9035796c8dcSSimon Schubert 	 or we have a quoted symbol reference ('foo(int,int)' in C++
9045796c8dcSSimon Schubert 	 for example).  */
9055796c8dcSSimon Schubert       lexptr++;
9065796c8dcSSimon Schubert       c = *lexptr++;
9075796c8dcSSimon Schubert       if (c == '\\')
908cf7f2e2dSJohn Marino 	c = parse_escape (parse_gdbarch, &lexptr);
9095796c8dcSSimon Schubert       else if (c == '\'')
9105796c8dcSSimon Schubert 	error (_("Empty character constant"));
9115796c8dcSSimon Schubert 
9125796c8dcSSimon Schubert       yylval.typed_val_int.val = c;
9135796c8dcSSimon Schubert       yylval.typed_val_int.type = parse_java_type->builtin_char;
9145796c8dcSSimon Schubert 
9155796c8dcSSimon Schubert       c = *lexptr++;
9165796c8dcSSimon Schubert       if (c != '\'')
9175796c8dcSSimon Schubert 	{
9185796c8dcSSimon Schubert 	  namelen = skip_quoted (tokstart) - tokstart;
9195796c8dcSSimon Schubert 	  if (namelen > 2)
9205796c8dcSSimon Schubert 	    {
9215796c8dcSSimon Schubert 	      lexptr = tokstart + namelen;
9225796c8dcSSimon Schubert 	      if (lexptr[-1] != '\'')
9235796c8dcSSimon Schubert 		error (_("Unmatched single quote"));
9245796c8dcSSimon Schubert 	      namelen -= 2;
9255796c8dcSSimon Schubert 	      tokstart++;
9265796c8dcSSimon Schubert 	      goto tryname;
9275796c8dcSSimon Schubert 	    }
9285796c8dcSSimon Schubert 	  error (_("Invalid character constant"));
9295796c8dcSSimon Schubert 	}
9305796c8dcSSimon Schubert       return INTEGER_LITERAL;
9315796c8dcSSimon Schubert 
9325796c8dcSSimon Schubert     case '(':
9335796c8dcSSimon Schubert       paren_depth++;
9345796c8dcSSimon Schubert       lexptr++;
9355796c8dcSSimon Schubert       return c;
9365796c8dcSSimon Schubert 
9375796c8dcSSimon Schubert     case ')':
9385796c8dcSSimon Schubert       if (paren_depth == 0)
9395796c8dcSSimon Schubert 	return 0;
9405796c8dcSSimon Schubert       paren_depth--;
9415796c8dcSSimon Schubert       lexptr++;
9425796c8dcSSimon Schubert       return c;
9435796c8dcSSimon Schubert 
9445796c8dcSSimon Schubert     case ',':
9455796c8dcSSimon Schubert       if (comma_terminates && paren_depth == 0)
9465796c8dcSSimon Schubert 	return 0;
9475796c8dcSSimon Schubert       lexptr++;
9485796c8dcSSimon Schubert       return c;
9495796c8dcSSimon Schubert 
9505796c8dcSSimon Schubert     case '.':
9515796c8dcSSimon Schubert       /* Might be a floating point number.  */
9525796c8dcSSimon Schubert       if (lexptr[1] < '0' || lexptr[1] > '9')
9535796c8dcSSimon Schubert 	goto symbol;		/* Nope, must be a symbol.  */
9545796c8dcSSimon Schubert       /* FALL THRU into number case.  */
9555796c8dcSSimon Schubert 
9565796c8dcSSimon Schubert     case '0':
9575796c8dcSSimon Schubert     case '1':
9585796c8dcSSimon Schubert     case '2':
9595796c8dcSSimon Schubert     case '3':
9605796c8dcSSimon Schubert     case '4':
9615796c8dcSSimon Schubert     case '5':
9625796c8dcSSimon Schubert     case '6':
9635796c8dcSSimon Schubert     case '7':
9645796c8dcSSimon Schubert     case '8':
9655796c8dcSSimon Schubert     case '9':
9665796c8dcSSimon Schubert       {
9675796c8dcSSimon Schubert 	/* It's a number.  */
9685796c8dcSSimon Schubert 	int got_dot = 0, got_e = 0, toktype;
9695796c8dcSSimon Schubert 	char *p = tokstart;
9705796c8dcSSimon Schubert 	int hex = input_radix > 10;
9715796c8dcSSimon Schubert 
9725796c8dcSSimon Schubert 	if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
9735796c8dcSSimon Schubert 	  {
9745796c8dcSSimon Schubert 	    p += 2;
9755796c8dcSSimon Schubert 	    hex = 1;
9765796c8dcSSimon Schubert 	  }
9775796c8dcSSimon Schubert 	else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
9785796c8dcSSimon Schubert 	  {
9795796c8dcSSimon Schubert 	    p += 2;
9805796c8dcSSimon Schubert 	    hex = 0;
9815796c8dcSSimon Schubert 	  }
9825796c8dcSSimon Schubert 
9835796c8dcSSimon Schubert 	for (;; ++p)
9845796c8dcSSimon Schubert 	  {
9855796c8dcSSimon Schubert 	    /* This test includes !hex because 'e' is a valid hex digit
9865796c8dcSSimon Schubert 	       and thus does not indicate a floating point number when
9875796c8dcSSimon Schubert 	       the radix is hex.  */
9885796c8dcSSimon Schubert 	    if (!hex && !got_e && (*p == 'e' || *p == 'E'))
9895796c8dcSSimon Schubert 	      got_dot = got_e = 1;
9905796c8dcSSimon Schubert 	    /* This test does not include !hex, because a '.' always indicates
9915796c8dcSSimon Schubert 	       a decimal floating point number regardless of the radix.  */
9925796c8dcSSimon Schubert 	    else if (!got_dot && *p == '.')
9935796c8dcSSimon Schubert 	      got_dot = 1;
9945796c8dcSSimon Schubert 	    else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
9955796c8dcSSimon Schubert 		     && (*p == '-' || *p == '+'))
9965796c8dcSSimon Schubert 	      /* This is the sign of the exponent, not the end of the
9975796c8dcSSimon Schubert 		 number.  */
9985796c8dcSSimon Schubert 	      continue;
9995796c8dcSSimon Schubert 	    /* We will take any letters or digits.  parse_number will
10005796c8dcSSimon Schubert 	       complain if past the radix, or if L or U are not final.  */
10015796c8dcSSimon Schubert 	    else if ((*p < '0' || *p > '9')
10025796c8dcSSimon Schubert 		     && ((*p < 'a' || *p > 'z')
10035796c8dcSSimon Schubert 				  && (*p < 'A' || *p > 'Z')))
10045796c8dcSSimon Schubert 	      break;
10055796c8dcSSimon Schubert 	  }
10065796c8dcSSimon Schubert 	toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
10075796c8dcSSimon Schubert         if (toktype == ERROR)
10085796c8dcSSimon Schubert 	  {
10095796c8dcSSimon Schubert 	    char *err_copy = (char *) alloca (p - tokstart + 1);
10105796c8dcSSimon Schubert 
10115796c8dcSSimon Schubert 	    memcpy (err_copy, tokstart, p - tokstart);
10125796c8dcSSimon Schubert 	    err_copy[p - tokstart] = 0;
10135796c8dcSSimon Schubert 	    error (_("Invalid number \"%s\""), err_copy);
10145796c8dcSSimon Schubert 	  }
10155796c8dcSSimon Schubert 	lexptr = p;
10165796c8dcSSimon Schubert 	return toktype;
10175796c8dcSSimon Schubert       }
10185796c8dcSSimon Schubert 
10195796c8dcSSimon Schubert     case '+':
10205796c8dcSSimon Schubert     case '-':
10215796c8dcSSimon Schubert     case '*':
10225796c8dcSSimon Schubert     case '/':
10235796c8dcSSimon Schubert     case '%':
10245796c8dcSSimon Schubert     case '|':
10255796c8dcSSimon Schubert     case '&':
10265796c8dcSSimon Schubert     case '^':
10275796c8dcSSimon Schubert     case '~':
10285796c8dcSSimon Schubert     case '!':
10295796c8dcSSimon Schubert     case '<':
10305796c8dcSSimon Schubert     case '>':
10315796c8dcSSimon Schubert     case '[':
10325796c8dcSSimon Schubert     case ']':
10335796c8dcSSimon Schubert     case '?':
10345796c8dcSSimon Schubert     case ':':
10355796c8dcSSimon Schubert     case '=':
10365796c8dcSSimon Schubert     case '{':
10375796c8dcSSimon Schubert     case '}':
10385796c8dcSSimon Schubert     symbol:
10395796c8dcSSimon Schubert       lexptr++;
10405796c8dcSSimon Schubert       return c;
10415796c8dcSSimon Schubert 
10425796c8dcSSimon Schubert     case '"':
10435796c8dcSSimon Schubert 
10445796c8dcSSimon Schubert       /* Build the gdb internal form of the input string in tempbuf,
10455796c8dcSSimon Schubert 	 translating any standard C escape forms seen.  Note that the
10465796c8dcSSimon Schubert 	 buffer is null byte terminated *only* for the convenience of
10475796c8dcSSimon Schubert 	 debugging gdb itself and printing the buffer contents when
10485796c8dcSSimon Schubert 	 the buffer contains no embedded nulls.  Gdb does not depend
10495796c8dcSSimon Schubert 	 upon the buffer being null byte terminated, it uses the length
10505796c8dcSSimon Schubert 	 string instead.  This allows gdb to handle C strings (as well
10515796c8dcSSimon Schubert 	 as strings in other languages) with embedded null bytes */
10525796c8dcSSimon Schubert 
10535796c8dcSSimon Schubert       tokptr = ++tokstart;
10545796c8dcSSimon Schubert       tempbufindex = 0;
10555796c8dcSSimon Schubert 
10565796c8dcSSimon Schubert       do {
10575796c8dcSSimon Schubert 	/* Grow the static temp buffer if necessary, including allocating
10585796c8dcSSimon Schubert 	   the first one on demand.  */
10595796c8dcSSimon Schubert 	if (tempbufindex + 1 >= tempbufsize)
10605796c8dcSSimon Schubert 	  {
10615796c8dcSSimon Schubert 	    tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
10625796c8dcSSimon Schubert 	  }
10635796c8dcSSimon Schubert 	switch (*tokptr)
10645796c8dcSSimon Schubert 	  {
10655796c8dcSSimon Schubert 	  case '\0':
10665796c8dcSSimon Schubert 	  case '"':
10675796c8dcSSimon Schubert 	    /* Do nothing, loop will terminate.  */
10685796c8dcSSimon Schubert 	    break;
10695796c8dcSSimon Schubert 	  case '\\':
10705796c8dcSSimon Schubert 	    tokptr++;
1071cf7f2e2dSJohn Marino 	    c = parse_escape (parse_gdbarch, &tokptr);
10725796c8dcSSimon Schubert 	    if (c == -1)
10735796c8dcSSimon Schubert 	      {
10745796c8dcSSimon Schubert 		continue;
10755796c8dcSSimon Schubert 	      }
10765796c8dcSSimon Schubert 	    tempbuf[tempbufindex++] = c;
10775796c8dcSSimon Schubert 	    break;
10785796c8dcSSimon Schubert 	  default:
10795796c8dcSSimon Schubert 	    tempbuf[tempbufindex++] = *tokptr++;
10805796c8dcSSimon Schubert 	    break;
10815796c8dcSSimon Schubert 	  }
10825796c8dcSSimon Schubert       } while ((*tokptr != '"') && (*tokptr != '\0'));
10835796c8dcSSimon Schubert       if (*tokptr++ != '"')
10845796c8dcSSimon Schubert 	{
10855796c8dcSSimon Schubert 	  error (_("Unterminated string in expression"));
10865796c8dcSSimon Schubert 	}
10875796c8dcSSimon Schubert       tempbuf[tempbufindex] = '\0';	/* See note above */
10885796c8dcSSimon Schubert       yylval.sval.ptr = tempbuf;
10895796c8dcSSimon Schubert       yylval.sval.length = tempbufindex;
10905796c8dcSSimon Schubert       lexptr = tokptr;
10915796c8dcSSimon Schubert       return (STRING_LITERAL);
10925796c8dcSSimon Schubert     }
10935796c8dcSSimon Schubert 
10945796c8dcSSimon Schubert   if (!(c == '_' || c == '$'
10955796c8dcSSimon Schubert 	|| (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
10965796c8dcSSimon Schubert     /* We must have come across a bad character (e.g. ';').  */
10975796c8dcSSimon Schubert     error (_("Invalid character '%c' in expression"), c);
10985796c8dcSSimon Schubert 
10995796c8dcSSimon Schubert   /* It's a name.  See how long it is.  */
11005796c8dcSSimon Schubert   namelen = 0;
11015796c8dcSSimon Schubert   for (c = tokstart[namelen];
11025796c8dcSSimon Schubert        (c == '_'
11035796c8dcSSimon Schubert 	|| c == '$'
11045796c8dcSSimon Schubert 	|| (c >= '0' && c <= '9')
11055796c8dcSSimon Schubert 	|| (c >= 'a' && c <= 'z')
11065796c8dcSSimon Schubert 	|| (c >= 'A' && c <= 'Z')
11075796c8dcSSimon Schubert 	|| c == '<');
11085796c8dcSSimon Schubert        )
11095796c8dcSSimon Schubert     {
11105796c8dcSSimon Schubert       if (c == '<')
11115796c8dcSSimon Schubert 	{
11125796c8dcSSimon Schubert 	  int i = namelen;
11135796c8dcSSimon Schubert 	  while (tokstart[++i] && tokstart[i] != '>');
11145796c8dcSSimon Schubert 	  if (tokstart[i] == '>')
11155796c8dcSSimon Schubert 	    namelen = i;
11165796c8dcSSimon Schubert 	}
11175796c8dcSSimon Schubert        c = tokstart[++namelen];
11185796c8dcSSimon Schubert      }
11195796c8dcSSimon Schubert 
11205796c8dcSSimon Schubert   /* The token "if" terminates the expression and is NOT
11215796c8dcSSimon Schubert      removed from the input stream.  */
11225796c8dcSSimon Schubert   if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
11235796c8dcSSimon Schubert     {
11245796c8dcSSimon Schubert       return 0;
11255796c8dcSSimon Schubert     }
11265796c8dcSSimon Schubert 
11275796c8dcSSimon Schubert   lexptr += namelen;
11285796c8dcSSimon Schubert 
11295796c8dcSSimon Schubert   tryname:
11305796c8dcSSimon Schubert 
11315796c8dcSSimon Schubert   /* Catch specific keywords.  Should be done with a data structure.  */
11325796c8dcSSimon Schubert   switch (namelen)
11335796c8dcSSimon Schubert     {
11345796c8dcSSimon Schubert     case 7:
11355796c8dcSSimon Schubert       if (strncmp (tokstart, "boolean", 7) == 0)
11365796c8dcSSimon Schubert 	return BOOLEAN;
11375796c8dcSSimon Schubert       break;
11385796c8dcSSimon Schubert     case 6:
11395796c8dcSSimon Schubert       if (strncmp (tokstart, "double", 6) == 0)
11405796c8dcSSimon Schubert 	return DOUBLE;
11415796c8dcSSimon Schubert       break;
11425796c8dcSSimon Schubert     case 5:
11435796c8dcSSimon Schubert       if (strncmp (tokstart, "short", 5) == 0)
11445796c8dcSSimon Schubert 	return SHORT;
11455796c8dcSSimon Schubert       if (strncmp (tokstart, "false", 5) == 0)
11465796c8dcSSimon Schubert 	{
11475796c8dcSSimon Schubert 	  yylval.lval = 0;
11485796c8dcSSimon Schubert 	  return BOOLEAN_LITERAL;
11495796c8dcSSimon Schubert 	}
11505796c8dcSSimon Schubert       if (strncmp (tokstart, "super", 5) == 0)
11515796c8dcSSimon Schubert 	return SUPER;
11525796c8dcSSimon Schubert       if (strncmp (tokstart, "float", 5) == 0)
11535796c8dcSSimon Schubert 	return FLOAT;
11545796c8dcSSimon Schubert       break;
11555796c8dcSSimon Schubert     case 4:
11565796c8dcSSimon Schubert       if (strncmp (tokstart, "long", 4) == 0)
11575796c8dcSSimon Schubert 	return LONG;
11585796c8dcSSimon Schubert       if (strncmp (tokstart, "byte", 4) == 0)
11595796c8dcSSimon Schubert 	return BYTE;
11605796c8dcSSimon Schubert       if (strncmp (tokstart, "char", 4) == 0)
11615796c8dcSSimon Schubert 	return CHAR;
11625796c8dcSSimon Schubert       if (strncmp (tokstart, "true", 4) == 0)
11635796c8dcSSimon Schubert 	{
11645796c8dcSSimon Schubert 	  yylval.lval = 1;
11655796c8dcSSimon Schubert 	  return BOOLEAN_LITERAL;
11665796c8dcSSimon Schubert 	}
11675796c8dcSSimon Schubert       break;
11685796c8dcSSimon Schubert     case 3:
11695796c8dcSSimon Schubert       if (strncmp (tokstart, "int", 3) == 0)
11705796c8dcSSimon Schubert 	return INT;
11715796c8dcSSimon Schubert       if (strncmp (tokstart, "new", 3) == 0)
11725796c8dcSSimon Schubert 	return NEW;
11735796c8dcSSimon Schubert       break;
11745796c8dcSSimon Schubert     default:
11755796c8dcSSimon Schubert       break;
11765796c8dcSSimon Schubert     }
11775796c8dcSSimon Schubert 
11785796c8dcSSimon Schubert   yylval.sval.ptr = tokstart;
11795796c8dcSSimon Schubert   yylval.sval.length = namelen;
11805796c8dcSSimon Schubert 
11815796c8dcSSimon Schubert   if (*tokstart == '$')
11825796c8dcSSimon Schubert     {
11835796c8dcSSimon Schubert       write_dollar_variable (yylval.sval);
11845796c8dcSSimon Schubert       return VARIABLE;
11855796c8dcSSimon Schubert     }
11865796c8dcSSimon Schubert 
11875796c8dcSSimon Schubert   /* Input names that aren't symbols but ARE valid hex numbers,
11885796c8dcSSimon Schubert      when the input radix permits them, can be names or numbers
11895796c8dcSSimon Schubert      depending on the parse.  Note we support radixes > 16 here.  */
11905796c8dcSSimon Schubert   if (((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) ||
11915796c8dcSSimon Schubert        (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
11925796c8dcSSimon Schubert     {
11935796c8dcSSimon Schubert       YYSTYPE newlval;	/* Its value is ignored.  */
11945796c8dcSSimon Schubert       int hextype = parse_number (tokstart, namelen, 0, &newlval);
11955796c8dcSSimon Schubert       if (hextype == INTEGER_LITERAL)
11965796c8dcSSimon Schubert 	return NAME_OR_INT;
11975796c8dcSSimon Schubert     }
11985796c8dcSSimon Schubert   return IDENTIFIER;
11995796c8dcSSimon Schubert }
12005796c8dcSSimon Schubert 
12015796c8dcSSimon Schubert void
yyerror(char * msg)12025796c8dcSSimon Schubert yyerror (char *msg)
12035796c8dcSSimon Schubert {
12045796c8dcSSimon Schubert   if (prev_lexptr)
12055796c8dcSSimon Schubert     lexptr = prev_lexptr;
12065796c8dcSSimon Schubert 
12075796c8dcSSimon Schubert   if (msg)
12085796c8dcSSimon Schubert     error (_("%s: near `%s'"), msg, lexptr);
12095796c8dcSSimon Schubert   else
12105796c8dcSSimon Schubert     error (_("error in expression, near `%s'"), lexptr);
12115796c8dcSSimon Schubert }
12125796c8dcSSimon Schubert 
12135796c8dcSSimon Schubert static struct type *
java_type_from_name(struct stoken name)12145796c8dcSSimon Schubert java_type_from_name (struct stoken name)
12155796c8dcSSimon Schubert {
12165796c8dcSSimon Schubert   char *tmp = copy_name (name);
12175796c8dcSSimon Schubert   struct type *typ = java_lookup_class (tmp);
12185796c8dcSSimon Schubert   if (typ == NULL || TYPE_CODE (typ) != TYPE_CODE_STRUCT)
12195796c8dcSSimon Schubert     error (_("No class named `%s'"), tmp);
12205796c8dcSSimon Schubert   return typ;
12215796c8dcSSimon Schubert }
12225796c8dcSSimon Schubert 
12235796c8dcSSimon Schubert /* If NAME is a valid variable name in this scope, push it and return 1.
12245796c8dcSSimon Schubert    Otherwise, return 0.  */
12255796c8dcSSimon Schubert 
12265796c8dcSSimon Schubert static int
push_variable(struct stoken name)12275796c8dcSSimon Schubert push_variable (struct stoken name)
12285796c8dcSSimon Schubert {
12295796c8dcSSimon Schubert   char *tmp = copy_name (name);
1230*ef5ccd6cSJohn Marino   struct field_of_this_result is_a_field_of_this;
12315796c8dcSSimon Schubert   struct symbol *sym;
12325796c8dcSSimon Schubert   sym = lookup_symbol (tmp, expression_context_block, VAR_DOMAIN,
12335796c8dcSSimon Schubert 		       &is_a_field_of_this);
12345796c8dcSSimon Schubert   if (sym && SYMBOL_CLASS (sym) != LOC_TYPEDEF)
12355796c8dcSSimon Schubert     {
12365796c8dcSSimon Schubert       if (symbol_read_needs_frame (sym))
12375796c8dcSSimon Schubert 	{
12385796c8dcSSimon Schubert 	  if (innermost_block == 0 ||
12395796c8dcSSimon Schubert 	      contained_in (block_found, innermost_block))
12405796c8dcSSimon Schubert 	    innermost_block = block_found;
12415796c8dcSSimon Schubert 	}
12425796c8dcSSimon Schubert 
12435796c8dcSSimon Schubert       write_exp_elt_opcode (OP_VAR_VALUE);
12445796c8dcSSimon Schubert       /* We want to use the selected frame, not another more inner frame
12455796c8dcSSimon Schubert 	 which happens to be in the same block.  */
12465796c8dcSSimon Schubert       write_exp_elt_block (NULL);
12475796c8dcSSimon Schubert       write_exp_elt_sym (sym);
12485796c8dcSSimon Schubert       write_exp_elt_opcode (OP_VAR_VALUE);
12495796c8dcSSimon Schubert       return 1;
12505796c8dcSSimon Schubert     }
1251*ef5ccd6cSJohn Marino   if (is_a_field_of_this.type != NULL)
12525796c8dcSSimon Schubert     {
12535796c8dcSSimon Schubert       /* it hangs off of `this'.  Must not inadvertently convert from a
12545796c8dcSSimon Schubert 	 method call to data ref.  */
12555796c8dcSSimon Schubert       if (innermost_block == 0 ||
12565796c8dcSSimon Schubert 	  contained_in (block_found, innermost_block))
12575796c8dcSSimon Schubert 	innermost_block = block_found;
12585796c8dcSSimon Schubert       write_exp_elt_opcode (OP_THIS);
12595796c8dcSSimon Schubert       write_exp_elt_opcode (OP_THIS);
12605796c8dcSSimon Schubert       write_exp_elt_opcode (STRUCTOP_PTR);
12615796c8dcSSimon Schubert       write_exp_string (name);
12625796c8dcSSimon Schubert       write_exp_elt_opcode (STRUCTOP_PTR);
12635796c8dcSSimon Schubert       return 1;
12645796c8dcSSimon Schubert     }
12655796c8dcSSimon Schubert   return 0;
12665796c8dcSSimon Schubert }
12675796c8dcSSimon Schubert 
12685796c8dcSSimon Schubert /* Assuming a reference expression has been pushed, emit the
12695796c8dcSSimon Schubert    STRUCTOP_PTR ops to access the field named NAME.  If NAME is a
12705796c8dcSSimon Schubert    qualified name (has '.'), generate a field access for each part.  */
12715796c8dcSSimon Schubert 
12725796c8dcSSimon Schubert static void
push_fieldnames(struct stoken name)12735796c8dcSSimon Schubert push_fieldnames (struct stoken name)
12745796c8dcSSimon Schubert {
12755796c8dcSSimon Schubert   int i;
12765796c8dcSSimon Schubert   struct stoken token;
12775796c8dcSSimon Schubert   token.ptr = name.ptr;
12785796c8dcSSimon Schubert   for (i = 0;  ;  i++)
12795796c8dcSSimon Schubert     {
12805796c8dcSSimon Schubert       if (i == name.length || name.ptr[i] == '.')
12815796c8dcSSimon Schubert 	{
12825796c8dcSSimon Schubert 	  /* token.ptr is start of current field name.  */
12835796c8dcSSimon Schubert 	  token.length = &name.ptr[i] - token.ptr;
12845796c8dcSSimon Schubert 	  write_exp_elt_opcode (STRUCTOP_PTR);
12855796c8dcSSimon Schubert 	  write_exp_string (token);
12865796c8dcSSimon Schubert 	  write_exp_elt_opcode (STRUCTOP_PTR);
12875796c8dcSSimon Schubert 	  token.ptr += token.length + 1;
12885796c8dcSSimon Schubert 	}
12895796c8dcSSimon Schubert       if (i >= name.length)
12905796c8dcSSimon Schubert 	break;
12915796c8dcSSimon Schubert     }
12925796c8dcSSimon Schubert }
12935796c8dcSSimon Schubert 
12945796c8dcSSimon Schubert /* Helper routine for push_expression_name.
12955796c8dcSSimon Schubert    Handle a qualified name, where DOT_INDEX is the index of the first '.' */
12965796c8dcSSimon Schubert 
12975796c8dcSSimon Schubert static void
push_qualified_expression_name(struct stoken name,int dot_index)12985796c8dcSSimon Schubert push_qualified_expression_name (struct stoken name, int dot_index)
12995796c8dcSSimon Schubert {
13005796c8dcSSimon Schubert   struct stoken token;
13015796c8dcSSimon Schubert   char *tmp;
13025796c8dcSSimon Schubert   struct type *typ;
13035796c8dcSSimon Schubert 
13045796c8dcSSimon Schubert   token.ptr = name.ptr;
13055796c8dcSSimon Schubert   token.length = dot_index;
13065796c8dcSSimon Schubert 
13075796c8dcSSimon Schubert   if (push_variable (token))
13085796c8dcSSimon Schubert     {
13095796c8dcSSimon Schubert       token.ptr = name.ptr + dot_index + 1;
13105796c8dcSSimon Schubert       token.length = name.length - dot_index - 1;
13115796c8dcSSimon Schubert       push_fieldnames (token);
13125796c8dcSSimon Schubert       return;
13135796c8dcSSimon Schubert     }
13145796c8dcSSimon Schubert 
13155796c8dcSSimon Schubert   token.ptr = name.ptr;
13165796c8dcSSimon Schubert   for (;;)
13175796c8dcSSimon Schubert     {
13185796c8dcSSimon Schubert       token.length = dot_index;
13195796c8dcSSimon Schubert       tmp = copy_name (token);
13205796c8dcSSimon Schubert       typ = java_lookup_class (tmp);
13215796c8dcSSimon Schubert       if (typ != NULL)
13225796c8dcSSimon Schubert 	{
13235796c8dcSSimon Schubert 	  if (dot_index == name.length)
13245796c8dcSSimon Schubert 	    {
13255796c8dcSSimon Schubert 	      write_exp_elt_opcode(OP_TYPE);
13265796c8dcSSimon Schubert 	      write_exp_elt_type(typ);
13275796c8dcSSimon Schubert 	      write_exp_elt_opcode(OP_TYPE);
13285796c8dcSSimon Schubert 	      return;
13295796c8dcSSimon Schubert 	    }
13305796c8dcSSimon Schubert 	  dot_index++;  /* Skip '.' */
13315796c8dcSSimon Schubert 	  name.ptr += dot_index;
13325796c8dcSSimon Schubert 	  name.length -= dot_index;
13335796c8dcSSimon Schubert 	  dot_index = 0;
13345796c8dcSSimon Schubert 	  while (dot_index < name.length && name.ptr[dot_index] != '.')
13355796c8dcSSimon Schubert 	    dot_index++;
13365796c8dcSSimon Schubert 	  token.ptr = name.ptr;
13375796c8dcSSimon Schubert 	  token.length = dot_index;
13385796c8dcSSimon Schubert 	  write_exp_elt_opcode (OP_SCOPE);
13395796c8dcSSimon Schubert 	  write_exp_elt_type (typ);
13405796c8dcSSimon Schubert 	  write_exp_string (token);
13415796c8dcSSimon Schubert 	  write_exp_elt_opcode (OP_SCOPE);
13425796c8dcSSimon Schubert 	  if (dot_index < name.length)
13435796c8dcSSimon Schubert 	    {
13445796c8dcSSimon Schubert 	      dot_index++;
13455796c8dcSSimon Schubert 	      name.ptr += dot_index;
13465796c8dcSSimon Schubert 	      name.length -= dot_index;
13475796c8dcSSimon Schubert 	      push_fieldnames (name);
13485796c8dcSSimon Schubert 	    }
13495796c8dcSSimon Schubert 	  return;
13505796c8dcSSimon Schubert 	}
13515796c8dcSSimon Schubert       else if (dot_index >= name.length)
13525796c8dcSSimon Schubert 	break;
13535796c8dcSSimon Schubert       dot_index++;  /* Skip '.' */
13545796c8dcSSimon Schubert       while (dot_index < name.length && name.ptr[dot_index] != '.')
13555796c8dcSSimon Schubert 	dot_index++;
13565796c8dcSSimon Schubert     }
13575796c8dcSSimon Schubert   error (_("unknown type `%.*s'"), name.length, name.ptr);
13585796c8dcSSimon Schubert }
13595796c8dcSSimon Schubert 
13605796c8dcSSimon Schubert /* Handle Name in an expression (or LHS).
13615796c8dcSSimon Schubert    Handle VAR, TYPE, TYPE.FIELD1....FIELDN and VAR.FIELD1....FIELDN.  */
13625796c8dcSSimon Schubert 
13635796c8dcSSimon Schubert static void
push_expression_name(struct stoken name)13645796c8dcSSimon Schubert push_expression_name (struct stoken name)
13655796c8dcSSimon Schubert {
13665796c8dcSSimon Schubert   char *tmp;
13675796c8dcSSimon Schubert   struct type *typ;
13685796c8dcSSimon Schubert   int i;
13695796c8dcSSimon Schubert 
13705796c8dcSSimon Schubert   for (i = 0;  i < name.length;  i++)
13715796c8dcSSimon Schubert     {
13725796c8dcSSimon Schubert       if (name.ptr[i] == '.')
13735796c8dcSSimon Schubert 	{
13745796c8dcSSimon Schubert 	  /* It's a Qualified Expression Name.  */
13755796c8dcSSimon Schubert 	  push_qualified_expression_name (name, i);
13765796c8dcSSimon Schubert 	  return;
13775796c8dcSSimon Schubert 	}
13785796c8dcSSimon Schubert     }
13795796c8dcSSimon Schubert 
13805796c8dcSSimon Schubert   /* It's a Simple Expression Name.  */
13815796c8dcSSimon Schubert 
13825796c8dcSSimon Schubert   if (push_variable (name))
13835796c8dcSSimon Schubert     return;
13845796c8dcSSimon Schubert   tmp = copy_name (name);
13855796c8dcSSimon Schubert   typ = java_lookup_class (tmp);
13865796c8dcSSimon Schubert   if (typ != NULL)
13875796c8dcSSimon Schubert     {
13885796c8dcSSimon Schubert       write_exp_elt_opcode(OP_TYPE);
13895796c8dcSSimon Schubert       write_exp_elt_type(typ);
13905796c8dcSSimon Schubert       write_exp_elt_opcode(OP_TYPE);
13915796c8dcSSimon Schubert     }
13925796c8dcSSimon Schubert   else
13935796c8dcSSimon Schubert     {
13945796c8dcSSimon Schubert       struct minimal_symbol *msymbol;
13955796c8dcSSimon Schubert 
13965796c8dcSSimon Schubert       msymbol = lookup_minimal_symbol (tmp, NULL, NULL);
13975796c8dcSSimon Schubert       if (msymbol != NULL)
13985796c8dcSSimon Schubert 	write_exp_msymbol (msymbol);
13995796c8dcSSimon Schubert       else if (!have_full_symbols () && !have_partial_symbols ())
14005796c8dcSSimon Schubert 	error (_("No symbol table is loaded.  Use the \"file\" command"));
14015796c8dcSSimon Schubert       else
1402*ef5ccd6cSJohn Marino 	error (_("No symbol \"%s\" in current context."), tmp);
14035796c8dcSSimon Schubert     }
14045796c8dcSSimon Schubert 
14055796c8dcSSimon Schubert }
14065796c8dcSSimon Schubert 
14075796c8dcSSimon Schubert 
14085796c8dcSSimon Schubert /* The following two routines, copy_exp and insert_exp, aren't specific to
14095796c8dcSSimon Schubert    Java, so they could go in parse.c, but their only purpose is to support
14105796c8dcSSimon Schubert    the parsing kludges we use in this file, so maybe it's best to isolate
14115796c8dcSSimon Schubert    them here.  */
14125796c8dcSSimon Schubert 
14135796c8dcSSimon Schubert /* Copy the expression whose last element is at index ENDPOS - 1 in EXPR
14145796c8dcSSimon Schubert    into a freshly malloc'ed struct expression.  Its language_defn is set
14155796c8dcSSimon Schubert    to null.  */
14165796c8dcSSimon Schubert static struct expression *
copy_exp(struct expression * expr,int endpos)14175796c8dcSSimon Schubert copy_exp (struct expression *expr, int endpos)
14185796c8dcSSimon Schubert {
14195796c8dcSSimon Schubert   int len = length_of_subexp (expr, endpos);
14205796c8dcSSimon Schubert   struct expression *new
14215796c8dcSSimon Schubert     = (struct expression *) malloc (sizeof (*new) + EXP_ELEM_TO_BYTES (len));
14225796c8dcSSimon Schubert   new->nelts = len;
14235796c8dcSSimon Schubert   memcpy (new->elts, expr->elts + endpos - len, EXP_ELEM_TO_BYTES (len));
14245796c8dcSSimon Schubert   new->language_defn = 0;
14255796c8dcSSimon Schubert 
14265796c8dcSSimon Schubert   return new;
14275796c8dcSSimon Schubert }
14285796c8dcSSimon Schubert 
14295796c8dcSSimon Schubert /* Insert the expression NEW into the current expression (expout) at POS.  */
14305796c8dcSSimon Schubert static void
insert_exp(int pos,struct expression * new)14315796c8dcSSimon Schubert insert_exp (int pos, struct expression *new)
14325796c8dcSSimon Schubert {
14335796c8dcSSimon Schubert   int newlen = new->nelts;
14345796c8dcSSimon Schubert 
14355796c8dcSSimon Schubert   /* Grow expout if necessary.  In this function's only use at present,
14365796c8dcSSimon Schubert      this should never be necessary.  */
14375796c8dcSSimon Schubert   if (expout_ptr + newlen > expout_size)
14385796c8dcSSimon Schubert     {
14395796c8dcSSimon Schubert       expout_size = max (expout_size * 2, expout_ptr + newlen + 10);
14405796c8dcSSimon Schubert       expout = (struct expression *)
14415796c8dcSSimon Schubert 	realloc ((char *) expout, (sizeof (struct expression)
14425796c8dcSSimon Schubert 				    + EXP_ELEM_TO_BYTES (expout_size)));
14435796c8dcSSimon Schubert     }
14445796c8dcSSimon Schubert 
14455796c8dcSSimon Schubert   {
14465796c8dcSSimon Schubert     int i;
14475796c8dcSSimon Schubert 
14485796c8dcSSimon Schubert     for (i = expout_ptr - 1; i >= pos; i--)
14495796c8dcSSimon Schubert       expout->elts[i + newlen] = expout->elts[i];
14505796c8dcSSimon Schubert   }
14515796c8dcSSimon Schubert 
14525796c8dcSSimon Schubert   memcpy (expout->elts + pos, new->elts, EXP_ELEM_TO_BYTES (newlen));
14535796c8dcSSimon Schubert   expout_ptr += newlen;
14545796c8dcSSimon Schubert }
1455