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