summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-10-05 16:47:24 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-10-05 16:47:24 +0000
commitdf51beda2f3237580976f241842c320b7121d72c (patch)
tree4615cb3fd4d75a4c3b0b2a76824e5eef17d09b43 /parse.y
parent4758d6584ec5c4056e76916e8aeecc5e5d61af12 (diff)
merge revision(s) 50409,51616,51617,51624: [Backport #10653] [Backport #11456]
parse.y: %-string cannot be a label * parse.y (parser_yylex): %-string cannot be a label even if terminated by single/double quotes. * parse.y: fix syntax error at do-block after a conditional operator. separate label-allowed and after-a-label states from others as bit flags. [ruby-dev:48790] [Bug #10653] * parse.y (IS_BEG): include labeled argument state, which was EXPR_LABELARG. [ruby-dev:49221] [Bug #11456] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_2@52046 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y82
1 files changed, 44 insertions, 38 deletions
diff --git a/parse.y b/parse.y
index 9bb569c4ed..4df09c9411 100644
--- a/parse.y
+++ b/parse.y
@@ -59,8 +59,8 @@ enum lex_state_bits {
EXPR_FNAME_bit, /* ignore newline, no reserved words. */
EXPR_DOT_bit, /* right after `.' or `::', no reserved words. */
EXPR_CLASS_bit, /* immediate after `class', no here document. */
- EXPR_VALUE_bit, /* alike EXPR_BEG but label is disallowed. */
- EXPR_LABELARG_bit, /* ignore significant, +/- is a sign. */
+ EXPR_LABEL_bit, /* flag bit, label is allowed. */
+ EXPR_LABELED_bit, /* flag bit, just after a label. */
EXPR_MAX_STATE
};
/* examine combinations */
@@ -76,14 +76,17 @@ enum lex_state_e {
DEF_EXPR(FNAME),
DEF_EXPR(DOT),
DEF_EXPR(CLASS),
- DEF_EXPR(VALUE),
- DEF_EXPR(LABELARG),
- EXPR_BEG_ANY = (EXPR_BEG | EXPR_VALUE | EXPR_MID | EXPR_CLASS | EXPR_LABELARG),
+ DEF_EXPR(LABEL),
+ DEF_EXPR(LABELED),
+ EXPR_VALUE = EXPR_BEG,
+ EXPR_BEG_ANY = (EXPR_BEG | EXPR_MID | EXPR_CLASS),
EXPR_ARG_ANY = (EXPR_ARG | EXPR_CMDARG),
EXPR_END_ANY = (EXPR_END | EXPR_ENDARG | EXPR_ENDFN)
};
#define IS_lex_state_for(x, ls) ((x) & (ls))
+#define IS_lex_state_all_for(x, ls) (((x) & (ls)) == (ls))
#define IS_lex_state(ls) IS_lex_state_for(lex_state, (ls))
+#define IS_lex_state_all(ls) IS_lex_state_all_for(lex_state, (ls))
#if PARSER_DEBUG
static const char *lex_state_name(enum lex_state_e state);
@@ -2357,24 +2360,14 @@ arg : lhs '=' arg
$$ = dispatch1(defined, $4);
%*/
}
- | arg '?'
- {
- $<val>$ = cond_stack;
- cond_stack = 0;
- COND_PUSH(1);
- }
- arg opt_nl ':'
- {
- cond_stack = $<val>3;
- }
- arg
+ | arg '?' arg opt_nl ':' arg
{
/*%%%*/
value_expr($1);
- $$ = NEW_IF(cond($1), $4, $8);
+ $$ = NEW_IF(cond($1), $3, $6);
fixpos($$, $1);
/*%
- $$ = dispatch3(ifop, $1, $4, $8);
+ $$ = dispatch3(ifop, $1, $3, $6);
%*/
}
| primary
@@ -3040,7 +3033,7 @@ primary : literal
| k_def singleton dot_or_colon {lex_state = EXPR_FNAME;} fname
{
in_single++;
- lex_state = EXPR_ENDFN; /* force for args */
+ lex_state = EXPR_ENDFN|EXPR_LABEL; /* force for args */
local_push(0);
$<id>$ = current_arg;
current_arg = 0;
@@ -4521,6 +4514,7 @@ f_arglist : '(' f_args rparen
| {
$<num>$ = parser->parser_in_kwarg;
parser->parser_in_kwarg = 1;
+ lex_state |= EXPR_LABEL; /* force for args */
}
f_args term
{
@@ -5701,8 +5695,10 @@ rb_parser_compile_file_path(volatile VALUE vparser, VALUE fname, VALUE file, int
#define STR_FUNC_QWORDS 0x08
#define STR_FUNC_SYMBOL 0x10
#define STR_FUNC_INDENT 0x20
+#define STR_FUNC_LABEL 0x40
enum string_type {
+ str_label = STR_FUNC_LABEL,
str_squote = (0),
str_dquote = (STR_FUNC_EXPAND),
str_xquote = (STR_FUNC_EXPAND),
@@ -7136,9 +7132,11 @@ parser_prepare(struct parser_params *parser)
#define IS_ARG() IS_lex_state(EXPR_ARG_ANY)
#define IS_END() IS_lex_state(EXPR_END_ANY)
-#define IS_BEG() IS_lex_state(EXPR_BEG_ANY)
+#define IS_BEG() (IS_lex_state(EXPR_BEG_ANY) || IS_lex_state_all(EXPR_ARG|EXPR_LABELED))
#define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
-#define IS_LABEL_POSSIBLE() ((IS_lex_state(EXPR_BEG | EXPR_ENDFN) && !cmd_state) || IS_ARG())
+#define IS_LABEL_POSSIBLE() (\
+ (IS_lex_state(EXPR_LABEL|EXPR_ENDFN) && !cmd_state) || \
+ IS_ARG())
#define IS_LABEL_SUFFIX(n) (peek_n(':',(n)) && !peek_n(':', (n)+1))
#define IS_AFTER_OPERATOR() IS_lex_state(EXPR_FNAME | EXPR_DOT)
@@ -7809,7 +7807,7 @@ parse_ident(struct parser_params *parser, int c, int cmd_state)
if (IS_LABEL_POSSIBLE()) {
if (IS_LABEL_SUFFIX(0)) {
- lex_state = EXPR_LABELARG;
+ lex_state = EXPR_ARG|EXPR_LABELED;
nextc();
set_yylval_name(TOK_INTERN());
return tLABEL;
@@ -7843,11 +7841,11 @@ parse_ident(struct parser_params *parser, int c, int cmd_state)
return keyword_do_block;
return keyword_do;
}
- if (IS_lex_state_for(state, (EXPR_BEG | EXPR_VALUE | EXPR_LABELARG)))
+ if (IS_lex_state_for(state, (EXPR_BEG | EXPR_LABELED)))
return kw->id[0];
else {
if (kw->id[0] != kw->id[1])
- lex_state = EXPR_BEG;
+ lex_state = EXPR_BEG | EXPR_LABEL;
return kw->id[1];
}
}
@@ -7878,6 +7876,7 @@ parser_yylex(struct parser_params *parser)
register int c;
int space_seen = 0;
int cmd_state;
+ int label;
enum lex_state_e last_state;
#ifdef RIPPER
int fallthru = FALSE;
@@ -7894,7 +7893,7 @@ parser_yylex(struct parser_params *parser)
}
else {
token = parse_string(lex_strterm);
- if (token == tSTRING_END && (peek_n('\'', -1) || peek_n('"', -1))) {
+ if ((token == tSTRING_END) && (lex_strterm->nd_func & STR_FUNC_LABEL)) {
if (((IS_lex_state(EXPR_BEG | EXPR_ENDFN) && !COND_P()) || IS_ARG()) &&
IS_LABEL_SUFFIX(0)) {
nextc();
@@ -7904,7 +7903,7 @@ parser_yylex(struct parser_params *parser)
if (token == tSTRING_END || token == tREGEXP_END || token == tLABEL_END) {
rb_gc_force_recycle((VALUE)lex_strterm);
lex_strterm = 0;
- lex_state = token == tLABEL_END ? EXPR_LABELARG : EXPR_END;
+ lex_state = token == tLABEL_END ? EXPR_BEG|EXPR_LABEL : EXPR_END;
}
}
return token;
@@ -7954,14 +7953,16 @@ parser_yylex(struct parser_params *parser)
#endif
/* fall through */
case '\n':
- if (IS_lex_state(EXPR_BEG | EXPR_VALUE | EXPR_CLASS | EXPR_FNAME | EXPR_DOT | EXPR_LABELARG)) {
+ c = (IS_lex_state(EXPR_BEG|EXPR_CLASS|EXPR_FNAME|EXPR_DOT) &&
+ !IS_lex_state(EXPR_LABELED));
+ if (c || IS_lex_state_all(EXPR_ARG|EXPR_LABELED)) {
#ifdef RIPPER
if (!fallthru) {
ripper_dispatch_scan_event(parser, tIGNORED_NL);
}
fallthru = FALSE;
#endif
- if (IS_lex_state(EXPR_LABELARG) && parser->parser_in_kwarg) {
+ if (!c && parser->parser_in_kwarg) {
goto normal_newline;
}
goto retry;
@@ -8175,7 +8176,8 @@ parser_yylex(struct parser_params *parser)
return '>';
case '"':
- lex_strterm = NEW_STRTERM(str_dquote, '"', 0);
+ label = (IS_LABEL_POSSIBLE() ? str_label : 0);
+ lex_strterm = NEW_STRTERM(str_dquote | label, '"', 0);
return tSTRING_BEG;
case '`':
@@ -8194,7 +8196,8 @@ parser_yylex(struct parser_params *parser)
return tXSTRING_BEG;
case '\'':
- lex_strterm = NEW_STRTERM(str_squote, '\'', 0);
+ label = (IS_LABEL_POSSIBLE() ? str_label : 0);
+ lex_strterm = NEW_STRTERM(str_squote | label, '\'', 0);
return tSTRING_BEG;
case '?':
@@ -8247,7 +8250,7 @@ parser_yylex(struct parser_params *parser)
lex_state = EXPR_BEG;
return tOP_ASGN;
}
- lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
+ lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG|EXPR_LABEL;
pushback(c);
return '|';
@@ -8377,7 +8380,7 @@ parser_yylex(struct parser_params *parser)
return tSYMBEG;
case '/':
- if (IS_lex_state(EXPR_BEG_ANY)) {
+ if (IS_BEG()) {
lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
return tREGEXP_BEG;
}
@@ -8412,7 +8415,7 @@ parser_yylex(struct parser_params *parser)
return ';';
case ',':
- lex_state = EXPR_BEG;
+ lex_state = EXPR_BEG|EXPR_LABEL;
return ',';
case '~':
@@ -8437,7 +8440,7 @@ parser_yylex(struct parser_params *parser)
paren_nest++;
COND_PUSH(0);
CMDARG_PUSH(0);
- lex_state = EXPR_BEG;
+ lex_state = EXPR_BEG|EXPR_LABEL;
return c;
case '[':
@@ -8452,15 +8455,16 @@ parser_yylex(struct parser_params *parser)
return tAREF;
}
pushback(c);
+ lex_state |= EXPR_LABEL;
return '[';
}
else if (IS_BEG()) {
c = tLBRACK;
}
- else if (IS_ARG() && space_seen) {
+ else if (IS_ARG() && (space_seen || IS_lex_state(EXPR_LABELED))) {
c = tLBRACK;
}
- lex_state = EXPR_BEG;
+ lex_state = EXPR_BEG|EXPR_LABEL;
COND_PUSH(0);
CMDARG_PUSH(0);
return c;
@@ -8475,7 +8479,9 @@ parser_yylex(struct parser_params *parser)
CMDARG_PUSH(0);
return tLAMBEG;
}
- if (IS_ARG() || IS_lex_state(EXPR_END | EXPR_ENDFN))
+ if (IS_lex_state(EXPR_LABELED))
+ c = tLBRACE; /* hash */
+ else if (IS_lex_state(EXPR_ARG_ANY | EXPR_END | EXPR_ENDFN))
c = '{'; /* block (primary) */
else if (IS_lex_state(EXPR_ENDARG))
c = tLBRACE_ARG; /* block (expr) */
@@ -8484,6 +8490,7 @@ parser_yylex(struct parser_params *parser)
COND_PUSH(0);
CMDARG_PUSH(0);
lex_state = EXPR_BEG;
+ if (c != tLBRACE_ARG) lex_state |= EXPR_LABEL;
if (c != tLBRACE) command_start = TRUE;
return c;
@@ -8977,7 +8984,6 @@ lex_state_name(enum lex_state_e state)
static const char names[][12] = {
"EXPR_BEG", "EXPR_END", "EXPR_ENDARG", "EXPR_ENDFN", "EXPR_ARG",
"EXPR_CMDARG", "EXPR_MID", "EXPR_FNAME", "EXPR_DOT", "EXPR_CLASS",
- "EXPR_VALUE",
};
if ((unsigned)state & ~(~0u << EXPR_MAX_STATE))