merged in latest cython-devel
[cython.git] / Cython / Compiler / Parsing.py
1 # cython: auto_cpdef=True, infer_types=True
2 #
3 #   Pyrex Parser
4 #
5
6 # This should be done automatically
7 import cython
8 cython.declare(Nodes=object, ExprNodes=object, EncodedString=object)
9
10 import os
11 import re
12 import sys
13
14 try:
15     from __builtin__ import set
16 except (ImportError, AttributeError):
17     try:
18         from builtins import set
19     except (ImportError, AttributeError):
20         from sets import Set as set
21
22 from Cython.Compiler.Scanning import PyrexScanner, FileSourceDescriptor
23 import Nodes
24 import ExprNodes
25 import StringEncoding
26 from StringEncoding import EncodedString, BytesLiteral, _unicode, _bytes
27 from ModuleNode import ModuleNode
28 from Errors import error, warning, InternalError
29 from Cython import Utils
30 import Future
31 import Options
32
33 class Ctx(object):
34     #  Parsing context
35     level = 'other'
36     visibility = 'private'
37     cdef_flag = 0
38     typedef_flag = 0
39     api = 0
40     overridable = 0
41     nogil = 0
42     namespace = None
43     templates = None
44
45     def __init__(self, **kwds):
46         self.__dict__.update(kwds)
47
48     def __call__(self, **kwds):
49         ctx = Ctx()
50         d = ctx.__dict__
51         d.update(self.__dict__)
52         d.update(kwds)
53         return ctx
54
55 def p_ident(s, message = "Expected an identifier"):
56     if s.sy == 'IDENT':
57         name = s.systring
58         s.next()
59         return name
60     else:
61         s.error(message)
62
63 def p_ident_list(s):
64     names = []
65     while s.sy == 'IDENT':
66         names.append(s.systring)
67         s.next()
68         if s.sy != ',':
69             break
70         s.next()
71     return names
72
73 #------------------------------------------
74 #
75 #   Expressions
76 #
77 #------------------------------------------
78
79 def p_binop_operator(s):
80     pos = s.position()
81     op = s.sy
82     s.next()
83     return op, pos
84
85 def p_binop_expr(s, ops, p_sub_expr):
86     n1 = p_sub_expr(s)
87     while s.sy in ops:
88         op, pos = p_binop_operator(s)
89         n2 = p_sub_expr(s)
90         n1 = ExprNodes.binop_node(pos, op, n1, n2)
91         if op == '/':
92             if Future.division in s.context.future_directives:
93                 n1.truedivision = True
94             else:
95                 n1.truedivision = None # unknown
96     return n1
97
98 #expression: or_test [if or_test else test] | lambda_form
99
100 # actually:
101 #test: or_test ['if' or_test 'else' test] | lambdef
102
103 def p_simple_expr(s):
104     if s.sy == 'lambda':
105         return p_lambdef(s)
106     pos = s.position()
107     expr = p_or_test(s)
108     if s.sy == 'if':
109         s.next()
110         test = p_or_test(s)
111         s.expect('else')
112         other = p_test(s)
113         return ExprNodes.CondExprNode(pos, test=test, true_val=expr, false_val=other)
114     else:
115         return expr
116
117 #lambdef: 'lambda' [varargslist] ':' test
118
119 def p_lambdef(s, allow_conditional=True):
120     # s.sy == 'lambda'
121     pos = s.position()
122     s.next()
123     if s.sy == ':':
124         args = []
125         star_arg = starstar_arg = None
126     else:
127         args, star_arg, starstar_arg = p_varargslist(
128             s, terminator=':', annotated=False)
129     s.expect(':')
130     if allow_conditional:
131         expr = p_simple_expr(s)
132     else:
133         expr = p_test_nocond(s)
134     return ExprNodes.LambdaNode(
135         pos, args = args,
136         star_arg = star_arg, starstar_arg = starstar_arg,
137         result_expr = expr)
138
139 #lambdef_nocond: 'lambda' [varargslist] ':' test_nocond
140
141 def p_lambdef_nocond(s):
142     return p_lambdef(s, allow_conditional=False)
143
144 #test: or_test | lambdef
145
146 def p_test(s):
147     return p_or_test(s)
148
149 #test_nocond: or_test | lambdef_nocond
150
151 def p_test_nocond(s):
152     if s.sy == 'lambda':
153         return p_lambdef_nocond(s)
154     else:
155         return p_or_test(s)
156
157 #or_test: and_test ('or' and_test)*
158
159 def p_or_test(s):
160     return p_rassoc_binop_expr(s, ('or',), p_and_test)
161
162 def p_rassoc_binop_expr(s, ops, p_subexpr):
163     n1 = p_subexpr(s)
164     if s.sy in ops:
165         pos = s.position()
166         op = s.sy
167         s.next()
168         n2 = p_rassoc_binop_expr(s, ops, p_subexpr)
169         n1 = ExprNodes.binop_node(pos, op, n1, n2)
170     return n1
171
172 #and_test: not_test ('and' not_test)*
173
174 def p_and_test(s):
175     #return p_binop_expr(s, ('and',), p_not_test)
176     return p_rassoc_binop_expr(s, ('and',), p_not_test)
177
178 #not_test: 'not' not_test | comparison
179
180 def p_not_test(s):
181     if s.sy == 'not':
182         pos = s.position()
183         s.next()
184         return ExprNodes.NotNode(pos, operand = p_not_test(s))
185     else:
186         return p_comparison(s)
187
188 #comparison: expr (comp_op expr)*
189 #comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
190
191 def p_comparison(s):
192     n1 = p_starred_expr(s)
193     if s.sy in comparison_ops:
194         pos = s.position()
195         op = p_cmp_op(s)
196         n2 = p_starred_expr(s)
197         n1 = ExprNodes.PrimaryCmpNode(pos, 
198             operator = op, operand1 = n1, operand2 = n2)
199         if s.sy in comparison_ops:
200             n1.cascade = p_cascaded_cmp(s)
201     return n1
202
203 def p_starred_expr(s):
204     pos = s.position()
205     if s.sy == '*':
206         starred = True
207         s.next()
208     else:
209         starred = False
210     expr = p_bit_expr(s)
211     if starred:
212         expr = ExprNodes.StarredTargetNode(pos, expr)
213     return expr
214
215 def p_cascaded_cmp(s):
216     pos = s.position()
217     op = p_cmp_op(s)
218     n2 = p_starred_expr(s)
219     result = ExprNodes.CascadedCmpNode(pos, 
220         operator = op, operand2 = n2)
221     if s.sy in comparison_ops:
222         result.cascade = p_cascaded_cmp(s)
223     return result
224
225 def p_cmp_op(s):
226     if s.sy == 'not':
227         s.next()
228         s.expect('in')
229         op = 'not_in'
230     elif s.sy == 'is':
231         s.next()
232         if s.sy == 'not':
233             s.next()
234             op = 'is_not'
235         else:
236             op = 'is'
237     else:
238         op = s.sy
239         s.next()
240     if op == '<>':
241         op = '!='
242     return op
243     
244 comparison_ops = (
245     '<', '>', '==', '>=', '<=', '<>', '!=', 
246     'in', 'is', 'not'
247 )
248
249 #expr: xor_expr ('|' xor_expr)*
250
251 def p_bit_expr(s):
252     return p_binop_expr(s, ('|',), p_xor_expr)
253
254 #xor_expr: and_expr ('^' and_expr)*
255
256 def p_xor_expr(s):
257     return p_binop_expr(s, ('^',), p_and_expr)
258
259 #and_expr: shift_expr ('&' shift_expr)*
260
261 def p_and_expr(s):
262     return p_binop_expr(s, ('&',), p_shift_expr)
263
264 #shift_expr: arith_expr (('<<'|'>>') arith_expr)*
265
266 def p_shift_expr(s):
267     return p_binop_expr(s, ('<<', '>>'), p_arith_expr)
268
269 #arith_expr: term (('+'|'-') term)*
270
271 def p_arith_expr(s):
272     return p_binop_expr(s, ('+', '-'), p_term)
273
274 #term: factor (('*'|'/'|'%') factor)*
275
276 def p_term(s):
277     return p_binop_expr(s, ('*', '/', '%', '//'), p_factor)
278
279 #factor: ('+'|'-'|'~'|'&'|typecast|sizeof) factor | power
280
281 def p_factor(s):
282     sy = s.sy
283     if sy in ('+', '-', '~'):
284         op = s.sy
285         pos = s.position()
286         s.next()
287         return ExprNodes.unop_node(pos, op, p_factor(s))
288     elif sy == '&':
289         pos = s.position()
290         s.next()
291         arg = p_factor(s)
292         return ExprNodes.AmpersandNode(pos, operand = arg)
293     elif sy == "<":
294         return p_typecast(s)
295     elif sy == 'IDENT' and s.systring == "sizeof":
296         return p_sizeof(s)
297     else:
298         return p_power(s)
299
300 def p_typecast(s):
301     # s.sy == "<"
302     pos = s.position()
303     s.next()
304     base_type = p_c_base_type(s)
305     if base_type.name is None:
306         s.error("Unknown type")
307     declarator = p_c_declarator(s, empty = 1)
308     if s.sy == '?':
309         s.next()
310         typecheck = 1
311     else:
312         typecheck = 0
313     s.expect(">")
314     operand = p_factor(s)
315     return ExprNodes.TypecastNode(pos, 
316         base_type = base_type, 
317         declarator = declarator,
318         operand = operand,
319         typecheck = typecheck)
320
321 def p_sizeof(s):
322     # s.sy == ident "sizeof"
323     pos = s.position()
324     s.next()
325     s.expect('(')
326     # Here we decide if we are looking at an expression or type
327     # If it is actually a type, but parsable as an expression, 
328     # we treat it as an expression here. 
329     if looking_at_expr(s):
330         operand = p_simple_expr(s)
331         node = ExprNodes.SizeofVarNode(pos, operand = operand)
332     else:
333         base_type = p_c_base_type(s)
334         declarator = p_c_declarator(s, empty = 1)
335         node = ExprNodes.SizeofTypeNode(pos, 
336             base_type = base_type, declarator = declarator)
337     s.expect(')')
338     return node
339
340 def p_yield_expression(s):
341     # s.sy == "yield"
342     pos = s.position()
343     s.next()
344     if s.sy != ')' and s.sy not in statement_terminators:
345         arg = p_expr(s)
346     else:
347         arg = None
348     return ExprNodes.YieldExprNode(pos, arg=arg)
349
350 def p_yield_statement(s):
351     # s.sy == "yield"
352     yield_expr = p_yield_expression(s)
353     return Nodes.ExprStatNode(yield_expr.pos, expr=yield_expr)
354
355 #power: atom trailer* ('**' factor)*
356
357 def p_power(s):
358     if s.systring == 'new' and s.peek()[0] == 'IDENT':
359         return p_new_expr(s)
360     n1 = p_atom(s)
361     while s.sy in ('(', '[', '.'):
362         n1 = p_trailer(s, n1)
363     if s.sy == '**':
364         pos = s.position()
365         s.next()
366         n2 = p_factor(s)
367         n1 = ExprNodes.binop_node(pos, '**', n1, n2)
368     return n1
369
370 def p_new_expr(s):
371     # s.systring == 'new'.
372     pos = s.position()
373     s.next()
374     cppclass = p_c_base_type(s)
375     return p_call(s, ExprNodes.NewExprNode(pos, cppclass = cppclass))
376
377 #trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
378
379 def p_trailer(s, node1):
380     pos = s.position()
381     if s.sy == '(':
382         return p_call(s, node1)
383     elif s.sy == '[':
384         return p_index(s, node1)
385     else: # s.sy == '.'
386         s.next()
387         name = EncodedString( p_ident(s) )
388         return ExprNodes.AttributeNode(pos, 
389             obj = node1, attribute = name)
390
391 # arglist:  argument (',' argument)* [',']
392 # argument: [test '='] test       # Really [keyword '='] test
393
394 def p_call(s, function):
395     # s.sy == '('
396     pos = s.position()
397     s.next()
398     positional_args = []
399     keyword_args = []
400     star_arg = None
401     starstar_arg = None
402     while s.sy not in ('**', ')'):
403         if s.sy == '*':
404             if star_arg:
405                 s.error("only one star-arg parameter allowed",
406                     pos = s.position())
407             s.next()
408             star_arg = p_simple_expr(s)
409         else:
410             arg = p_simple_expr(s)
411             if s.sy == '=':
412                 s.next()
413                 if not arg.is_name:
414                     s.error("Expected an identifier before '='",
415                         pos = arg.pos)
416                 encoded_name = EncodedString(arg.name)
417                 keyword = ExprNodes.IdentifierStringNode(arg.pos, value = encoded_name)
418                 arg = p_simple_expr(s)
419                 keyword_args.append((keyword, arg))
420             else:
421                 if keyword_args:
422                     s.error("Non-keyword arg following keyword arg",
423                         pos = arg.pos)
424                 if star_arg:
425                     s.error("Non-keyword arg following star-arg",
426                         pos = arg.pos)
427                 positional_args.append(arg)
428         if s.sy != ',':
429             break
430         s.next()
431
432     if s.sy == '**':
433         s.next()
434         starstar_arg = p_simple_expr(s)
435         if s.sy == ',':
436             s.next()
437     s.expect(')')
438     if not (keyword_args or star_arg or starstar_arg):
439         return ExprNodes.SimpleCallNode(pos,
440             function = function,
441             args = positional_args)
442     else:
443         arg_tuple = None
444         keyword_dict = None
445         if positional_args or not star_arg:
446             arg_tuple = ExprNodes.TupleNode(pos, 
447                 args = positional_args)
448         if star_arg:
449             star_arg_tuple = ExprNodes.AsTupleNode(pos, arg = star_arg)
450             if arg_tuple:
451                 arg_tuple = ExprNodes.binop_node(pos, 
452                     operator = '+', operand1 = arg_tuple,
453                     operand2 = star_arg_tuple)
454             else:
455                 arg_tuple = star_arg_tuple
456         if keyword_args:
457             keyword_args = [ExprNodes.DictItemNode(pos=key.pos, key=key, value=value) 
458                               for key, value in keyword_args]
459             keyword_dict = ExprNodes.DictNode(pos,
460                 key_value_pairs = keyword_args)
461         return ExprNodes.GeneralCallNode(pos, 
462             function = function,
463             positional_args = arg_tuple,
464             keyword_args = keyword_dict,
465             starstar_arg = starstar_arg)
466
467 #lambdef: 'lambda' [varargslist] ':' test
468
469 #subscriptlist: subscript (',' subscript)* [',']
470
471 def p_index(s, base):
472     # s.sy == '['
473     pos = s.position()
474     s.next()
475     subscripts = p_subscript_list(s)
476     if len(subscripts) == 1 and len(subscripts[0]) == 2:
477         start, stop = subscripts[0]
478         result = ExprNodes.SliceIndexNode(pos, 
479             base = base, start = start, stop = stop)
480     else:
481         indexes = make_slice_nodes(pos, subscripts)
482         if len(indexes) == 1:
483             index = indexes[0]
484         else:
485             index = ExprNodes.TupleNode(pos, args = indexes)
486         result = ExprNodes.IndexNode(pos,
487             base = base, index = index)
488     s.expect(']')
489     return result
490
491 def p_subscript_list(s):
492     items = [p_subscript(s)]
493     while s.sy == ',':
494         s.next()
495         if s.sy == ']':
496             break
497         items.append(p_subscript(s))
498     return items
499
500 #subscript: '.' '.' '.' | test | [test] ':' [test] [':' [test]]
501
502 def p_subscript(s):
503     # Parse a subscript and return a list of
504     # 1, 2 or 3 ExprNodes, depending on how
505     # many slice elements were encountered.
506     pos = s.position()
507     if s.sy == '.':
508         expect_ellipsis(s)
509         return [ExprNodes.EllipsisNode(pos)]
510     else:
511         start = p_slice_element(s, (':',))
512         if s.sy != ':':
513             return [start]
514         s.next()
515         stop = p_slice_element(s, (':', ',', ']'))
516         if s.sy != ':':
517             return [start, stop]
518         s.next()
519         step = p_slice_element(s, (':', ',', ']'))
520         return [start, stop, step]
521
522 def p_slice_element(s, follow_set):
523     # Simple expression which may be missing iff
524     # it is followed by something in follow_set.
525     if s.sy not in follow_set:
526         return p_simple_expr(s)
527     else:
528         return None
529
530 def expect_ellipsis(s):
531     s.expect('.')
532     s.expect('.')
533     s.expect('.')
534
535 def make_slice_nodes(pos, subscripts):
536     # Convert a list of subscripts as returned
537     # by p_subscript_list into a list of ExprNodes,
538     # creating SliceNodes for elements with 2 or
539     # more components.
540     result = []
541     for subscript in subscripts:
542         if len(subscript) == 1:
543             result.append(subscript[0])
544         else:
545             result.append(make_slice_node(pos, *subscript))
546     return result
547
548 def make_slice_node(pos, start, stop = None, step = None):
549     if not start:
550         start = ExprNodes.NoneNode(pos)
551     if not stop:
552         stop = ExprNodes.NoneNode(pos)
553     if not step:
554         step = ExprNodes.NoneNode(pos)
555     return ExprNodes.SliceNode(pos,
556         start = start, stop = stop, step = step)
557
558 #atom: '(' [testlist] ')' | '[' [listmaker] ']' | '{' [dict_or_set_maker] '}' | '`' testlist '`' | NAME | NUMBER | STRING+
559
560 def p_atom(s):
561     pos = s.position()
562     sy = s.sy
563     if sy == '(':
564         s.next()
565         if s.sy == ')':
566             result = ExprNodes.TupleNode(pos, args = [])
567         elif s.sy == 'yield':
568             result = p_yield_expression(s)
569         else:
570             result = p_expr(s)
571         s.expect(')')
572         return result
573     elif sy == '[':
574         return p_list_maker(s)
575     elif sy == '{':
576         return p_dict_or_set_maker(s)
577     elif sy == '`':
578         return p_backquote_expr(s)
579     elif sy == 'INT':
580         value = s.systring
581         s.next()
582         unsigned = ""
583         longness = ""
584         while value[-1] in "UuLl":
585             if value[-1] in "Ll":
586                 longness += "L"
587             else:
588                 unsigned += "U"
589             value = value[:-1]
590         return ExprNodes.IntNode(pos, 
591                                  value = value,
592                                  unsigned = unsigned,
593                                  longness = longness)
594     elif sy == 'FLOAT':
595         value = s.systring
596         s.next()
597         return ExprNodes.FloatNode(pos, value = value)
598     elif sy == 'IMAG':
599         value = s.systring[:-1]
600         s.next()
601         return ExprNodes.ImagNode(pos, value = value)
602     elif sy == 'BEGIN_STRING':
603         kind, value = p_cat_string_literal(s)
604         if kind == 'c':
605             return ExprNodes.CharNode(pos, value = value)
606         elif kind == 'u':
607             return ExprNodes.UnicodeNode(pos, value = value)
608         elif kind == 'b':
609             return ExprNodes.BytesNode(pos, value = value)
610         else:
611             return ExprNodes.StringNode(pos, value = value)
612     elif sy == 'IDENT':
613         name = EncodedString( s.systring )
614         s.next()
615         if name == "None":
616             return ExprNodes.NoneNode(pos)
617         elif name == "True":
618             return ExprNodes.BoolNode(pos, value=True)
619         elif name == "False":
620             return ExprNodes.BoolNode(pos, value=False)
621         elif name == "NULL":
622             return ExprNodes.NullNode(pos)
623         else:
624             return p_name(s, name)
625     else:
626         s.error("Expected an identifier or literal")
627
628 def p_name(s, name):
629     pos = s.position()
630     if not s.compile_time_expr and name in s.compile_time_env:
631         value = s.compile_time_env.lookup_here(name)
632         rep = repr(value)
633         if isinstance(value, bool):
634             return ExprNodes.BoolNode(pos, value = value)
635         elif isinstance(value, int):
636             return ExprNodes.IntNode(pos, value = rep)
637         elif isinstance(value, long):
638             return ExprNodes.IntNode(pos, value = rep, longness = "L")
639         elif isinstance(value, float):
640             return ExprNodes.FloatNode(pos, value = rep)
641         elif isinstance(value, _unicode):
642             return ExprNodes.UnicodeNode(pos, value = value)
643         elif isinstance(value, _bytes):
644             return ExprNodes.BytesNode(pos, value = value)
645         else:
646             error(pos, "Invalid type for compile-time constant: %s"
647                 % value.__class__.__name__)
648     return ExprNodes.NameNode(pos, name = name)
649
650 def p_cat_string_literal(s):
651     # A sequence of one or more adjacent string literals.
652     # Returns (kind, value) where kind in ('b', 'c', 'u', '')
653     kind, value = p_string_literal(s)
654     if s.sy != 'BEGIN_STRING':
655         return kind, value
656     if kind != 'c':
657         strings = [value]
658         while s.sy == 'BEGIN_STRING':
659             pos = s.position()
660             next_kind, next_value = p_string_literal(s)
661             if next_kind == 'c':
662                 error(pos, "Cannot concatenate char literal with another string or char literal")
663             elif next_kind != kind:
664                 error(pos, "Cannot mix string literals of different types, expected %s'', got %s''" %
665                       (kind, next_kind))
666             else:
667                 strings.append(next_value)
668         if kind == 'u':
669             value = EncodedString( u''.join(strings) )
670         else:
671             value = BytesLiteral( StringEncoding.join_bytes(strings) )
672             value.encoding = s.source_encoding
673     return kind, value
674
675 def p_opt_string_literal(s):
676     if s.sy == 'BEGIN_STRING':
677         return p_string_literal(s)
678     else:
679         return None
680
681 def p_string_literal(s):
682     # A single string or char literal.
683     # Returns (kind, value) where kind in ('b', 'c', 'u')
684     # s.sy == 'BEGIN_STRING'
685     pos = s.position()
686     is_raw = 0
687     kind = s.systring[:1].lower()
688     if kind == 'r':
689         kind = ''
690         is_raw = 1
691     elif kind in 'ub':
692         is_raw = s.systring[1:2].lower() == 'r'
693     elif kind != 'c':
694         kind = ''
695     if Future.unicode_literals in s.context.future_directives:
696         if kind == '':
697             kind = 'u'
698     if kind == 'u':
699         chars = StringEncoding.UnicodeLiteralBuilder()
700     else:
701         chars = StringEncoding.BytesLiteralBuilder(s.source_encoding)
702     while 1:
703         s.next()
704         sy = s.sy
705         #print "p_string_literal: sy =", sy, repr(s.systring) ###
706         if sy == 'CHARS':
707             chars.append(s.systring)
708         elif sy == 'ESCAPE':
709             has_escape = True
710             systr = s.systring
711             if is_raw:
712                 if systr == u'\\\n':
713                     chars.append(u'\\\n')
714                 elif systr == u'\\\"':
715                     chars.append(u'"')
716                 elif systr == u'\\\'':
717                     chars.append(u"'")
718                 else:
719                     chars.append(systr)
720             else:
721                 c = systr[1]
722                 if c in u"01234567":
723                     chars.append_charval( int(systr[1:], 8) )
724                 elif c in u"'\"\\":
725                     chars.append(c)
726                 elif c in u"abfnrtv":
727                     chars.append(
728                         StringEncoding.char_from_escape_sequence(systr))
729                 elif c == u'\n':
730                     pass
731                 elif c in u'Uux':
732                     if kind == 'u' or c == 'x':
733                         chrval = int(systr[2:], 16)
734                         if chrval > 1114111: # sys.maxunicode:
735                             s.error("Invalid unicode escape '%s'" % systr,
736                                     pos = pos)
737                         elif chrval > 65535:
738                             warning(s.position(),
739                                     "Unicode characters above 65535 are not "
740                                     "necessarily portable across Python installations", 1)
741                         chars.append_charval(chrval)
742                     else:
743                         # unicode escapes in plain byte strings are not unescaped
744                         chars.append(systr)
745                 else:
746                     chars.append(u'\\' + systr[1:])
747         elif sy == 'NEWLINE':
748             chars.append(u'\n')
749         elif sy == 'END_STRING':
750             break
751         elif sy == 'EOF':
752             s.error("Unclosed string literal", pos = pos)
753         else:
754             s.error(
755                 "Unexpected token %r:%r in string literal" %
756                     (sy, s.systring))
757     if kind == 'c':
758         value = chars.getchar()
759         if len(value) != 1:
760             error(pos, u"invalid character literal: %r" % value)
761     else:
762         value = chars.getstring()
763     s.next()
764     #print "p_string_literal: value =", repr(value) ###
765     return kind, value
766
767 # list_display      ::=      "[" [listmaker] "]"
768 # listmaker     ::=     expression ( comp_for | ( "," expression )* [","] )
769 # comp_iter     ::=     comp_for | comp_if
770 # comp_for     ::=     "for" expression_list "in" testlist [comp_iter]
771 # comp_if     ::=     "if" test [comp_iter]
772         
773 def p_list_maker(s):
774     # s.sy == '['
775     pos = s.position()
776     s.next()
777     if s.sy == ']':
778         s.expect(']')
779         return ExprNodes.ListNode(pos, args = [])
780     expr = p_simple_expr(s)
781     if s.sy == 'for':
782         target = ExprNodes.ListNode(pos, args = [])
783         append = ExprNodes.ComprehensionAppendNode(
784             pos, expr=expr, target=ExprNodes.CloneNode(target))
785         loop = p_comp_for(s, Nodes.ExprStatNode(append.pos, expr=append))
786         s.expect(']')
787         return ExprNodes.ComprehensionNode(
788             pos, loop=loop, append=append, target=target)
789     else:
790         exprs = [expr]
791         if s.sy == ',':
792             s.next()
793             exprs += p_simple_expr_list(s)
794         s.expect(']')
795         return ExprNodes.ListNode(pos, args = exprs)
796         
797 def p_comp_iter(s, body):
798     if s.sy == 'for':
799         return p_comp_for(s, body)
800     elif s.sy == 'if':
801         return p_comp_if(s, body)
802     else:
803         # insert the 'append' operation into the loop
804         return body
805
806 def p_comp_for(s, body):
807     # s.sy == 'for'
808     pos = s.position()
809     s.next()
810     kw = p_for_bounds(s)
811     kw['else_clause'] = None
812     kw['body'] = p_comp_iter(s, body)
813     return Nodes.ForStatNode(pos, **kw)
814         
815 def p_comp_if(s, body):
816     # s.sy == 'if'
817     pos = s.position()
818     s.next()
819     test = p_test_nocond(s)
820     return Nodes.IfStatNode(pos, 
821         if_clauses = [Nodes.IfClauseNode(pos, condition = test,
822                                          body = p_comp_iter(s, body))],
823         else_clause = None )
824
825 #dictmaker: test ':' test (',' test ':' test)* [',']
826
827 def p_dict_or_set_maker(s):
828     # s.sy == '{'
829     pos = s.position()
830     s.next()
831     if s.sy == '}':
832         s.next()
833         return ExprNodes.DictNode(pos, key_value_pairs = [])
834     item = p_simple_expr(s)
835     if s.sy == ',' or s.sy == '}':
836         # set literal
837         values = [item]
838         while s.sy == ',':
839             s.next()
840             if s.sy == '}':
841                 break
842             values.append( p_simple_expr(s) )
843         s.expect('}')
844         return ExprNodes.SetNode(pos, args=values)
845     elif s.sy == 'for':
846         # set comprehension
847         target = ExprNodes.SetNode(pos, args=[])
848         append = ExprNodes.ComprehensionAppendNode(
849             item.pos, expr=item, target=ExprNodes.CloneNode(target))
850         loop = p_comp_for(s, Nodes.ExprStatNode(append.pos, expr=append))
851         s.expect('}')
852         return ExprNodes.ComprehensionNode(
853             pos, loop=loop, append=append, target=target)
854     elif s.sy == ':':
855         # dict literal or comprehension
856         key = item
857         s.next()
858         value = p_simple_expr(s)
859         if s.sy == 'for':
860             # dict comprehension
861             target = ExprNodes.DictNode(pos, key_value_pairs = [])
862             append = ExprNodes.DictComprehensionAppendNode(
863                 item.pos, key_expr=key, value_expr=value,
864                 target=ExprNodes.CloneNode(target))
865             loop = p_comp_for(s, Nodes.ExprStatNode(append.pos, expr=append))
866             s.expect('}')
867             return ExprNodes.ComprehensionNode(
868                 pos, loop=loop, append=append, target=target)
869         else:
870             # dict literal
871             items = [ExprNodes.DictItemNode(key.pos, key=key, value=value)]
872             while s.sy == ',':
873                 s.next()
874                 if s.sy == '}':
875                     break
876                 key = p_simple_expr(s)
877                 s.expect(':')
878                 value = p_simple_expr(s)
879                 items.append(
880                     ExprNodes.DictItemNode(key.pos, key=key, value=value))
881             s.expect('}')
882             return ExprNodes.DictNode(pos, key_value_pairs=items)
883     else:
884         # raise an error
885         s.expect('}')
886     return ExprNodes.DictNode(pos, key_value_pairs = [])
887
888 def p_backquote_expr(s):
889     # s.sy == '`'
890     pos = s.position()
891     s.next()
892     arg = p_expr(s)
893     s.expect('`')
894     return ExprNodes.BackquoteNode(pos, arg = arg)
895
896 def p_simple_expr_list(s):
897     exprs = []
898     while s.sy not in expr_terminators:
899         expr = p_simple_expr(s)
900         exprs.append(expr)
901         if s.sy != ',':
902             break
903         s.next()
904     return exprs
905
906 def p_expr(s):
907     pos = s.position()
908     expr = p_simple_expr(s)
909     if s.sy == ',':
910         s.next()
911         exprs = [expr] + p_simple_expr_list(s)
912         return ExprNodes.TupleNode(pos, args = exprs)
913     else:
914         return expr
915
916
917 #testlist: test (',' test)* [',']
918 # differs from p_expr only in the fact that it cannot contain conditional expressions
919
920 def p_testlist(s):
921     pos = s.position()
922     expr = p_test(s)
923     if s.sy == ',':
924         exprs = [expr]
925         while s.sy == ',':
926             s.next()
927             exprs.append(p_test(s))
928         return ExprNodes.TupleNode(pos, args = exprs)
929     else:
930         return expr
931         
932 expr_terminators = (')', ']', '}', ':', '=', 'NEWLINE')
933
934 #-------------------------------------------------------
935 #
936 #   Statements
937 #
938 #-------------------------------------------------------
939
940 def p_global_statement(s):
941     # assume s.sy == 'global'
942     pos = s.position()
943     s.next()
944     names = p_ident_list(s)
945     return Nodes.GlobalNode(pos, names = names)
946
947 def p_expression_or_assignment(s):
948     expr_list = [p_expr(s)]
949     while s.sy == '=':
950         s.next()
951         expr_list.append(p_expr(s))
952     if len(expr_list) == 1:
953         if re.match(r"([+*/\%^\&|-]|<<|>>|\*\*|//)=", s.sy):
954             lhs = expr_list[0]
955             if not isinstance(lhs, (ExprNodes.AttributeNode, ExprNodes.IndexNode, ExprNodes.NameNode) ):
956                 error(lhs.pos, "Illegal operand for inplace operation.")
957             operator = s.sy[:-1]
958             s.next()
959             rhs = p_expr(s)
960             return Nodes.InPlaceAssignmentNode(lhs.pos, operator = operator, lhs = lhs, rhs = rhs)
961         expr = expr_list[0]
962         if isinstance(expr, (ExprNodes.UnicodeNode, ExprNodes.StringNode, ExprNodes.BytesNode)):
963             return Nodes.PassStatNode(expr.pos)
964         else:
965             return Nodes.ExprStatNode(expr.pos, expr = expr)
966
967     rhs = expr_list[-1]
968     if len(expr_list) == 2:
969         return Nodes.SingleAssignmentNode(rhs.pos, 
970             lhs = expr_list[0], rhs = rhs)
971     else:
972         return Nodes.CascadedAssignmentNode(rhs.pos,
973             lhs_list = expr_list[:-1], rhs = rhs)
974
975 def p_print_statement(s):
976     # s.sy == 'print'
977     pos = s.position()
978     ends_with_comma = 0
979     s.next()
980     if s.sy == '>>':
981         s.next()
982         stream = p_simple_expr(s)
983         if s.sy == ',':
984             s.next()
985             ends_with_comma = s.sy in ('NEWLINE', 'EOF')
986     else:
987         stream = None
988     args = []
989     if s.sy not in ('NEWLINE', 'EOF'):
990         args.append(p_simple_expr(s))
991         while s.sy == ',':
992             s.next()
993             if s.sy in ('NEWLINE', 'EOF'):
994                 ends_with_comma = 1
995                 break
996             args.append(p_simple_expr(s))
997     arg_tuple = ExprNodes.TupleNode(pos, args = args)
998     return Nodes.PrintStatNode(pos,
999         arg_tuple = arg_tuple, stream = stream,
1000         append_newline = not ends_with_comma)
1001
1002 def p_exec_statement(s):
1003     # s.sy == 'exec'
1004     pos = s.position()
1005     s.next()
1006     args = [ p_bit_expr(s) ]
1007     if s.sy == 'in':
1008         s.next()
1009         args.append(p_simple_expr(s))
1010         if s.sy == ',':
1011             s.next()
1012             args.append(p_simple_expr(s))
1013     else:
1014         error(pos, "'exec' currently requires a target mapping (globals/locals)")
1015     return Nodes.ExecStatNode(pos, args = args)
1016
1017 def p_del_statement(s):
1018     # s.sy == 'del'
1019     pos = s.position()
1020     s.next()
1021     args = p_simple_expr_list(s)
1022     return Nodes.DelStatNode(pos, args = args)
1023
1024 def p_pass_statement(s, with_newline = 0):
1025     pos = s.position()
1026     s.expect('pass')
1027     if with_newline:
1028         s.expect_newline("Expected a newline")
1029     return Nodes.PassStatNode(pos)
1030
1031 def p_break_statement(s):
1032     # s.sy == 'break'
1033     pos = s.position()
1034     s.next()
1035     return Nodes.BreakStatNode(pos)
1036
1037 def p_continue_statement(s):
1038     # s.sy == 'continue'
1039     pos = s.position()
1040     s.next()
1041     return Nodes.ContinueStatNode(pos)
1042
1043 def p_return_statement(s):
1044     # s.sy == 'return'
1045     pos = s.position()
1046     s.next()
1047     if s.sy not in statement_terminators:
1048         value = p_expr(s)
1049     else:
1050         value = None
1051     return Nodes.ReturnStatNode(pos, value = value)
1052
1053 def p_raise_statement(s):
1054     # s.sy == 'raise'
1055     pos = s.position()
1056     s.next()
1057     exc_type = None
1058     exc_value = None
1059     exc_tb = None
1060     if s.sy not in statement_terminators:
1061         exc_type = p_simple_expr(s)
1062         if s.sy == ',':
1063             s.next()
1064             exc_value = p_simple_expr(s)
1065             if s.sy == ',':
1066                 s.next()
1067                 exc_tb = p_simple_expr(s)
1068     if exc_type or exc_value or exc_tb:
1069         return Nodes.RaiseStatNode(pos, 
1070             exc_type = exc_type,
1071             exc_value = exc_value,
1072             exc_tb = exc_tb)
1073     else:
1074         return Nodes.ReraiseStatNode(pos)
1075
1076 def p_import_statement(s):
1077     # s.sy in ('import', 'cimport')
1078     pos = s.position()
1079     kind = s.sy
1080     s.next()
1081     items = [p_dotted_name(s, as_allowed = 1)]
1082     while s.sy == ',':
1083         s.next()
1084         items.append(p_dotted_name(s, as_allowed = 1))
1085     stats = []
1086     for pos, target_name, dotted_name, as_name in items:
1087         dotted_name = EncodedString(dotted_name)
1088         if kind == 'cimport':
1089             stat = Nodes.CImportStatNode(pos, 
1090                 module_name = dotted_name,
1091                 as_name = as_name)
1092         else:
1093             if as_name and "." in dotted_name:
1094                 name_list = ExprNodes.ListNode(pos, args = [
1095                         ExprNodes.IdentifierStringNode(pos, value = EncodedString("*"))])
1096             else:
1097                 name_list = None
1098             stat = Nodes.SingleAssignmentNode(pos,
1099                 lhs = ExprNodes.NameNode(pos, 
1100                     name = as_name or target_name),
1101                 rhs = ExprNodes.ImportNode(pos, 
1102                     module_name = ExprNodes.IdentifierStringNode(
1103                         pos, value = dotted_name),
1104                     name_list = name_list))
1105         stats.append(stat)
1106     return Nodes.StatListNode(pos, stats = stats)
1107
1108 def p_from_import_statement(s, first_statement = 0):
1109     # s.sy == 'from'
1110     pos = s.position()
1111     s.next()
1112     (dotted_name_pos, _, dotted_name, _) = \
1113         p_dotted_name(s, as_allowed = 0)
1114     if s.sy in ('import', 'cimport'):
1115         kind = s.sy
1116         s.next()
1117     else:
1118         s.error("Expected 'import' or 'cimport'")
1119     is_cimport = kind == 'cimport'
1120     is_parenthesized = False
1121     if s.sy == '*':
1122         imported_names = [(s.position(), "*", None, None)]
1123         s.next()
1124     else:
1125         if s.sy == '(':
1126             is_parenthesized = True
1127             s.next()
1128         imported_names = [p_imported_name(s, is_cimport)]
1129     while s.sy == ',':
1130         s.next()
1131         if is_parenthesized and s.sy == ')':
1132             break
1133         imported_names.append(p_imported_name(s, is_cimport))
1134     if is_parenthesized:
1135         s.expect(')')
1136     dotted_name = EncodedString(dotted_name)
1137     if dotted_name == '__future__':
1138         if not first_statement:
1139             s.error("from __future__ imports must occur at the beginning of the file")
1140         else:
1141             for (name_pos, name, as_name, kind) in imported_names:
1142                 if name == "braces":
1143                     s.error("not a chance", name_pos)
1144                     break
1145                 try:
1146                     directive = getattr(Future, name)
1147                 except AttributeError:
1148                     s.error("future feature %s is not defined" % name, name_pos)
1149                     break
1150                 s.context.future_directives.add(directive)
1151         return Nodes.PassStatNode(pos)
1152     elif kind == 'cimport':
1153         return Nodes.FromCImportStatNode(pos,
1154             module_name = dotted_name,
1155             imported_names = imported_names)
1156     else:
1157         imported_name_strings = []
1158         items = []
1159         for (name_pos, name, as_name, kind) in imported_names:
1160             encoded_name = EncodedString(name)
1161             imported_name_strings.append(
1162                 ExprNodes.IdentifierStringNode(name_pos, value = encoded_name))
1163             items.append(
1164                 (name,
1165                  ExprNodes.NameNode(name_pos, 
1166                                     name = as_name or name)))
1167         import_list = ExprNodes.ListNode(
1168             imported_names[0][0], args = imported_name_strings)
1169         dotted_name = EncodedString(dotted_name)
1170         return Nodes.FromImportStatNode(pos,
1171             module = ExprNodes.ImportNode(dotted_name_pos,
1172                 module_name = ExprNodes.IdentifierStringNode(pos, value = dotted_name),
1173                 name_list = import_list),
1174             items = items)
1175
1176 imported_name_kinds = ('class', 'struct', 'union')
1177
1178 def p_imported_name(s, is_cimport):
1179     pos = s.position()
1180     kind = None
1181     if is_cimport and s.systring in imported_name_kinds:
1182         kind = s.systring
1183         s.next()
1184     name = p_ident(s)
1185     as_name = p_as_name(s)
1186     return (pos, name, as_name, kind)
1187
1188 def p_dotted_name(s, as_allowed):
1189     pos = s.position()
1190     target_name = p_ident(s)
1191     as_name = None
1192     names = [target_name]
1193     while s.sy == '.':
1194         s.next()
1195         names.append(p_ident(s))
1196     if as_allowed:
1197         as_name = p_as_name(s)
1198     return (pos, target_name, u'.'.join(names), as_name)
1199
1200 def p_as_name(s):
1201     if s.sy == 'IDENT' and s.systring == 'as':
1202         s.next()
1203         return p_ident(s)
1204     else:
1205         return None
1206
1207 def p_assert_statement(s):
1208     # s.sy == 'assert'
1209     pos = s.position()
1210     s.next()
1211     cond = p_simple_expr(s)
1212     if s.sy == ',':
1213         s.next()
1214         value = p_simple_expr(s)
1215     else:
1216         value = None
1217     return Nodes.AssertStatNode(pos, cond = cond, value = value)
1218
1219 statement_terminators = (';', 'NEWLINE', 'EOF')
1220
1221 def p_if_statement(s):
1222     # s.sy == 'if'
1223     pos = s.position()
1224     s.next()
1225     if_clauses = [p_if_clause(s)]
1226     while s.sy == 'elif':
1227         s.next()
1228         if_clauses.append(p_if_clause(s))
1229     else_clause = p_else_clause(s)
1230     return Nodes.IfStatNode(pos,
1231         if_clauses = if_clauses, else_clause = else_clause)
1232
1233 def p_if_clause(s):
1234     pos = s.position()
1235     test = p_simple_expr(s)
1236     body = p_suite(s)
1237     return Nodes.IfClauseNode(pos,
1238         condition = test, body = body)
1239
1240 def p_else_clause(s):
1241     if s.sy == 'else':
1242         s.next()
1243         return p_suite(s)
1244     else:
1245         return None
1246
1247 def p_while_statement(s):
1248     # s.sy == 'while'
1249     pos = s.position()
1250     s.next()
1251     test = p_simple_expr(s)
1252     body = p_suite(s)
1253     else_clause = p_else_clause(s)
1254     return Nodes.WhileStatNode(pos, 
1255         condition = test, body = body, 
1256         else_clause = else_clause)
1257
1258 def p_for_statement(s):
1259     # s.sy == 'for'
1260     pos = s.position()
1261     s.next()
1262     kw = p_for_bounds(s)
1263     kw['body'] = p_suite(s)
1264     kw['else_clause'] = p_else_clause(s)
1265     return Nodes.ForStatNode(pos, **kw)
1266             
1267 def p_for_bounds(s):
1268     target = p_for_target(s)
1269     if s.sy == 'in':
1270         s.next()
1271         iterator = p_for_iterator(s)
1272         return { 'target': target, 'iterator': iterator }
1273     else:
1274         if s.sy == 'from':
1275             s.next()
1276             bound1 = p_bit_expr(s)
1277         else:
1278             # Support shorter "for a <= x < b" syntax
1279             bound1, target = target, None
1280         rel1 = p_for_from_relation(s)
1281         name2_pos = s.position()
1282         name2 = p_ident(s)
1283         rel2_pos = s.position()
1284         rel2 = p_for_from_relation(s)
1285         bound2 = p_bit_expr(s)
1286         step = p_for_from_step(s)
1287         if target is None:
1288             target = ExprNodes.NameNode(name2_pos, name = name2)
1289         else:
1290             if not target.is_name:
1291                 error(target.pos, 
1292                     "Target of for-from statement must be a variable name")
1293             elif name2 != target.name:
1294                 error(name2_pos,
1295                     "Variable name in for-from range does not match target")
1296         if rel1[0] != rel2[0]:
1297             error(rel2_pos,
1298                 "Relation directions in for-from do not match")
1299         return {'target': target, 
1300                 'bound1': bound1, 
1301                 'relation1': rel1, 
1302                 'relation2': rel2,
1303                 'bound2': bound2,
1304                 'step': step }
1305
1306 def p_for_from_relation(s):
1307     if s.sy in inequality_relations:
1308         op = s.sy
1309         s.next()
1310         return op
1311     else:
1312         s.error("Expected one of '<', '<=', '>' '>='")
1313
1314 def p_for_from_step(s):
1315     if s.sy == 'by':
1316         s.next()
1317         step = p_bit_expr(s)
1318         return step
1319     else:
1320         return None
1321
1322 inequality_relations = ('<', '<=', '>', '>=')
1323
1324 def p_target(s, terminator):
1325     pos = s.position()
1326     expr = p_starred_expr(s)
1327     if s.sy == ',':
1328         s.next()
1329         exprs = [expr]
1330         while s.sy != terminator:
1331             exprs.append(p_starred_expr(s))
1332             if s.sy != ',':
1333                 break
1334             s.next()
1335         return ExprNodes.TupleNode(pos, args = exprs)
1336     else:
1337         return expr
1338
1339 def p_for_target(s):
1340     return p_target(s, 'in')
1341
1342 def p_for_iterator(s):
1343     pos = s.position()
1344     expr = p_testlist(s)
1345     return ExprNodes.IteratorNode(pos, sequence = expr)
1346
1347 def p_try_statement(s):
1348     # s.sy == 'try'
1349     pos = s.position()
1350     s.next()
1351     body = p_suite(s)
1352     except_clauses = []
1353     else_clause = None
1354     if s.sy in ('except', 'else'):
1355         while s.sy == 'except':
1356             except_clauses.append(p_except_clause(s))
1357         if s.sy == 'else':
1358             s.next()
1359             else_clause = p_suite(s)
1360         body = Nodes.TryExceptStatNode(pos,
1361             body = body, except_clauses = except_clauses,
1362             else_clause = else_clause)
1363         if s.sy != 'finally':
1364             return body
1365         # try-except-finally is equivalent to nested try-except/try-finally
1366     if s.sy == 'finally':
1367         s.next()
1368         finally_clause = p_suite(s)
1369         return Nodes.TryFinallyStatNode(pos,
1370             body = body, finally_clause = finally_clause)
1371     else:
1372         s.error("Expected 'except' or 'finally'")
1373
1374 def p_except_clause(s):
1375     # s.sy == 'except'
1376     pos = s.position()
1377     s.next()
1378     exc_type = None
1379     exc_value = None
1380     if s.sy != ':':
1381         exc_type = p_simple_expr(s)
1382         if s.sy == ',' or (s.sy == 'IDENT' and s.systring == 'as'):
1383             s.next()
1384             exc_value = p_simple_expr(s)
1385         elif s.sy == 'IDENT' and s.systring == 'as':
1386             # Py3 syntax requires a name here
1387             s.next()
1388             pos2 = s.position()
1389             name = p_ident(s)
1390             exc_value = ExprNodes.NameNode(pos2, name = name)
1391     body = p_suite(s)
1392     return Nodes.ExceptClauseNode(pos,
1393         pattern = exc_type, target = exc_value, body = body)
1394
1395 def p_include_statement(s, ctx):
1396     pos = s.position()
1397     s.next() # 'include'
1398     _, include_file_name = p_string_literal(s)
1399     s.expect_newline("Syntax error in include statement")
1400     if s.compile_time_eval:
1401         include_file_name = include_file_name.decode(s.source_encoding)
1402         include_file_path = s.context.find_include_file(include_file_name, pos)
1403         if include_file_path:
1404             s.included_files.append(include_file_name)
1405             f = Utils.open_source_file(include_file_path, mode="rU")
1406             source_desc = FileSourceDescriptor(include_file_path)
1407             s2 = PyrexScanner(f, source_desc, s, source_encoding=f.encoding, parse_comments=s.parse_comments)
1408             try:
1409                 tree = p_statement_list(s2, ctx)
1410             finally:
1411                 f.close()
1412             return tree
1413         else:
1414             return None
1415     else:
1416         return Nodes.PassStatNode(pos)
1417
1418 def p_with_statement(s):
1419     pos = s.position()
1420     s.next() # 'with'
1421 #    if s.sy == 'IDENT' and s.systring in ('gil', 'nogil'):
1422     if s.sy == 'IDENT' and s.systring == 'nogil':
1423         state = s.systring
1424         s.next()
1425         body = p_suite(s)
1426         return Nodes.GILStatNode(pos, state = state, body = body)
1427     elif s.systring == 'template':
1428         templates = []
1429         s.next()
1430         s.expect('[')
1431         #s.next()
1432         templates.append(s.systring)
1433         s.next()
1434         while s.systring == ',':
1435             s.next()
1436             templates.append(s.systring)
1437             s.next()
1438         s.expect(']')
1439         if s.sy == ':':
1440             s.next()
1441             s.expect_newline("Syntax error in template function declaration")
1442             s.expect_indent()
1443             body_ctx = Ctx()
1444             body_ctx.templates = templates
1445             func_or_var = p_c_func_or_var_declaration(s, pos, body_ctx)
1446             s.expect_dedent()
1447             return func_or_var
1448         else:
1449             error(pos, "Syntax error in template function declaration")
1450     else:
1451         manager = p_expr(s)
1452         target = None
1453         if s.sy == 'IDENT' and s.systring == 'as':
1454             s.next()
1455             allow_multi = (s.sy == '(')
1456             target = p_target(s, ':')
1457             if not allow_multi and isinstance(target, ExprNodes.TupleNode):
1458                 s.error("Multiple with statement target values not allowed without paranthesis")
1459         body = p_suite(s)
1460     return Nodes.WithStatNode(pos, manager = manager, 
1461                               target = target, body = body)
1462     
1463 def p_simple_statement(s, first_statement = 0):
1464     #print "p_simple_statement:", s.sy, s.systring ###
1465     if s.sy == 'global':
1466         node = p_global_statement(s)
1467     elif s.sy == 'print':
1468         node = p_print_statement(s)
1469     elif s.sy == 'exec':
1470         node = p_exec_statement(s)
1471     elif s.sy == 'del':
1472         node = p_del_statement(s)
1473     elif s.sy == 'break':
1474         node = p_break_statement(s)
1475     elif s.sy == 'continue':
1476         node = p_continue_statement(s)
1477     elif s.sy == 'return':
1478         node = p_return_statement(s)
1479     elif s.sy == 'raise':
1480         node = p_raise_statement(s)
1481     elif s.sy in ('import', 'cimport'):
1482         node = p_import_statement(s)
1483     elif s.sy == 'from':
1484         node = p_from_import_statement(s, first_statement = first_statement)
1485     elif s.sy == 'yield':
1486         node = p_yield_statement(s)
1487     elif s.sy == 'assert':
1488         node = p_assert_statement(s)
1489     elif s.sy == 'pass':
1490         node = p_pass_statement(s)
1491     else:
1492         node = p_expression_or_assignment(s)
1493     return node
1494
1495 def p_simple_statement_list(s, ctx, first_statement = 0):
1496     # Parse a series of simple statements on one line
1497     # separated by semicolons.
1498     stat = p_simple_statement(s, first_statement = first_statement)
1499     if s.sy == ';':
1500         stats = [stat]
1501         while s.sy == ';':
1502             #print "p_simple_statement_list: maybe more to follow" ###
1503             s.next()
1504             if s.sy in ('NEWLINE', 'EOF'):
1505                 break
1506             stats.append(p_simple_statement(s))
1507         stat = Nodes.StatListNode(stats[0].pos, stats = stats)
1508     s.expect_newline("Syntax error in simple statement list")
1509     return stat
1510
1511 def p_compile_time_expr(s):
1512     old = s.compile_time_expr
1513     s.compile_time_expr = 1
1514     expr = p_expr(s)
1515     s.compile_time_expr = old
1516     return expr
1517
1518 def p_DEF_statement(s):
1519     pos = s.position()
1520     denv = s.compile_time_env
1521     s.next() # 'DEF'
1522     name = p_ident(s)
1523     s.expect('=')
1524     expr = p_compile_time_expr(s)
1525     value = expr.compile_time_value(denv)
1526     #print "p_DEF_statement: %s = %r" % (name, value) ###
1527     denv.declare(name, value)
1528     s.expect_newline()
1529     return Nodes.PassStatNode(pos)
1530
1531 def p_IF_statement(s, ctx):
1532     pos = s.position()
1533     saved_eval = s.compile_time_eval
1534     current_eval = saved_eval
1535     denv = s.compile_time_env
1536     result = None
1537     while 1:
1538         s.next() # 'IF' or 'ELIF'
1539         expr = p_compile_time_expr(s)
1540         s.compile_time_eval = current_eval and bool(expr.compile_time_value(denv))
1541         body = p_suite(s, ctx)
1542         if s.compile_time_eval:
1543             result = body
1544             current_eval = 0
1545         if s.sy != 'ELIF':
1546             break
1547     if s.sy == 'ELSE':
1548         s.next()
1549         s.compile_time_eval = current_eval
1550         body = p_suite(s, ctx)
1551         if current_eval:
1552             result = body
1553     if not result:
1554         result = Nodes.PassStatNode(pos)
1555     s.compile_time_eval = saved_eval
1556     return result
1557
1558 def p_statement(s, ctx, first_statement = 0):
1559     cdef_flag = ctx.cdef_flag
1560     decorators = None
1561     if s.sy == 'ctypedef':
1562         if ctx.level not in ('module', 'module_pxd'):
1563             s.error("ctypedef statement not allowed here")
1564         #if ctx.api:
1565         #    error(s.position(), "'api' not allowed with 'ctypedef'")
1566         return p_ctypedef_statement(s, ctx)
1567     elif s.sy == 'DEF':
1568         return p_DEF_statement(s)
1569     elif s.sy == 'IF':
1570         return p_IF_statement(s, ctx)
1571     elif s.sy == 'DECORATOR':
1572         if ctx.level not in ('module', 'class', 'c_class', 'function', 'property', 'module_pxd', 'c_class_pxd'):
1573             print ctx.level
1574             s.error('decorator not allowed here')
1575         s.level = ctx.level
1576         decorators = p_decorators(s)
1577         if s.sy not in ('def', 'cdef', 'cpdef', 'class'):
1578             s.error("Decorators can only be followed by functions or classes")
1579     elif s.sy == 'pass' and cdef_flag:
1580         # empty cdef block
1581         return p_pass_statement(s, with_newline = 1)
1582
1583     overridable = 0
1584     if s.sy == 'cdef':
1585         cdef_flag = 1
1586         s.next()
1587     elif s.sy == 'cpdef':
1588         cdef_flag = 1
1589         overridable = 1
1590         s.next()
1591     if cdef_flag:
1592         if ctx.level not in ('module', 'module_pxd', 'function', 'c_class', 'c_class_pxd'):
1593             s.error('cdef statement not allowed here')
1594         s.level = ctx.level
1595         node = p_cdef_statement(s, ctx(overridable = overridable))
1596         if decorators is not None:
1597             if not isinstance(node, (Nodes.CFuncDefNode, Nodes.CVarDefNode)):
1598                 s.error("Decorators can only be followed by functions or Python classes")
1599             node.decorators = decorators
1600         return node
1601     else:
1602         if ctx.api:
1603             error(s.pos, "'api' not allowed with this statement")
1604         elif s.sy == 'def':
1605             # def statements aren't allowed in pxd files, except
1606             # as part of a cdef class
1607             if ('pxd' in ctx.level) and (ctx.level != 'c_class_pxd'):
1608                 s.error('def statement not allowed here')
1609             s.level = ctx.level
1610             return p_def_statement(s, decorators)
1611         elif s.sy == 'class':
1612             if ctx.level != 'module':
1613                 s.error("class definition not allowed here")
1614             return p_class_statement(s, decorators)
1615         elif s.sy == 'include':
1616             if ctx.level not in ('module', 'module_pxd'):
1617                 s.error("include statement not allowed here")
1618             return p_include_statement(s, ctx)
1619         elif ctx.level == 'c_class' and s.sy == 'IDENT' and s.systring == 'property':
1620             return p_property_decl(s)
1621         elif s.sy == 'pass' and ctx.level != 'property':
1622             return p_pass_statement(s, with_newline = 1)
1623         else:
1624             if ctx.level in ('c_class_pxd', 'property'):
1625                 s.error("Executable statement not allowed here")
1626             if s.sy == 'if':
1627                 return p_if_statement(s)
1628             elif s.sy == 'while':
1629                 return p_while_statement(s)
1630             elif s.sy == 'for':
1631                 return p_for_statement(s)
1632             elif s.sy == 'try':
1633                 return p_try_statement(s)
1634             elif s.sy == 'with':
1635                 return p_with_statement(s)
1636             else:
1637                 return p_simple_statement_list(
1638                     s, ctx, first_statement = first_statement)
1639
1640 def p_statement_list(s, ctx, first_statement = 0):
1641     # Parse a series of statements separated by newlines.
1642     pos = s.position()
1643     stats = []
1644     while s.sy not in ('DEDENT', 'EOF'):
1645         stats.append(p_statement(s, ctx, first_statement = first_statement))
1646         first_statement = 0
1647     if len(stats) == 1:
1648         return stats[0]
1649     else:
1650         return Nodes.StatListNode(pos, stats = stats)
1651
1652 def p_suite(s, ctx = Ctx(), with_doc = 0, with_pseudo_doc = 0):
1653     pos = s.position()
1654     s.expect(':')
1655     doc = None
1656     stmts = []
1657     if s.sy == 'NEWLINE':
1658         s.next()
1659         s.expect_indent()
1660         if with_doc or with_pseudo_doc:
1661             doc = p_doc_string(s)
1662         body = p_statement_list(s, ctx)
1663         s.expect_dedent()
1664     else:
1665         if ctx.api:
1666             error(s.pos, "'api' not allowed with this statement")
1667         if ctx.level in ('module', 'class', 'function', 'other'):
1668             body = p_simple_statement_list(s, ctx)
1669         else:
1670             body = p_pass_statement(s)
1671             s.expect_newline("Syntax error in declarations")
1672     if with_doc:
1673         return doc, body
1674     else:
1675         return body
1676
1677 def p_positional_and_keyword_args(s, end_sy_set, templates = None):
1678     """
1679     Parses positional and keyword arguments. end_sy_set
1680     should contain any s.sy that terminate the argument list.
1681     Argument expansion (* and **) are not allowed.
1682
1683     Returns: (positional_args, keyword_args)
1684     """
1685     positional_args = []
1686     keyword_args = []
1687     pos_idx = 0
1688
1689     while s.sy not in end_sy_set:
1690         if s.sy == '*' or s.sy == '**':
1691             s.error('Argument expansion not allowed here.')
1692
1693         parsed_type = False
1694         if s.sy == 'IDENT' and s.peek()[0] == '=':
1695             ident = s.systring
1696             s.next() # s.sy is '='
1697             s.next()
1698             if looking_at_expr(s):
1699                 arg = p_simple_expr(s)
1700             else:
1701                 base_type = p_c_base_type(s, templates = templates)
1702                 declarator = p_c_declarator(s, empty = 1)
1703                 arg = Nodes.CComplexBaseTypeNode(base_type.pos, 
1704                     base_type = base_type, declarator = declarator)
1705                 parsed_type = True
1706             keyword_node = ExprNodes.IdentifierStringNode(
1707                 arg.pos, value = EncodedString(ident))
1708             keyword_args.append((keyword_node, arg))
1709             was_keyword = True
1710                 
1711         else:
1712             if looking_at_expr(s):
1713                 arg = p_simple_expr(s)
1714             else:
1715                 base_type = p_c_base_type(s, templates = templates)
1716                 declarator = p_c_declarator(s, empty = 1)
1717                 arg = Nodes.CComplexBaseTypeNode(base_type.pos, 
1718                     base_type = base_type, declarator = declarator)
1719                 parsed_type = True
1720             positional_args.append(arg)
1721             pos_idx += 1
1722             if len(keyword_args) > 0:
1723                 s.error("Non-keyword arg following keyword arg",
1724                         pos = arg.pos)
1725
1726         if s.sy != ',':
1727             if s.sy not in end_sy_set:
1728                 if parsed_type:
1729                     s.error("Unmatched %s" % " or ".join(end_sy_set))
1730             break
1731         s.next()
1732     return positional_args, keyword_args
1733
1734 def p_c_base_type(s, self_flag = 0, nonempty = 0, templates = None):
1735     # If self_flag is true, this is the base type for the
1736     # self argument of a C method of an extension type.
1737     if s.sy == '(':
1738         return p_c_complex_base_type(s)
1739     else:
1740         return p_c_simple_base_type(s, self_flag, nonempty = nonempty, templates = templates)
1741
1742 def p_calling_convention(s):
1743     if s.sy == 'IDENT' and s.systring in calling_convention_words:
1744         result = s.systring
1745         s.next()
1746         return result
1747     else:
1748         return ""
1749
1750 calling_convention_words = ("__stdcall", "__cdecl", "__fastcall")
1751
1752 def p_c_complex_base_type(s):
1753     # s.sy == '('
1754     pos = s.position()
1755     s.next()
1756     base_type = p_c_base_type(s)
1757     declarator = p_c_declarator(s, empty = 1)
1758     s.expect(')')
1759     return Nodes.CComplexBaseTypeNode(pos, 
1760         base_type = base_type, declarator = declarator)
1761
1762 def p_c_simple_base_type(s, self_flag, nonempty, templates = None):
1763     #print "p_c_simple_base_type: self_flag =", self_flag, nonempty
1764     is_basic = 0
1765     signed = 1
1766     longness = 0
1767     complex = 0
1768     module_path = []
1769     pos = s.position()
1770     if not s.sy == 'IDENT':
1771         error(pos, "Expected an identifier, found '%s'" % s.sy)
1772     if looking_at_base_type(s):
1773         #print "p_c_simple_base_type: looking_at_base_type at", s.position()
1774         is_basic = 1
1775         if s.sy == 'IDENT' and s.systring in special_basic_c_types:
1776             signed, longness = special_basic_c_types[s.systring]
1777             name = s.systring
1778             s.next()
1779         else:
1780             signed, longness = p_sign_and_longness(s)
1781             if s.sy == 'IDENT' and s.systring in basic_c_type_names:
1782                 name = s.systring
1783                 s.next()
1784             else:
1785                 name = 'int'
1786         if s.sy == 'IDENT' and s.systring == 'complex':
1787             complex = 1
1788             s.next()
1789     elif looking_at_dotted_name(s):
1790         #print "p_c_simple_base_type: looking_at_type_name at", s.position()
1791         name = s.systring
1792         s.next()
1793         while s.sy == '.':
1794             module_path.append(name)
1795             s.next()
1796             name = p_ident(s)
1797     else:
1798         name = s.systring
1799         s.next()
1800         if nonempty and s.sy != 'IDENT':
1801             # Make sure this is not a declaration of a variable or function.  
1802             if s.sy == '(':
1803                 s.next()
1804                 if s.sy == '*' or s.sy == '**' or s.sy == '&':
1805                     s.put_back('(', '(')
1806                 else:
1807                     s.put_back('(', '(')
1808                     s.put_back('IDENT', name)
1809                     name = None
1810             elif s.sy not in ('*', '**', '[', '&'):
1811                 s.put_back('IDENT', name)
1812                 name = None
1813
1814     type_node = Nodes.CSimpleBaseTypeNode(pos, 
1815         name = name, module_path = module_path,
1816         is_basic_c_type = is_basic, signed = signed,
1817         complex = complex, longness = longness, 
1818         is_self_arg = self_flag, templates = templates)
1819
1820     if s.sy == '[':
1821         type_node = p_buffer_or_template(s, type_node, templates)
1822     
1823     if s.sy == '.':
1824         s.next()
1825         name = p_ident(s)
1826         type_node = Nodes.CNestedBaseTypeNode(pos, base_type = type_node, name = name)
1827     
1828     return type_node
1829
1830 def p_buffer_or_template(s, base_type_node, templates):
1831     # s.sy == '['
1832     pos = s.position()
1833     s.next()
1834     # Note that buffer_positional_options_count=1, so the only positional argument is dtype. 
1835     # For templated types, all parameters are types. 
1836     positional_args, keyword_args = (
1837         p_positional_and_keyword_args(s, (']',), templates)
1838     )
1839     s.expect(']')
1840
1841     keyword_dict = ExprNodes.DictNode(pos,
1842         key_value_pairs = [
1843             ExprNodes.DictItemNode(pos=key.pos, key=key, value=value)
1844             for key, value in keyword_args
1845         ])
1846     result = Nodes.TemplatedTypeNode(pos,
1847         positional_args = positional_args,
1848         keyword_args = keyword_dict,
1849         base_type_node = base_type_node)
1850     return result
1851     
1852
1853 def looking_at_name(s):
1854     return s.sy == 'IDENT' and not s.systring in calling_convention_words
1855
1856 def looking_at_expr(s):
1857     if s.systring in base_type_start_words:
1858         return False
1859     elif s.sy == 'IDENT':
1860         is_type = False
1861         name = s.systring
1862         dotted_path = []
1863         s.next()
1864         while s.sy == '.':
1865             s.next()
1866             dotted_path.append(s.systring)
1867             s.expect('IDENT')
1868         saved = s.sy, s.systring
1869         if s.sy == 'IDENT':
1870             is_type = True
1871         elif s.sy == '*' or s.sy == '**':
1872             s.next()
1873             is_type = s.sy == ')'
1874             s.put_back(*saved)
1875         elif s.sy == '(':
1876             s.next()
1877             is_type = s.sy == '*'
1878             s.put_back(*saved)
1879         elif s.sy == '[':
1880             s.next()
1881             is_type = s.sy == ']'
1882             s.put_back(*saved)
1883         dotted_path.reverse()
1884         for p in dotted_path:
1885             s.put_back('IDENT', p)
1886             s.put_back('.', '.')
1887         s.put_back('IDENT', name)
1888         return not is_type
1889     else:
1890         return True
1891
1892 def looking_at_base_type(s):
1893     #print "looking_at_base_type?", s.sy, s.systring, s.position()
1894     return s.sy == 'IDENT' and s.systring in base_type_start_words
1895
1896 def looking_at_dotted_name(s):
1897     if s.sy == 'IDENT':
1898         name = s.systring
1899         s.next()
1900         result = s.sy == '.'
1901         s.put_back('IDENT', name)
1902         return result
1903     else:
1904         return 0
1905
1906 basic_c_type_names = ("void", "char", "int", "float", "double", "bint")
1907
1908 special_basic_c_types = {
1909     # name : (signed, longness)
1910     "Py_ssize_t" : (2, 0),
1911     "size_t"     : (0, 0),
1912 }
1913
1914 sign_and_longness_words = ("short", "long", "signed", "unsigned")
1915
1916 base_type_start_words = \
1917     basic_c_type_names + sign_and_longness_words + tuple(special_basic_c_types)
1918
1919 def p_sign_and_longness(s):
1920     signed = 1
1921     longness = 0
1922     while s.sy == 'IDENT' and s.systring in sign_and_longness_words:
1923         if s.systring == 'unsigned':
1924             signed = 0
1925         elif s.systring == 'signed':
1926             signed = 2
1927         elif s.systring == 'short':
1928             longness = -1
1929         elif s.systring == 'long':
1930             longness += 1
1931         s.next()
1932     return signed, longness
1933
1934 def p_opt_cname(s):
1935     literal = p_opt_string_literal(s)
1936     if literal:
1937         _, cname = literal
1938         cname = EncodedString(cname)
1939         cname.encoding = s.source_encoding
1940     else:
1941         cname = None
1942     return cname
1943
1944 def p_c_declarator(s, ctx = Ctx(), empty = 0, is_type = 0, cmethod_flag = 0,
1945                    assignable = 0, nonempty = 0,
1946                    calling_convention_allowed = 0):
1947     # If empty is true, the declarator must be empty. If nonempty is true,
1948     # the declarator must be nonempty. Otherwise we don't care.
1949     # If cmethod_flag is true, then if this declarator declares
1950     # a function, it's a C method of an extension type.
1951     pos = s.position()
1952     if s.sy == '(':
1953         s.next()
1954         if s.sy == ')' or looking_at_name(s):
1955             base = Nodes.CNameDeclaratorNode(pos, name = EncodedString(u""), cname = None)
1956             result = p_c_func_declarator(s, pos, ctx, base, cmethod_flag)
1957         else:
1958             result = p_c_declarator(s, ctx, empty = empty, is_type = is_type,
1959                                     cmethod_flag = cmethod_flag,
1960                                     nonempty = nonempty,
1961                                     calling_convention_allowed = 1)
1962             s.expect(')')
1963     else:
1964         result = p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag,
1965                                        assignable, nonempty)
1966     if not calling_convention_allowed and result.calling_convention and s.sy != '(':
1967         error(s.position(), "%s on something that is not a function"
1968             % result.calling_convention)
1969     while s.sy in ('[', '('):
1970         pos = s.position()
1971         if s.sy == '[':
1972             result = p_c_array_declarator(s, result)
1973         else: # sy == '('
1974             s.next()
1975             result = p_c_func_declarator(s, pos, ctx, result, cmethod_flag)
1976         cmethod_flag = 0
1977     return result
1978
1979 def p_c_array_declarator(s, base):
1980     pos = s.position()
1981     s.next() # '['
1982     if s.sy != ']':
1983         dim = p_expr(s)
1984     else:
1985         dim = None
1986     s.expect(']')
1987     return Nodes.CArrayDeclaratorNode(pos, base = base, dimension = dim)
1988
1989 def p_c_func_declarator(s, pos, ctx, base, cmethod_flag):
1990     #  Opening paren has already been skipped
1991     args = p_c_arg_list(s, ctx, cmethod_flag = cmethod_flag,
1992                         nonempty_declarators = 0)
1993     ellipsis = p_optional_ellipsis(s)
1994     s.expect(')')
1995     nogil = p_nogil(s)
1996     exc_val, exc_check = p_exception_value_clause(s)
1997     with_gil = p_with_gil(s)
1998     return Nodes.CFuncDeclaratorNode(pos, 
1999         base = base, args = args, has_varargs = ellipsis,
2000         exception_value = exc_val, exception_check = exc_check,
2001         nogil = nogil or ctx.nogil or with_gil, with_gil = with_gil)
2002
2003 supported_overloaded_operators = set([
2004     '+', '-', '*', '/', '%', 
2005     '++', '--', '~', '|', '&', '^', '<<', '>>',
2006     '==', '!=', '>=', '>', '<=', '<',
2007     '[]', '()',
2008 ])
2009
2010 def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag,
2011                           assignable, nonempty):
2012     pos = s.position()
2013     calling_convention = p_calling_convention(s)
2014     if s.sy == '*':
2015         s.next()
2016         base = p_c_declarator(s, ctx, empty = empty, is_type = is_type,
2017                               cmethod_flag = cmethod_flag,
2018                               assignable = assignable, nonempty = nonempty)
2019         result = Nodes.CPtrDeclaratorNode(pos, 
2020             base = base)
2021     elif s.sy == '**': # scanner returns this as a single token
2022         s.next()
2023         base = p_c_declarator(s, ctx, empty = empty, is_type = is_type,
2024                               cmethod_flag = cmethod_flag,
2025                               assignable = assignable, nonempty = nonempty)
2026         result = Nodes.CPtrDeclaratorNode(pos,
2027             base = Nodes.CPtrDeclaratorNode(pos,
2028                 base = base))
2029     elif s.sy == '&':
2030         s.next()
2031         base = p_c_declarator(s, ctx, empty = empty, is_type = is_type,
2032                               cmethod_flag = cmethod_flag,
2033                               assignable = assignable, nonempty = nonempty)
2034         result = Nodes.CReferenceDeclaratorNode(pos, base = base)
2035     else:
2036         rhs = None
2037         if s.sy == 'IDENT':
2038             name = EncodedString(s.systring)
2039             if empty:
2040                 error(s.position(), "Declarator should be empty")
2041             s.next()
2042             cname = p_opt_cname(s)
2043             if name != "operator" and s.sy == '=' and assignable:
2044                 s.next()
2045                 rhs = p_simple_expr(s)
2046         else:
2047             if nonempty:
2048                 error(s.position(), "Empty declarator")
2049             name = ""
2050             cname = None
2051         if cname is None and ctx.namespace is not None:
2052             cname = ctx.namespace + "::" + name
2053         if name == 'operator' and ctx.visibility == 'extern':
2054             op = s.sy
2055             s.next()
2056             # Handle diphthong operators.
2057             if op == '(':
2058                 s.expect(')')
2059                 op = '()'
2060             elif op == '[':
2061                 s.expect(']')
2062                 op = '[]'
2063             if op in ['-', '+', '|', '&'] and s.sy == op:
2064                 op = op*2
2065                 s.next()
2066             if s.sy == '=':
2067                 op += s.sy
2068                 s.next()
2069             if op not in supported_overloaded_operators:
2070                 s.error("Overloading operator '%s' not yet supported." % op)
2071             name = name+op
2072         result = Nodes.CNameDeclaratorNode(pos,
2073             name = name, cname = cname, default = rhs)
2074     result.calling_convention = calling_convention
2075     return result
2076
2077 def p_nogil(s):
2078     if s.sy == 'IDENT' and s.systring == 'nogil':
2079         s.next()
2080         return 1
2081     else:
2082         return 0
2083
2084 def p_with_gil(s):
2085     if s.sy == 'with':
2086         s.next()
2087         s.expect_keyword('gil')
2088         return 1
2089     else:
2090         return 0
2091
2092 def p_exception_value_clause(s):
2093     exc_val = None
2094     exc_check = 0
2095     if s.sy == 'except':
2096         s.next()
2097         if s.sy == '*':
2098             exc_check = 1
2099             s.next()
2100         elif s.sy == '+':
2101             exc_check = '+'
2102             s.next()
2103             if s.sy == 'IDENT':
2104                 name = s.systring
2105                 s.next()
2106                 exc_val = p_name(s, name)
2107         else:
2108             if s.sy == '?':
2109                 exc_check = 1
2110                 s.next()
2111             exc_val = p_simple_expr(s)
2112     return exc_val, exc_check
2113
2114 c_arg_list_terminators = ('*', '**', '.', ')')
2115
2116 def p_c_arg_list(s, ctx = Ctx(), in_pyfunc = 0, cmethod_flag = 0,
2117                  nonempty_declarators = 0, kw_only = 0, annotated = 1):
2118     #  Comma-separated list of C argument declarations, possibly empty.
2119     #  May have a trailing comma.
2120     args = []
2121     is_self_arg = cmethod_flag
2122     while s.sy not in c_arg_list_terminators:
2123         args.append(p_c_arg_decl(s, ctx, in_pyfunc, is_self_arg,
2124             nonempty = nonempty_declarators, kw_only = kw_only,
2125             annotated = annotated))
2126         if s.sy != ',':
2127             break
2128         s.next()
2129         is_self_arg = 0
2130     return args
2131
2132 def p_optional_ellipsis(s):
2133     if s.sy == '.':
2134         expect_ellipsis(s)
2135         return 1
2136     else:
2137         return 0
2138
2139 def p_c_arg_decl(s, ctx, in_pyfunc, cmethod_flag = 0, nonempty = 0,
2140                  kw_only = 0, annotated = 1):
2141     pos = s.position()
2142     not_none = 0
2143     default = None
2144     annotation = None
2145     if s.in_python_file:
2146         # empty type declaration
2147         base_type = Nodes.CSimpleBaseTypeNode(pos,
2148             name = None, module_path = [],
2149             is_basic_c_type = 0, signed = 0,
2150             complex = 0, longness = 0,
2151             is_self_arg = cmethod_flag, templates = None)
2152     else:
2153         base_type = p_c_base_type(s, cmethod_flag, nonempty = nonempty)
2154     declarator = p_c_declarator(s, ctx, nonempty = nonempty)
2155     if s.sy == 'not' and not s.in_python_file:
2156         s.next()
2157         if s.sy == 'IDENT' and s.systring == 'None':
2158             s.next()
2159         else:
2160             s.error("Expected 'None'")
2161         if not in_pyfunc:
2162             error(pos, "'not None' only allowed in Python functions")
2163         not_none = 1
2164     if annotated and s.sy == ':':
2165         s.next()
2166         annotation = p_simple_expr(s)
2167     if s.sy == '=':
2168         s.next()
2169         if 'pxd' in s.level:
2170             if s.sy not in ['*', '?']:
2171                 error(pos, "default values cannot be specified in pxd files, use ? or *")
2172             default = ExprNodes.BoolNode(1)
2173             s.next()
2174         else:
2175             default = p_simple_expr(s)
2176     return Nodes.CArgDeclNode(pos,
2177         base_type = base_type,
2178         declarator = declarator,
2179         not_none = not_none,
2180         default = default,
2181         annotation = annotation,
2182         kw_only = kw_only)
2183
2184 def p_api(s):
2185     if s.sy == 'IDENT' and s.systring == 'api':
2186         s.next()
2187         return 1
2188     else:
2189         return 0
2190
2191 def p_cdef_statement(s, ctx):
2192     pos = s.position()
2193     ctx.visibility = p_visibility(s, ctx.visibility)
2194     ctx.api = ctx.api or p_api(s)
2195     if ctx.api:
2196         if ctx.visibility not in ('private', 'public'):
2197             error(pos, "Cannot combine 'api' with '%s'" % ctx.visibility)
2198     if (ctx.visibility == 'extern') and s.sy == 'from':
2199         return p_cdef_extern_block(s, pos, ctx)
2200     elif s.sy == 'import':
2201         s.next()
2202         return p_cdef_extern_block(s, pos, ctx)
2203     elif p_nogil(s):
2204         ctx.nogil = 1
2205         if ctx.overridable:
2206             error(pos, "cdef blocks cannot be declared cpdef")
2207         return p_cdef_block(s, ctx)
2208     elif s.sy == ':':
2209         if ctx.overridable:
2210             error(pos, "cdef blocks cannot be declared cpdef")
2211         return p_cdef_block(s, ctx)
2212     elif s.sy == 'class':
2213         if ctx.level not in ('module', 'module_pxd'):
2214             error(pos, "Extension type definition not allowed here")
2215         if ctx.overridable:
2216             error(pos, "Extension types cannot be declared cpdef")
2217         return p_c_class_definition(s, pos, ctx)
2218     elif s.sy == 'IDENT' and s.systring == 'cppclass':
2219         if ctx.visibility != 'extern':
2220             error(pos, "C++ classes need to be declared extern")
2221         return p_cpp_class_definition(s, pos, ctx)
2222     elif s.sy == 'IDENT' and s.systring in ("struct", "union", "enum", "packed"):
2223         if ctx.level not in ('module', 'module_pxd'):
2224             error(pos, "C struct/union/enum definition not allowed here")
2225         if ctx.overridable:
2226             error(pos, "C struct/union/enum cannot be declared cpdef")
2227         if s.systring == "enum":
2228             return p_c_enum_definition(s, pos, ctx)
2229         else:
2230             return p_c_struct_or_union_definition(s, pos, ctx)
2231     else:
2232         return p_c_func_or_var_declaration(s, pos, ctx)
2233
2234 def p_cdef_block(s, ctx):
2235     return p_suite(s, ctx(cdef_flag = 1))
2236
2237 def p_cdef_extern_block(s, pos, ctx):
2238     if ctx.overridable:
2239         error(pos, "cdef extern blocks cannot be declared cpdef")
2240     include_file = None
2241     s.expect('from')
2242     if s.sy == '*':
2243         s.next()
2244     else:
2245         _, include_file = p_string_literal(s)
2246     if s.systring == "namespace":
2247         s.next()
2248         ctx.namespace = p_string_literal(s)[1]
2249     ctx = ctx(cdef_flag = 1, visibility = 'extern')
2250     if p_nogil(s):
2251         ctx.nogil = 1
2252     body = p_suite(s, ctx)
2253     return Nodes.CDefExternNode(pos,
2254         include_file = include_file,
2255         body = body,
2256         namespace = ctx.namespace)
2257
2258 def p_c_enum_definition(s, pos, ctx):
2259     # s.sy == ident 'enum'
2260     s.next()
2261     if s.sy == 'IDENT':
2262         name = s.systring
2263         s.next()
2264         cname = p_opt_cname(s)
2265         if cname is None and ctx.namespace is not None:
2266             cname = ctx.namespace + "::" + name
2267     else:
2268         name = None
2269         cname = None
2270     items = None
2271     s.expect(':')
2272     items = []
2273     if s.sy != 'NEWLINE':
2274         p_c_enum_line(s, items)
2275     else:
2276         s.next() # 'NEWLINE'
2277         s.expect_indent()
2278         while s.sy not in ('DEDENT', 'EOF'):
2279             p_c_enum_line(s, items)
2280         s.expect_dedent()
2281     return Nodes.CEnumDefNode(
2282         pos, name = name, cname = cname, items = items,
2283         typedef_flag = ctx.typedef_flag, visibility = ctx.visibility,
2284         in_pxd = ctx.level == 'module_pxd')
2285
2286 def p_c_enum_line(s, items):
2287     if s.sy != 'pass':
2288         p_c_enum_item(s, items)
2289         while s.sy == ',':
2290             s.next()
2291             if s.sy in ('NEWLINE', 'EOF'):
2292                 break
2293             p_c_enum_item(s, items)
2294     else:
2295         s.next()
2296     s.expect_newline("Syntax error in enum item list")
2297
2298 def p_c_enum_item(s, items):
2299     pos = s.position()
2300     name = p_ident(s)
2301     cname = p_opt_cname(s)
2302     value = None
2303     if s.sy == '=':
2304         s.next()
2305         value = p_simple_expr(s)
2306     items.append(Nodes.CEnumDefItemNode(pos, 
2307         name = name, cname = cname, value = value))
2308
2309 def p_c_struct_or_union_definition(s, pos, ctx):
2310     packed = False
2311     if s.systring == 'packed':
2312         packed = True
2313         s.next()
2314         if s.sy != 'IDENT' or s.systring != 'struct':
2315             s.expected('struct')
2316     # s.sy == ident 'struct' or 'union'
2317     kind = s.systring
2318     s.next()
2319     name = p_ident(s)
2320     cname = p_opt_cname(s)
2321     if cname is None and ctx.namespace is not None:
2322         cname = ctx.namespace + "::" + name
2323     attributes = None
2324     if s.sy == ':':
2325         s.next()
2326         s.expect('NEWLINE')
2327         s.expect_indent()
2328         attributes = []
2329         body_ctx = Ctx()
2330         while s.sy != 'DEDENT':
2331             if s.sy != 'pass':
2332                 attributes.append(
2333                     p_c_func_or_var_declaration(s, s.position(), body_ctx))
2334             else:
2335                 s.next()
2336                 s.expect_newline("Expected a newline")
2337         s.expect_dedent()
2338     else:
2339         s.expect_newline("Syntax error in struct or union definition")
2340     return Nodes.CStructOrUnionDefNode(pos, 
2341         name = name, cname = cname, kind = kind, attributes = attributes,
2342         typedef_flag = ctx.typedef_flag, visibility = ctx.visibility,
2343         in_pxd = ctx.level == 'module_pxd', packed = packed)
2344
2345 def p_visibility(s, prev_visibility):
2346     pos = s.position()
2347     visibility = prev_visibility
2348     if s.sy == 'IDENT' and s.systring in ('extern', 'public', 'readonly'):
2349         visibility = s.systring
2350         if prev_visibility != 'private' and visibility != prev_visibility:
2351             s.error("Conflicting visibility options '%s' and '%s'"
2352                 % (prev_visibility, visibility))
2353         s.next()
2354     return visibility
2355     
2356 def p_c_modifiers(s):
2357     if s.sy == 'IDENT' and s.systring in ('inline',):
2358         modifier = s.systring
2359         s.next()
2360         return [modifier] + p_c_modifiers(s)
2361     return []
2362
2363 def p_c_func_or_var_declaration(s, pos, ctx):
2364     cmethod_flag = ctx.level in ('c_class', 'c_class_pxd')
2365     modifiers = p_c_modifiers(s)
2366     base_type = p_c_base_type(s, nonempty = 1, templates = ctx.templates)
2367     declarator = p_c_declarator(s, ctx, cmethod_flag = cmethod_flag,
2368                                 assignable = 1, nonempty = 1)
2369     declarator.overridable = ctx.overridable
2370     if s.sy == ':':
2371         if ctx.level not in ('module', 'c_class', 'module_pxd', 'c_class_pxd') and not ctx.templates:
2372             s.error("C function definition not allowed here")
2373         doc, suite = p_suite(s, Ctx(level = 'function'), with_doc = 1)
2374         result = Nodes.CFuncDefNode(pos,
2375             visibility = ctx.visibility,
2376             base_type = base_type,
2377             declarator = declarator, 
2378             body = suite,
2379             doc = doc,
2380             modifiers = modifiers,
2381             api = ctx.api,
2382             overridable = ctx.overridable)
2383     else:
2384         #if api:
2385         #    error(s.pos, "'api' not allowed with variable declaration")
2386         declarators = [declarator]
2387         while s.sy == ',':
2388             s.next()
2389             if s.sy == 'NEWLINE':
2390                 break
2391             declarator = p_c_declarator(s, ctx, cmethod_flag = cmethod_flag,
2392                                         assignable = 1, nonempty = 1)
2393             declarators.append(declarator)
2394         s.expect_newline("Syntax error in C variable declaration")
2395         result = Nodes.CVarDefNode(pos, 
2396             visibility = ctx.visibility,
2397             base_type = base_type,
2398             declarators = declarators,
2399             in_pxd = ctx.level == 'module_pxd',
2400             api = ctx.api,
2401             overridable = ctx.overridable)
2402     return result
2403
2404 def p_ctypedef_statement(s, ctx):
2405     # s.sy == 'ctypedef'
2406     pos = s.position()
2407     s.next()
2408     visibility = p_visibility(s, ctx.visibility)
2409     api = p_api(s)
2410     ctx = ctx(typedef_flag = 1, visibility = visibility)
2411     if api:
2412         ctx.api = 1
2413     if s.sy == 'class':
2414         return p_c_class_definition(s, pos, ctx)
2415     elif s.sy == 'IDENT' and s.systring in ('packed', 'struct', 'union', 'enum'):
2416         if s.systring == 'enum':
2417             return p_c_enum_definition(s, pos, ctx)
2418         else:
2419             return p_c_struct_or_union_definition(s, pos, ctx)
2420     else:
2421         base_type = p_c_base_type(s, nonempty = 1)
2422         if base_type.name is None:
2423             s.error("Syntax error in ctypedef statement")
2424         declarator = p_c_declarator(s, ctx, is_type = 1, nonempty = 1)
2425         s.expect_newline("Syntax error in ctypedef statement")
2426         return Nodes.CTypeDefNode(
2427             pos, base_type = base_type,
2428             declarator = declarator, visibility = visibility,
2429             in_pxd = ctx.level == 'module_pxd')
2430
2431 def p_decorators(s):
2432     decorators = []
2433     while s.sy == 'DECORATOR':
2434         pos = s.position()
2435         s.next()
2436         decstring = p_dotted_name(s, as_allowed=0)[2]
2437         names = decstring.split('.')
2438         decorator = ExprNodes.NameNode(pos, name=EncodedString(names[0]))
2439         for name in names[1:]:
2440             decorator = ExprNodes.AttributeNode(pos,
2441                                            attribute=EncodedString(name),
2442                                            obj=decorator)
2443         if s.sy == '(':
2444             decorator = p_call(s, decorator)
2445         decorators.append(Nodes.DecoratorNode(pos, decorator=decorator))
2446         s.expect_newline("Expected a newline after decorator")
2447     return decorators
2448
2449 def p_def_statement(s, decorators=None):
2450     # s.sy == 'def'
2451     pos = s.position()
2452     s.next()
2453     name = EncodedString( p_ident(s) )
2454     s.expect('(');
2455     args, star_arg, starstar_arg = p_varargslist(s, terminator=')')
2456     s.expect(')')
2457     if p_nogil(s):
2458         error(s.pos, "Python function cannot be declared nogil")
2459     return_type_annotation = None
2460     if s.sy == '->':
2461         s.next()
2462         return_type_annotation = p_simple_expr(s)
2463     doc, body = p_suite(s, Ctx(level = 'function'), with_doc = 1)
2464     return Nodes.DefNode(pos, name = name, args = args, 
2465         star_arg = star_arg, starstar_arg = starstar_arg,
2466         doc = doc, body = body, decorators = decorators,
2467         return_type_annotation = return_type_annotation)
2468
2469 def p_varargslist(s, terminator=')', annotated=1):
2470     args = p_c_arg_list(s, in_pyfunc = 1, nonempty_declarators = 1,
2471                         annotated = annotated)
2472     star_arg = None
2473     starstar_arg = None
2474     if s.sy == '*':
2475         s.next()
2476         if s.sy == 'IDENT':
2477             star_arg = p_py_arg_decl(s)
2478         if s.sy == ',':
2479             s.next()
2480             args.extend(p_c_arg_list(s, in_pyfunc = 1,
2481                 nonempty_declarators = 1, kw_only = 1))
2482         elif s.sy != terminator:
2483             s.error("Syntax error in Python function argument list")
2484     if s.sy == '**':
2485         s.next()
2486         starstar_arg = p_py_arg_decl(s)
2487     return (args, star_arg, starstar_arg)
2488
2489 def p_py_arg_decl(s):
2490     pos = s.position()
2491     name = p_ident(s)
2492     annotation = None
2493     if s.sy == ':':
2494         s.next()
2495         annotation = p_simple_expr(s)
2496     return Nodes.PyArgDeclNode(pos, name = name, annotation = annotation)
2497
2498 def p_class_statement(s, decorators):
2499     # s.sy == 'class'
2500     pos = s.position()
2501     s.next()
2502     class_name = EncodedString( p_ident(s) )
2503     class_name.encoding = s.source_encoding
2504     if s.sy == '(':
2505         s.next()
2506         base_list = p_simple_expr_list(s)
2507         s.expect(')')
2508     else:
2509         base_list = []
2510     doc, body = p_suite(s, Ctx(level = 'class'), with_doc = 1)
2511     return Nodes.PyClassDefNode(pos,
2512         name = class_name,
2513         bases = ExprNodes.TupleNode(pos, args = base_list),
2514         doc = doc, body = body, decorators = decorators)
2515
2516 def p_c_class_definition(s, pos,  ctx):
2517     # s.sy == 'class'
2518     s.next()
2519     module_path = []
2520     class_name = p_ident(s)
2521     while s.sy == '.':
2522         s.next()
2523         module_path.append(class_name)
2524         class_name = p_ident(s)
2525     if module_path and ctx.visibility != 'extern':
2526         error(pos, "Qualified class name only allowed for 'extern' C class")
2527     if module_path and s.sy == 'IDENT' and s.systring == 'as':
2528         s.next()
2529         as_name = p_ident(s)
2530     else:
2531         as_name = class_name
2532     objstruct_name = None
2533     typeobj_name = None
2534     base_class_module = None
2535     base_class_name = None
2536     if s.sy == '(':
2537         s.next()
2538         base_class_path = [p_ident(s)]
2539         while s.sy == '.':
2540             s.next()
2541             base_class_path.append(p_ident(s))
2542         if s.sy == ',':
2543             s.error("C class may only have one base class")
2544         s.expect(')')
2545         base_class_module = ".".join(base_class_path[:-1])
2546         base_class_name = base_class_path[-1]
2547     if s.sy == '[':
2548         if ctx.visibility not in ('public', 'extern'):
2549             error(s.position(), "Name options only allowed for 'public' or 'extern' C class")
2550         objstruct_name, typeobj_name = p_c_class_options(s)
2551     if s.sy == ':':
2552         if ctx.level == 'module_pxd':
2553             body_level = 'c_class_pxd'
2554         else:
2555             body_level = 'c_class'
2556         doc, body = p_suite(s, Ctx(level = body_level), with_doc = 1)
2557     else:
2558         s.expect_newline("Syntax error in C class definition")
2559         doc = None
2560         body = None
2561     if ctx.visibility == 'extern':
2562         if not module_path:
2563             error(pos, "Module name required for 'extern' C class")
2564         if typeobj_name:
2565             error(pos, "Type object name specification not allowed for 'extern' C class")
2566     elif ctx.visibility == 'public':
2567         if not objstruct_name:
2568             error(pos, "Object struct name specification required for 'public' C class")
2569         if not typeobj_name:
2570             error(pos, "Type object name specification required for 'public' C class")
2571     elif ctx.visibility == 'private':
2572         if ctx.api:
2573             error(pos, "Only 'public' C class can be declared 'api'")
2574     else:
2575         error(pos, "Invalid class visibility '%s'" % ctx.visibility)
2576     return Nodes.CClassDefNode(pos,
2577         visibility = ctx.visibility,
2578         typedef_flag = ctx.typedef_flag,
2579         api = ctx.api,
2580         module_name = ".".join(module_path),
2581         class_name = class_name,
2582         as_name = as_name,
2583         base_class_module = base_class_module,
2584         base_class_name = base_class_name,
2585         objstruct_name = objstruct_name,
2586         typeobj_name = typeobj_name,
2587         in_pxd = ctx.level == 'module_pxd',
2588         doc = doc,
2589         body = body)
2590
2591 def p_c_class_options(s):
2592     objstruct_name = None
2593     typeobj_name = None
2594     s.expect('[')
2595     while 1:
2596         if s.sy != 'IDENT':
2597             break
2598         if s.systring == 'object':
2599             s.next()
2600             objstruct_name = p_ident(s)
2601         elif s.systring == 'type':
2602             s.next()
2603             typeobj_name = p_ident(s)
2604         if s.sy != ',':
2605             break
2606         s.next()
2607     s.expect(']', "Expected 'object' or 'type'")
2608     return objstruct_name, typeobj_name
2609
2610 def p_property_decl(s):
2611     pos = s.position()
2612     s.next() # 'property'
2613     name = p_ident(s)
2614     doc, body = p_suite(s, Ctx(level = 'property'), with_doc = 1)
2615     return Nodes.PropertyNode(pos, name = name, doc = doc, body = body)
2616
2617 def p_doc_string(s):
2618     if s.sy == 'BEGIN_STRING':
2619         pos = s.position()
2620         kind, result = p_cat_string_literal(s)
2621         if s.sy != 'EOF':
2622             s.expect_newline("Syntax error in doc string")
2623         if kind != 'u':
2624             # warning(pos, "Python 3 requires docstrings to be unicode strings")
2625             if kind == 'b':
2626                 result.encoding = None # force a unicode string
2627         return result
2628     else:
2629         return None
2630         
2631 def p_code(s, level=None):
2632     body = p_statement_list(s, Ctx(level = level), first_statement = 1)
2633     if s.sy != 'EOF':
2634         s.error("Syntax error in statement [%s,%s]" % (
2635             repr(s.sy), repr(s.systring)))
2636     return body
2637
2638 COMPILER_DIRECTIVE_COMMENT_RE = re.compile(r"^#\s*cython:\s*((\w|[.])+\s*=.*)$")
2639
2640 def p_compiler_directive_comments(s):
2641     result = {}
2642     while s.sy == 'commentline':
2643         m = COMPILER_DIRECTIVE_COMMENT_RE.match(s.systring)
2644         if m:
2645             directives = m.group(1).strip()
2646             try:
2647                 result.update( Options.parse_directive_list(
2648                     directives, ignore_unknown=True) )
2649             except ValueError, e:
2650                 s.error(e.args[0], fatal=False)
2651         s.next()
2652     return result
2653
2654 def p_module(s, pxd, full_module_name):
2655     pos = s.position()
2656
2657     directive_comments = p_compiler_directive_comments(s)
2658     s.parse_comments = False
2659
2660     doc = p_doc_string(s)
2661     if pxd:
2662         level = 'module_pxd'
2663     else:
2664         level = 'module'
2665
2666     body = p_statement_list(s, Ctx(level = level), first_statement = 1)
2667     if s.sy != 'EOF':
2668         s.error("Syntax error in statement [%s,%s]" % (
2669             repr(s.sy), repr(s.systring)))
2670     return ModuleNode(pos, doc = doc, body = body,
2671                       full_module_name = full_module_name,
2672                       directive_comments = directive_comments)
2673
2674 def p_cpp_class_definition(s, pos,  ctx):
2675     # s.sy == 'cppclass'
2676     s.next()
2677     module_path = []
2678     class_name = p_ident(s)
2679     cname = p_opt_cname(s)
2680     if cname is None and ctx.namespace is not None:
2681         cname = ctx.namespace + "::" + class_name
2682     if s.sy == '.':
2683         error(pos, "Qualified class name not allowed C++ class")
2684     if s.sy == '[':
2685         s.next()
2686         templates = [p_ident(s)]
2687         while s.sy == ',':
2688             s.next()
2689             templates.append(p_ident(s))
2690         s.expect(']')
2691     else:
2692         templates = None
2693     if s.sy == '(':
2694         s.next()
2695         base_classes = [p_dotted_name(s, False)[2]]
2696         while s.sy == ',':
2697             s.next()
2698             base_classes.append(p_dotted_name(s, False)[2])
2699         s.expect(')')
2700     else:
2701         base_classes = []
2702     if s.sy == '[':
2703         error(s.position(), "Name options not allowed for C++ class")
2704     if s.sy == ':':
2705         s.next()
2706         s.expect('NEWLINE')
2707         s.expect_indent()
2708         attributes = []
2709         body_ctx = Ctx(visibility = ctx.visibility)
2710         body_ctx.templates = templates
2711         while s.sy != 'DEDENT':
2712             if s.systring == 'cppclass':
2713                 attributes.append(
2714                     p_cpp_class_definition(s, s.position(), body_ctx))
2715             elif s.sy != 'pass':
2716                 attributes.append(
2717                     p_c_func_or_var_declaration(s, s.position(), body_ctx))
2718             else:
2719                 s.next()
2720                 s.expect_newline("Expected a newline")
2721         s.expect_dedent()
2722     else:
2723         s.expect_newline("Syntax error in C++ class definition")
2724     return Nodes.CppClassNode(pos,
2725         name = class_name,
2726         cname = cname,
2727         base_classes = base_classes,
2728         visibility = ctx.visibility,
2729         in_pxd = ctx.level == 'module_pxd',
2730         attributes = attributes,
2731         templates = templates)
2732
2733
2734
2735 #----------------------------------------------
2736 #
2737 #   Debugging
2738 #
2739 #----------------------------------------------
2740
2741 def print_parse_tree(f, node, level, key = None):
2742     from types import ListType, TupleType
2743     from Nodes import Node
2744     ind = "  " * level
2745     if node:
2746         f.write(ind)
2747         if key:
2748             f.write("%s: " % key)
2749         t = type(node)
2750         if t is tuple:
2751             f.write("(%s @ %s\n" % (node[0], node[1]))
2752             for i in xrange(2, len(node)):
2753                 print_parse_tree(f, node[i], level+1)
2754             f.write("%s)\n" % ind)
2755             return
2756         elif isinstance(node, Node):
2757             try:
2758                 tag = node.tag
2759             except AttributeError:
2760                 tag = node.__class__.__name__
2761             f.write("%s @ %s\n" % (tag, node.pos))
2762             for name, value in node.__dict__.items():
2763                 if name != 'tag' and name != 'pos':
2764                     print_parse_tree(f, value, level+1, name)
2765             return
2766         elif t is list:
2767             f.write("[\n")
2768             for i in xrange(len(node)):
2769                 print_parse_tree(f, node[i], level+1)
2770             f.write("%s]\n" % ind)
2771             return
2772     f.write("%s%s\n" % (ind, node))
2773