mirror of
https://github.com/python/cpython
synced 2026-09-29 12:10:30 +03:00
from __future__ import with_statement addon for 'with', mostly written by
Neal.
This commit is contained in:
parent
edc8f1366a
commit
34aa7ba114
16 changed files with 102 additions and 40 deletions
|
|
@ -79,8 +79,8 @@ PyParser_New(grammar *g, int start)
|
|||
if (ps == NULL)
|
||||
return NULL;
|
||||
ps->p_grammar = g;
|
||||
#if 0 /* future keyword */
|
||||
ps->p_generators = 0;
|
||||
#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
|
||||
ps->p_flags = 0;
|
||||
#endif
|
||||
ps->p_tree = PyNode_New(start);
|
||||
if (ps->p_tree == NULL) {
|
||||
|
|
@ -147,10 +147,10 @@ classify(parser_state *ps, int type, char *str)
|
|||
if (l->lb_type == NAME && l->lb_str != NULL &&
|
||||
l->lb_str[0] == s[0] &&
|
||||
strcmp(l->lb_str, s) == 0) {
|
||||
#if 0 /* future keyword */
|
||||
if (!ps->p_generators &&
|
||||
s[0] == 'y' &&
|
||||
strcmp(s, "yield") == 0)
|
||||
#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
|
||||
if (!(ps->p_flags & CO_FUTURE_WITH_STATEMENT) &&
|
||||
s[0] == 'w' &&
|
||||
strcmp(s, "with") == 0)
|
||||
break; /* not a keyword */
|
||||
#endif
|
||||
D(printf("It's a keyword\n"));
|
||||
|
|
@ -174,7 +174,7 @@ classify(parser_state *ps, int type, char *str)
|
|||
return -1;
|
||||
}
|
||||
|
||||
#if 0 /* future keyword */
|
||||
#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
|
||||
static void
|
||||
future_hack(parser_state *ps)
|
||||
{
|
||||
|
|
@ -182,16 +182,27 @@ future_hack(parser_state *ps)
|
|||
node *ch;
|
||||
int i;
|
||||
|
||||
if (strcmp(STR(CHILD(n, 0)), "from") != 0)
|
||||
/* from __future__ import ..., must have at least 4 children */
|
||||
n = CHILD(n, 0);
|
||||
if (NCH(n) < 4)
|
||||
return;
|
||||
ch = CHILD(n, 0);
|
||||
if (STR(ch) == NULL || strcmp(STR(ch), "from") != 0)
|
||||
return;
|
||||
ch = CHILD(n, 1);
|
||||
if (strcmp(STR(CHILD(ch, 0)), "__future__") != 0)
|
||||
if (NCH(ch) == 1 && STR(CHILD(ch, 0)) &&
|
||||
strcmp(STR(CHILD(ch, 0)), "__future__") != 0)
|
||||
return;
|
||||
for (i = 3; i < NCH(n); i += 2) {
|
||||
/* XXX: assume we don't have parentheses in import:
|
||||
from __future__ import (x, y, z)
|
||||
*/
|
||||
ch = CHILD(n, i);
|
||||
if (NCH(ch) == 1)
|
||||
ch = CHILD(ch, 0);
|
||||
if (NCH(ch) >= 1 && TYPE(CHILD(ch, 0)) == NAME &&
|
||||
strcmp(STR(CHILD(ch, 0)), "generators") == 0) {
|
||||
ps->p_generators = 1;
|
||||
strcmp(STR(CHILD(ch, 0)), "with_statement") == 0) {
|
||||
ps->p_flags |= CO_FUTURE_WITH_STATEMENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -255,7 +266,7 @@ PyParser_AddToken(register parser_state *ps, register int type, char *str,
|
|||
"Direct pop.\n",
|
||||
d->d_name,
|
||||
ps->p_stack.s_top->s_state));
|
||||
#if 0 /* future keyword */
|
||||
#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
|
||||
if (d->d_name[0] == 'i' &&
|
||||
strcmp(d->d_name,
|
||||
"import_stmt") == 0)
|
||||
|
|
@ -273,7 +284,7 @@ PyParser_AddToken(register parser_state *ps, register int type, char *str,
|
|||
}
|
||||
|
||||
if (s->s_accept) {
|
||||
#if 0 /* future keyword */
|
||||
#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
|
||||
if (d->d_name[0] == 'i' &&
|
||||
strcmp(d->d_name, "import_stmt") == 0)
|
||||
future_hack(ps);
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ typedef struct {
|
|||
stack p_stack; /* Stack of parser states */
|
||||
grammar *p_grammar; /* Grammar to use */
|
||||
node *p_tree; /* Top of parse tree */
|
||||
#if 0 /* future keyword */
|
||||
int p_generators; /* 1 if yield is a keyword */
|
||||
#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
|
||||
unsigned long p_flags; /* see co_flags in Include/code.h */
|
||||
#endif
|
||||
} parser_state;
|
||||
|
||||
|
|
|
|||
|
|
@ -92,10 +92,19 @@ PyParser_ParseFileFlags(FILE *fp, const char *filename, grammar *g, int start,
|
|||
/* Parse input coming from the given tokenizer structure.
|
||||
Return error code. */
|
||||
|
||||
#if 0 /* future keyword */
|
||||
static char yield_msg[] =
|
||||
"%s:%d: Warning: 'yield' will become a reserved keyword in the future\n";
|
||||
#endif
|
||||
static char with_msg[] =
|
||||
"%s:%d: Warning: 'with' will become a reserved keyword in Python 2.6\n";
|
||||
|
||||
static char as_msg[] =
|
||||
"%s:%d: Warning: 'as' will become a reserved keyword in Python 2.6\n";
|
||||
|
||||
static void
|
||||
warn(const char *msg, const char *filename, int lineno)
|
||||
{
|
||||
if (filename == NULL)
|
||||
filename = "<string>";
|
||||
PySys_WriteStderr(msg, filename, lineno);
|
||||
}
|
||||
|
||||
static node *
|
||||
parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
|
||||
|
|
@ -103,7 +112,7 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
|
|||
{
|
||||
parser_state *ps;
|
||||
node *n;
|
||||
int started = 0;
|
||||
int started = 0, handling_import = 0, handling_with = 0;
|
||||
|
||||
if ((ps = PyParser_New(g, start)) == NULL) {
|
||||
fprintf(stderr, "no mem for new parser\n");
|
||||
|
|
@ -111,9 +120,9 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
|
|||
PyTokenizer_Free(tok);
|
||||
return NULL;
|
||||
}
|
||||
#if 0 /* future keyword */
|
||||
if (flags & PyPARSE_YIELD_IS_KEYWORD)
|
||||
ps->p_generators = 1;
|
||||
#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
|
||||
if (flags & PyPARSE_WITH_IS_KEYWORD)
|
||||
ps->p_flags |= CO_FUTURE_WITH_STATEMENT;
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
|
|
@ -129,6 +138,7 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
|
|||
}
|
||||
if (type == ENDMARKER && started) {
|
||||
type = NEWLINE; /* Add an extra newline */
|
||||
handling_with = handling_import = 0;
|
||||
started = 0;
|
||||
/* Add the right number of dedent tokens,
|
||||
except if a certain flag is given --
|
||||
|
|
@ -153,14 +163,27 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
|
|||
strncpy(str, a, len);
|
||||
str[len] = '\0';
|
||||
|
||||
#if 0 /* future keyword */
|
||||
/* Warn about yield as NAME */
|
||||
if (type == NAME && !ps->p_generators &&
|
||||
len == 5 && str[0] == 'y' && strcmp(str, "yield") == 0)
|
||||
PySys_WriteStderr(yield_msg,
|
||||
err_ret->filename==NULL ?
|
||||
"<string>" : err_ret->filename,
|
||||
tok->lineno);
|
||||
#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
|
||||
/* This is only necessary to support the "as" warning, but
|
||||
we don't want to warn about "as" in import statements. */
|
||||
if (type == NAME &&
|
||||
len == 6 && str[0] == 'i' && strcmp(str, "import") == 0)
|
||||
handling_import = 1;
|
||||
|
||||
/* Warn about with as NAME */
|
||||
if (type == NAME &&
|
||||
!(ps->p_flags & CO_FUTURE_WITH_STATEMENT)) {
|
||||
if (len == 4 && str[0] == 'w' && strcmp(str, "with") == 0)
|
||||
warn(with_msg, err_ret->filename, tok->lineno);
|
||||
else if (!(handling_import || handling_with) &&
|
||||
len == 2 &&
|
||||
str[0] == 'a' && strcmp(str, "as") == 0)
|
||||
warn(as_msg, err_ret->filename, tok->lineno);
|
||||
}
|
||||
else if (type == NAME &&
|
||||
(ps->p_flags & CO_FUTURE_WITH_STATEMENT) &&
|
||||
len == 4 && str[0] == 'w' && strcmp(str, "with") == 0)
|
||||
handling_with = 1;
|
||||
#endif
|
||||
|
||||
if ((err_ret->error =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue