Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / cython / src / Cython / Compiler / Parsing.py
blob8b9eadaaf9933a1dc3f2f02dfd1831bb7c947511
1 # cython: auto_cpdef=True, infer_types=True, language_level=3, py2_import=True
3 # Parser
6 # This should be done automatically
7 import cython
8 cython.declare(Nodes=object, ExprNodes=object, EncodedString=object,
9 BytesLiteral=object, StringEncoding=object,
10 FileSourceDescriptor=object, lookup_unicodechar=object,
11 Future=object, Options=object, error=object, warning=object,
12 Builtin=object, ModuleNode=object, Utils=object,
13 re=object, _unicode=object, _bytes=object)
15 import re
16 from unicodedata import lookup as lookup_unicodechar
18 from Cython.Compiler.Scanning import PyrexScanner, FileSourceDescriptor
19 import Nodes
20 import ExprNodes
21 import Builtin
22 import StringEncoding
23 from StringEncoding import EncodedString, BytesLiteral, _unicode, _bytes
24 from ModuleNode import ModuleNode
25 from Errors import error, warning
26 from Cython import Utils
27 import Future
28 import Options
30 class Ctx(object):
31 # Parsing context
32 level = 'other'
33 visibility = 'private'
34 cdef_flag = 0
35 typedef_flag = 0
36 api = 0
37 overridable = 0
38 nogil = 0
39 namespace = None
40 templates = None
41 allow_struct_enum_decorator = False
43 def __init__(self, **kwds):
44 self.__dict__.update(kwds)
46 def __call__(self, **kwds):
47 ctx = Ctx()
48 d = ctx.__dict__
49 d.update(self.__dict__)
50 d.update(kwds)
51 return ctx
53 def p_ident(s, message = "Expected an identifier"):
54 if s.sy == 'IDENT':
55 name = s.systring
56 s.next()
57 return name
58 else:
59 s.error(message)
61 def p_ident_list(s):
62 names = []
63 while s.sy == 'IDENT':
64 names.append(s.systring)
65 s.next()
66 if s.sy != ',':
67 break
68 s.next()
69 return names
71 #------------------------------------------
73 # Expressions
75 #------------------------------------------
77 def p_binop_operator(s):
78 pos = s.position()
79 op = s.sy
80 s.next()
81 return op, pos
83 def p_binop_expr(s, ops, p_sub_expr):
84 n1 = p_sub_expr(s)
85 while s.sy in ops:
86 op, pos = p_binop_operator(s)
87 n2 = p_sub_expr(s)
88 n1 = ExprNodes.binop_node(pos, op, n1, n2)
89 if op == '/':
90 if Future.division in s.context.future_directives:
91 n1.truedivision = True
92 else:
93 n1.truedivision = None # unknown
94 return n1
96 #lambdef: 'lambda' [varargslist] ':' test
98 def p_lambdef(s, allow_conditional=True):
99 # s.sy == 'lambda'
100 pos = s.position()
101 s.next()
102 if s.sy == ':':
103 args = []
104 star_arg = starstar_arg = None
105 else:
106 args, star_arg, starstar_arg = p_varargslist(
107 s, terminator=':', annotated=False)
108 s.expect(':')
109 if allow_conditional:
110 expr = p_test(s)
111 else:
112 expr = p_test_nocond(s)
113 return ExprNodes.LambdaNode(
114 pos, args = args,
115 star_arg = star_arg, starstar_arg = starstar_arg,
116 result_expr = expr)
118 #lambdef_nocond: 'lambda' [varargslist] ':' test_nocond
120 def p_lambdef_nocond(s):
121 return p_lambdef(s, allow_conditional=False)
123 #test: or_test ['if' or_test 'else' test] | lambdef
125 def p_test(s):
126 if s.sy == 'lambda':
127 return p_lambdef(s)
128 pos = s.position()
129 expr = p_or_test(s)
130 if s.sy == 'if':
131 s.next()
132 test = p_or_test(s)
133 s.expect('else')
134 other = p_test(s)
135 return ExprNodes.CondExprNode(pos, test=test, true_val=expr, false_val=other)
136 else:
137 return expr
139 #test_nocond: or_test | lambdef_nocond
141 def p_test_nocond(s):
142 if s.sy == 'lambda':
143 return p_lambdef_nocond(s)
144 else:
145 return p_or_test(s)
147 #or_test: and_test ('or' and_test)*
149 def p_or_test(s):
150 return p_rassoc_binop_expr(s, ('or',), p_and_test)
152 def p_rassoc_binop_expr(s, ops, p_subexpr):
153 n1 = p_subexpr(s)
154 if s.sy in ops:
155 pos = s.position()
156 op = s.sy
157 s.next()
158 n2 = p_rassoc_binop_expr(s, ops, p_subexpr)
159 n1 = ExprNodes.binop_node(pos, op, n1, n2)
160 return n1
162 #and_test: not_test ('and' not_test)*
164 def p_and_test(s):
165 #return p_binop_expr(s, ('and',), p_not_test)
166 return p_rassoc_binop_expr(s, ('and',), p_not_test)
168 #not_test: 'not' not_test | comparison
170 def p_not_test(s):
171 if s.sy == 'not':
172 pos = s.position()
173 s.next()
174 return ExprNodes.NotNode(pos, operand = p_not_test(s))
175 else:
176 return p_comparison(s)
178 #comparison: expr (comp_op expr)*
179 #comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
181 def p_comparison(s):
182 n1 = p_starred_expr(s)
183 if s.sy in comparison_ops:
184 pos = s.position()
185 op = p_cmp_op(s)
186 n2 = p_starred_expr(s)
187 n1 = ExprNodes.PrimaryCmpNode(pos,
188 operator = op, operand1 = n1, operand2 = n2)
189 if s.sy in comparison_ops:
190 n1.cascade = p_cascaded_cmp(s)
191 return n1
193 def p_test_or_starred_expr(s):
194 if s.sy == '*':
195 return p_starred_expr(s)
196 else:
197 return p_test(s)
199 def p_starred_expr(s):
200 pos = s.position()
201 if s.sy == '*':
202 starred = True
203 s.next()
204 else:
205 starred = False
206 expr = p_bit_expr(s)
207 if starred:
208 expr = ExprNodes.StarredTargetNode(pos, expr)
209 return expr
211 def p_cascaded_cmp(s):
212 pos = s.position()
213 op = p_cmp_op(s)
214 n2 = p_starred_expr(s)
215 result = ExprNodes.CascadedCmpNode(pos,
216 operator = op, operand2 = n2)
217 if s.sy in comparison_ops:
218 result.cascade = p_cascaded_cmp(s)
219 return result
221 def p_cmp_op(s):
222 if s.sy == 'not':
223 s.next()
224 s.expect('in')
225 op = 'not_in'
226 elif s.sy == 'is':
227 s.next()
228 if s.sy == 'not':
229 s.next()
230 op = 'is_not'
231 else:
232 op = 'is'
233 else:
234 op = s.sy
235 s.next()
236 if op == '<>':
237 op = '!='
238 return op
240 comparison_ops = cython.declare(set, set([
241 '<', '>', '==', '>=', '<=', '<>', '!=',
242 'in', 'is', 'not'
245 #expr: xor_expr ('|' xor_expr)*
247 def p_bit_expr(s):
248 return p_binop_expr(s, ('|',), p_xor_expr)
250 #xor_expr: and_expr ('^' and_expr)*
252 def p_xor_expr(s):
253 return p_binop_expr(s, ('^',), p_and_expr)
255 #and_expr: shift_expr ('&' shift_expr)*
257 def p_and_expr(s):
258 return p_binop_expr(s, ('&',), p_shift_expr)
260 #shift_expr: arith_expr (('<<'|'>>') arith_expr)*
262 def p_shift_expr(s):
263 return p_binop_expr(s, ('<<', '>>'), p_arith_expr)
265 #arith_expr: term (('+'|'-') term)*
267 def p_arith_expr(s):
268 return p_binop_expr(s, ('+', '-'), p_term)
270 #term: factor (('*'|'/'|'%') factor)*
272 def p_term(s):
273 return p_binop_expr(s, ('*', '/', '%', '//'), p_factor)
275 #factor: ('+'|'-'|'~'|'&'|typecast|sizeof) factor | power
277 def p_factor(s):
278 # little indirection for C-ification purposes
279 return _p_factor(s)
281 def _p_factor(s):
282 sy = s.sy
283 if sy in ('+', '-', '~'):
284 op = s.sy
285 pos = s.position()
286 s.next()
287 return ExprNodes.unop_node(pos, op, p_factor(s))
288 elif not s.in_python_file:
289 if sy == '&':
290 pos = s.position()
291 s.next()
292 arg = p_factor(s)
293 return ExprNodes.AmpersandNode(pos, operand = arg)
294 elif sy == "<":
295 return p_typecast(s)
296 elif sy == 'IDENT' and s.systring == "sizeof":
297 return p_sizeof(s)
298 return p_power(s)
300 def p_typecast(s):
301 # s.sy == "<"
302 pos = s.position()
303 s.next()
304 base_type = p_c_base_type(s)
305 is_memslice = isinstance(base_type, Nodes.MemoryViewSliceTypeNode)
306 is_template = isinstance(base_type, Nodes.TemplatedTypeNode)
307 is_const = isinstance(base_type, Nodes.CConstTypeNode)
308 if (not is_memslice and not is_template and not is_const
309 and base_type.name is None):
310 s.error("Unknown type")
311 declarator = p_c_declarator(s, empty = 1)
312 if s.sy == '?':
313 s.next()
314 typecheck = 1
315 else:
316 typecheck = 0
317 s.expect(">")
318 operand = p_factor(s)
319 if is_memslice:
320 return ExprNodes.CythonArrayNode(pos, base_type_node=base_type,
321 operand=operand)
323 return ExprNodes.TypecastNode(pos,
324 base_type = base_type,
325 declarator = declarator,
326 operand = operand,
327 typecheck = typecheck)
329 def p_sizeof(s):
330 # s.sy == ident "sizeof"
331 pos = s.position()
332 s.next()
333 s.expect('(')
334 # Here we decide if we are looking at an expression or type
335 # If it is actually a type, but parsable as an expression,
336 # we treat it as an expression here.
337 if looking_at_expr(s):
338 operand = p_test(s)
339 node = ExprNodes.SizeofVarNode(pos, operand = operand)
340 else:
341 base_type = p_c_base_type(s)
342 declarator = p_c_declarator(s, empty = 1)
343 node = ExprNodes.SizeofTypeNode(pos,
344 base_type = base_type, declarator = declarator)
345 s.expect(')')
346 return node
348 def p_yield_expression(s):
349 # s.sy == "yield"
350 pos = s.position()
351 s.next()
352 is_yield_from = False
353 if s.sy == 'from':
354 is_yield_from = True
355 s.next()
356 if s.sy != ')' and s.sy not in statement_terminators:
357 arg = p_testlist(s)
358 else:
359 if is_yield_from:
360 s.error("'yield from' requires a source argument",
361 pos=pos, fatal=False)
362 arg = None
363 if is_yield_from:
364 return ExprNodes.YieldFromExprNode(pos, arg=arg)
365 else:
366 return ExprNodes.YieldExprNode(pos, arg=arg)
368 def p_yield_statement(s):
369 # s.sy == "yield"
370 yield_expr = p_yield_expression(s)
371 return Nodes.ExprStatNode(yield_expr.pos, expr=yield_expr)
373 #power: atom trailer* ('**' factor)*
375 def p_power(s):
376 if s.systring == 'new' and s.peek()[0] == 'IDENT':
377 return p_new_expr(s)
378 n1 = p_atom(s)
379 while s.sy in ('(', '[', '.'):
380 n1 = p_trailer(s, n1)
381 if s.sy == '**':
382 pos = s.position()
383 s.next()
384 n2 = p_factor(s)
385 n1 = ExprNodes.binop_node(pos, '**', n1, n2)
386 return n1
388 def p_new_expr(s):
389 # s.systring == 'new'.
390 pos = s.position()
391 s.next()
392 cppclass = p_c_base_type(s)
393 return p_call(s, ExprNodes.NewExprNode(pos, cppclass = cppclass))
395 #trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
397 def p_trailer(s, node1):
398 pos = s.position()
399 if s.sy == '(':
400 return p_call(s, node1)
401 elif s.sy == '[':
402 return p_index(s, node1)
403 else: # s.sy == '.'
404 s.next()
405 name = EncodedString( p_ident(s) )
406 return ExprNodes.AttributeNode(pos,
407 obj = node1, attribute = name)
409 # arglist: argument (',' argument)* [',']
410 # argument: [test '='] test # Really [keyword '='] test
412 def p_call_parse_args(s, allow_genexp = True):
413 # s.sy == '('
414 pos = s.position()
415 s.next()
416 positional_args = []
417 keyword_args = []
418 star_arg = None
419 starstar_arg = None
420 while s.sy not in ('**', ')'):
421 if s.sy == '*':
422 if star_arg:
423 s.error("only one star-arg parameter allowed",
424 pos=s.position())
425 s.next()
426 star_arg = p_test(s)
427 else:
428 arg = p_test(s)
429 if s.sy == '=':
430 s.next()
431 if not arg.is_name:
432 s.error("Expected an identifier before '='",
433 pos=arg.pos)
434 encoded_name = EncodedString(arg.name)
435 keyword = ExprNodes.IdentifierStringNode(
436 arg.pos, value=encoded_name)
437 arg = p_test(s)
438 keyword_args.append((keyword, arg))
439 else:
440 if keyword_args:
441 s.error("Non-keyword arg following keyword arg",
442 pos=arg.pos)
443 if star_arg:
444 s.error("Non-keyword arg following star-arg",
445 pos=arg.pos)
446 positional_args.append(arg)
447 if s.sy != ',':
448 break
449 s.next()
451 if s.sy == 'for':
452 if len(positional_args) == 1 and not star_arg:
453 positional_args = [ p_genexp(s, positional_args[0]) ]
454 elif s.sy == '**':
455 s.next()
456 starstar_arg = p_test(s)
457 if s.sy == ',':
458 s.next()
459 s.expect(')')
460 return positional_args, keyword_args, star_arg, starstar_arg
462 def p_call_build_packed_args(pos, positional_args, keyword_args,
463 star_arg, starstar_arg):
464 arg_tuple = None
465 keyword_dict = None
466 if positional_args or not star_arg:
467 arg_tuple = ExprNodes.TupleNode(pos,
468 args = positional_args)
469 if star_arg:
470 star_arg_tuple = ExprNodes.AsTupleNode(pos, arg = star_arg)
471 if arg_tuple:
472 arg_tuple = ExprNodes.binop_node(pos,
473 operator = '+', operand1 = arg_tuple,
474 operand2 = star_arg_tuple)
475 else:
476 arg_tuple = star_arg_tuple
477 if keyword_args or starstar_arg:
478 keyword_args = [ExprNodes.DictItemNode(pos=key.pos, key=key, value=value)
479 for key, value in keyword_args]
480 if starstar_arg:
481 keyword_dict = ExprNodes.KeywordArgsNode(
482 pos,
483 starstar_arg = starstar_arg,
484 keyword_args = keyword_args)
485 else:
486 keyword_dict = ExprNodes.DictNode(
487 pos, key_value_pairs = keyword_args)
488 return arg_tuple, keyword_dict
490 def p_call(s, function):
491 # s.sy == '('
492 pos = s.position()
494 positional_args, keyword_args, star_arg, starstar_arg = \
495 p_call_parse_args(s)
497 if not (keyword_args or star_arg or starstar_arg):
498 return ExprNodes.SimpleCallNode(pos,
499 function = function,
500 args = positional_args)
501 else:
502 arg_tuple, keyword_dict = p_call_build_packed_args(
503 pos, positional_args, keyword_args, star_arg, starstar_arg)
504 return ExprNodes.GeneralCallNode(pos,
505 function = function,
506 positional_args = arg_tuple,
507 keyword_args = keyword_dict)
509 #lambdef: 'lambda' [varargslist] ':' test
511 #subscriptlist: subscript (',' subscript)* [',']
513 def p_index(s, base):
514 # s.sy == '['
515 pos = s.position()
516 s.next()
517 subscripts, is_single_value = p_subscript_list(s)
518 if is_single_value and len(subscripts[0]) == 2:
519 start, stop = subscripts[0]
520 result = ExprNodes.SliceIndexNode(pos,
521 base = base, start = start, stop = stop)
522 else:
523 indexes = make_slice_nodes(pos, subscripts)
524 if is_single_value:
525 index = indexes[0]
526 else:
527 index = ExprNodes.TupleNode(pos, args = indexes)
528 result = ExprNodes.IndexNode(pos,
529 base = base, index = index)
530 s.expect(']')
531 return result
533 def p_subscript_list(s):
534 is_single_value = True
535 items = [p_subscript(s)]
536 while s.sy == ',':
537 is_single_value = False
538 s.next()
539 if s.sy == ']':
540 break
541 items.append(p_subscript(s))
542 return items, is_single_value
544 #subscript: '.' '.' '.' | test | [test] ':' [test] [':' [test]]
546 def p_subscript(s):
547 # Parse a subscript and return a list of
548 # 1, 2 or 3 ExprNodes, depending on how
549 # many slice elements were encountered.
550 pos = s.position()
551 start = p_slice_element(s, (':',))
552 if s.sy != ':':
553 return [start]
554 s.next()
555 stop = p_slice_element(s, (':', ',', ']'))
556 if s.sy != ':':
557 return [start, stop]
558 s.next()
559 step = p_slice_element(s, (':', ',', ']'))
560 return [start, stop, step]
562 def p_slice_element(s, follow_set):
563 # Simple expression which may be missing iff
564 # it is followed by something in follow_set.
565 if s.sy not in follow_set:
566 return p_test(s)
567 else:
568 return None
570 def expect_ellipsis(s):
571 s.expect('.')
572 s.expect('.')
573 s.expect('.')
575 def make_slice_nodes(pos, subscripts):
576 # Convert a list of subscripts as returned
577 # by p_subscript_list into a list of ExprNodes,
578 # creating SliceNodes for elements with 2 or
579 # more components.
580 result = []
581 for subscript in subscripts:
582 if len(subscript) == 1:
583 result.append(subscript[0])
584 else:
585 result.append(make_slice_node(pos, *subscript))
586 return result
588 def make_slice_node(pos, start, stop = None, step = None):
589 if not start:
590 start = ExprNodes.NoneNode(pos)
591 if not stop:
592 stop = ExprNodes.NoneNode(pos)
593 if not step:
594 step = ExprNodes.NoneNode(pos)
595 return ExprNodes.SliceNode(pos,
596 start = start, stop = stop, step = step)
598 #atom: '(' [yield_expr|testlist_comp] ')' | '[' [listmaker] ']' | '{' [dict_or_set_maker] '}' | '`' testlist '`' | NAME | NUMBER | STRING+
600 def p_atom(s):
601 pos = s.position()
602 sy = s.sy
603 if sy == '(':
604 s.next()
605 if s.sy == ')':
606 result = ExprNodes.TupleNode(pos, args = [])
607 elif s.sy == 'yield':
608 result = p_yield_expression(s)
609 else:
610 result = p_testlist_comp(s)
611 s.expect(')')
612 return result
613 elif sy == '[':
614 return p_list_maker(s)
615 elif sy == '{':
616 return p_dict_or_set_maker(s)
617 elif sy == '`':
618 return p_backquote_expr(s)
619 elif sy == '.':
620 expect_ellipsis(s)
621 return ExprNodes.EllipsisNode(pos)
622 elif sy == 'INT':
623 return p_int_literal(s)
624 elif sy == 'FLOAT':
625 value = s.systring
626 s.next()
627 return ExprNodes.FloatNode(pos, value = value)
628 elif sy == 'IMAG':
629 value = s.systring[:-1]
630 s.next()
631 return ExprNodes.ImagNode(pos, value = value)
632 elif sy == 'BEGIN_STRING':
633 kind, bytes_value, unicode_value = p_cat_string_literal(s)
634 if kind == 'c':
635 return ExprNodes.CharNode(pos, value = bytes_value)
636 elif kind == 'u':
637 return ExprNodes.UnicodeNode(pos, value = unicode_value, bytes_value = bytes_value)
638 elif kind == 'b':
639 return ExprNodes.BytesNode(pos, value = bytes_value)
640 else:
641 return ExprNodes.StringNode(pos, value = bytes_value, unicode_value = unicode_value)
642 elif sy == 'IDENT':
643 name = EncodedString( s.systring )
644 s.next()
645 if name == "None":
646 return ExprNodes.NoneNode(pos)
647 elif name == "True":
648 return ExprNodes.BoolNode(pos, value=True)
649 elif name == "False":
650 return ExprNodes.BoolNode(pos, value=False)
651 elif name == "NULL" and not s.in_python_file:
652 return ExprNodes.NullNode(pos)
653 else:
654 return p_name(s, name)
655 else:
656 s.error("Expected an identifier or literal")
658 def p_int_literal(s):
659 pos = s.position()
660 value = s.systring
661 s.next()
662 unsigned = ""
663 longness = ""
664 while value[-1] in u"UuLl":
665 if value[-1] in u"Ll":
666 longness += "L"
667 else:
668 unsigned += "U"
669 value = value[:-1]
670 # '3L' is ambiguous in Py2 but not in Py3. '3U' and '3LL' are
671 # illegal in Py2 Python files. All suffixes are illegal in Py3
672 # Python files.
673 is_c_literal = None
674 if unsigned:
675 is_c_literal = True
676 elif longness:
677 if longness == 'LL' or s.context.language_level >= 3:
678 is_c_literal = True
679 if s.in_python_file:
680 if is_c_literal:
681 error(pos, "illegal integer literal syntax in Python source file")
682 is_c_literal = False
683 return ExprNodes.IntNode(pos,
684 is_c_literal = is_c_literal,
685 value = value,
686 unsigned = unsigned,
687 longness = longness)
690 def p_name(s, name):
691 pos = s.position()
692 if not s.compile_time_expr and name in s.compile_time_env:
693 value = s.compile_time_env.lookup_here(name)
694 node = wrap_compile_time_constant(pos, value)
695 if node is not None:
696 return node
697 return ExprNodes.NameNode(pos, name=name)
700 def wrap_compile_time_constant(pos, value):
701 rep = repr(value)
702 if value is None:
703 return ExprNodes.NoneNode(pos)
704 elif value is Ellipsis:
705 return ExprNodes.EllipsisNode(pos)
706 elif isinstance(value, bool):
707 return ExprNodes.BoolNode(pos, value=value)
708 elif isinstance(value, int):
709 return ExprNodes.IntNode(pos, value=rep)
710 elif isinstance(value, long):
711 return ExprNodes.IntNode(pos, value=rep, longness="L")
712 elif isinstance(value, float):
713 return ExprNodes.FloatNode(pos, value=rep)
714 elif isinstance(value, _unicode):
715 return ExprNodes.UnicodeNode(pos, value=EncodedString(value))
716 elif isinstance(value, _bytes):
717 return ExprNodes.BytesNode(pos, value=BytesLiteral(value))
718 elif isinstance(value, tuple):
719 args = [wrap_compile_time_constant(pos, arg)
720 for arg in value]
721 if None not in args:
722 return ExprNodes.TupleNode(pos, args=args)
723 else:
724 # error already reported
725 return None
726 error(pos, "Invalid type for compile-time constant: %r (type %s)"
727 % (value, value.__class__.__name__))
728 return None
731 def p_cat_string_literal(s):
732 # A sequence of one or more adjacent string literals.
733 # Returns (kind, bytes_value, unicode_value)
734 # where kind in ('b', 'c', 'u', '')
735 kind, bytes_value, unicode_value = p_string_literal(s)
736 if kind == 'c' or s.sy != 'BEGIN_STRING':
737 return kind, bytes_value, unicode_value
738 bstrings, ustrings = [bytes_value], [unicode_value]
739 bytes_value = unicode_value = None
740 while s.sy == 'BEGIN_STRING':
741 pos = s.position()
742 next_kind, next_bytes_value, next_unicode_value = p_string_literal(s)
743 if next_kind == 'c':
744 error(pos, "Cannot concatenate char literal with another string or char literal")
745 elif next_kind != kind:
746 error(pos, "Cannot mix string literals of different types, expected %s'', got %s''" %
747 (kind, next_kind))
748 else:
749 bstrings.append(next_bytes_value)
750 ustrings.append(next_unicode_value)
751 # join and rewrap the partial literals
752 if kind in ('b', 'c', '') or kind == 'u' and None not in bstrings:
753 # Py3 enforced unicode literals are parsed as bytes/unicode combination
754 bytes_value = BytesLiteral( StringEncoding.join_bytes(bstrings) )
755 bytes_value.encoding = s.source_encoding
756 if kind in ('u', ''):
757 unicode_value = EncodedString( u''.join([ u for u in ustrings if u is not None ]) )
758 return kind, bytes_value, unicode_value
760 def p_opt_string_literal(s, required_type='u'):
761 if s.sy == 'BEGIN_STRING':
762 kind, bytes_value, unicode_value = p_string_literal(s, required_type)
763 if required_type == 'u':
764 return unicode_value
765 elif required_type == 'b':
766 return bytes_value
767 else:
768 s.error("internal parser configuration error")
769 else:
770 return None
772 def check_for_non_ascii_characters(string):
773 for c in string:
774 if c >= u'\x80':
775 return True
776 return False
778 def p_string_literal(s, kind_override=None):
779 # A single string or char literal. Returns (kind, bvalue, uvalue)
780 # where kind in ('b', 'c', 'u', ''). The 'bvalue' is the source
781 # code byte sequence of the string literal, 'uvalue' is the
782 # decoded Unicode string. Either of the two may be None depending
783 # on the 'kind' of string, only unprefixed strings have both
784 # representations.
786 # s.sy == 'BEGIN_STRING'
787 pos = s.position()
788 is_raw = False
789 is_python3_source = s.context.language_level >= 3
790 has_non_ASCII_literal_characters = False
791 kind = s.systring[:1].lower()
792 if kind == 'r':
793 # Py3 allows both 'br' and 'rb' as prefix
794 if s.systring[1:2].lower() == 'b':
795 kind = 'b'
796 else:
797 kind = ''
798 is_raw = True
799 elif kind in 'ub':
800 is_raw = s.systring[1:2].lower() == 'r'
801 elif kind != 'c':
802 kind = ''
803 if kind == '' and kind_override is None and Future.unicode_literals in s.context.future_directives:
804 chars = StringEncoding.StrLiteralBuilder(s.source_encoding)
805 kind = 'u'
806 else:
807 if kind_override is not None and kind_override in 'ub':
808 kind = kind_override
809 if kind == 'u':
810 chars = StringEncoding.UnicodeLiteralBuilder()
811 elif kind == '':
812 chars = StringEncoding.StrLiteralBuilder(s.source_encoding)
813 else:
814 chars = StringEncoding.BytesLiteralBuilder(s.source_encoding)
816 while 1:
817 s.next()
818 sy = s.sy
819 systr = s.systring
820 #print "p_string_literal: sy =", sy, repr(s.systring) ###
821 if sy == 'CHARS':
822 chars.append(systr)
823 if is_python3_source and not has_non_ASCII_literal_characters and check_for_non_ascii_characters(systr):
824 has_non_ASCII_literal_characters = True
825 elif sy == 'ESCAPE':
826 if is_raw:
827 chars.append(systr)
828 if is_python3_source and not has_non_ASCII_literal_characters \
829 and check_for_non_ascii_characters(systr):
830 has_non_ASCII_literal_characters = True
831 else:
832 c = systr[1]
833 if c in u"01234567":
834 chars.append_charval( int(systr[1:], 8) )
835 elif c in u"'\"\\":
836 chars.append(c)
837 elif c in u"abfnrtv":
838 chars.append(
839 StringEncoding.char_from_escape_sequence(systr))
840 elif c == u'\n':
841 pass
842 elif c == u'x': # \xXX
843 if len(systr) == 4:
844 chars.append_charval( int(systr[2:], 16) )
845 else:
846 s.error("Invalid hex escape '%s'" % systr,
847 fatal=False)
848 elif c in u'NUu' and kind in ('u', ''): # \uxxxx, \Uxxxxxxxx, \N{...}
849 chrval = -1
850 if c == u'N':
851 try:
852 chrval = ord(lookup_unicodechar(systr[3:-1]))
853 except KeyError:
854 s.error("Unknown Unicode character name %s" %
855 repr(systr[3:-1]).lstrip('u'))
856 elif len(systr) in (6,10):
857 chrval = int(systr[2:], 16)
858 if chrval > 1114111: # sys.maxunicode:
859 s.error("Invalid unicode escape '%s'" % systr)
860 chrval = -1
861 else:
862 s.error("Invalid unicode escape '%s'" % systr,
863 fatal=False)
864 if chrval >= 0:
865 chars.append_uescape(chrval, systr)
866 else:
867 chars.append(u'\\' + systr[1:])
868 if is_python3_source and not has_non_ASCII_literal_characters \
869 and check_for_non_ascii_characters(systr):
870 has_non_ASCII_literal_characters = True
871 elif sy == 'NEWLINE':
872 chars.append(u'\n')
873 elif sy == 'END_STRING':
874 break
875 elif sy == 'EOF':
876 s.error("Unclosed string literal", pos=pos)
877 else:
878 s.error("Unexpected token %r:%r in string literal" %
879 (sy, s.systring))
881 if kind == 'c':
882 unicode_value = None
883 bytes_value = chars.getchar()
884 if len(bytes_value) != 1:
885 error(pos, u"invalid character literal: %r" % bytes_value)
886 else:
887 bytes_value, unicode_value = chars.getstrings()
888 if is_python3_source and has_non_ASCII_literal_characters:
889 # Python 3 forbids literal non-ASCII characters in byte strings
890 if kind != 'u':
891 s.error("bytes can only contain ASCII literal characters.",
892 pos=pos, fatal=False)
893 bytes_value = None
894 s.next()
895 return (kind, bytes_value, unicode_value)
897 # list_display ::= "[" [listmaker] "]"
898 # listmaker ::= expression ( comp_for | ( "," expression )* [","] )
899 # comp_iter ::= comp_for | comp_if
900 # comp_for ::= "for" expression_list "in" testlist [comp_iter]
901 # comp_if ::= "if" test [comp_iter]
903 def p_list_maker(s):
904 # s.sy == '['
905 pos = s.position()
906 s.next()
907 if s.sy == ']':
908 s.expect(']')
909 return ExprNodes.ListNode(pos, args = [])
910 expr = p_test(s)
911 if s.sy == 'for':
912 append = ExprNodes.ComprehensionAppendNode(pos, expr=expr)
913 loop = p_comp_for(s, append)
914 s.expect(']')
915 return ExprNodes.ComprehensionNode(
916 pos, loop=loop, append=append, type = Builtin.list_type,
917 # list comprehensions leak their loop variable in Py2
918 has_local_scope = s.context.language_level >= 3)
919 else:
920 if s.sy == ',':
921 s.next()
922 exprs = p_simple_expr_list(s, expr)
923 else:
924 exprs = [expr]
925 s.expect(']')
926 return ExprNodes.ListNode(pos, args = exprs)
928 def p_comp_iter(s, body):
929 if s.sy == 'for':
930 return p_comp_for(s, body)
931 elif s.sy == 'if':
932 return p_comp_if(s, body)
933 else:
934 # insert the 'append' operation into the loop
935 return body
937 def p_comp_for(s, body):
938 # s.sy == 'for'
939 pos = s.position()
940 s.next()
941 kw = p_for_bounds(s, allow_testlist=False)
942 kw.update(else_clause = None, body = p_comp_iter(s, body))
943 return Nodes.ForStatNode(pos, **kw)
945 def p_comp_if(s, body):
946 # s.sy == 'if'
947 pos = s.position()
948 s.next()
949 test = p_test_nocond(s)
950 return Nodes.IfStatNode(pos,
951 if_clauses = [Nodes.IfClauseNode(pos, condition = test,
952 body = p_comp_iter(s, body))],
953 else_clause = None )
955 #dictmaker: test ':' test (',' test ':' test)* [',']
957 def p_dict_or_set_maker(s):
958 # s.sy == '{'
959 pos = s.position()
960 s.next()
961 if s.sy == '}':
962 s.next()
963 return ExprNodes.DictNode(pos, key_value_pairs = [])
964 item = p_test(s)
965 if s.sy == ',' or s.sy == '}':
966 # set literal
967 values = [item]
968 while s.sy == ',':
969 s.next()
970 if s.sy == '}':
971 break
972 values.append( p_test(s) )
973 s.expect('}')
974 return ExprNodes.SetNode(pos, args=values)
975 elif s.sy == 'for':
976 # set comprehension
977 append = ExprNodes.ComprehensionAppendNode(
978 item.pos, expr=item)
979 loop = p_comp_for(s, append)
980 s.expect('}')
981 return ExprNodes.ComprehensionNode(
982 pos, loop=loop, append=append, type=Builtin.set_type)
983 elif s.sy == ':':
984 # dict literal or comprehension
985 key = item
986 s.next()
987 value = p_test(s)
988 if s.sy == 'for':
989 # dict comprehension
990 append = ExprNodes.DictComprehensionAppendNode(
991 item.pos, key_expr=key, value_expr=value)
992 loop = p_comp_for(s, append)
993 s.expect('}')
994 return ExprNodes.ComprehensionNode(
995 pos, loop=loop, append=append, type=Builtin.dict_type)
996 else:
997 # dict literal
998 items = [ExprNodes.DictItemNode(key.pos, key=key, value=value)]
999 while s.sy == ',':
1000 s.next()
1001 if s.sy == '}':
1002 break
1003 key = p_test(s)
1004 s.expect(':')
1005 value = p_test(s)
1006 items.append(
1007 ExprNodes.DictItemNode(key.pos, key=key, value=value))
1008 s.expect('}')
1009 return ExprNodes.DictNode(pos, key_value_pairs=items)
1010 else:
1011 # raise an error
1012 s.expect('}')
1013 return ExprNodes.DictNode(pos, key_value_pairs = [])
1015 # NOTE: no longer in Py3 :)
1016 def p_backquote_expr(s):
1017 # s.sy == '`'
1018 pos = s.position()
1019 s.next()
1020 args = [p_test(s)]
1021 while s.sy == ',':
1022 s.next()
1023 args.append(p_test(s))
1024 s.expect('`')
1025 if len(args) == 1:
1026 arg = args[0]
1027 else:
1028 arg = ExprNodes.TupleNode(pos, args = args)
1029 return ExprNodes.BackquoteNode(pos, arg = arg)
1031 def p_simple_expr_list(s, expr=None):
1032 exprs = expr is not None and [expr] or []
1033 while s.sy not in expr_terminators:
1034 exprs.append( p_test(s) )
1035 if s.sy != ',':
1036 break
1037 s.next()
1038 return exprs
1040 def p_test_or_starred_expr_list(s, expr=None):
1041 exprs = expr is not None and [expr] or []
1042 while s.sy not in expr_terminators:
1043 exprs.append( p_test_or_starred_expr(s) )
1044 if s.sy != ',':
1045 break
1046 s.next()
1047 return exprs
1050 #testlist: test (',' test)* [',']
1052 def p_testlist(s):
1053 pos = s.position()
1054 expr = p_test(s)
1055 if s.sy == ',':
1056 s.next()
1057 exprs = p_simple_expr_list(s, expr)
1058 return ExprNodes.TupleNode(pos, args = exprs)
1059 else:
1060 return expr
1062 # testlist_star_expr: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
1064 def p_testlist_star_expr(s):
1065 pos = s.position()
1066 expr = p_test_or_starred_expr(s)
1067 if s.sy == ',':
1068 s.next()
1069 exprs = p_test_or_starred_expr_list(s, expr)
1070 return ExprNodes.TupleNode(pos, args = exprs)
1071 else:
1072 return expr
1074 # testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
1076 def p_testlist_comp(s):
1077 pos = s.position()
1078 expr = p_test_or_starred_expr(s)
1079 if s.sy == ',':
1080 s.next()
1081 exprs = p_test_or_starred_expr_list(s, expr)
1082 return ExprNodes.TupleNode(pos, args = exprs)
1083 elif s.sy == 'for':
1084 return p_genexp(s, expr)
1085 else:
1086 return expr
1088 def p_genexp(s, expr):
1089 # s.sy == 'for'
1090 loop = p_comp_for(s, Nodes.ExprStatNode(
1091 expr.pos, expr = ExprNodes.YieldExprNode(expr.pos, arg=expr)))
1092 return ExprNodes.GeneratorExpressionNode(expr.pos, loop=loop)
1094 expr_terminators = cython.declare(set, set([
1095 ')', ']', '}', ':', '=', 'NEWLINE']))
1097 #-------------------------------------------------------
1099 # Statements
1101 #-------------------------------------------------------
1103 def p_global_statement(s):
1104 # assume s.sy == 'global'
1105 pos = s.position()
1106 s.next()
1107 names = p_ident_list(s)
1108 return Nodes.GlobalNode(pos, names = names)
1110 def p_nonlocal_statement(s):
1111 pos = s.position()
1112 s.next()
1113 names = p_ident_list(s)
1114 return Nodes.NonlocalNode(pos, names = names)
1116 def p_expression_or_assignment(s):
1117 expr_list = [p_testlist_star_expr(s)]
1118 if s.sy == '=' and expr_list[0].is_starred:
1119 # This is a common enough error to make when learning Cython to let
1120 # it fail as early as possible and give a very clear error message.
1121 s.error("a starred assignment target must be in a list or tuple"
1122 " - maybe you meant to use an index assignment: var[0] = ...",
1123 pos=expr_list[0].pos)
1124 while s.sy == '=':
1125 s.next()
1126 if s.sy == 'yield':
1127 expr = p_yield_expression(s)
1128 else:
1129 expr = p_testlist_star_expr(s)
1130 expr_list.append(expr)
1131 if len(expr_list) == 1:
1132 if re.match(r"([+*/\%^\&|-]|<<|>>|\*\*|//)=", s.sy):
1133 lhs = expr_list[0]
1134 if isinstance(lhs, ExprNodes.SliceIndexNode):
1135 # implementation requires IndexNode
1136 lhs = ExprNodes.IndexNode(
1137 lhs.pos,
1138 base=lhs.base,
1139 index=make_slice_node(lhs.pos, lhs.start, lhs.stop))
1140 elif not isinstance(lhs, (ExprNodes.AttributeNode, ExprNodes.IndexNode, ExprNodes.NameNode) ):
1141 error(lhs.pos, "Illegal operand for inplace operation.")
1142 operator = s.sy[:-1]
1143 s.next()
1144 if s.sy == 'yield':
1145 rhs = p_yield_expression(s)
1146 else:
1147 rhs = p_testlist(s)
1148 return Nodes.InPlaceAssignmentNode(lhs.pos, operator = operator, lhs = lhs, rhs = rhs)
1149 expr = expr_list[0]
1150 return Nodes.ExprStatNode(expr.pos, expr=expr)
1152 rhs = expr_list[-1]
1153 if len(expr_list) == 2:
1154 return Nodes.SingleAssignmentNode(rhs.pos,
1155 lhs = expr_list[0], rhs = rhs)
1156 else:
1157 return Nodes.CascadedAssignmentNode(rhs.pos,
1158 lhs_list = expr_list[:-1], rhs = rhs)
1160 def p_print_statement(s):
1161 # s.sy == 'print'
1162 pos = s.position()
1163 ends_with_comma = 0
1164 s.next()
1165 if s.sy == '>>':
1166 s.next()
1167 stream = p_test(s)
1168 if s.sy == ',':
1169 s.next()
1170 ends_with_comma = s.sy in ('NEWLINE', 'EOF')
1171 else:
1172 stream = None
1173 args = []
1174 if s.sy not in ('NEWLINE', 'EOF'):
1175 args.append(p_test(s))
1176 while s.sy == ',':
1177 s.next()
1178 if s.sy in ('NEWLINE', 'EOF'):
1179 ends_with_comma = 1
1180 break
1181 args.append(p_test(s))
1182 arg_tuple = ExprNodes.TupleNode(pos, args = args)
1183 return Nodes.PrintStatNode(pos,
1184 arg_tuple = arg_tuple, stream = stream,
1185 append_newline = not ends_with_comma)
1187 def p_exec_statement(s):
1188 # s.sy == 'exec'
1189 pos = s.position()
1190 s.next()
1191 code = p_bit_expr(s)
1192 if isinstance(code, ExprNodes.TupleNode):
1193 # Py3 compatibility syntax
1194 tuple_variant = True
1195 args = code.args
1196 if len(args) not in (2, 3):
1197 s.error("expected tuple of length 2 or 3, got length %d" % len(args),
1198 pos=pos, fatal=False)
1199 args = [code]
1200 else:
1201 tuple_variant = False
1202 args = [code]
1203 if s.sy == 'in':
1204 if tuple_variant:
1205 s.error("tuple variant of exec does not support additional 'in' arguments",
1206 fatal=False)
1207 s.next()
1208 args.append(p_test(s))
1209 if s.sy == ',':
1210 s.next()
1211 args.append(p_test(s))
1212 return Nodes.ExecStatNode(pos, args=args)
1214 def p_del_statement(s):
1215 # s.sy == 'del'
1216 pos = s.position()
1217 s.next()
1218 # FIXME: 'exprlist' in Python
1219 args = p_simple_expr_list(s)
1220 return Nodes.DelStatNode(pos, args = args)
1222 def p_pass_statement(s, with_newline = 0):
1223 pos = s.position()
1224 s.expect('pass')
1225 if with_newline:
1226 s.expect_newline("Expected a newline")
1227 return Nodes.PassStatNode(pos)
1229 def p_break_statement(s):
1230 # s.sy == 'break'
1231 pos = s.position()
1232 s.next()
1233 return Nodes.BreakStatNode(pos)
1235 def p_continue_statement(s):
1236 # s.sy == 'continue'
1237 pos = s.position()
1238 s.next()
1239 return Nodes.ContinueStatNode(pos)
1241 def p_return_statement(s):
1242 # s.sy == 'return'
1243 pos = s.position()
1244 s.next()
1245 if s.sy not in statement_terminators:
1246 value = p_testlist(s)
1247 else:
1248 value = None
1249 return Nodes.ReturnStatNode(pos, value = value)
1251 def p_raise_statement(s):
1252 # s.sy == 'raise'
1253 pos = s.position()
1254 s.next()
1255 exc_type = None
1256 exc_value = None
1257 exc_tb = None
1258 cause = None
1259 if s.sy not in statement_terminators:
1260 exc_type = p_test(s)
1261 if s.sy == ',':
1262 s.next()
1263 exc_value = p_test(s)
1264 if s.sy == ',':
1265 s.next()
1266 exc_tb = p_test(s)
1267 elif s.sy == 'from':
1268 s.next()
1269 cause = p_test(s)
1270 if exc_type or exc_value or exc_tb:
1271 return Nodes.RaiseStatNode(pos,
1272 exc_type = exc_type,
1273 exc_value = exc_value,
1274 exc_tb = exc_tb,
1275 cause = cause)
1276 else:
1277 return Nodes.ReraiseStatNode(pos)
1279 def p_import_statement(s):
1280 # s.sy in ('import', 'cimport')
1281 pos = s.position()
1282 kind = s.sy
1283 s.next()
1284 items = [p_dotted_name(s, as_allowed = 1)]
1285 while s.sy == ',':
1286 s.next()
1287 items.append(p_dotted_name(s, as_allowed = 1))
1288 stats = []
1289 for pos, target_name, dotted_name, as_name in items:
1290 dotted_name = EncodedString(dotted_name)
1291 if kind == 'cimport':
1292 stat = Nodes.CImportStatNode(pos,
1293 module_name = dotted_name,
1294 as_name = as_name)
1295 else:
1296 if as_name and "." in dotted_name:
1297 name_list = ExprNodes.ListNode(pos, args = [
1298 ExprNodes.IdentifierStringNode(pos, value = EncodedString("*"))])
1299 else:
1300 name_list = None
1301 stat = Nodes.SingleAssignmentNode(pos,
1302 lhs = ExprNodes.NameNode(pos,
1303 name = as_name or target_name),
1304 rhs = ExprNodes.ImportNode(pos,
1305 module_name = ExprNodes.IdentifierStringNode(
1306 pos, value = dotted_name),
1307 level = None,
1308 name_list = name_list))
1309 stats.append(stat)
1310 return Nodes.StatListNode(pos, stats = stats)
1312 def p_from_import_statement(s, first_statement = 0):
1313 # s.sy == 'from'
1314 pos = s.position()
1315 s.next()
1316 if s.sy == '.':
1317 # count relative import level
1318 level = 0
1319 while s.sy == '.':
1320 level += 1
1321 s.next()
1322 if s.sy == 'cimport':
1323 s.error("Relative cimport is not supported yet")
1324 else:
1325 level = None
1326 if level is not None and s.sy == 'import':
1327 # we are dealing with "from .. import foo, bar"
1328 dotted_name_pos, dotted_name = s.position(), ''
1329 elif level is not None and s.sy == 'cimport':
1330 # "from .. cimport"
1331 s.error("Relative cimport is not supported yet")
1332 else:
1333 (dotted_name_pos, _, dotted_name, _) = \
1334 p_dotted_name(s, as_allowed = 0)
1335 if s.sy in ('import', 'cimport'):
1336 kind = s.sy
1337 s.next()
1338 else:
1339 s.error("Expected 'import' or 'cimport'")
1341 is_cimport = kind == 'cimport'
1342 is_parenthesized = False
1343 if s.sy == '*':
1344 imported_names = [(s.position(), "*", None, None)]
1345 s.next()
1346 else:
1347 if s.sy == '(':
1348 is_parenthesized = True
1349 s.next()
1350 imported_names = [p_imported_name(s, is_cimport)]
1351 while s.sy == ',':
1352 s.next()
1353 if is_parenthesized and s.sy == ')':
1354 break
1355 imported_names.append(p_imported_name(s, is_cimport))
1356 if is_parenthesized:
1357 s.expect(')')
1358 dotted_name = EncodedString(dotted_name)
1359 if dotted_name == '__future__':
1360 if not first_statement:
1361 s.error("from __future__ imports must occur at the beginning of the file")
1362 elif level is not None:
1363 s.error("invalid syntax")
1364 else:
1365 for (name_pos, name, as_name, kind) in imported_names:
1366 if name == "braces":
1367 s.error("not a chance", name_pos)
1368 break
1369 try:
1370 directive = getattr(Future, name)
1371 except AttributeError:
1372 s.error("future feature %s is not defined" % name, name_pos)
1373 break
1374 s.context.future_directives.add(directive)
1375 return Nodes.PassStatNode(pos)
1376 elif kind == 'cimport':
1377 return Nodes.FromCImportStatNode(pos,
1378 module_name = dotted_name,
1379 imported_names = imported_names)
1380 else:
1381 imported_name_strings = []
1382 items = []
1383 for (name_pos, name, as_name, kind) in imported_names:
1384 encoded_name = EncodedString(name)
1385 imported_name_strings.append(
1386 ExprNodes.IdentifierStringNode(name_pos, value = encoded_name))
1387 items.append(
1388 (name,
1389 ExprNodes.NameNode(name_pos,
1390 name = as_name or name)))
1391 import_list = ExprNodes.ListNode(
1392 imported_names[0][0], args = imported_name_strings)
1393 dotted_name = EncodedString(dotted_name)
1394 return Nodes.FromImportStatNode(pos,
1395 module = ExprNodes.ImportNode(dotted_name_pos,
1396 module_name = ExprNodes.IdentifierStringNode(pos, value = dotted_name),
1397 level = level,
1398 name_list = import_list),
1399 items = items)
1401 imported_name_kinds = cython.declare(
1402 set, set(['class', 'struct', 'union']))
1404 def p_imported_name(s, is_cimport):
1405 pos = s.position()
1406 kind = None
1407 if is_cimport and s.systring in imported_name_kinds:
1408 kind = s.systring
1409 s.next()
1410 name = p_ident(s)
1411 as_name = p_as_name(s)
1412 return (pos, name, as_name, kind)
1414 def p_dotted_name(s, as_allowed):
1415 pos = s.position()
1416 target_name = p_ident(s)
1417 as_name = None
1418 names = [target_name]
1419 while s.sy == '.':
1420 s.next()
1421 names.append(p_ident(s))
1422 if as_allowed:
1423 as_name = p_as_name(s)
1424 return (pos, target_name, u'.'.join(names), as_name)
1426 def p_as_name(s):
1427 if s.sy == 'IDENT' and s.systring == 'as':
1428 s.next()
1429 return p_ident(s)
1430 else:
1431 return None
1433 def p_assert_statement(s):
1434 # s.sy == 'assert'
1435 pos = s.position()
1436 s.next()
1437 cond = p_test(s)
1438 if s.sy == ',':
1439 s.next()
1440 value = p_test(s)
1441 else:
1442 value = None
1443 return Nodes.AssertStatNode(pos, cond = cond, value = value)
1445 statement_terminators = cython.declare(set, set([';', 'NEWLINE', 'EOF']))
1447 def p_if_statement(s):
1448 # s.sy == 'if'
1449 pos = s.position()
1450 s.next()
1451 if_clauses = [p_if_clause(s)]
1452 while s.sy == 'elif':
1453 s.next()
1454 if_clauses.append(p_if_clause(s))
1455 else_clause = p_else_clause(s)
1456 return Nodes.IfStatNode(pos,
1457 if_clauses = if_clauses, else_clause = else_clause)
1459 def p_if_clause(s):
1460 pos = s.position()
1461 test = p_test(s)
1462 body = p_suite(s)
1463 return Nodes.IfClauseNode(pos,
1464 condition = test, body = body)
1466 def p_else_clause(s):
1467 if s.sy == 'else':
1468 s.next()
1469 return p_suite(s)
1470 else:
1471 return None
1473 def p_while_statement(s):
1474 # s.sy == 'while'
1475 pos = s.position()
1476 s.next()
1477 test = p_test(s)
1478 body = p_suite(s)
1479 else_clause = p_else_clause(s)
1480 return Nodes.WhileStatNode(pos,
1481 condition = test, body = body,
1482 else_clause = else_clause)
1484 def p_for_statement(s):
1485 # s.sy == 'for'
1486 pos = s.position()
1487 s.next()
1488 kw = p_for_bounds(s, allow_testlist=True)
1489 body = p_suite(s)
1490 else_clause = p_else_clause(s)
1491 kw.update(body = body, else_clause = else_clause)
1492 return Nodes.ForStatNode(pos, **kw)
1494 def p_for_bounds(s, allow_testlist=True):
1495 target = p_for_target(s)
1496 if s.sy == 'in':
1497 s.next()
1498 iterator = p_for_iterator(s, allow_testlist)
1499 return dict( target = target, iterator = iterator )
1500 elif not s.in_python_file:
1501 if s.sy == 'from':
1502 s.next()
1503 bound1 = p_bit_expr(s)
1504 else:
1505 # Support shorter "for a <= x < b" syntax
1506 bound1, target = target, None
1507 rel1 = p_for_from_relation(s)
1508 name2_pos = s.position()
1509 name2 = p_ident(s)
1510 rel2_pos = s.position()
1511 rel2 = p_for_from_relation(s)
1512 bound2 = p_bit_expr(s)
1513 step = p_for_from_step(s)
1514 if target is None:
1515 target = ExprNodes.NameNode(name2_pos, name = name2)
1516 else:
1517 if not target.is_name:
1518 error(target.pos,
1519 "Target of for-from statement must be a variable name")
1520 elif name2 != target.name:
1521 error(name2_pos,
1522 "Variable name in for-from range does not match target")
1523 if rel1[0] != rel2[0]:
1524 error(rel2_pos,
1525 "Relation directions in for-from do not match")
1526 return dict(target = target,
1527 bound1 = bound1,
1528 relation1 = rel1,
1529 relation2 = rel2,
1530 bound2 = bound2,
1531 step = step,
1533 else:
1534 s.expect('in')
1535 return {}
1537 def p_for_from_relation(s):
1538 if s.sy in inequality_relations:
1539 op = s.sy
1540 s.next()
1541 return op
1542 else:
1543 s.error("Expected one of '<', '<=', '>' '>='")
1545 def p_for_from_step(s):
1546 if s.sy == 'IDENT' and s.systring == 'by':
1547 s.next()
1548 step = p_bit_expr(s)
1549 return step
1550 else:
1551 return None
1553 inequality_relations = cython.declare(set, set(['<', '<=', '>', '>=']))
1555 def p_target(s, terminator):
1556 pos = s.position()
1557 expr = p_starred_expr(s)
1558 if s.sy == ',':
1559 s.next()
1560 exprs = [expr]
1561 while s.sy != terminator:
1562 exprs.append(p_starred_expr(s))
1563 if s.sy != ',':
1564 break
1565 s.next()
1566 return ExprNodes.TupleNode(pos, args = exprs)
1567 else:
1568 return expr
1570 def p_for_target(s):
1571 return p_target(s, 'in')
1573 def p_for_iterator(s, allow_testlist=True):
1574 pos = s.position()
1575 if allow_testlist:
1576 expr = p_testlist(s)
1577 else:
1578 expr = p_or_test(s)
1579 return ExprNodes.IteratorNode(pos, sequence = expr)
1581 def p_try_statement(s):
1582 # s.sy == 'try'
1583 pos = s.position()
1584 s.next()
1585 body = p_suite(s)
1586 except_clauses = []
1587 else_clause = None
1588 if s.sy in ('except', 'else'):
1589 while s.sy == 'except':
1590 except_clauses.append(p_except_clause(s))
1591 if s.sy == 'else':
1592 s.next()
1593 else_clause = p_suite(s)
1594 body = Nodes.TryExceptStatNode(pos,
1595 body = body, except_clauses = except_clauses,
1596 else_clause = else_clause)
1597 if s.sy != 'finally':
1598 return body
1599 # try-except-finally is equivalent to nested try-except/try-finally
1600 if s.sy == 'finally':
1601 s.next()
1602 finally_clause = p_suite(s)
1603 return Nodes.TryFinallyStatNode(pos,
1604 body = body, finally_clause = finally_clause)
1605 else:
1606 s.error("Expected 'except' or 'finally'")
1608 def p_except_clause(s):
1609 # s.sy == 'except'
1610 pos = s.position()
1611 s.next()
1612 exc_type = None
1613 exc_value = None
1614 is_except_as = False
1615 if s.sy != ':':
1616 exc_type = p_test(s)
1617 # normalise into list of single exception tests
1618 if isinstance(exc_type, ExprNodes.TupleNode):
1619 exc_type = exc_type.args
1620 else:
1621 exc_type = [exc_type]
1622 if s.sy == ',' or (s.sy == 'IDENT' and s.systring == 'as'
1623 and s.context.language_level == 2):
1624 s.next()
1625 exc_value = p_test(s)
1626 elif s.sy == 'IDENT' and s.systring == 'as':
1627 # Py3 syntax requires a name here
1628 s.next()
1629 pos2 = s.position()
1630 name = p_ident(s)
1631 exc_value = ExprNodes.NameNode(pos2, name = name)
1632 is_except_as = True
1633 body = p_suite(s)
1634 return Nodes.ExceptClauseNode(pos,
1635 pattern = exc_type, target = exc_value,
1636 body = body, is_except_as=is_except_as)
1638 def p_include_statement(s, ctx):
1639 pos = s.position()
1640 s.next() # 'include'
1641 unicode_include_file_name = p_string_literal(s, 'u')[2]
1642 s.expect_newline("Syntax error in include statement")
1643 if s.compile_time_eval:
1644 include_file_name = unicode_include_file_name
1645 include_file_path = s.context.find_include_file(include_file_name, pos)
1646 if include_file_path:
1647 s.included_files.append(include_file_name)
1648 f = Utils.open_source_file(include_file_path, mode="rU")
1649 source_desc = FileSourceDescriptor(include_file_path)
1650 s2 = PyrexScanner(f, source_desc, s, source_encoding=f.encoding, parse_comments=s.parse_comments)
1651 try:
1652 tree = p_statement_list(s2, ctx)
1653 finally:
1654 f.close()
1655 return tree
1656 else:
1657 return None
1658 else:
1659 return Nodes.PassStatNode(pos)
1661 def p_with_statement(s):
1662 s.next() # 'with'
1663 if s.systring == 'template' and not s.in_python_file:
1664 node = p_with_template(s)
1665 else:
1666 node = p_with_items(s)
1667 return node
1669 def p_with_items(s):
1670 pos = s.position()
1671 if not s.in_python_file and s.sy == 'IDENT' and s.systring in ('nogil', 'gil'):
1672 state = s.systring
1673 s.next()
1674 if s.sy == ',':
1675 s.next()
1676 body = p_with_items(s)
1677 else:
1678 body = p_suite(s)
1679 return Nodes.GILStatNode(pos, state = state, body = body)
1680 else:
1681 manager = p_test(s)
1682 target = None
1683 if s.sy == 'IDENT' and s.systring == 'as':
1684 s.next()
1685 target = p_starred_expr(s)
1686 if s.sy == ',':
1687 s.next()
1688 body = p_with_items(s)
1689 else:
1690 body = p_suite(s)
1691 return Nodes.WithStatNode(pos, manager = manager,
1692 target = target, body = body)
1694 def p_with_template(s):
1695 pos = s.position()
1696 templates = []
1697 s.next()
1698 s.expect('[')
1699 templates.append(s.systring)
1700 s.next()
1701 while s.systring == ',':
1702 s.next()
1703 templates.append(s.systring)
1704 s.next()
1705 s.expect(']')
1706 if s.sy == ':':
1707 s.next()
1708 s.expect_newline("Syntax error in template function declaration")
1709 s.expect_indent()
1710 body_ctx = Ctx()
1711 body_ctx.templates = templates
1712 func_or_var = p_c_func_or_var_declaration(s, pos, body_ctx)
1713 s.expect_dedent()
1714 return func_or_var
1715 else:
1716 error(pos, "Syntax error in template function declaration")
1718 def p_simple_statement(s, first_statement = 0):
1719 #print "p_simple_statement:", s.sy, s.systring ###
1720 if s.sy == 'global':
1721 node = p_global_statement(s)
1722 elif s.sy == 'nonlocal':
1723 node = p_nonlocal_statement(s)
1724 elif s.sy == 'print':
1725 node = p_print_statement(s)
1726 elif s.sy == 'exec':
1727 node = p_exec_statement(s)
1728 elif s.sy == 'del':
1729 node = p_del_statement(s)
1730 elif s.sy == 'break':
1731 node = p_break_statement(s)
1732 elif s.sy == 'continue':
1733 node = p_continue_statement(s)
1734 elif s.sy == 'return':
1735 node = p_return_statement(s)
1736 elif s.sy == 'raise':
1737 node = p_raise_statement(s)
1738 elif s.sy in ('import', 'cimport'):
1739 node = p_import_statement(s)
1740 elif s.sy == 'from':
1741 node = p_from_import_statement(s, first_statement = first_statement)
1742 elif s.sy == 'yield':
1743 node = p_yield_statement(s)
1744 elif s.sy == 'assert':
1745 node = p_assert_statement(s)
1746 elif s.sy == 'pass':
1747 node = p_pass_statement(s)
1748 else:
1749 node = p_expression_or_assignment(s)
1750 return node
1752 def p_simple_statement_list(s, ctx, first_statement = 0):
1753 # Parse a series of simple statements on one line
1754 # separated by semicolons.
1755 stat = p_simple_statement(s, first_statement = first_statement)
1756 pos = stat.pos
1757 stats = []
1758 if not isinstance(stat, Nodes.PassStatNode):
1759 stats.append(stat)
1760 while s.sy == ';':
1761 #print "p_simple_statement_list: maybe more to follow" ###
1762 s.next()
1763 if s.sy in ('NEWLINE', 'EOF'):
1764 break
1765 stat = p_simple_statement(s, first_statement = first_statement)
1766 if isinstance(stat, Nodes.PassStatNode):
1767 continue
1768 stats.append(stat)
1769 first_statement = False
1771 if not stats:
1772 stat = Nodes.PassStatNode(pos)
1773 elif len(stats) == 1:
1774 stat = stats[0]
1775 else:
1776 stat = Nodes.StatListNode(pos, stats = stats)
1777 s.expect_newline("Syntax error in simple statement list")
1778 return stat
1780 def p_compile_time_expr(s):
1781 old = s.compile_time_expr
1782 s.compile_time_expr = 1
1783 expr = p_testlist(s)
1784 s.compile_time_expr = old
1785 return expr
1787 def p_DEF_statement(s):
1788 pos = s.position()
1789 denv = s.compile_time_env
1790 s.next() # 'DEF'
1791 name = p_ident(s)
1792 s.expect('=')
1793 expr = p_compile_time_expr(s)
1794 value = expr.compile_time_value(denv)
1795 #print "p_DEF_statement: %s = %r" % (name, value) ###
1796 denv.declare(name, value)
1797 s.expect_newline()
1798 return Nodes.PassStatNode(pos)
1800 def p_IF_statement(s, ctx):
1801 pos = s.position()
1802 saved_eval = s.compile_time_eval
1803 current_eval = saved_eval
1804 denv = s.compile_time_env
1805 result = None
1806 while 1:
1807 s.next() # 'IF' or 'ELIF'
1808 expr = p_compile_time_expr(s)
1809 s.compile_time_eval = current_eval and bool(expr.compile_time_value(denv))
1810 body = p_suite(s, ctx)
1811 if s.compile_time_eval:
1812 result = body
1813 current_eval = 0
1814 if s.sy != 'ELIF':
1815 break
1816 if s.sy == 'ELSE':
1817 s.next()
1818 s.compile_time_eval = current_eval
1819 body = p_suite(s, ctx)
1820 if current_eval:
1821 result = body
1822 if not result:
1823 result = Nodes.PassStatNode(pos)
1824 s.compile_time_eval = saved_eval
1825 return result
1827 def p_statement(s, ctx, first_statement = 0):
1828 cdef_flag = ctx.cdef_flag
1829 decorators = None
1830 if s.sy == 'ctypedef':
1831 if ctx.level not in ('module', 'module_pxd'):
1832 s.error("ctypedef statement not allowed here")
1833 #if ctx.api:
1834 # error(s.position(), "'api' not allowed with 'ctypedef'")
1835 return p_ctypedef_statement(s, ctx)
1836 elif s.sy == 'DEF':
1837 return p_DEF_statement(s)
1838 elif s.sy == 'IF':
1839 return p_IF_statement(s, ctx)
1840 elif s.sy == 'DECORATOR':
1841 if ctx.level not in ('module', 'class', 'c_class', 'function', 'property', 'module_pxd', 'c_class_pxd', 'other'):
1842 s.error('decorator not allowed here')
1843 s.level = ctx.level
1844 decorators = p_decorators(s)
1845 bad_toks = 'def', 'cdef', 'cpdef', 'class'
1846 if not ctx.allow_struct_enum_decorator and s.sy not in bad_toks:
1847 s.error("Decorators can only be followed by functions or classes")
1848 elif s.sy == 'pass' and cdef_flag:
1849 # empty cdef block
1850 return p_pass_statement(s, with_newline = 1)
1852 overridable = 0
1853 if s.sy == 'cdef':
1854 cdef_flag = 1
1855 s.next()
1856 elif s.sy == 'cpdef':
1857 cdef_flag = 1
1858 overridable = 1
1859 s.next()
1860 if cdef_flag:
1861 if ctx.level not in ('module', 'module_pxd', 'function', 'c_class', 'c_class_pxd'):
1862 s.error('cdef statement not allowed here')
1863 s.level = ctx.level
1864 node = p_cdef_statement(s, ctx(overridable = overridable))
1865 if decorators is not None:
1866 tup = Nodes.CFuncDefNode, Nodes.CVarDefNode, Nodes.CClassDefNode
1867 if ctx.allow_struct_enum_decorator:
1868 tup += Nodes.CStructOrUnionDefNode, Nodes.CEnumDefNode
1869 if not isinstance(node, tup):
1870 s.error("Decorators can only be followed by functions or classes")
1871 node.decorators = decorators
1872 return node
1873 else:
1874 if ctx.api:
1875 s.error("'api' not allowed with this statement", fatal=False)
1876 elif s.sy == 'def':
1877 # def statements aren't allowed in pxd files, except
1878 # as part of a cdef class
1879 if ('pxd' in ctx.level) and (ctx.level != 'c_class_pxd'):
1880 s.error('def statement not allowed here')
1881 s.level = ctx.level
1882 return p_def_statement(s, decorators)
1883 elif s.sy == 'class':
1884 if ctx.level not in ('module', 'function', 'class', 'other'):
1885 s.error("class definition not allowed here")
1886 return p_class_statement(s, decorators)
1887 elif s.sy == 'include':
1888 if ctx.level not in ('module', 'module_pxd'):
1889 s.error("include statement not allowed here")
1890 return p_include_statement(s, ctx)
1891 elif ctx.level == 'c_class' and s.sy == 'IDENT' and s.systring == 'property':
1892 return p_property_decl(s)
1893 elif s.sy == 'pass' and ctx.level != 'property':
1894 return p_pass_statement(s, with_newline=True)
1895 else:
1896 if ctx.level in ('c_class_pxd', 'property'):
1897 node = p_ignorable_statement(s)
1898 if node is not None:
1899 return node
1900 s.error("Executable statement not allowed here")
1901 if s.sy == 'if':
1902 return p_if_statement(s)
1903 elif s.sy == 'while':
1904 return p_while_statement(s)
1905 elif s.sy == 'for':
1906 return p_for_statement(s)
1907 elif s.sy == 'try':
1908 return p_try_statement(s)
1909 elif s.sy == 'with':
1910 return p_with_statement(s)
1911 else:
1912 return p_simple_statement_list(
1913 s, ctx, first_statement = first_statement)
1915 def p_statement_list(s, ctx, first_statement = 0):
1916 # Parse a series of statements separated by newlines.
1917 pos = s.position()
1918 stats = []
1919 while s.sy not in ('DEDENT', 'EOF'):
1920 stat = p_statement(s, ctx, first_statement = first_statement)
1921 if isinstance(stat, Nodes.PassStatNode):
1922 continue
1923 stats.append(stat)
1924 first_statement = False
1925 if not stats:
1926 return Nodes.PassStatNode(pos)
1927 elif len(stats) == 1:
1928 return stats[0]
1929 else:
1930 return Nodes.StatListNode(pos, stats = stats)
1933 def p_suite(s, ctx=Ctx()):
1934 return p_suite_with_docstring(s, ctx, with_doc_only=False)[1]
1937 def p_suite_with_docstring(s, ctx, with_doc_only=False):
1938 s.expect(':')
1939 doc = None
1940 if s.sy == 'NEWLINE':
1941 s.next()
1942 s.expect_indent()
1943 if with_doc_only:
1944 doc = p_doc_string(s)
1945 body = p_statement_list(s, ctx)
1946 s.expect_dedent()
1947 else:
1948 if ctx.api:
1949 s.error("'api' not allowed with this statement", fatal=False)
1950 if ctx.level in ('module', 'class', 'function', 'other'):
1951 body = p_simple_statement_list(s, ctx)
1952 else:
1953 body = p_pass_statement(s)
1954 s.expect_newline("Syntax error in declarations")
1955 if not with_doc_only:
1956 doc, body = _extract_docstring(body)
1957 return doc, body
1960 def p_positional_and_keyword_args(s, end_sy_set, templates = None):
1962 Parses positional and keyword arguments. end_sy_set
1963 should contain any s.sy that terminate the argument list.
1964 Argument expansion (* and **) are not allowed.
1966 Returns: (positional_args, keyword_args)
1968 positional_args = []
1969 keyword_args = []
1970 pos_idx = 0
1972 while s.sy not in end_sy_set:
1973 if s.sy == '*' or s.sy == '**':
1974 s.error('Argument expansion not allowed here.', fatal=False)
1976 parsed_type = False
1977 if s.sy == 'IDENT' and s.peek()[0] == '=':
1978 ident = s.systring
1979 s.next() # s.sy is '='
1980 s.next()
1981 if looking_at_expr(s):
1982 arg = p_test(s)
1983 else:
1984 base_type = p_c_base_type(s, templates = templates)
1985 declarator = p_c_declarator(s, empty = 1)
1986 arg = Nodes.CComplexBaseTypeNode(base_type.pos,
1987 base_type = base_type, declarator = declarator)
1988 parsed_type = True
1989 keyword_node = ExprNodes.IdentifierStringNode(
1990 arg.pos, value = EncodedString(ident))
1991 keyword_args.append((keyword_node, arg))
1992 was_keyword = True
1994 else:
1995 if looking_at_expr(s):
1996 arg = p_test(s)
1997 else:
1998 base_type = p_c_base_type(s, templates = templates)
1999 declarator = p_c_declarator(s, empty = 1)
2000 arg = Nodes.CComplexBaseTypeNode(base_type.pos,
2001 base_type = base_type, declarator = declarator)
2002 parsed_type = True
2003 positional_args.append(arg)
2004 pos_idx += 1
2005 if len(keyword_args) > 0:
2006 s.error("Non-keyword arg following keyword arg",
2007 pos=arg.pos)
2009 if s.sy != ',':
2010 if s.sy not in end_sy_set:
2011 if parsed_type:
2012 s.error("Unmatched %s" % " or ".join(end_sy_set))
2013 break
2014 s.next()
2015 return positional_args, keyword_args
2017 def p_c_base_type(s, self_flag = 0, nonempty = 0, templates = None):
2018 # If self_flag is true, this is the base type for the
2019 # self argument of a C method of an extension type.
2020 if s.sy == '(':
2021 return p_c_complex_base_type(s, templates = templates)
2022 else:
2023 return p_c_simple_base_type(s, self_flag, nonempty = nonempty, templates = templates)
2025 def p_calling_convention(s):
2026 if s.sy == 'IDENT' and s.systring in calling_convention_words:
2027 result = s.systring
2028 s.next()
2029 return result
2030 else:
2031 return ""
2033 calling_convention_words = cython.declare(
2034 set, set(["__stdcall", "__cdecl", "__fastcall"]))
2036 def p_c_complex_base_type(s, templates = None):
2037 # s.sy == '('
2038 pos = s.position()
2039 s.next()
2040 base_type = p_c_base_type(s, templates = templates)
2041 declarator = p_c_declarator(s, empty = 1)
2042 s.expect(')')
2043 type_node = Nodes.CComplexBaseTypeNode(pos,
2044 base_type = base_type, declarator = declarator)
2045 if s.sy == '[':
2046 if is_memoryviewslice_access(s):
2047 type_node = p_memoryviewslice_access(s, type_node)
2048 else:
2049 type_node = p_buffer_or_template(s, type_node, templates)
2050 return type_node
2053 def p_c_simple_base_type(s, self_flag, nonempty, templates = None):
2054 #print "p_c_simple_base_type: self_flag =", self_flag, nonempty
2055 is_basic = 0
2056 signed = 1
2057 longness = 0
2058 complex = 0
2059 module_path = []
2060 pos = s.position()
2061 if not s.sy == 'IDENT':
2062 error(pos, "Expected an identifier, found '%s'" % s.sy)
2063 if s.systring == 'const':
2064 s.next()
2065 base_type = p_c_base_type(s,
2066 self_flag = self_flag, nonempty = nonempty, templates = templates)
2067 return Nodes.CConstTypeNode(pos, base_type = base_type)
2068 if looking_at_base_type(s):
2069 #print "p_c_simple_base_type: looking_at_base_type at", s.position()
2070 is_basic = 1
2071 if s.sy == 'IDENT' and s.systring in special_basic_c_types:
2072 signed, longness = special_basic_c_types[s.systring]
2073 name = s.systring
2074 s.next()
2075 else:
2076 signed, longness = p_sign_and_longness(s)
2077 if s.sy == 'IDENT' and s.systring in basic_c_type_names:
2078 name = s.systring
2079 s.next()
2080 else:
2081 name = 'int' # long [int], short [int], long [int] complex, etc.
2082 if s.sy == 'IDENT' and s.systring == 'complex':
2083 complex = 1
2084 s.next()
2085 elif looking_at_dotted_name(s):
2086 #print "p_c_simple_base_type: looking_at_type_name at", s.position()
2087 name = s.systring
2088 s.next()
2089 while s.sy == '.':
2090 module_path.append(name)
2091 s.next()
2092 name = p_ident(s)
2093 else:
2094 name = s.systring
2095 s.next()
2096 if nonempty and s.sy != 'IDENT':
2097 # Make sure this is not a declaration of a variable or function.
2098 if s.sy == '(':
2099 s.next()
2100 if (s.sy == '*' or s.sy == '**' or s.sy == '&'
2101 or (s.sy == 'IDENT' and s.systring in calling_convention_words)):
2102 s.put_back('(', '(')
2103 else:
2104 s.put_back('(', '(')
2105 s.put_back('IDENT', name)
2106 name = None
2107 elif s.sy not in ('*', '**', '[', '&'):
2108 s.put_back('IDENT', name)
2109 name = None
2111 type_node = Nodes.CSimpleBaseTypeNode(pos,
2112 name = name, module_path = module_path,
2113 is_basic_c_type = is_basic, signed = signed,
2114 complex = complex, longness = longness,
2115 is_self_arg = self_flag, templates = templates)
2117 # declarations here.
2118 if s.sy == '[':
2119 if is_memoryviewslice_access(s):
2120 type_node = p_memoryviewslice_access(s, type_node)
2121 else:
2122 type_node = p_buffer_or_template(s, type_node, templates)
2124 if s.sy == '.':
2125 s.next()
2126 name = p_ident(s)
2127 type_node = Nodes.CNestedBaseTypeNode(pos, base_type = type_node, name = name)
2129 return type_node
2131 def p_buffer_or_template(s, base_type_node, templates):
2132 # s.sy == '['
2133 pos = s.position()
2134 s.next()
2135 # Note that buffer_positional_options_count=1, so the only positional argument is dtype.
2136 # For templated types, all parameters are types.
2137 positional_args, keyword_args = (
2138 p_positional_and_keyword_args(s, (']',), templates)
2140 s.expect(']')
2142 if s.sy == '[':
2143 base_type_node = p_buffer_or_template(s, base_type_node, templates)
2145 keyword_dict = ExprNodes.DictNode(pos,
2146 key_value_pairs = [
2147 ExprNodes.DictItemNode(pos=key.pos, key=key, value=value)
2148 for key, value in keyword_args
2150 result = Nodes.TemplatedTypeNode(pos,
2151 positional_args = positional_args,
2152 keyword_args = keyword_dict,
2153 base_type_node = base_type_node)
2154 return result
2156 def p_bracketed_base_type(s, base_type_node, nonempty, empty):
2157 # s.sy == '['
2158 if empty and not nonempty:
2159 # sizeof-like thing. Only anonymous C arrays allowed (int[SIZE]).
2160 return base_type_node
2161 elif not empty and nonempty:
2162 # declaration of either memoryview slice or buffer.
2163 if is_memoryviewslice_access(s):
2164 return p_memoryviewslice_access(s, base_type_node)
2165 else:
2166 return p_buffer_or_template(s, base_type_node, None)
2167 # return p_buffer_access(s, base_type_node)
2168 elif not empty and not nonempty:
2169 # only anonymous C arrays and memoryview slice arrays here. We
2170 # disallow buffer declarations for now, due to ambiguity with anonymous
2171 # C arrays.
2172 if is_memoryviewslice_access(s):
2173 return p_memoryviewslice_access(s, base_type_node)
2174 else:
2175 return base_type_node
2177 def is_memoryviewslice_access(s):
2178 # s.sy == '['
2179 # a memoryview slice declaration is distinguishable from a buffer access
2180 # declaration by the first entry in the bracketed list. The buffer will
2181 # not have an unnested colon in the first entry; the memoryview slice will.
2182 saved = [(s.sy, s.systring)]
2183 s.next()
2184 retval = False
2185 if s.systring == ':':
2186 retval = True
2187 elif s.sy == 'INT':
2188 saved.append((s.sy, s.systring))
2189 s.next()
2190 if s.sy == ':':
2191 retval = True
2193 for sv in saved[::-1]:
2194 s.put_back(*sv)
2196 return retval
2198 def p_memoryviewslice_access(s, base_type_node):
2199 # s.sy == '['
2200 pos = s.position()
2201 s.next()
2202 subscripts, _ = p_subscript_list(s)
2203 # make sure each entry in subscripts is a slice
2204 for subscript in subscripts:
2205 if len(subscript) < 2:
2206 s.error("An axis specification in memoryview declaration does not have a ':'.")
2207 s.expect(']')
2208 indexes = make_slice_nodes(pos, subscripts)
2209 result = Nodes.MemoryViewSliceTypeNode(pos,
2210 base_type_node = base_type_node,
2211 axes = indexes)
2212 return result
2214 def looking_at_name(s):
2215 return s.sy == 'IDENT' and not s.systring in calling_convention_words
2217 def looking_at_expr(s):
2218 if s.systring in base_type_start_words:
2219 return False
2220 elif s.sy == 'IDENT':
2221 is_type = False
2222 name = s.systring
2223 dotted_path = []
2224 s.next()
2226 while s.sy == '.':
2227 s.next()
2228 dotted_path.append(s.systring)
2229 s.expect('IDENT')
2231 saved = s.sy, s.systring
2232 if s.sy == 'IDENT':
2233 is_type = True
2234 elif s.sy == '*' or s.sy == '**':
2235 s.next()
2236 is_type = s.sy in (')', ']')
2237 s.put_back(*saved)
2238 elif s.sy == '(':
2239 s.next()
2240 is_type = s.sy == '*'
2241 s.put_back(*saved)
2242 elif s.sy == '[':
2243 s.next()
2244 is_type = s.sy == ']'
2245 s.put_back(*saved)
2247 dotted_path.reverse()
2248 for p in dotted_path:
2249 s.put_back('IDENT', p)
2250 s.put_back('.', '.')
2252 s.put_back('IDENT', name)
2253 return not is_type and saved[0]
2254 else:
2255 return True
2257 def looking_at_base_type(s):
2258 #print "looking_at_base_type?", s.sy, s.systring, s.position()
2259 return s.sy == 'IDENT' and s.systring in base_type_start_words
2261 def looking_at_dotted_name(s):
2262 if s.sy == 'IDENT':
2263 name = s.systring
2264 s.next()
2265 result = s.sy == '.'
2266 s.put_back('IDENT', name)
2267 return result
2268 else:
2269 return 0
2271 def looking_at_call(s):
2272 "See if we're looking at a.b.c("
2273 # Don't mess up the original position, so save and restore it.
2274 # Unfortunately there's no good way to handle this, as a subsequent call
2275 # to next() will not advance the position until it reads a new token.
2276 position = s.start_line, s.start_col
2277 result = looking_at_expr(s) == u'('
2278 if not result:
2279 s.start_line, s.start_col = position
2280 return result
2282 basic_c_type_names = cython.declare(
2283 set, set(["void", "char", "int", "float", "double", "bint"]))
2285 special_basic_c_types = cython.declare(dict, {
2286 # name : (signed, longness)
2287 "Py_UNICODE" : (0, 0),
2288 "Py_UCS4" : (0, 0),
2289 "Py_ssize_t" : (2, 0),
2290 "ssize_t" : (2, 0),
2291 "size_t" : (0, 0),
2292 "ptrdiff_t" : (2, 0),
2295 sign_and_longness_words = cython.declare(
2296 set, set(["short", "long", "signed", "unsigned"]))
2298 base_type_start_words = cython.declare(
2299 set,
2300 basic_c_type_names
2301 | sign_and_longness_words
2302 | set(special_basic_c_types))
2304 struct_enum_union = cython.declare(
2305 set, set(["struct", "union", "enum", "packed"]))
2307 def p_sign_and_longness(s):
2308 signed = 1
2309 longness = 0
2310 while s.sy == 'IDENT' and s.systring in sign_and_longness_words:
2311 if s.systring == 'unsigned':
2312 signed = 0
2313 elif s.systring == 'signed':
2314 signed = 2
2315 elif s.systring == 'short':
2316 longness = -1
2317 elif s.systring == 'long':
2318 longness += 1
2319 s.next()
2320 return signed, longness
2322 def p_opt_cname(s):
2323 literal = p_opt_string_literal(s, 'u')
2324 if literal is not None:
2325 cname = EncodedString(literal)
2326 cname.encoding = s.source_encoding
2327 else:
2328 cname = None
2329 return cname
2331 def p_c_declarator(s, ctx = Ctx(), empty = 0, is_type = 0, cmethod_flag = 0,
2332 assignable = 0, nonempty = 0,
2333 calling_convention_allowed = 0):
2334 # If empty is true, the declarator must be empty. If nonempty is true,
2335 # the declarator must be nonempty. Otherwise we don't care.
2336 # If cmethod_flag is true, then if this declarator declares
2337 # a function, it's a C method of an extension type.
2338 pos = s.position()
2339 if s.sy == '(':
2340 s.next()
2341 if s.sy == ')' or looking_at_name(s):
2342 base = Nodes.CNameDeclaratorNode(pos, name = EncodedString(u""), cname = None)
2343 result = p_c_func_declarator(s, pos, ctx, base, cmethod_flag)
2344 else:
2345 result = p_c_declarator(s, ctx, empty = empty, is_type = is_type,
2346 cmethod_flag = cmethod_flag,
2347 nonempty = nonempty,
2348 calling_convention_allowed = 1)
2349 s.expect(')')
2350 else:
2351 result = p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag,
2352 assignable, nonempty)
2353 if not calling_convention_allowed and result.calling_convention and s.sy != '(':
2354 error(s.position(), "%s on something that is not a function"
2355 % result.calling_convention)
2356 while s.sy in ('[', '('):
2357 pos = s.position()
2358 if s.sy == '[':
2359 result = p_c_array_declarator(s, result)
2360 else: # sy == '('
2361 s.next()
2362 result = p_c_func_declarator(s, pos, ctx, result, cmethod_flag)
2363 cmethod_flag = 0
2364 return result
2366 def p_c_array_declarator(s, base):
2367 pos = s.position()
2368 s.next() # '['
2369 if s.sy != ']':
2370 dim = p_testlist(s)
2371 else:
2372 dim = None
2373 s.expect(']')
2374 return Nodes.CArrayDeclaratorNode(pos, base = base, dimension = dim)
2376 def p_c_func_declarator(s, pos, ctx, base, cmethod_flag):
2377 # Opening paren has already been skipped
2378 args = p_c_arg_list(s, ctx, cmethod_flag = cmethod_flag,
2379 nonempty_declarators = 0)
2380 ellipsis = p_optional_ellipsis(s)
2381 s.expect(')')
2382 nogil = p_nogil(s)
2383 exc_val, exc_check = p_exception_value_clause(s)
2384 with_gil = p_with_gil(s)
2385 return Nodes.CFuncDeclaratorNode(pos,
2386 base = base, args = args, has_varargs = ellipsis,
2387 exception_value = exc_val, exception_check = exc_check,
2388 nogil = nogil or ctx.nogil or with_gil, with_gil = with_gil)
2390 supported_overloaded_operators = cython.declare(set, set([
2391 '+', '-', '*', '/', '%',
2392 '++', '--', '~', '|', '&', '^', '<<', '>>', ',',
2393 '==', '!=', '>=', '>', '<=', '<',
2394 '[]', '()', '!',
2397 def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag,
2398 assignable, nonempty):
2399 pos = s.position()
2400 calling_convention = p_calling_convention(s)
2401 if s.sy == '*':
2402 s.next()
2403 if s.systring == 'const':
2404 const_pos = s.position()
2405 s.next()
2406 const_base = p_c_declarator(s, ctx, empty = empty,
2407 is_type = is_type,
2408 cmethod_flag = cmethod_flag,
2409 assignable = assignable,
2410 nonempty = nonempty)
2411 base = Nodes.CConstDeclaratorNode(const_pos, base = const_base)
2412 else:
2413 base = p_c_declarator(s, ctx, empty = empty, is_type = is_type,
2414 cmethod_flag = cmethod_flag,
2415 assignable = assignable, nonempty = nonempty)
2416 result = Nodes.CPtrDeclaratorNode(pos,
2417 base = base)
2418 elif s.sy == '**': # scanner returns this as a single token
2419 s.next()
2420 base = p_c_declarator(s, ctx, empty = empty, is_type = is_type,
2421 cmethod_flag = cmethod_flag,
2422 assignable = assignable, nonempty = nonempty)
2423 result = Nodes.CPtrDeclaratorNode(pos,
2424 base = Nodes.CPtrDeclaratorNode(pos,
2425 base = base))
2426 elif s.sy == '&':
2427 s.next()
2428 base = p_c_declarator(s, ctx, empty = empty, is_type = is_type,
2429 cmethod_flag = cmethod_flag,
2430 assignable = assignable, nonempty = nonempty)
2431 result = Nodes.CReferenceDeclaratorNode(pos, base = base)
2432 else:
2433 rhs = None
2434 if s.sy == 'IDENT':
2435 name = EncodedString(s.systring)
2436 if empty:
2437 error(s.position(), "Declarator should be empty")
2438 s.next()
2439 cname = p_opt_cname(s)
2440 if name != 'operator' and s.sy == '=' and assignable:
2441 s.next()
2442 rhs = p_test(s)
2443 else:
2444 if nonempty:
2445 error(s.position(), "Empty declarator")
2446 name = ""
2447 cname = None
2448 if cname is None and ctx.namespace is not None and nonempty:
2449 cname = ctx.namespace + "::" + name
2450 if name == 'operator' and ctx.visibility == 'extern' and nonempty:
2451 op = s.sy
2452 if [1 for c in op if c in '+-*/<=>!%&|([^~,']:
2453 s.next()
2454 # Handle diphthong operators.
2455 if op == '(':
2456 s.expect(')')
2457 op = '()'
2458 elif op == '[':
2459 s.expect(']')
2460 op = '[]'
2461 elif op in ('-', '+', '|', '&') and s.sy == op:
2462 op *= 2 # ++, --, ...
2463 s.next()
2464 elif s.sy == '=':
2465 op += s.sy # +=, -=, ...
2466 s.next()
2467 if op not in supported_overloaded_operators:
2468 s.error("Overloading operator '%s' not yet supported." % op,
2469 fatal=False)
2470 name += op
2471 result = Nodes.CNameDeclaratorNode(pos,
2472 name = name, cname = cname, default = rhs)
2473 result.calling_convention = calling_convention
2474 return result
2476 def p_nogil(s):
2477 if s.sy == 'IDENT' and s.systring == 'nogil':
2478 s.next()
2479 return 1
2480 else:
2481 return 0
2483 def p_with_gil(s):
2484 if s.sy == 'with':
2485 s.next()
2486 s.expect_keyword('gil')
2487 return 1
2488 else:
2489 return 0
2491 def p_exception_value_clause(s):
2492 exc_val = None
2493 exc_check = 0
2494 if s.sy == 'except':
2495 s.next()
2496 if s.sy == '*':
2497 exc_check = 1
2498 s.next()
2499 elif s.sy == '+':
2500 exc_check = '+'
2501 s.next()
2502 if s.sy == 'IDENT':
2503 name = s.systring
2504 s.next()
2505 exc_val = p_name(s, name)
2506 else:
2507 if s.sy == '?':
2508 exc_check = 1
2509 s.next()
2510 exc_val = p_test(s)
2511 return exc_val, exc_check
2513 c_arg_list_terminators = cython.declare(set, set(['*', '**', '.', ')']))
2515 def p_c_arg_list(s, ctx = Ctx(), in_pyfunc = 0, cmethod_flag = 0,
2516 nonempty_declarators = 0, kw_only = 0, annotated = 1):
2517 # Comma-separated list of C argument declarations, possibly empty.
2518 # May have a trailing comma.
2519 args = []
2520 is_self_arg = cmethod_flag
2521 while s.sy not in c_arg_list_terminators:
2522 args.append(p_c_arg_decl(s, ctx, in_pyfunc, is_self_arg,
2523 nonempty = nonempty_declarators, kw_only = kw_only,
2524 annotated = annotated))
2525 if s.sy != ',':
2526 break
2527 s.next()
2528 is_self_arg = 0
2529 return args
2531 def p_optional_ellipsis(s):
2532 if s.sy == '.':
2533 expect_ellipsis(s)
2534 return 1
2535 else:
2536 return 0
2538 def p_c_arg_decl(s, ctx, in_pyfunc, cmethod_flag = 0, nonempty = 0,
2539 kw_only = 0, annotated = 1):
2540 pos = s.position()
2541 not_none = or_none = 0
2542 default = None
2543 annotation = None
2544 if s.in_python_file:
2545 # empty type declaration
2546 base_type = Nodes.CSimpleBaseTypeNode(pos,
2547 name = None, module_path = [],
2548 is_basic_c_type = 0, signed = 0,
2549 complex = 0, longness = 0,
2550 is_self_arg = cmethod_flag, templates = None)
2551 else:
2552 base_type = p_c_base_type(s, cmethod_flag, nonempty = nonempty)
2553 declarator = p_c_declarator(s, ctx, nonempty = nonempty)
2554 if s.sy in ('not', 'or') and not s.in_python_file:
2555 kind = s.sy
2556 s.next()
2557 if s.sy == 'IDENT' and s.systring == 'None':
2558 s.next()
2559 else:
2560 s.error("Expected 'None'")
2561 if not in_pyfunc:
2562 error(pos, "'%s None' only allowed in Python functions" % kind)
2563 or_none = kind == 'or'
2564 not_none = kind == 'not'
2565 if annotated and s.sy == ':':
2566 s.next()
2567 annotation = p_test(s)
2568 if s.sy == '=':
2569 s.next()
2570 if 'pxd' in ctx.level:
2571 if s.sy not in ['*', '?']:
2572 error(pos, "default values cannot be specified in pxd files, use ? or *")
2573 default = ExprNodes.BoolNode(1)
2574 s.next()
2575 else:
2576 default = p_test(s)
2577 return Nodes.CArgDeclNode(pos,
2578 base_type = base_type,
2579 declarator = declarator,
2580 not_none = not_none,
2581 or_none = or_none,
2582 default = default,
2583 annotation = annotation,
2584 kw_only = kw_only)
2586 def p_api(s):
2587 if s.sy == 'IDENT' and s.systring == 'api':
2588 s.next()
2589 return 1
2590 else:
2591 return 0
2593 def p_cdef_statement(s, ctx):
2594 pos = s.position()
2595 ctx.visibility = p_visibility(s, ctx.visibility)
2596 ctx.api = ctx.api or p_api(s)
2597 if ctx.api:
2598 if ctx.visibility not in ('private', 'public'):
2599 error(pos, "Cannot combine 'api' with '%s'" % ctx.visibility)
2600 if (ctx.visibility == 'extern') and s.sy == 'from':
2601 return p_cdef_extern_block(s, pos, ctx)
2602 elif s.sy == 'import':
2603 s.next()
2604 return p_cdef_extern_block(s, pos, ctx)
2605 elif p_nogil(s):
2606 ctx.nogil = 1
2607 if ctx.overridable:
2608 error(pos, "cdef blocks cannot be declared cpdef")
2609 return p_cdef_block(s, ctx)
2610 elif s.sy == ':':
2611 if ctx.overridable:
2612 error(pos, "cdef blocks cannot be declared cpdef")
2613 return p_cdef_block(s, ctx)
2614 elif s.sy == 'class':
2615 if ctx.level not in ('module', 'module_pxd'):
2616 error(pos, "Extension type definition not allowed here")
2617 if ctx.overridable:
2618 error(pos, "Extension types cannot be declared cpdef")
2619 return p_c_class_definition(s, pos, ctx)
2620 elif s.sy == 'IDENT' and s.systring == 'cppclass':
2621 return p_cpp_class_definition(s, pos, ctx)
2622 elif s.sy == 'IDENT' and s.systring in struct_enum_union:
2623 if ctx.level not in ('module', 'module_pxd'):
2624 error(pos, "C struct/union/enum definition not allowed here")
2625 if ctx.overridable:
2626 error(pos, "C struct/union/enum cannot be declared cpdef")
2627 return p_struct_enum(s, pos, ctx)
2628 elif s.sy == 'IDENT' and s.systring == 'fused':
2629 return p_fused_definition(s, pos, ctx)
2630 else:
2631 return p_c_func_or_var_declaration(s, pos, ctx)
2633 def p_cdef_block(s, ctx):
2634 return p_suite(s, ctx(cdef_flag = 1))
2636 def p_cdef_extern_block(s, pos, ctx):
2637 if ctx.overridable:
2638 error(pos, "cdef extern blocks cannot be declared cpdef")
2639 include_file = None
2640 s.expect('from')
2641 if s.sy == '*':
2642 s.next()
2643 else:
2644 include_file = p_string_literal(s, 'u')[2]
2645 ctx = ctx(cdef_flag = 1, visibility = 'extern')
2646 if s.systring == "namespace":
2647 s.next()
2648 ctx.namespace = p_string_literal(s, 'u')[2]
2649 if p_nogil(s):
2650 ctx.nogil = 1
2651 body = p_suite(s, ctx)
2652 return Nodes.CDefExternNode(pos,
2653 include_file = include_file,
2654 body = body,
2655 namespace = ctx.namespace)
2657 def p_c_enum_definition(s, pos, ctx):
2658 # s.sy == ident 'enum'
2659 s.next()
2660 if s.sy == 'IDENT':
2661 name = s.systring
2662 s.next()
2663 cname = p_opt_cname(s)
2664 if cname is None and ctx.namespace is not None:
2665 cname = ctx.namespace + "::" + name
2666 else:
2667 name = None
2668 cname = None
2669 items = None
2670 s.expect(':')
2671 items = []
2672 if s.sy != 'NEWLINE':
2673 p_c_enum_line(s, ctx, items)
2674 else:
2675 s.next() # 'NEWLINE'
2676 s.expect_indent()
2677 while s.sy not in ('DEDENT', 'EOF'):
2678 p_c_enum_line(s, ctx, items)
2679 s.expect_dedent()
2680 return Nodes.CEnumDefNode(
2681 pos, name = name, cname = cname, items = items,
2682 typedef_flag = ctx.typedef_flag, visibility = ctx.visibility,
2683 api = ctx.api, in_pxd = ctx.level == 'module_pxd')
2685 def p_c_enum_line(s, ctx, items):
2686 if s.sy != 'pass':
2687 p_c_enum_item(s, ctx, items)
2688 while s.sy == ',':
2689 s.next()
2690 if s.sy in ('NEWLINE', 'EOF'):
2691 break
2692 p_c_enum_item(s, ctx, items)
2693 else:
2694 s.next()
2695 s.expect_newline("Syntax error in enum item list")
2697 def p_c_enum_item(s, ctx, items):
2698 pos = s.position()
2699 name = p_ident(s)
2700 cname = p_opt_cname(s)
2701 if cname is None and ctx.namespace is not None:
2702 cname = ctx.namespace + "::" + name
2703 value = None
2704 if s.sy == '=':
2705 s.next()
2706 value = p_test(s)
2707 items.append(Nodes.CEnumDefItemNode(pos,
2708 name = name, cname = cname, value = value))
2710 def p_c_struct_or_union_definition(s, pos, ctx):
2711 packed = False
2712 if s.systring == 'packed':
2713 packed = True
2714 s.next()
2715 if s.sy != 'IDENT' or s.systring != 'struct':
2716 s.expected('struct')
2717 # s.sy == ident 'struct' or 'union'
2718 kind = s.systring
2719 s.next()
2720 name = p_ident(s)
2721 cname = p_opt_cname(s)
2722 if cname is None and ctx.namespace is not None:
2723 cname = ctx.namespace + "::" + name
2724 attributes = None
2725 if s.sy == ':':
2726 s.next()
2727 s.expect('NEWLINE')
2728 s.expect_indent()
2729 attributes = []
2730 body_ctx = Ctx()
2731 while s.sy != 'DEDENT':
2732 if s.sy != 'pass':
2733 attributes.append(
2734 p_c_func_or_var_declaration(s, s.position(), body_ctx))
2735 else:
2736 s.next()
2737 s.expect_newline("Expected a newline")
2738 s.expect_dedent()
2739 else:
2740 s.expect_newline("Syntax error in struct or union definition")
2741 return Nodes.CStructOrUnionDefNode(pos,
2742 name = name, cname = cname, kind = kind, attributes = attributes,
2743 typedef_flag = ctx.typedef_flag, visibility = ctx.visibility,
2744 api = ctx.api, in_pxd = ctx.level == 'module_pxd', packed = packed)
2746 def p_fused_definition(s, pos, ctx):
2748 c(type)def fused my_fused_type:
2751 # s.systring == 'fused'
2753 if ctx.level not in ('module', 'module_pxd'):
2754 error(pos, "Fused type definition not allowed here")
2756 s.next()
2757 name = p_ident(s)
2759 s.expect(":")
2760 s.expect_newline()
2761 s.expect_indent()
2763 types = []
2764 while s.sy != 'DEDENT':
2765 if s.sy != 'pass':
2766 #types.append(p_c_declarator(s))
2767 types.append(p_c_base_type(s)) #, nonempty=1))
2768 else:
2769 s.next()
2771 s.expect_newline()
2773 s.expect_dedent()
2775 if not types:
2776 error(pos, "Need at least one type")
2778 return Nodes.FusedTypeNode(pos, name=name, types=types)
2780 def p_struct_enum(s, pos, ctx):
2781 if s.systring == 'enum':
2782 return p_c_enum_definition(s, pos, ctx)
2783 else:
2784 return p_c_struct_or_union_definition(s, pos, ctx)
2786 def p_visibility(s, prev_visibility):
2787 pos = s.position()
2788 visibility = prev_visibility
2789 if s.sy == 'IDENT' and s.systring in ('extern', 'public', 'readonly'):
2790 visibility = s.systring
2791 if prev_visibility != 'private' and visibility != prev_visibility:
2792 s.error("Conflicting visibility options '%s' and '%s'"
2793 % (prev_visibility, visibility), fatal=False)
2794 s.next()
2795 return visibility
2797 def p_c_modifiers(s):
2798 if s.sy == 'IDENT' and s.systring in ('inline',):
2799 modifier = s.systring
2800 s.next()
2801 return [modifier] + p_c_modifiers(s)
2802 return []
2804 def p_c_func_or_var_declaration(s, pos, ctx):
2805 cmethod_flag = ctx.level in ('c_class', 'c_class_pxd')
2806 modifiers = p_c_modifiers(s)
2807 base_type = p_c_base_type(s, nonempty = 1, templates = ctx.templates)
2808 declarator = p_c_declarator(s, ctx, cmethod_flag = cmethod_flag,
2809 assignable = 1, nonempty = 1)
2810 declarator.overridable = ctx.overridable
2811 if s.sy == 'IDENT' and s.systring == 'const' and ctx.level == 'cpp_class':
2812 s.next()
2813 is_const_method = 1
2814 else:
2815 is_const_method = 0
2816 if s.sy == ':':
2817 if ctx.level not in ('module', 'c_class', 'module_pxd', 'c_class_pxd', 'cpp_class') and not ctx.templates:
2818 s.error("C function definition not allowed here")
2819 doc, suite = p_suite_with_docstring(s, Ctx(level='function'))
2820 result = Nodes.CFuncDefNode(pos,
2821 visibility = ctx.visibility,
2822 base_type = base_type,
2823 declarator = declarator,
2824 body = suite,
2825 doc = doc,
2826 modifiers = modifiers,
2827 api = ctx.api,
2828 overridable = ctx.overridable,
2829 is_const_method = is_const_method)
2830 else:
2831 #if api:
2832 # s.error("'api' not allowed with variable declaration")
2833 if is_const_method:
2834 declarator.is_const_method = is_const_method
2835 declarators = [declarator]
2836 while s.sy == ',':
2837 s.next()
2838 if s.sy == 'NEWLINE':
2839 break
2840 declarator = p_c_declarator(s, ctx, cmethod_flag = cmethod_flag,
2841 assignable = 1, nonempty = 1)
2842 declarators.append(declarator)
2843 doc_line = s.start_line + 1
2844 s.expect_newline("Syntax error in C variable declaration")
2845 if ctx.level in ('c_class', 'c_class_pxd') and s.start_line == doc_line:
2846 doc = p_doc_string(s)
2847 else:
2848 doc = None
2849 result = Nodes.CVarDefNode(pos,
2850 visibility = ctx.visibility,
2851 base_type = base_type,
2852 declarators = declarators,
2853 in_pxd = ctx.level in ('module_pxd', 'c_class_pxd'),
2854 doc = doc,
2855 api = ctx.api,
2856 modifiers = modifiers,
2857 overridable = ctx.overridable)
2858 return result
2860 def p_ctypedef_statement(s, ctx):
2861 # s.sy == 'ctypedef'
2862 pos = s.position()
2863 s.next()
2864 visibility = p_visibility(s, ctx.visibility)
2865 api = p_api(s)
2866 ctx = ctx(typedef_flag = 1, visibility = visibility)
2867 if api:
2868 ctx.api = 1
2869 if s.sy == 'class':
2870 return p_c_class_definition(s, pos, ctx)
2871 elif s.sy == 'IDENT' and s.systring in struct_enum_union:
2872 return p_struct_enum(s, pos, ctx)
2873 elif s.sy == 'IDENT' and s.systring == 'fused':
2874 return p_fused_definition(s, pos, ctx)
2875 else:
2876 base_type = p_c_base_type(s, nonempty = 1)
2877 declarator = p_c_declarator(s, ctx, is_type = 1, nonempty = 1)
2878 s.expect_newline("Syntax error in ctypedef statement")
2879 return Nodes.CTypeDefNode(
2880 pos, base_type = base_type,
2881 declarator = declarator,
2882 visibility = visibility, api = api,
2883 in_pxd = ctx.level == 'module_pxd')
2885 def p_decorators(s):
2886 decorators = []
2887 while s.sy == 'DECORATOR':
2888 pos = s.position()
2889 s.next()
2890 decstring = p_dotted_name(s, as_allowed=0)[2]
2891 names = decstring.split('.')
2892 decorator = ExprNodes.NameNode(pos, name=EncodedString(names[0]))
2893 for name in names[1:]:
2894 decorator = ExprNodes.AttributeNode(pos,
2895 attribute=EncodedString(name),
2896 obj=decorator)
2897 if s.sy == '(':
2898 decorator = p_call(s, decorator)
2899 decorators.append(Nodes.DecoratorNode(pos, decorator=decorator))
2900 s.expect_newline("Expected a newline after decorator")
2901 return decorators
2903 def p_def_statement(s, decorators=None):
2904 # s.sy == 'def'
2905 pos = s.position()
2906 s.next()
2907 name = EncodedString( p_ident(s) )
2908 s.expect('(')
2909 args, star_arg, starstar_arg = p_varargslist(s, terminator=')')
2910 s.expect(')')
2911 if p_nogil(s):
2912 error(pos, "Python function cannot be declared nogil")
2913 return_type_annotation = None
2914 if s.sy == '->':
2915 s.next()
2916 return_type_annotation = p_test(s)
2917 doc, body = p_suite_with_docstring(s, Ctx(level='function'))
2918 return Nodes.DefNode(pos, name = name, args = args,
2919 star_arg = star_arg, starstar_arg = starstar_arg,
2920 doc = doc, body = body, decorators = decorators,
2921 return_type_annotation = return_type_annotation)
2923 def p_varargslist(s, terminator=')', annotated=1):
2924 args = p_c_arg_list(s, in_pyfunc = 1, nonempty_declarators = 1,
2925 annotated = annotated)
2926 star_arg = None
2927 starstar_arg = None
2928 if s.sy == '*':
2929 s.next()
2930 if s.sy == 'IDENT':
2931 star_arg = p_py_arg_decl(s, annotated=annotated)
2932 if s.sy == ',':
2933 s.next()
2934 args.extend(p_c_arg_list(s, in_pyfunc = 1,
2935 nonempty_declarators = 1, kw_only = 1, annotated = annotated))
2936 elif s.sy != terminator:
2937 s.error("Syntax error in Python function argument list")
2938 if s.sy == '**':
2939 s.next()
2940 starstar_arg = p_py_arg_decl(s, annotated=annotated)
2941 return (args, star_arg, starstar_arg)
2943 def p_py_arg_decl(s, annotated = 1):
2944 pos = s.position()
2945 name = p_ident(s)
2946 annotation = None
2947 if annotated and s.sy == ':':
2948 s.next()
2949 annotation = p_test(s)
2950 return Nodes.PyArgDeclNode(pos, name = name, annotation = annotation)
2952 def p_class_statement(s, decorators):
2953 # s.sy == 'class'
2954 pos = s.position()
2955 s.next()
2956 class_name = EncodedString( p_ident(s) )
2957 class_name.encoding = s.source_encoding
2958 arg_tuple = None
2959 keyword_dict = None
2960 starstar_arg = None
2961 if s.sy == '(':
2962 positional_args, keyword_args, star_arg, starstar_arg = \
2963 p_call_parse_args(s, allow_genexp = False)
2964 arg_tuple, keyword_dict = p_call_build_packed_args(
2965 pos, positional_args, keyword_args, star_arg, None)
2966 if arg_tuple is None:
2967 # XXX: empty arg_tuple
2968 arg_tuple = ExprNodes.TupleNode(pos, args=[])
2969 doc, body = p_suite_with_docstring(s, Ctx(level='class'))
2970 return Nodes.PyClassDefNode(
2971 pos, name=class_name,
2972 bases=arg_tuple,
2973 keyword_args=keyword_dict,
2974 starstar_arg=starstar_arg,
2975 doc=doc, body=body, decorators=decorators,
2976 force_py3_semantics=s.context.language_level >= 3)
2978 def p_c_class_definition(s, pos, ctx):
2979 # s.sy == 'class'
2980 s.next()
2981 module_path = []
2982 class_name = p_ident(s)
2983 while s.sy == '.':
2984 s.next()
2985 module_path.append(class_name)
2986 class_name = p_ident(s)
2987 if module_path and ctx.visibility != 'extern':
2988 error(pos, "Qualified class name only allowed for 'extern' C class")
2989 if module_path and s.sy == 'IDENT' and s.systring == 'as':
2990 s.next()
2991 as_name = p_ident(s)
2992 else:
2993 as_name = class_name
2994 objstruct_name = None
2995 typeobj_name = None
2996 base_class_module = None
2997 base_class_name = None
2998 if s.sy == '(':
2999 s.next()
3000 base_class_path = [p_ident(s)]
3001 while s.sy == '.':
3002 s.next()
3003 base_class_path.append(p_ident(s))
3004 if s.sy == ',':
3005 s.error("C class may only have one base class", fatal=False)
3006 s.expect(')')
3007 base_class_module = ".".join(base_class_path[:-1])
3008 base_class_name = base_class_path[-1]
3009 if s.sy == '[':
3010 if ctx.visibility not in ('public', 'extern') and not ctx.api:
3011 error(s.position(), "Name options only allowed for 'public', 'api', or 'extern' C class")
3012 objstruct_name, typeobj_name = p_c_class_options(s)
3013 if s.sy == ':':
3014 if ctx.level == 'module_pxd':
3015 body_level = 'c_class_pxd'
3016 else:
3017 body_level = 'c_class'
3018 doc, body = p_suite_with_docstring(s, Ctx(level=body_level))
3019 else:
3020 s.expect_newline("Syntax error in C class definition")
3021 doc = None
3022 body = None
3023 if ctx.visibility == 'extern':
3024 if not module_path:
3025 error(pos, "Module name required for 'extern' C class")
3026 if typeobj_name:
3027 error(pos, "Type object name specification not allowed for 'extern' C class")
3028 elif ctx.visibility == 'public':
3029 if not objstruct_name:
3030 error(pos, "Object struct name specification required for 'public' C class")
3031 if not typeobj_name:
3032 error(pos, "Type object name specification required for 'public' C class")
3033 elif ctx.visibility == 'private':
3034 if ctx.api:
3035 if not objstruct_name:
3036 error(pos, "Object struct name specification required for 'api' C class")
3037 if not typeobj_name:
3038 error(pos, "Type object name specification required for 'api' C class")
3039 else:
3040 error(pos, "Invalid class visibility '%s'" % ctx.visibility)
3041 return Nodes.CClassDefNode(pos,
3042 visibility = ctx.visibility,
3043 typedef_flag = ctx.typedef_flag,
3044 api = ctx.api,
3045 module_name = ".".join(module_path),
3046 class_name = class_name,
3047 as_name = as_name,
3048 base_class_module = base_class_module,
3049 base_class_name = base_class_name,
3050 objstruct_name = objstruct_name,
3051 typeobj_name = typeobj_name,
3052 in_pxd = ctx.level == 'module_pxd',
3053 doc = doc,
3054 body = body)
3056 def p_c_class_options(s):
3057 objstruct_name = None
3058 typeobj_name = None
3059 s.expect('[')
3060 while 1:
3061 if s.sy != 'IDENT':
3062 break
3063 if s.systring == 'object':
3064 s.next()
3065 objstruct_name = p_ident(s)
3066 elif s.systring == 'type':
3067 s.next()
3068 typeobj_name = p_ident(s)
3069 if s.sy != ',':
3070 break
3071 s.next()
3072 s.expect(']', "Expected 'object' or 'type'")
3073 return objstruct_name, typeobj_name
3076 def p_property_decl(s):
3077 pos = s.position()
3078 s.next() # 'property'
3079 name = p_ident(s)
3080 doc, body = p_suite_with_docstring(
3081 s, Ctx(level='property'), with_doc_only=True)
3082 return Nodes.PropertyNode(pos, name=name, doc=doc, body=body)
3085 def p_ignorable_statement(s):
3087 Parses any kind of ignorable statement that is allowed in .pxd files.
3089 if s.sy == 'BEGIN_STRING':
3090 pos = s.position()
3091 string_node = p_atom(s)
3092 if s.sy != 'EOF':
3093 s.expect_newline("Syntax error in string")
3094 return Nodes.ExprStatNode(pos, expr=string_node)
3095 return None
3098 def p_doc_string(s):
3099 if s.sy == 'BEGIN_STRING':
3100 pos = s.position()
3101 kind, bytes_result, unicode_result = p_cat_string_literal(s)
3102 if s.sy != 'EOF':
3103 s.expect_newline("Syntax error in doc string")
3104 if kind in ('u', ''):
3105 return unicode_result
3106 warning(pos, "Python 3 requires docstrings to be unicode strings")
3107 return bytes_result
3108 else:
3109 return None
3112 def _extract_docstring(node):
3114 Extract a docstring from a statement or from the first statement
3115 in a list. Remove the statement if found. Return a tuple
3116 (plain-docstring or None, node).
3118 doc_node = None
3119 if node is None:
3120 pass
3121 elif isinstance(node, Nodes.ExprStatNode):
3122 if node.expr.is_string_literal:
3123 doc_node = node.expr
3124 node = Nodes.StatListNode(node.pos, stats=[])
3125 elif isinstance(node, Nodes.StatListNode) and node.stats:
3126 stats = node.stats
3127 if isinstance(stats[0], Nodes.ExprStatNode):
3128 if stats[0].expr.is_string_literal:
3129 doc_node = stats[0].expr
3130 del stats[0]
3132 if doc_node is None:
3133 doc = None
3134 elif isinstance(doc_node, ExprNodes.BytesNode):
3135 warning(node.pos,
3136 "Python 3 requires docstrings to be unicode strings")
3137 doc = doc_node.value
3138 elif isinstance(doc_node, ExprNodes.StringNode):
3139 doc = doc_node.unicode_value
3140 if doc is None:
3141 doc = doc_node.value
3142 else:
3143 doc = doc_node.value
3144 return doc, node
3147 def p_code(s, level=None, ctx=Ctx):
3148 body = p_statement_list(s, ctx(level = level), first_statement = 1)
3149 if s.sy != 'EOF':
3150 s.error("Syntax error in statement [%s,%s]" % (
3151 repr(s.sy), repr(s.systring)))
3152 return body
3154 _match_compiler_directive_comment = cython.declare(object, re.compile(
3155 r"^#\s*cython\s*:\s*((\w|[.])+\s*=.*)$").match)
3157 def p_compiler_directive_comments(s):
3158 result = {}
3159 while s.sy == 'commentline':
3160 m = _match_compiler_directive_comment(s.systring)
3161 if m:
3162 directives = m.group(1).strip()
3163 try:
3164 result.update(Options.parse_directive_list(
3165 directives, ignore_unknown=True))
3166 except ValueError, e:
3167 s.error(e.args[0], fatal=False)
3168 s.next()
3169 return result
3171 def p_module(s, pxd, full_module_name, ctx=Ctx):
3172 pos = s.position()
3174 directive_comments = p_compiler_directive_comments(s)
3175 s.parse_comments = False
3177 if 'language_level' in directive_comments:
3178 s.context.set_language_level(directive_comments['language_level'])
3180 doc = p_doc_string(s)
3181 if pxd:
3182 level = 'module_pxd'
3183 else:
3184 level = 'module'
3186 body = p_statement_list(s, ctx(level=level), first_statement = 1)
3187 if s.sy != 'EOF':
3188 s.error("Syntax error in statement [%s,%s]" % (
3189 repr(s.sy), repr(s.systring)))
3190 return ModuleNode(pos, doc = doc, body = body,
3191 full_module_name = full_module_name,
3192 directive_comments = directive_comments)
3194 def p_cpp_class_definition(s, pos, ctx):
3195 # s.sy == 'cppclass'
3196 s.next()
3197 module_path = []
3198 class_name = p_ident(s)
3199 cname = p_opt_cname(s)
3200 if cname is None and ctx.namespace is not None:
3201 cname = ctx.namespace + "::" + class_name
3202 if s.sy == '.':
3203 error(pos, "Qualified class name not allowed C++ class")
3204 if s.sy == '[':
3205 s.next()
3206 templates = [p_ident(s)]
3207 while s.sy == ',':
3208 s.next()
3209 templates.append(p_ident(s))
3210 s.expect(']')
3211 else:
3212 templates = None
3213 if s.sy == '(':
3214 s.next()
3215 base_classes = [p_c_base_type(s, templates = templates)]
3216 while s.sy == ',':
3217 s.next()
3218 base_classes.append(p_c_base_type(s, templates = templates))
3219 s.expect(')')
3220 else:
3221 base_classes = []
3222 if s.sy == '[':
3223 error(s.position(), "Name options not allowed for C++ class")
3224 nogil = p_nogil(s)
3225 if s.sy == ':':
3226 s.next()
3227 s.expect('NEWLINE')
3228 s.expect_indent()
3229 attributes = []
3230 body_ctx = Ctx(visibility = ctx.visibility, level='cpp_class', nogil=nogil or ctx.nogil)
3231 body_ctx.templates = templates
3232 while s.sy != 'DEDENT':
3233 if s.systring == 'cppclass':
3234 attributes.append(
3235 p_cpp_class_definition(s, s.position(), body_ctx))
3236 elif s.sy != 'pass':
3237 attributes.append(
3238 p_c_func_or_var_declaration(s, s.position(), body_ctx))
3239 else:
3240 s.next()
3241 s.expect_newline("Expected a newline")
3242 s.expect_dedent()
3243 else:
3244 attributes = None
3245 s.expect_newline("Syntax error in C++ class definition")
3246 return Nodes.CppClassNode(pos,
3247 name = class_name,
3248 cname = cname,
3249 base_classes = base_classes,
3250 visibility = ctx.visibility,
3251 in_pxd = ctx.level == 'module_pxd',
3252 attributes = attributes,
3253 templates = templates)
3257 #----------------------------------------------
3259 # Debugging
3261 #----------------------------------------------
3263 def print_parse_tree(f, node, level, key = None):
3264 from types import ListType, TupleType
3265 from Nodes import Node
3266 ind = " " * level
3267 if node:
3268 f.write(ind)
3269 if key:
3270 f.write("%s: " % key)
3271 t = type(node)
3272 if t is tuple:
3273 f.write("(%s @ %s\n" % (node[0], node[1]))
3274 for i in xrange(2, len(node)):
3275 print_parse_tree(f, node[i], level+1)
3276 f.write("%s)\n" % ind)
3277 return
3278 elif isinstance(node, Node):
3279 try:
3280 tag = node.tag
3281 except AttributeError:
3282 tag = node.__class__.__name__
3283 f.write("%s @ %s\n" % (tag, node.pos))
3284 for name, value in node.__dict__.items():
3285 if name != 'tag' and name != 'pos':
3286 print_parse_tree(f, value, level+1, name)
3287 return
3288 elif t is list:
3289 f.write("[\n")
3290 for i in xrange(len(node)):
3291 print_parse_tree(f, node[i], level+1)
3292 f.write("%s]\n" % ind)
3293 return
3294 f.write("%s%s\n" % (ind, node))