mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-23 19:50:13 +08:00
**** start-sanitize-chill ****
* ch-exp.y (FLOAT_LITERAL): Add token. * ch-exp.y (literal): Add FLOAT_LITERAL. * ch-exp.y (match_float_literal): New lexer routine. * ch-exp.y (convert_float): Remove. * ch-exp.y (yylex): Call match_float_literal. * ch-exp.y (yylex): Match single '.' after trying to match floating point literals. **** end-sanitize-chill ****
This commit is contained in:
@ -1,5 +1,15 @@
|
|||||||
Sat Jan 2 12:16:41 1993 Fred Fish (fnf@cygnus.com)
|
Sat Jan 2 12:16:41 1993 Fred Fish (fnf@cygnus.com)
|
||||||
|
|
||||||
|
**** start-sanitize-chill ****
|
||||||
|
* ch-exp.y (FLOAT_LITERAL): Add token.
|
||||||
|
* ch-exp.y (literal): Add FLOAT_LITERAL.
|
||||||
|
* ch-exp.y (match_float_literal): New lexer routine.
|
||||||
|
* ch-exp.y (convert_float): Remove.
|
||||||
|
* ch-exp.y (yylex): Call match_float_literal.
|
||||||
|
* ch-exp.y (yylex): Match single '.' after trying
|
||||||
|
to match floating point literals.
|
||||||
|
**** end-sanitize-chill ****
|
||||||
|
|
||||||
* eval.c (evaluate_subexp): Add case MULTI_SUBSCRIPT.
|
* eval.c (evaluate_subexp): Add case MULTI_SUBSCRIPT.
|
||||||
* expprint.c (print_subexp): Rename BINOP_MULTI_SUBSCRIPT to
|
* expprint.c (print_subexp): Rename BINOP_MULTI_SUBSCRIPT to
|
||||||
MULTI_SUBSCRIPT.
|
MULTI_SUBSCRIPT.
|
||||||
|
202
gdb/ch-exp.y
202
gdb/ch-exp.y
@ -144,6 +144,7 @@ yyerror PARAMS ((char *));
|
|||||||
%token <typed_val> INTEGER_LITERAL
|
%token <typed_val> INTEGER_LITERAL
|
||||||
%token <ulval> BOOLEAN_LITERAL
|
%token <ulval> BOOLEAN_LITERAL
|
||||||
%token <typed_val> CHARACTER_LITERAL
|
%token <typed_val> CHARACTER_LITERAL
|
||||||
|
%token <dval> FLOAT_LITERAL
|
||||||
%token <ssym> GENERAL_PROCEDURE_NAME
|
%token <ssym> GENERAL_PROCEDURE_NAME
|
||||||
%token <ssym> LOCATION_NAME
|
%token <ssym> LOCATION_NAME
|
||||||
%token <voidval> SET_LITERAL
|
%token <voidval> SET_LITERAL
|
||||||
@ -457,6 +458,13 @@ literal : INTEGER_LITERAL
|
|||||||
write_exp_elt_longcst ((LONGEST) ($1.val));
|
write_exp_elt_longcst ((LONGEST) ($1.val));
|
||||||
write_exp_elt_opcode (OP_LONG);
|
write_exp_elt_opcode (OP_LONG);
|
||||||
}
|
}
|
||||||
|
| FLOAT_LITERAL
|
||||||
|
{
|
||||||
|
write_exp_elt_opcode (OP_DOUBLE);
|
||||||
|
write_exp_elt_type (builtin_type_double);
|
||||||
|
write_exp_elt_dblcst ($1);
|
||||||
|
write_exp_elt_opcode (OP_DOUBLE);
|
||||||
|
}
|
||||||
| SET_LITERAL
|
| SET_LITERAL
|
||||||
{
|
{
|
||||||
$$ = 0; /* FIXME */
|
$$ = 0; /* FIXME */
|
||||||
@ -1005,6 +1013,141 @@ decode_integer_literal (valptr, tokptrptr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If it wasn't for the fact that floating point values can contain '_'
|
||||||
|
characters, we could just let strtod do all the hard work by letting it
|
||||||
|
try to consume as much of the current token buffer as possible and
|
||||||
|
find a legal conversion. Unfortunately we need to filter out the '_'
|
||||||
|
characters before calling strtod, which we do by copying the other
|
||||||
|
legal chars to a local buffer to be converted. However since we also
|
||||||
|
need to keep track of where the last unconsumed character in the input
|
||||||
|
buffer is, we have transfer only as many characters as may compose a
|
||||||
|
legal floating point value. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
match_float_literal ()
|
||||||
|
{
|
||||||
|
char *tokptr = lexptr;
|
||||||
|
char *buf;
|
||||||
|
char *copy;
|
||||||
|
char ch;
|
||||||
|
double dval;
|
||||||
|
extern double strtod ();
|
||||||
|
|
||||||
|
/* Make local buffer in which to build the string to convert. This is
|
||||||
|
required because underscores are valid in chill floating point numbers
|
||||||
|
but not in the string passed to strtod to convert. The string will be
|
||||||
|
no longer than our input string. */
|
||||||
|
|
||||||
|
copy = buf = (char *) alloca (strlen (tokptr) + 1);
|
||||||
|
|
||||||
|
/* Transfer all leading digits to the conversion buffer, discarding any
|
||||||
|
underscores. */
|
||||||
|
|
||||||
|
while (isdigit (*tokptr) || *tokptr == '_')
|
||||||
|
{
|
||||||
|
if (*tokptr != '_')
|
||||||
|
{
|
||||||
|
*copy++ = *tokptr;
|
||||||
|
}
|
||||||
|
tokptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now accept either a '.', or one of [eEdD]. Dot is legal regardless
|
||||||
|
of whether we found any leading digits, and we simply accept it and
|
||||||
|
continue on to look for the fractional part and/or exponent. One of
|
||||||
|
[eEdD] is legal only if we have seen digits, and means that there
|
||||||
|
is no fractional part. If we find neither of these, then this is
|
||||||
|
not a floating point number, so return failure. */
|
||||||
|
|
||||||
|
switch (*tokptr++)
|
||||||
|
{
|
||||||
|
case '.':
|
||||||
|
/* Accept and then look for fractional part and/or exponent. */
|
||||||
|
*copy++ = '.';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'e':
|
||||||
|
case 'E':
|
||||||
|
case 'd':
|
||||||
|
case 'D':
|
||||||
|
if (copy == buf)
|
||||||
|
{
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
*copy++ = 'e';
|
||||||
|
goto collect_exponent;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We found a '.', copy any fractional digits to the conversion buffer, up
|
||||||
|
to the first nondigit, non-underscore character. */
|
||||||
|
|
||||||
|
while (isdigit (*tokptr) || *tokptr == '_')
|
||||||
|
{
|
||||||
|
if (*tokptr != '_')
|
||||||
|
{
|
||||||
|
*copy++ = *tokptr;
|
||||||
|
}
|
||||||
|
tokptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look for an exponent, which must start with one of [eEdD]. If none
|
||||||
|
is found, jump directly to trying to convert what we have collected
|
||||||
|
so far. */
|
||||||
|
|
||||||
|
switch (*tokptr)
|
||||||
|
{
|
||||||
|
case 'e':
|
||||||
|
case 'E':
|
||||||
|
case 'd':
|
||||||
|
case 'D':
|
||||||
|
*copy++ = 'e';
|
||||||
|
tokptr++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto convert_float;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Accept an optional '-' or '+' following one of [eEdD]. */
|
||||||
|
|
||||||
|
collect_exponent:
|
||||||
|
if (*tokptr == '+' || *tokptr == '-')
|
||||||
|
{
|
||||||
|
*copy++ = *tokptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now copy an exponent into the conversion buffer. Note that at the
|
||||||
|
moment underscores are *not* allowed in exponents. */
|
||||||
|
|
||||||
|
while (isdigit (*tokptr))
|
||||||
|
{
|
||||||
|
*copy++ = *tokptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we transfered any chars to the conversion buffer, try to interpret its
|
||||||
|
contents as a floating point value. If any characters remain, then we
|
||||||
|
must not have a valid floating point string. */
|
||||||
|
|
||||||
|
convert_float:
|
||||||
|
*copy = '\0';
|
||||||
|
if (copy != buf)
|
||||||
|
{
|
||||||
|
dval = strtod (buf, ©);
|
||||||
|
if (*copy == '\0')
|
||||||
|
{
|
||||||
|
yylval.dval = dval;
|
||||||
|
lexptr = tokptr;
|
||||||
|
return (FLOAT_LITERAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Recognize a character literal. A character literal is single character
|
/* Recognize a character literal. A character literal is single character
|
||||||
or a control sequence, enclosed in single quotes. A control sequence
|
or a control sequence, enclosed in single quotes. A control sequence
|
||||||
is a comma separated list of one or more integer literals, enclosed
|
is a comma separated list of one or more integer literals, enclosed
|
||||||
@ -1229,48 +1372,6 @@ match_dollar_tokens ()
|
|||||||
return (GDB_LAST);
|
return (GDB_LAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void convert_float ()
|
|
||||||
{
|
|
||||||
extern double strtod ();
|
|
||||||
double d;
|
|
||||||
char tmp[256];
|
|
||||||
char *p = yytext, *p1 = tmp;
|
|
||||||
char c;
|
|
||||||
|
|
||||||
while (c = *p++)
|
|
||||||
{
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case '_':
|
|
||||||
break;
|
|
||||||
case 'E':
|
|
||||||
case 'd':
|
|
||||||
case 'D':
|
|
||||||
*p1++ = 'e';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
*p1++ = c;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*p1 = '\0';
|
|
||||||
d = strtod (tmp, &p1);
|
|
||||||
if (*p1)
|
|
||||||
{
|
|
||||||
/* add error handling here */
|
|
||||||
;
|
|
||||||
}
|
|
||||||
yylval.dval = d;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Take care of parsing a number (anything that starts with a digit).
|
|
||||||
Set yylval and return the token type; update lexptr.
|
|
||||||
LEN is the number of characters in it. */
|
|
||||||
|
|
||||||
/*** Needs some error checking for the float case ***/
|
|
||||||
|
|
||||||
struct token
|
struct token
|
||||||
{
|
{
|
||||||
char *operator;
|
char *operator;
|
||||||
@ -1329,7 +1430,6 @@ yylex ()
|
|||||||
case '\0':
|
case '\0':
|
||||||
return (0);
|
return (0);
|
||||||
case ',':
|
case ',':
|
||||||
case '.':
|
|
||||||
case '=':
|
case '=':
|
||||||
case ';':
|
case ';':
|
||||||
case '!':
|
case '!':
|
||||||
@ -1425,6 +1525,13 @@ yylex ()
|
|||||||
lexptr += 5;
|
lexptr += 5;
|
||||||
return (BOOLEAN_LITERAL);
|
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 ();
|
||||||
|
if (token != 0)
|
||||||
|
{
|
||||||
|
return (token);
|
||||||
|
}
|
||||||
token = match_integer_literal ();
|
token = match_integer_literal ();
|
||||||
if (token != 0)
|
if (token != 0)
|
||||||
{
|
{
|
||||||
@ -1481,6 +1588,15 @@ yylex ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Catch single character tokens which are not part of some
|
||||||
|
longer token. */
|
||||||
|
|
||||||
|
switch (*lexptr)
|
||||||
|
{
|
||||||
|
case '.': /* Not float for example. */
|
||||||
|
return (*lexptr++);
|
||||||
|
}
|
||||||
|
|
||||||
return (ILLEGAL_TOKEN);
|
return (ILLEGAL_TOKEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user