summaryrefslogtreecommitdiffstats
path: root/Parser/tokenizer.c
diff options
context:
space:
mode:
authorGuido 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)
commitdcfcd146f8e6fc5c2fc16a4c192a0c5f5ca8c53c (patch)
tree07829c4f286194d0e3d08151a26ef1f3494a849b /Parser/tokenizer.c
parentd97daebfa69b4df95231bcae4123eacad6a48d14 (diff)
downloadcpython-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.c57
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 */