diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-07-17 04:30:31 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-07-17 04:30:31 +0000 |
commit | 5faf8f07e9ec21758b374473d044c8465c231c29 (patch) | |
tree | af72c9dff57b123997be50c1ec571cdd1b40a8d0 /parse.y | |
parent | d41b3e8874a73f2386bd48e2d8a11928b1995fb1 (diff) |
parse.y: parse_gvar
* 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
Diffstat (limited to 'parse.y')
-rw-r--r-- | parse.y | 181 |
1 files changed, 96 insertions, 85 deletions
@@ -7368,6 +7368,99 @@ parse_percent(struct parser_params *parser, const int space_seen, const enum lex } 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) { register int c; @@ -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 '@': |