From: nobu.nakada@... Date: 2004-03-06T11:05:38+09:00 Subject: [ruby-dev:23150] multidigit hex char in leteral なかだです。 Onigurumaもimportされたことだし、リテラル中の\x{}を有効にしては どうかと思うのですが。 $ ./ruby -v -e "p Regexp.new('\x{33}')" ruby 1.9.0 (2004-03-06) [i686-linux] /\x{33}/ $ ./ruby -v -e "p /\x{33}/" ruby 1.9.0 (2004-03-06) [i686-linux] -e:1: warning: ambiguous first argument; put parentheses or even spaces -e:1: Invalid escape character syntax p /\x{33}/ ^ -e:1: unterminated string meets end of file -e:1: parse error p /\x{33}/ ^ -e:1: warning: useless use of a literal in void context * parse.y (read_escape, tokadd_escape, tokadd_string): allow multiple hexadecimal escape. Index: parse.y =================================================================== RCS file: /cvs/ruby/src/ruby/parse.y,v retrieving revision 1.317 diff -u -2 -p -d -r1.317 parse.y --- parse.y 3 Mar 2004 04:55:31 -0000 1.317 +++ parse.y 6 Mar 2004 02:00:37 -0000 @@ -2720,4 +2720,15 @@ newtok() static void +tokspace(n) + int n; +{ + tokidx += n; + if (tokidx >= toksiz) { + do {toksiz *= 2;} while (toksiz < tokidx); + REALLOC_N(tokenbuf, char, toksiz); + } +} + +static void tokadd(c) char c; @@ -2731,4 +2742,61 @@ tokadd(c) static int +tokadd_hex() +{ + int num, n, i, c; + char *s; + + if (!peek('{')) { + c = scan_hex(lex_p, 2, &num); + if (num) tokadd(c); + return num; + } + + s = lex_p; + do { + if (++s >= lex_pend) return 0; + } while (ISXDIGIT(*s)); + if (*s != '}') return 0; + num = s - ++lex_p; + s = lex_p; + lex_p += num + 1; /* skip {...} */ + if (!num) return 0; + i = tokidx; + tokspace((num + 1) >> 1); + n = num; + if (n & 1) { + tokenbuf[i++] = scan_hex(s++, 1, &c); + if (!--n) return num; + } + do { + tokenbuf[i++] = scan_hex(s, 2, &c); + } while (s += 2, (n -= 2) > 0); + return num; +} + +static int +tok_hex(numlen) + int *numlen; +{ + int c, n; + char *s, *p; + + if (!peek('{')) return scan_hex(lex_p, 2, numlen); + s = lex_p + 1; + p = memchr(s, '}', lex_pend - s); + if (!p || (n = p - s) == 0) { + *numlen = 0; + return 0; + } + c = scan_hex(s, n, numlen); + if (*numlen != n) { + *numlen = 0; + return 0; + } + *numlen += 2; + return c; +} + +static int read_escape() { @@ -2775,5 +2843,5 @@ read_escape() int numlen; - c = scan_hex(lex_p, 2, &numlen); + c = tok_hex(&numlen); if (numlen == 0) { yyerror("Invalid escape character syntax"); @@ -2864,5 +2932,5 @@ tokadd_escape(term) tokadd('\\'); tokadd(c); - scan_hex(lex_p, 2, &numlen); + tok_hex(&numlen); if (numlen == 0) { yyerror("Invalid escape character syntax"); @@ -3034,4 +3102,8 @@ tokadd_string(func, term, paren, nest) } else if (func & STR_FUNC_EXPAND) { + if (c == 'x') { + if (!tokadd_hex()) return -1; + continue; + } pushback(c); if (func & STR_FUNC_ESCAPE) tokadd('\\'); -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦