**** 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:
Fred Fish
1993-01-03 06:56:08 +00:00
parent 54bbbfb433
commit 1188fbbf27
2 changed files with 169 additions and 43 deletions

View File

@ -1,5 +1,15 @@
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.
* expprint.c (print_subexp): Rename BINOP_MULTI_SUBSCRIPT to
MULTI_SUBSCRIPT.

View File

@ -144,6 +144,7 @@ yyerror PARAMS ((char *));
%token <typed_val> INTEGER_LITERAL
%token <ulval> BOOLEAN_LITERAL
%token <typed_val> CHARACTER_LITERAL
%token <dval> FLOAT_LITERAL
%token <ssym> GENERAL_PROCEDURE_NAME
%token <ssym> LOCATION_NAME
%token <voidval> SET_LITERAL
@ -457,6 +458,13 @@ literal : INTEGER_LITERAL
write_exp_elt_longcst ((LONGEST) ($1.val));
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
{
$$ = 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, &copy);
if (*copy == '\0')
{
yylval.dval = dval;
lexptr = tokptr;
return (FLOAT_LITERAL);
}
}
return (0);
}
/* Recognize a character literal. A character literal is single character
or a control sequence, enclosed in single quotes. A control sequence
is a comma separated list of one or more integer literals, enclosed
@ -1229,48 +1372,6 @@ match_dollar_tokens ()
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
{
char *operator;
@ -1329,7 +1430,6 @@ yylex ()
case '\0':
return (0);
case ',':
case '.':
case '=':
case ';':
case '!':
@ -1425,6 +1525,13 @@ yylex ()
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 ();
if (token != 0)
{
return (token);
}
token = match_integer_literal ();
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);
}