mirror of
https://github.com/python/cpython.git
synced 2025-09-11 03:07:01 +00:00
Improved __future__ parser; still more to do
Makefile.pre.in: add target future.o Include/compile.h: define PyFutureFeaters and PyNode_Future() add c_future slot to struct compiling Include/symtable.h: add st_future slot to struct symtable Python/future.c: implementation of PyNode_Future() Python/compile.c: use PyNode_Future() for nested_scopes support Python/symtable.c: include compile.h to pick up PyFutureFeatures decl
This commit is contained in:
parent
ed5e8234d7
commit
4db62b1e14
6 changed files with 167 additions and 46 deletions
146
Python/future.c
Normal file
146
Python/future.c
Normal file
|
@ -0,0 +1,146 @@
|
|||
#include "Python.h"
|
||||
#include "node.h"
|
||||
#include "token.h"
|
||||
#include "graminit.h"
|
||||
#include "compile.h"
|
||||
#include "symtable.h"
|
||||
|
||||
#define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined"
|
||||
|
||||
static int
|
||||
future_check_features(PyFutureFeatures *ff, node *n)
|
||||
{
|
||||
int i;
|
||||
char *feature;
|
||||
|
||||
REQ(n, import_stmt); /* must by from __future__ import ... */
|
||||
|
||||
for (i = 3; i < NCH(n); ++i) {
|
||||
feature = STR(CHILD(CHILD(n, i), 0));
|
||||
if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) {
|
||||
ff->ff_nested_scopes = 1;
|
||||
} else {
|
||||
PyErr_Format(PyExc_SyntaxError,
|
||||
UNDEFINED_FUTURE_FEATURE, feature);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Relevant portions of the grammar:
|
||||
|
||||
single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
|
||||
file_input: (NEWLINE | stmt)* ENDMARKER
|
||||
stmt: simple_stmt | compound_stmt
|
||||
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
|
||||
small_stmt: expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | import_stmt | global_stmt | exec_stmt | assert_stmt
|
||||
import_stmt: 'import' dotted_as_name (',' dotted_as_name)* | 'from' dotted_name 'import' ('*' | import_as_name (',' import_as_name)*)
|
||||
import_as_name: NAME [NAME NAME]
|
||||
dotted_as_name: dotted_name [NAME NAME]
|
||||
dotted_name: NAME ('.' NAME)*
|
||||
*/
|
||||
|
||||
/* future_parse() return values:
|
||||
-1 indicates an error occurred, e.g. unknown feature name
|
||||
0 indicates no feature was found
|
||||
1 indicates a feature was found
|
||||
*/
|
||||
|
||||
static int
|
||||
future_parse(PyFutureFeatures *ff, node *n)
|
||||
{
|
||||
int i, r, found;
|
||||
loop:
|
||||
|
||||
/* fprintf(stderr, "future_parse(%d, %d, %s)\n",
|
||||
TYPE(n), NCH(n), (n == NULL) ? "NULL" : STR(n));
|
||||
*/
|
||||
switch (TYPE(n)) {
|
||||
|
||||
case file_input:
|
||||
for (i = 0; i < NCH(n); i++) {
|
||||
node *ch = CHILD(n, i);
|
||||
if (TYPE(ch) == stmt) {
|
||||
n = ch;
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
case simple_stmt:
|
||||
if (NCH(n) == 1) {
|
||||
REQ(CHILD(n, 0), small_stmt);
|
||||
n = CHILD(n, 0);
|
||||
goto loop;
|
||||
}
|
||||
found = 0;
|
||||
for (i = 0; i < NCH(n); ++i)
|
||||
if (TYPE(CHILD(n, i)) == small_stmt) {
|
||||
r = future_parse(ff, CHILD(n, i));
|
||||
if (r < 1) {
|
||||
ff->ff_last_lineno = n->n_lineno;
|
||||
ff->ff_n_simple_stmt = i;
|
||||
return r;
|
||||
} else
|
||||
found++;
|
||||
}
|
||||
if (found)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
|
||||
case stmt:
|
||||
if (TYPE(CHILD(n, 0)) == simple_stmt) {
|
||||
n = CHILD(n, 0);
|
||||
goto loop;
|
||||
} else {
|
||||
REQ(CHILD(n, 0), compound_stmt);
|
||||
ff->ff_last_lineno = n->n_lineno;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case small_stmt:
|
||||
n = CHILD(n, 0);
|
||||
goto loop;
|
||||
|
||||
case import_stmt: {
|
||||
node *name;
|
||||
|
||||
if (STR(CHILD(n, 0))[0] != 'f') { /* from */
|
||||
ff->ff_last_lineno = n->n_lineno;
|
||||
return 0;
|
||||
}
|
||||
name = CHILD(n, 1);
|
||||
if (strcmp(STR(CHILD(name, 0)), "__future__") != 0)
|
||||
return 0;
|
||||
if (future_check_features(ff, n) < 0)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
default:
|
||||
ff->ff_last_lineno = n->n_lineno;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
PyFutureFeatures *
|
||||
PyNode_Future(node *n, char *filename)
|
||||
{
|
||||
PyFutureFeatures *ff;
|
||||
|
||||
ff = (PyFutureFeatures *)PyMem_Malloc(sizeof(PyFutureFeatures));
|
||||
if (ff == NULL)
|
||||
return NULL;
|
||||
ff->ff_last_lineno = 0;
|
||||
ff->ff_n_simple_stmt = -1;
|
||||
ff->ff_nested_scopes = 0;
|
||||
|
||||
if (future_parse(ff, n) < 0) {
|
||||
PyMem_Free((void *)ff);
|
||||
return NULL;
|
||||
}
|
||||
return ff;
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue