Resolve conflicts between labels and conditional ternary; fix #3931

parent 7a116f27
...@@ -781,7 +781,7 @@ new_dxstr(parser_state *p, node *a) ...@@ -781,7 +781,7 @@ new_dxstr(parser_state *p, node *a)
static node* static node*
new_dsym(parser_state *p, node *a) new_dsym(parser_state *p, node *a)
{ {
return cons((node*)NODE_DSYM, new_dstr(p, a)); return cons((node*)NODE_DSYM, a);
} }
/* (:regx . (s . (opt . enc))) */ /* (:regx . (s . (opt . enc))) */
...@@ -1106,9 +1106,9 @@ heredoc_end(parser_state *p) ...@@ -1106,9 +1106,9 @@ heredoc_end(parser_state *p)
keyword__FILE__ keyword__FILE__
keyword__ENCODING__ keyword__ENCODING__
%token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL %token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL_TAG
%token <nd> tINTEGER tFLOAT tCHAR tXSTRING tREGEXP %token <nd> tINTEGER tFLOAT tCHAR tXSTRING tREGEXP
%token <nd> tSTRING tSTRING_PART tSTRING_MID tLABEL_END %token <nd> tSTRING tSTRING_PART tSTRING_MID
%token <nd> tNTH_REF tBACK_REF %token <nd> tNTH_REF tBACK_REF
%token <num> tREGEXP_END %token <num> tREGEXP_END
...@@ -1180,7 +1180,7 @@ heredoc_end(parser_state *p) ...@@ -1180,7 +1180,7 @@ heredoc_end(parser_state *p)
%right keyword_not %right keyword_not
%right '=' tOP_ASGN %right '=' tOP_ASGN
%left modifier_rescue %left modifier_rescue
%right '?' ':' %right '?' ':' tLABEL_TAG
%nonassoc tDOT2 tDOT3 %nonassoc tDOT2 tDOT3
%left tOROP %left tOROP
%left tANDOP %left tANDOP
...@@ -1926,6 +1926,10 @@ arg : lhs '=' arg_rhs ...@@ -1926,6 +1926,10 @@ arg : lhs '=' arg_rhs
{ {
$$ = new_if(p, cond($1), $3, $6); $$ = new_if(p, cond($1), $3, $6);
} }
| arg '?' arg opt_nl tLABEL_TAG arg
{
$$ = new_if(p, cond($1), $3, $6);
}
| primary | primary
{ {
$$ = $1; $$ = $1;
...@@ -2861,7 +2865,7 @@ symbol : basic_symbol ...@@ -2861,7 +2865,7 @@ symbol : basic_symbol
| tSYMBEG tSTRING_BEG string_rep tSTRING | tSYMBEG tSTRING_BEG string_rep tSTRING
{ {
p->lstate = EXPR_ENDARG; p->lstate = EXPR_ENDARG;
$$ = new_dsym(p, push($3, $4)); $$ = new_dsym(p, new_dstr(p, push($3, $4)));
} }
; ;
...@@ -3266,25 +3270,20 @@ assoc : arg tASSOC arg ...@@ -3266,25 +3270,20 @@ assoc : arg tASSOC arg
void_expr_error(p, $3); void_expr_error(p, $3);
$$ = cons($1, $3); $$ = cons($1, $3);
} }
| tLABEL arg | tIDENTIFIER tLABEL_TAG arg
{
void_expr_error(p, $2);
$$ = cons(new_sym(p, $1), $2);
}
| tLABEL_END arg
{
void_expr_error(p, $2);
$$ = cons(new_sym(p, new_strsym(p, $1)), $2);
}
| tSTRING_BEG tLABEL_END arg
{ {
void_expr_error(p, $3); void_expr_error(p, $3);
$$ = cons(new_sym(p, new_strsym(p, $2)), $3); $$ = cons(new_sym(p, $1), $3);
} }
| tSTRING_BEG string_rep tLABEL_END arg | string tLABEL_TAG arg
{ {
void_expr_error(p, $4); void_expr_error(p, $3);
$$ = cons(new_dsym(p, push($2, $3)), $4); if ($1->car == (node*)NODE_DSTR) {
$$ = cons(new_dsym(p, $1), $3);
}
else {
$$ = cons(new_sym(p, new_strsym(p, $1)), $3);
}
} }
; ;
...@@ -3973,8 +3972,6 @@ parse_string(parser_state *p) ...@@ -3973,8 +3972,6 @@ parse_string(parser_state *p)
int beg = intn(p->lex_strterm->cdr->cdr->car); int beg = intn(p->lex_strterm->cdr->cdr->car);
int end = intn(p->lex_strterm->cdr->cdr->cdr); int end = intn(p->lex_strterm->cdr->cdr->cdr);
parser_heredoc_info *hinf = (type & STR_FUNC_HEREDOC) ? parsing_heredoc_inf(p) : NULL; parser_heredoc_info *hinf = (type & STR_FUNC_HEREDOC) ? parsing_heredoc_inf(p) : NULL;
int cmd_state = p->cmd_start;
int label_p = IS_LABEL_POSSIBLE();
if (beg == 0) beg = -3; /* should never happen */ if (beg == 0) beg = -3; /* should never happen */
if (end == 0) end = -3; if (end == 0) end = -3;
...@@ -4189,13 +4186,6 @@ parse_string(parser_state *p) ...@@ -4189,13 +4186,6 @@ parse_string(parser_state *p)
return tREGEXP; return tREGEXP;
} }
pylval.nd = new_str(p, tok(p), toklen(p)); pylval.nd = new_str(p, tok(p), toklen(p));
if (label_p) {
if (IS_LABEL_SUFFIX(0)) {
p->lstate = EXPR_BEG;
nextc(p);
return tLABEL_END;
}
}
return tSTRING; return tSTRING;
} }
...@@ -5013,14 +5003,19 @@ parser_yylex(parser_state *p) ...@@ -5013,14 +5003,19 @@ parser_yylex(parser_state *p)
p->lstate = EXPR_DOT; p->lstate = EXPR_DOT;
return tCOLON2; return tCOLON2;
} }
if (IS_END() || ISSPACE(c)) { if (!space_seen && IS_END()) {
pushback(p, c); pushback(p, c);
p->lstate = EXPR_BEG; p->lstate = EXPR_BEG;
return ':'; return tLABEL_TAG;
}
if (!ISSPACE(c) || IS_BEG()) {
pushback(p, c);
p->lstate = EXPR_FNAME;
return tSYMBEG;
} }
pushback(p, c); pushback(p, c);
p->lstate = EXPR_FNAME; p->lstate = EXPR_BEG;
return tSYMBEG; return ':';
case '/': case '/':
if (IS_BEG()) { if (IS_BEG()) {
...@@ -5444,11 +5439,10 @@ parser_yylex(parser_state *p) ...@@ -5444,11 +5439,10 @@ parser_yylex(parser_state *p)
if (IS_LABEL_POSSIBLE()) { if (IS_LABEL_POSSIBLE()) {
if (IS_LABEL_SUFFIX(0)) { if (IS_LABEL_SUFFIX(0)) {
p->lstate = EXPR_BEG; p->lstate = EXPR_END;
nextc(p);
tokfix(p); tokfix(p);
pylval.id = intern_cstr(tok(p)); pylval.id = intern_cstr(tok(p));
return tLABEL; return tIDENTIFIER;
} }
} }
if (p->lstate != EXPR_DOT) { if (p->lstate != EXPR_DOT) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment