parse.y: Fix the first location of heredoc identifier

* parse.y (parser_heredoc_identifier):
  Put length of term at the head of rb_strterm_heredoc_struct.term.

* parse.y (rb_parser_set_location_from_strterm_heredoc):
  Use length of term to calculate first_loc.column.

  e.g. The locations of the NODE_DSTR is fixed:

  ```
  a <<STR
  123
  #{:a}
  STR
  ```

  * Before

  ```
  NODE_DSTR (line: 3, code_range: (1,3)-(1,7))
  ```

  * After

  ```
  NODE_DSTR (line: 3, code_range: (1,2)-(1,7))
  ```

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61039 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
yui-knk 2017-12-06 03:09:55 +00:00
parent b7c17ad14d
commit c1bd83cef7
1 changed files with 16 additions and 3 deletions

19
parse.y
View File

@ -6625,7 +6625,7 @@ parser_parse_string(struct parser_params *parser, rb_strterm_literal_t *quote)
static enum yytokentype static enum yytokentype
parser_heredoc_identifier(struct parser_params *parser) parser_heredoc_identifier(struct parser_params *parser)
{ {
int c = nextc(), term, func = 0; int c = nextc(), term, func = 0, term_len = 2; /* length of "<<" */
enum yytokentype token = tSTRING_BEG; enum yytokentype token = tSTRING_BEG;
long len; long len;
int newline = 0; int newline = 0;
@ -6633,24 +6633,31 @@ parser_heredoc_identifier(struct parser_params *parser)
if (c == '-') { if (c == '-') {
c = nextc(); c = nextc();
term_len++;
func = STR_FUNC_INDENT; func = STR_FUNC_INDENT;
} }
else if (c == '~') { else if (c == '~') {
c = nextc(); c = nextc();
term_len++;
func = STR_FUNC_INDENT; func = STR_FUNC_INDENT;
indent = INT_MAX; indent = INT_MAX;
} }
switch (c) { switch (c) {
case '\'': case '\'':
term_len++;
func |= str_squote; goto quoted; func |= str_squote; goto quoted;
case '"': case '"':
term_len++;
func |= str_dquote; goto quoted; func |= str_dquote; goto quoted;
case '`': case '`':
term_len++;
token = tXSTRING_BEG; token = tXSTRING_BEG;
func |= str_xquote; goto quoted; func |= str_xquote; goto quoted;
quoted: quoted:
term_len++;
newtok(); newtok();
tokadd(term_len);
tokadd(func); tokadd(func);
term = c; term = c;
while ((c = nextc()) != -1 && c != term) { while ((c = nextc()) != -1 && c != term) {
@ -6682,6 +6689,7 @@ parser_heredoc_identifier(struct parser_params *parser)
return 0; return 0;
} }
newtok(); newtok();
tokadd(term_len);
tokadd(func |= str_dquote); tokadd(func |= str_dquote);
do { do {
if (tokadd_mbchar(c) == -1) return 0; if (tokadd_mbchar(c) == -1) return 0;
@ -6690,6 +6698,7 @@ parser_heredoc_identifier(struct parser_params *parser)
break; break;
} }
tokenbuf[0] = tokenbuf[0] + toklen() - 2;
tokfix(); tokfix();
dispatch_scan_event(tHEREDOC_BEG); dispatch_scan_event(tHEREDOC_BEG);
len = lex_p - lex_pbeg; len = lex_p - lex_pbeg;
@ -6925,7 +6934,8 @@ parser_here_document(struct parser_params *parser, rb_strterm_heredoc_t *here)
rb_encoding *enc = current_enc; rb_encoding *enc = current_enc;
eos = RSTRING_PTR(here->term); eos = RSTRING_PTR(here->term);
len = RSTRING_LEN(here->term) - 1; len = RSTRING_LEN(here->term) - 2; /* here->term includes term_len and func */
eos++; /* skip term_len */
indent = (func = *eos++) & STR_FUNC_INDENT; indent = (func = *eos++) & STR_FUNC_INDENT;
if ((c = nextc()) == -1) { if ((c = nextc()) == -1) {
@ -9841,8 +9851,11 @@ rb_parser_fatal(struct parser_params *parser, const char *fmt, ...)
void void
rb_parser_set_location_from_strterm_heredoc(struct parser_params *parser, rb_strterm_heredoc_t *here, YYLTYPE *yylloc) rb_parser_set_location_from_strterm_heredoc(struct parser_params *parser, rb_strterm_heredoc_t *here, YYLTYPE *yylloc)
{ {
const char *eos = RSTRING_PTR(here->term);
int term_len = (int)eos[0];
yylloc->first_loc.lineno = (int)here->sourceline; yylloc->first_loc.lineno = (int)here->sourceline;
yylloc->first_loc.column = (int)(here->u3.lastidx - RSTRING_LEN(here->term)); yylloc->first_loc.column = (int)(here->u3.lastidx - term_len);
yylloc->last_loc.lineno = (int)here->sourceline; yylloc->last_loc.lineno = (int)here->sourceline;
yylloc->last_loc.column = (int)(here->u3.lastidx); yylloc->last_loc.column = (int)(here->u3.lastidx);
} }