Commit | Line | Data |
---|---|---|
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 | |
272 | goal | |
273 | : NEWLINE | |
274 | | simple_stmt | |
275 | | compound_stmt | |
276 | ; | |
277 | ||
278 | ;;;**************************************************************************** | |
279 | ;;;@ simple_stmt | |
280 | ;;;**************************************************************************** | |
281 | ||
282 | ;; simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE | |
283 | simple_stmt | |
284 | : small_stmt_list semicolon_opt NEWLINE | |
285 | ; | |
286 | ||
287 | ;; small_stmt (';' small_stmt)* | |
288 | small_stmt_list | |
289 | : small_stmt | |
290 | | small_stmt_list SEMICOLON small_stmt | |
291 | ; | |
292 | ||
293 | small_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)+ [','] ] | |
311 | print_stmt | |
312 | : PRINT print_stmt_trailer | |
313 | (CODE-TAG $1 nil) | |
314 | ; | |
315 | ||
316 | ;; [ test (',' test)* [','] ] | '>>' test [ (',' test)+ [','] ] | |
317 | print_stmt_trailer | |
318 | : test_list_opt | |
319 | () | |
320 | | GTGT test trailing_test_list_with_opt_comma_opt | |
321 | () | |
322 | ; | |
323 | ||
324 | ;; [ (',' test)+ [','] ] | |
325 | trailing_test_list_with_opt_comma_opt | |
326 | : ;;EMPTY | |
327 | | trailing_test_list comma_opt | |
328 | () | |
329 | ; | |
330 | ||
331 | ;; (',' test)+ | |
332 | trailing_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)*) | |
344 | expr_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)*) | |
355 | expr_stmt_trailer | |
356 | : augassign testlist | |
357 | | eq_testlist_zom | |
358 | ; | |
359 | ||
360 | ;; Could be EMPTY! | |
361 | ;; ('=' testlist)* | |
362 | eq_testlist_zom | |
363 | : ;;EMPTY | |
364 | | eq_testlist_zom ASSIGN testlist | |
365 | (identity $3) | |
366 | ; | |
367 | ||
368 | ;; augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | |
369 | ;; | '<<=' | '>>=' | '**=' | '//=' | |
370 | augassign | |
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 | |
381 | del_stmt | |
382 | : DEL exprlist | |
383 | (CODE-TAG $1 nil) | |
384 | ; | |
385 | ||
386 | ;; exprlist: expr (',' expr)* [','] | |
387 | exprlist | |
388 | : expr_list comma_opt | |
389 | () | |
390 | ; | |
391 | ||
392 | ;; expr (',' expr)* | |
393 | expr_list | |
394 | : expr | |
395 | () | |
396 | | expr_list COMMA expr | |
397 | () | |
398 | ; | |
399 | ||
400 | ;;;============================================================================ | |
401 | ;;;@@ pass_stmt | |
402 | ;;;============================================================================ | |
403 | ||
404 | ;; pass_stmt: 'pass' | |
405 | pass_stmt | |
406 | : PASS | |
407 | (CODE-TAG $1 nil) | |
408 | ; | |
409 | ||
410 | ;;;============================================================================ | |
411 | ;;;@@ flow_stmt | |
412 | ;;;============================================================================ | |
413 | ||
414 | flow_stmt | |
415 | : break_stmt | |
416 | | continue_stmt | |
417 | | return_stmt | |
418 | | raise_stmt | |
419 | | yield_stmt | |
420 | ; | |
421 | ||
422 | ;; break_stmt: 'break' | |
423 | break_stmt | |
424 | : BREAK | |
425 | (CODE-TAG $1 nil) | |
426 | ; | |
427 | ||
428 | ;; continue_stmt: 'continue' | |
429 | continue_stmt | |
430 | : CONTINUE | |
431 | (CODE-TAG $1 nil) | |
432 | ; | |
433 | ||
434 | ;; return_stmt: 'return' [testlist] | |
435 | return_stmt | |
436 | : RETURN testlist_opt | |
437 | (CODE-TAG $1 nil) | |
438 | ; | |
439 | ||
440 | ;; [testlist] | |
441 | testlist_opt | |
442 | : ;;EMPTY | |
443 | | testlist | |
444 | () | |
445 | ; | |
446 | ||
447 | ;; yield_stmt: 'yield' testlist | |
448 | yield_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]]] | |
456 | raise_stmt | |
457 | : RAISE zero_one_two_or_three_tests | |
458 | (CODE-TAG $1 nil) | |
459 | ; | |
460 | ||
461 | ;; [test [',' test [',' test]]] | |
462 | zero_one_two_or_three_tests | |
463 | : ;;EMPTY | |
464 | | test zero_one_or_two_tests | |
465 | () | |
466 | ; | |
467 | ||
468 | ;; [',' test [',' test]] | |
469 | zero_one_or_two_tests | |
470 | : ;;EMPTY | |
471 | | COMMA test zero_or_one_comma_test | |
472 | () | |
473 | ; | |
474 | ||
475 | ;; [',' test] | |
476 | zero_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)*) | |
489 | import_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)* | |
497 | dotted_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)*) | |
503 | star_or_import_as_name_list | |
504 | : MULT | |
505 | () | |
506 | | import_as_name_list | |
507 | () | |
508 | ; | |
509 | ||
510 | ;; import_as_name (',' import_as_name)* | |
511 | import_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] | |
519 | import_as_name | |
520 | : NAME as_name_opt | |
521 | () | |
522 | ; | |
523 | ||
524 | ;; dotted_as_name: dotted_name [AS NAME] | |
525 | dotted_as_name | |
526 | : dotted_name as_name_opt | |
527 | ; | |
528 | ||
529 | ;; [AS NAME] | |
530 | as_name_opt | |
531 | : ;;EMPTY | |
532 | | AS NAME | |
533 | (identity $2) | |
534 | ; | |
535 | ||
536 | ;; dotted_name: NAME ('.' NAME)* | |
537 | dotted_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)* | |
548 | global_stmt | |
549 | : GLOBAL comma_sep_name_list | |
550 | (CODE-TAG $1 nil) | |
551 | ; | |
552 | ||
553 | ;; NAME (',' NAME)* | |
554 | comma_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]] | |
564 | exec_stmt | |
565 | : EXEC expr exec_trailer | |
566 | (CODE-TAG $1 nil) | |
567 | ; | |
568 | ||
569 | ;; ['in' test [',' test]] | |
570 | exec_trailer | |
571 | : ;;EMPTY | |
572 | | IN test comma_test_opt | |
573 | () | |
574 | ; | |
575 | ||
576 | ;; [',' test] | |
577 | comma_test_opt | |
578 | : ;;EMPTY | |
579 | | COMMA test | |
580 | () | |
581 | ; | |
582 | ||
583 | ;;;============================================================================ | |
584 | ;;;@@ assert_stmt | |
585 | ;;;============================================================================ | |
586 | ||
587 | ;; assert_stmt: 'assert' test [',' test] | |
588 | assert_stmt | |
589 | : ASSERT test comma_test_opt | |
590 | (CODE-TAG $1 nil) | |
591 | ; | |
592 | ||
593 | ;;;**************************************************************************** | |
594 | ;;;@ compound_stmt | |
595 | ;;;**************************************************************************** | |
596 | ||
597 | compound_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] | |
611 | if_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)* | |
617 | elif_suite_pair_list | |
618 | : ;;EMPTY | |
619 | | elif_suite_pair_list ELIF test COLON suite | |
620 | () | |
621 | ; | |
622 | ||
623 | ;; ['else' ':' suite] | |
624 | else_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 | |
632 | suite | |
633 | : simple_stmt | |
634 | (list $1) | |
635 | | NEWLINE indented_block | |
636 | (progn $2) | |
637 | ; | |
638 | ||
639 | indented_block | |
640 | : INDENT_BLOCK | |
641 | (EXPANDFULL $1 indented_block_body) | |
642 | ; | |
643 | ||
644 | indented_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] | |
658 | while_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] | |
668 | for_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) | |
679 | try_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)+ | |
687 | except_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]] | |
696 | except_clause | |
697 | : EXCEPT zero_one_or_two_test | |
698 | () | |
699 | ; | |
700 | ||
701 | ;; [test [',' test]] | |
702 | zero_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 | |
713 | funcdef | |
714 | : DEF NAME function_parameter_list COLON suite | |
715 | (FUNCTION-TAG $2 nil $3) | |
716 | ; | |
717 | ||
718 | function_parameter_list | |
719 | : PAREN_BLOCK | |
720 | (let ((wisent-python-EXPANDING-block t)) | |
721 | (EXPANDFULL $1 function_parameters)) | |
722 | ; | |
723 | ||
724 | ;; parameters: '(' [varargslist] ')' | |
725 | function_parameters | |
726 | : LPAREN | |
727 | () | |
728 | | RPAREN | |
729 | () | |
730 | | function_parameter COMMA | |
731 | | function_parameter RPAREN | |
732 | ; | |
733 | ||
734 | function_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 | |
749 | class_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 ')'] | |
758 | paren_class_list_opt | |
759 | : ;;EMPTY | |
760 | | paren_class_list | |
761 | ; | |
762 | ||
763 | paren_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] ')' | |
770 | paren_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". | |
787 | paren_class | |
788 | : dotted_name | |
789 | ; | |
790 | ||
791 | ;;;**************************************************************************** | |
792 | ;;;@ test | |
793 | ;;;**************************************************************************** | |
794 | ||
795 | ;; test: and_test ('or' and_test)* | lambdef | |
796 | test | |
797 | : test_test | |
798 | | lambdef | |
799 | ; | |
800 | ||
801 | ;; and_test ('or' and_test)* | |
802 | test_test | |
803 | : and_test | |
804 | | test_test OR and_test | |
805 | () | |
806 | ; | |
807 | ||
808 | ;; and_test: not_test ('and' not_test)* | |
809 | and_test | |
810 | : not_test | |
811 | | and_test AND not_test | |
812 | () | |
813 | ; | |
814 | ||
815 | ;; not_test: 'not' not_test | comparison | |
816 | not_test | |
817 | : NOT not_test | |
818 | () | |
819 | | comparison | |
820 | ; | |
821 | ||
822 | ;; comparison: expr (comp_op expr)* | |
823 | comparison | |
824 | : expr | |
825 | | comparison comp_op expr | |
826 | () | |
827 | ; | |
828 | ||
829 | ;; comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' | |
830 | comp_op | |
831 | : LT | GT | EQ | GE | LE | LTGT | NE | IN | NOT IN | IS | IS NOT | |
832 | ; | |
833 | ||
834 | ;; expr: xor_expr ('|' xor_expr)* | |
835 | expr | |
836 | : xor_expr | |
837 | | expr BAR xor_expr | |
838 | () | |
839 | ; | |
840 | ||
841 | ;; xor_expr: and_expr ('^' and_expr)* | |
842 | xor_expr | |
843 | : and_expr | |
844 | | xor_expr HAT and_expr | |
845 | () | |
846 | ; | |
847 | ||
848 | ;; and_expr: shift_expr ('&' shift_expr)* | |
849 | and_expr | |
850 | : shift_expr | |
851 | | and_expr AMP shift_expr | |
852 | () | |
853 | ; | |
854 | ||
855 | ;; shift_expr: arith_expr (('<<'|'>>') arith_expr)* | |
856 | shift_expr | |
857 | : arith_expr | |
858 | | shift_expr shift_expr_operators arith_expr | |
859 | () | |
860 | ; | |
861 | ||
862 | ;; ('<<'|'>>') | |
863 | shift_expr_operators | |
864 | : LTLT | |
865 | | GTGT | |
866 | ; | |
867 | ||
868 | ;; arith_expr: term (('+'|'-') term)* | |
869 | arith_expr | |
870 | : term | |
871 | | arith_expr plus_or_minus term | |
872 | () | |
873 | ; | |
874 | ||
875 | ;; ('+'|'-') | |
876 | plus_or_minus | |
877 | : PLUS | |
878 | | MINUS | |
879 | ; | |
880 | ||
881 | ;; term: factor (('*'|'/'|'%'|'//') factor)* | |
882 | term | |
883 | : factor | |
884 | | term term_operator factor | |
885 | () | |
886 | ; | |
887 | ||
888 | term_operator | |
889 | : MULT | |
890 | | DIV | |
891 | | MOD | |
892 | | DIVDIV | |
893 | ; | |
894 | ||
895 | ;; factor: ('+'|'-'|'~') factor | power | |
896 | factor | |
897 | : prefix_operators factor | |
898 | () | |
899 | | power | |
900 | ; | |
901 | ||
902 | ;; ('+'|'-'|'~') | |
903 | prefix_operators | |
904 | : PLUS | |
905 | | MINUS | |
906 | | TILDE | |
907 | ; | |
908 | ||
909 | ;; power: atom trailer* ('**' factor)* | |
910 | power | |
911 | : atom trailer_zom exponent_zom | |
912 | (concat $1 | |
913 | (if $2 (concat " " $2 " ") "") | |
914 | (if $3 (concat " " $3) "") | |
915 | ) | |
916 | ; | |
917 | ||
918 | trailer_zom | |
919 | : ;;EMPTY | |
920 | | trailer_zom trailer | |
921 | () | |
922 | ; | |
923 | ||
924 | exponent_zom | |
925 | : ;;EMPTY | |
926 | | exponent_zom EXPONENT factor | |
927 | () | |
928 | ; | |
929 | ||
930 | ;; trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME | |
931 | trailer | |
932 | : PAREN_BLOCK | |
933 | () | |
934 | | BRACK_BLOCK | |
935 | () | |
936 | | PERIOD NAME | |
937 | () | |
938 | ; | |
939 | ||
940 | ;; atom: '(' [testlist] ')' | '[' [listmaker] ']' | '{' [dictmaker] '}' | |
941 | ;; | '`' testlist '`' | NAME | NUMBER | STRING+ | |
942 | atom | |
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 | ||
956 | test_list_opt | |
957 | : ;;EMPTY | |
958 | | testlist | |
959 | () | |
960 | ; | |
961 | ||
962 | ;; testlist: test (',' test)* [','] | |
963 | testlist | |
964 | : comma_sep_test_list comma_opt | |
965 | ; | |
966 | ||
967 | ;; test (',' test)* | |
968 | comma_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. | |
976 | one_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 | |
987 | lambdef | |
988 | : LAMBDA varargslist_opt COLON test | |
989 | (format "%s %s" $1 (or $2 "")) | |
990 | ; | |
991 | ||
992 | ;; [varargslist] | |
993 | varargslist_opt | |
994 | : ;;EMPTY | |
995 | | varargslist | |
996 | ; | |
997 | ||
998 | ;; varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] | '**' NAME) | |
999 | ;; | fpdef ['=' test] (',' fpdef ['=' test])* [','] | |
1000 | varargslist | |
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) | |
1007 | rest_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] | |
1015 | multmult_name_opt | |
1016 | : ;;EMPTY | |
1017 | | COMMA EXPONENT NAME | |
1018 | (VARIABLE-TAG $3 nil nil) | |
1019 | ; | |
1020 | ||
1021 | fpdef_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])* | |
1028 | fpdef_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] | |
1035 | fpdef_opt_test | |
1036 | : fpdef eq_test_opt | |
1037 | ; | |
1038 | ||
1039 | ;; fpdef: NAME | '(' fplist ')' | |
1040 | fpdef | |
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)* [','] | |
1050 | fplist | |
1051 | : fpdef_list comma_opt | |
1052 | ; | |
1053 | ||
1054 | ;; fpdef (',' fpdef)* | |
1055 | fpdef_list | |
1056 | : fpdef | |
1057 | | fpdef_list COMMA fpdef | |
1058 | ; | |
1059 | ||
1060 | ;; ['=' test] | |
1061 | eq_test_opt | |
1062 | : ;;EMPTY | |
1063 | | ASSIGN test | |
1064 | () | |
1065 | ; | |
1066 | ||
1067 | ;;;**************************************************************************** | |
1068 | ;;;@ Misc | |
1069 | ;;;**************************************************************************** | |
1070 | ||
1071 | ;; [','] | |
1072 | comma_opt | |
1073 | : ;;EMPTY | |
1074 | | COMMA | |
1075 | ; | |
1076 | ||
1077 | ;; [';'] | |
1078 | semicolon_opt | |
1079 | : ;;EMPTY | |
1080 | | SEMICOLON | |
1081 | ; | |
1082 | ||
1083 | ;;; semantic/wisent/python.wy ends here |