[#18440] racc segv revisited — "Akinori MUSHA" <knu@...>

 次のバグの件なんですが、現時点では原因究明を含めて未解決という

24 messages 2002/10/02
[#18617] Re: racc segv revisited — "Akinori MUSHA" <knu@...> 2002/11/02

At Wed, 2 Oct 2002 23:19:59 +0900,

[ruby-dev:18557] Re: symbol literal with non-alphanumeric

From: nobu.nakada@...
Date: 2002-10-22 09:56:43 UTC
List: ruby-dev #18557
なかだです。

At Tue, 22 Oct 2002 00:00:48 +0900,
Yukihiro Matsumoto wrote:
> |>   * :".."形式で式展開を許すか(許したほうが一貫性がある?)
> |
> |やっぱり使えたほうがいいでしょうか。NODEを追加したほうがいいの
> |かも知れませんが、とりあえず[ruby-dev:18537]への追加です。
> 
> 使えた方が良いでしょう。NODE_CALLを使うよりは専用のNODEを用
> 意したほうが良いのかなあ。

あと、Symbol#inspectも忘れてました。

いささか手抜きっぽいですが、こんなとこでしょうか。


Index: eval.c
===================================================================
RCS file: /cvs/ruby/src/ruby/eval.c,v
retrieving revision 1.342
diff -u -2 -p -r1.342 eval.c
--- eval.c	17 Oct 2002 16:13:44 -0000	1.342
+++ eval.c	22 Oct 2002 08:49:13 -0000
@@ -3090,4 +3090,5 @@ rb_eval(self, n)
       case NODE_DREGX:
       case NODE_DREGX_ONCE:
+      case NODE_DSYM:
 	{
 	    VALUE str, str2;
@@ -3124,4 +3125,7 @@ rb_eval(self, n)
 		result = rb_funcall(self, '`', 1, str);
 		break;
+	      case NODE_DSYM:
+		result = rb_str_intern(str);
+		break;
 	      default:
 		result = str;
Index: intern.h
===================================================================
RCS file: /cvs/ruby/src/ruby/intern.h,v
retrieving revision 1.97
diff -u -2 -p -r1.97 intern.h
--- intern.h	23 Sep 2002 15:48:42 -0000	1.97
+++ intern.h	22 Oct 2002 09:52:57 -0000
@@ -298,4 +298,5 @@ int rb_is_instance_id _((ID));
 int rb_is_class_id _((ID));
 int rb_is_local_id _((ID));
+int rb_is_junk_id _((ID));
 VALUE rb_backref_get _((void));
 void rb_backref_set _((VALUE));
@@ -381,8 +382,10 @@ VALUE rb_str_upto _((VALUE, VALUE, int))
 void rb_str_update _((VALUE, long, long, VALUE));
 VALUE rb_str_inspect _((VALUE));
+VALUE rb_str_dump _((VALUE));
 VALUE rb_str_split _((VALUE, const char*));
 void rb_str_associate _((VALUE, VALUE));
 VALUE rb_str_associated _((VALUE));
 void rb_str_setter _((VALUE, ID, VALUE*));
+VALUE rb_str_intern _((VALUE));
 /* struct.c */
 VALUE rb_struct_new __((VALUE, ...));
Index: node.h
===================================================================
RCS file: /cvs/ruby/src/ruby/node.h,v
retrieving revision 1.33
diff -u -2 -p -r1.33 node.h
--- node.h	27 Aug 2002 08:27:11 -0000	1.33
+++ node.h	22 Oct 2002 08:50:51 -0000
@@ -123,4 +123,5 @@ enum node_type {
     NODE_MEMO,
     NODE_IFUNC,
+    NODE_DSYM,
     NODE_LAST
 };
@@ -295,4 +296,5 @@ typedef struct RNode {
 #define NEW_XSTR(s) rb_node_newnode(NODE_XSTR,s,0,0)
 #define NEW_DXSTR(s) rb_node_newnode(NODE_DXSTR,s,0,0)
+#define NEW_DSYM(s) rb_node_newnode(NODE_DSYM,s,0,0)
 #define NEW_EVSTR(n) rb_node_newnode(NODE_EVSTR,0,(n),0)
 #define NEW_CALL(r,m,a) rb_node_newnode(NODE_CALL,r,m,a)
Index: object.c
===================================================================
RCS file: /cvs/ruby/src/ruby/object.c,v
retrieving revision 1.90
diff -u -2 -p -r1.90 object.c
--- object.c	17 Oct 2002 07:26:59 -0000	1.90
+++ object.c	22 Oct 2002 09:53:13 -0000
@@ -520,9 +520,14 @@ sym_inspect(sym)
     VALUE str;
     char *name;
+    ID id = SYM2ID(sym);
 
-    name = rb_id2name(SYM2ID(sym));
+    name = rb_id2name(id);
     str = rb_str_new(0, strlen(name)+1);
     RSTRING(str)->ptr[0] = ':';
     strcpy(RSTRING(str)->ptr+1, name);
+    if (rb_is_junk_id(id)) {
+	str = rb_str_dump(str);
+	strncpy(RSTRING(str)->ptr, ":\"", 2);
+    }
     return str;
 }
Index: parse.y
===================================================================
RCS file: /cvs/ruby/src/ruby/parse.y,v
retrieving revision 1.223
diff -u -2 -p -r1.223 parse.y
--- parse.y	18 Oct 2002 14:13:41 -0000	1.223
+++ parse.y	22 Oct 2002 09:40:55 -0000
@@ -49,4 +49,5 @@
 #define is_const_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CONST)
 #define is_class_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CLASS)
+#define is_junk_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_JUNK)
 
 #define is_asgn_or_id(id) ((is_notop_id(id)) && \
@@ -239,5 +240,5 @@ static void top_local_setup();
 %type <node> string_contents xstring_contents string_content
 %type <node> words qwords word_list qword_list word
-%type <node> literal numeric
+%type <node> literal numeric dsym
 %type <node> bodystmt compstmt stmts stmt expr arg primary command command_call method_call
 %type <node> expr_value arg_value primary_value
@@ -1741,4 +1742,5 @@ literal		: numeric
 			$$ = NEW_LIT(ID2SYM($1));
 		    }
+		| dsym
 		;
 
@@ -1958,4 +1960,29 @@ sym		: fname
 		;
 
+dsym		: tSYMBEG xstring_contents tSTRING_END
+		    {
+		        lex_state = EXPR_END;
+			if (!$2) {
+			    yyerror("empty symbol literal");
+			}
+			else {
+			    $$ = $2;
+			    switch (nd_type($$)) {
+			      case NODE_STR:
+				$$->nd_lit = ID2SYM(rb_intern(RSTRING($$->nd_lit)->ptr));
+				nd_set_type($$, NODE_LIT);
+				break;
+			      case NODE_DSTR:
+				nd_set_type($$, NODE_DSYM);
+				break;
+			      default:
+				$$ = rb_node_newnode(NODE_DSYM, rb_str_new(0, 0),
+						     1, NEW_LIST($$));
+				break;
+			    }
+			}
+		    }
+		;
+
 numeric		: tINTEGER
 		| tFLOAT
@@ -2771,4 +2798,5 @@ regx_options()
 #define STR_FUNC_REGEXP 0x04
 #define STR_FUNC_QWORDS 0x08
+#define STR_FUNC_SYMBOL 0x10
 #define STR_FUNC_INDENT 0x20
 
@@ -2780,4 +2808,6 @@ enum string_type {
     str_sword  = (STR_FUNC_QWORDS),
     str_dword  = (STR_FUNC_QWORDS|STR_FUNC_EXPAND),
+    str_ssym   = (STR_FUNC_SYMBOL),
+    str_dsym   = (STR_FUNC_SYMBOL|STR_FUNC_EXPAND),
 };
 
@@ -2852,4 +2882,9 @@ tokadd_string(func, term, paren)
 	    break;
 	}
+	if (!c && (func & STR_FUNC_SYMBOL)) {
+	    func &= ~STR_FUNC_SYMBOL;
+	    rb_compile_error("symbol cannot contain '\\0'");
+	    continue;
+	}
 	tokadd(c);
     }
@@ -3763,9 +3798,20 @@ yylex()
 	    return tCOLON2;
 	}
-	pushback(c);
 	if (lex_state == EXPR_END || lex_state == EXPR_ENDARG || ISSPACE(c)) {
+	    pushback(c);
 	    lex_state = EXPR_BEG;
 	    return ':';
 	}
+	switch (c) {
+	  case '\'':
+	    lex_strterm = NEW_STRTERM(str_ssym, c, 0);
+	    break;
+	  case '"':
+	    lex_strterm = NEW_STRTERM(str_dsym, c, 0);
+	    break;
+	  default:
+	    pushback(c);
+	    break;
+	}
 	lex_state = EXPR_FNAME;
 	return tSYMBEG;
@@ -3969,4 +4015,9 @@ yylex()
 		return tREGEXP_BEG;
 
+	      case 's':
+		lex_strterm = NEW_STRTERM(str_ssym, term, paren);
+		lex_state = EXPR_FNAME;
+		return tSYMBEG;
+
 	      default:
 		yyerror("unknown type of %string");
@@ -5603,4 +5654,12 @@ rb_is_local_id(id)
 {
     if (is_local_id(id)) return Qtrue;
+    return Qfalse;
+}
+
+int
+rb_is_junk_id(id)
+    ID id;
+{
+    if (is_junk_id(id)) return Qtrue;
     return Qfalse;
 }
Index: string.c
===================================================================
RCS file: /cvs/ruby/src/ruby/string.c,v
retrieving revision 1.121
diff -u -2 -p -r1.121 string.c
--- string.c	25 Sep 2002 07:03:01 -0000	1.121
+++ string.c	22 Oct 2002 09:52:50 -0000
@@ -1874,5 +1874,5 @@ rb_str_inspect(str)
 }
 
-static VALUE
+VALUE
 rb_str_dump(str)
     VALUE str;
@@ -3004,5 +3004,5 @@ rb_str_crypt(str, salt)
 }
 
-static VALUE
+VALUE
 rb_str_intern(str)
     VALUE str;


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

In This Thread