@@ -79,6 +79,7 @@ PyParser_New(grammar *g, int start)
7979 if (ps == NULL )
8080 return NULL ;
8181 ps -> p_grammar = g ;
82+ ps -> p_generators = 0 ;
8283 ps -> p_tree = PyNode_New (start );
8384 if (ps -> p_tree == NULL ) {
8485 PyMem_DEL (ps );
@@ -131,8 +132,9 @@ push(register stack *s, int type, dfa *d, int newstate, int lineno)
131132/* PARSER PROPER */
132133
133134static int
134- classify (grammar * g , int type , char * str )
135+ classify (parser_state * ps , int type , char * str )
135136{
137+ grammar * g = ps -> p_grammar ;
136138 register int n = g -> g_ll .ll_nlabels ;
137139
138140 if (type == NAME ) {
@@ -143,6 +145,10 @@ classify(grammar *g, int type, char *str)
143145 if (l -> lb_type == NAME && l -> lb_str != NULL &&
144146 l -> lb_str [0 ] == s [0 ] &&
145147 strcmp (l -> lb_str , s ) == 0 ) {
148+ if (!ps -> p_generators &&
149+ s [0 ] == 'y' &&
150+ strcmp (s , "yield" ) == 0 )
151+ break ; /* not a keyword */
146152 D (printf ("It's a keyword\n" ));
147153 return n - i ;
148154 }
@@ -164,6 +170,22 @@ classify(grammar *g, int type, char *str)
164170 return -1 ;
165171}
166172
173+ static void
174+ future_hack (parser_state * ps )
175+ {
176+ node * n = ps -> p_stack .s_top -> s_parent ;
177+ node * ch ;
178+
179+ if (strcmp (STR (CHILD (n , 0 )), "from" ) != 0 )
180+ return ;
181+ ch = CHILD (n , 1 );
182+ if (strcmp (STR (CHILD (ch , 0 )), "__future__" ) != 0 )
183+ return ;
184+ ch = CHILD (n , 3 );
185+ if (NCH (ch ) == 1 && strcmp (STR (CHILD (ch , 0 )), "generators" ) == 0 )
186+ ps -> p_generators = 1 ;
187+ }
188+
167189int
168190PyParser_AddToken (register parser_state * ps , register int type , char * str ,
169191 int lineno , int * expected_ret )
@@ -174,7 +196,7 @@ PyParser_AddToken(register parser_state *ps, register int type, char *str,
174196 D (printf ("Token %s/'%s' ... " , _PyParser_TokenNames [type ], str ));
175197
176198 /* Find out which label this token is */
177- ilabel = classify (ps -> p_grammar , type , str );
199+ ilabel = classify (ps , type , str );
178200 if (ilabel < 0 )
179201 return E_SYNTAX ;
180202
@@ -217,7 +239,14 @@ PyParser_AddToken(register parser_state *ps, register int type, char *str,
217239 while (s = & d -> d_state
218240 [ps -> p_stack .s_top -> s_state ],
219241 s -> s_accept && s -> s_narcs == 1 ) {
220- D (printf (" Direct pop.\n" ));
242+ D (printf (" DFA '%s', state %d: "
243+ "Direct pop.\n" ,
244+ d -> d_name ,
245+ ps -> p_stack .s_top -> s_state ));
246+ if (d -> d_name [0 ] == 'i' &&
247+ strcmp (d -> d_name ,
248+ "import_stmt" ) == 0 )
249+ future_hack (ps );
221250 s_pop (& ps -> p_stack );
222251 if (s_empty (& ps -> p_stack )) {
223252 D (printf (" ACCEPT.\n" ));
@@ -230,6 +259,9 @@ PyParser_AddToken(register parser_state *ps, register int type, char *str,
230259 }
231260
232261 if (s -> s_accept ) {
262+ if (d -> d_name [0 ] == 'i' &&
263+ strcmp (d -> d_name , "import_stmt" ) == 0 )
264+ future_hack (ps );
233265 /* Pop this dfa and try again */
234266 s_pop (& ps -> p_stack );
235267 D (printf (" Pop ...\n" ));
0 commit comments