annotate Parser/parser.c @ 49955:878d40468c4e legacy-trunk

Issue #4384: Added logging integration with warnings module using captureWarnings(). This change includes a NullHandler which does nothing; it will be of use to library developers who want to avoid the "No handlers could be found for logger XXX" message which can appear if the library user doesn't configure logging.
author Vinay Sajip <vinay_sajip@yahoo.co.uk>
date Wed, 03 Dec 2008 23:22:58 +0000
parents e80d9e6e26bb
children fd25030223b0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
853b736a6a9e Added copyright notice.
Guido van Rossum <guido@python.org>
parents: 86
diff changeset
1
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2 /* Parser implementation */
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
4 /* For a description, see the comments at end of this file */
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
5
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
6 /* XXX To do: error recovery */
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
7
21181
944d6e02f359 The parser doesn't need its own implementation of assert, and having its
Tim Peters <tim.peters@gmail.com>
parents: 18739
diff changeset
8 #include "Python.h"
86
a6934380c6e7 "Compiling" version
Guido van Rossum <guido@python.org>
parents: 79
diff changeset
9 #include "pgenheaders.h"
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
10 #include "token.h"
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
11 #include "grammar.h"
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
12 #include "node.h"
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
13 #include "parser.h"
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
14 #include "errcode.h"
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
15
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
16
4839
4567e158d20c Rename DEBUG macro to Py_DEBUG
Guido van Rossum <guido@python.org>
parents: 4503
diff changeset
17 #ifdef Py_DEBUG
5379
1c9a84e0981d Another directory quickly renamed.
Guido van Rossum <guido@python.org>
parents: 4839
diff changeset
18 extern int Py_DebugFlag;
1c9a84e0981d Another directory quickly renamed.
Guido van Rossum <guido@python.org>
parents: 4839
diff changeset
19 #define D(x) if (!Py_DebugFlag); else x
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
20 #else
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
21 #define D(x)
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
22 #endif
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
23
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
24
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
25 /* STACK DATA TYPE */
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
26
13447
a89f7f268de4 Nuke all remaining occurrences of Py_PROTO and Py_FPROTO.
Tim Peters <tim.peters@gmail.com>
parents: 13256
diff changeset
27 static void s_reset(stack *);
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
28
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
29 static void
13659
e78153e179fb Mass ANSIfication.
Thomas Wouters <thomas@python.org>
parents: 13539
diff changeset
30 s_reset(stack *s)
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
31 {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
32 s->s_top = &s->s_base[MAXSTACK];
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
33 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
34
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
35 #define s_empty(s) ((s)->s_top == &(s)->s_base[MAXSTACK])
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
36
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
37 static int
13659
e78153e179fb Mass ANSIfication.
Thomas Wouters <thomas@python.org>
parents: 13539
diff changeset
38 s_push(register stack *s, dfa *d, node *parent)
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
39 {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
40 register stackentry *top;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
41 if (s->s_top == s->s_base) {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
42 fprintf(stderr, "s_push: parser stack overflow\n");
14968
5336946b6495 Fix a bug in stack overflow error handling. This fixes half of Bug
Guido van Rossum <guido@python.org>
parents: 14375
diff changeset
43 return E_NOMEM;
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
44 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
45 top = --s->s_top;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
46 top->s_dfa = d;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
47 top->s_parent = parent;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
48 top->s_state = 0;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
49 return 0;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
50 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
51
4839
4567e158d20c Rename DEBUG macro to Py_DEBUG
Guido van Rossum <guido@python.org>
parents: 4503
diff changeset
52 #ifdef Py_DEBUG
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
53
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
54 static void
13659
e78153e179fb Mass ANSIfication.
Thomas Wouters <thomas@python.org>
parents: 13539
diff changeset
55 s_pop(register stack *s)
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
56 {
2044
281e40652e23 Parser/tokenizer.c (tok_nextc): zap tok->buf after freeing;
Guido van Rossum <guido@python.org>
parents: 1848
diff changeset
57 if (s_empty(s))
5379
1c9a84e0981d Another directory quickly renamed.
Guido van Rossum <guido@python.org>
parents: 4839
diff changeset
58 Py_FatalError("s_pop: parser stack underflow -- FATAL");
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
59 s->s_top++;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
60 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
61
4839
4567e158d20c Rename DEBUG macro to Py_DEBUG
Guido van Rossum <guido@python.org>
parents: 4503
diff changeset
62 #else /* !Py_DEBUG */
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
63
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
64 #define s_pop(s) (s)->s_top++
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
65
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
66 #endif
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
67
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
68
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
69 /* PARSER CREATION */
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
70
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
71 parser_state *
13659
e78153e179fb Mass ANSIfication.
Thomas Wouters <thomas@python.org>
parents: 13539
diff changeset
72 PyParser_New(grammar *g, int start)
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
73 {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
74 parser_state *ps;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
75
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
76 if (!g->g_accel)
5379
1c9a84e0981d Another directory quickly renamed.
Guido van Rossum <guido@python.org>
parents: 4839
diff changeset
77 PyGrammar_AddAccelerators(g);
37585
292854c43b99 Fix the code in Parser/ to also compile with C++. This was mostly casts for
Anthony Baxter <anthonybaxter@gmail.com>
parents: 37557
diff changeset
78 ps = (parser_state *)PyMem_MALLOC(sizeof(parser_state));
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
79 if (ps == NULL)
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
80 return NULL;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
81 ps->p_grammar = g;
36726
bbf16fd024df from __future__ import with_statement addon for 'with', mostly written by
Thomas Wouters <thomas@python.org>
parents: 22466
diff changeset
82 #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
bbf16fd024df from __future__ import with_statement addon for 'with', mostly written by
Thomas Wouters <thomas@python.org>
parents: 22466
diff changeset
83 ps->p_flags = 0;
22466
1db1510abe21 Disable the parser hacks that allowed the "yield" keyword to be enabled
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 21181
diff changeset
84 #endif
5379
1c9a84e0981d Another directory quickly renamed.
Guido van Rossum <guido@python.org>
parents: 4839
diff changeset
85 ps->p_tree = PyNode_New(start);
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
86 if (ps->p_tree == NULL) {
37557
6ae4adefc573 SF patch #1467512, fix double free with triple quoted string in standard build.
Neal Norwitz <nnorwitz@gmail.com>
parents: 36786
diff changeset
87 PyMem_FREE(ps);
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
88 return NULL;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
89 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
90 s_reset(&ps->p_stack);
5379
1c9a84e0981d Another directory quickly renamed.
Guido van Rossum <guido@python.org>
parents: 4839
diff changeset
91 (void) s_push(&ps->p_stack, PyGrammar_FindDFA(g, start), ps->p_tree);
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
92 return ps;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
93 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
94
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
95 void
13659
e78153e179fb Mass ANSIfication.
Thomas Wouters <thomas@python.org>
parents: 13539
diff changeset
96 PyParser_Delete(parser_state *ps)
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
97 {
79
6c43e5476de6 Free parse tree when deleting parser.
Guido van Rossum <guido@python.org>
parents: 6
diff changeset
98 /* NB If you want to save the parse tree,
6c43e5476de6 Free parse tree when deleting parser.
Guido van Rossum <guido@python.org>
parents: 6
diff changeset
99 you must set p_tree to NULL before calling delparser! */
5379
1c9a84e0981d Another directory quickly renamed.
Guido van Rossum <guido@python.org>
parents: 4839
diff changeset
100 PyNode_Free(ps->p_tree);
37557
6ae4adefc573 SF patch #1467512, fix double free with triple quoted string in standard build.
Neal Norwitz <nnorwitz@gmail.com>
parents: 36786
diff changeset
101 PyMem_FREE(ps);
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
102 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
103
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
104
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
105 /* PARSER STACK OPERATIONS */
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
106
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
107 static int
36786
57322cb2ca11 Patch #1440601: Add col_offset attribute to AST nodes.
Martin v. Löwis <martin@v.loewis.de>
parents: 36742
diff changeset
108 shift(register stack *s, int type, char *str, int newstate, int lineno, int col_offset)
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
109 {
12970
63436719d12e Add new parser error code, E_OVERFLOW. This error is returned when
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 5379
diff changeset
110 int err;
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
111 assert(!s_empty(s));
36786
57322cb2ca11 Patch #1440601: Add col_offset attribute to AST nodes.
Martin v. Löwis <martin@v.loewis.de>
parents: 36742
diff changeset
112 err = PyNode_AddChild(s->s_top->s_parent, type, str, lineno, col_offset);
12970
63436719d12e Add new parser error code, E_OVERFLOW. This error is returned when
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 5379
diff changeset
113 if (err)
63436719d12e Add new parser error code, E_OVERFLOW. This error is returned when
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 5379
diff changeset
114 return err;
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
115 s->s_top->s_state = newstate;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
116 return 0;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
117 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
118
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
119 static int
36786
57322cb2ca11 Patch #1440601: Add col_offset attribute to AST nodes.
Martin v. Löwis <martin@v.loewis.de>
parents: 36742
diff changeset
120 push(register stack *s, int type, dfa *d, int newstate, int lineno, int col_offset)
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
121 {
12970
63436719d12e Add new parser error code, E_OVERFLOW. This error is returned when
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 5379
diff changeset
122 int err;
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
123 register node *n;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
124 n = s->s_top->s_parent;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
125 assert(!s_empty(s));
36786
57322cb2ca11 Patch #1440601: Add col_offset attribute to AST nodes.
Martin v. Löwis <martin@v.loewis.de>
parents: 36742
diff changeset
126 err = PyNode_AddChild(n, type, (char *)NULL, lineno, col_offset);
12970
63436719d12e Add new parser error code, E_OVERFLOW. This error is returned when
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 5379
diff changeset
127 if (err)
63436719d12e Add new parser error code, E_OVERFLOW. This error is returned when
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 5379
diff changeset
128 return err;
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
129 s->s_top->s_state = newstate;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
130 return s_push(s, d, CHILD(n, NCH(n)-1));
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
131 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
132
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
133
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
134 /* PARSER PROPER */
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
135
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
136 static int
18609
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
137 classify(parser_state *ps, int type, char *str)
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
138 {
18609
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
139 grammar *g = ps->p_grammar;
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
140 register int n = g->g_ll.ll_nlabels;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
141
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
142 if (type == NAME) {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
143 register char *s = str;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
144 register label *l = g->g_ll.ll_label;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
145 register int i;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
146 for (i = n; i > 0; i--, l++) {
36742
658f8ff2a442 Make 'as' an actual keyword when with's future statement is used. Not
Thomas Wouters <thomas@python.org>
parents: 36726
diff changeset
147 if (l->lb_type != NAME || l->lb_str == NULL ||
658f8ff2a442 Make 'as' an actual keyword when with's future statement is used. Not
Thomas Wouters <thomas@python.org>
parents: 36726
diff changeset
148 l->lb_str[0] != s[0] ||
658f8ff2a442 Make 'as' an actual keyword when with's future statement is used. Not
Thomas Wouters <thomas@python.org>
parents: 36726
diff changeset
149 strcmp(l->lb_str, s) != 0)
658f8ff2a442 Make 'as' an actual keyword when with's future statement is used. Not
Thomas Wouters <thomas@python.org>
parents: 36726
diff changeset
150 continue;
36726
bbf16fd024df from __future__ import with_statement addon for 'with', mostly written by
Thomas Wouters <thomas@python.org>
parents: 22466
diff changeset
151 #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
45891
727f743cf630 Backport of the print function, using a __future__ import.
Eric Smith <eric@trueblade.com>
parents: 39881
diff changeset
152 if (ps->p_flags & CO_FUTURE_PRINT_FUNCTION &&
727f743cf630 Backport of the print function, using a __future__ import.
Eric Smith <eric@trueblade.com>
parents: 39881
diff changeset
153 s[0] == 'p' && strcmp(s, "print") == 0) {
727f743cf630 Backport of the print function, using a __future__ import.
Eric Smith <eric@trueblade.com>
parents: 39881
diff changeset
154 break; /* no longer a keyword */
727f743cf630 Backport of the print function, using a __future__ import.
Eric Smith <eric@trueblade.com>
parents: 39881
diff changeset
155 }
22466
1db1510abe21 Disable the parser hacks that allowed the "yield" keyword to be enabled
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 21181
diff changeset
156 #endif
36742
658f8ff2a442 Make 'as' an actual keyword when with's future statement is used. Not
Thomas Wouters <thomas@python.org>
parents: 36726
diff changeset
157 D(printf("It's a keyword\n"));
658f8ff2a442 Make 'as' an actual keyword when with's future statement is used. Not
Thomas Wouters <thomas@python.org>
parents: 36726
diff changeset
158 return n - i;
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
159 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
160 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
161
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
162 {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
163 register label *l = g->g_ll.ll_label;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
164 register int i;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
165 for (i = n; i > 0; i--, l++) {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
166 if (l->lb_type == type && l->lb_str == NULL) {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
167 D(printf("It's a token we know\n"));
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
168 return n - i;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
169 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
170 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
171 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
172
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
173 D(printf("Illegal token\n"));
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
174 return -1;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
175 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
176
36726
bbf16fd024df from __future__ import with_statement addon for 'with', mostly written by
Thomas Wouters <thomas@python.org>
parents: 22466
diff changeset
177 #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
18609
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
178 static void
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
179 future_hack(parser_state *ps)
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
180 {
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
181 node *n = ps->p_stack.s_top->s_parent;
39881
25bcdf3cd194 Fix a bug in the parser's future statement handling that led to "with"
Georg Brandl <georg@python.org>
parents: 37585
diff changeset
182 node *ch, *cch;
18739
704486642079 Fis SF bug #442647: not all forms of legal future statements were
Guido van Rossum <guido@python.org>
parents: 18609
diff changeset
183 int i;
18609
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
184
36726
bbf16fd024df from __future__ import with_statement addon for 'with', mostly written by
Thomas Wouters <thomas@python.org>
parents: 22466
diff changeset
185 /* from __future__ import ..., must have at least 4 children */
bbf16fd024df from __future__ import with_statement addon for 'with', mostly written by
Thomas Wouters <thomas@python.org>
parents: 22466
diff changeset
186 n = CHILD(n, 0);
bbf16fd024df from __future__ import with_statement addon for 'with', mostly written by
Thomas Wouters <thomas@python.org>
parents: 22466
diff changeset
187 if (NCH(n) < 4)
bbf16fd024df from __future__ import with_statement addon for 'with', mostly written by
Thomas Wouters <thomas@python.org>
parents: 22466
diff changeset
188 return;
bbf16fd024df from __future__ import with_statement addon for 'with', mostly written by
Thomas Wouters <thomas@python.org>
parents: 22466
diff changeset
189 ch = CHILD(n, 0);
bbf16fd024df from __future__ import with_statement addon for 'with', mostly written by
Thomas Wouters <thomas@python.org>
parents: 22466
diff changeset
190 if (STR(ch) == NULL || strcmp(STR(ch), "from") != 0)
18609
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
191 return;
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
192 ch = CHILD(n, 1);
36726
bbf16fd024df from __future__ import with_statement addon for 'with', mostly written by
Thomas Wouters <thomas@python.org>
parents: 22466
diff changeset
193 if (NCH(ch) == 1 && STR(CHILD(ch, 0)) &&
bbf16fd024df from __future__ import with_statement addon for 'with', mostly written by
Thomas Wouters <thomas@python.org>
parents: 22466
diff changeset
194 strcmp(STR(CHILD(ch, 0)), "__future__") != 0)
18609
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
195 return;
39881
25bcdf3cd194 Fix a bug in the parser's future statement handling that led to "with"
Georg Brandl <georg@python.org>
parents: 37585
diff changeset
196 ch = CHILD(n, 3);
25bcdf3cd194 Fix a bug in the parser's future statement handling that led to "with"
Georg Brandl <georg@python.org>
parents: 37585
diff changeset
197 /* ch can be a star, a parenthesis or import_as_names */
25bcdf3cd194 Fix a bug in the parser's future statement handling that led to "with"
Georg Brandl <georg@python.org>
parents: 37585
diff changeset
198 if (TYPE(ch) == STAR)
25bcdf3cd194 Fix a bug in the parser's future statement handling that led to "with"
Georg Brandl <georg@python.org>
parents: 37585
diff changeset
199 return;
25bcdf3cd194 Fix a bug in the parser's future statement handling that led to "with"
Georg Brandl <georg@python.org>
parents: 37585
diff changeset
200 if (TYPE(ch) == LPAR)
25bcdf3cd194 Fix a bug in the parser's future statement handling that led to "with"
Georg Brandl <georg@python.org>
parents: 37585
diff changeset
201 ch = CHILD(n, 4);
25bcdf3cd194 Fix a bug in the parser's future statement handling that led to "with"
Georg Brandl <georg@python.org>
parents: 37585
diff changeset
202
25bcdf3cd194 Fix a bug in the parser's future statement handling that led to "with"
Georg Brandl <georg@python.org>
parents: 37585
diff changeset
203 for (i = 0; i < NCH(ch); i += 2) {
25bcdf3cd194 Fix a bug in the parser's future statement handling that led to "with"
Georg Brandl <georg@python.org>
parents: 37585
diff changeset
204 cch = CHILD(ch, i);
46118
c78d3586c474 Patch #2477: Added from __future__ import unicode_literals
Christian Heimes <christian@cheimes.de>
parents: 45891
diff changeset
205 if (NCH(cch) >= 1 && TYPE(CHILD(cch, 0)) == NAME) {
c78d3586c474 Patch #2477: Added from __future__ import unicode_literals
Christian Heimes <christian@cheimes.de>
parents: 45891
diff changeset
206 char *str_ch = STR(CHILD(cch, 0));
c78d3586c474 Patch #2477: Added from __future__ import unicode_literals
Christian Heimes <christian@cheimes.de>
parents: 45891
diff changeset
207 if (strcmp(str_ch, FUTURE_WITH_STATEMENT) == 0) {
c78d3586c474 Patch #2477: Added from __future__ import unicode_literals
Christian Heimes <christian@cheimes.de>
parents: 45891
diff changeset
208 ps->p_flags |= CO_FUTURE_WITH_STATEMENT;
c78d3586c474 Patch #2477: Added from __future__ import unicode_literals
Christian Heimes <christian@cheimes.de>
parents: 45891
diff changeset
209 } else if (strcmp(str_ch, FUTURE_PRINT_FUNCTION) == 0) {
c78d3586c474 Patch #2477: Added from __future__ import unicode_literals
Christian Heimes <christian@cheimes.de>
parents: 45891
diff changeset
210 ps->p_flags |= CO_FUTURE_PRINT_FUNCTION;
c78d3586c474 Patch #2477: Added from __future__ import unicode_literals
Christian Heimes <christian@cheimes.de>
parents: 45891
diff changeset
211 } else if (strcmp(str_ch, FUTURE_UNICODE_LITERALS) == 0) {
c78d3586c474 Patch #2477: Added from __future__ import unicode_literals
Christian Heimes <christian@cheimes.de>
parents: 45891
diff changeset
212 ps->p_flags |= CO_FUTURE_UNICODE_LITERALS;
c78d3586c474 Patch #2477: Added from __future__ import unicode_literals
Christian Heimes <christian@cheimes.de>
parents: 45891
diff changeset
213 }
18739
704486642079 Fis SF bug #442647: not all forms of legal future statements were
Guido van Rossum <guido@python.org>
parents: 18609
diff changeset
214 }
704486642079 Fis SF bug #442647: not all forms of legal future statements were
Guido van Rossum <guido@python.org>
parents: 18609
diff changeset
215 }
18609
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
216 }
22466
1db1510abe21 Disable the parser hacks that allowed the "yield" keyword to be enabled
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 21181
diff changeset
217 #endif /* future keyword */
18609
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
218
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
219 int
13659
e78153e179fb Mass ANSIfication.
Thomas Wouters <thomas@python.org>
parents: 13539
diff changeset
220 PyParser_AddToken(register parser_state *ps, register int type, char *str,
36786
57322cb2ca11 Patch #1440601: Add col_offset attribute to AST nodes.
Martin v. Löwis <martin@v.loewis.de>
parents: 36742
diff changeset
221 int lineno, int col_offset, int *expected_ret)
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
222 {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
223 register int ilabel;
12970
63436719d12e Add new parser error code, E_OVERFLOW. This error is returned when
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 5379
diff changeset
224 int err;
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
225
5379
1c9a84e0981d Another directory quickly renamed.
Guido van Rossum <guido@python.org>
parents: 4839
diff changeset
226 D(printf("Token %s/'%s' ... ", _PyParser_TokenNames[type], str));
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
227
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
228 /* Find out which label this token is */
18609
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
229 ilabel = classify(ps, type, str);
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
230 if (ilabel < 0)
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
231 return E_SYNTAX;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
232
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
233 /* Loop until the token is shifted or an error occurred */
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
234 for (;;) {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
235 /* Fetch the current dfa and state */
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
236 register dfa *d = ps->p_stack.s_top->s_dfa;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
237 register state *s = &d->d_state[ps->p_stack.s_top->s_state];
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
238
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
239 D(printf(" DFA '%s', state %d:",
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
240 d->d_name, ps->p_stack.s_top->s_state));
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
241
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
242 /* Check accelerator */
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
243 if (s->s_lower <= ilabel && ilabel < s->s_upper) {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
244 register int x = s->s_accel[ilabel - s->s_lower];
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
245 if (x != -1) {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
246 if (x & (1<<7)) {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
247 /* Push non-terminal */
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
248 int nt = (x >> 8) + NT_OFFSET;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
249 int arrow = x & ((1<<7)-1);
5379
1c9a84e0981d Another directory quickly renamed.
Guido van Rossum <guido@python.org>
parents: 4839
diff changeset
250 dfa *d1 = PyGrammar_FindDFA(
1c9a84e0981d Another directory quickly renamed.
Guido van Rossum <guido@python.org>
parents: 4839
diff changeset
251 ps->p_grammar, nt);
12970
63436719d12e Add new parser error code, E_OVERFLOW. This error is returned when
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 5379
diff changeset
252 if ((err = push(&ps->p_stack, nt, d1,
36786
57322cb2ca11 Patch #1440601: Add col_offset attribute to AST nodes.
Martin v. Löwis <martin@v.loewis.de>
parents: 36742
diff changeset
253 arrow, lineno, col_offset)) > 0) {
5379
1c9a84e0981d Another directory quickly renamed.
Guido van Rossum <guido@python.org>
parents: 4839
diff changeset
254 D(printf(" MemError: push\n"));
12970
63436719d12e Add new parser error code, E_OVERFLOW. This error is returned when
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 5379
diff changeset
255 return err;
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
256 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
257 D(printf(" Push ...\n"));
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
258 continue;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
259 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
260
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
261 /* Shift the token */
12970
63436719d12e Add new parser error code, E_OVERFLOW. This error is returned when
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 5379
diff changeset
262 if ((err = shift(&ps->p_stack, type, str,
36786
57322cb2ca11 Patch #1440601: Add col_offset attribute to AST nodes.
Martin v. Löwis <martin@v.loewis.de>
parents: 36742
diff changeset
263 x, lineno, col_offset)) > 0) {
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
264 D(printf(" MemError: shift.\n"));
12970
63436719d12e Add new parser error code, E_OVERFLOW. This error is returned when
Jeremy Hylton <jeremy@alum.mit.edu>
parents: 5379
diff changeset
265 return err;
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
266 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
267 D(printf(" Shift.\n"));
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
268 /* Pop while we are in an accept-only state */
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
269 while (s = &d->d_state
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
270 [ps->p_stack.s_top->s_state],
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
271 s->s_accept && s->s_narcs == 1) {
18609
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
272 D(printf(" DFA '%s', state %d: "
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
273 "Direct pop.\n",
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
274 d->d_name,
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
275 ps->p_stack.s_top->s_state));
36726
bbf16fd024df from __future__ import with_statement addon for 'with', mostly written by
Thomas Wouters <thomas@python.org>
parents: 22466
diff changeset
276 #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
18609
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
277 if (d->d_name[0] == 'i' &&
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
278 strcmp(d->d_name,
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
279 "import_stmt") == 0)
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
280 future_hack(ps);
22466
1db1510abe21 Disable the parser hacks that allowed the "yield" keyword to be enabled
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 21181
diff changeset
281 #endif
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
282 s_pop(&ps->p_stack);
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
283 if (s_empty(&ps->p_stack)) {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
284 D(printf(" ACCEPT.\n"));
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
285 return E_DONE;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
286 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
287 d = ps->p_stack.s_top->s_dfa;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
288 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
289 return E_OK;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
290 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
291 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
292
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
293 if (s->s_accept) {
36726
bbf16fd024df from __future__ import with_statement addon for 'with', mostly written by
Thomas Wouters <thomas@python.org>
parents: 22466
diff changeset
294 #ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
18609
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
295 if (d->d_name[0] == 'i' &&
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
296 strcmp(d->d_name, "import_stmt") == 0)
59446d0f8341 Preliminary support for "from __future__ import generators" to enable
Guido van Rossum <guido@python.org>
parents: 14968
diff changeset
297 future_hack(ps);
22466
1db1510abe21 Disable the parser hacks that allowed the "yield" keyword to be enabled
Neil Schemenauer <nascheme@enme.ucalgary.ca>
parents: 21181
diff changeset
298 #endif
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
299 /* Pop this dfa and try again */
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
300 s_pop(&ps->p_stack);
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
301 D(printf(" Pop ...\n"));
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
302 if (s_empty(&ps->p_stack)) {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
303 D(printf(" Error: bottom of stack.\n"));
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
304 return E_SYNTAX;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
305 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
306 continue;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
307 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
308
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
309 /* Stuck, report syntax error */
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
310 D(printf(" Error.\n"));
13539
feab677269e0 Create two new exceptions: IndentationError and TabError. These are
Fred Drake <fdrake@acm.org>
parents: 13447
diff changeset
311 if (expected_ret) {
feab677269e0 Create two new exceptions: IndentationError and TabError. These are
Fred Drake <fdrake@acm.org>
parents: 13447
diff changeset
312 if (s->s_lower == s->s_upper - 1) {
feab677269e0 Create two new exceptions: IndentationError and TabError. These are
Fred Drake <fdrake@acm.org>
parents: 13447
diff changeset
313 /* Only one possible expected token */
feab677269e0 Create two new exceptions: IndentationError and TabError. These are
Fred Drake <fdrake@acm.org>
parents: 13447
diff changeset
314 *expected_ret = ps->p_grammar->
feab677269e0 Create two new exceptions: IndentationError and TabError. These are
Fred Drake <fdrake@acm.org>
parents: 13447
diff changeset
315 g_ll.ll_label[s->s_lower].lb_type;
feab677269e0 Create two new exceptions: IndentationError and TabError. These are
Fred Drake <fdrake@acm.org>
parents: 13447
diff changeset
316 }
feab677269e0 Create two new exceptions: IndentationError and TabError. These are
Fred Drake <fdrake@acm.org>
parents: 13447
diff changeset
317 else
feab677269e0 Create two new exceptions: IndentationError and TabError. These are
Fred Drake <fdrake@acm.org>
parents: 13447
diff changeset
318 *expected_ret = -1;
feab677269e0 Create two new exceptions: IndentationError and TabError. These are
Fred Drake <fdrake@acm.org>
parents: 13447
diff changeset
319 }
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
320 return E_SYNTAX;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
321 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
322 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
323
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
324
4839
4567e158d20c Rename DEBUG macro to Py_DEBUG
Guido van Rossum <guido@python.org>
parents: 4503
diff changeset
325 #ifdef Py_DEBUG
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
326
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
327 /* DEBUG OUTPUT */
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
328
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
329 void
13659
e78153e179fb Mass ANSIfication.
Thomas Wouters <thomas@python.org>
parents: 13539
diff changeset
330 dumptree(grammar *g, node *n)
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
331 {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
332 int i;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
333
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
334 if (n == NULL)
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
335 printf("NIL");
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
336 else {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
337 label l;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
338 l.lb_type = TYPE(n);
1027
513940eb4d7b Correct debug printing code
Guido van Rossum <guido@python.org>
parents: 795
diff changeset
339 l.lb_str = STR(n);
5379
1c9a84e0981d Another directory quickly renamed.
Guido van Rossum <guido@python.org>
parents: 4839
diff changeset
340 printf("%s", PyGrammar_LabelRepr(&l));
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
341 if (ISNONTERMINAL(TYPE(n))) {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
342 printf("(");
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
343 for (i = 0; i < NCH(n); i++) {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
344 if (i > 0)
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
345 printf(",");
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
346 dumptree(g, CHILD(n, i));
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
347 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
348 printf(")");
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
349 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
350 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
351 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
352
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
353 void
13659
e78153e179fb Mass ANSIfication.
Thomas Wouters <thomas@python.org>
parents: 13539
diff changeset
354 showtree(grammar *g, node *n)
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
355 {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
356 int i;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
357
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
358 if (n == NULL)
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
359 return;
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
360 if (ISNONTERMINAL(TYPE(n))) {
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
361 for (i = 0; i < NCH(n); i++)
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
362 showtree(g, CHILD(n, i));
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
363 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
364 else if (ISTERMINAL(TYPE(n))) {
5379
1c9a84e0981d Another directory quickly renamed.
Guido van Rossum <guido@python.org>
parents: 4839
diff changeset
365 printf("%s", _PyParser_TokenNames[TYPE(n)]);
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
366 if (TYPE(n) == NUMBER || TYPE(n) == NAME)
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
367 printf("(%s)", STR(n));
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
368 printf(" ");
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
369 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
370 else
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
371 printf("? ");
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
372 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
373
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
374 void
13659
e78153e179fb Mass ANSIfication.
Thomas Wouters <thomas@python.org>
parents: 13539
diff changeset
375 printtree(parser_state *ps)
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
376 {
5379
1c9a84e0981d Another directory quickly renamed.
Guido van Rossum <guido@python.org>
parents: 4839
diff changeset
377 if (Py_DebugFlag) {
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
378 printf("Parse tree:\n");
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
379 dumptree(ps->p_grammar, ps->p_tree);
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
380 printf("\n");
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
381 printf("Tokens:\n");
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
382 showtree(ps->p_grammar, ps->p_tree);
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
383 printf("\n");
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
384 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
385 printf("Listing:\n");
5379
1c9a84e0981d Another directory quickly renamed.
Guido van Rossum <guido@python.org>
parents: 4839
diff changeset
386 PyNode_ListTree(ps->p_tree);
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
387 printf("\n");
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
388 }
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
389
4839
4567e158d20c Rename DEBUG macro to Py_DEBUG
Guido van Rossum <guido@python.org>
parents: 4503
diff changeset
390 #endif /* Py_DEBUG */
6
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
391
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
392 /*
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
393
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
394 Description
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
395 -----------
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
396
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
397 The parser's interface is different than usual: the function addtoken()
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
398 must be called for each token in the input. This makes it possible to
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
399 turn it into an incremental parsing system later. The parsing system
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
400 constructs a parse tree as it goes.
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
401
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
402 A parsing rule is represented as a Deterministic Finite-state Automaton
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
403 (DFA). A node in a DFA represents a state of the parser; an arc represents
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
404 a transition. Transitions are either labeled with terminal symbols or
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
405 with non-terminals. When the parser decides to follow an arc labeled
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
406 with a non-terminal, it is invoked recursively with the DFA representing
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
407 the parsing rule for that as its initial state; when that DFA accepts,
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
408 the parser that invoked it continues. The parse tree constructed by the
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
409 recursively called parser is inserted as a child in the current parse tree.
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
410
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
411 The DFA's can be constructed automatically from a more conventional
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
412 language description. An extended LL(1) grammar (ELL(1)) is suitable.
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
413 Certain restrictions make the parser's life easier: rules that can produce
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
414 the empty string should be outlawed (there are other ways to put loops
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
415 or optional parts in the language). To avoid the need to construct
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
416 FIRST sets, we can require that all but the last alternative of a rule
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
417 (really: arc going out of a DFA's state) must begin with a terminal
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
418 symbol.
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
419
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
420 As an example, consider this grammar:
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
421
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
422 expr: term (OP term)*
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
423 term: CONSTANT | '(' expr ')'
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
424
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
425 The DFA corresponding to the rule for expr is:
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
426
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
427 ------->.---term-->.------->
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
428 ^ |
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
429 | |
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
430 \----OP----/
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
431
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
432 The parse tree generated for the input a+b is:
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
433
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
434 (expr: (term: (NAME: a)), (OP: +), (term: (NAME: b)))
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
435
fc6fcd7df4f7 Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
436 */