xref: /dragonfly/contrib/gdb-7/gdb/f-exp.y (revision ef5ccd6c)
15796c8dcSSimon Schubert /* YACC parser for Fortran expressions, for GDB.
2*ef5ccd6cSJohn Marino    Copyright (C) 1986-2013 Free Software Foundation, Inc.
35796c8dcSSimon Schubert 
45796c8dcSSimon Schubert    Contributed by Motorola.  Adapted from the C parser by Farooq Butt
55796c8dcSSimon Schubert    (fmbutt@engage.sps.mot.com).
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This file is part of GDB.
85796c8dcSSimon Schubert 
95796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
105796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
115796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
125796c8dcSSimon Schubert    (at your option) any later version.
135796c8dcSSimon Schubert 
145796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
155796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
165796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
175796c8dcSSimon Schubert    GNU General Public License for more details.
185796c8dcSSimon Schubert 
195796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
205796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
215796c8dcSSimon Schubert 
225796c8dcSSimon Schubert /* This was blantantly ripped off the C expression parser, please
235796c8dcSSimon Schubert    be aware of that as you look at its basic structure -FMB */
245796c8dcSSimon Schubert 
255796c8dcSSimon Schubert /* Parse a F77 expression from text in a string,
265796c8dcSSimon Schubert    and return the result as a  struct expression  pointer.
275796c8dcSSimon Schubert    That structure contains arithmetic operations in reverse polish,
285796c8dcSSimon Schubert    with constants represented by operations that are followed by special data.
295796c8dcSSimon Schubert    See expression.h for the details of the format.
305796c8dcSSimon Schubert    What is important here is that it can be built up sequentially
315796c8dcSSimon Schubert    during the process of parsing; the lower levels of the tree always
325796c8dcSSimon Schubert    come first in the result.
335796c8dcSSimon Schubert 
345796c8dcSSimon Schubert    Note that malloc's and realloc's in this file are transformed to
355796c8dcSSimon Schubert    xmalloc and xrealloc respectively by the same sed command in the
365796c8dcSSimon Schubert    makefile that remaps any other malloc/realloc inserted by the parser
375796c8dcSSimon Schubert    generator.  Doing this with #defines and trying to control the interaction
385796c8dcSSimon Schubert    with include files (<malloc.h> and <stdlib.h> for example) just became
395796c8dcSSimon Schubert    too messy, particularly when such includes can be inserted at random
405796c8dcSSimon Schubert    times by the parser generator.  */
415796c8dcSSimon Schubert 
425796c8dcSSimon Schubert %{
435796c8dcSSimon Schubert 
445796c8dcSSimon Schubert #include "defs.h"
455796c8dcSSimon Schubert #include "gdb_string.h"
465796c8dcSSimon Schubert #include "expression.h"
475796c8dcSSimon Schubert #include "value.h"
485796c8dcSSimon Schubert #include "parser-defs.h"
495796c8dcSSimon Schubert #include "language.h"
505796c8dcSSimon Schubert #include "f-lang.h"
515796c8dcSSimon Schubert #include "bfd.h" /* Required by objfiles.h.  */
525796c8dcSSimon Schubert #include "symfile.h" /* Required by objfiles.h.  */
535796c8dcSSimon Schubert #include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
545796c8dcSSimon Schubert #include "block.h"
555796c8dcSSimon Schubert #include <ctype.h>
565796c8dcSSimon Schubert 
575796c8dcSSimon Schubert #define parse_type builtin_type (parse_gdbarch)
585796c8dcSSimon Schubert #define parse_f_type builtin_f_type (parse_gdbarch)
595796c8dcSSimon Schubert 
605796c8dcSSimon Schubert /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
615796c8dcSSimon Schubert    as well as gratuitiously global symbol names, so we can have multiple
625796c8dcSSimon Schubert    yacc generated parsers in gdb.  Note that these are only the variables
635796c8dcSSimon Schubert    produced by yacc.  If other parser generators (bison, byacc, etc) produce
645796c8dcSSimon Schubert    additional global names that conflict at link time, then those parser
655796c8dcSSimon Schubert    generators need to be fixed instead of adding those names to this list.  */
665796c8dcSSimon Schubert 
675796c8dcSSimon Schubert #define	yymaxdepth f_maxdepth
685796c8dcSSimon Schubert #define	yyparse	f_parse
695796c8dcSSimon Schubert #define	yylex	f_lex
705796c8dcSSimon Schubert #define	yyerror	f_error
715796c8dcSSimon Schubert #define	yylval	f_lval
725796c8dcSSimon Schubert #define	yychar	f_char
735796c8dcSSimon Schubert #define	yydebug	f_debug
745796c8dcSSimon Schubert #define	yypact	f_pact
755796c8dcSSimon Schubert #define	yyr1	f_r1
765796c8dcSSimon Schubert #define	yyr2	f_r2
775796c8dcSSimon Schubert #define	yydef	f_def
785796c8dcSSimon Schubert #define	yychk	f_chk
795796c8dcSSimon Schubert #define	yypgo	f_pgo
805796c8dcSSimon Schubert #define	yyact	f_act
815796c8dcSSimon Schubert #define	yyexca	f_exca
825796c8dcSSimon Schubert #define yyerrflag f_errflag
835796c8dcSSimon Schubert #define yynerrs	f_nerrs
845796c8dcSSimon Schubert #define	yyps	f_ps
855796c8dcSSimon Schubert #define	yypv	f_pv
865796c8dcSSimon Schubert #define	yys	f_s
875796c8dcSSimon Schubert #define	yy_yys	f_yys
885796c8dcSSimon Schubert #define	yystate	f_state
895796c8dcSSimon Schubert #define	yytmp	f_tmp
905796c8dcSSimon Schubert #define	yyv	f_v
915796c8dcSSimon Schubert #define	yy_yyv	f_yyv
925796c8dcSSimon Schubert #define	yyval	f_val
935796c8dcSSimon Schubert #define	yylloc	f_lloc
945796c8dcSSimon Schubert #define yyreds	f_reds		/* With YYDEBUG defined */
955796c8dcSSimon Schubert #define yytoks	f_toks		/* With YYDEBUG defined */
965796c8dcSSimon Schubert #define yyname	f_name		/* With YYDEBUG defined */
975796c8dcSSimon Schubert #define yyrule	f_rule		/* With YYDEBUG defined */
985796c8dcSSimon Schubert #define yylhs	f_yylhs
995796c8dcSSimon Schubert #define yylen	f_yylen
1005796c8dcSSimon Schubert #define yydefred f_yydefred
1015796c8dcSSimon Schubert #define yydgoto	f_yydgoto
1025796c8dcSSimon Schubert #define yysindex f_yysindex
1035796c8dcSSimon Schubert #define yyrindex f_yyrindex
1045796c8dcSSimon Schubert #define yygindex f_yygindex
1055796c8dcSSimon Schubert #define yytable	 f_yytable
1065796c8dcSSimon Schubert #define yycheck	 f_yycheck
107*ef5ccd6cSJohn Marino #define yyss	f_yyss
108*ef5ccd6cSJohn Marino #define yysslim	f_yysslim
109*ef5ccd6cSJohn Marino #define yyssp	f_yyssp
110*ef5ccd6cSJohn Marino #define yystacksize f_yystacksize
111*ef5ccd6cSJohn Marino #define yyvs	f_yyvs
112*ef5ccd6cSJohn Marino #define yyvsp	f_yyvsp
1135796c8dcSSimon Schubert 
1145796c8dcSSimon Schubert #ifndef YYDEBUG
1155796c8dcSSimon Schubert #define	YYDEBUG	1		/* Default to yydebug support */
1165796c8dcSSimon Schubert #endif
1175796c8dcSSimon Schubert 
1185796c8dcSSimon Schubert #define YYFPRINTF parser_fprintf
1195796c8dcSSimon Schubert 
1205796c8dcSSimon Schubert int yyparse (void);
1215796c8dcSSimon Schubert 
1225796c8dcSSimon Schubert static int yylex (void);
1235796c8dcSSimon Schubert 
1245796c8dcSSimon Schubert void yyerror (char *);
1255796c8dcSSimon Schubert 
1265796c8dcSSimon Schubert static void growbuf_by_size (int);
1275796c8dcSSimon Schubert 
1285796c8dcSSimon Schubert static int match_string_literal (void);
1295796c8dcSSimon Schubert 
1305796c8dcSSimon Schubert %}
1315796c8dcSSimon Schubert 
1325796c8dcSSimon Schubert /* Although the yacc "value" of an expression is not used,
1335796c8dcSSimon Schubert    since the result is stored in the structure being created,
1345796c8dcSSimon Schubert    other node types do have values.  */
1355796c8dcSSimon Schubert 
1365796c8dcSSimon Schubert %union
1375796c8dcSSimon Schubert   {
1385796c8dcSSimon Schubert     LONGEST lval;
1395796c8dcSSimon Schubert     struct {
1405796c8dcSSimon Schubert       LONGEST val;
1415796c8dcSSimon Schubert       struct type *type;
1425796c8dcSSimon Schubert     } typed_val;
1435796c8dcSSimon Schubert     DOUBLEST dval;
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     int voidval;
1505796c8dcSSimon Schubert     struct block *bval;
1515796c8dcSSimon Schubert     enum exp_opcode opcode;
1525796c8dcSSimon Schubert     struct internalvar *ivar;
1535796c8dcSSimon Schubert 
1545796c8dcSSimon Schubert     struct type **tvec;
1555796c8dcSSimon Schubert     int *ivec;
1565796c8dcSSimon Schubert   }
1575796c8dcSSimon Schubert 
1585796c8dcSSimon Schubert %{
1595796c8dcSSimon Schubert /* YYSTYPE gets defined by %union */
1605796c8dcSSimon Schubert static int parse_number (char *, int, int, YYSTYPE *);
1615796c8dcSSimon Schubert %}
1625796c8dcSSimon Schubert 
1635796c8dcSSimon Schubert %type <voidval> exp  type_exp start variable
1645796c8dcSSimon Schubert %type <tval> type typebase
1655796c8dcSSimon Schubert %type <tvec> nonempty_typelist
1665796c8dcSSimon Schubert /* %type <bval> block */
1675796c8dcSSimon Schubert 
1685796c8dcSSimon Schubert /* Fancy type parsing.  */
1695796c8dcSSimon Schubert %type <voidval> func_mod direct_abs_decl abs_decl
1705796c8dcSSimon Schubert %type <tval> ptype
1715796c8dcSSimon Schubert 
1725796c8dcSSimon Schubert %token <typed_val> INT
1735796c8dcSSimon Schubert %token <dval> FLOAT
1745796c8dcSSimon Schubert 
1755796c8dcSSimon Schubert /* Both NAME and TYPENAME tokens represent symbols in the input,
1765796c8dcSSimon Schubert    and both convey their data as strings.
1775796c8dcSSimon Schubert    But a TYPENAME is a string that happens to be defined as a typedef
1785796c8dcSSimon Schubert    or builtin type name (such as int or char)
1795796c8dcSSimon Schubert    and a NAME is any other symbol.
1805796c8dcSSimon Schubert    Contexts where this distinction is not important can use the
1815796c8dcSSimon Schubert    nonterminal "name", which matches either NAME or TYPENAME.  */
1825796c8dcSSimon Schubert 
1835796c8dcSSimon Schubert %token <sval> STRING_LITERAL
1845796c8dcSSimon Schubert %token <lval> BOOLEAN_LITERAL
1855796c8dcSSimon Schubert %token <ssym> NAME
1865796c8dcSSimon Schubert %token <tsym> TYPENAME
1875796c8dcSSimon Schubert %type <sval> name
1885796c8dcSSimon Schubert %type <ssym> name_not_typename
1895796c8dcSSimon Schubert 
1905796c8dcSSimon Schubert /* A NAME_OR_INT is a symbol which is not known in the symbol table,
1915796c8dcSSimon Schubert    but which would parse as a valid number in the current input radix.
1925796c8dcSSimon Schubert    E.g. "c" when input_radix==16.  Depending on the parse, it will be
1935796c8dcSSimon Schubert    turned into a name or into a number.  */
1945796c8dcSSimon Schubert 
1955796c8dcSSimon Schubert %token <ssym> NAME_OR_INT
1965796c8dcSSimon Schubert 
1975796c8dcSSimon Schubert %token  SIZEOF
1985796c8dcSSimon Schubert %token ERROR
1995796c8dcSSimon Schubert 
2005796c8dcSSimon Schubert /* Special type cases, put in to allow the parser to distinguish different
2015796c8dcSSimon Schubert    legal basetypes.  */
2025796c8dcSSimon Schubert %token INT_KEYWORD INT_S2_KEYWORD LOGICAL_S1_KEYWORD LOGICAL_S2_KEYWORD
203cf7f2e2dSJohn Marino %token LOGICAL_S8_KEYWORD
2045796c8dcSSimon Schubert %token LOGICAL_KEYWORD REAL_KEYWORD REAL_S8_KEYWORD REAL_S16_KEYWORD
2055796c8dcSSimon Schubert %token COMPLEX_S8_KEYWORD COMPLEX_S16_KEYWORD COMPLEX_S32_KEYWORD
2065796c8dcSSimon Schubert %token BOOL_AND BOOL_OR BOOL_NOT
2075796c8dcSSimon Schubert %token <lval> CHARACTER
2085796c8dcSSimon Schubert 
2095796c8dcSSimon Schubert %token <voidval> VARIABLE
2105796c8dcSSimon Schubert 
2115796c8dcSSimon Schubert %token <opcode> ASSIGN_MODIFY
2125796c8dcSSimon Schubert 
2135796c8dcSSimon Schubert %left ','
2145796c8dcSSimon Schubert %left ABOVE_COMMA
2155796c8dcSSimon Schubert %right '=' ASSIGN_MODIFY
2165796c8dcSSimon Schubert %right '?'
2175796c8dcSSimon Schubert %left BOOL_OR
2185796c8dcSSimon Schubert %right BOOL_NOT
2195796c8dcSSimon Schubert %left BOOL_AND
2205796c8dcSSimon Schubert %left '|'
2215796c8dcSSimon Schubert %left '^'
2225796c8dcSSimon Schubert %left '&'
2235796c8dcSSimon Schubert %left EQUAL NOTEQUAL
2245796c8dcSSimon Schubert %left LESSTHAN GREATERTHAN LEQ GEQ
2255796c8dcSSimon Schubert %left LSH RSH
2265796c8dcSSimon Schubert %left '@'
2275796c8dcSSimon Schubert %left '+' '-'
2285796c8dcSSimon Schubert %left '*' '/'
2295796c8dcSSimon Schubert %right STARSTAR
2305796c8dcSSimon Schubert %right '%'
2315796c8dcSSimon Schubert %right UNARY
2325796c8dcSSimon Schubert %right '('
2335796c8dcSSimon Schubert 
2345796c8dcSSimon Schubert 
2355796c8dcSSimon Schubert %%
2365796c8dcSSimon Schubert 
2375796c8dcSSimon Schubert start   :	exp
2385796c8dcSSimon Schubert 	|	type_exp
2395796c8dcSSimon Schubert 	;
2405796c8dcSSimon Schubert 
2415796c8dcSSimon Schubert type_exp:	type
2425796c8dcSSimon Schubert 			{ write_exp_elt_opcode(OP_TYPE);
2435796c8dcSSimon Schubert 			  write_exp_elt_type($1);
2445796c8dcSSimon Schubert 			  write_exp_elt_opcode(OP_TYPE); }
2455796c8dcSSimon Schubert 	;
2465796c8dcSSimon Schubert 
2475796c8dcSSimon Schubert exp     :       '(' exp ')'
2485796c8dcSSimon Schubert         		{ }
2495796c8dcSSimon Schubert         ;
2505796c8dcSSimon Schubert 
2515796c8dcSSimon Schubert /* Expressions, not including the comma operator.  */
2525796c8dcSSimon Schubert exp	:	'*' exp    %prec UNARY
2535796c8dcSSimon Schubert 			{ write_exp_elt_opcode (UNOP_IND); }
2545796c8dcSSimon Schubert 	;
2555796c8dcSSimon Schubert 
2565796c8dcSSimon Schubert exp	:	'&' exp    %prec UNARY
2575796c8dcSSimon Schubert 			{ write_exp_elt_opcode (UNOP_ADDR); }
2585796c8dcSSimon Schubert 	;
2595796c8dcSSimon Schubert 
2605796c8dcSSimon Schubert exp	:	'-' exp    %prec UNARY
2615796c8dcSSimon Schubert 			{ write_exp_elt_opcode (UNOP_NEG); }
2625796c8dcSSimon Schubert 	;
2635796c8dcSSimon Schubert 
2645796c8dcSSimon Schubert exp	:	BOOL_NOT exp    %prec UNARY
2655796c8dcSSimon Schubert 			{ write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
2665796c8dcSSimon Schubert 	;
2675796c8dcSSimon Schubert 
2685796c8dcSSimon Schubert exp	:	'~' exp    %prec UNARY
2695796c8dcSSimon Schubert 			{ write_exp_elt_opcode (UNOP_COMPLEMENT); }
2705796c8dcSSimon Schubert 	;
2715796c8dcSSimon Schubert 
2725796c8dcSSimon Schubert exp	:	SIZEOF exp       %prec UNARY
2735796c8dcSSimon Schubert 			{ write_exp_elt_opcode (UNOP_SIZEOF); }
2745796c8dcSSimon Schubert 	;
2755796c8dcSSimon Schubert 
2765796c8dcSSimon Schubert /* No more explicit array operators, we treat everything in F77 as
2775796c8dcSSimon Schubert    a function call.  The disambiguation as to whether we are
2785796c8dcSSimon Schubert    doing a subscript operation or a function call is done
2795796c8dcSSimon Schubert    later in eval.c.  */
2805796c8dcSSimon Schubert 
2815796c8dcSSimon Schubert exp	:	exp '('
2825796c8dcSSimon Schubert 			{ start_arglist (); }
2835796c8dcSSimon Schubert 		arglist ')'
2845796c8dcSSimon Schubert 			{ write_exp_elt_opcode (OP_F77_UNDETERMINED_ARGLIST);
2855796c8dcSSimon Schubert 			  write_exp_elt_longcst ((LONGEST) end_arglist ());
2865796c8dcSSimon Schubert 			  write_exp_elt_opcode (OP_F77_UNDETERMINED_ARGLIST); }
2875796c8dcSSimon Schubert 	;
2885796c8dcSSimon Schubert 
2895796c8dcSSimon Schubert arglist	:
2905796c8dcSSimon Schubert 	;
2915796c8dcSSimon Schubert 
2925796c8dcSSimon Schubert arglist	:	exp
2935796c8dcSSimon Schubert 			{ arglist_len = 1; }
2945796c8dcSSimon Schubert 	;
2955796c8dcSSimon Schubert 
2965796c8dcSSimon Schubert arglist :	subrange
2975796c8dcSSimon Schubert 			{ arglist_len = 1; }
2985796c8dcSSimon Schubert 	;
2995796c8dcSSimon Schubert 
3005796c8dcSSimon Schubert arglist	:	arglist ',' exp   %prec ABOVE_COMMA
3015796c8dcSSimon Schubert 			{ arglist_len++; }
3025796c8dcSSimon Schubert 	;
3035796c8dcSSimon Schubert 
3045796c8dcSSimon Schubert /* There are four sorts of subrange types in F90.  */
3055796c8dcSSimon Schubert 
3065796c8dcSSimon Schubert subrange:	exp ':' exp	%prec ABOVE_COMMA
3075796c8dcSSimon Schubert 			{ write_exp_elt_opcode (OP_F90_RANGE);
3085796c8dcSSimon Schubert 			  write_exp_elt_longcst (NONE_BOUND_DEFAULT);
3095796c8dcSSimon Schubert 			  write_exp_elt_opcode (OP_F90_RANGE); }
3105796c8dcSSimon Schubert 	;
3115796c8dcSSimon Schubert 
3125796c8dcSSimon Schubert subrange:	exp ':'	%prec ABOVE_COMMA
3135796c8dcSSimon Schubert 			{ write_exp_elt_opcode (OP_F90_RANGE);
3145796c8dcSSimon Schubert 			  write_exp_elt_longcst (HIGH_BOUND_DEFAULT);
3155796c8dcSSimon Schubert 			  write_exp_elt_opcode (OP_F90_RANGE); }
3165796c8dcSSimon Schubert 	;
3175796c8dcSSimon Schubert 
3185796c8dcSSimon Schubert subrange:	':' exp	%prec ABOVE_COMMA
3195796c8dcSSimon Schubert 			{ write_exp_elt_opcode (OP_F90_RANGE);
3205796c8dcSSimon Schubert 			  write_exp_elt_longcst (LOW_BOUND_DEFAULT);
3215796c8dcSSimon Schubert 			  write_exp_elt_opcode (OP_F90_RANGE); }
3225796c8dcSSimon Schubert 	;
3235796c8dcSSimon Schubert 
3245796c8dcSSimon Schubert subrange:	':'	%prec ABOVE_COMMA
3255796c8dcSSimon Schubert 			{ write_exp_elt_opcode (OP_F90_RANGE);
3265796c8dcSSimon Schubert 			  write_exp_elt_longcst (BOTH_BOUND_DEFAULT);
3275796c8dcSSimon Schubert 			  write_exp_elt_opcode (OP_F90_RANGE); }
3285796c8dcSSimon Schubert 	;
3295796c8dcSSimon Schubert 
3305796c8dcSSimon Schubert complexnum:     exp ',' exp
3315796c8dcSSimon Schubert                 	{ }
3325796c8dcSSimon Schubert         ;
3335796c8dcSSimon Schubert 
3345796c8dcSSimon Schubert exp	:	'(' complexnum ')'
3355796c8dcSSimon Schubert                 	{ write_exp_elt_opcode(OP_COMPLEX);
3365796c8dcSSimon Schubert 			  write_exp_elt_type (parse_f_type->builtin_complex_s16);
3375796c8dcSSimon Schubert                 	  write_exp_elt_opcode(OP_COMPLEX); }
3385796c8dcSSimon Schubert 	;
3395796c8dcSSimon Schubert 
3405796c8dcSSimon Schubert exp	:	'(' type ')' exp  %prec UNARY
3415796c8dcSSimon Schubert 			{ write_exp_elt_opcode (UNOP_CAST);
3425796c8dcSSimon Schubert 			  write_exp_elt_type ($2);
3435796c8dcSSimon Schubert 			  write_exp_elt_opcode (UNOP_CAST); }
3445796c8dcSSimon Schubert 	;
3455796c8dcSSimon Schubert 
3465796c8dcSSimon Schubert exp     :       exp '%' name
3475796c8dcSSimon Schubert                         { write_exp_elt_opcode (STRUCTOP_STRUCT);
3485796c8dcSSimon Schubert                           write_exp_string ($3);
3495796c8dcSSimon Schubert                           write_exp_elt_opcode (STRUCTOP_STRUCT); }
3505796c8dcSSimon Schubert         ;
3515796c8dcSSimon Schubert 
3525796c8dcSSimon Schubert /* Binary operators in order of decreasing precedence.  */
3535796c8dcSSimon Schubert 
3545796c8dcSSimon Schubert exp	:	exp '@' exp
3555796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_REPEAT); }
3565796c8dcSSimon Schubert 	;
3575796c8dcSSimon Schubert 
3585796c8dcSSimon Schubert exp	:	exp STARSTAR exp
3595796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_EXP); }
3605796c8dcSSimon Schubert 	;
3615796c8dcSSimon Schubert 
3625796c8dcSSimon Schubert exp	:	exp '*' exp
3635796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_MUL); }
3645796c8dcSSimon Schubert 	;
3655796c8dcSSimon Schubert 
3665796c8dcSSimon Schubert exp	:	exp '/' exp
3675796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_DIV); }
3685796c8dcSSimon Schubert 	;
3695796c8dcSSimon Schubert 
3705796c8dcSSimon Schubert exp	:	exp '+' exp
3715796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_ADD); }
3725796c8dcSSimon Schubert 	;
3735796c8dcSSimon Schubert 
3745796c8dcSSimon Schubert exp	:	exp '-' exp
3755796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_SUB); }
3765796c8dcSSimon Schubert 	;
3775796c8dcSSimon Schubert 
3785796c8dcSSimon Schubert exp	:	exp LSH exp
3795796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_LSH); }
3805796c8dcSSimon Schubert 	;
3815796c8dcSSimon Schubert 
3825796c8dcSSimon Schubert exp	:	exp RSH exp
3835796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_RSH); }
3845796c8dcSSimon Schubert 	;
3855796c8dcSSimon Schubert 
3865796c8dcSSimon Schubert exp	:	exp EQUAL exp
3875796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_EQUAL); }
3885796c8dcSSimon Schubert 	;
3895796c8dcSSimon Schubert 
3905796c8dcSSimon Schubert exp	:	exp NOTEQUAL exp
3915796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_NOTEQUAL); }
3925796c8dcSSimon Schubert 	;
3935796c8dcSSimon Schubert 
3945796c8dcSSimon Schubert exp	:	exp LEQ exp
3955796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_LEQ); }
3965796c8dcSSimon Schubert 	;
3975796c8dcSSimon Schubert 
3985796c8dcSSimon Schubert exp	:	exp GEQ exp
3995796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_GEQ); }
4005796c8dcSSimon Schubert 	;
4015796c8dcSSimon Schubert 
4025796c8dcSSimon Schubert exp	:	exp LESSTHAN exp
4035796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_LESS); }
4045796c8dcSSimon Schubert 	;
4055796c8dcSSimon Schubert 
4065796c8dcSSimon Schubert exp	:	exp GREATERTHAN exp
4075796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_GTR); }
4085796c8dcSSimon Schubert 	;
4095796c8dcSSimon Schubert 
4105796c8dcSSimon Schubert exp	:	exp '&' exp
4115796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_BITWISE_AND); }
4125796c8dcSSimon Schubert 	;
4135796c8dcSSimon Schubert 
4145796c8dcSSimon Schubert exp	:	exp '^' exp
4155796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_BITWISE_XOR); }
4165796c8dcSSimon Schubert 	;
4175796c8dcSSimon Schubert 
4185796c8dcSSimon Schubert exp	:	exp '|' exp
4195796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_BITWISE_IOR); }
4205796c8dcSSimon Schubert 	;
4215796c8dcSSimon Schubert 
4225796c8dcSSimon Schubert exp     :       exp BOOL_AND exp
4235796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_LOGICAL_AND); }
4245796c8dcSSimon Schubert 	;
4255796c8dcSSimon Schubert 
4265796c8dcSSimon Schubert 
4275796c8dcSSimon Schubert exp	:	exp BOOL_OR exp
4285796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_LOGICAL_OR); }
4295796c8dcSSimon Schubert 	;
4305796c8dcSSimon Schubert 
4315796c8dcSSimon Schubert exp	:	exp '=' exp
4325796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_ASSIGN); }
4335796c8dcSSimon Schubert 	;
4345796c8dcSSimon Schubert 
4355796c8dcSSimon Schubert exp	:	exp ASSIGN_MODIFY exp
4365796c8dcSSimon Schubert 			{ write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
4375796c8dcSSimon Schubert 			  write_exp_elt_opcode ($2);
4385796c8dcSSimon Schubert 			  write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); }
4395796c8dcSSimon Schubert 	;
4405796c8dcSSimon Schubert 
4415796c8dcSSimon Schubert exp	:	INT
4425796c8dcSSimon Schubert 			{ write_exp_elt_opcode (OP_LONG);
4435796c8dcSSimon Schubert 			  write_exp_elt_type ($1.type);
4445796c8dcSSimon Schubert 			  write_exp_elt_longcst ((LONGEST)($1.val));
4455796c8dcSSimon Schubert 			  write_exp_elt_opcode (OP_LONG); }
4465796c8dcSSimon Schubert 	;
4475796c8dcSSimon Schubert 
4485796c8dcSSimon Schubert exp	:	NAME_OR_INT
4495796c8dcSSimon Schubert 			{ YYSTYPE val;
4505796c8dcSSimon Schubert 			  parse_number ($1.stoken.ptr, $1.stoken.length, 0, &val);
4515796c8dcSSimon Schubert 			  write_exp_elt_opcode (OP_LONG);
4525796c8dcSSimon Schubert 			  write_exp_elt_type (val.typed_val.type);
4535796c8dcSSimon Schubert 			  write_exp_elt_longcst ((LONGEST)val.typed_val.val);
4545796c8dcSSimon Schubert 			  write_exp_elt_opcode (OP_LONG); }
4555796c8dcSSimon Schubert 	;
4565796c8dcSSimon Schubert 
4575796c8dcSSimon Schubert exp	:	FLOAT
4585796c8dcSSimon Schubert 			{ write_exp_elt_opcode (OP_DOUBLE);
4595796c8dcSSimon Schubert 			  write_exp_elt_type (parse_f_type->builtin_real_s8);
4605796c8dcSSimon Schubert 			  write_exp_elt_dblcst ($1);
4615796c8dcSSimon Schubert 			  write_exp_elt_opcode (OP_DOUBLE); }
4625796c8dcSSimon Schubert 	;
4635796c8dcSSimon Schubert 
4645796c8dcSSimon Schubert exp	:	variable
4655796c8dcSSimon Schubert 	;
4665796c8dcSSimon Schubert 
4675796c8dcSSimon Schubert exp	:	VARIABLE
4685796c8dcSSimon Schubert 	;
4695796c8dcSSimon Schubert 
4705796c8dcSSimon Schubert exp	:	SIZEOF '(' type ')'	%prec UNARY
4715796c8dcSSimon Schubert 			{ write_exp_elt_opcode (OP_LONG);
4725796c8dcSSimon Schubert 			  write_exp_elt_type (parse_f_type->builtin_integer);
4735796c8dcSSimon Schubert 			  CHECK_TYPEDEF ($3);
4745796c8dcSSimon Schubert 			  write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3));
4755796c8dcSSimon Schubert 			  write_exp_elt_opcode (OP_LONG); }
4765796c8dcSSimon Schubert 	;
4775796c8dcSSimon Schubert 
4785796c8dcSSimon Schubert exp     :       BOOLEAN_LITERAL
4795796c8dcSSimon Schubert 			{ write_exp_elt_opcode (OP_BOOL);
4805796c8dcSSimon Schubert 			  write_exp_elt_longcst ((LONGEST) $1);
4815796c8dcSSimon Schubert 			  write_exp_elt_opcode (OP_BOOL);
4825796c8dcSSimon Schubert 			}
4835796c8dcSSimon Schubert         ;
4845796c8dcSSimon Schubert 
4855796c8dcSSimon Schubert exp	:	STRING_LITERAL
4865796c8dcSSimon Schubert 			{
4875796c8dcSSimon Schubert 			  write_exp_elt_opcode (OP_STRING);
4885796c8dcSSimon Schubert 			  write_exp_string ($1);
4895796c8dcSSimon Schubert 			  write_exp_elt_opcode (OP_STRING);
4905796c8dcSSimon Schubert 			}
4915796c8dcSSimon Schubert 	;
4925796c8dcSSimon Schubert 
4935796c8dcSSimon Schubert variable:	name_not_typename
4945796c8dcSSimon Schubert 			{ struct symbol *sym = $1.sym;
4955796c8dcSSimon Schubert 
4965796c8dcSSimon Schubert 			  if (sym)
4975796c8dcSSimon Schubert 			    {
4985796c8dcSSimon Schubert 			      if (symbol_read_needs_frame (sym))
4995796c8dcSSimon Schubert 				{
500cf7f2e2dSJohn Marino 				  if (innermost_block == 0
501cf7f2e2dSJohn Marino 				      || contained_in (block_found,
5025796c8dcSSimon Schubert 						       innermost_block))
5035796c8dcSSimon Schubert 				    innermost_block = block_found;
5045796c8dcSSimon Schubert 				}
5055796c8dcSSimon Schubert 			      write_exp_elt_opcode (OP_VAR_VALUE);
5065796c8dcSSimon Schubert 			      /* We want to use the selected frame, not
5075796c8dcSSimon Schubert 				 another more inner frame which happens to
5085796c8dcSSimon Schubert 				 be in the same block.  */
5095796c8dcSSimon Schubert 			      write_exp_elt_block (NULL);
5105796c8dcSSimon Schubert 			      write_exp_elt_sym (sym);
5115796c8dcSSimon Schubert 			      write_exp_elt_opcode (OP_VAR_VALUE);
5125796c8dcSSimon Schubert 			      break;
5135796c8dcSSimon Schubert 			    }
5145796c8dcSSimon Schubert 			  else
5155796c8dcSSimon Schubert 			    {
5165796c8dcSSimon Schubert 			      struct minimal_symbol *msymbol;
5175796c8dcSSimon Schubert 			      char *arg = copy_name ($1.stoken);
5185796c8dcSSimon Schubert 
5195796c8dcSSimon Schubert 			      msymbol =
5205796c8dcSSimon Schubert 				lookup_minimal_symbol (arg, NULL, NULL);
5215796c8dcSSimon Schubert 			      if (msymbol != NULL)
5225796c8dcSSimon Schubert 				write_exp_msymbol (msymbol);
5235796c8dcSSimon Schubert 			      else if (!have_full_symbols () && !have_partial_symbols ())
524c50c785cSJohn Marino 				error (_("No symbol table is loaded.  Use the \"file\" command."));
5255796c8dcSSimon Schubert 			      else
526c50c785cSJohn Marino 				error (_("No symbol \"%s\" in current context."),
5275796c8dcSSimon Schubert 				       copy_name ($1.stoken));
5285796c8dcSSimon Schubert 			    }
5295796c8dcSSimon Schubert 			}
5305796c8dcSSimon Schubert 	;
5315796c8dcSSimon Schubert 
5325796c8dcSSimon Schubert 
5335796c8dcSSimon Schubert type    :       ptype
5345796c8dcSSimon Schubert         ;
5355796c8dcSSimon Schubert 
5365796c8dcSSimon Schubert ptype	:	typebase
5375796c8dcSSimon Schubert 	|	typebase abs_decl
5385796c8dcSSimon Schubert 		{
5395796c8dcSSimon Schubert 		  /* This is where the interesting stuff happens.  */
5405796c8dcSSimon Schubert 		  int done = 0;
5415796c8dcSSimon Schubert 		  int array_size;
5425796c8dcSSimon Schubert 		  struct type *follow_type = $1;
5435796c8dcSSimon Schubert 		  struct type *range_type;
5445796c8dcSSimon Schubert 
5455796c8dcSSimon Schubert 		  while (!done)
5465796c8dcSSimon Schubert 		    switch (pop_type ())
5475796c8dcSSimon Schubert 		      {
5485796c8dcSSimon Schubert 		      case tp_end:
5495796c8dcSSimon Schubert 			done = 1;
5505796c8dcSSimon Schubert 			break;
5515796c8dcSSimon Schubert 		      case tp_pointer:
5525796c8dcSSimon Schubert 			follow_type = lookup_pointer_type (follow_type);
5535796c8dcSSimon Schubert 			break;
5545796c8dcSSimon Schubert 		      case tp_reference:
5555796c8dcSSimon Schubert 			follow_type = lookup_reference_type (follow_type);
5565796c8dcSSimon Schubert 			break;
5575796c8dcSSimon Schubert 		      case tp_array:
5585796c8dcSSimon Schubert 			array_size = pop_type_int ();
5595796c8dcSSimon Schubert 			if (array_size != -1)
5605796c8dcSSimon Schubert 			  {
5615796c8dcSSimon Schubert 			    range_type =
5625796c8dcSSimon Schubert 			      create_range_type ((struct type *) NULL,
5635796c8dcSSimon Schubert 						 parse_f_type->builtin_integer,
5645796c8dcSSimon Schubert 						 0, array_size - 1);
5655796c8dcSSimon Schubert 			    follow_type =
5665796c8dcSSimon Schubert 			      create_array_type ((struct type *) NULL,
5675796c8dcSSimon Schubert 						 follow_type, range_type);
5685796c8dcSSimon Schubert 			  }
5695796c8dcSSimon Schubert 			else
5705796c8dcSSimon Schubert 			  follow_type = lookup_pointer_type (follow_type);
5715796c8dcSSimon Schubert 			break;
5725796c8dcSSimon Schubert 		      case tp_function:
5735796c8dcSSimon Schubert 			follow_type = lookup_function_type (follow_type);
5745796c8dcSSimon Schubert 			break;
5755796c8dcSSimon Schubert 		      }
5765796c8dcSSimon Schubert 		  $$ = follow_type;
5775796c8dcSSimon Schubert 		}
5785796c8dcSSimon Schubert 	;
5795796c8dcSSimon Schubert 
5805796c8dcSSimon Schubert abs_decl:	'*'
5815796c8dcSSimon Schubert 			{ push_type (tp_pointer); $$ = 0; }
5825796c8dcSSimon Schubert 	|	'*' abs_decl
5835796c8dcSSimon Schubert 			{ push_type (tp_pointer); $$ = $2; }
5845796c8dcSSimon Schubert 	|	'&'
5855796c8dcSSimon Schubert 			{ push_type (tp_reference); $$ = 0; }
5865796c8dcSSimon Schubert 	|	'&' abs_decl
5875796c8dcSSimon Schubert 			{ push_type (tp_reference); $$ = $2; }
5885796c8dcSSimon Schubert 	|	direct_abs_decl
5895796c8dcSSimon Schubert 	;
5905796c8dcSSimon Schubert 
5915796c8dcSSimon Schubert direct_abs_decl: '(' abs_decl ')'
5925796c8dcSSimon Schubert 			{ $$ = $2; }
5935796c8dcSSimon Schubert 	| 	direct_abs_decl func_mod
5945796c8dcSSimon Schubert 			{ push_type (tp_function); }
5955796c8dcSSimon Schubert 	|	func_mod
5965796c8dcSSimon Schubert 			{ push_type (tp_function); }
5975796c8dcSSimon Schubert 	;
5985796c8dcSSimon Schubert 
5995796c8dcSSimon Schubert func_mod:	'(' ')'
6005796c8dcSSimon Schubert 			{ $$ = 0; }
6015796c8dcSSimon Schubert 	|	'(' nonempty_typelist ')'
6025796c8dcSSimon Schubert 			{ free ($2); $$ = 0; }
6035796c8dcSSimon Schubert 	;
6045796c8dcSSimon Schubert 
6055796c8dcSSimon Schubert typebase  /* Implements (approximately): (type-qualifier)* type-specifier */
6065796c8dcSSimon Schubert 	:	TYPENAME
6075796c8dcSSimon Schubert 			{ $$ = $1.type; }
6085796c8dcSSimon Schubert 	|	INT_KEYWORD
6095796c8dcSSimon Schubert 			{ $$ = parse_f_type->builtin_integer; }
6105796c8dcSSimon Schubert 	|	INT_S2_KEYWORD
6115796c8dcSSimon Schubert 			{ $$ = parse_f_type->builtin_integer_s2; }
6125796c8dcSSimon Schubert 	|	CHARACTER
6135796c8dcSSimon Schubert 			{ $$ = parse_f_type->builtin_character; }
614cf7f2e2dSJohn Marino 	|	LOGICAL_S8_KEYWORD
615cf7f2e2dSJohn Marino 			{ $$ = parse_f_type->builtin_logical_s8; }
6165796c8dcSSimon Schubert 	|	LOGICAL_KEYWORD
6175796c8dcSSimon Schubert 			{ $$ = parse_f_type->builtin_logical; }
6185796c8dcSSimon Schubert 	|	LOGICAL_S2_KEYWORD
6195796c8dcSSimon Schubert 			{ $$ = parse_f_type->builtin_logical_s2; }
6205796c8dcSSimon Schubert 	|	LOGICAL_S1_KEYWORD
6215796c8dcSSimon Schubert 			{ $$ = parse_f_type->builtin_logical_s1; }
6225796c8dcSSimon Schubert 	|	REAL_KEYWORD
6235796c8dcSSimon Schubert 			{ $$ = parse_f_type->builtin_real; }
6245796c8dcSSimon Schubert 	|       REAL_S8_KEYWORD
6255796c8dcSSimon Schubert 			{ $$ = parse_f_type->builtin_real_s8; }
6265796c8dcSSimon Schubert 	|	REAL_S16_KEYWORD
6275796c8dcSSimon Schubert 			{ $$ = parse_f_type->builtin_real_s16; }
6285796c8dcSSimon Schubert 	|	COMPLEX_S8_KEYWORD
6295796c8dcSSimon Schubert 			{ $$ = parse_f_type->builtin_complex_s8; }
6305796c8dcSSimon Schubert 	|	COMPLEX_S16_KEYWORD
6315796c8dcSSimon Schubert 			{ $$ = parse_f_type->builtin_complex_s16; }
6325796c8dcSSimon Schubert 	|	COMPLEX_S32_KEYWORD
6335796c8dcSSimon Schubert 			{ $$ = parse_f_type->builtin_complex_s32; }
6345796c8dcSSimon Schubert 	;
6355796c8dcSSimon Schubert 
6365796c8dcSSimon Schubert nonempty_typelist
6375796c8dcSSimon Schubert 	:	type
6385796c8dcSSimon Schubert 		{ $$ = (struct type **) malloc (sizeof (struct type *) * 2);
6395796c8dcSSimon Schubert 		  $<ivec>$[0] = 1;	/* Number of types in vector */
6405796c8dcSSimon Schubert 		  $$[1] = $1;
6415796c8dcSSimon Schubert 		}
6425796c8dcSSimon Schubert 	|	nonempty_typelist ',' type
6435796c8dcSSimon Schubert 		{ int len = sizeof (struct type *) * (++($<ivec>1[0]) + 1);
6445796c8dcSSimon Schubert 		  $$ = (struct type **) realloc ((char *) $1, len);
6455796c8dcSSimon Schubert 		  $$[$<ivec>$[0]] = $3;
6465796c8dcSSimon Schubert 		}
6475796c8dcSSimon Schubert 	;
6485796c8dcSSimon Schubert 
6495796c8dcSSimon Schubert name	:	NAME
6505796c8dcSSimon Schubert 		{  $$ = $1.stoken; }
6515796c8dcSSimon Schubert 	;
6525796c8dcSSimon Schubert 
6535796c8dcSSimon Schubert name_not_typename :	NAME
6545796c8dcSSimon Schubert /* These would be useful if name_not_typename was useful, but it is just
6555796c8dcSSimon Schubert    a fake for "variable", so these cause reduce/reduce conflicts because
6565796c8dcSSimon Schubert    the parser can't tell whether NAME_OR_INT is a name_not_typename (=variable,
6575796c8dcSSimon Schubert    =exp) or just an exp.  If name_not_typename was ever used in an lvalue
6585796c8dcSSimon Schubert    context where only a name could occur, this might be useful.
6595796c8dcSSimon Schubert   	|	NAME_OR_INT
6605796c8dcSSimon Schubert    */
6615796c8dcSSimon Schubert 	;
6625796c8dcSSimon Schubert 
6635796c8dcSSimon Schubert %%
6645796c8dcSSimon Schubert 
6655796c8dcSSimon Schubert /* Take care of parsing a number (anything that starts with a digit).
6665796c8dcSSimon Schubert    Set yylval and return the token type; update lexptr.
6675796c8dcSSimon Schubert    LEN is the number of characters in it.  */
6685796c8dcSSimon Schubert 
6695796c8dcSSimon Schubert /*** Needs some error checking for the float case ***/
6705796c8dcSSimon Schubert 
6715796c8dcSSimon Schubert static int
672*ef5ccd6cSJohn Marino parse_number (char *p, int len, int parsed_float, YYSTYPE *putithere)
6735796c8dcSSimon Schubert {
6745796c8dcSSimon Schubert   LONGEST n = 0;
6755796c8dcSSimon Schubert   LONGEST prevn = 0;
6765796c8dcSSimon Schubert   int c;
6775796c8dcSSimon Schubert   int base = input_radix;
6785796c8dcSSimon Schubert   int unsigned_p = 0;
6795796c8dcSSimon Schubert   int long_p = 0;
6805796c8dcSSimon Schubert   ULONGEST high_bit;
6815796c8dcSSimon Schubert   struct type *signed_type;
6825796c8dcSSimon Schubert   struct type *unsigned_type;
6835796c8dcSSimon Schubert 
6845796c8dcSSimon Schubert   if (parsed_float)
6855796c8dcSSimon Schubert     {
6865796c8dcSSimon Schubert       /* It's a float since it contains a point or an exponent.  */
6875796c8dcSSimon Schubert       /* [dD] is not understood as an exponent by atof, change it to 'e'.  */
6885796c8dcSSimon Schubert       char *tmp, *tmp2;
6895796c8dcSSimon Schubert 
6905796c8dcSSimon Schubert       tmp = xstrdup (p);
6915796c8dcSSimon Schubert       for (tmp2 = tmp; *tmp2; ++tmp2)
6925796c8dcSSimon Schubert 	if (*tmp2 == 'd' || *tmp2 == 'D')
6935796c8dcSSimon Schubert 	  *tmp2 = 'e';
6945796c8dcSSimon Schubert       putithere->dval = atof (tmp);
6955796c8dcSSimon Schubert       free (tmp);
6965796c8dcSSimon Schubert       return FLOAT;
6975796c8dcSSimon Schubert     }
6985796c8dcSSimon Schubert 
6995796c8dcSSimon Schubert   /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
7005796c8dcSSimon Schubert   if (p[0] == '0')
7015796c8dcSSimon Schubert     switch (p[1])
7025796c8dcSSimon Schubert       {
7035796c8dcSSimon Schubert       case 'x':
7045796c8dcSSimon Schubert       case 'X':
7055796c8dcSSimon Schubert 	if (len >= 3)
7065796c8dcSSimon Schubert 	  {
7075796c8dcSSimon Schubert 	    p += 2;
7085796c8dcSSimon Schubert 	    base = 16;
7095796c8dcSSimon Schubert 	    len -= 2;
7105796c8dcSSimon Schubert 	  }
7115796c8dcSSimon Schubert 	break;
7125796c8dcSSimon Schubert 
7135796c8dcSSimon Schubert       case 't':
7145796c8dcSSimon Schubert       case 'T':
7155796c8dcSSimon Schubert       case 'd':
7165796c8dcSSimon Schubert       case 'D':
7175796c8dcSSimon Schubert 	if (len >= 3)
7185796c8dcSSimon Schubert 	  {
7195796c8dcSSimon Schubert 	    p += 2;
7205796c8dcSSimon Schubert 	    base = 10;
7215796c8dcSSimon Schubert 	    len -= 2;
7225796c8dcSSimon Schubert 	  }
7235796c8dcSSimon Schubert 	break;
7245796c8dcSSimon Schubert 
7255796c8dcSSimon Schubert       default:
7265796c8dcSSimon Schubert 	base = 8;
7275796c8dcSSimon Schubert 	break;
7285796c8dcSSimon Schubert       }
7295796c8dcSSimon Schubert 
7305796c8dcSSimon Schubert   while (len-- > 0)
7315796c8dcSSimon Schubert     {
7325796c8dcSSimon Schubert       c = *p++;
7335796c8dcSSimon Schubert       if (isupper (c))
7345796c8dcSSimon Schubert 	c = tolower (c);
7355796c8dcSSimon Schubert       if (len == 0 && c == 'l')
7365796c8dcSSimon Schubert 	long_p = 1;
7375796c8dcSSimon Schubert       else if (len == 0 && c == 'u')
7385796c8dcSSimon Schubert 	unsigned_p = 1;
7395796c8dcSSimon Schubert       else
7405796c8dcSSimon Schubert 	{
7415796c8dcSSimon Schubert 	  int i;
7425796c8dcSSimon Schubert 	  if (c >= '0' && c <= '9')
7435796c8dcSSimon Schubert 	    i = c - '0';
7445796c8dcSSimon Schubert 	  else if (c >= 'a' && c <= 'f')
7455796c8dcSSimon Schubert 	    i = c - 'a' + 10;
7465796c8dcSSimon Schubert 	  else
7475796c8dcSSimon Schubert 	    return ERROR;	/* Char not a digit */
7485796c8dcSSimon Schubert 	  if (i >= base)
7495796c8dcSSimon Schubert 	    return ERROR;		/* Invalid digit in this base */
7505796c8dcSSimon Schubert 	  n *= base;
7515796c8dcSSimon Schubert 	  n += i;
7525796c8dcSSimon Schubert 	}
7535796c8dcSSimon Schubert       /* Portably test for overflow (only works for nonzero values, so make
7545796c8dcSSimon Schubert 	 a second check for zero).  */
7555796c8dcSSimon Schubert       if ((prevn >= n) && n != 0)
7565796c8dcSSimon Schubert 	unsigned_p=1;		/* Try something unsigned */
7575796c8dcSSimon Schubert       /* If range checking enabled, portably test for unsigned overflow.  */
7585796c8dcSSimon Schubert       if (RANGE_CHECK && n != 0)
7595796c8dcSSimon Schubert 	{
7605796c8dcSSimon Schubert 	  if ((unsigned_p && (unsigned)prevn >= (unsigned)n))
761c50c785cSJohn Marino 	    range_error (_("Overflow on numeric constant."));
7625796c8dcSSimon Schubert 	}
7635796c8dcSSimon Schubert       prevn = n;
7645796c8dcSSimon Schubert     }
7655796c8dcSSimon Schubert 
7665796c8dcSSimon Schubert   /* If the number is too big to be an int, or it's got an l suffix
7675796c8dcSSimon Schubert      then it's a long.  Work out if this has to be a long by
768a45ae5f8SJohn Marino      shifting right and seeing if anything remains, and the
7695796c8dcSSimon Schubert      target int size is different to the target long size.
7705796c8dcSSimon Schubert 
7715796c8dcSSimon Schubert      In the expression below, we could have tested
7725796c8dcSSimon Schubert      (n >> gdbarch_int_bit (parse_gdbarch))
7735796c8dcSSimon Schubert      to see if it was zero,
7745796c8dcSSimon Schubert      but too many compilers warn about that, when ints and longs
7755796c8dcSSimon Schubert      are the same size.  So we shift it twice, with fewer bits
7765796c8dcSSimon Schubert      each time, for the same result.  */
7775796c8dcSSimon Schubert 
7785796c8dcSSimon Schubert   if ((gdbarch_int_bit (parse_gdbarch) != gdbarch_long_bit (parse_gdbarch)
7795796c8dcSSimon Schubert        && ((n >> 2)
7805796c8dcSSimon Schubert 	   >> (gdbarch_int_bit (parse_gdbarch)-2))) /* Avoid shift warning */
7815796c8dcSSimon Schubert       || long_p)
7825796c8dcSSimon Schubert     {
7835796c8dcSSimon Schubert       high_bit = ((ULONGEST)1) << (gdbarch_long_bit (parse_gdbarch)-1);
7845796c8dcSSimon Schubert       unsigned_type = parse_type->builtin_unsigned_long;
7855796c8dcSSimon Schubert       signed_type = parse_type->builtin_long;
7865796c8dcSSimon Schubert     }
7875796c8dcSSimon Schubert   else
7885796c8dcSSimon Schubert     {
7895796c8dcSSimon Schubert       high_bit = ((ULONGEST)1) << (gdbarch_int_bit (parse_gdbarch)-1);
7905796c8dcSSimon Schubert       unsigned_type = parse_type->builtin_unsigned_int;
7915796c8dcSSimon Schubert       signed_type = parse_type->builtin_int;
7925796c8dcSSimon Schubert     }
7935796c8dcSSimon Schubert 
7945796c8dcSSimon Schubert   putithere->typed_val.val = n;
7955796c8dcSSimon Schubert 
7965796c8dcSSimon Schubert   /* If the high bit of the worked out type is set then this number
7975796c8dcSSimon Schubert      has to be unsigned.  */
7985796c8dcSSimon Schubert 
7995796c8dcSSimon Schubert   if (unsigned_p || (n & high_bit))
8005796c8dcSSimon Schubert     putithere->typed_val.type = unsigned_type;
8015796c8dcSSimon Schubert   else
8025796c8dcSSimon Schubert     putithere->typed_val.type = signed_type;
8035796c8dcSSimon Schubert 
8045796c8dcSSimon Schubert   return INT;
8055796c8dcSSimon Schubert }
8065796c8dcSSimon Schubert 
8075796c8dcSSimon Schubert struct token
8085796c8dcSSimon Schubert {
8095796c8dcSSimon Schubert   char *operator;
8105796c8dcSSimon Schubert   int token;
8115796c8dcSSimon Schubert   enum exp_opcode opcode;
8125796c8dcSSimon Schubert };
8135796c8dcSSimon Schubert 
8145796c8dcSSimon Schubert static const struct token dot_ops[] =
8155796c8dcSSimon Schubert {
8165796c8dcSSimon Schubert   { ".and.", BOOL_AND, BINOP_END },
8175796c8dcSSimon Schubert   { ".AND.", BOOL_AND, BINOP_END },
8185796c8dcSSimon Schubert   { ".or.", BOOL_OR, BINOP_END },
8195796c8dcSSimon Schubert   { ".OR.", BOOL_OR, BINOP_END },
8205796c8dcSSimon Schubert   { ".not.", BOOL_NOT, BINOP_END },
8215796c8dcSSimon Schubert   { ".NOT.", BOOL_NOT, BINOP_END },
8225796c8dcSSimon Schubert   { ".eq.", EQUAL, BINOP_END },
8235796c8dcSSimon Schubert   { ".EQ.", EQUAL, BINOP_END },
8245796c8dcSSimon Schubert   { ".eqv.", EQUAL, BINOP_END },
8255796c8dcSSimon Schubert   { ".NEQV.", NOTEQUAL, BINOP_END },
8265796c8dcSSimon Schubert   { ".neqv.", NOTEQUAL, BINOP_END },
8275796c8dcSSimon Schubert   { ".EQV.", EQUAL, BINOP_END },
8285796c8dcSSimon Schubert   { ".ne.", NOTEQUAL, BINOP_END },
8295796c8dcSSimon Schubert   { ".NE.", NOTEQUAL, BINOP_END },
8305796c8dcSSimon Schubert   { ".le.", LEQ, BINOP_END },
8315796c8dcSSimon Schubert   { ".LE.", LEQ, BINOP_END },
8325796c8dcSSimon Schubert   { ".ge.", GEQ, BINOP_END },
8335796c8dcSSimon Schubert   { ".GE.", GEQ, BINOP_END },
8345796c8dcSSimon Schubert   { ".gt.", GREATERTHAN, BINOP_END },
8355796c8dcSSimon Schubert   { ".GT.", GREATERTHAN, BINOP_END },
8365796c8dcSSimon Schubert   { ".lt.", LESSTHAN, BINOP_END },
8375796c8dcSSimon Schubert   { ".LT.", LESSTHAN, BINOP_END },
8385796c8dcSSimon Schubert   { NULL, 0, 0 }
8395796c8dcSSimon Schubert };
8405796c8dcSSimon Schubert 
8415796c8dcSSimon Schubert struct f77_boolean_val
8425796c8dcSSimon Schubert {
8435796c8dcSSimon Schubert   char *name;
8445796c8dcSSimon Schubert   int value;
8455796c8dcSSimon Schubert };
8465796c8dcSSimon Schubert 
8475796c8dcSSimon Schubert static const struct f77_boolean_val boolean_values[]  =
8485796c8dcSSimon Schubert {
8495796c8dcSSimon Schubert   { ".true.", 1 },
8505796c8dcSSimon Schubert   { ".TRUE.", 1 },
8515796c8dcSSimon Schubert   { ".false.", 0 },
8525796c8dcSSimon Schubert   { ".FALSE.", 0 },
8535796c8dcSSimon Schubert   { NULL, 0 }
8545796c8dcSSimon Schubert };
8555796c8dcSSimon Schubert 
8565796c8dcSSimon Schubert static const struct token f77_keywords[] =
8575796c8dcSSimon Schubert {
8585796c8dcSSimon Schubert   { "complex_16", COMPLEX_S16_KEYWORD, BINOP_END },
8595796c8dcSSimon Schubert   { "complex_32", COMPLEX_S32_KEYWORD, BINOP_END },
8605796c8dcSSimon Schubert   { "character", CHARACTER, BINOP_END },
8615796c8dcSSimon Schubert   { "integer_2", INT_S2_KEYWORD, BINOP_END },
8625796c8dcSSimon Schubert   { "logical_1", LOGICAL_S1_KEYWORD, BINOP_END },
8635796c8dcSSimon Schubert   { "logical_2", LOGICAL_S2_KEYWORD, BINOP_END },
864cf7f2e2dSJohn Marino   { "logical_8", LOGICAL_S8_KEYWORD, BINOP_END },
8655796c8dcSSimon Schubert   { "complex_8", COMPLEX_S8_KEYWORD, BINOP_END },
8665796c8dcSSimon Schubert   { "integer", INT_KEYWORD, BINOP_END },
8675796c8dcSSimon Schubert   { "logical", LOGICAL_KEYWORD, BINOP_END },
8685796c8dcSSimon Schubert   { "real_16", REAL_S16_KEYWORD, BINOP_END },
8695796c8dcSSimon Schubert   { "complex", COMPLEX_S8_KEYWORD, BINOP_END },
8705796c8dcSSimon Schubert   { "sizeof", SIZEOF, BINOP_END },
8715796c8dcSSimon Schubert   { "real_8", REAL_S8_KEYWORD, BINOP_END },
8725796c8dcSSimon Schubert   { "real", REAL_KEYWORD, BINOP_END },
8735796c8dcSSimon Schubert   { NULL, 0, 0 }
8745796c8dcSSimon Schubert };
8755796c8dcSSimon Schubert 
8765796c8dcSSimon Schubert /* Implementation of a dynamically expandable buffer for processing input
8775796c8dcSSimon Schubert    characters acquired through lexptr and building a value to return in
8785796c8dcSSimon Schubert    yylval.  Ripped off from ch-exp.y */
8795796c8dcSSimon Schubert 
8805796c8dcSSimon Schubert static char *tempbuf;		/* Current buffer contents */
8815796c8dcSSimon Schubert static int tempbufsize;		/* Size of allocated buffer */
8825796c8dcSSimon Schubert static int tempbufindex;	/* Current index into buffer */
8835796c8dcSSimon Schubert 
8845796c8dcSSimon Schubert #define GROWBY_MIN_SIZE 64	/* Minimum amount to grow buffer by */
8855796c8dcSSimon Schubert 
8865796c8dcSSimon Schubert #define CHECKBUF(size) \
8875796c8dcSSimon Schubert   do { \
8885796c8dcSSimon Schubert     if (tempbufindex + (size) >= tempbufsize) \
8895796c8dcSSimon Schubert       { \
8905796c8dcSSimon Schubert 	growbuf_by_size (size); \
8915796c8dcSSimon Schubert       } \
8925796c8dcSSimon Schubert   } while (0);
8935796c8dcSSimon Schubert 
8945796c8dcSSimon Schubert 
895c50c785cSJohn Marino /* Grow the static temp buffer if necessary, including allocating the
896c50c785cSJohn Marino    first one on demand.  */
8975796c8dcSSimon Schubert 
8985796c8dcSSimon Schubert static void
growbuf_by_size(int count)899*ef5ccd6cSJohn Marino growbuf_by_size (int count)
9005796c8dcSSimon Schubert {
9015796c8dcSSimon Schubert   int growby;
9025796c8dcSSimon Schubert 
9035796c8dcSSimon Schubert   growby = max (count, GROWBY_MIN_SIZE);
9045796c8dcSSimon Schubert   tempbufsize += growby;
9055796c8dcSSimon Schubert   if (tempbuf == NULL)
9065796c8dcSSimon Schubert     tempbuf = (char *) malloc (tempbufsize);
9075796c8dcSSimon Schubert   else
9085796c8dcSSimon Schubert     tempbuf = (char *) realloc (tempbuf, tempbufsize);
9095796c8dcSSimon Schubert }
9105796c8dcSSimon Schubert 
9115796c8dcSSimon Schubert /* Blatantly ripped off from ch-exp.y. This routine recognizes F77
9125796c8dcSSimon Schubert    string-literals.
9135796c8dcSSimon Schubert 
9145796c8dcSSimon Schubert    Recognize a string literal.  A string literal is a nonzero sequence
9155796c8dcSSimon Schubert    of characters enclosed in matching single quotes, except that
9165796c8dcSSimon Schubert    a single character inside single quotes is a character literal, which
9175796c8dcSSimon Schubert    we reject as a string literal.  To embed the terminator character inside
9185796c8dcSSimon Schubert    a string, it is simply doubled (I.E. 'this''is''one''string') */
9195796c8dcSSimon Schubert 
9205796c8dcSSimon Schubert static int
match_string_literal(void)921c50c785cSJohn Marino match_string_literal (void)
9225796c8dcSSimon Schubert {
9235796c8dcSSimon Schubert   char *tokptr = lexptr;
9245796c8dcSSimon Schubert 
9255796c8dcSSimon Schubert   for (tempbufindex = 0, tokptr++; *tokptr != '\0'; tokptr++)
9265796c8dcSSimon Schubert     {
9275796c8dcSSimon Schubert       CHECKBUF (1);
9285796c8dcSSimon Schubert       if (*tokptr == *lexptr)
9295796c8dcSSimon Schubert 	{
9305796c8dcSSimon Schubert 	  if (*(tokptr + 1) == *lexptr)
9315796c8dcSSimon Schubert 	    tokptr++;
9325796c8dcSSimon Schubert 	  else
9335796c8dcSSimon Schubert 	    break;
9345796c8dcSSimon Schubert 	}
9355796c8dcSSimon Schubert       tempbuf[tempbufindex++] = *tokptr;
9365796c8dcSSimon Schubert     }
9375796c8dcSSimon Schubert   if (*tokptr == '\0'					/* no terminator */
9385796c8dcSSimon Schubert       || tempbufindex == 0)				/* no string */
9395796c8dcSSimon Schubert     return 0;
9405796c8dcSSimon Schubert   else
9415796c8dcSSimon Schubert     {
9425796c8dcSSimon Schubert       tempbuf[tempbufindex] = '\0';
9435796c8dcSSimon Schubert       yylval.sval.ptr = tempbuf;
9445796c8dcSSimon Schubert       yylval.sval.length = tempbufindex;
9455796c8dcSSimon Schubert       lexptr = ++tokptr;
9465796c8dcSSimon Schubert       return STRING_LITERAL;
9475796c8dcSSimon Schubert     }
9485796c8dcSSimon Schubert }
9495796c8dcSSimon Schubert 
9505796c8dcSSimon Schubert /* Read one token, getting characters through lexptr.  */
9515796c8dcSSimon Schubert 
9525796c8dcSSimon Schubert static int
yylex(void)953c50c785cSJohn Marino yylex (void)
9545796c8dcSSimon Schubert {
9555796c8dcSSimon Schubert   int c;
9565796c8dcSSimon Schubert   int namelen;
9575796c8dcSSimon Schubert   unsigned int i,token;
9585796c8dcSSimon Schubert   char *tokstart;
9595796c8dcSSimon Schubert 
9605796c8dcSSimon Schubert  retry:
9615796c8dcSSimon Schubert 
9625796c8dcSSimon Schubert   prev_lexptr = lexptr;
9635796c8dcSSimon Schubert 
9645796c8dcSSimon Schubert   tokstart = lexptr;
9655796c8dcSSimon Schubert 
9665796c8dcSSimon Schubert   /* First of all, let us make sure we are not dealing with the
9675796c8dcSSimon Schubert      special tokens .true. and .false. which evaluate to 1 and 0.  */
9685796c8dcSSimon Schubert 
9695796c8dcSSimon Schubert   if (*lexptr == '.')
9705796c8dcSSimon Schubert     {
9715796c8dcSSimon Schubert       for (i = 0; boolean_values[i].name != NULL; i++)
9725796c8dcSSimon Schubert 	{
9735796c8dcSSimon Schubert 	  if (strncmp (tokstart, boolean_values[i].name,
9745796c8dcSSimon Schubert 		       strlen (boolean_values[i].name)) == 0)
9755796c8dcSSimon Schubert 	    {
9765796c8dcSSimon Schubert 	      lexptr += strlen (boolean_values[i].name);
9775796c8dcSSimon Schubert 	      yylval.lval = boolean_values[i].value;
9785796c8dcSSimon Schubert 	      return BOOLEAN_LITERAL;
9795796c8dcSSimon Schubert 	    }
9805796c8dcSSimon Schubert 	}
9815796c8dcSSimon Schubert     }
9825796c8dcSSimon Schubert 
9835796c8dcSSimon Schubert   /* See if it is a special .foo. operator.  */
9845796c8dcSSimon Schubert 
9855796c8dcSSimon Schubert   for (i = 0; dot_ops[i].operator != NULL; i++)
986c50c785cSJohn Marino     if (strncmp (tokstart, dot_ops[i].operator,
987c50c785cSJohn Marino 		 strlen (dot_ops[i].operator)) == 0)
9885796c8dcSSimon Schubert       {
9895796c8dcSSimon Schubert 	lexptr += strlen (dot_ops[i].operator);
9905796c8dcSSimon Schubert 	yylval.opcode = dot_ops[i].opcode;
9915796c8dcSSimon Schubert 	return dot_ops[i].token;
9925796c8dcSSimon Schubert       }
9935796c8dcSSimon Schubert 
9945796c8dcSSimon Schubert   /* See if it is an exponentiation operator.  */
9955796c8dcSSimon Schubert 
9965796c8dcSSimon Schubert   if (strncmp (tokstart, "**", 2) == 0)
9975796c8dcSSimon Schubert     {
9985796c8dcSSimon Schubert       lexptr += 2;
9995796c8dcSSimon Schubert       yylval.opcode = BINOP_EXP;
10005796c8dcSSimon Schubert       return STARSTAR;
10015796c8dcSSimon Schubert     }
10025796c8dcSSimon Schubert 
10035796c8dcSSimon Schubert   switch (c = *tokstart)
10045796c8dcSSimon Schubert     {
10055796c8dcSSimon Schubert     case 0:
10065796c8dcSSimon Schubert       return 0;
10075796c8dcSSimon Schubert 
10085796c8dcSSimon Schubert     case ' ':
10095796c8dcSSimon Schubert     case '\t':
10105796c8dcSSimon Schubert     case '\n':
10115796c8dcSSimon Schubert       lexptr++;
10125796c8dcSSimon Schubert       goto retry;
10135796c8dcSSimon Schubert 
10145796c8dcSSimon Schubert     case '\'':
10155796c8dcSSimon Schubert       token = match_string_literal ();
10165796c8dcSSimon Schubert       if (token != 0)
10175796c8dcSSimon Schubert 	return (token);
10185796c8dcSSimon Schubert       break;
10195796c8dcSSimon Schubert 
10205796c8dcSSimon Schubert     case '(':
10215796c8dcSSimon Schubert       paren_depth++;
10225796c8dcSSimon Schubert       lexptr++;
10235796c8dcSSimon Schubert       return c;
10245796c8dcSSimon Schubert 
10255796c8dcSSimon Schubert     case ')':
10265796c8dcSSimon Schubert       if (paren_depth == 0)
10275796c8dcSSimon Schubert 	return 0;
10285796c8dcSSimon Schubert       paren_depth--;
10295796c8dcSSimon Schubert       lexptr++;
10305796c8dcSSimon Schubert       return c;
10315796c8dcSSimon Schubert 
10325796c8dcSSimon Schubert     case ',':
10335796c8dcSSimon Schubert       if (comma_terminates && paren_depth == 0)
10345796c8dcSSimon Schubert 	return 0;
10355796c8dcSSimon Schubert       lexptr++;
10365796c8dcSSimon Schubert       return c;
10375796c8dcSSimon Schubert 
10385796c8dcSSimon Schubert     case '.':
10395796c8dcSSimon Schubert       /* Might be a floating point number.  */
10405796c8dcSSimon Schubert       if (lexptr[1] < '0' || lexptr[1] > '9')
10415796c8dcSSimon Schubert 	goto symbol;		/* Nope, must be a symbol.  */
10425796c8dcSSimon Schubert       /* FALL THRU into number case.  */
10435796c8dcSSimon Schubert 
10445796c8dcSSimon Schubert     case '0':
10455796c8dcSSimon Schubert     case '1':
10465796c8dcSSimon Schubert     case '2':
10475796c8dcSSimon Schubert     case '3':
10485796c8dcSSimon Schubert     case '4':
10495796c8dcSSimon Schubert     case '5':
10505796c8dcSSimon Schubert     case '6':
10515796c8dcSSimon Schubert     case '7':
10525796c8dcSSimon Schubert     case '8':
10535796c8dcSSimon Schubert     case '9':
10545796c8dcSSimon Schubert       {
10555796c8dcSSimon Schubert         /* It's a number.  */
10565796c8dcSSimon Schubert 	int got_dot = 0, got_e = 0, got_d = 0, toktype;
10575796c8dcSSimon Schubert 	char *p = tokstart;
10585796c8dcSSimon Schubert 	int hex = input_radix > 10;
10595796c8dcSSimon Schubert 
10605796c8dcSSimon Schubert 	if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
10615796c8dcSSimon Schubert 	  {
10625796c8dcSSimon Schubert 	    p += 2;
10635796c8dcSSimon Schubert 	    hex = 1;
10645796c8dcSSimon Schubert 	  }
1065c50c785cSJohn Marino 	else if (c == '0' && (p[1]=='t' || p[1]=='T'
1066c50c785cSJohn Marino 			      || p[1]=='d' || p[1]=='D'))
10675796c8dcSSimon Schubert 	  {
10685796c8dcSSimon Schubert 	    p += 2;
10695796c8dcSSimon Schubert 	    hex = 0;
10705796c8dcSSimon Schubert 	  }
10715796c8dcSSimon Schubert 
10725796c8dcSSimon Schubert 	for (;; ++p)
10735796c8dcSSimon Schubert 	  {
10745796c8dcSSimon Schubert 	    if (!hex && !got_e && (*p == 'e' || *p == 'E'))
10755796c8dcSSimon Schubert 	      got_dot = got_e = 1;
10765796c8dcSSimon Schubert 	    else if (!hex && !got_d && (*p == 'd' || *p == 'D'))
10775796c8dcSSimon Schubert 	      got_dot = got_d = 1;
10785796c8dcSSimon Schubert 	    else if (!hex && !got_dot && *p == '.')
10795796c8dcSSimon Schubert 	      got_dot = 1;
10805796c8dcSSimon Schubert 	    else if (((got_e && (p[-1] == 'e' || p[-1] == 'E'))
10815796c8dcSSimon Schubert 		     || (got_d && (p[-1] == 'd' || p[-1] == 'D')))
10825796c8dcSSimon Schubert 		     && (*p == '-' || *p == '+'))
10835796c8dcSSimon Schubert 	      /* This is the sign of the exponent, not the end of the
10845796c8dcSSimon Schubert 		 number.  */
10855796c8dcSSimon Schubert 	      continue;
10865796c8dcSSimon Schubert 	    /* We will take any letters or digits.  parse_number will
10875796c8dcSSimon Schubert 	       complain if past the radix, or if L or U are not final.  */
10885796c8dcSSimon Schubert 	    else if ((*p < '0' || *p > '9')
10895796c8dcSSimon Schubert 		     && ((*p < 'a' || *p > 'z')
10905796c8dcSSimon Schubert 			 && (*p < 'A' || *p > 'Z')))
10915796c8dcSSimon Schubert 	      break;
10925796c8dcSSimon Schubert 	  }
10935796c8dcSSimon Schubert 	toktype = parse_number (tokstart, p - tokstart, got_dot|got_e|got_d,
10945796c8dcSSimon Schubert 				&yylval);
10955796c8dcSSimon Schubert         if (toktype == ERROR)
10965796c8dcSSimon Schubert           {
10975796c8dcSSimon Schubert 	    char *err_copy = (char *) alloca (p - tokstart + 1);
10985796c8dcSSimon Schubert 
10995796c8dcSSimon Schubert 	    memcpy (err_copy, tokstart, p - tokstart);
11005796c8dcSSimon Schubert 	    err_copy[p - tokstart] = 0;
1101c50c785cSJohn Marino 	    error (_("Invalid number \"%s\"."), err_copy);
11025796c8dcSSimon Schubert 	  }
11035796c8dcSSimon Schubert 	lexptr = p;
11045796c8dcSSimon Schubert 	return toktype;
11055796c8dcSSimon Schubert       }
11065796c8dcSSimon Schubert 
11075796c8dcSSimon Schubert     case '+':
11085796c8dcSSimon Schubert     case '-':
11095796c8dcSSimon Schubert     case '*':
11105796c8dcSSimon Schubert     case '/':
11115796c8dcSSimon Schubert     case '%':
11125796c8dcSSimon Schubert     case '|':
11135796c8dcSSimon Schubert     case '&':
11145796c8dcSSimon Schubert     case '^':
11155796c8dcSSimon Schubert     case '~':
11165796c8dcSSimon Schubert     case '!':
11175796c8dcSSimon Schubert     case '@':
11185796c8dcSSimon Schubert     case '<':
11195796c8dcSSimon Schubert     case '>':
11205796c8dcSSimon Schubert     case '[':
11215796c8dcSSimon Schubert     case ']':
11225796c8dcSSimon Schubert     case '?':
11235796c8dcSSimon Schubert     case ':':
11245796c8dcSSimon Schubert     case '=':
11255796c8dcSSimon Schubert     case '{':
11265796c8dcSSimon Schubert     case '}':
11275796c8dcSSimon Schubert     symbol:
11285796c8dcSSimon Schubert       lexptr++;
11295796c8dcSSimon Schubert       return c;
11305796c8dcSSimon Schubert     }
11315796c8dcSSimon Schubert 
1132cf7f2e2dSJohn Marino   if (!(c == '_' || c == '$' || c ==':'
11335796c8dcSSimon Schubert 	|| (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
11345796c8dcSSimon Schubert     /* We must have come across a bad character (e.g. ';').  */
1135c50c785cSJohn Marino     error (_("Invalid character '%c' in expression."), c);
11365796c8dcSSimon Schubert 
11375796c8dcSSimon Schubert   namelen = 0;
11385796c8dcSSimon Schubert   for (c = tokstart[namelen];
1139cf7f2e2dSJohn Marino        (c == '_' || c == '$' || c == ':' || (c >= '0' && c <= '9')
11405796c8dcSSimon Schubert 	|| (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
11415796c8dcSSimon Schubert        c = tokstart[++namelen]);
11425796c8dcSSimon Schubert 
11435796c8dcSSimon Schubert   /* The token "if" terminates the expression and is NOT
11445796c8dcSSimon Schubert      removed from the input stream.  */
11455796c8dcSSimon Schubert 
11465796c8dcSSimon Schubert   if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
11475796c8dcSSimon Schubert     return 0;
11485796c8dcSSimon Schubert 
11495796c8dcSSimon Schubert   lexptr += namelen;
11505796c8dcSSimon Schubert 
11515796c8dcSSimon Schubert   /* Catch specific keywords.  */
11525796c8dcSSimon Schubert 
11535796c8dcSSimon Schubert   for (i = 0; f77_keywords[i].operator != NULL; i++)
1154c50c785cSJohn Marino     if (strlen (f77_keywords[i].operator) == namelen
1155c50c785cSJohn Marino 	&& strncmp (tokstart, f77_keywords[i].operator, namelen) == 0)
11565796c8dcSSimon Schubert       {
11575796c8dcSSimon Schubert 	/* 	lexptr += strlen(f77_keywords[i].operator); */
11585796c8dcSSimon Schubert 	yylval.opcode = f77_keywords[i].opcode;
11595796c8dcSSimon Schubert 	return f77_keywords[i].token;
11605796c8dcSSimon Schubert       }
11615796c8dcSSimon Schubert 
11625796c8dcSSimon Schubert   yylval.sval.ptr = tokstart;
11635796c8dcSSimon Schubert   yylval.sval.length = namelen;
11645796c8dcSSimon Schubert 
11655796c8dcSSimon Schubert   if (*tokstart == '$')
11665796c8dcSSimon Schubert     {
11675796c8dcSSimon Schubert       write_dollar_variable (yylval.sval);
11685796c8dcSSimon Schubert       return VARIABLE;
11695796c8dcSSimon Schubert     }
11705796c8dcSSimon Schubert 
11715796c8dcSSimon Schubert   /* Use token-type TYPENAME for symbols that happen to be defined
11725796c8dcSSimon Schubert      currently as names of types; NAME for other symbols.
11735796c8dcSSimon Schubert      The caller is not constrained to care about the distinction.  */
11745796c8dcSSimon Schubert   {
11755796c8dcSSimon Schubert     char *tmp = copy_name (yylval.sval);
11765796c8dcSSimon Schubert     struct symbol *sym;
1177*ef5ccd6cSJohn Marino     struct field_of_this_result is_a_field_of_this;
11785796c8dcSSimon Schubert     int hextype;
11795796c8dcSSimon Schubert 
1180*ef5ccd6cSJohn Marino     /* Initialize this in case we *don't* use it in this call; that
1181*ef5ccd6cSJohn Marino        way we can refer to it unconditionally below.  */
1182*ef5ccd6cSJohn Marino     memset (&is_a_field_of_this, 0, sizeof (is_a_field_of_this));
1183*ef5ccd6cSJohn Marino 
11845796c8dcSSimon Schubert     sym = lookup_symbol (tmp, expression_context_block,
11855796c8dcSSimon Schubert 			 VAR_DOMAIN,
11865796c8dcSSimon Schubert 			 parse_language->la_language == language_cplus
11875796c8dcSSimon Schubert 			 ? &is_a_field_of_this : NULL);
11885796c8dcSSimon Schubert     if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
11895796c8dcSSimon Schubert       {
11905796c8dcSSimon Schubert 	yylval.tsym.type = SYMBOL_TYPE (sym);
11915796c8dcSSimon Schubert 	return TYPENAME;
11925796c8dcSSimon Schubert       }
11935796c8dcSSimon Schubert     yylval.tsym.type
11945796c8dcSSimon Schubert       = language_lookup_primitive_type_by_name (parse_language,
11955796c8dcSSimon Schubert 						parse_gdbarch, tmp);
11965796c8dcSSimon Schubert     if (yylval.tsym.type != NULL)
11975796c8dcSSimon Schubert       return TYPENAME;
11985796c8dcSSimon Schubert 
11995796c8dcSSimon Schubert     /* Input names that aren't symbols but ARE valid hex numbers,
12005796c8dcSSimon Schubert        when the input radix permits them, can be names or numbers
12015796c8dcSSimon Schubert        depending on the parse.  Note we support radixes > 16 here.  */
12025796c8dcSSimon Schubert     if (!sym
12035796c8dcSSimon Schubert 	&& ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10)
12045796c8dcSSimon Schubert 	    || (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
12055796c8dcSSimon Schubert       {
12065796c8dcSSimon Schubert  	YYSTYPE newlval;	/* Its value is ignored.  */
12075796c8dcSSimon Schubert 	hextype = parse_number (tokstart, namelen, 0, &newlval);
12085796c8dcSSimon Schubert 	if (hextype == INT)
12095796c8dcSSimon Schubert 	  {
12105796c8dcSSimon Schubert 	    yylval.ssym.sym = sym;
1211*ef5ccd6cSJohn Marino 	    yylval.ssym.is_a_field_of_this = is_a_field_of_this.type != NULL;
12125796c8dcSSimon Schubert 	    return NAME_OR_INT;
12135796c8dcSSimon Schubert 	  }
12145796c8dcSSimon Schubert       }
12155796c8dcSSimon Schubert 
12165796c8dcSSimon Schubert     /* Any other kind of symbol */
12175796c8dcSSimon Schubert     yylval.ssym.sym = sym;
1218*ef5ccd6cSJohn Marino     yylval.ssym.is_a_field_of_this = is_a_field_of_this.type != NULL;
12195796c8dcSSimon Schubert     return NAME;
12205796c8dcSSimon Schubert   }
12215796c8dcSSimon Schubert }
12225796c8dcSSimon Schubert 
12235796c8dcSSimon Schubert void
yyerror(char * msg)1224*ef5ccd6cSJohn Marino yyerror (char *msg)
12255796c8dcSSimon Schubert {
12265796c8dcSSimon Schubert   if (prev_lexptr)
12275796c8dcSSimon Schubert     lexptr = prev_lexptr;
12285796c8dcSSimon Schubert 
1229c50c785cSJohn Marino   error (_("A %s in expression, near `%s'."), (msg ? msg : "error"), lexptr);
12305796c8dcSSimon Schubert }
1231