なかだです。

http://www.rubyist.net/~matz/slides/rc2003/mgp00027.htmlを見る
と、{key: value}というのを入れるのは確定のようなので、実装して
みました。

# 他のはもっと影響が大きそうなので、後回し。

できればlex_stateを増やしたくなかったんですが、どうもうまく行き
そうにないですねぇ。

* parse.y: new hash literal.


Index: parse.y =================================================================== RCS file: /cvs/ruby/src/ruby/parse.y,v retrieving revision 1.302 diff -u -2 -p -r1.302 parse.y --- parse.y 9 Nov 2003 15:07:14 -0000 1.302 +++ parse.y 17 Nov 2003 08:40:45 -0000 @@ -75,4 +75,5 @@ static enum lex_state { EXPR_DOT, /* right after `.' or `::', no reserved words. */ EXPR_CLASS, /* immediate after `class', no here document. */ + EXPR_TERNARY, /* alike EXPR_BEG but immediate after ternary op. */ } lex_state; static NODE *lex_strterm; @@ -235,5 +236,5 @@ static void top_local_setup(); k__FILE__ -%token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR +%token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL %token <node> tINTEGER tFLOAT tSTRING_CONTENT %token <node> tNTH_REF tBACK_REF @@ -2363,4 +2364,8 @@ assoc : arg_value tASSOC arg_value $$ = list_append(NEW_LIST($1), $3); } + | tLABEL arg_value + { + $$ = list_append(NEW_LIST(NEW_LIT(ID2SYM($1))), $2); + } ; @@ -3272,4 +3277,5 @@ arg_ambiguous() #define IS_ARG() (lex_state == EXPR_ARG || lex_state == EXPR_CMDARG) +#define IS_BEG() (lex_state == EXPR_BEG || lex_state == EXPR_MID || lex_state == EXPR_TERNARY) static int @@ -3327,4 +3333,5 @@ yylex() case EXPR_DOT: case EXPR_CLASS: + case EXPR_TERNARY: goto retry; default: @@ -3356,5 +3363,5 @@ yylex() c = tSTAR; } - else if (lex_state == EXPR_BEG || lex_state == EXPR_MID) { + else if (IS_BEG()) { c = tSTAR; } @@ -3509,5 +3516,5 @@ yylex() case '?': if (lex_state == EXPR_END || lex_state == EXPR_ENDARG) { - lex_state = EXPR_BEG; + lex_state = EXPR_TERNARY; return '?'; } @@ -3546,5 +3553,5 @@ yylex() ternary: pushback(c); - lex_state = EXPR_BEG; + lex_state = EXPR_TERNARY; return '?'; } @@ -3585,5 +3592,5 @@ yylex() c = tAMPER; } - else if (lex_state == EXPR_BEG || lex_state == EXPR_MID) { + else if (IS_BEG()) { c = tAMPER; } @@ -3639,5 +3646,5 @@ yylex() return tOP_ASGN; } - if (lex_state == EXPR_BEG || lex_state == EXPR_MID || + if (IS_BEG() || (IS_ARG() && space_seen && !ISSPACE(c))) { if (IS_ARG()) arg_ambiguous(); @@ -3669,5 +3676,5 @@ yylex() return tOP_ASGN; } - if (lex_state == EXPR_BEG || lex_state == EXPR_MID || + if (IS_BEG() || (IS_ARG() && space_seen && !ISSPACE(c))) { if (IS_ARG()) arg_ambiguous(); @@ -3928,5 +3935,5 @@ yylex() c = nextc(); if (c == ':') { - if (lex_state == EXPR_BEG || lex_state == EXPR_MID || + if (IS_BEG() || lex_state == EXPR_CLASS || (IS_ARG() && space_seen)) { lex_state = EXPR_BEG; @@ -3956,5 +3963,5 @@ yylex() case '/': - if (lex_state == EXPR_BEG || lex_state == EXPR_MID) { + if (IS_BEG()) { lex_strterm = NEW_STRTERM(str_regexp, '/', 0); return tREGEXP_BEG; @@ -4018,5 +4025,5 @@ yylex() case '(': command_start = Qtrue; - if (lex_state == EXPR_BEG || lex_state == EXPR_MID) { + if (IS_BEG()) { c = tLPAREN; } @@ -4048,5 +4055,5 @@ yylex() return '['; } - else if (lex_state == EXPR_BEG || lex_state == EXPR_MID) { + else if (IS_BEG()) { c = tLBRACK; } @@ -4081,5 +4088,5 @@ yylex() case '%': - if (lex_state == EXPR_BEG || lex_state == EXPR_MID) { + if (IS_BEG()) { int term; int paren; @@ -4364,5 +4371,5 @@ yylex() return kDO; } - if (state == EXPR_BEG) + if (state == EXPR_BEG || state == EXPR_TERNARY) return kw->id[0]; else { @@ -4375,8 +4382,16 @@ yylex() if (lex_state == EXPR_BEG || - lex_state == EXPR_MID || - lex_state == EXPR_DOT || lex_state == EXPR_ARG || lex_state == EXPR_CMDARG) { + if (peek(':') && !(lex_p + 1 < lex_pend && lex_p[1] == ':')) { + lex_state = EXPR_BEG; + nextc(); + yylval.id = rb_intern(tok()); + return tLABEL; + } + } + if (IS_BEG() || + lex_state == EXPR_DOT || + IS_ARG()) { if (cmd_state) { lex_state = EXPR_CMDARG;
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦