diff options
author | Guido van Rossum <guido@python.org> | 2019-01-31 11:40:27 (GMT) |
---|---|---|
committer | Ćukasz Langa <lukasz@langa.pl> | 2019-01-31 11:40:27 (GMT) |
commit | dcfcd146f8e6fc5c2fc16a4c192a0c5f5ca8c53c (patch) | |
tree | 07829c4f286194d0e3d08151a26ef1f3494a849b /Parser/tokenizer.c | |
parent | d97daebfa69b4df95231bcae4123eacad6a48d14 (diff) | |
download | cpython-dcfcd146f8e6fc5c2fc16a4c192a0c5f5ca8c53c.zip cpython-dcfcd146f8e6fc5c2fc16a4c192a0c5f5ca8c53c.tar.gz cpython-dcfcd146f8e6fc5c2fc16a4c192a0c5f5ca8c53c.tar.bz2 |
bpo-35766: Merge typed_ast back into CPython (GH-11645)
Diffstat (limited to 'Parser/tokenizer.c')
-rw-r--r-- | Parser/tokenizer.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index 3e3cf2c..1ded9ad 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -48,6 +48,10 @@ static int tok_nextc(struct tok_state *tok); static void tok_backup(struct tok_state *tok, int c); +/* Spaces in this constant are treated as "zero or more spaces or tabs" when + tokenizing. */ +static const char* type_comment_prefix = "# type: "; + /* Create and initialize a new tok_state structure */ static struct tok_state * @@ -82,6 +86,7 @@ tok_new(void) tok->decoding_readline = NULL; tok->decoding_buffer = NULL; #endif + tok->type_comments = 0; return tok; } @@ -1245,11 +1250,61 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end) /* Set start of current token */ tok->start = tok->cur - 1; - /* Skip comment */ + /* Skip comment, unless it's a type comment */ if (c == '#') { + const char *prefix, *p, *type_start; + while (c != EOF && c != '\n') { c = tok_nextc(tok); } + + if (tok->type_comments) { + p = tok->start; + prefix = type_comment_prefix; + while (*prefix && p < tok->cur) { + if (*prefix == ' ') { + while (*p == ' ' || *p == '\t') { + p++; + } + } else if (*prefix == *p) { + p++; + } else { + break; + } + + prefix++; + } + + /* This is a type comment if we matched all of type_comment_prefix. */ + if (!*prefix) { + int is_type_ignore = 1; + tok_backup(tok, c); /* don't eat the newline or EOF */ + + type_start = p; + + is_type_ignore = tok->cur >= p + 6 && memcmp(p, "ignore", 6) == 0; + p += 6; + while (is_type_ignore && p < tok->cur) { + if (*p == '#') + break; + is_type_ignore = is_type_ignore && (*p == ' ' || *p == '\t'); + p++; + } + + if (is_type_ignore) { + /* If this type ignore is the only thing on the line, consume the newline also. */ + if (blankline) { + tok_nextc(tok); + tok->atbol = 1; + } + return TYPE_IGNORE; + } else { + *p_start = (char *) type_start; /* after type_comment_prefix */ + *p_end = tok->cur; + return TYPE_COMMENT; + } + } + } } /* Check for EOF and errors now */ |