* parse.y (parse_gvar): extract from parser_yylex().

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46847 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2014-07-17 04:30:31 +00:00
Родитель d41b3e8874
Коммит 5faf8f07e9
1 изменённых файлов: 96 добавлений и 85 удалений

181
parse.y
Просмотреть файл

@ -7367,6 +7367,99 @@ parse_percent(struct parser_params *parser, const int space_seen, const enum lex
return '%';
}
static int
parse_gvar(struct parser_params *parser, const enum lex_state_e last_state)
{
register int c;
lex_state = EXPR_END;
newtok();
c = nextc();
switch (c) {
case '_': /* $_: last read line string */
c = nextc();
if (parser_is_identchar()) {
tokadd('$');
tokadd('_');
break;
}
pushback(c);
c = '_';
/* fall through */
case '~': /* $~: match-data */
case '*': /* $*: argv */
case '$': /* $$: pid */
case '?': /* $?: last status */
case '!': /* $!: error string */
case '@': /* $@: error position */
case '/': /* $/: input record separator */
case '\\': /* $\: output record separator */
case ';': /* $;: field separator */
case ',': /* $,: output field separator */
case '.': /* $.: last read line number */
case '=': /* $=: ignorecase */
case ':': /* $:: load path */
case '<': /* $<: reading filename */
case '>': /* $>: default output handle */
case '\"': /* $": already loaded files */
tokadd('$');
tokadd(c);
goto gvar;
case '-':
tokadd('$');
tokadd(c);
c = nextc();
if (parser_is_identchar()) {
if (tokadd_mbchar(c) == -1) return 0;
}
else {
pushback(c);
pushback('-');
return '$';
}
gvar:
set_yylval_name(intern_cstr_without_pindown(tok(), tokidx, current_enc));
return tGVAR;
case '&': /* $&: last match */
case '`': /* $`: string before last match */
case '\'': /* $': string after last match */
case '+': /* $+: string matches last paren. */
if (IS_lex_state_for(last_state, EXPR_FNAME)) {
tokadd('$');
tokadd(c);
goto gvar;
}
set_yylval_node(NEW_BACK_REF(c));
return tBACK_REF;
case '1': case '2': case '3':
case '4': case '5': case '6':
case '7': case '8': case '9':
tokadd('$');
do {
tokadd(c);
c = nextc();
} while (c != -1 && ISDIGIT(c));
pushback(c);
if (IS_lex_state_for(last_state, EXPR_FNAME)) goto gvar;
tokfix();
set_yylval_node(NEW_NTH_REF(atoi(tok()+1)));
return tNTH_REF;
default:
if (!parser_is_identchar()) {
pushback(c);
compile_error(PARSER_ARG "`$%c' is not allowed as a global variable name", c);
return 0;
}
case '0':
tokadd('$');
}
return -c;
}
static int
parser_yylex(struct parser_params *parser)
{
@ -7986,91 +8079,9 @@ parser_yylex(struct parser_params *parser)
return parse_percent(parser, space_seen, last_state);
case '$':
lex_state = EXPR_END;
newtok();
c = nextc();
switch (c) {
case '_': /* $_: last read line string */
c = nextc();
if (parser_is_identchar()) {
tokadd('$');
tokadd('_');
break;
}
pushback(c);
c = '_';
/* fall through */
case '~': /* $~: match-data */
case '*': /* $*: argv */
case '$': /* $$: pid */
case '?': /* $?: last status */
case '!': /* $!: error string */
case '@': /* $@: error position */
case '/': /* $/: input record separator */
case '\\': /* $\: output record separator */
case ';': /* $;: field separator */
case ',': /* $,: output field separator */
case '.': /* $.: last read line number */
case '=': /* $=: ignorecase */
case ':': /* $:: load path */
case '<': /* $<: reading filename */
case '>': /* $>: default output handle */
case '\"': /* $": already loaded files */
tokadd('$');
tokadd(c);
goto gvar;
case '-':
tokadd('$');
tokadd(c);
c = nextc();
if (parser_is_identchar()) {
if (tokadd_mbchar(c) == -1) return 0;
}
else {
pushback(c);
pushback('-');
return '$';
}
gvar:
set_yylval_name(intern_cstr_without_pindown(tok(), tokidx, current_enc));
return tGVAR;
case '&': /* $&: last match */
case '`': /* $`: string before last match */
case '\'': /* $': string after last match */
case '+': /* $+: string matches last paren. */
if (IS_lex_state_for(last_state, EXPR_FNAME)) {
tokadd('$');
tokadd(c);
goto gvar;
}
set_yylval_node(NEW_BACK_REF(c));
return tBACK_REF;
case '1': case '2': case '3':
case '4': case '5': case '6':
case '7': case '8': case '9':
tokadd('$');
do {
tokadd(c);
c = nextc();
} while (c != -1 && ISDIGIT(c));
pushback(c);
if (IS_lex_state_for(last_state, EXPR_FNAME)) goto gvar;
tokfix();
set_yylval_node(NEW_NTH_REF(atoi(tok()+1)));
return tNTH_REF;
default:
if (!parser_is_identchar()) {
pushback(c);
compile_error(PARSER_ARG "`$%c' is not allowed as a global variable name", c);
return 0;
}
case '0':
tokadd('$');
}
c = parse_gvar(parser, last_state);
if (c >= 0) return c;
c = -c;
break;
case '@':