/* YACC grammar for Chill expressions, for GDB.
- Copyright 1992, 1993 Free Software Foundation, Inc.
+ Copyright 1992, 1993, 1994 Free Software Foundation, Inc.
This file is part of GDB.
%{
#include "defs.h"
+#include <string.h>
#include <ctype.h>
#include "expression.h"
#include "language.h"
#include "value.h"
#include "parser-defs.h"
#include "ch-lang.h"
+#include "bfd.h" /* Required by objfiles.h. */
+#include "symfile.h" /* Required by objfiles.h. */
+#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
as well as gratuitiously global symbol names, so we can have multiple
%token <ivar> GDB_VARIABLE /* Convenience variable */
%token <voidval> GDB_ASSIGNMENT /* Assign value to somewhere */
-%type <voidval> location
%type <voidval> access_name
%type <voidval> primitive_value
-%type <voidval> location_contents
%type <voidval> value_name
%type <voidval> literal
%type <voidval> tuple
%type <voidval> value_string_element
%type <voidval> value_string_slice
-%type <voidval> value_array_element
%type <voidval> value_array_slice
-%type <voidval> value_structure_field
%type <voidval> expression_conversion
%type <voidval> value_procedure_call
%type <voidval> value_built_in_routine_call
%type <voidval> left_element
%type <voidval> right_element
%type <voidval> slice_size
-%type <voidval> array_primitive_value
%type <voidval> expression_list
%type <voidval> lower_element
%type <voidval> upper_element
%type <voidval> first_element
-%type <voidval> mode_argument
+%type <tval> mode_argument
%type <voidval> upper_lower_argument
%type <voidval> length_argument
%type <voidval> array_mode_name
}
;
-/* Z.200, 4.2.1 */
-
-location : access_name
- | primitive_value POINTER
- {
- write_exp_elt_opcode (UNOP_IND);
- }
- ;
-
/* Z.200, 4.2.2 */
access_name : LOCATION_NAME
/* Z.200, 5.2.1 */
-primitive_value : location_contents
+primitive_value :
+ access_name
+ | primitive_value '('
+ /* This is to save the value of arglist_len
+ being accumulated for each dimension. */
+ { start_arglist (); }
+ expression_list ')'
{
- $$ = 0; /* FIXME */
+ write_exp_elt_opcode (MULTI_SUBSCRIPT);
+ write_exp_elt_longcst ((LONGEST) end_arglist ());
+ write_exp_elt_opcode (MULTI_SUBSCRIPT);
+ }
+ | primitive_value FIELD_NAME
+ { write_exp_elt_opcode (STRUCTOP_STRUCT);
+ write_exp_string ($2);
+ write_exp_elt_opcode (STRUCTOP_STRUCT);
+ }
+ | primitive_value POINTER
+ {
+ write_exp_elt_opcode (UNOP_IND);
}
| value_name
{
{
$$ = 0; /* FIXME */
}
- | value_array_element
- {
- $$ = 0; /* FIXME */
- }
| value_array_slice
{
$$ = 0; /* FIXME */
}
- | value_structure_field
- {
- $$ = 0; /* FIXME */
- }
| expression_conversion
{
$$ = 0; /* FIXME */
}
;
-/* Z.200, 5.2.2 */
-
-location_contents: location
- {
- $$ = 0; /* FIXME */
- }
- ;
-
/* Z.200, 5.2.3 */
value_name : synonym_name
}
;
-/* Z.200, 5.2.8 */
-
-value_array_element: array_primitive_value '('
- /* This is to save the value of arglist_len
- being accumulated for each dimension. */
- { start_arglist (); }
- expression_list ')'
- {
- write_exp_elt_opcode (MULTI_SUBSCRIPT);
- write_exp_elt_longcst ((LONGEST) end_arglist ());
- write_exp_elt_opcode (MULTI_SUBSCRIPT);
- }
- ;
-
/* Z.200, 5.2.9 */
-value_array_slice: array_primitive_value '(' lower_element ':' upper_element ')'
+value_array_slice: primitive_value '(' lower_element ':' upper_element ')'
{
$$ = 0; /* FIXME */
}
- | array_primitive_value '(' first_element UP slice_size ')'
+ | primitive_value '(' first_element UP slice_size ')'
{
$$ = 0; /* FIXME */
}
;
-/* Z.200, 5.2.10 */
-
-value_structure_field: primitive_value FIELD_NAME
- { write_exp_elt_opcode (STRUCTOP_STRUCT);
- write_exp_string ($2);
- write_exp_elt_opcode (STRUCTOP_STRUCT);
- }
- ;
-
/* Z.200, 5.2.11 */
expression_conversion: mode_name parenthesised_expression
}
| operand_2 IN operand_3
{
- $$ = 0; /* FIXME */
+ write_exp_elt_opcode (BINOP_IN);
}
;
/* Z.200, 5.3.9 */
-operand_6 : POINTER location
+operand_6 : POINTER primitive_value
{
write_exp_elt_opcode (UNOP_ADDR);
}
/* Z.200, 6.2 */
single_assignment_action :
- location GDB_ASSIGNMENT value
+ primitive_value GDB_ASSIGNMENT value
{
write_exp_elt_opcode (BINOP_ASSIGN);
}
{
$$ = 0; /* FIXME */
}
- | SIZE '(' location ')'
- {
- $$ = 0; /* FIXME */
- }
+ | SIZE '(' expression ')'
+ { write_exp_elt_opcode (UNOP_SIZEOF); }
| SIZE '(' mode_argument ')'
- {
- $$ = 0; /* FIXME */
- }
+ { write_exp_elt_opcode (OP_LONG);
+ write_exp_elt_type (builtin_type_int);
+ write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3));
+ write_exp_elt_opcode (OP_LONG); }
| UPPER '(' upper_lower_argument ')'
{
$$ = 0; /* FIXME */
mode_argument : mode_name
{
- $$ = 0; /* FIXME */
+ $$ = $1.type;
}
| array_mode_name '(' expression ')'
{
}
;
-/* Z.200, 12.4.3 */
-
-array_primitive_value : primitive_value
- {
- $$ = 0;
- }
- ;
-
-
/* Things which still need productions... */
array_mode_name : FIXME_08 { $$ = 0; }
{
char *tokptr = lexptr;
- if (isalpha (*tokptr))
+ if (isalpha (*tokptr) || *tokptr == '_')
{
char *result;
do {
yylval.sval.length = tokptr - lexptr;
lexptr = tokptr;
result = copy_name (yylval.sval);
- for (tokptr = result; *tokptr; tokptr++)
- if (isupper (*tokptr))
- *tokptr = tolower(*tokptr);
return result;
}
return (NULL);
while (*tokptr != '\0')
{
- temp = tolower (*tokptr);
+ temp = *tokptr;
+ if (isupper (temp))
+ temp = tolower (temp);
tokptr++;
switch (temp)
{
char *tokptr = lexptr;
char *buf;
char *copy;
- char ch;
double dval;
extern double strtod ();
return (0);
}
-/* Recognize a string literal. A string literal is a nonzero sequence
+/* Recognize a string literal. A string literal is a sequence
of characters enclosed in matching single or double quotes, except that
a single character inside single quotes is a character literal, which
we reject as a string literal. To embed the terminator character inside
tempbuf[tempbufindex++] = *tokptr;
}
if (*tokptr == '\0' /* no terminator */
- || tempbufindex == 0 /* no string */
|| (tempbufindex == 1 && *tokptr == '\'')) /* char literal */
{
return (0);
char *tokptr = lexptr;
int ival = 0;
- if ((tolower (*tokptr) == 'c') && (*(tokptr + 1) == '\''))
+ if ((*tokptr == 'c' || *tokptr == 'C') && (*(tokptr + 1) == '\''))
{
/* We have a GNU chill extension form, so skip the leading "C'",
decode the hex value, and then ensure that we have a trailing
while (*tokptr != '\0' && *tokptr != '\'')
{
- digit = tolower (*tokptr);
+ digit = *tokptr;
+ if (isupper (digit))
+ digit = tolower (digit);
tokptr++;
switch (digit)
{
&& !isalnum (tokptr[namelength]))
{
yylval.lval = regno;
- lexptr += namelength + 1;
+ lexptr += namelength;
return (GDB_REGNAME);
}
}
{
unsigned int i;
int token;
- char *simplename;
+ char *inputname;
struct symbol *sym;
/* Skip over any leading whitespace. */
{
case '\'':
case '\"':
- /* First try to match a string literal, which is any nonzero
+ /* First try to match a string literal, which is any
sequence of characters enclosed in matching single or double
quotes, except that a single character inside single quotes
is a character literal, so we have to catch that case also. */
the token from lexptr, so we can't back out if we later find that
we can't classify what sort of name it is. */
- simplename = match_simple_name_string ();
+ inputname = match_simple_name_string ();
- if (simplename != NULL)
+ if (inputname != NULL)
{
+ char *simplename = (char*) alloca (strlen (inputname));
+
+ char *dptr = simplename, *sptr = inputname;
+ for (; *sptr; sptr++)
+ *dptr++ = isupper (*sptr) ? tolower(*sptr) : *sptr;
+
/* See if it is a reserved identifier. */
for (i = 0; i < sizeof (idtokentab) / sizeof (idtokentab[0]); i++)
{
return (BOOLEAN_LITERAL);
}
- sym = lookup_symbol (simplename, expression_context_block,
+ sym = lookup_symbol (inputname, expression_context_block,
VAR_NAMESPACE, (int *) NULL,
(struct symtab **) NULL);
+ if (sym == NULL && strcmp (inputname, simplename) != 0)
+ {
+ sym = lookup_symbol (simplename, expression_context_block,
+ VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **) NULL);
+ }
if (sym != NULL)
{
yylval.ssym.stoken.ptr = NULL;
case LOC_ARG:
case LOC_REF_ARG:
case LOC_REGPARM:
+ case LOC_REGPARM_ADDR:
case LOC_LOCAL:
case LOC_LOCAL_ARG:
case LOC_BASEREG:
case LOC_UNDEF:
case LOC_CONST_BYTES:
case LOC_OPTIMIZED_OUT:
- error ("Symbol \"%s\" names no location.", simplename);
+ error ("Symbol \"%s\" names no location.", inputname);
break;
}
}
}
else
{
- error ("No symbol \"%s\" in current context.", simplename);
+ error ("No symbol \"%s\" in current context.", inputname);
}
}
case '.': /* Not float for example. */
lexptr++;
while (isspace (*lexptr)) lexptr++;
- simplename = match_simple_name_string ();
- if (!simplename)
+ inputname = match_simple_name_string ();
+ if (!inputname)
return '.';
return FIELD_NAME;
}
void
yyerror (msg)
- char *msg; /* unused */
+ char *msg;
{
- printf ("Parsing: %s\n", lexptr);
- if (yychar < 256)
- {
- error ("Invalid syntax in expression near character '%c'.", yychar);
- }
- else
- {
- error ("Invalid syntax in expression");
- }
+ error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
}