summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-07-17 04:30:31 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-07-17 04:30:31 +0000
commit5faf8f07e9ec21758b374473d044c8465c231c29 (patch)
treeaf72c9dff57b123997be50c1ec571cdd1b40a8d0 /parse.y
parentd41b3e8874a73f2386bd48e2d8a11928b1995fb1 (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.y181
1 files changed, 96 insertions, 85 deletions
diff --git a/parse.y b/parse.y
index 3f27fe9c49..ce6c721c40 100644
--- a/parse.y
+++ b/parse.y
@@ -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 '@':