/* YACC grammar for Chill expressions, for GDB.
- Copyright (C) 1992 Free Software Foundation, Inc.
+ Copyright 1992, 1993 Free Software Foundation, Inc.
This file is part of GDB.
#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
#define yypgo chill_pgo
#define yyact chill_act
#define yyexca chill_exca
-#define yyerrflag chill_errflag
-#define yynerrs chill_nerrs
+#define yyerrflag chill_errflag
+#define yynerrs chill_nerrs
#define yyps chill_ps
#define yypv chill_pv
#define yys chill_s
#define yy_yyv chill_yyv
#define yyval chill_val
#define yylloc chill_lloc
-#define yyreds chill_reds /* With YYDEBUG defined */
-#define yytoks chill_toks /* With YYDEBUG defined */
+#define yyreds chill_reds /* With YYDEBUG defined */
+#define yytoks chill_toks /* With YYDEBUG defined */
#ifndef YYDEBUG
#define YYDEBUG 0 /* Default to no yydebug support */
%token <voidval> FIXME_20
%token <voidval> FIXME_21
%token <voidval> FIXME_22
-%token <voidval> FIXME_23
%token <voidval> FIXME_24
%token <voidval> FIXME_25
%token <voidval> FIXME_26
%token <voidval> EMPTINESS_LITERAL
%token <sval> CHARACTER_STRING_LITERAL
%token <sval> BIT_STRING_LITERAL
+%token <tsym> TYPENAME
+%token <sval> FIELD_NAME
%token <voidval> '.'
%token <voidval> ';'
%token <voidval> SUCC
%token <voidval> ABS
%token <voidval> CARD
-%token <voidval> MAX
-%token <voidval> MIN
+%token <voidval> MAX_TOKEN
+%token <voidval> MIN_TOKEN
%token <voidval> SIZE
%token <voidval> UPPER
%token <voidval> LOWER
%type <voidval> lower_element
%type <voidval> upper_element
%type <voidval> first_element
-%type <voidval> structure_primitive_value
-%type <voidval> field_name
%type <voidval> mode_argument
%type <voidval> upper_lower_argument
%type <voidval> length_argument
-%type <voidval> mode_name
%type <voidval> array_mode_name
%type <voidval> string_mode_name
%type <voidval> variant_structure_mode_name
%type <voidval> subexpression
%type <voidval> case_label_specification
%type <voidval> buffer_location
-
%type <voidval> single_assignment_action
+%type <tsym> mode_name
%%
/* Z.200, 5.3.1 */
+start : value { }
+ | mode_name
+ { write_exp_elt_opcode(OP_TYPE);
+ write_exp_elt_type($1.type);
+ write_exp_elt_opcode(OP_TYPE);}
+ ;
+
value : expression
{
$$ = 0; /* FIXME */
/* Z.200, 4.2.1 */
location : access_name
+ | primitive_value POINTER
{
- $$ = 0; /* FIXME */
- }
- | FIXME_02
- {
- $$ = 0; /* FIXME */
+ write_exp_elt_opcode (UNOP_IND);
}
;
access_name : LOCATION_NAME
{
write_exp_elt_opcode (OP_VAR_VALUE);
+ write_exp_elt_block (NULL);
write_exp_elt_sym ($1.sym);
write_exp_elt_opcode (OP_VAR_VALUE);
}
| GENERAL_PROCEDURE_NAME
{
write_exp_elt_opcode (OP_VAR_VALUE);
+ write_exp_elt_block (NULL);
write_exp_elt_sym ($1.sym);
write_exp_elt_opcode (OP_VAR_VALUE);
}
/* Z.200, 5.2.10 */
-value_structure_field: structure_primitive_value '.' field_name
- {
- $$ = 0; /* FIXME */
+value_structure_field: primitive_value FIELD_NAME
+ { write_exp_elt_opcode (STRUCTOP_STRUCT);
+ write_exp_string ($2);
+ write_exp_elt_opcode (STRUCTOP_STRUCT);
}
;
expression_conversion: mode_name parenthesised_expression
{
- $$ = 0; /* FIXME */
+ write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type ($1.type);
+ write_exp_elt_opcode (UNOP_CAST);
}
;
{
$$ = 0; /* FIXME */
}
+ | single_assignment_action
+ {
+ $$ = 0; /* FIXME */
+ }
| conditional_expression
{
$$ = 0; /* FIXME */
{
write_exp_elt_opcode (BINOP_BITWISE_XOR);
}
- | single_assignment_action
- {
- $$ = 0; /* FIXME */
- }
;
/* Z.200, 5.3.4 */
}
| operand_2 IN operand_3
{
- $$ = 0; /* FIXME */
+ write_exp_elt_opcode (BINOP_IN);
}
;
;
/* Z.200, 5.3.8 */
-/* Note that we accept any expression for BINOP_CONCAT, not just
- integer literal expressions. (FIXME?) */
operand_5 : operand_6
{
{
write_exp_elt_opcode (UNOP_LOGICAL_NOT);
}
- | parenthesised_expression operand_6
+ | parenthesised_expression literal
+/* We require the string operand to be a literal, to avoid some
+ nasty parsing ambiguities. */
{
write_exp_elt_opcode (BINOP_CONCAT);
}
operand_6 : POINTER location
{
- $$ = 0; /* FIXME */
+ write_exp_elt_opcode (UNOP_ADDR);
}
| RECEIVE buffer_location
{
{
$$ = 0; /* FIXME */
}
- | MAX '(' expression ')'
+ | MAX_TOKEN '(' expression ')'
{
$$ = 0; /* FIXME */
}
- | MIN '(' expression ')'
+ | MIN_TOKEN '(' expression ')'
{
$$ = 0; /* FIXME */
}
}
;
-upper_lower_argument : location
- {
- $$ = 0; /* FIXME */
- }
- | expression
+mode_name : TYPENAME
+ ;
+
+upper_lower_argument : expression
{
$$ = 0; /* FIXME */
}
}
;
-length_argument : location
- {
- $$ = 0; /* FIXME */
- }
- | expression
+length_argument : expression
{
$$ = 0; /* FIXME */
}
lower_element : FIXME_20 { $$ = 0; }
upper_element : FIXME_21 { $$ = 0; }
first_element : FIXME_22 { $$ = 0; }
-structure_primitive_value: FIXME_23 { $$ = 0; }
-field_name : FIXME_24 { $$ = 0; }
-mode_name : FIXME_25 { $$ = 0; }
boolean_expression : FIXME_26 { $$ = 0; }
case_selector_list : FIXME_27 { $$ = 0; }
subexpression : FIXME_28 { $$ = 0; }
if (isalpha (*tokptr))
{
+ char *result;
do {
tokptr++;
- } while (isalpha (*tokptr) || isdigit (*tokptr) || (*tokptr == '_'));
+ } while (isalnum (*tokptr) || (*tokptr == '_'));
yylval.sval.ptr = lexptr;
yylval.sval.length = tokptr - lexptr;
lexptr = tokptr;
- return (copy_name (yylval.sval));
+ result = copy_name (yylval.sval);
+ for (tokptr = result; *tokptr; tokptr++)
+ if (isupper (*tokptr))
+ *tokptr = tolower(*tokptr);
+ return result;
}
return (NULL);
}
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);
&& !isalnum (tokptr[namelength]))
{
yylval.lval = regno;
- lexptr += namelength + 1;
+ lexptr += namelength;
return (GDB_REGNAME);
}
}
int token;
};
-static const struct token tokentab6[] =
-{
- { "LENGTH", LENGTH }
-};
-
-static const struct token tokentab5[] =
+static const struct token idtokentab[] =
{
- { "LOWER", LOWER },
- { "UPPER", UPPER },
- { "ANDIF", ANDIF }
-};
-
-static const struct token tokentab4[] =
-{
- { "PRED", PRED },
- { "SUCC", SUCC },
- { "CARD", CARD },
- { "SIZE", SIZE },
- { "ORIF", ORIF }
-};
-
-static const struct token tokentab3[] =
-{
- { "NUM", NUM },
- { "ABS", ABS },
- { "MAX", MAX },
- { "MIN", MIN },
- { "MOD", MOD },
- { "REM", REM },
- { "NOT", NOT },
- { "XOR", LOGXOR },
- { "AND", LOGAND }
+ { "length", LENGTH },
+ { "lower", LOWER },
+ { "upper", UPPER },
+ { "andif", ANDIF },
+ { "pred", PRED },
+ { "succ", SUCC },
+ { "card", CARD },
+ { "size", SIZE },
+ { "orif", ORIF },
+ { "num", NUM },
+ { "abs", ABS },
+ { "max", MAX_TOKEN },
+ { "min", MIN_TOKEN },
+ { "mod", MOD },
+ { "rem", REM },
+ { "not", NOT },
+ { "xor", LOGXOR },
+ { "and", LOGAND },
+ { "in", IN },
+ { "or", LOGIOR }
};
static const struct token tokentab2[] =
{
{ ":=", GDB_ASSIGNMENT },
{ "//", SLASH_SLASH },
+ { "->", POINTER },
{ "/=", NOTEQUAL },
{ "<=", LEQ },
- { ">=", GTR },
- { "IN", IN },
- { "OR", LOGIOR }
+ { ">=", GTR }
};
/* Read one token, getting characters through lexptr. */
case ';':
case '!':
case '+':
- case '-':
case '*':
case '(':
case ')':
{
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. */
}
break;
}
- /* See if it is a special token of length 6. */
- for (i = 0; i < sizeof (tokentab6) / sizeof (tokentab6[0]); i++)
- {
- if (STREQN (lexptr, tokentab6[i].operator, 6))
- {
- lexptr += 6;
- return (tokentab6[i].token);
- }
- }
- /* See if it is a special token of length 5. */
- for (i = 0; i < sizeof (tokentab5) / sizeof (tokentab5[0]); i++)
- {
- if (STREQN (lexptr, tokentab5[i].operator, 5))
- {
- lexptr += 5;
- return (tokentab5[i].token);
- }
- }
- /* See if it is a special token of length 4. */
- for (i = 0; i < sizeof (tokentab4) / sizeof (tokentab4[0]); i++)
- {
- if (STREQN (lexptr, tokentab4[i].operator, 4))
- {
- lexptr += 4;
- return (tokentab4[i].token);
- }
- }
- /* See if it is a special token of length 3. */
- for (i = 0; i < sizeof (tokentab3) / sizeof (tokentab3[0]); i++)
- {
- if (STREQN (lexptr, tokentab3[i].operator, 3))
- {
- lexptr += 3;
- return (tokentab3[i].token);
- }
- }
/* See if it is a special token of length 2. */
for (i = 0; i < sizeof (tokentab2) / sizeof (tokentab2[0]); i++)
{
would already have found it. */
switch (*lexptr)
{
+ case '-':
case ':':
case '/':
case '<':
case '>':
return (*lexptr++);
}
- /* Look for other special tokens. */
- if (STREQN (lexptr, "TRUE", 4)) /* FIXME: What about lowercase? */
- {
- yylval.ulval = 1;
- lexptr += 4;
- return (BOOLEAN_LITERAL);
- }
- if (STREQN (lexptr, "FALSE", 5)) /* FIXME: What about lowercase? */
- {
- yylval.ulval = 0;
- lexptr += 5;
- return (BOOLEAN_LITERAL);
- }
/* Look for a float literal before looking for an integer literal, so
we match as much of the input stream as possible. */
token = match_float_literal ();
we can't classify what sort of name it is. */
simplename = match_simple_name_string ();
+
if (simplename != NULL)
{
+ /* See if it is a reserved identifier. */
+ for (i = 0; i < sizeof (idtokentab) / sizeof (idtokentab[0]); i++)
+ {
+ if (STREQ (simplename, idtokentab[i].operator))
+ {
+ return (idtokentab[i].token);
+ }
+ }
+
+ /* Look for other special tokens. */
+ if (STREQ (simplename, "true"))
+ {
+ yylval.ulval = 1;
+ return (BOOLEAN_LITERAL);
+ }
+ if (STREQ (simplename, "false"))
+ {
+ yylval.ulval = 0;
+ return (BOOLEAN_LITERAL);
+ }
+
sym = lookup_symbol (simplename, expression_context_block,
VAR_NAMESPACE, (int *) NULL,
(struct symtab **) 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_BASEREG_ARG:
if (innermost_block == NULL
|| contained_in (block_found, innermost_block))
{
case LOC_LABEL:
return (LOCATION_NAME);
break;
- case LOC_UNDEF:
case LOC_TYPEDEF:
+ yylval.tsym.type = SYMBOL_TYPE (sym);
+ return TYPENAME;
+ case LOC_UNDEF:
case LOC_CONST_BYTES:
case LOC_OPTIMIZED_OUT:
error ("Symbol \"%s\" names no location.", simplename);
switch (*lexptr)
{
case '.': /* Not float for example. */
- return (*lexptr++);
+ lexptr++;
+ while (isspace (*lexptr)) lexptr++;
+ simplename = match_simple_name_string ();
+ if (!simplename)
+ return '.';
+ return FIELD_NAME;
}
return (ILLEGAL_TOKEN);
yyerror (msg)
char *msg; /* unused */
{
- printf ("Parsing: %s\n", lexptr);
+ printf_unfiltered ("Parsing: %s\n", lexptr);
if (yychar < 256)
{
error ("Invalid syntax in expression near character '%c'.", yychar);