1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

parse.y: bit field lex_state

* parse.y (enum lex_state_e): [EXPERIMENTAL] lex_state as bit field /
  IS_lex_state() macro.  based on the patch by Dave B in
  [ruby-core:23503].  [Feature #1493]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37338 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2012-10-27 01:07:59 +00:00
parent 854c5ec470
commit 197e7b812c
2 changed files with 78 additions and 102 deletions

View file

@ -1,3 +1,9 @@
Sat Oct 27 10:07:57 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* parse.y (enum lex_state_e): [EXPERIMENTAL] lex_state as bit field /
IS_lex_state() macro. based on the patch by Dave B in
[ruby-core:23503]. [Feature #1493]
Sat Oct 27 10:05:03 2012 Nobuyoshi Nakada <nobu@ruby-lang.org> Sat Oct 27 10:05:03 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* include/ruby/win32.h (fstat): use _fstati64() instead of fstati64() * include/ruby/win32.h (fstat): use _fstati64() instead of fstati64()

172
parse.y
View file

@ -63,20 +63,39 @@ static ID register_symid_str(ID, VALUE);
((id)&ID_SCOPE_MASK) == ID_INSTANCE || \ ((id)&ID_SCOPE_MASK) == ID_INSTANCE || \
((id)&ID_SCOPE_MASK) == ID_CLASS)) ((id)&ID_SCOPE_MASK) == ID_CLASS))
enum lex_state_e { enum lex_state_bits {
EXPR_BEG, /* ignore newline, +/- is a sign. */ EXPR_BEG_bit, /* ignore newline, +/- is a sign. */
EXPR_END, /* newline significant, +/- is an operator. */ EXPR_END_bit, /* newline significant, +/- is an operator. */
EXPR_ENDARG, /* ditto, and unbound braces. */ EXPR_ENDARG_bit, /* ditto, and unbound braces. */
EXPR_ENDFN, /* ditto, and unbound braces. */ EXPR_ENDFN_bit, /* ditto, and unbound braces. */
EXPR_ARG, /* newline significant, +/- is an operator. */ EXPR_ARG_bit, /* newline significant, +/- is an operator. */
EXPR_CMDARG, /* newline significant, +/- is an operator. */ EXPR_CMDARG_bit, /* newline significant, +/- is an operator. */
EXPR_MID, /* newline significant, +/- is an operator. */ EXPR_MID_bit, /* newline significant, +/- is an operator. */
EXPR_FNAME, /* ignore newline, no reserved words. */ EXPR_FNAME_bit, /* ignore newline, no reserved words. */
EXPR_DOT, /* right after `.' or `::', no reserved words. */ EXPR_DOT_bit, /* right after `.' or `::', no reserved words. */
EXPR_CLASS, /* immediate after `class', no here document. */ EXPR_CLASS_bit, /* immediate after `class', no here document. */
EXPR_VALUE, /* alike EXPR_BEG but label is disallowed. */ EXPR_VALUE_bit, /* alike EXPR_BEG but label is disallowed. */
EXPR_MAX_STATE EXPR_MAX_STATE
}; };
/* examine combinations */
enum lex_state_e {
#define DEF_EXPR(n) EXPR_##n = (1 << EXPR_##n##_bit)
DEF_EXPR(BEG),
DEF_EXPR(END),
DEF_EXPR(ENDARG),
DEF_EXPR(ENDFN),
DEF_EXPR(ARG),
DEF_EXPR(CMDARG),
DEF_EXPR(MID),
DEF_EXPR(FNAME),
DEF_EXPR(DOT),
DEF_EXPR(CLASS),
DEF_EXPR(VALUE),
EXPR_BEG_ANY = (EXPR_BEG | EXPR_VALUE | EXPR_MID | EXPR_CLASS),
EXPR_ARG_ANY = (EXPR_ARG | EXPR_CMDARG),
EXPR_END_ANY = (EXPR_END | EXPR_ENDARG | EXPR_ENDFN)
};
#define IS_lex_state(ls) (lex_state & ( ls ))
#if PARSER_DEBUG #if PARSER_DEBUG
static const char *lex_state_name(enum lex_state_e state); static const char *lex_state_name(enum lex_state_e state);
@ -6705,12 +6724,13 @@ parser_prepare(struct parser_params *parser)
parser->enc = rb_enc_get(lex_lastline); parser->enc = rb_enc_get(lex_lastline);
} }
#define IS_ARG() (lex_state == EXPR_ARG || lex_state == EXPR_CMDARG) #define IS_ARG() IS_lex_state(EXPR_ARG_ANY)
#define IS_END() (lex_state == EXPR_END || lex_state == EXPR_ENDARG || lex_state == EXPR_ENDFN) #define IS_END() IS_lex_state(EXPR_END_ANY)
#define IS_BEG() (lex_state == EXPR_BEG || lex_state == EXPR_MID || lex_state == EXPR_VALUE || lex_state == EXPR_CLASS) #define IS_BEG() IS_lex_state(EXPR_BEG_ANY)
#define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c)) #define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
#define IS_LABEL_POSSIBLE() ((lex_state == EXPR_BEG && !cmd_state) || IS_ARG()) #define IS_LABEL_POSSIBLE() ((IS_lex_state(EXPR_BEG) && !cmd_state) || IS_ARG())
#define IS_LABEL_SUFFIX(n) (peek_n(':',(n)) && !peek_n(':', (n)+1)) #define IS_LABEL_SUFFIX(n) (peek_n(':',(n)) && !peek_n(':', (n)+1))
#define IS_AFTER_OPERATOR() IS_lex_state(EXPR_FNAME | EXPR_DOT)
#ifndef RIPPER #ifndef RIPPER
#define ambiguous_operator(op, syn) ( \ #define ambiguous_operator(op, syn) ( \
@ -6803,12 +6823,7 @@ parser_yylex(struct parser_params *parser)
#endif #endif
/* fall through */ /* fall through */
case '\n': case '\n':
switch (lex_state) { if (IS_lex_state(EXPR_BEG | EXPR_VALUE | EXPR_CLASS | EXPR_FNAME | EXPR_DOT)) {
case EXPR_BEG:
case EXPR_FNAME:
case EXPR_DOT:
case EXPR_CLASS:
case EXPR_VALUE:
#ifdef RIPPER #ifdef RIPPER
if (!fallthru) { if (!fallthru) {
ripper_dispatch_scan_event(parser, tIGNORED_NL); ripper_dispatch_scan_event(parser, tIGNORED_NL);
@ -6816,8 +6831,6 @@ parser_yylex(struct parser_params *parser)
fallthru = FALSE; fallthru = FALSE;
#endif #endif
goto retry; goto retry;
default:
break;
} }
while ((c = nextc())) { while ((c = nextc())) {
switch (c) { switch (c) {
@ -6889,17 +6902,12 @@ parser_yylex(struct parser_params *parser)
c = '*'; c = '*';
} }
} }
switch (lex_state) { lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
case EXPR_FNAME: case EXPR_DOT:
lex_state = EXPR_ARG; break;
default:
lex_state = EXPR_BEG; break;
}
return c; return c;
case '!': case '!':
c = nextc(); c = nextc();
if (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) { if (IS_AFTER_OPERATOR()) {
lex_state = EXPR_ARG; lex_state = EXPR_ARG;
if (c == '@') { if (c == '@') {
return '!'; return '!';
@ -6954,12 +6962,7 @@ parser_yylex(struct parser_params *parser)
} }
} }
switch (lex_state) { lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
case EXPR_FNAME: case EXPR_DOT:
lex_state = EXPR_ARG; break;
default:
lex_state = EXPR_BEG; break;
}
if ((c = nextc()) == '=') { if ((c = nextc()) == '=') {
if ((c = nextc()) == '=') { if ((c = nextc()) == '=') {
return tEQQ; return tEQQ;
@ -6980,20 +6983,19 @@ parser_yylex(struct parser_params *parser)
last_state = lex_state; last_state = lex_state;
c = nextc(); c = nextc();
if (c == '<' && if (c == '<' &&
lex_state != EXPR_DOT && !IS_lex_state(EXPR_DOT | EXPR_CLASS) &&
lex_state != EXPR_CLASS &&
!IS_END() && !IS_END() &&
(!IS_ARG() || space_seen)) { (!IS_ARG() || space_seen)) {
int token = heredoc_identifier(); int token = heredoc_identifier();
if (token) return token; if (token) return token;
} }
switch (lex_state) { if (IS_AFTER_OPERATOR()) {
case EXPR_FNAME: case EXPR_DOT: lex_state = EXPR_ARG;
lex_state = EXPR_ARG; break; }
case EXPR_CLASS: else {
if (IS_lex_state(EXPR_CLASS))
command_start = TRUE; command_start = TRUE;
default: lex_state = EXPR_BEG;
lex_state = EXPR_BEG; break;
} }
if (c == '=') { if (c == '=') {
if ((c = nextc()) == '>') { if ((c = nextc()) == '>') {
@ -7016,12 +7018,7 @@ parser_yylex(struct parser_params *parser)
return '<'; return '<';
case '>': case '>':
switch (lex_state) { lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
case EXPR_FNAME: case EXPR_DOT:
lex_state = EXPR_ARG; break;
default:
lex_state = EXPR_BEG; break;
}
if ((c = nextc()) == '=') { if ((c = nextc()) == '=') {
return tGEQ; return tGEQ;
} }
@ -7042,11 +7039,11 @@ parser_yylex(struct parser_params *parser)
return tSTRING_BEG; return tSTRING_BEG;
case '`': case '`':
if (lex_state == EXPR_FNAME) { if (IS_lex_state(EXPR_FNAME)) {
lex_state = EXPR_ENDFN; lex_state = EXPR_ENDFN;
return c; return c;
} }
if (lex_state == EXPR_DOT) { if (IS_lex_state(EXPR_DOT)) {
if (cmd_state) if (cmd_state)
lex_state = EXPR_CMDARG; lex_state = EXPR_CMDARG;
else else
@ -7167,12 +7164,7 @@ parser_yylex(struct parser_params *parser)
warn_balanced("&", "argument prefix"); warn_balanced("&", "argument prefix");
c = '&'; c = '&';
} }
switch (lex_state) { lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
case EXPR_FNAME: case EXPR_DOT:
lex_state = EXPR_ARG; break;
default:
lex_state = EXPR_BEG;
}
return c; return c;
case '|': case '|':
@ -7191,18 +7183,13 @@ parser_yylex(struct parser_params *parser)
lex_state = EXPR_BEG; lex_state = EXPR_BEG;
return tOP_ASGN; return tOP_ASGN;
} }
if (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) { lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
lex_state = EXPR_ARG;
}
else {
lex_state = EXPR_BEG;
}
pushback(c); pushback(c);
return '|'; return '|';
case '+': case '+':
c = nextc(); c = nextc();
if (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) { if (IS_AFTER_OPERATOR()) {
lex_state = EXPR_ARG; lex_state = EXPR_ARG;
if (c == '@') { if (c == '@') {
return tUPLUS; return tUPLUS;
@ -7231,7 +7218,7 @@ parser_yylex(struct parser_params *parser)
case '-': case '-':
c = nextc(); c = nextc();
if (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) { if (IS_AFTER_OPERATOR()) {
lex_state = EXPR_ARG; lex_state = EXPR_ARG;
if (c == '@') { if (c == '@') {
return tUMINUS; return tUMINUS;
@ -7516,7 +7503,7 @@ parser_yylex(struct parser_params *parser)
case ':': case ':':
c = nextc(); c = nextc();
if (c == ':') { if (c == ':') {
if (IS_BEG() || lex_state == EXPR_CLASS || IS_SPCARG(-1)) { if (IS_BEG() || IS_lex_state(EXPR_CLASS) || IS_SPCARG(-1)) {
lex_state = EXPR_BEG; lex_state = EXPR_BEG;
return tCOLON3; return tCOLON3;
} }
@ -7544,7 +7531,7 @@ parser_yylex(struct parser_params *parser)
return tSYMBEG; return tSYMBEG;
case '/': case '/':
if (IS_BEG()) { if (IS_lex_state(EXPR_BEG_ANY)) {
lex_strterm = NEW_STRTERM(str_regexp, '/', 0); lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
return tREGEXP_BEG; return tREGEXP_BEG;
} }
@ -7559,12 +7546,7 @@ parser_yylex(struct parser_params *parser)
lex_strterm = NEW_STRTERM(str_regexp, '/', 0); lex_strterm = NEW_STRTERM(str_regexp, '/', 0);
return tREGEXP_BEG; return tREGEXP_BEG;
} }
switch (lex_state) { lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
case EXPR_FNAME: case EXPR_DOT:
lex_state = EXPR_ARG; break;
default:
lex_state = EXPR_BEG; break;
}
warn_balanced("/", "regexp literal"); warn_balanced("/", "regexp literal");
return '/'; return '/';
@ -7574,12 +7556,7 @@ parser_yylex(struct parser_params *parser)
lex_state = EXPR_BEG; lex_state = EXPR_BEG;
return tOP_ASGN; return tOP_ASGN;
} }
switch (lex_state) { lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
case EXPR_FNAME: case EXPR_DOT:
lex_state = EXPR_ARG; break;
default:
lex_state = EXPR_BEG; break;
}
pushback(c); pushback(c);
return '^'; return '^';
@ -7593,7 +7570,7 @@ parser_yylex(struct parser_params *parser)
return ','; return ',';
case '~': case '~':
if (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) { if (IS_AFTER_OPERATOR()) {
if ((c = nextc()) != '@') { if ((c = nextc()) != '@') {
pushback(c); pushback(c);
} }
@ -7619,7 +7596,7 @@ parser_yylex(struct parser_params *parser)
case '[': case '[':
paren_nest++; paren_nest++;
if (lex_state == EXPR_FNAME || lex_state == EXPR_DOT) { if (IS_AFTER_OPERATOR()) {
lex_state = EXPR_ARG; lex_state = EXPR_ARG;
if ((c = nextc()) == ']') { if ((c = nextc()) == ']') {
if ((c = nextc()) == '=') { if ((c = nextc()) == '=') {
@ -7652,9 +7629,9 @@ parser_yylex(struct parser_params *parser)
CMDARG_PUSH(0); CMDARG_PUSH(0);
return tLAMBEG; return tLAMBEG;
} }
if (IS_ARG() || lex_state == EXPR_END || lex_state == EXPR_ENDFN) if (IS_ARG() || IS_lex_state(EXPR_END | EXPR_ENDFN))
c = '{'; /* block (primary) */ c = '{'; /* block (primary) */
else if (lex_state == EXPR_ENDARG) else if (IS_lex_state(EXPR_ENDARG))
c = tLBRACE_ARG; /* block (expr) */ c = tLBRACE_ARG; /* block (expr) */
else else
c = tLBRACE; /* hash */ c = tLBRACE; /* hash */
@ -7677,7 +7654,7 @@ parser_yylex(struct parser_params *parser)
return '\\'; return '\\';
case '%': case '%':
if (IS_BEG()) { if (IS_lex_state(EXPR_BEG_ANY)) {
int term; int term;
int paren; int paren;
@ -7764,12 +7741,7 @@ parser_yylex(struct parser_params *parser)
if (IS_SPCARG(c)) { if (IS_SPCARG(c)) {
goto quotation; goto quotation;
} }
switch (lex_state) { lex_state = IS_AFTER_OPERATOR() ? EXPR_ARG : EXPR_BEG;
case EXPR_FNAME: case EXPR_DOT:
lex_state = EXPR_ARG; break;
default:
lex_state = EXPR_BEG; break;
}
pushback(c); pushback(c);
warn_balanced("%%", "string literal"); warn_balanced("%%", "string literal");
return '%'; return '%';
@ -7952,7 +7924,7 @@ parser_yylex(struct parser_params *parser)
result = tFID; result = tFID;
} }
else { else {
if (lex_state == EXPR_FNAME) { if (IS_lex_state(EXPR_FNAME)) {
if ((c = nextc()) == '=' && !peek('~') && !peek('>') && if ((c = nextc()) == '=' && !peek('~') && !peek('>') &&
(!peek('=') || (peek_n('>', 1)))) { (!peek('=') || (peek_n('>', 1)))) {
result = tIDENTIFIER; result = tIDENTIFIER;
@ -7979,7 +7951,7 @@ parser_yylex(struct parser_params *parser)
return tLABEL; return tLABEL;
} }
} }
if (mb == ENC_CODERANGE_7BIT && lex_state != EXPR_DOT) { if (mb == ENC_CODERANGE_7BIT && !IS_lex_state(EXPR_DOT)) {
const struct kwtable *kw; const struct kwtable *kw;
/* See if it is a reserved word. */ /* See if it is a reserved word. */
@ -8003,11 +7975,11 @@ parser_yylex(struct parser_params *parser)
if (COND_P()) return keyword_do_cond; if (COND_P()) return keyword_do_cond;
if (CMDARG_P() && state != EXPR_CMDARG) if (CMDARG_P() && state != EXPR_CMDARG)
return keyword_do_block; return keyword_do_block;
if (state == EXPR_ENDARG || state == EXPR_BEG) if (state & (EXPR_BEG | EXPR_ENDARG))
return keyword_do_block; return keyword_do_block;
return keyword_do; return keyword_do;
} }
if (state == EXPR_BEG || state == EXPR_VALUE) if (state & (EXPR_BEG | EXPR_VALUE))
return kw->id[0]; return kw->id[0];
else { else {
if (kw->id[0] != kw->id[1]) if (kw->id[0] != kw->id[1])
@ -8017,9 +7989,7 @@ parser_yylex(struct parser_params *parser)
} }
} }
if (IS_BEG() || if (IS_lex_state(EXPR_BEG_ANY | EXPR_ARG_ANY | EXPR_DOT)) {
lex_state == EXPR_DOT ||
IS_ARG()) {
if (cmd_state) { if (cmd_state) {
lex_state = EXPR_CMDARG; lex_state = EXPR_CMDARG;
} }
@ -8463,8 +8433,8 @@ lex_state_name(enum lex_state_e state)
"EXPR_VALUE", "EXPR_VALUE",
}; };
if ((unsigned)state < EXPR_MAX_STATE) if ((unsigned)state & ~(~0u << EXPR_MAX_STATE))
return names[state]; return names[ffs(state)];
return NULL; return NULL;
} }
#endif #endif