[#15625] rb_hash_initialize — Takaaki Tateishi <ttate@...>

立石です.

22 messages 2002/01/04
[#15627] Re: rb_hash_initialize — matz@... (Yukihiro Matsumoto) 2002/01/04

まつもと ゆきひろです

[#15628] Re: rb_hash_initialize — Takaaki Tateishi <ttate@...> 2002/01/04

立石です.

[#15685] undefined method `inherited' for false (NameError) — WATANABE Hirofumi <eban@...>

わたなべです。

13 messages 2002/01/15
[#15686] Re: undefined method `inherited' for false (NameError) — nobu.nakada@... 2002/01/15

なかだです。

[#15757] 文字列→整数変換 — nobu.nakada@...

なかだです。

30 messages 2002/01/25

[#15830] [ 提案 ] puts, print 等を IO から分離 — UENO Katsuhiro <unnie@...>

うえのです。

14 messages 2002/01/31

[ruby-dev:15779] Re: 文字列→整数変換

From: nobu.nakada@...
Date: 2002-01-27 19:59:30 UTC
List: ruby-dev #15779
なかだです。

追加。

At Fri, 25 Jan 2002 17:35:02 +0900,
Nobuyoshi-Nakada wrote:
> * eval/parser, Integer(), Float()
>   各数字間に高々一個の'_'が許される。符号の後、'.','e'の前後(浮
>   動少数点数の場合)には許されない。

    prefixだけしかない整数(0xだけ、0bだけ)はエラー。
    'e'のあとに指数部がないもの(符号だけのものも含む)もエラー。

前者は1.4はちゃんとエラーになるんですが、1.6.2あたりから-0xとか
-0bなんてのが通ってしまいます。

あと、今のところどうも'e'の前後の'_'はわざと通るようにしてある
ようなんですが、これはエラーになるように変更するということでしょ
うか。



Index: parse.y
===================================================================
RCS file: /cvs/ruby/src/ruby/parse.y,v
retrieving revision 1.144
diff -u -2 -p -w -r1.144 parse.y
--- parse.y	2002/01/21 07:44:06	1.144
+++ parse.y	2002/01/27 18:31:34
@@ -3313,7 +3313,7 @@ yylex()
       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();
@@ -3323,23 +3323,27 @@ yylex()
 	    }
 	    if (c == '0') {
+		int start = toklen();
 		c = nextc();
 		if (c == 'x' || c == 'X') {
 		    /* hexadecimal */
 		    c = nextc();
+		    if (ISXDIGIT(c)) {
 		    do {
 			if (c == '_') {
-			    seen_uc = 1;
+				if (nondigit) break;
+				nondigit = c;
 			    continue;
 			}
 			if (!ISXDIGIT(c)) break;
-			seen_uc = 0;
+			    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;
@@ -3348,19 +3352,22 @@ yylex()
 		    /* binary */
 		    c = nextc();
+		    if (c == '0' || c == '1') {
 		    do {
 			if (c == '_') {
-			    seen_uc = 1;
+				if (nondigit) break;
+				nondigit = c;
 			    continue;
 			}
 			if (c != '0'&& c != '1') break;
-			seen_uc = 0;
+			    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;
@@ -3370,21 +3377,24 @@ yylex()
 	            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());
+		    if (toklen() > start) {
 		    pushback(c);
 		    tokfix();
-		    if (seen_uc) goto trailing_uc;
+			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');
 		}
@@ -3400,10 +3410,10 @@ yylex()
 		  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;
@@ -3421,5 +3431,5 @@ yylex()
 		    is_float++;
 		    seen_point++;
-		    seen_uc = 0;
+		    nondigit = 0;
 		    break;
 
@@ -3432,8 +3442,13 @@ yylex()
 		    seen_e++;
 		    is_float++;
-		    while ((c = nextc()) == '_')
-			seen_uc = 1;
-		    if (c == '-' || c == '+')
+		    nondigit = c;
+		    if ((c = nextc()) == '_') {
+			nondigit = c;
+			c = nextc();
+		    }
+		    if (c == '-' || c == '+') {
 			tokadd(c);
+			nondigit = c;
+		    }
 		    else 
 			continue;
@@ -3441,5 +3456,6 @@ yylex()
 
 		  case '_':	/* `_' in number just ignored */
-		    seen_uc = 1;
+		    if (nondigit) goto decode_num;
+		    nondigit = c;
 		    break;
 
@@ -3453,7 +3469,9 @@ yylex()
 	    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) {


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread