* 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> Mon Jan 28 13:29:41 2002 K.Kosako <kosako@sofnec.co.jp>
* eval.c (is_defined): defined?(Foo::Baz) should check constants * eval.c (is_defined): defined?(Foo::Baz) should check constants

67
parse.y
View File

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