Slide 42
Slide 42 text
"Dissecting and Reconstructing Ruby Syntactic Structures" ʔ @ydah
Ruby - stmt and expr
https://github.com/ruby/ruby/blob/master/parse.y
stmt : keyword_alias f
i
tem {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} f
i
tem
{
$$ = NEW_ALIAS($2, $4, &@$, &@1);
/ *
% ripper: alias!($
:
2, $
:
4) %
* /
}
| keyword_alias tGVAR tGVAR
{
$$ = NEW_VALIAS($2, $3, &@$, &@1);
/ *
% ripper: var_alias!($
:
2, $
:
3) %
* /
}
| keyword_alias tGVAR tBACK_REF
{
char buf[2];
buf[0] = '$';
buf[1] = (char)RNODE_BACK_REF($3)
- >
nd_nth;
$$ = NEW_VALIAS($2, rb_intern2(buf, 2), &@$, &@1);
/ *
% ripper: var_alias!($
:
2, $
:
3) %
* /
}
| keyword_alias tGVAR tNTH_REF
{
static const char mesg[] = "can't make alias for the number variables";
/ *
%%%
* /
yyerror1(&@3, mesg);
/ *
% %
* /
$$ = NEW_ERROR(&@$);
/ *
% ripper[error]
:
alias_error!(ERR_MESG(), $
:
3) %
* /
}
| keyword_undef undef_list
{
nd_set_f
i
rst_loc($2, @1.beg_pos);
RNODE_UNDEF($2)
- >
keyword_loc = @1;
$$ = $2;
/ *
% ripper: undef!($
:
2) %
* /
}
| stmt modif
i
er_if expr_value
{
$$ = new_if(p, $3, remove_begin($1), 0, &@$, &@2, &NULL_LOC, &NULL_LOC);
f
i
xpos($$, $3);
/ *
% ripper: if_mod!($
:
3, $
:
1) %
* /
}
| stmt modif
i
er_unless expr_value
{
$$ = new_unless(p, $3, remove_begin($1), 0, &@$, &@2, &NULL_LOC, &NULL_LOC);
f
i
xpos($$, $3);
/ *
% ripper: unless_mod!($
:
3, $
:
1) %
* /
}
| stmt modif
i
er_while expr_value
{
clear_block_exit(p, false);
if ($1
& &
nd_type_p($1, NODE_BEGIN)) {
$$ = NEW_WHILE(cond(p, $3, &@3), RNODE_BEGIN($1)
- >
nd_body, 0, &@$, &@2, &NULL_LOC);
}
else {
$$ = NEW_WHILE(cond(p, $3, &@3), $1, 1, &@$, &@2, &NULL_LOC);
}
/ *
% ripper: while_mod!($
:
3, $
:
1) %
* /
}
| stmt modif
i
er_until expr_value
{
clear_block_exit(p, false);
if ($1
& &
nd_type_p($1, NODE_BEGIN)) {
$$ = NEW_UNTIL(cond(p, $3, &@3), RNODE_BEGIN($1)
- >
nd_body, 0, &@$, &@2, &NULL_LOC);
}
else {
$$ = NEW_UNTIL(cond(p, $3, &@3), $1, 1, &@$, &@2, &NULL_LOC);
}
/ *
% ripper: until_mod!($
:
3, $
:
1) %
* /
}
| stmt modif
i
er_rescue after_rescue stmt
{
p
- >
ctxt.in_rescue = $3.in_rescue;
NODE
*
resq;
YYLTYPE loc = code_loc_gen(&@2, &@4);
resq = NEW_RESBODY(0, 0, remove_begin($4), 0, &loc);
$$ = NEW_RESCUE(remove_begin($1), resq, 0, &@$);
/ *
% ripper: rescue_mod!($
:
1, $
:
4) %
* /
}
| k_END allow_exits '{' compstmt(stmts) '}'
{
if (p
- >
ctxt.in_def) {
rb_warn0("END in method; use at_exit");
}
restore_block_exit(p, $allow_exits);
p
- >
ctxt = $k_END;
{
NODE
*
scope = NEW_SCOPE2(0
/ *
tbl
* /
, 0
/ *
args
* /
, $compstmt
/ *
body
* /
, &@$);
$$ = NEW_POSTEXE(scope, &@$, &@1, &@3, &@5);
}
/ *
% ripper: END!($:compstmt) %
* /
}
| command_asgn
| mlhs '=' lex_ctxt command_call_value
{
$$ = node_assign(p, (NODE *)$1, $4, $3, &@$);
/ *
% ripper: massign!($
:
1, $
:
4) %
* /
}
| asgn(mrhs)
| mlhs '=' lex_ctxt mrhs_arg modif
i
er_rescue
after_rescue stmt[resbody]
{
p
- >
ctxt.in_rescue = $3.in_rescue;
YYLTYPE loc = code_loc_gen(&@modif
i
er_rescue, &@resbody);
$resbody = NEW_RESBODY(0, 0, remove_begin($resbody), 0, &loc);
loc.beg_pos = @mrhs_arg.beg_pos;
$mrhs_arg = NEW_RESCUE($mrhs_arg, $resbody, 0, &loc);
$$ = node_assign(p, (NODE *)$mlhs, $mrhs_arg, $lex_ctxt, &@$);
/ *
% ripper: massign!($
:
1, rescue_mod!($
:
4, $
:
7)) %
* /
}
| mlhs '=' lex_ctxt mrhs_arg
{
$$ = node_assign(p, (NODE *)$1, $4, $3, &@$);
/ *
% ripper: massign!($
:
1, $
:
4) %
* /
}
| expr
| error
{
(void)yynerrs;
$$ = NEW_ERROR(&@$);
}
;
expr : command_call
| expr keyword_and expr
{
$$ = logop(p, idAND, $1, $3, &@2, &@$);
/ *
% ripper: binary!($
:
1, ID2VAL(idAND), $
:
3) %
* /
}
| expr keyword_or expr
{
$$ = logop(p, idOR, $1, $3, &@2, &@$);
/ *
% ripper: binary!($
:
1, ID2VAL(idOR), $
:
3) %
* /
}
| keyword_not '\n'? expr
{
$$ = call_uni_op(p, method_cond(p, $3, &@3), METHOD_NOT, &@1, &@$);
/ *
% ripper: unary!(ID2VAL(idNOT), $
:
3) %
* /
}
| '!' command_call
{
$$ = call_uni_op(p, method_cond(p, $2, &@2), '!', &@1, &@$);
/ *
% ripper: unary!(ID2VAL('\'!\''), $
:
2) %
* /
}
| arg tASSOC
{
value_expr($arg);
}
p_in_kwarg[ctxt] p_pvtbl p_pktbl
p_top_expr_body[body]
{
pop_pktbl(p, $p_pktbl);
pop_pvtbl(p, $p_pvtbl);
p
- >
ctxt.in_kwarg = $ctxt.in_kwarg;
$$ = NEW_CASE3($arg, NEW_IN($body, 0, 0, &@body), &@$, &NULL_LOC, &NULL_LOC);
/ *
% ripper: case!($:arg, in!($:body, Qnil, Qnil)) %
* /
}
| arg keyword_in
{
value_expr($arg);
}
p_in_kwarg[ctxt] p_pvtbl p_pktbl
p_top_expr_body[body]
{
pop_pktbl(p, $p_pktbl);
pop_pvtbl(p, $p_pvtbl);
p
- >
ctxt.in_kwarg = $ctxt.in_kwarg;
$$ = NEW_CASE3($arg, NEW_IN($body, NEW_TRUE(&@body), NEW_FALSE(&@body), &@body), &@$, &NULL_LOC, &NULL_LOC);
/ *
% ripper: case!($:arg, in!($:body, Qnil, Qnil)) %
* /
}
| arg %prec tLBRACE_ARG
;