summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2016-11-24 10:32:28 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2016-11-24 10:32:28 +0900
commit1c9593954bfcdcd1c99732eb572c3995228d8fbb (patch)
tree76ba50be166e1d201ef6ff090141412e7b36319f
parentdc4be19aab7df7b3d31102a68c4ed12c63a5814c (diff)
downloadmruby-1c9593954bfcdcd1c99732eb572c3995228d8fbb.tar.gz
mruby-1c9593954bfcdcd1c99732eb572c3995228d8fbb.zip
Add "void value expression" check to the parser.
-rw-r--r--mrbgems/mruby-compiler/core/parse.y78
1 files changed, 52 insertions, 26 deletions
diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y
index 90b8812b9..ea7f809f3 100644
--- a/mrbgems/mruby-compiler/core/parse.y
+++ b/mrbgems/mruby-compiler/core/parse.y
@@ -41,6 +41,7 @@ static void yyerror(parser_state *p, const char *s);
static void yywarn(parser_state *p, const char *s);
static void yywarning(parser_state *p, const char *s);
static void backref_error(parser_state *p, node *n);
+static void void_expr_error(parser_state *p, node *n);
static void tokadd(parser_state *p, int32_t c);
#define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c))
@@ -1097,7 +1098,7 @@ heredoc_end(parser_state *p)
%type <nd> literal numeric cpath symbol
%type <nd> top_compstmt top_stmts top_stmt
%type <nd> bodystmt compstmt stmts stmt expr arg primary command command_call method_call
-%type <nd> expr_value arg_value arg_rhs primary_value
+%type <nd> expr_value arg0 arg_rhs primary_value
%type <nd> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
%type <nd> args call_args opt_call_args
%type <nd> paren_args opt_paren_args variable
@@ -1322,7 +1323,7 @@ stmt : keyword_alias fsym {p->lstate = EXPR_FNAME;} fsym
{
$$ = new_asgn(p, $1, new_array(p, $3));
}
- | mlhs '=' arg_value
+ | mlhs '=' arg
{
$$ = new_masgn(p, $1, $3);
}
@@ -1395,13 +1396,16 @@ expr : command_call
{
$$ = call_uni_op(p, cond($2), "!");
}
- | arg
+ | arg0
;
expr_value : expr
{
if (!$1) $$ = new_nil(p);
- else $$ = $1;
+ else {
+ void_expr_error(p, $1);
+ $$ = $1;
+ }
}
;
@@ -1734,7 +1738,7 @@ reswords : keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
| keyword_while | keyword_until
;
-arg : lhs '=' arg_rhs
+arg0 : lhs '=' arg_rhs
{
$$ = new_asgn(p, $1, $3);
}
@@ -1907,10 +1911,13 @@ arg : lhs '=' arg_rhs
}
;
-arg_value : arg
+arg : arg0
{
- $$ = $1;
- if (!$$) $$ = new_nil(p);
+ if (!$1) $$ = new_nil(p);
+ else {
+ void_expr_error(p, $1);
+ $$ = $1;
+ }
}
;
@@ -1931,7 +1938,7 @@ aref_args : none
}
;
-arg_rhs : arg %prec tOP_ASGN
+arg_rhs : arg %prec tOP_ASGN
| arg modifier_rescue arg
{
$$ = new_mod_rescue(p, $1, $3);
@@ -2005,7 +2012,7 @@ command_args : {
}
;
-block_arg : tAMPER arg_value
+block_arg : tAMPER arg
{
$$ = new_block_arg(p, $2);
}
@@ -2021,43 +2028,43 @@ opt_block_arg : ',' block_arg
}
;
-args : arg_value
+args : arg
{
$$ = cons($1, 0);
NODE_LINENO($$, $1);
}
- | tSTAR arg_value
+ | tSTAR arg
{
$$ = cons(new_splat(p, $2), 0);
NODE_LINENO($$, $2);
}
- | args ',' arg_value
+ | args ',' arg
{
$$ = push($1, $3);
}
- | args ',' tSTAR arg_value
+ | args ',' tSTAR arg
{
$$ = push($1, new_splat(p, $4));
}
- | args ',' heredoc_bodies arg_value
+ | args ',' heredoc_bodies arg
{
$$ = push($1, $4);
}
- | args ',' heredoc_bodies tSTAR arg_value
+ | args ',' heredoc_bodies tSTAR arg
{
$$ = push($1, new_splat(p, $5));
}
;
-mrhs : args ',' arg_value
+mrhs : args ',' arg
{
$$ = push($1, $3);
}
- | args ',' tSTAR arg_value
+ | args ',' tSTAR arg
{
$$ = push($1, new_splat(p, $4));
}
- | tSTAR arg_value
+ | tSTAR arg
{
$$ = list1(new_splat(p, $2));
}
@@ -2688,7 +2695,7 @@ opt_rescue : keyword_rescue exc_list exc_var then
| none
;
-exc_list : arg_value
+exc_list : arg
{
$$ = list1($1);
}
@@ -3115,7 +3122,7 @@ f_opt_asgn : tIDENTIFIER '='
}
;
-f_opt : f_opt_asgn arg_value
+f_opt : f_opt_asgn arg
{
$$ = cons(nsym($1), $2);
}
@@ -3233,23 +3240,23 @@ assocs : assoc
}
;
-assoc : arg_value tASSOC arg_value
+assoc : arg tASSOC arg
{
$$ = cons($1, $3);
}
- | tLABEL arg_value
+ | tLABEL arg
{
$$ = cons(new_sym(p, $1), $2);
}
- | tLABEL_END arg_value
+ | tLABEL_END arg
{
$$ = cons(new_sym(p, new_strsym(p, $1)), $2);
}
- | tSTRING_BEG tLABEL_END arg_value
+ | tSTRING_BEG tLABEL_END arg
{
$$ = cons(new_sym(p, new_strsym(p, $2)), $3);
}
- | tSTRING_BEG string_rep tLABEL_END arg_value
+ | tSTRING_BEG string_rep tLABEL_END arg
{
$$ = cons(new_dsym(p, push($2, $3)), $4);
}
@@ -3430,6 +3437,25 @@ backref_error(parser_state *p, node *n)
}
}
+static void
+void_expr_error(parser_state *p, node *n)
+{
+ int c;
+
+ c = (int)(intptr_t)n->car;
+ switch (c) {
+ case NODE_BREAK:
+ case NODE_RETURN:
+ case NODE_NEXT:
+ case NODE_REDO:
+ case NODE_RETRY:
+ yyerror(p, "void value expression");
+ break;
+ default:
+ break;
+ }
+}
+
static void pushback(parser_state *p, int c);
static mrb_bool peeks(parser_state *p, const char *s);
static mrb_bool skips(parser_state *p, const char *s);