Fix regexp for finding code blocks
[bpt/emacs.git] / etc / grammars / python.wy
CommitLineData
469d2149
CY
1;;; semantic/wisent/python.wy -- LALR grammar for Python
2;;
3;; Copyright (C) 2002, 2003, 2004, 2007 Richard Kim
4;;
5;; Author: Richard Kim <ryk@dspwiz.com>
6;; Maintainer: Richard Kim <ryk@dspwiz.com>
7;; Created: June 2002
8;; Keywords: syntax
9;;
10;; This file is not part of GNU Emacs.
11;;
12;; This program is free software; you can redistribute it and/or
13;; modify it under the terms of the GNU General Public License as
14;; published by the Free Software Foundation; either version 2, or (at
15;; your option) any later version.
16;;
17;; This software is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20;; General Public License for more details.
21;;
22;; You should have received a copy of the GNU General Public License
23;; along with GNU Emacs; see the file COPYING. If not, write to the
24;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25;; Boston, MA 02110-1301, USA.
26
27;;; Commentary:
28;;
29;; This is an LALR python parser that follows the official python
30;; grammar closely with very few exceptions.
31;;
32;;; To do:
33;;
34;; * Verify that semantic-lex-python-number regexp is correct.
35
36;; --------
37;; Settings
38;; --------
39
40%package python-wy
41
42%languagemode python-mode
43
44;; The default start symbol
45%start goal
46;; Alternate entry points
47;; - Needed by partial re-parse
48%start function_parameter
49%start paren_class
50%start indented_block
51;; - Needed by EXPANDFULL clauses
52%start function_parameters
53%start paren_classes
54%start indented_block_body
55
56;; -------------------------------
57;; Misc. Python specific terminals
58;; -------------------------------
59;; The value of these tokens are for documentation only, they are not
60;; used by the lexer.
61%token <charquote> BACKSLASH "\\"
62%token <newline> NEWLINE "\n"
63%token <indentation> INDENT "^\\s-+"
64%token <indentation> DEDENT "[^:INDENT:]"
65%token <indentation> INDENT_BLOCK "(INDENT DEDENT)"
66
67;; -----------------------------
68;; Block & Parenthesis terminals
69;; -----------------------------
70%type <block> ;;syntax "\\s(\\|\\s)" matchdatatype block
71
72%token <block> PAREN_BLOCK "(LPAREN RPAREN)"
73%token <block> BRACE_BLOCK "(LBRACE RBRACE)"
74%token <block> BRACK_BLOCK "(LBRACK RBRACK)"
75
76%token <open-paren> LPAREN "("
77%token <close-paren> RPAREN ")"
78%token <open-paren> LBRACE "{"
79%token <close-paren> RBRACE "}"
80%token <open-paren> LBRACK "["
81%token <close-paren> RBRACK "]"
82
83;; ------------------
84;; Operator terminals
85;; ------------------
86%type <punctuation> ;;syntax "\\(\\s.\\|\\s$\\|\\s'\\)+" matchdatatype string
87
88%token <punctuation> LTLTEQ "<<="
89%token <punctuation> GTGTEQ ">>="
90%token <punctuation> EXPEQ "**="
91%token <punctuation> DIVDIVEQ "//="
92%token <punctuation> DIVDIV "//"
93%token <punctuation> LTLT "<<"
94%token <punctuation> GTGT ">>"
95%token <punctuation> EXPONENT "**"
96%token <punctuation> EQ "=="
97%token <punctuation> GE ">="
98%token <punctuation> LE "<="
99%token <punctuation> PLUSEQ "+="
100%token <punctuation> MINUSEQ "-="
101%token <punctuation> MULTEQ "*="
102%token <punctuation> DIVEQ "/="
103%token <punctuation> MODEQ "%="
104%token <punctuation> AMPEQ "&="
105%token <punctuation> OREQ "|="
106%token <punctuation> HATEQ "^="
107%token <punctuation> LTGT "<>"
108%token <punctuation> NE "!="
109%token <punctuation> HAT "^"
110%token <punctuation> LT "<"
111%token <punctuation> GT ">"
112%token <punctuation> AMP "&"
113%token <punctuation> MULT "*"
114%token <punctuation> DIV "/"
115%token <punctuation> MOD "%"
116%token <punctuation> PLUS "+"
117%token <punctuation> MINUS "-"
118%token <punctuation> PERIOD "."
119%token <punctuation> TILDE "~"
120%token <punctuation> BAR "|"
121%token <punctuation> COLON ":"
122%token <punctuation> SEMICOLON ";"
123%token <punctuation> COMMA ","
124%token <punctuation> ASSIGN "="
125%token <punctuation> BACKQUOTE "`"
126
127
128;; -----------------
129;; Literal terminals
130;; -----------------
131%token <string> STRING_LITERAL
132
133%type <number> ;;syntax semantic-lex-number-expression
134%token <number> NUMBER_LITERAL
135
136%type <symbol> ;;syntax "\\(\\sw\\|\\s_\\)+"
137%token <symbol> NAME
138
139;; -----------------
140;; Keyword terminals
141;; -----------------
142%type <keyword> ;;syntax "\\(\\sw\\|\\s_\\)+" matchdatatype keyword
143
144%keyword AND "and"
145%put AND summary
146"Logical AND binary operator ... "
147
148%keyword AS "as"
149%put AS summary
150"EXPR as NAME makes value of EXPR available as variable NAME"
151
152%keyword ASSERT "assert"
153%put ASSERT summary
154"Raise AssertionError exception if <expr> is false"
155
156%keyword BREAK "break"
157%put BREAK summary
158"Terminate 'for' or 'while' loop"
159
160%keyword CLASS "class"
161%put CLASS summary
162"Define a new class"
163
164%keyword CONTINUE "continue"
165%put CONTINUE summary
166"Skip to the next iteration of enclosing 'for' or 'while' loop"
167
168%keyword DEF "def"
169%put DEF summary
170"Define a new function"
171
172%keyword DEL "del"
173%put DEL summary
174"Delete specified objects, i.e., undo what assignment did"
175
176%keyword ELIF "elif"
177%put ELIF summary
178"Shorthand for 'else if' following an 'if' statement"
179
180%keyword ELSE "else"
181%put ELSE summary
182"Start the 'else' clause following an 'if' statement"
183
184%keyword EXCEPT "except"
185%put EXCEPT summary
186"Specify exception handlers along with 'try' keyword"
187
188%keyword EXEC "exec"
189%put EXEC summary
190"Dynamically execute Python code"
191
192%keyword FINALLY "finally"
193%put FINALLY summary
194"Specify code to be executed after 'try' statements whether or not an exception occurred"
195
196%keyword FOR "for"
197%put FOR summary
198"Start a 'for' loop"
199
200%keyword FROM "from"
201%put FROM summary
202"Modify behavior of 'import' statement"
203
204%keyword GLOBAL "global"
205%put GLOBAL summary
206"Declare one or more symbols as global symbols"
207
208%keyword IF "if"
209%put IF summary
210"Start 'if' conditional statement"
211
212%keyword IMPORT "import"
213%put IMPORT summary
214"Load specified modules"
215
216%keyword IN "in"
217%put IN summary
218"Part of 'for' statement "
219
220%keyword IS "is"
221%put IS summary
222"Binary operator that tests for object equality"
223
224%keyword LAMBDA "lambda"
225%put LAMBDA summary
226"Create anonymous function"
227
228%keyword NOT "not"
229%put NOT summary
230"Unary boolean negation operator"
231
232%keyword OR "or"
233%put OR summary
234"Binary logical 'or' operator"
235
236%keyword PASS "pass"
237%put PASS summary
238"Statement that does nothing"
239
240%keyword PRINT "print"
241%put PRINT summary
242"Print each argument to standard output"
243
244%keyword RAISE "raise"
245%put RAISE summary
246"Raise an exception"
247
248%keyword RETURN "return"
249%put RETURN summary
250"Return from a function"
251
252%keyword TRY "try"
253%put TRY summary
254"Start of statements protected by exception handlers"
255
256%keyword WHILE "while"
257%put WHILE summary
258"Start a 'while' loop"
259
260%keyword YIELD "yield"
261%put YIELD summary
262"Create a generator function"
263
264%%
265
266;;;****************************************************************************
267;;;@ goal
268;;;****************************************************************************
269
270;; simple_stmt are statements that do not involve INDENT tokens
271;; compound_stmt are statements that involve INDENT tokens
272goal
273 : NEWLINE
274 | simple_stmt
275 | compound_stmt
276 ;
277
278;;;****************************************************************************
279;;;@ simple_stmt
280;;;****************************************************************************
281
282;; simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
283simple_stmt
284 : small_stmt_list semicolon_opt NEWLINE
285 ;
286
287;; small_stmt (';' small_stmt)*
288small_stmt_list
289 : small_stmt
290 | small_stmt_list SEMICOLON small_stmt
291 ;
292
293small_stmt
294 : expr_stmt
295 | print_stmt
296 | del_stmt
297 | pass_stmt
298 | flow_stmt
299 | import_stmt
300 | global_stmt
301 | exec_stmt
302 | assert_stmt
303 ;
304
305;;;============================================================================
306;;;@@ print_stmt
307;;;============================================================================
308
309;; print_stmt: 'print' [ test (',' test)* [','] ]
310;; | '>>' test [ (',' test)+ [','] ]
311print_stmt
312 : PRINT print_stmt_trailer
313 (CODE-TAG $1 nil)
314 ;
315
316;; [ test (',' test)* [','] ] | '>>' test [ (',' test)+ [','] ]
317print_stmt_trailer
318 : test_list_opt
319 ()
320 | GTGT test trailing_test_list_with_opt_comma_opt
321 ()
322 ;
323
324;; [ (',' test)+ [','] ]
325trailing_test_list_with_opt_comma_opt
326 : ;;EMPTY
327 | trailing_test_list comma_opt
328 ()
329 ;
330
331;; (',' test)+
332trailing_test_list
333 : COMMA test
334 ()
335 | trailing_test_list COMMA test
336 ()
337 ;
338
339;;;============================================================================
340;;;@@ expr_stmt
341;;;============================================================================
342
343;; expr_stmt: testlist (augassign testlist | ('=' testlist)*)
344expr_stmt
345 : testlist expr_stmt_trailer
346 (if (and $2 (stringp $1) (string-match "^\\(\\sw\\|\\s_\\)+$" $1))
347 ;; If this is an assignment statement and left side is a symbol,
348 ;; then generate a 'variable token, else return 'code token.
349 (VARIABLE-TAG $1 nil nil)
350 (CODE-TAG $1 nil))
351 ;
352
353;; Could be EMPTY because of eq_testlist_zom.
354;; (augassign testlist | ('=' testlist)*)
355expr_stmt_trailer
356 : augassign testlist
357 | eq_testlist_zom
358 ;
359
360;; Could be EMPTY!
361;; ('=' testlist)*
362eq_testlist_zom
363 : ;;EMPTY
364 | eq_testlist_zom ASSIGN testlist
365 (identity $3)
366 ;
367
368;; augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^='
369;; | '<<=' | '>>=' | '**=' | '//='
370augassign
371 : PLUSEQ | MINUSEQ | MULTEQ | DIVEQ | MODEQ
372 | AMPEQ | OREQ | HATEQ | LTLTEQ
373 | GTGTEQ | EXPEQ | DIVDIVEQ
374 ;
375
376;;;============================================================================
377;;;@@ del_stmt
378;;;============================================================================
379
380;; del_stmt: 'del' exprlist
381del_stmt
382 : DEL exprlist
383 (CODE-TAG $1 nil)
384 ;
385
386;; exprlist: expr (',' expr)* [',']
387exprlist
388 : expr_list comma_opt
389 ()
390 ;
391
392;; expr (',' expr)*
393expr_list
394 : expr
395 ()
396 | expr_list COMMA expr
397 ()
398 ;
399
400;;;============================================================================
401;;;@@ pass_stmt
402;;;============================================================================
403
404;; pass_stmt: 'pass'
405pass_stmt
406 : PASS
407 (CODE-TAG $1 nil)
408 ;
409
410;;;============================================================================
411;;;@@ flow_stmt
412;;;============================================================================
413
414flow_stmt
415 : break_stmt
416 | continue_stmt
417 | return_stmt
418 | raise_stmt
419 | yield_stmt
420 ;
421
422;; break_stmt: 'break'
423break_stmt
424 : BREAK
425 (CODE-TAG $1 nil)
426 ;
427
428;; continue_stmt: 'continue'
429continue_stmt
430 : CONTINUE
431 (CODE-TAG $1 nil)
432 ;
433
434;; return_stmt: 'return' [testlist]
435return_stmt
436 : RETURN testlist_opt
437 (CODE-TAG $1 nil)
438 ;
439
440;; [testlist]
441testlist_opt
442 : ;;EMPTY
443 | testlist
444 ()
445 ;
446
447;; yield_stmt: 'yield' testlist
448yield_stmt
449 : YIELD
450 (CODE-TAG $1 nil)
451 | YIELD testlist
452 (CODE-TAG $1 nil)
453 ;
454
455;; raise_stmt: 'raise' [test [',' test [',' test]]]
456raise_stmt
457 : RAISE zero_one_two_or_three_tests
458 (CODE-TAG $1 nil)
459 ;
460
461;; [test [',' test [',' test]]]
462zero_one_two_or_three_tests
463 : ;;EMPTY
464 | test zero_one_or_two_tests
465 ()
466 ;
467
468;; [',' test [',' test]]
469zero_one_or_two_tests
470 : ;;EMPTY
471 | COMMA test zero_or_one_comma_test
472 ()
473 ;
474
475;; [',' test]
476zero_or_one_comma_test
477 : ;;EMPTY
478 | COMMA test
479 ()
480 ;
481
482;;;============================================================================
483;;;@@ import_stmt
484;;;============================================================================
485
486;; import_stmt : 'import' dotted_as_name (',' dotted_as_name)*
487;; | 'from' dotted_name 'import'
488;; ('*' | import_as_name (',' import_as_name)*)
489import_stmt
490 : IMPORT dotted_as_name_list
491 (INCLUDE-TAG $2 nil)
492 | FROM dotted_name IMPORT star_or_import_as_name_list
493 (INCLUDE-TAG $2 nil)
494 ;
495
496;; dotted_as_name (',' dotted_as_name)*
497dotted_as_name_list
498 : dotted_as_name
499 | dotted_as_name_list COMMA dotted_as_name
500 ;
501
502;; ('*' | import_as_name (',' import_as_name)*)
503star_or_import_as_name_list
504 : MULT
505 ()
506 | import_as_name_list
507 ()
508 ;
509
510;; import_as_name (',' import_as_name)*
511import_as_name_list
512 : import_as_name
513 ()
514 | import_as_name_list COMMA import_as_name
515 ()
516 ;
517
518;; import_as_name: NAME [NAME NAME]
519import_as_name
520 : NAME as_name_opt
521 ()
522 ;
523
524;; dotted_as_name: dotted_name [AS NAME]
525dotted_as_name
526 : dotted_name as_name_opt
527 ;
528
529;; [AS NAME]
530as_name_opt
531 : ;;EMPTY
532 | AS NAME
533 (identity $2)
534 ;
535
536;; dotted_name: NAME ('.' NAME)*
537dotted_name
538 : NAME
539 | dotted_name PERIOD NAME
540 (format "%s.%s" $1 $3)
541 ;
542
543;;;============================================================================
544;;;@@ global_stmt
545;;;============================================================================
546
547;; global_stmt: 'global' NAME (',' NAME)*
548global_stmt
549 : GLOBAL comma_sep_name_list
550 (CODE-TAG $1 nil)
551 ;
552
553;; NAME (',' NAME)*
554comma_sep_name_list
555 : NAME
556 | comma_sep_name_list COMMA NAME
557 ;
558
559;;;============================================================================
560;;;@@ exec_stmt
561;;;============================================================================
562
563;; exec_stmt: 'exec' expr ['in' test [',' test]]
564exec_stmt
565 : EXEC expr exec_trailer
566 (CODE-TAG $1 nil)
567 ;
568
569;; ['in' test [',' test]]
570exec_trailer
571 : ;;EMPTY
572 | IN test comma_test_opt
573 ()
574 ;
575
576;; [',' test]
577comma_test_opt
578 : ;;EMPTY
579 | COMMA test
580 ()
581 ;
582
583;;;============================================================================
584;;;@@ assert_stmt
585;;;============================================================================
586
587;; assert_stmt: 'assert' test [',' test]
588assert_stmt
589 : ASSERT test comma_test_opt
590 (CODE-TAG $1 nil)
591 ;
592
593;;;****************************************************************************
594;;;@ compound_stmt
595;;;****************************************************************************
596
597compound_stmt
598 : if_stmt
599 | while_stmt
600 | for_stmt
601 | try_stmt
602 | funcdef
603 | class_declaration
604 ;
605
606;;;============================================================================
607;;;@@ if_stmt
608;;;============================================================================
609
610;; if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
611if_stmt
612 : IF test COLON suite elif_suite_pair_list else_suite_pair_opt
613 (CODE-TAG $1 nil)
614 ;
615
616;; ('elif' test ':' suite)*
617elif_suite_pair_list
618 : ;;EMPTY
619 | elif_suite_pair_list ELIF test COLON suite
620 ()
621 ;
622
623;; ['else' ':' suite]
624else_suite_pair_opt
625 : ;;EMPTY
626 | ELSE COLON suite
627 ()
628 ;
629
630;; This NT follows the COLON token for most compound statements.
631;; suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
632suite
633 : simple_stmt
634 (list $1)
635 | NEWLINE indented_block
636 (progn $2)
637 ;
638
639indented_block
640 : INDENT_BLOCK
641 (EXPANDFULL $1 indented_block_body)
642 ;
643
644indented_block_body
645 : INDENT
646 ()
647 | DEDENT
648 ()
649 | simple_stmt
650 | compound_stmt
651 ;
652
653;;;============================================================================
654;;;@@ while_stmt
655;;;============================================================================
656
657;; while_stmt: 'while' test ':' suite ['else' ':' suite]
658while_stmt
659 : WHILE test COLON suite else_suite_pair_opt
660 (CODE-TAG $1 nil)
661 ;
662
663;;;============================================================================
664;;;@@ for_stmt
665;;;============================================================================
666
667;; for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
668for_stmt
669 : FOR exprlist IN testlist COLON suite else_suite_pair_opt
670 (CODE-TAG $1 nil)
671 ;
672
673;;;============================================================================
674;;;@@ try_stmt
675;;;============================================================================
676
677;; try_stmt: ('try' ':' suite (except_clause ':' suite)+ #diagram:break
678;; ['else' ':' suite] | 'try' ':' suite 'finally' ':' suite)
679try_stmt
680 : TRY COLON suite except_clause_suite_pair_list else_suite_pair_opt
681 (CODE-TAG $1 nil)
682 | TRY COLON suite FINALLY COLON suite
683 (CODE-TAG $1 nil)
684 ;
685
686;; (except_clause ':' suite)+
687except_clause_suite_pair_list
688 : except_clause COLON suite
689 ()
690 | except_clause_suite_pair_list except_clause COLON suite
691 ()
692 ;
693
694;; # NB compile.c makes sure that the default except clause is last
695;; except_clause: 'except' [test [',' test]]
696except_clause
697 : EXCEPT zero_one_or_two_test
698 ()
699 ;
700
701;; [test [',' test]]
702zero_one_or_two_test
703 : ;;EMPTY
704 | test zero_or_one_comma_test
705 ()
706 ;
707
708;;;============================================================================
709;;;@@ funcdef
710;;;============================================================================
711
712;; funcdef: 'def' NAME parameters ':' suite
713funcdef
714 : DEF NAME function_parameter_list COLON suite
715 (FUNCTION-TAG $2 nil $3)
716 ;
717
718function_parameter_list
719 : PAREN_BLOCK
720 (let ((wisent-python-EXPANDING-block t))
721 (EXPANDFULL $1 function_parameters))
722 ;
723
724;; parameters: '(' [varargslist] ')'
725function_parameters
726 : LPAREN
727 ()
728 | RPAREN
729 ()
730 | function_parameter COMMA
731 | function_parameter RPAREN
732 ;
733
734function_parameter
735 : fpdef_opt_test
736 ;; : NAME
737 ;; (VARIABLE-TAG $1 nil nil)
738 | MULT NAME
739 (VARIABLE-TAG $2 nil nil)
740 | EXPONENT NAME
741 (VARIABLE-TAG $2 nil nil)
742 ;
743
744;;;============================================================================
745;;;@@ class_declaration
746;;;============================================================================
747
748;; classdef: 'class' NAME ['(' testlist ')'] ':' suite
749class_declaration
750 : CLASS NAME paren_class_list_opt COLON suite
751 (TYPE-TAG $2 $1 ;; Name "class"
752 $5 ;; Members
753 (cons $3 nil) ;; (SUPERCLASSES . INTERFACES)
754 )
755 ;
756
757;; ['(' testlist ')']
758paren_class_list_opt
759 : ;;EMPTY
760 | paren_class_list
761 ;
762
763paren_class_list
764 : PAREN_BLOCK
765 (let ((wisent-python-EXPANDING-block t))
766 (mapcar 'semantic-tag-name (EXPANDFULL $1 paren_classes)))
767 ;
768
769;; parameters: '(' [varargslist] ')'
770paren_classes
771 : LPAREN
772 ()
773 | RPAREN
774 ()
775 | paren_class COMMA
776 (VARIABLE-TAG $1 nil nil)
777 | paren_class RPAREN
778 (VARIABLE-TAG $1 nil nil)
779 ;
780
781;; In general, the base class can be specified by a general expression
782;; which evalue to a class object, i.e., base classes are not just names!
783;; However base classes are names in most cases. Thus the
784;; non-terminals below work only with simple names. Even if the
785;; parser can parse general expressions, I don't see much benefit in
786;; generating a string of expression as base class "name".
787paren_class
788 : dotted_name
789 ;
790
791;;;****************************************************************************
792;;;@ test
793;;;****************************************************************************
794
795;; test: and_test ('or' and_test)* | lambdef
796test
797 : test_test
798 | lambdef
799 ;
800
801;; and_test ('or' and_test)*
802test_test
803 : and_test
804 | test_test OR and_test
805 ()
806 ;
807
808;; and_test: not_test ('and' not_test)*
809and_test
810 : not_test
811 | and_test AND not_test
812 ()
813 ;
814
815;; not_test: 'not' not_test | comparison
816not_test
817 : NOT not_test
818 ()
819 | comparison
820 ;
821
822;; comparison: expr (comp_op expr)*
823comparison
824 : expr
825 | comparison comp_op expr
826 ()
827 ;
828
829;; comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
830comp_op
831 : LT | GT | EQ | GE | LE | LTGT | NE | IN | NOT IN | IS | IS NOT
832 ;
833
834;; expr: xor_expr ('|' xor_expr)*
835expr
836 : xor_expr
837 | expr BAR xor_expr
838 ()
839 ;
840
841;; xor_expr: and_expr ('^' and_expr)*
842xor_expr
843 : and_expr
844 | xor_expr HAT and_expr
845 ()
846 ;
847
848;; and_expr: shift_expr ('&' shift_expr)*
849and_expr
850 : shift_expr
851 | and_expr AMP shift_expr
852 ()
853 ;
854
855;; shift_expr: arith_expr (('<<'|'>>') arith_expr)*
856shift_expr
857 : arith_expr
858 | shift_expr shift_expr_operators arith_expr
859 ()
860 ;
861
862;; ('<<'|'>>')
863shift_expr_operators
864 : LTLT
865 | GTGT
866 ;
867
868;; arith_expr: term (('+'|'-') term)*
869arith_expr
870 : term
871 | arith_expr plus_or_minus term
872 ()
873 ;
874
875;; ('+'|'-')
876plus_or_minus
877 : PLUS
878 | MINUS
879 ;
880
881;; term: factor (('*'|'/'|'%'|'//') factor)*
882term
883 : factor
884 | term term_operator factor
885 ()
886 ;
887
888term_operator
889 : MULT
890 | DIV
891 | MOD
892 | DIVDIV
893 ;
894
895;; factor: ('+'|'-'|'~') factor | power
896factor
897 : prefix_operators factor
898 ()
899 | power
900 ;
901
902;; ('+'|'-'|'~')
903prefix_operators
904 : PLUS
905 | MINUS
906 | TILDE
907 ;
908
909;; power: atom trailer* ('**' factor)*
910power
911 : atom trailer_zom exponent_zom
912 (concat $1
913 (if $2 (concat " " $2 " ") "")
914 (if $3 (concat " " $3) "")
915 )
916 ;
917
918trailer_zom
919 : ;;EMPTY
920 | trailer_zom trailer
921 ()
922 ;
923
924exponent_zom
925 : ;;EMPTY
926 | exponent_zom EXPONENT factor
927 ()
928 ;
929
930;; trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
931trailer
932 : PAREN_BLOCK
933 ()
934 | BRACK_BLOCK
935 ()
936 | PERIOD NAME
937 ()
938 ;
939
940;; atom: '(' [testlist] ')' | '[' [listmaker] ']' | '{' [dictmaker] '}'
941;; | '`' testlist '`' | NAME | NUMBER | STRING+
942atom
943 : PAREN_BLOCK
944 ()
945 | BRACK_BLOCK
946 ()
947 | BRACE_BLOCK
948 ()
949 | BACKQUOTE testlist BACKQUOTE
950 ()
951 | NAME
952 | NUMBER_LITERAL
953 | one_or_more_string
954 ;
955
956test_list_opt
957 : ;;EMPTY
958 | testlist
959 ()
960 ;
961
962;; testlist: test (',' test)* [',']
963testlist
964 : comma_sep_test_list comma_opt
965 ;
966
967;; test (',' test)*
968comma_sep_test_list
969 : test
970 | comma_sep_test_list COMMA test
971 (format "%s, %s" $1 $3)
972 ;
973
974;; (read $1) and (read $2) were done before to peel away the double quotes.
975;; However that does not work for single quotes, so it was taken out.
976one_or_more_string
977 : STRING_LITERAL
978 | one_or_more_string STRING_LITERAL
979 (concat $1 $2)
980 ;
981
982;;;****************************************************************************
983;;;@ lambdef
984;;;****************************************************************************
985
986;; lambdef: 'lambda' [varargslist] ':' test
987lambdef
988 : LAMBDA varargslist_opt COLON test
989 (format "%s %s" $1 (or $2 ""))
990 ;
991
992;; [varargslist]
993varargslist_opt
994 : ;;EMPTY
995 | varargslist
996 ;
997
998;; varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] | '**' NAME)
999;; | fpdef ['=' test] (',' fpdef ['=' test])* [',']
1000varargslist
1001 : fpdef_opt_test_list_comma_zom rest_args
1002 (nconc $2 $1)
1003 | fpdef_opt_test_list comma_opt
1004 ;
1005
1006;; ('*' NAME [',' '**' NAME] | '**' NAME)
1007rest_args
1008 : MULT NAME multmult_name_opt
1009 () ;;(VARIABLE-TAG $2 nil nil)
1010 | EXPONENT NAME
1011 () ;;(VARIABLE-TAG $2 nil nil)
1012 ;
1013
1014;; [',' '**' NAME]
1015multmult_name_opt
1016 : ;;EMPTY
1017 | COMMA EXPONENT NAME
1018 (VARIABLE-TAG $3 nil nil)
1019 ;
1020
1021fpdef_opt_test_list_comma_zom
1022 : ;;EMPTY
1023 | fpdef_opt_test_list_comma_zom fpdef_opt_test COMMA
1024 (nconc $2 $1)
1025 ;
1026
1027;; fpdef ['=' test] (',' fpdef ['=' test])*
1028fpdef_opt_test_list
1029 : fpdef_opt_test
1030 | fpdef_opt_test_list COMMA fpdef_opt_test
1031 (nconc $3 $1)
1032 ;
1033
1034;; fpdef ['=' test]
1035fpdef_opt_test
1036 : fpdef eq_test_opt
1037 ;
1038
1039;; fpdef: NAME | '(' fplist ')'
1040fpdef
1041 : NAME
1042 (VARIABLE-TAG $1 nil nil)
1043 ;; Below breaks the parser. Don't know why, but my guess is that
1044 ;; LPAREN/RPAREN clashes with the ones in function_parameters.
1045 ;; | LPAREN fplist RPAREN
1046 ;; (identity $2)
1047 ;
1048
1049;; fplist: fpdef (',' fpdef)* [',']
1050fplist
1051 : fpdef_list comma_opt
1052 ;
1053
1054;; fpdef (',' fpdef)*
1055fpdef_list
1056 : fpdef
1057 | fpdef_list COMMA fpdef
1058 ;
1059
1060;; ['=' test]
1061eq_test_opt
1062 : ;;EMPTY
1063 | ASSIGN test
1064 ()
1065 ;
1066
1067;;;****************************************************************************
1068;;;@ Misc
1069;;;****************************************************************************
1070
1071;; [',']
1072comma_opt
1073 : ;;EMPTY
1074 | COMMA
1075 ;
1076
1077;; [';']
1078semicolon_opt
1079 : ;;EMPTY
1080 | SEMICOLON
1081 ;
1082
1083;;; semantic/wisent/python.wy ends here