LEFT | RIGHT |
1 # cython: auto_cpdef=True, infer_types=True | 1 # cython: auto_cpdef=True, infer_types=True |
2 # | 2 # |
3 # Pyrex Parser | 3 # Pyrex Parser |
4 # | 4 # |
5 | 5 |
6 # This should be done automatically | 6 # This should be done automatically |
7 import cython | 7 import cython |
8 cython.declare(Nodes=object, ExprNodes=object, EncodedString=object) | 8 cython.declare(Nodes=object, ExprNodes=object, EncodedString=object) |
9 | 9 |
10 import os | 10 import os |
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
585 longness = longness) | 585 longness = longness) |
586 elif sy == 'FLOAT': | 586 elif sy == 'FLOAT': |
587 value = s.systring | 587 value = s.systring |
588 s.next() | 588 s.next() |
589 return ExprNodes.FloatNode(pos, value = value) | 589 return ExprNodes.FloatNode(pos, value = value) |
590 elif sy == 'IMAG': | 590 elif sy == 'IMAG': |
591 value = s.systring[:-1] | 591 value = s.systring[:-1] |
592 s.next() | 592 s.next() |
593 return ExprNodes.ImagNode(pos, value = value) | 593 return ExprNodes.ImagNode(pos, value = value) |
594 elif sy == 'BEGIN_STRING': | 594 elif sy == 'BEGIN_STRING': |
595 kind, value = p_cat_string_literal(s) | 595 kind, bytes_value, unicode_value = p_cat_string_literal(s) |
596 if kind == 'c': | 596 if kind == 'c': |
597 return ExprNodes.CharNode(pos, value = value) | 597 return ExprNodes.CharNode(pos, value = bytes_value) |
598 elif kind == 'u': | 598 elif kind == 'u': |
599 return ExprNodes.UnicodeNode(pos, value = value) | 599 return ExprNodes.UnicodeNode(pos, value = unicode_value, bytes_value
= bytes_value) |
600 elif kind == 'b': | 600 elif kind == 'b': |
601 return ExprNodes.BytesNode(pos, value = value) | 601 return ExprNodes.BytesNode(pos, value = bytes_value) |
602 else: | 602 else: |
603 return ExprNodes.StringNode(pos, value = value) | 603 return ExprNodes.StringNode(pos, value = bytes_value, unicode_value
= unicode_value) |
604 elif sy == 'IDENT': | 604 elif sy == 'IDENT': |
605 name = EncodedString( s.systring ) | 605 name = EncodedString( s.systring ) |
606 s.next() | 606 s.next() |
607 if name == "None": | 607 if name == "None": |
608 return ExprNodes.NoneNode(pos) | 608 return ExprNodes.NoneNode(pos) |
609 elif name == "True": | 609 elif name == "True": |
610 return ExprNodes.BoolNode(pos, value=True) | 610 return ExprNodes.BoolNode(pos, value=True) |
611 elif name == "False": | 611 elif name == "False": |
612 return ExprNodes.BoolNode(pos, value=False) | 612 return ExprNodes.BoolNode(pos, value=False) |
613 elif name == "NULL": | 613 elif name == "NULL": |
(...skipping 20 matching lines...) Expand all Loading... |
634 return ExprNodes.UnicodeNode(pos, value = value) | 634 return ExprNodes.UnicodeNode(pos, value = value) |
635 elif isinstance(value, _bytes): | 635 elif isinstance(value, _bytes): |
636 return ExprNodes.BytesNode(pos, value = value) | 636 return ExprNodes.BytesNode(pos, value = value) |
637 else: | 637 else: |
638 error(pos, "Invalid type for compile-time constant: %s" | 638 error(pos, "Invalid type for compile-time constant: %s" |
639 % value.__class__.__name__) | 639 % value.__class__.__name__) |
640 return ExprNodes.NameNode(pos, name = name) | 640 return ExprNodes.NameNode(pos, name = name) |
641 | 641 |
642 def p_cat_string_literal(s): | 642 def p_cat_string_literal(s): |
643 # A sequence of one or more adjacent string literals. | 643 # A sequence of one or more adjacent string literals. |
644 # Returns (kind, value) where kind in ('b', 'c', 'u', '') | 644 # Returns (kind, bytes_value, unicode_value) |
645 kind, value = p_string_literal(s) | 645 # where kind in ('b', 'c', 'u', '') |
646 if s.sy != 'BEGIN_STRING': | 646 kind, bytes_value, unicode_value = p_string_literal(s) |
647 return kind, value | 647 if kind == 'c' or s.sy != 'BEGIN_STRING': |
648 if kind != 'c': | 648 return kind, bytes_value, unicode_value |
649 strings = [value] | 649 bstrings, ustrings = [bytes_value], [unicode_value] |
650 while s.sy == 'BEGIN_STRING': | 650 bytes_value = unicode_value = None |
651 pos = s.position() | 651 while s.sy == 'BEGIN_STRING': |
652 next_kind, next_value = p_string_literal(s) | 652 pos = s.position() |
653 if next_kind == 'c': | 653 next_kind, next_bytes_value, next_unicode_value = p_string_literal(s) |
654 error(pos, "Cannot concatenate char literal with another string
or char literal") | 654 if next_kind == 'c': |
655 elif next_kind != kind: | 655 error(pos, "Cannot concatenate char literal with another string or c
har literal") |
656 error(pos, "Cannot mix string literals of different types, expec
ted %s'', got %s''" % | 656 elif next_kind != kind: |
657 (kind, next_kind)) | 657 error(pos, "Cannot mix string literals of different types, expected
%s'', got %s''" % |
658 else: | 658 (kind, next_kind)) |
659 strings.append(next_value) | 659 else: |
660 if kind == 'u': | 660 bstrings.append(next_bytes_value) |
661 value = EncodedString( u''.join(strings) ) | 661 ustrings.append(next_unicode_value) |
662 else: | 662 # join and rewrap the partial literals |
663 value = BytesLiteral( StringEncoding.join_bytes(strings) ) | 663 if kind in ('b', 'c', '') or kind == 'u' and None not in bstrings: |
664 value.encoding = s.source_encoding | 664 # Py3 enforced unicode literals are parsed as bytes/unicode combination |
665 return kind, value | 665 bytes_value = BytesLiteral( StringEncoding.join_bytes(bstrings) ) |
666 | 666 bytes_value.encoding = s.source_encoding |
667 def p_opt_string_literal(s): | 667 if kind in ('u', ''): |
| 668 unicode_value = EncodedString( u''.join([ u for u in ustrings if u is no
t None ]) ) |
| 669 return kind, bytes_value, unicode_value |
| 670 |
| 671 def p_opt_string_literal(s, required_type='u'): |
668 if s.sy == 'BEGIN_STRING': | 672 if s.sy == 'BEGIN_STRING': |
669 return p_string_literal(s) | 673 kind, bytes_value, unicode_value = p_string_literal(s, required_type) |
| 674 if required_type == 'u': |
| 675 return unicode_value |
| 676 elif required_type == 'b': |
| 677 return bytes_value |
| 678 else: |
| 679 s.error("internal parser configuration error") |
670 else: | 680 else: |
671 return None | 681 return None |
672 | 682 |
| 683 def check_for_non_ascii_characters(string): |
| 684 for c in string: |
| 685 if c >= u'\x80': |
| 686 return True |
| 687 return False |
| 688 |
673 def p_string_literal(s, kind_override=None): | 689 def p_string_literal(s, kind_override=None): |
674 # A single string or char literal. | 690 # A single string or char literal. Returns (kind, bvalue, uvalue) |
675 # Returns (kind, value) where kind in ('b', 'c', 'u', '') | 691 # where kind in ('b', 'c', 'u', ''). The 'bvalue' is the source |
| 692 # code byte sequence of the string literal, 'uvalue' is the |
| 693 # decoded Unicode string. Either of the two may be None depending |
| 694 # on the 'kind' of string, only unprefixed strings have both |
| 695 # representations. |
| 696 |
676 # s.sy == 'BEGIN_STRING' | 697 # s.sy == 'BEGIN_STRING' |
677 pos = s.position() | 698 pos = s.position() |
678 is_raw = 0 | 699 is_raw = 0 |
| 700 is_python3_source = s.context.language_level >= 3 |
| 701 has_non_ASCII_literal_characters = False |
679 kind = s.systring[:1].lower() | 702 kind = s.systring[:1].lower() |
680 if kind == 'r': | 703 if kind == 'r': |
681 kind = '' | 704 kind = '' |
682 is_raw = 1 | 705 is_raw = 1 |
683 elif kind in 'ub': | 706 elif kind in 'ub': |
684 is_raw = s.systring[1:2].lower() == 'r' | 707 is_raw = s.systring[1:2].lower() == 'r' |
685 elif kind != 'c': | 708 elif kind != 'c': |
686 kind = '' | 709 kind = '' |
687 if Future.unicode_literals in s.context.future_directives: | 710 if kind == '' and kind_override is None and Future.unicode_literals in s.con
text.future_directives: |
688 if kind == '': | 711 chars = StringEncoding.StrLiteralBuilder(s.source_encoding) |
689 kind = 'u' | 712 kind = 'u' |
690 if kind_override is not None and kind_override in 'ub': | 713 else: |
691 kind = kind_override | 714 if kind_override is not None and kind_override in 'ub': |
692 if kind == 'u': | 715 kind = kind_override |
693 chars = StringEncoding.UnicodeLiteralBuilder() | 716 if kind == 'u': |
694 else: | 717 chars = StringEncoding.UnicodeLiteralBuilder() |
695 chars = StringEncoding.BytesLiteralBuilder(s.source_encoding) | 718 elif kind == '': |
| 719 chars = StringEncoding.StrLiteralBuilder(s.source_encoding) |
| 720 else: |
| 721 chars = StringEncoding.BytesLiteralBuilder(s.source_encoding) |
696 while 1: | 722 while 1: |
697 s.next() | 723 s.next() |
698 sy = s.sy | 724 sy = s.sy |
| 725 systr = s.systring |
699 #print "p_string_literal: sy =", sy, repr(s.systring) ### | 726 #print "p_string_literal: sy =", sy, repr(s.systring) ### |
700 if sy == 'CHARS': | 727 if sy == 'CHARS': |
701 chars.append(s.systring) | 728 chars.append(systr) |
| 729 if is_python3_source and not has_non_ASCII_literal_characters and ch
eck_for_non_ascii_characters(systr): |
| 730 has_non_ASCII_literal_characters = True |
702 elif sy == 'ESCAPE': | 731 elif sy == 'ESCAPE': |
703 has_escape = True | |
704 systr = s.systring | |
705 if is_raw: | 732 if is_raw: |
706 if systr == u'\\\n': | 733 if systr == u'\\\n': |
707 chars.append(u'\\\n') | 734 chars.append(u'\\\n') |
708 elif systr == u'\\\"': | 735 elif systr == u'\\\"': |
709 chars.append(u'"') | 736 chars.append(u'"') |
710 elif systr == u'\\\'': | 737 elif systr == u'\\\'': |
711 chars.append(u"'") | 738 chars.append(u"'") |
712 else: | 739 else: |
713 chars.append(systr) | 740 chars.append(systr) |
| 741 if is_python3_source and not has_non_ASCII_literal_character
s \ |
| 742 and check_for_non_ascii_characters(systr): |
| 743 has_non_ASCII_literal_characters = True |
714 else: | 744 else: |
715 c = systr[1] | 745 c = systr[1] |
716 if c in u"01234567": | 746 if c in u"01234567": |
717 chars.append_charval( int(systr[1:], 8) ) | 747 chars.append_charval( int(systr[1:], 8) ) |
718 elif c in u"'\"\\": | 748 elif c in u"'\"\\": |
719 chars.append(c) | 749 chars.append(c) |
720 elif c in u"abfnrtv": | 750 elif c in u"abfnrtv": |
721 chars.append( | 751 chars.append( |
722 StringEncoding.char_from_escape_sequence(systr)) | 752 StringEncoding.char_from_escape_sequence(systr)) |
723 elif c == u'\n': | 753 elif c == u'\n': |
724 pass | 754 pass |
725 elif c in u'Uux': | 755 elif c == u'x': |
726 if kind == 'u' or c == 'x': | 756 chars.append_charval( int(systr[2:], 16) ) |
| 757 elif c in u'Uu': |
| 758 if kind in ('u', ''): |
727 chrval = int(systr[2:], 16) | 759 chrval = int(systr[2:], 16) |
728 if chrval > 1114111: # sys.maxunicode: | 760 if chrval > 1114111: # sys.maxunicode: |
729 s.error("Invalid unicode escape '%s'" % systr, | 761 s.error("Invalid unicode escape '%s'" % systr, |
730 pos = pos) | 762 pos = pos) |
731 elif chrval > 65535: | |
732 warning(s.position(), | |
733 "Unicode characters above 65535 are not " | |
734 "necessarily portable across Python installa
tions", 1) | |
735 chars.append_charval(chrval) | |
736 else: | 763 else: |
737 # unicode escapes in plain byte strings are not unescape
d | 764 # unicode escapes in plain byte strings are not unescape
d |
738 chars.append(systr) | 765 chrval = None |
| 766 chars.append_uescape(chrval, systr) |
739 else: | 767 else: |
740 chars.append(u'\\' + systr[1:]) | 768 chars.append(u'\\' + systr[1:]) |
| 769 if is_python3_source and not has_non_ASCII_literal_character
s \ |
| 770 and check_for_non_ascii_characters(systr): |
| 771 has_non_ASCII_literal_characters = True |
741 elif sy == 'NEWLINE': | 772 elif sy == 'NEWLINE': |
742 chars.append(u'\n') | 773 chars.append(u'\n') |
743 elif sy == 'END_STRING': | 774 elif sy == 'END_STRING': |
744 break | 775 break |
745 elif sy == 'EOF': | 776 elif sy == 'EOF': |
746 s.error("Unclosed string literal", pos = pos) | 777 s.error("Unclosed string literal", pos = pos) |
747 else: | 778 else: |
748 s.error( | 779 s.error( |
749 "Unexpected token %r:%r in string literal" % | 780 "Unexpected token %r:%r in string literal" % |
750 (sy, s.systring)) | 781 (sy, s.systring)) |
751 if kind == 'c': | 782 if kind == 'c': |
752 value = chars.getchar() | 783 unicode_value = None |
753 if len(value) != 1: | 784 bytes_value = chars.getchar() |
754 error(pos, u"invalid character literal: %r" % value) | 785 if len(bytes_value) != 1: |
755 else: | 786 error(pos, u"invalid character literal: %r" % bytes_value) |
756 value = chars.getstring() | 787 else: |
757 s.next() | 788 bytes_value, unicode_value = chars.getstrings() |
758 #print "p_string_literal: value =", repr(value) ### | 789 if is_python3_source and has_non_ASCII_literal_characters: |
759 return kind, value | 790 # Python 3 forbids literal non-ASCII characters in byte strings |
| 791 if kind != 'u': |
| 792 s.error("bytes can only contain ASCII literal characters.", pos
= pos) |
| 793 bytes_value = None |
| 794 s.next() |
| 795 return (kind, bytes_value, unicode_value) |
760 | 796 |
761 # list_display ::= "[" [listmaker] "]" | 797 # list_display ::= "[" [listmaker] "]" |
762 # listmaker ::= expression ( comp_for | ( "," expression )* [","] ) | 798 # listmaker ::= expression ( comp_for | ( "," expression )* [","] ) |
763 # comp_iter ::= comp_for | comp_if | 799 # comp_iter ::= comp_for | comp_if |
764 # comp_for ::= "for" expression_list "in" testlist [comp_iter] | 800 # comp_for ::= "for" expression_list "in" testlist [comp_iter] |
765 # comp_if ::= "if" test [comp_iter] | 801 # comp_if ::= "if" test [comp_iter] |
766 ········ | 802 ········ |
767 def p_list_maker(s): | 803 def p_list_maker(s): |
768 # s.sy == '[' | 804 # s.sy == '[' |
769 pos = s.position() | 805 pos = s.position() |
770 s.next() | 806 s.next() |
771 if s.sy == ']': | 807 if s.sy == ']': |
772 s.expect(']') | 808 s.expect(']') |
773 return ExprNodes.ListNode(pos, args = []) | 809 return ExprNodes.ListNode(pos, args = []) |
774 expr = p_test(s) | 810 expr = p_test(s) |
775 if s.sy == 'for': | 811 if s.sy == 'for': |
776 target = ExprNodes.ListNode(pos, args = []) | 812 target = ExprNodes.ListNode(pos, args = []) |
777 append = ExprNodes.ComprehensionAppendNode( | 813 append = ExprNodes.ComprehensionAppendNode( |
778 pos, expr=expr, target=ExprNodes.CloneNode(target)) | 814 pos, expr=expr, target=ExprNodes.CloneNode(target)) |
779 loop = p_comp_for(s, append) | 815 loop = p_comp_for(s, append) |
780 s.expect(']') | 816 s.expect(']') |
781 return ExprNodes.ComprehensionNode( | 817 return ExprNodes.ComprehensionNode( |
782 pos, loop=loop, append=append, target=target) | 818 pos, loop=loop, append=append, target=target, |
| 819 # list comprehensions leak their loop variable in Py2 |
| 820 has_local_scope = s.context.language_level >= 3) |
783 else: | 821 else: |
784 if s.sy == ',': | 822 if s.sy == ',': |
785 s.next() | 823 s.next() |
786 exprs = p_simple_expr_list(s, expr) | 824 exprs = p_simple_expr_list(s, expr) |
787 else: | 825 else: |
788 exprs = [expr] | 826 exprs = [expr] |
789 s.expect(']') | 827 s.expect(']') |
790 return ExprNodes.ListNode(pos, args = exprs) | 828 return ExprNodes.ListNode(pos, args = exprs) |
791 ········ | 829 ········ |
792 def p_comp_iter(s, body): | 830 def p_comp_iter(s, body): |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
948 s.next() | 986 s.next() |
949 exprs = p_test_or_starred_expr_list(s, expr) | 987 exprs = p_test_or_starred_expr_list(s, expr) |
950 return ExprNodes.TupleNode(pos, args = exprs) | 988 return ExprNodes.TupleNode(pos, args = exprs) |
951 elif s.sy == 'for': | 989 elif s.sy == 'for': |
952 return p_genexp(s, expr) | 990 return p_genexp(s, expr) |
953 else: | 991 else: |
954 return expr | 992 return expr |
955 | 993 |
956 def p_genexp(s, expr): | 994 def p_genexp(s, expr): |
957 # s.sy == 'for' | 995 # s.sy == 'for' |
958 loop = p_comp_for(s, ExprNodes.YieldExprNode(expr.pos, arg=expr)) | 996 loop = p_comp_for(s, Nodes.ExprStatNode( |
| 997 expr.pos, expr = ExprNodes.YieldExprNode(expr.pos, arg=expr))) |
959 return ExprNodes.GeneratorExpressionNode(expr.pos, loop=loop) | 998 return ExprNodes.GeneratorExpressionNode(expr.pos, loop=loop) |
960 | 999 |
961 expr_terminators = (')', ']', '}', ':', '=', 'NEWLINE') | 1000 expr_terminators = (')', ']', '}', ':', '=', 'NEWLINE') |
962 | 1001 |
963 #------------------------------------------------------- | 1002 #------------------------------------------------------- |
964 # | 1003 # |
965 # Statements | 1004 # Statements |
966 # | 1005 # |
967 #------------------------------------------------------- | 1006 #------------------------------------------------------- |
968 | 1007 |
969 def p_global_statement(s): | 1008 def p_global_statement(s): |
970 # assume s.sy == 'global' | 1009 # assume s.sy == 'global' |
971 pos = s.position() | 1010 pos = s.position() |
972 s.next() | 1011 s.next() |
973 names = p_ident_list(s) | 1012 names = p_ident_list(s) |
974 return Nodes.GlobalNode(pos, names = names) | 1013 return Nodes.GlobalNode(pos, names = names) |
975 | |
976 def p_nonlocal_statement(s): | |
977 pos = s.position() | |
978 s.next() | |
979 names = p_ident_list(s) | |
980 #TODO(bhy) | |
981 return Nodes.NonlocalNode(pos, names = names) | |
982 | 1014 |
983 def p_expression_or_assignment(s): | 1015 def p_expression_or_assignment(s): |
984 expr_list = [p_testlist_star_expr(s)] | 1016 expr_list = [p_testlist_star_expr(s)] |
985 while s.sy == '=': | 1017 while s.sy == '=': |
986 s.next() | 1018 s.next() |
987 if s.sy == 'yield': | 1019 if s.sy == 'yield': |
988 expr = p_yield_expression(s) | 1020 expr = p_yield_expression(s) |
989 else: | 1021 else: |
990 expr = p_testlist_star_expr(s) | 1022 expr = p_testlist_star_expr(s) |
991 expr_list.append(expr) | 1023 expr_list.append(expr) |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1094 value = None | 1126 value = None |
1095 return Nodes.ReturnStatNode(pos, value = value) | 1127 return Nodes.ReturnStatNode(pos, value = value) |
1096 | 1128 |
1097 def p_raise_statement(s): | 1129 def p_raise_statement(s): |
1098 # s.sy == 'raise' | 1130 # s.sy == 'raise' |
1099 pos = s.position() | 1131 pos = s.position() |
1100 s.next() | 1132 s.next() |
1101 exc_type = None | 1133 exc_type = None |
1102 exc_value = None | 1134 exc_value = None |
1103 exc_tb = None | 1135 exc_tb = None |
1104 cause = None | |
1105 if s.sy not in statement_terminators: | 1136 if s.sy not in statement_terminators: |
1106 exc_type = p_test(s) | 1137 exc_type = p_test(s) |
1107 if s.sy == ',': | 1138 if s.sy == ',': |
1108 s.next() | 1139 s.next() |
1109 exc_value = p_test(s) | 1140 exc_value = p_test(s) |
1110 if s.sy == ',': | 1141 if s.sy == ',': |
1111 s.next() | 1142 s.next() |
1112 exc_tb = p_test(s) | 1143 exc_tb = p_test(s) |
1113 elif s.sy == 'from': | |
1114 s.next() | |
1115 cause = p_test(s) | |
1116 if exc_type or exc_value or exc_tb: | 1144 if exc_type or exc_value or exc_tb: |
1117 return Nodes.RaiseStatNode(pos,· | 1145 return Nodes.RaiseStatNode(pos,· |
1118 exc_type = exc_type, | 1146 exc_type = exc_type, |
1119 exc_value = exc_value, | 1147 exc_value = exc_value, |
1120 exc_tb = exc_tb, | 1148 exc_tb = exc_tb) |
1121 cause = cause) | |
1122 else: | 1149 else: |
1123 return Nodes.ReraiseStatNode(pos) | 1150 return Nodes.ReraiseStatNode(pos) |
1124 | 1151 |
1125 def p_import_statement(s): | 1152 def p_import_statement(s): |
1126 # s.sy in ('import', 'cimport') | 1153 # s.sy in ('import', 'cimport') |
1127 pos = s.position() | 1154 pos = s.position() |
1128 kind = s.sy | 1155 kind = s.sy |
1129 s.next() | 1156 s.next() |
1130 items = [p_dotted_name(s, as_allowed = 1)] | 1157 items = [p_dotted_name(s, as_allowed = 1)] |
1131 while s.sy == ',': | 1158 while s.sy == ',': |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1427 s.error("Expected 'except' or 'finally'") | 1454 s.error("Expected 'except' or 'finally'") |
1428 | 1455 |
1429 def p_except_clause(s): | 1456 def p_except_clause(s): |
1430 # s.sy == 'except' | 1457 # s.sy == 'except' |
1431 pos = s.position() | 1458 pos = s.position() |
1432 s.next() | 1459 s.next() |
1433 exc_type = None | 1460 exc_type = None |
1434 exc_value = None | 1461 exc_value = None |
1435 if s.sy != ':': | 1462 if s.sy != ':': |
1436 exc_type = p_test(s) | 1463 exc_type = p_test(s) |
| 1464 # normalise into list of single exception tests |
| 1465 if isinstance(exc_type, ExprNodes.TupleNode): |
| 1466 exc_type = exc_type.args |
| 1467 else: |
| 1468 exc_type = [exc_type] |
1437 if s.sy == ',' or (s.sy == 'IDENT' and s.systring == 'as'): | 1469 if s.sy == ',' or (s.sy == 'IDENT' and s.systring == 'as'): |
1438 s.next() | 1470 s.next() |
1439 exc_value = p_test(s) | 1471 exc_value = p_test(s) |
1440 elif s.sy == 'IDENT' and s.systring == 'as': | 1472 elif s.sy == 'IDENT' and s.systring == 'as': |
1441 # Py3 syntax requires a name here | 1473 # Py3 syntax requires a name here |
1442 s.next() | 1474 s.next() |
1443 pos2 = s.position() | 1475 pos2 = s.position() |
1444 name = p_ident(s) | 1476 name = p_ident(s) |
1445 exc_value = ExprNodes.NameNode(pos2, name = name) | 1477 exc_value = ExprNodes.NameNode(pos2, name = name) |
1446 body = p_suite(s) | 1478 body = p_suite(s) |
1447 return Nodes.ExceptClauseNode(pos, | 1479 return Nodes.ExceptClauseNode(pos, |
1448 pattern = exc_type, target = exc_value, body = body) | 1480 pattern = exc_type, target = exc_value, body = body) |
1449 | 1481 |
1450 def p_include_statement(s, ctx): | 1482 def p_include_statement(s, ctx): |
1451 pos = s.position() | 1483 pos = s.position() |
1452 s.next() # 'include' | 1484 s.next() # 'include' |
1453 _, include_file_name = p_string_literal(s) | 1485 unicode_include_file_name = p_string_literal(s, 'u')[2] |
1454 s.expect_newline("Syntax error in include statement") | 1486 s.expect_newline("Syntax error in include statement") |
1455 if s.compile_time_eval: | 1487 if s.compile_time_eval: |
1456 include_file_name = include_file_name.decode(s.source_encoding) | 1488 include_file_name = unicode_include_file_name |
1457 include_file_path = s.context.find_include_file(include_file_name, pos) | 1489 include_file_path = s.context.find_include_file(include_file_name, pos) |
1458 if include_file_path: | 1490 if include_file_path: |
1459 s.included_files.append(include_file_name) | 1491 s.included_files.append(include_file_name) |
1460 f = Utils.open_source_file(include_file_path, mode="rU") | 1492 f = Utils.open_source_file(include_file_path, mode="rU") |
1461 source_desc = FileSourceDescriptor(include_file_path) | 1493 source_desc = FileSourceDescriptor(include_file_path) |
1462 s2 = PyrexScanner(f, source_desc, s, source_encoding=f.encoding, par
se_comments=s.parse_comments) | 1494 s2 = PyrexScanner(f, source_desc, s, source_encoding=f.encoding, par
se_comments=s.parse_comments) |
1463 try: | 1495 try: |
1464 tree = p_statement_list(s2, ctx) | 1496 tree = p_statement_list(s2, ctx) |
1465 finally: | 1497 finally: |
1466 f.close() | 1498 f.close() |
1467 return tree | 1499 return tree |
1468 else: | 1500 else: |
1469 return None | 1501 return None |
1470 else: | 1502 else: |
1471 return Nodes.PassStatNode(pos) | 1503 return Nodes.PassStatNode(pos) |
1472 | 1504 |
1473 def p_with_statement(s): | 1505 def p_with_statement(s): |
| 1506 pos = s.position() |
1474 s.next() # 'with' | 1507 s.next() # 'with' |
1475 if s.systring == 'template': | 1508 # if s.sy == 'IDENT' and s.systring in ('gil', 'nogil'): |
1476 node = p_with_template(s) | |
1477 else: | |
1478 node = p_with_items(s) | |
1479 return node | |
1480 | |
1481 def p_with_items(s): | |
1482 pos = s.position() | |
1483 if s.sy == 'IDENT' and s.systring == 'nogil': | 1509 if s.sy == 'IDENT' and s.systring == 'nogil': |
1484 state = s.systring | 1510 state = s.systring |
1485 s.next() | 1511 s.next() |
1486 if s.sy == ',': | 1512 body = p_suite(s) |
1487 s.next() | |
1488 body = p_with_items(s) | |
1489 else: | |
1490 body = p_suite(s) | |
1491 return Nodes.GILStatNode(pos, state = state, body = body) | 1513 return Nodes.GILStatNode(pos, state = state, body = body) |
| 1514 elif s.systring == 'template': |
| 1515 templates = [] |
| 1516 s.next() |
| 1517 s.expect('[') |
| 1518 #s.next() |
| 1519 templates.append(s.systring) |
| 1520 s.next() |
| 1521 while s.systring == ',': |
| 1522 s.next() |
| 1523 templates.append(s.systring) |
| 1524 s.next() |
| 1525 s.expect(']') |
| 1526 if s.sy == ':': |
| 1527 s.next() |
| 1528 s.expect_newline("Syntax error in template function declaration") |
| 1529 s.expect_indent() |
| 1530 body_ctx = Ctx() |
| 1531 body_ctx.templates = templates |
| 1532 func_or_var = p_c_func_or_var_declaration(s, pos, body_ctx) |
| 1533 s.expect_dedent() |
| 1534 return func_or_var |
| 1535 else: |
| 1536 error(pos, "Syntax error in template function declaration") |
1492 else: | 1537 else: |
1493 manager = p_test(s) | 1538 manager = p_test(s) |
1494 target = None | 1539 target = None |
1495 if s.sy == 'IDENT' and s.systring == 'as': | 1540 if s.sy == 'IDENT' and s.systring == 'as': |
1496 s.next() | 1541 s.next() |
1497 target = p_starred_expr(s) | 1542 allow_multi = (s.sy == '(') |
1498 if s.sy == ',': | 1543 target = p_target(s, ':') |
1499 s.next() | 1544 if not allow_multi and isinstance(target, ExprNodes.TupleNode): |
1500 body = p_with_items(s) | 1545 s.error("Multiple with statement target values not allowed witho
ut paranthesis") |
1501 else: | 1546 body = p_suite(s) |
1502 body = p_suite(s) | |
1503 return Nodes.WithStatNode(pos, manager = manager,· | 1547 return Nodes.WithStatNode(pos, manager = manager,· |
1504 target = target, body = body) | 1548 target = target, body = body) |
1505 | 1549 ···· |
1506 def p_with_template(s): | |
1507 pos = s.position() | |
1508 templates = [] | |
1509 s.next() | |
1510 s.expect('[') | |
1511 templates.append(s.systring) | |
1512 s.next() | |
1513 while s.systring == ',': | |
1514 s.next() | |
1515 templates.append(s.systring) | |
1516 s.next() | |
1517 s.expect(']') | |
1518 if s.sy == ':': | |
1519 s.next() | |
1520 s.expect_newline("Syntax error in template function declaration") | |
1521 s.expect_indent() | |
1522 body_ctx = Ctx() | |
1523 body_ctx.templates = templates | |
1524 func_or_var = p_c_func_or_var_declaration(s, pos, body_ctx) | |
1525 s.expect_dedent() | |
1526 return func_or_var | |
1527 else: | |
1528 error(pos, "Syntax error in template function declaration") | |
1529 | |
1530 def p_simple_statement(s, first_statement = 0): | 1550 def p_simple_statement(s, first_statement = 0): |
1531 #print "p_simple_statement:", s.sy, s.systring ### | 1551 #print "p_simple_statement:", s.sy, s.systring ### |
1532 if s.sy == 'global': | 1552 if s.sy == 'global': |
1533 node = p_global_statement(s) | 1553 node = p_global_statement(s) |
1534 elif s.sy == 'nonlocal': | |
1535 node = p_nonlocal_statement(s) | |
1536 elif s.sy == 'print': | 1554 elif s.sy == 'print': |
1537 node = p_print_statement(s) | 1555 node = p_print_statement(s) |
1538 elif s.sy == 'exec': | 1556 elif s.sy == 'exec': |
1539 node = p_exec_statement(s) | 1557 node = p_exec_statement(s) |
1540 elif s.sy == 'del': | 1558 elif s.sy == 'del': |
1541 node = p_del_statement(s) | 1559 node = p_del_statement(s) |
1542 elif s.sy == 'break': | 1560 elif s.sy == 'break': |
1543 node = p_break_statement(s) | 1561 node = p_break_statement(s) |
1544 elif s.sy == 'continue': | 1562 elif s.sy == 'continue': |
1545 node = p_continue_statement(s) | 1563 node = p_continue_statement(s) |
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1996 elif s.systring == 'signed': | 2014 elif s.systring == 'signed': |
1997 signed = 2 | 2015 signed = 2 |
1998 elif s.systring == 'short': | 2016 elif s.systring == 'short': |
1999 longness = -1 | 2017 longness = -1 |
2000 elif s.systring == 'long': | 2018 elif s.systring == 'long': |
2001 longness += 1 | 2019 longness += 1 |
2002 s.next() | 2020 s.next() |
2003 return signed, longness | 2021 return signed, longness |
2004 | 2022 |
2005 def p_opt_cname(s): | 2023 def p_opt_cname(s): |
2006 literal = p_opt_string_literal(s) | 2024 literal = p_opt_string_literal(s, 'u') |
2007 if literal: | 2025 if literal is not None: |
2008 _, cname = literal | 2026 cname = EncodedString(literal) |
2009 cname = EncodedString(cname) | |
2010 cname.encoding = s.source_encoding | 2027 cname.encoding = s.source_encoding |
2011 else: | 2028 else: |
2012 cname = None | 2029 cname = None |
2013 return cname | 2030 return cname |
2014 | 2031 |
2015 def p_c_declarator(s, ctx = Ctx(), empty = 0, is_type = 0, cmethod_flag = 0, | 2032 def p_c_declarator(s, ctx = Ctx(), empty = 0, is_type = 0, cmethod_flag = 0, |
2016 assignable = 0, nonempty = 0, | 2033 assignable = 0, nonempty = 0, |
2017 calling_convention_allowed = 0): | 2034 calling_convention_allowed = 0): |
2018 # If empty is true, the declarator must be empty. If nonempty is true, | 2035 # If empty is true, the declarator must be empty. If nonempty is true, |
2019 # the declarator must be nonempty. Otherwise we don't care. | 2036 # the declarator must be nonempty. Otherwise we don't care. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2066 nogil = p_nogil(s) | 2083 nogil = p_nogil(s) |
2067 exc_val, exc_check = p_exception_value_clause(s) | 2084 exc_val, exc_check = p_exception_value_clause(s) |
2068 with_gil = p_with_gil(s) | 2085 with_gil = p_with_gil(s) |
2069 return Nodes.CFuncDeclaratorNode(pos,· | 2086 return Nodes.CFuncDeclaratorNode(pos,· |
2070 base = base, args = args, has_varargs = ellipsis, | 2087 base = base, args = args, has_varargs = ellipsis, |
2071 exception_value = exc_val, exception_check = exc_check, | 2088 exception_value = exc_val, exception_check = exc_check, |
2072 nogil = nogil or ctx.nogil or with_gil, with_gil = with_gil) | 2089 nogil = nogil or ctx.nogil or with_gil, with_gil = with_gil) |
2073 | 2090 |
2074 supported_overloaded_operators = cython.set([ | 2091 supported_overloaded_operators = cython.set([ |
2075 '+', '-', '*', '/', '%',· | 2092 '+', '-', '*', '/', '%',· |
2076 '++', '--', '~', '|', '&', '^', '<<', '>>', | 2093 '++', '--', '~', '|', '&', '^', '<<', '>>', ',', |
2077 '==', '!=', '>=', '>', '<=', '<', | 2094 '==', '!=', '>=', '>', '<=', '<', |
2078 '[]', '()', | 2095 '[]', '()', |
2079 ]) | 2096 ]) |
2080 | 2097 |
2081 def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag, | 2098 def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag, |
2082 assignable, nonempty): | 2099 assignable, nonempty): |
2083 pos = s.position() | 2100 pos = s.position() |
2084 calling_convention = p_calling_convention(s) | 2101 calling_convention = p_calling_convention(s) |
2085 if s.sy == '*': | 2102 if s.sy == '*': |
2086 s.next() | 2103 s.next() |
(...skipping 17 matching lines...) Expand all Loading... |
2104 assignable = assignable, nonempty = nonempty) | 2121 assignable = assignable, nonempty = nonempty) |
2105 result = Nodes.CReferenceDeclaratorNode(pos, base = base) | 2122 result = Nodes.CReferenceDeclaratorNode(pos, base = base) |
2106 else: | 2123 else: |
2107 rhs = None | 2124 rhs = None |
2108 if s.sy == 'IDENT': | 2125 if s.sy == 'IDENT': |
2109 name = EncodedString(s.systring) | 2126 name = EncodedString(s.systring) |
2110 if empty: | 2127 if empty: |
2111 error(s.position(), "Declarator should be empty") | 2128 error(s.position(), "Declarator should be empty") |
2112 s.next() | 2129 s.next() |
2113 cname = p_opt_cname(s) | 2130 cname = p_opt_cname(s) |
2114 if name != "operator" and s.sy == '=' and assignable: | 2131 if name != 'operator' and s.sy == '=' and assignable: |
2115 s.next() | 2132 s.next() |
2116 rhs = p_test(s) | 2133 rhs = p_test(s) |
2117 else: | 2134 else: |
2118 if nonempty: | 2135 if nonempty: |
2119 error(s.position(), "Empty declarator") | 2136 error(s.position(), "Empty declarator") |
2120 name = "" | 2137 name = "" |
2121 cname = None | 2138 cname = None |
2122 if cname is None and ctx.namespace is not None: | 2139 if cname is None and ctx.namespace is not None and nonempty: |
2123 cname = ctx.namespace + "::" + name | 2140 cname = ctx.namespace + "::" + name |
2124 if name == 'operator' and ctx.visibility == 'extern': | 2141 if name == 'operator' and ctx.visibility == 'extern' and nonempty: |
2125 op = s.sy | 2142 op = s.sy |
2126 s.next() | 2143 if [c in '+-*/<=>!%&|([^~,' for c in op]: |
2127 # Handle diphthong operators. | |
2128 if op == '(': | |
2129 s.expect(')') | |
2130 op = '()' | |
2131 elif op == '[': | |
2132 s.expect(']') | |
2133 op = '[]' | |
2134 if op in ['-', '+', '|', '&'] and s.sy == op: | |
2135 op = op*2 | |
2136 s.next() | 2144 s.next() |
2137 if s.sy == '=': | 2145 # Handle diphthong operators. |
2138 op += s.sy | 2146 if op == '(': |
2139 s.next() | 2147 s.expect(')') |
2140 if op not in supported_overloaded_operators: | 2148 op = '()' |
2141 s.error("Overloading operator '%s' not yet supported." % op) | 2149 elif op == '[': |
2142 name = name+op | 2150 s.expect(']') |
| 2151 op = '[]' |
| 2152 if op in ['-', '+', '|', '&'] and s.sy == op: |
| 2153 op = op*2 |
| 2154 s.next() |
| 2155 if s.sy == '=': |
| 2156 op += s.sy |
| 2157 s.next() |
| 2158 if op not in supported_overloaded_operators: |
| 2159 s.error("Overloading operator '%s' not yet supported." % op) |
| 2160 name = name+op |
2143 result = Nodes.CNameDeclaratorNode(pos, | 2161 result = Nodes.CNameDeclaratorNode(pos, |
2144 name = name, cname = cname, default = rhs) | 2162 name = name, cname = cname, default = rhs) |
2145 result.calling_convention = calling_convention | 2163 result.calling_convention = calling_convention |
2146 return result | 2164 return result |
2147 | 2165 |
2148 def p_nogil(s): | 2166 def p_nogil(s): |
2149 if s.sy == 'IDENT' and s.systring == 'nogil': | 2167 if s.sy == 'IDENT' and s.systring == 'nogil': |
2150 s.next() | 2168 s.next() |
2151 return 1 | 2169 return 1 |
2152 else: | 2170 else: |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2309 return p_suite(s, ctx(cdef_flag = 1)) | 2327 return p_suite(s, ctx(cdef_flag = 1)) |
2310 | 2328 |
2311 def p_cdef_extern_block(s, pos, ctx): | 2329 def p_cdef_extern_block(s, pos, ctx): |
2312 if ctx.overridable: | 2330 if ctx.overridable: |
2313 error(pos, "cdef extern blocks cannot be declared cpdef") | 2331 error(pos, "cdef extern blocks cannot be declared cpdef") |
2314 include_file = None | 2332 include_file = None |
2315 s.expect('from') | 2333 s.expect('from') |
2316 if s.sy == '*': | 2334 if s.sy == '*': |
2317 s.next() | 2335 s.next() |
2318 else: | 2336 else: |
2319 _, include_file = p_string_literal(s) | 2337 include_file = p_string_literal(s, 'u')[2] |
2320 ctx = ctx(cdef_flag = 1, visibility = 'extern') | 2338 ctx = ctx(cdef_flag = 1, visibility = 'extern') |
2321 if s.systring == "namespace": | 2339 if s.systring == "namespace": |
2322 s.next() | 2340 s.next() |
2323 ctx.namespace = p_string_literal(s, kind_override='u')[1] | 2341 ctx.namespace = p_string_literal(s, 'u')[2] |
2324 if p_nogil(s): | 2342 if p_nogil(s): |
2325 ctx.nogil = 1 | 2343 ctx.nogil = 1 |
2326 body = p_suite(s, ctx) | 2344 body = p_suite(s, ctx) |
2327 return Nodes.CDefExternNode(pos, | 2345 return Nodes.CDefExternNode(pos, |
2328 include_file = include_file, | 2346 include_file = include_file, |
2329 body = body, | 2347 body = body, |
2330 namespace = ctx.namespace) | 2348 namespace = ctx.namespace) |
2331 | 2349 |
2332 def p_c_enum_definition(s, pos, ctx): | 2350 def p_c_enum_definition(s, pos, ctx): |
2333 # s.sy == ident 'enum' | 2351 # s.sy == ident 'enum' |
2334 s.next() | 2352 s.next() |
2335 if s.sy == 'IDENT': | 2353 if s.sy == 'IDENT': |
2336 name = s.systring | 2354 name = s.systring |
2337 s.next() | 2355 s.next() |
2338 cname = p_opt_cname(s) | 2356 cname = p_opt_cname(s) |
2339 if cname is None and ctx.namespace is not None: | 2357 if cname is None and ctx.namespace is not None: |
2340 cname = ctx.namespace + "::" + name | 2358 cname = ctx.namespace + "::" + name |
2341 else: | 2359 else: |
2342 name = None | 2360 name = None |
2343 cname = None | 2361 cname = None |
2344 items = None | 2362 items = None |
2345 s.expect(':') | 2363 s.expect(':') |
2346 items = [] | 2364 items = [] |
2347 if s.sy != 'NEWLINE': | 2365 if s.sy != 'NEWLINE': |
2348 p_c_enum_line(s, items) | 2366 p_c_enum_line(s, ctx, items) |
2349 else: | 2367 else: |
2350 s.next() # 'NEWLINE' | 2368 s.next() # 'NEWLINE' |
2351 s.expect_indent() | 2369 s.expect_indent() |
2352 while s.sy not in ('DEDENT', 'EOF'): | 2370 while s.sy not in ('DEDENT', 'EOF'): |
2353 p_c_enum_line(s, items) | 2371 p_c_enum_line(s, ctx, items) |
2354 s.expect_dedent() | 2372 s.expect_dedent() |
2355 return Nodes.CEnumDefNode( | 2373 return Nodes.CEnumDefNode( |
2356 pos, name = name, cname = cname, items = items, | 2374 pos, name = name, cname = cname, items = items, |
2357 typedef_flag = ctx.typedef_flag, visibility = ctx.visibility, | 2375 typedef_flag = ctx.typedef_flag, visibility = ctx.visibility, |
2358 in_pxd = ctx.level == 'module_pxd') | 2376 in_pxd = ctx.level == 'module_pxd') |
2359 | 2377 |
2360 def p_c_enum_line(s, items): | 2378 def p_c_enum_line(s, ctx, items): |
2361 if s.sy != 'pass': | 2379 if s.sy != 'pass': |
2362 p_c_enum_item(s, items) | 2380 p_c_enum_item(s, ctx, items) |
2363 while s.sy == ',': | 2381 while s.sy == ',': |
2364 s.next() | 2382 s.next() |
2365 if s.sy in ('NEWLINE', 'EOF'): | 2383 if s.sy in ('NEWLINE', 'EOF'): |
2366 break | 2384 break |
2367 p_c_enum_item(s, items) | 2385 p_c_enum_item(s, ctx, items) |
2368 else: | 2386 else: |
2369 s.next() | 2387 s.next() |
2370 s.expect_newline("Syntax error in enum item list") | 2388 s.expect_newline("Syntax error in enum item list") |
2371 | 2389 |
2372 def p_c_enum_item(s, items): | 2390 def p_c_enum_item(s, ctx, items): |
2373 pos = s.position() | 2391 pos = s.position() |
2374 name = p_ident(s) | 2392 name = p_ident(s) |
2375 cname = p_opt_cname(s) | 2393 cname = p_opt_cname(s) |
| 2394 if cname is None and ctx.namespace is not None: |
| 2395 cname = ctx.namespace + "::" + name |
2376 value = None | 2396 value = None |
2377 if s.sy == '=': | 2397 if s.sy == '=': |
2378 s.next() | 2398 s.next() |
2379 value = p_test(s) | 2399 value = p_test(s) |
2380 items.append(Nodes.CEnumDefItemNode(pos,· | 2400 items.append(Nodes.CEnumDefItemNode(pos,· |
2381 name = name, cname = cname, value = value)) | 2401 name = name, cname = cname, value = value)) |
2382 | 2402 |
2383 def p_c_struct_or_union_definition(s, pos, ctx): | 2403 def p_c_struct_or_union_definition(s, pos, ctx): |
2384 packed = False | 2404 packed = False |
2385 if s.systring == 'packed': | 2405 if s.systring == 'packed': |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2684 def p_property_decl(s): | 2704 def p_property_decl(s): |
2685 pos = s.position() | 2705 pos = s.position() |
2686 s.next() # 'property' | 2706 s.next() # 'property' |
2687 name = p_ident(s) | 2707 name = p_ident(s) |
2688 doc, body = p_suite(s, Ctx(level = 'property'), with_doc = 1) | 2708 doc, body = p_suite(s, Ctx(level = 'property'), with_doc = 1) |
2689 return Nodes.PropertyNode(pos, name = name, doc = doc, body = body) | 2709 return Nodes.PropertyNode(pos, name = name, doc = doc, body = body) |
2690 | 2710 |
2691 def p_doc_string(s): | 2711 def p_doc_string(s): |
2692 if s.sy == 'BEGIN_STRING': | 2712 if s.sy == 'BEGIN_STRING': |
2693 pos = s.position() | 2713 pos = s.position() |
2694 kind, result = p_cat_string_literal(s) | 2714 kind, bytes_result, unicode_result = p_cat_string_literal(s) |
2695 if s.sy != 'EOF': | 2715 if s.sy != 'EOF': |
2696 s.expect_newline("Syntax error in doc string") | 2716 s.expect_newline("Syntax error in doc string") |
2697 if kind != 'u': | 2717 if kind in ('u', ''): |
2698 # warning(pos, "Python 3 requires docstrings to be unicode strings") | 2718 return unicode_result |
2699 if kind == 'b': | 2719 warning(pos, "Python 3 requires docstrings to be unicode strings") |
2700 result.encoding = None # force a unicode string | 2720 return bytes_result |
2701 return result | |
2702 else: | 2721 else: |
2703 return None | 2722 return None |
2704 | 2723 |
2705 def p_code(s, level=None): | 2724 def p_code(s, level=None): |
2706 body = p_statement_list(s, Ctx(level = level), first_statement = 1) | 2725 body = p_statement_list(s, Ctx(level = level), first_statement = 1) |
2707 if s.sy != 'EOF': | 2726 if s.sy != 'EOF': |
2708 s.error("Syntax error in statement [%s,%s]" % ( | 2727 s.error("Syntax error in statement [%s,%s]" % ( |
2709 repr(s.sy), repr(s.systring))) | 2728 repr(s.sy), repr(s.systring))) |
2710 return body | 2729 return body |
2711 | 2730 |
2712 COMPILER_DIRECTIVE_COMMENT_RE = re.compile(r"^#\s*cython:\s*((\w|[.])+\s*=.*)$") | 2731 COMPILER_DIRECTIVE_COMMENT_RE = re.compile(r"^#\s*cython:\s*((\w|[.])+\s*=.*)$") |
2713 | 2732 |
2714 def p_compiler_directive_comments(s): | 2733 def p_compiler_directive_comments(s): |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2842 print_parse_tree(f, value, level+1, name) | 2861 print_parse_tree(f, value, level+1, name) |
2843 return | 2862 return |
2844 elif t is list: | 2863 elif t is list: |
2845 f.write("[\n") | 2864 f.write("[\n") |
2846 for i in xrange(len(node)): | 2865 for i in xrange(len(node)): |
2847 print_parse_tree(f, node[i], level+1) | 2866 print_parse_tree(f, node[i], level+1) |
2848 f.write("%s]\n" % ind) | 2867 f.write("%s]\n" % ind) |
2849 return | 2868 return |
2850 f.write("%s%s\n" % (ind, node)) | 2869 f.write("%s%s\n" % (ind, node)) |
2851 | 2870 |
LEFT | RIGHT |