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