diff options
author | yui-knk <yui-knk@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-06-10 06:22:15 +0000 |
---|---|---|
committer | yui-knk <yui-knk@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-06-10 06:22:15 +0000 |
commit | 744b0bdb7b9d87158491099fa55719f027c7140b (patch) | |
tree | d5c5b3f1eb9806765a2117f0d885b728c760bc29 | |
parent | 5e9ea3c75fdda92c2761a3ed463357272812c5c5 (diff) | |
download | ruby-744b0bdb7b9d87158491099fa55719f027c7140b.tar.gz |
parse.y: Fix locations of none and mid-rule actions
When an empty rule or a mid-rule action is reduced,
`YYLLOC_DEFAULT` is called with the third parameter to be zero.
If we use `RUBY_SET_YYLLOC_OF_NONE` to set their locations,
sometimes the end position of NODE indicates a blank.
For example, `a.b ;` generates `NODE_CALL (line: 1, location: (1,0)-(1,4))*`,
whose end position indicates a blank.
This is because of the following reasons:
* `NODE_CALL` is created when `primary_value call_op operation2 opt_paren_args` is
reduced to `method_call`.
* `opt_paren_args` is `none`.
* `yylex` is called and `lex.pbeg` moves before `none` is reduced, so
the beginning position of `none` does not match with the end position of `operation2`.
To fix locations, use `YYRHSLOC(Rhs, 0)` in `YYLLOC_DEFAULT`
(0 "refers to the symbol just before the reduction").
By this change, the bottom of the location stack would be referenced,
so initialize the bottom with `RUBY_SET_YYLLOC_OF_NONE` in `%initial-action`.
Ref: https://www.gnu.org/software/bison/manual/html_node/Location-Default-Action.html#Location-Default-Action
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63623 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | parse.y | 9 |
1 files changed, 8 insertions, 1 deletions
@@ -59,7 +59,10 @@ (Current).end_pos = YYRHSLOC(Rhs, N).end_pos; \ } \ else \ - RUBY_SET_YYLLOC_OF_NONE(Current); \ + { \ + (Current).beg_pos = YYRHSLOC(Rhs, 0).end_pos; \ + (Current).end_pos = YYRHSLOC(Rhs, 0).end_pos; \ + } \ while (0) #define RUBY_SET_YYLLOC_FROM_STRTERM_HEREDOC(Current) \ @@ -747,6 +750,10 @@ static void token_info_warn(struct parser_params *p, const char *token, token_in %pure-parser %lex-param {struct parser_params *p} %parse-param {struct parser_params *p} +%initial-action +{ + RUBY_SET_YYLLOC_OF_NONE(@$); +}; %union { VALUE val; |