diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-01-28 09:33:56 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-01-28 09:33:56 +0000 |
commit | 8a95f7f981c5e25ca26de2b112c4979627a72a02 (patch) | |
tree | 3d254785019c4df7b363528307069a65d7c83f77 /parse.y | |
parent | 4f38c453b4fccfbc529909781c2c1659f256697b (diff) |
* parse.y (yylex): strict check for numbers.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2024 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'parse.y')
-rw-r--r-- | parse.y | 105 |
1 files changed, 61 insertions, 44 deletions
@@ -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); |