1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* parse.y (yylex): strict check for numbers.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2024 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2002-01-28 09:33:56 +00:00
parent 4f38c453b4
commit 8a95f7f981
2 changed files with 65 additions and 44 deletions

View file

@ -1,3 +1,7 @@
Mon Jan 28 18:33:18 2002 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
* parse.y (yylex): strict check for numbers.
Mon Jan 28 13:29:41 2002 K.Kosako <kosako@sofnec.co.jp>
* eval.c (is_defined): defined?(Foo::Baz) should check constants

105
parse.y
View file

@ -3312,9 +3312,9 @@ yylex()
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
{
int is_float, seen_point, seen_e, seen_uc;
int is_float, seen_point, seen_e, nondigit;
is_float = seen_point = seen_e = seen_uc = 0;
is_float = seen_point = seen_e = nondigit = 0;
lex_state = EXPR_END;
newtok();
if (c == '-' || c == '+') {
@ -3322,46 +3322,53 @@ yylex()
c = nextc();
}
if (c == '0') {
int start = toklen();
c = nextc();
if (c == 'x' || c == 'X') {
/* hexadecimal */
c = nextc();
do {
if (c == '_') {
seen_uc = 1;
continue;
}
if (!ISXDIGIT(c)) break;
seen_uc = 0;
tokadd(c);
} while (c = nextc());
if (ISXDIGIT(c)) {
do {
if (c == '_') {
if (nondigit) break;
nondigit = c;
continue;
}
if (!ISXDIGIT(c)) break;
nondigit = 0;
tokadd(c);
} while (c = nextc());
}
pushback(c);
tokfix();
if (toklen() == 0) {
if (toklen() == start) {
yyerror("hexadecimal number without hex-digits");
}
else if (seen_uc) goto trailing_uc;
else if (nondigit) goto trailing_uc;
yylval.val = rb_cstr2inum(tok(), 16);
return tINTEGER;
}
if (c == 'b' || c == 'B') {
/* binary */
c = nextc();
do {
if (c == '_') {
seen_uc = 1;
continue;
}
if (c != '0'&& c != '1') break;
seen_uc = 0;
tokadd(c);
} while (c = nextc());
if (c == '0' || c == '1') {
do {
if (c == '_') {
if (nondigit) break;
nondigit = c;
continue;
}
if (c != '0' && c != '1') break;
nondigit = 0;
tokadd(c);
} while (c = nextc());
}
pushback(c);
tokfix();
if (toklen() == 0) {
if (toklen() == start) {
yyerror("numeric literal without digits");
}
else if (seen_uc) goto trailing_uc;
else if (nondigit) goto trailing_uc;
yylval.val = rb_cstr2inum(tok(), 2);
return tINTEGER;
}
@ -3369,23 +3376,26 @@ yylex()
/* octal */
do {
if (c == '_') {
seen_uc = 1;
if (nondigit) break;
nondigit = c;
continue;
}
if (c < '0' || c > '7') break;
seen_uc = 0;
nondigit = 0;
tokadd(c);
} while (c = nextc());
pushback(c);
tokfix();
if (seen_uc) goto trailing_uc;
yylval.val = rb_cstr2inum(tok(), 8);
return tINTEGER;
if (toklen() > start) {
pushback(c);
tokfix();
if (nondigit) goto trailing_uc;
yylval.val = rb_cstr2inum(tok(), 8);
return tINTEGER;
}
}
if (c > '7' && c <= '9') {
yyerror("Illegal octal digit");
}
else if (c == '.') {
else if (c == '.' || c == 'e' || c == 'E') {
tokadd('0');
}
else {
@ -3399,12 +3409,12 @@ yylex()
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
seen_uc = 0;
nondigit = 0;
tokadd(c);
break;
case '.':
if (seen_uc) goto trailing_uc;
if (nondigit) goto trailing_uc;
if (seen_point || seen_e) {
goto decode_num;
}
@ -3420,27 +3430,32 @@ yylex()
tokadd(c);
is_float++;
seen_point++;
seen_uc = 0;
nondigit = 0;
break;
case 'e':
case 'E':
if (nondigit) {
pushback(c);
c = nondigit;
goto decode_num;
}
if (seen_e) {
goto decode_num;
}
tokadd(c);
seen_e++;
is_float++;
while ((c = nextc()) == '_')
seen_uc = 1;
if (c == '-' || c == '+')
tokadd(c);
else
continue;
nondigit = c;
c = nextc();
if (c != '-' && c != '+') continue;
tokadd(c);
nondigit = c;
break;
case '_': /* `_' in number just ignored */
seen_uc = 1;
if (nondigit) goto decode_num;
nondigit = c;
break;
default:
@ -3452,9 +3467,11 @@ yylex()
decode_num:
pushback(c);
tokfix();
if (seen_uc) {
if (nondigit) {
char tmp[30];
trailing_uc:
yyerror("trailing `_' in number");
sprintf(tmp, "trailing `%c' in number", nondigit);
yyerror(tmp);
}
if (is_float) {
double d = strtod(tok(), 0);