119370Spst/* YACC parser for Fortran expressions, for GDB. 298944Sobrien Copyright 1986, 1989, 1990, 1991, 1993, 1994, 1995, 1996, 2000, 2001 398944Sobrien Free Software Foundation, Inc. 498944Sobrien 519370Spst Contributed by Motorola. Adapted from the C parser by Farooq Butt 619370Spst (fmbutt@engage.sps.mot.com). 719370Spst 819370SpstThis file is part of GDB. 919370Spst 1019370SpstThis program is free software; you can redistribute it and/or modify 1119370Spstit under the terms of the GNU General Public License as published by 1219370Spstthe Free Software Foundation; either version 2 of the License, or 1319370Spst(at your option) any later version. 1419370Spst 1519370SpstThis program is distributed in the hope that it will be useful, 1619370Spstbut WITHOUT ANY WARRANTY; without even the implied warranty of 1719370SpstMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1819370SpstGNU General Public License for more details. 1919370Spst 2019370SpstYou should have received a copy of the GNU General Public License 2119370Spstalong with this program; if not, write to the Free Software 2219370SpstFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 2319370Spst 2419370Spst/* This was blantantly ripped off the C expression parser, please 2519370Spst be aware of that as you look at its basic structure -FMB */ 2619370Spst 2719370Spst/* Parse a F77 expression from text in a string, 2819370Spst and return the result as a struct expression pointer. 2919370Spst That structure contains arithmetic operations in reverse polish, 3019370Spst with constants represented by operations that are followed by special data. 3119370Spst See expression.h for the details of the format. 3219370Spst What is important here is that it can be built up sequentially 3319370Spst during the process of parsing; the lower levels of the tree always 3419370Spst come first in the result. 3519370Spst 3619370Spst Note that malloc's and realloc's in this file are transformed to 3719370Spst xmalloc and xrealloc respectively by the same sed command in the 3819370Spst makefile that remaps any other malloc/realloc inserted by the parser 3919370Spst generator. Doing this with #defines and trying to control the interaction 4019370Spst with include files (<malloc.h> and <stdlib.h> for example) just became 4119370Spst too messy, particularly when such includes can be inserted at random 4219370Spst times by the parser generator. */ 4319370Spst 4419370Spst%{ 4519370Spst 4619370Spst#include "defs.h" 4719370Spst#include "gdb_string.h" 4819370Spst#include "expression.h" 4919370Spst#include "value.h" 5019370Spst#include "parser-defs.h" 5119370Spst#include "language.h" 5219370Spst#include "f-lang.h" 5319370Spst#include "bfd.h" /* Required by objfiles.h. */ 5419370Spst#include "symfile.h" /* Required by objfiles.h. */ 5519370Spst#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */ 56130803Smarcel#include "block.h" 5798944Sobrien#include <ctype.h> 5819370Spst 5919370Spst/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc), 6019370Spst as well as gratuitiously global symbol names, so we can have multiple 6119370Spst yacc generated parsers in gdb. Note that these are only the variables 6219370Spst produced by yacc. If other parser generators (bison, byacc, etc) produce 6319370Spst additional global names that conflict at link time, then those parser 6419370Spst generators need to be fixed instead of adding those names to this list. */ 6519370Spst 6619370Spst#define yymaxdepth f_maxdepth 6719370Spst#define yyparse f_parse 6819370Spst#define yylex f_lex 6919370Spst#define yyerror f_error 7019370Spst#define yylval f_lval 7119370Spst#define yychar f_char 7219370Spst#define yydebug f_debug 7319370Spst#define yypact f_pact 7419370Spst#define yyr1 f_r1 7519370Spst#define yyr2 f_r2 7619370Spst#define yydef f_def 7719370Spst#define yychk f_chk 7819370Spst#define yypgo f_pgo 7919370Spst#define yyact f_act 8019370Spst#define yyexca f_exca 8119370Spst#define yyerrflag f_errflag 8219370Spst#define yynerrs f_nerrs 8319370Spst#define yyps f_ps 8419370Spst#define yypv f_pv 8519370Spst#define yys f_s 8619370Spst#define yy_yys f_yys 8719370Spst#define yystate f_state 8819370Spst#define yytmp f_tmp 8919370Spst#define yyv f_v 9019370Spst#define yy_yyv f_yyv 9119370Spst#define yyval f_val 9219370Spst#define yylloc f_lloc 9319370Spst#define yyreds f_reds /* With YYDEBUG defined */ 9419370Spst#define yytoks f_toks /* With YYDEBUG defined */ 95130803Smarcel#define yyname f_name /* With YYDEBUG defined */ 96130803Smarcel#define yyrule f_rule /* With YYDEBUG defined */ 9719370Spst#define yylhs f_yylhs 9819370Spst#define yylen f_yylen 9919370Spst#define yydefred f_yydefred 10019370Spst#define yydgoto f_yydgoto 10119370Spst#define yysindex f_yysindex 10219370Spst#define yyrindex f_yyrindex 10319370Spst#define yygindex f_yygindex 10419370Spst#define yytable f_yytable 10519370Spst#define yycheck f_yycheck 10619370Spst 10719370Spst#ifndef YYDEBUG 108130803Smarcel#define YYDEBUG 1 /* Default to yydebug support */ 10919370Spst#endif 11019370Spst 111130803Smarcel#define YYFPRINTF parser_fprintf 112130803Smarcel 11398944Sobrienint yyparse (void); 11419370Spst 11598944Sobrienstatic int yylex (void); 11619370Spst 11798944Sobrienvoid yyerror (char *); 11819370Spst 11998944Sobrienstatic void growbuf_by_size (int); 12046283Sdfr 12198944Sobrienstatic int match_string_literal (void); 12246283Sdfr 12319370Spst%} 12419370Spst 12519370Spst/* Although the yacc "value" of an expression is not used, 12619370Spst since the result is stored in the structure being created, 12719370Spst other node types do have values. */ 12819370Spst 12919370Spst%union 13019370Spst { 13119370Spst LONGEST lval; 13219370Spst struct { 13319370Spst LONGEST val; 13419370Spst struct type *type; 13519370Spst } typed_val; 13619370Spst DOUBLEST dval; 13719370Spst struct symbol *sym; 13819370Spst struct type *tval; 13919370Spst struct stoken sval; 14019370Spst struct ttype tsym; 14119370Spst struct symtoken ssym; 14219370Spst int voidval; 14319370Spst struct block *bval; 14419370Spst enum exp_opcode opcode; 14519370Spst struct internalvar *ivar; 14619370Spst 14719370Spst struct type **tvec; 14819370Spst int *ivec; 14919370Spst } 15019370Spst 15119370Spst%{ 15219370Spst/* YYSTYPE gets defined by %union */ 15398944Sobrienstatic int parse_number (char *, int, int, YYSTYPE *); 15419370Spst%} 15519370Spst 15619370Spst%type <voidval> exp type_exp start variable 15719370Spst%type <tval> type typebase 15819370Spst%type <tvec> nonempty_typelist 15919370Spst/* %type <bval> block */ 16019370Spst 16119370Spst/* Fancy type parsing. */ 16219370Spst%type <voidval> func_mod direct_abs_decl abs_decl 16319370Spst%type <tval> ptype 16419370Spst 16519370Spst%token <typed_val> INT 16619370Spst%token <dval> FLOAT 16719370Spst 16819370Spst/* Both NAME and TYPENAME tokens represent symbols in the input, 16919370Spst and both convey their data as strings. 17019370Spst But a TYPENAME is a string that happens to be defined as a typedef 17119370Spst or builtin type name (such as int or char) 17219370Spst and a NAME is any other symbol. 17319370Spst Contexts where this distinction is not important can use the 17419370Spst nonterminal "name", which matches either NAME or TYPENAME. */ 17519370Spst 17619370Spst%token <sval> STRING_LITERAL 17719370Spst%token <lval> BOOLEAN_LITERAL 17819370Spst%token <ssym> NAME 17919370Spst%token <tsym> TYPENAME 18019370Spst%type <sval> name 18119370Spst%type <ssym> name_not_typename 18219370Spst%type <tsym> typename 18319370Spst 18419370Spst/* A NAME_OR_INT is a symbol which is not known in the symbol table, 18519370Spst but which would parse as a valid number in the current input radix. 18619370Spst E.g. "c" when input_radix==16. Depending on the parse, it will be 18719370Spst turned into a name or into a number. */ 18819370Spst 18919370Spst%token <ssym> NAME_OR_INT 19019370Spst 19119370Spst%token SIZEOF 19219370Spst%token ERROR 19319370Spst 19419370Spst/* Special type cases, put in to allow the parser to distinguish different 19519370Spst legal basetypes. */ 19619370Spst%token INT_KEYWORD INT_S2_KEYWORD LOGICAL_S1_KEYWORD LOGICAL_S2_KEYWORD 19719370Spst%token LOGICAL_KEYWORD REAL_KEYWORD REAL_S8_KEYWORD REAL_S16_KEYWORD 19819370Spst%token COMPLEX_S8_KEYWORD COMPLEX_S16_KEYWORD COMPLEX_S32_KEYWORD 19919370Spst%token BOOL_AND BOOL_OR BOOL_NOT 20019370Spst%token <lval> CHARACTER 20119370Spst 20219370Spst%token <voidval> VARIABLE 20319370Spst 20419370Spst%token <opcode> ASSIGN_MODIFY 20519370Spst 20619370Spst%left ',' 20719370Spst%left ABOVE_COMMA 20819370Spst%right '=' ASSIGN_MODIFY 20919370Spst%right '?' 21019370Spst%left BOOL_OR 21119370Spst%right BOOL_NOT 21219370Spst%left BOOL_AND 21319370Spst%left '|' 21419370Spst%left '^' 21519370Spst%left '&' 21619370Spst%left EQUAL NOTEQUAL 21719370Spst%left LESSTHAN GREATERTHAN LEQ GEQ 21819370Spst%left LSH RSH 21919370Spst%left '@' 22019370Spst%left '+' '-' 22119370Spst%left '*' '/' '%' 22219370Spst%right UNARY 22319370Spst%right '(' 22419370Spst 22519370Spst 22619370Spst%% 22719370Spst 22819370Spststart : exp 22919370Spst | type_exp 23019370Spst ; 23119370Spst 23219370Spsttype_exp: type 23319370Spst { write_exp_elt_opcode(OP_TYPE); 23419370Spst write_exp_elt_type($1); 23519370Spst write_exp_elt_opcode(OP_TYPE); } 23619370Spst ; 23719370Spst 23819370Spstexp : '(' exp ')' 23919370Spst { } 24019370Spst ; 24119370Spst 24219370Spst/* Expressions, not including the comma operator. */ 24319370Spstexp : '*' exp %prec UNARY 24419370Spst { write_exp_elt_opcode (UNOP_IND); } 245130803Smarcel ; 24619370Spst 24719370Spstexp : '&' exp %prec UNARY 24819370Spst { write_exp_elt_opcode (UNOP_ADDR); } 249130803Smarcel ; 25019370Spst 25119370Spstexp : '-' exp %prec UNARY 25219370Spst { write_exp_elt_opcode (UNOP_NEG); } 25319370Spst ; 25419370Spst 25519370Spstexp : BOOL_NOT exp %prec UNARY 25619370Spst { write_exp_elt_opcode (UNOP_LOGICAL_NOT); } 25719370Spst ; 25819370Spst 25919370Spstexp : '~' exp %prec UNARY 26019370Spst { write_exp_elt_opcode (UNOP_COMPLEMENT); } 26119370Spst ; 26219370Spst 26319370Spstexp : SIZEOF exp %prec UNARY 26419370Spst { write_exp_elt_opcode (UNOP_SIZEOF); } 26519370Spst ; 26619370Spst 26719370Spst/* No more explicit array operators, we treat everything in F77 as 26819370Spst a function call. The disambiguation as to whether we are 26919370Spst doing a subscript operation or a function call is done 27019370Spst later in eval.c. */ 27119370Spst 27219370Spstexp : exp '(' 27319370Spst { start_arglist (); } 27419370Spst arglist ')' 27519370Spst { write_exp_elt_opcode (OP_F77_UNDETERMINED_ARGLIST); 27619370Spst write_exp_elt_longcst ((LONGEST) end_arglist ()); 27719370Spst write_exp_elt_opcode (OP_F77_UNDETERMINED_ARGLIST); } 27819370Spst ; 27919370Spst 28019370Spstarglist : 28119370Spst ; 28219370Spst 28319370Spstarglist : exp 28419370Spst { arglist_len = 1; } 28519370Spst ; 28619370Spst 28719370Spstarglist : substring 28819370Spst { arglist_len = 2;} 289130803Smarcel ; 29019370Spst 29119370Spstarglist : arglist ',' exp %prec ABOVE_COMMA 29219370Spst { arglist_len++; } 29319370Spst ; 29419370Spst 29519370Spstsubstring: exp ':' exp %prec ABOVE_COMMA 29619370Spst { } 29719370Spst ; 29819370Spst 29919370Spst 30019370Spstcomplexnum: exp ',' exp 30119370Spst { } 30219370Spst ; 30319370Spst 30419370Spstexp : '(' complexnum ')' 30519370Spst { write_exp_elt_opcode(OP_COMPLEX); } 30619370Spst ; 30719370Spst 30819370Spstexp : '(' type ')' exp %prec UNARY 30919370Spst { write_exp_elt_opcode (UNOP_CAST); 31019370Spst write_exp_elt_type ($2); 31119370Spst write_exp_elt_opcode (UNOP_CAST); } 31219370Spst ; 31319370Spst 31419370Spst/* Binary operators in order of decreasing precedence. */ 31519370Spst 31619370Spstexp : exp '@' exp 31719370Spst { write_exp_elt_opcode (BINOP_REPEAT); } 31819370Spst ; 31919370Spst 32019370Spstexp : exp '*' exp 32119370Spst { write_exp_elt_opcode (BINOP_MUL); } 32219370Spst ; 32319370Spst 32419370Spstexp : exp '/' exp 32519370Spst { write_exp_elt_opcode (BINOP_DIV); } 32619370Spst ; 32719370Spst 32819370Spstexp : exp '%' exp 32919370Spst { write_exp_elt_opcode (BINOP_REM); } 33019370Spst ; 33119370Spst 33219370Spstexp : exp '+' exp 33319370Spst { write_exp_elt_opcode (BINOP_ADD); } 33419370Spst ; 33519370Spst 33619370Spstexp : exp '-' exp 33719370Spst { write_exp_elt_opcode (BINOP_SUB); } 33819370Spst ; 33919370Spst 34019370Spstexp : exp LSH exp 34119370Spst { write_exp_elt_opcode (BINOP_LSH); } 34219370Spst ; 34319370Spst 34419370Spstexp : exp RSH exp 34519370Spst { write_exp_elt_opcode (BINOP_RSH); } 34619370Spst ; 34719370Spst 34819370Spstexp : exp EQUAL exp 34919370Spst { write_exp_elt_opcode (BINOP_EQUAL); } 35019370Spst ; 35119370Spst 35219370Spstexp : exp NOTEQUAL exp 35319370Spst { write_exp_elt_opcode (BINOP_NOTEQUAL); } 35419370Spst ; 35519370Spst 35619370Spstexp : exp LEQ exp 35719370Spst { write_exp_elt_opcode (BINOP_LEQ); } 35819370Spst ; 35919370Spst 36019370Spstexp : exp GEQ exp 36119370Spst { write_exp_elt_opcode (BINOP_GEQ); } 36219370Spst ; 36319370Spst 36419370Spstexp : exp LESSTHAN exp 36519370Spst { write_exp_elt_opcode (BINOP_LESS); } 36619370Spst ; 36719370Spst 36819370Spstexp : exp GREATERTHAN exp 36919370Spst { write_exp_elt_opcode (BINOP_GTR); } 37019370Spst ; 37119370Spst 37219370Spstexp : exp '&' exp 37319370Spst { write_exp_elt_opcode (BINOP_BITWISE_AND); } 37419370Spst ; 37519370Spst 37619370Spstexp : exp '^' exp 37719370Spst { write_exp_elt_opcode (BINOP_BITWISE_XOR); } 37819370Spst ; 37919370Spst 38019370Spstexp : exp '|' exp 38119370Spst { write_exp_elt_opcode (BINOP_BITWISE_IOR); } 38219370Spst ; 38319370Spst 38419370Spstexp : exp BOOL_AND exp 38519370Spst { write_exp_elt_opcode (BINOP_LOGICAL_AND); } 38619370Spst ; 38719370Spst 38819370Spst 38919370Spstexp : exp BOOL_OR exp 39019370Spst { write_exp_elt_opcode (BINOP_LOGICAL_OR); } 39119370Spst ; 39219370Spst 39319370Spstexp : exp '=' exp 39419370Spst { write_exp_elt_opcode (BINOP_ASSIGN); } 39519370Spst ; 39619370Spst 39719370Spstexp : exp ASSIGN_MODIFY exp 39819370Spst { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); 39919370Spst write_exp_elt_opcode ($2); 40019370Spst write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); } 40119370Spst ; 40219370Spst 40319370Spstexp : INT 40419370Spst { write_exp_elt_opcode (OP_LONG); 40519370Spst write_exp_elt_type ($1.type); 40619370Spst write_exp_elt_longcst ((LONGEST)($1.val)); 40719370Spst write_exp_elt_opcode (OP_LONG); } 40819370Spst ; 40919370Spst 41019370Spstexp : NAME_OR_INT 41119370Spst { YYSTYPE val; 41219370Spst parse_number ($1.stoken.ptr, $1.stoken.length, 0, &val); 41319370Spst write_exp_elt_opcode (OP_LONG); 41419370Spst write_exp_elt_type (val.typed_val.type); 41519370Spst write_exp_elt_longcst ((LONGEST)val.typed_val.val); 41619370Spst write_exp_elt_opcode (OP_LONG); } 41719370Spst ; 41819370Spst 41919370Spstexp : FLOAT 42019370Spst { write_exp_elt_opcode (OP_DOUBLE); 42119370Spst write_exp_elt_type (builtin_type_f_real_s8); 42219370Spst write_exp_elt_dblcst ($1); 42319370Spst write_exp_elt_opcode (OP_DOUBLE); } 42419370Spst ; 42519370Spst 42619370Spstexp : variable 42719370Spst ; 42819370Spst 42919370Spstexp : VARIABLE 43019370Spst ; 43119370Spst 43219370Spstexp : SIZEOF '(' type ')' %prec UNARY 43319370Spst { write_exp_elt_opcode (OP_LONG); 43419370Spst write_exp_elt_type (builtin_type_f_integer); 43519370Spst CHECK_TYPEDEF ($3); 43619370Spst write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3)); 43719370Spst write_exp_elt_opcode (OP_LONG); } 43819370Spst ; 43919370Spst 44019370Spstexp : BOOLEAN_LITERAL 44119370Spst { write_exp_elt_opcode (OP_BOOL); 44219370Spst write_exp_elt_longcst ((LONGEST) $1); 44319370Spst write_exp_elt_opcode (OP_BOOL); 44419370Spst } 44519370Spst ; 44619370Spst 44719370Spstexp : STRING_LITERAL 44819370Spst { 44919370Spst write_exp_elt_opcode (OP_STRING); 45019370Spst write_exp_string ($1); 45119370Spst write_exp_elt_opcode (OP_STRING); 45219370Spst } 45319370Spst ; 45419370Spst 45519370Spstvariable: name_not_typename 45619370Spst { struct symbol *sym = $1.sym; 45719370Spst 45819370Spst if (sym) 45919370Spst { 46019370Spst if (symbol_read_needs_frame (sym)) 46119370Spst { 46219370Spst if (innermost_block == 0 || 46319370Spst contained_in (block_found, 46419370Spst innermost_block)) 46519370Spst innermost_block = block_found; 46619370Spst } 46719370Spst write_exp_elt_opcode (OP_VAR_VALUE); 46819370Spst /* We want to use the selected frame, not 46919370Spst another more inner frame which happens to 47019370Spst be in the same block. */ 47119370Spst write_exp_elt_block (NULL); 47219370Spst write_exp_elt_sym (sym); 47319370Spst write_exp_elt_opcode (OP_VAR_VALUE); 47419370Spst break; 47519370Spst } 47619370Spst else 47719370Spst { 47819370Spst struct minimal_symbol *msymbol; 479130803Smarcel char *arg = copy_name ($1.stoken); 48019370Spst 48119370Spst msymbol = 48219370Spst lookup_minimal_symbol (arg, NULL, NULL); 48319370Spst if (msymbol != NULL) 48419370Spst { 48519370Spst write_exp_msymbol (msymbol, 48619370Spst lookup_function_type (builtin_type_int), 48719370Spst builtin_type_int); 48819370Spst } 48919370Spst else if (!have_full_symbols () && !have_partial_symbols ()) 49019370Spst error ("No symbol table is loaded. Use the \"file\" command."); 49119370Spst else 49219370Spst error ("No symbol \"%s\" in current context.", 49319370Spst copy_name ($1.stoken)); 49419370Spst } 49519370Spst } 49619370Spst ; 49719370Spst 49819370Spst 49919370Spsttype : ptype 50019370Spst ; 50119370Spst 50219370Spstptype : typebase 50319370Spst | typebase abs_decl 50419370Spst { 50519370Spst /* This is where the interesting stuff happens. */ 50619370Spst int done = 0; 50719370Spst int array_size; 50819370Spst struct type *follow_type = $1; 50919370Spst struct type *range_type; 51019370Spst 51119370Spst while (!done) 51219370Spst switch (pop_type ()) 51319370Spst { 51419370Spst case tp_end: 51519370Spst done = 1; 51619370Spst break; 51719370Spst case tp_pointer: 51819370Spst follow_type = lookup_pointer_type (follow_type); 51919370Spst break; 52019370Spst case tp_reference: 52119370Spst follow_type = lookup_reference_type (follow_type); 52219370Spst break; 52319370Spst case tp_array: 52419370Spst array_size = pop_type_int (); 52519370Spst if (array_size != -1) 52619370Spst { 52719370Spst range_type = 52819370Spst create_range_type ((struct type *) NULL, 52919370Spst builtin_type_f_integer, 0, 53019370Spst array_size - 1); 53119370Spst follow_type = 53219370Spst create_array_type ((struct type *) NULL, 53319370Spst follow_type, range_type); 53419370Spst } 53519370Spst else 53619370Spst follow_type = lookup_pointer_type (follow_type); 53719370Spst break; 53819370Spst case tp_function: 53919370Spst follow_type = lookup_function_type (follow_type); 54019370Spst break; 54119370Spst } 54219370Spst $$ = follow_type; 54319370Spst } 54419370Spst ; 54519370Spst 54619370Spstabs_decl: '*' 54719370Spst { push_type (tp_pointer); $$ = 0; } 54819370Spst | '*' abs_decl 54919370Spst { push_type (tp_pointer); $$ = $2; } 55019370Spst | '&' 55119370Spst { push_type (tp_reference); $$ = 0; } 55219370Spst | '&' abs_decl 55319370Spst { push_type (tp_reference); $$ = $2; } 55419370Spst | direct_abs_decl 55519370Spst ; 55619370Spst 55719370Spstdirect_abs_decl: '(' abs_decl ')' 55819370Spst { $$ = $2; } 55919370Spst | direct_abs_decl func_mod 56019370Spst { push_type (tp_function); } 56119370Spst | func_mod 56219370Spst { push_type (tp_function); } 56319370Spst ; 56419370Spst 56519370Spstfunc_mod: '(' ')' 56619370Spst { $$ = 0; } 56719370Spst | '(' nonempty_typelist ')' 568130803Smarcel { free ($2); $$ = 0; } 56919370Spst ; 57019370Spst 57119370Spsttypebase /* Implements (approximately): (type-qualifier)* type-specifier */ 57219370Spst : TYPENAME 57319370Spst { $$ = $1.type; } 57419370Spst | INT_KEYWORD 57519370Spst { $$ = builtin_type_f_integer; } 57619370Spst | INT_S2_KEYWORD 57719370Spst { $$ = builtin_type_f_integer_s2; } 57819370Spst | CHARACTER 57919370Spst { $$ = builtin_type_f_character; } 58019370Spst | LOGICAL_KEYWORD 58119370Spst { $$ = builtin_type_f_logical;} 58219370Spst | LOGICAL_S2_KEYWORD 58319370Spst { $$ = builtin_type_f_logical_s2;} 58419370Spst | LOGICAL_S1_KEYWORD 58519370Spst { $$ = builtin_type_f_logical_s1;} 58619370Spst | REAL_KEYWORD 58719370Spst { $$ = builtin_type_f_real;} 58819370Spst | REAL_S8_KEYWORD 58919370Spst { $$ = builtin_type_f_real_s8;} 59019370Spst | REAL_S16_KEYWORD 59119370Spst { $$ = builtin_type_f_real_s16;} 59219370Spst | COMPLEX_S8_KEYWORD 59319370Spst { $$ = builtin_type_f_complex_s8;} 59419370Spst | COMPLEX_S16_KEYWORD 59519370Spst { $$ = builtin_type_f_complex_s16;} 59619370Spst | COMPLEX_S32_KEYWORD 59719370Spst { $$ = builtin_type_f_complex_s32;} 59819370Spst ; 59919370Spst 60019370Spsttypename: TYPENAME 60119370Spst ; 60219370Spst 60319370Spstnonempty_typelist 60419370Spst : type 60519370Spst { $$ = (struct type **) malloc (sizeof (struct type *) * 2); 60619370Spst $<ivec>$[0] = 1; /* Number of types in vector */ 60719370Spst $$[1] = $1; 60819370Spst } 60919370Spst | nonempty_typelist ',' type 61019370Spst { int len = sizeof (struct type *) * (++($<ivec>1[0]) + 1); 61119370Spst $$ = (struct type **) realloc ((char *) $1, len); 61219370Spst $$[$<ivec>$[0]] = $3; 61319370Spst } 61419370Spst ; 61519370Spst 61619370Spstname : NAME 61719370Spst { $$ = $1.stoken; } 61819370Spst | TYPENAME 61919370Spst { $$ = $1.stoken; } 62019370Spst | NAME_OR_INT 62119370Spst { $$ = $1.stoken; } 62219370Spst ; 62319370Spst 62419370Spstname_not_typename : NAME 62519370Spst/* These would be useful if name_not_typename was useful, but it is just 62619370Spst a fake for "variable", so these cause reduce/reduce conflicts because 62719370Spst the parser can't tell whether NAME_OR_INT is a name_not_typename (=variable, 62819370Spst =exp) or just an exp. If name_not_typename was ever used in an lvalue 62919370Spst context where only a name could occur, this might be useful. 63019370Spst | NAME_OR_INT 63119370Spst */ 63219370Spst ; 63319370Spst 63419370Spst%% 63519370Spst 63619370Spst/* Take care of parsing a number (anything that starts with a digit). 63719370Spst Set yylval and return the token type; update lexptr. 63819370Spst LEN is the number of characters in it. */ 63919370Spst 64019370Spst/*** Needs some error checking for the float case ***/ 64119370Spst 64219370Spststatic int 64319370Spstparse_number (p, len, parsed_float, putithere) 644130803Smarcel char *p; 645130803Smarcel int len; 64619370Spst int parsed_float; 64719370Spst YYSTYPE *putithere; 64819370Spst{ 649130803Smarcel LONGEST n = 0; 650130803Smarcel LONGEST prevn = 0; 651130803Smarcel int c; 652130803Smarcel int base = input_radix; 65319370Spst int unsigned_p = 0; 65419370Spst int long_p = 0; 65546283Sdfr ULONGEST high_bit; 65619370Spst struct type *signed_type; 65719370Spst struct type *unsigned_type; 65819370Spst 65919370Spst if (parsed_float) 66019370Spst { 66119370Spst /* It's a float since it contains a point or an exponent. */ 66219370Spst /* [dD] is not understood as an exponent by atof, change it to 'e'. */ 66319370Spst char *tmp, *tmp2; 66419370Spst 66598944Sobrien tmp = xstrdup (p); 66619370Spst for (tmp2 = tmp; *tmp2; ++tmp2) 66719370Spst if (*tmp2 == 'd' || *tmp2 == 'D') 66819370Spst *tmp2 = 'e'; 66919370Spst putithere->dval = atof (tmp); 67019370Spst free (tmp); 67119370Spst return FLOAT; 67219370Spst } 67319370Spst 67419370Spst /* Handle base-switching prefixes 0x, 0t, 0d, 0 */ 67519370Spst if (p[0] == '0') 67619370Spst switch (p[1]) 67719370Spst { 67819370Spst case 'x': 67919370Spst case 'X': 68019370Spst if (len >= 3) 68119370Spst { 68219370Spst p += 2; 68319370Spst base = 16; 68419370Spst len -= 2; 68519370Spst } 68619370Spst break; 68719370Spst 68819370Spst case 't': 68919370Spst case 'T': 69019370Spst case 'd': 69119370Spst case 'D': 69219370Spst if (len >= 3) 69319370Spst { 69419370Spst p += 2; 69519370Spst base = 10; 69619370Spst len -= 2; 69719370Spst } 69819370Spst break; 69919370Spst 70019370Spst default: 70119370Spst base = 8; 70219370Spst break; 70319370Spst } 70419370Spst 70519370Spst while (len-- > 0) 70619370Spst { 70719370Spst c = *p++; 70898944Sobrien if (isupper (c)) 70998944Sobrien c = tolower (c); 71098944Sobrien if (len == 0 && c == 'l') 71198944Sobrien long_p = 1; 71298944Sobrien else if (len == 0 && c == 'u') 71398944Sobrien unsigned_p = 1; 71419370Spst else 71519370Spst { 71698944Sobrien int i; 71798944Sobrien if (c >= '0' && c <= '9') 71898944Sobrien i = c - '0'; 71998944Sobrien else if (c >= 'a' && c <= 'f') 72098944Sobrien i = c - 'a' + 10; 72119370Spst else 72219370Spst return ERROR; /* Char not a digit */ 72398944Sobrien if (i >= base) 72498944Sobrien return ERROR; /* Invalid digit in this base */ 72598944Sobrien n *= base; 72698944Sobrien n += i; 72719370Spst } 72819370Spst /* Portably test for overflow (only works for nonzero values, so make 72919370Spst a second check for zero). */ 73019370Spst if ((prevn >= n) && n != 0) 73119370Spst unsigned_p=1; /* Try something unsigned */ 73219370Spst /* If range checking enabled, portably test for unsigned overflow. */ 73319370Spst if (RANGE_CHECK && n != 0) 73419370Spst { 73519370Spst if ((unsigned_p && (unsigned)prevn >= (unsigned)n)) 73619370Spst range_error("Overflow on numeric constant."); 73719370Spst } 73819370Spst prevn = n; 73919370Spst } 74019370Spst 74119370Spst /* If the number is too big to be an int, or it's got an l suffix 74219370Spst then it's a long. Work out if this has to be a long by 74319370Spst shifting right and and seeing if anything remains, and the 74419370Spst target int size is different to the target long size. 74519370Spst 74619370Spst In the expression below, we could have tested 74719370Spst (n >> TARGET_INT_BIT) 74819370Spst to see if it was zero, 74919370Spst but too many compilers warn about that, when ints and longs 75019370Spst are the same size. So we shift it twice, with fewer bits 75119370Spst each time, for the same result. */ 75219370Spst 75319370Spst if ((TARGET_INT_BIT != TARGET_LONG_BIT 75419370Spst && ((n >> 2) >> (TARGET_INT_BIT-2))) /* Avoid shift warning */ 75519370Spst || long_p) 75619370Spst { 75746283Sdfr high_bit = ((ULONGEST)1) << (TARGET_LONG_BIT-1); 75819370Spst unsigned_type = builtin_type_unsigned_long; 75919370Spst signed_type = builtin_type_long; 76019370Spst } 76119370Spst else 76219370Spst { 76346283Sdfr high_bit = ((ULONGEST)1) << (TARGET_INT_BIT-1); 76419370Spst unsigned_type = builtin_type_unsigned_int; 76519370Spst signed_type = builtin_type_int; 76619370Spst } 76719370Spst 76819370Spst putithere->typed_val.val = n; 76919370Spst 77019370Spst /* If the high bit of the worked out type is set then this number 77119370Spst has to be unsigned. */ 77219370Spst 77319370Spst if (unsigned_p || (n & high_bit)) 77419370Spst putithere->typed_val.type = unsigned_type; 77519370Spst else 77619370Spst putithere->typed_val.type = signed_type; 77719370Spst 77819370Spst return INT; 77919370Spst} 78019370Spst 78119370Spststruct token 78219370Spst{ 78319370Spst char *operator; 78419370Spst int token; 78519370Spst enum exp_opcode opcode; 78619370Spst}; 78719370Spst 78819370Spststatic const struct token dot_ops[] = 78919370Spst{ 79019370Spst { ".and.", BOOL_AND, BINOP_END }, 79119370Spst { ".AND.", BOOL_AND, BINOP_END }, 79219370Spst { ".or.", BOOL_OR, BINOP_END }, 79319370Spst { ".OR.", BOOL_OR, BINOP_END }, 79419370Spst { ".not.", BOOL_NOT, BINOP_END }, 79519370Spst { ".NOT.", BOOL_NOT, BINOP_END }, 79619370Spst { ".eq.", EQUAL, BINOP_END }, 79719370Spst { ".EQ.", EQUAL, BINOP_END }, 79819370Spst { ".eqv.", EQUAL, BINOP_END }, 79919370Spst { ".NEQV.", NOTEQUAL, BINOP_END }, 80019370Spst { ".neqv.", NOTEQUAL, BINOP_END }, 80119370Spst { ".EQV.", EQUAL, BINOP_END }, 80219370Spst { ".ne.", NOTEQUAL, BINOP_END }, 80319370Spst { ".NE.", NOTEQUAL, BINOP_END }, 80419370Spst { ".le.", LEQ, BINOP_END }, 80519370Spst { ".LE.", LEQ, BINOP_END }, 80619370Spst { ".ge.", GEQ, BINOP_END }, 80719370Spst { ".GE.", GEQ, BINOP_END }, 80819370Spst { ".gt.", GREATERTHAN, BINOP_END }, 80919370Spst { ".GT.", GREATERTHAN, BINOP_END }, 81019370Spst { ".lt.", LESSTHAN, BINOP_END }, 81119370Spst { ".LT.", LESSTHAN, BINOP_END }, 81219370Spst { NULL, 0, 0 } 81319370Spst}; 81419370Spst 81519370Spststruct f77_boolean_val 81619370Spst{ 81719370Spst char *name; 81819370Spst int value; 81919370Spst}; 82019370Spst 82119370Spststatic const struct f77_boolean_val boolean_values[] = 82219370Spst{ 82319370Spst { ".true.", 1 }, 82419370Spst { ".TRUE.", 1 }, 82519370Spst { ".false.", 0 }, 82619370Spst { ".FALSE.", 0 }, 82719370Spst { NULL, 0 } 82819370Spst}; 82919370Spst 83019370Spststatic const struct token f77_keywords[] = 83119370Spst{ 83219370Spst { "complex_16", COMPLEX_S16_KEYWORD, BINOP_END }, 83319370Spst { "complex_32", COMPLEX_S32_KEYWORD, BINOP_END }, 83419370Spst { "character", CHARACTER, BINOP_END }, 83519370Spst { "integer_2", INT_S2_KEYWORD, BINOP_END }, 83619370Spst { "logical_1", LOGICAL_S1_KEYWORD, BINOP_END }, 83719370Spst { "logical_2", LOGICAL_S2_KEYWORD, BINOP_END }, 83819370Spst { "complex_8", COMPLEX_S8_KEYWORD, BINOP_END }, 83919370Spst { "integer", INT_KEYWORD, BINOP_END }, 84019370Spst { "logical", LOGICAL_KEYWORD, BINOP_END }, 84119370Spst { "real_16", REAL_S16_KEYWORD, BINOP_END }, 84219370Spst { "complex", COMPLEX_S8_KEYWORD, BINOP_END }, 84319370Spst { "sizeof", SIZEOF, BINOP_END }, 84419370Spst { "real_8", REAL_S8_KEYWORD, BINOP_END }, 84519370Spst { "real", REAL_KEYWORD, BINOP_END }, 84619370Spst { NULL, 0, 0 } 84719370Spst}; 84819370Spst 84919370Spst/* Implementation of a dynamically expandable buffer for processing input 85019370Spst characters acquired through lexptr and building a value to return in 85119370Spst yylval. Ripped off from ch-exp.y */ 85219370Spst 85319370Spststatic char *tempbuf; /* Current buffer contents */ 85419370Spststatic int tempbufsize; /* Size of allocated buffer */ 85519370Spststatic int tempbufindex; /* Current index into buffer */ 85619370Spst 85719370Spst#define GROWBY_MIN_SIZE 64 /* Minimum amount to grow buffer by */ 85819370Spst 85919370Spst#define CHECKBUF(size) \ 86019370Spst do { \ 86119370Spst if (tempbufindex + (size) >= tempbufsize) \ 86219370Spst { \ 86319370Spst growbuf_by_size (size); \ 86419370Spst } \ 86519370Spst } while (0); 86619370Spst 86719370Spst 86819370Spst/* Grow the static temp buffer if necessary, including allocating the first one 86919370Spst on demand. */ 87019370Spst 87119370Spststatic void 87219370Spstgrowbuf_by_size (count) 87319370Spst int count; 87419370Spst{ 87519370Spst int growby; 87619370Spst 87719370Spst growby = max (count, GROWBY_MIN_SIZE); 87819370Spst tempbufsize += growby; 87919370Spst if (tempbuf == NULL) 88019370Spst tempbuf = (char *) malloc (tempbufsize); 88119370Spst else 88219370Spst tempbuf = (char *) realloc (tempbuf, tempbufsize); 88319370Spst} 88419370Spst 88519370Spst/* Blatantly ripped off from ch-exp.y. This routine recognizes F77 88619370Spst string-literals. 88719370Spst 88819370Spst Recognize a string literal. A string literal is a nonzero sequence 88919370Spst of characters enclosed in matching single quotes, except that 89019370Spst a single character inside single quotes is a character literal, which 89119370Spst we reject as a string literal. To embed the terminator character inside 89219370Spst a string, it is simply doubled (I.E. 'this''is''one''string') */ 89319370Spst 89419370Spststatic int 89519370Spstmatch_string_literal () 89619370Spst{ 89719370Spst char *tokptr = lexptr; 89819370Spst 89919370Spst for (tempbufindex = 0, tokptr++; *tokptr != '\0'; tokptr++) 90019370Spst { 90119370Spst CHECKBUF (1); 90219370Spst if (*tokptr == *lexptr) 90319370Spst { 90419370Spst if (*(tokptr + 1) == *lexptr) 90519370Spst tokptr++; 90619370Spst else 90719370Spst break; 90819370Spst } 90919370Spst tempbuf[tempbufindex++] = *tokptr; 91019370Spst } 91119370Spst if (*tokptr == '\0' /* no terminator */ 91219370Spst || tempbufindex == 0) /* no string */ 91319370Spst return 0; 91419370Spst else 91519370Spst { 91619370Spst tempbuf[tempbufindex] = '\0'; 91719370Spst yylval.sval.ptr = tempbuf; 91819370Spst yylval.sval.length = tempbufindex; 91919370Spst lexptr = ++tokptr; 92019370Spst return STRING_LITERAL; 92119370Spst } 92219370Spst} 92319370Spst 92419370Spst/* Read one token, getting characters through lexptr. */ 92519370Spst 92619370Spststatic int 92719370Spstyylex () 92819370Spst{ 92919370Spst int c; 93019370Spst int namelen; 93119370Spst unsigned int i,token; 93219370Spst char *tokstart; 93319370Spst 93419370Spst retry: 935130803Smarcel 936130803Smarcel prev_lexptr = lexptr; 937130803Smarcel 93819370Spst tokstart = lexptr; 93919370Spst 94019370Spst /* First of all, let us make sure we are not dealing with the 94119370Spst special tokens .true. and .false. which evaluate to 1 and 0. */ 94219370Spst 94319370Spst if (*lexptr == '.') 94419370Spst { 94519370Spst for (i = 0; boolean_values[i].name != NULL; i++) 94619370Spst { 947130803Smarcel if (strncmp (tokstart, boolean_values[i].name, 948130803Smarcel strlen (boolean_values[i].name)) == 0) 94919370Spst { 95019370Spst lexptr += strlen (boolean_values[i].name); 95119370Spst yylval.lval = boolean_values[i].value; 95219370Spst return BOOLEAN_LITERAL; 95319370Spst } 95419370Spst } 95519370Spst } 95619370Spst 95719370Spst /* See if it is a special .foo. operator */ 95819370Spst 95919370Spst for (i = 0; dot_ops[i].operator != NULL; i++) 960130803Smarcel if (strncmp (tokstart, dot_ops[i].operator, strlen (dot_ops[i].operator)) == 0) 96119370Spst { 96219370Spst lexptr += strlen (dot_ops[i].operator); 96319370Spst yylval.opcode = dot_ops[i].opcode; 96419370Spst return dot_ops[i].token; 96519370Spst } 96619370Spst 96719370Spst switch (c = *tokstart) 96819370Spst { 96919370Spst case 0: 97019370Spst return 0; 97119370Spst 97219370Spst case ' ': 97319370Spst case '\t': 97419370Spst case '\n': 97519370Spst lexptr++; 97619370Spst goto retry; 97719370Spst 97819370Spst case '\'': 97919370Spst token = match_string_literal (); 98019370Spst if (token != 0) 98119370Spst return (token); 98219370Spst break; 98319370Spst 98419370Spst case '(': 98519370Spst paren_depth++; 98619370Spst lexptr++; 98719370Spst return c; 98819370Spst 98919370Spst case ')': 99019370Spst if (paren_depth == 0) 99119370Spst return 0; 99219370Spst paren_depth--; 99319370Spst lexptr++; 99419370Spst return c; 99519370Spst 99619370Spst case ',': 99719370Spst if (comma_terminates && paren_depth == 0) 99819370Spst return 0; 99919370Spst lexptr++; 100019370Spst return c; 100119370Spst 100219370Spst case '.': 100319370Spst /* Might be a floating point number. */ 100419370Spst if (lexptr[1] < '0' || lexptr[1] > '9') 100519370Spst goto symbol; /* Nope, must be a symbol. */ 100619370Spst /* FALL THRU into number case. */ 100719370Spst 100819370Spst case '0': 100919370Spst case '1': 101019370Spst case '2': 101119370Spst case '3': 101219370Spst case '4': 101319370Spst case '5': 101419370Spst case '6': 101519370Spst case '7': 101619370Spst case '8': 101719370Spst case '9': 101819370Spst { 101919370Spst /* It's a number. */ 102019370Spst int got_dot = 0, got_e = 0, got_d = 0, toktype; 1021130803Smarcel char *p = tokstart; 102219370Spst int hex = input_radix > 10; 102319370Spst 102419370Spst if (c == '0' && (p[1] == 'x' || p[1] == 'X')) 102519370Spst { 102619370Spst p += 2; 102719370Spst hex = 1; 102819370Spst } 102919370Spst else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D')) 103019370Spst { 103119370Spst p += 2; 103219370Spst hex = 0; 103319370Spst } 103419370Spst 103519370Spst for (;; ++p) 103619370Spst { 103719370Spst if (!hex && !got_e && (*p == 'e' || *p == 'E')) 103819370Spst got_dot = got_e = 1; 103919370Spst else if (!hex && !got_d && (*p == 'd' || *p == 'D')) 104019370Spst got_dot = got_d = 1; 104119370Spst else if (!hex && !got_dot && *p == '.') 104219370Spst got_dot = 1; 104319370Spst else if (((got_e && (p[-1] == 'e' || p[-1] == 'E')) 104419370Spst || (got_d && (p[-1] == 'd' || p[-1] == 'D'))) 104519370Spst && (*p == '-' || *p == '+')) 104619370Spst /* This is the sign of the exponent, not the end of the 104719370Spst number. */ 104819370Spst continue; 104919370Spst /* We will take any letters or digits. parse_number will 105019370Spst complain if past the radix, or if L or U are not final. */ 105119370Spst else if ((*p < '0' || *p > '9') 105219370Spst && ((*p < 'a' || *p > 'z') 105319370Spst && (*p < 'A' || *p > 'Z'))) 105419370Spst break; 105519370Spst } 105619370Spst toktype = parse_number (tokstart, p - tokstart, got_dot|got_e|got_d, 105719370Spst &yylval); 105819370Spst if (toktype == ERROR) 105919370Spst { 106019370Spst char *err_copy = (char *) alloca (p - tokstart + 1); 106119370Spst 106219370Spst memcpy (err_copy, tokstart, p - tokstart); 106319370Spst err_copy[p - tokstart] = 0; 106419370Spst error ("Invalid number \"%s\".", err_copy); 106519370Spst } 106619370Spst lexptr = p; 106719370Spst return toktype; 106819370Spst } 106919370Spst 107019370Spst case '+': 107119370Spst case '-': 107219370Spst case '*': 107319370Spst case '/': 107419370Spst case '%': 107519370Spst case '|': 107619370Spst case '&': 107719370Spst case '^': 107819370Spst case '~': 107919370Spst case '!': 108019370Spst case '@': 108119370Spst case '<': 108219370Spst case '>': 108319370Spst case '[': 108419370Spst case ']': 108519370Spst case '?': 108619370Spst case ':': 108719370Spst case '=': 108819370Spst case '{': 108919370Spst case '}': 109019370Spst symbol: 109119370Spst lexptr++; 109219370Spst return c; 109319370Spst } 109419370Spst 109519370Spst if (!(c == '_' || c == '$' 109619370Spst || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) 109719370Spst /* We must have come across a bad character (e.g. ';'). */ 109819370Spst error ("Invalid character '%c' in expression.", c); 109919370Spst 110019370Spst namelen = 0; 110119370Spst for (c = tokstart[namelen]; 110219370Spst (c == '_' || c == '$' || (c >= '0' && c <= '9') 110319370Spst || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); 110419370Spst c = tokstart[++namelen]); 110519370Spst 110619370Spst /* The token "if" terminates the expression and is NOT 110719370Spst removed from the input stream. */ 110819370Spst 110919370Spst if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f') 111019370Spst return 0; 111119370Spst 111219370Spst lexptr += namelen; 111319370Spst 111419370Spst /* Catch specific keywords. */ 111519370Spst 111619370Spst for (i = 0; f77_keywords[i].operator != NULL; i++) 1117130803Smarcel if (strncmp (tokstart, f77_keywords[i].operator, 1118130803Smarcel strlen(f77_keywords[i].operator)) == 0) 111919370Spst { 112019370Spst /* lexptr += strlen(f77_keywords[i].operator); */ 112119370Spst yylval.opcode = f77_keywords[i].opcode; 112219370Spst return f77_keywords[i].token; 112319370Spst } 112419370Spst 112519370Spst yylval.sval.ptr = tokstart; 112619370Spst yylval.sval.length = namelen; 112719370Spst 112819370Spst if (*tokstart == '$') 112919370Spst { 113019370Spst write_dollar_variable (yylval.sval); 113119370Spst return VARIABLE; 113219370Spst } 113319370Spst 113419370Spst /* Use token-type TYPENAME for symbols that happen to be defined 113519370Spst currently as names of types; NAME for other symbols. 113619370Spst The caller is not constrained to care about the distinction. */ 113719370Spst { 113819370Spst char *tmp = copy_name (yylval.sval); 113919370Spst struct symbol *sym; 114019370Spst int is_a_field_of_this = 0; 114119370Spst int hextype; 114219370Spst 114319370Spst sym = lookup_symbol (tmp, expression_context_block, 1144130803Smarcel VAR_DOMAIN, 114519370Spst current_language->la_language == language_cplus 114619370Spst ? &is_a_field_of_this : NULL, 114719370Spst NULL); 114819370Spst if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF) 114919370Spst { 115019370Spst yylval.tsym.type = SYMBOL_TYPE (sym); 115119370Spst return TYPENAME; 115219370Spst } 115319370Spst if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0) 115419370Spst return TYPENAME; 115519370Spst 115619370Spst /* Input names that aren't symbols but ARE valid hex numbers, 115719370Spst when the input radix permits them, can be names or numbers 115819370Spst depending on the parse. Note we support radixes > 16 here. */ 115919370Spst if (!sym 116019370Spst && ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) 116119370Spst || (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10))) 116219370Spst { 116319370Spst YYSTYPE newlval; /* Its value is ignored. */ 116419370Spst hextype = parse_number (tokstart, namelen, 0, &newlval); 116519370Spst if (hextype == INT) 116619370Spst { 116719370Spst yylval.ssym.sym = sym; 116819370Spst yylval.ssym.is_a_field_of_this = is_a_field_of_this; 116919370Spst return NAME_OR_INT; 117019370Spst } 117119370Spst } 117219370Spst 117319370Spst /* Any other kind of symbol */ 117419370Spst yylval.ssym.sym = sym; 117519370Spst yylval.ssym.is_a_field_of_this = is_a_field_of_this; 117619370Spst return NAME; 117719370Spst } 117819370Spst} 117919370Spst 118019370Spstvoid 118119370Spstyyerror (msg) 118219370Spst char *msg; 118319370Spst{ 1184130803Smarcel if (prev_lexptr) 1185130803Smarcel lexptr = prev_lexptr; 1186130803Smarcel 118719370Spst error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr); 118819370Spst} 1189