SHOW:
|
|
- or go back to the newest paste.
1 | /* Grammar for Python | |
2 | ||
3 | -- Taken from https://docs.python.org/3/reference/grammar.html and converted | |
4 | with some simple find + replace to EBNF. | |
5 | ||
6 | There may still be bits that are not proper translations. | |
7 | ||
8 | This can be used to make a railroad diagram using this tool: http://bottlecaps.de/rr/ui | |
9 | */ | |
10 | ||
11 | single_input::= NEWLINE | simple_stmt | compound_stmt NEWLINE | |
12 | - | file_input::= (NEWLINE | stmt)* ENDMARKER |
12 | + | file_input::= (NEWLINE | stmt)* EOF |
13 | - | eval_input::= testlist NEWLINE* ENDMARKER |
13 | + | eval_input::= testlist NEWLINE* EOF |
14 | ||
15 | decorator::='@' dotted_name ( '(' (arglist)? ')' )? NEWLINE | |
16 | decorators::= decorator+ | |
17 | decorated::= decorators (classdef | funcdef) | |
18 | funcdef::= 'def' NAME parameters ('->' test)? ':' suite | |
19 | parameters::= '(' (typedargslist)? ')' | |
20 | typedargslist::= (tfpdef ('=' test)? (',' tfpdef ('=' test)?)* (',' | |
21 | ('*' (tfpdef)? (',' tfpdef ('=' test)?)* (',' '**' tfpdef)? | '**' tfpdef)?)? | |
22 | | '*' (tfpdef)? (',' tfpdef ('=' test)?)* (',' '**' tfpdef)? | '**' tfpdef) | |
23 | tfpdef::= NAME (':' test)? | |
24 | varargslist::= (vfpdef ('=' test)? (',' vfpdef ('=' test)?)* (',' | |
25 | ('*' (vfpdef)? (',' vfpdef ('=' test)?)* (',' '**' vfpdef)? | '**' vfpdef)?)? | |
26 | | '*' (vfpdef)? (',' vfpdef ('=' test)?)* (',' '**' vfpdef)? | '**' vfpdef) | |
27 | vfpdef::= NAME | |
28 | ||
29 | stmt::= simple_stmt | compound_stmt | |
30 | simple_stmt::= small_stmt (';' small_stmt)* (';')? NEWLINE | |
31 | small_stmt::= (expr_stmt | del_stmt | pass_stmt | flow_stmt | | |
32 | import_stmt | global_stmt | nonlocal_stmt | assert_stmt) | |
33 | expr_stmt::= testlist_star_expr (augassign (yield_expr|testlist) | | |
34 | ('=' (yield_expr|testlist_star_expr))*) | |
35 | testlist_star_expr::= (test|star_expr) (',' (test|star_expr))* (',')? | |
36 | augassign::= ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | | |
37 | '<<=' | '>>=' | '**=' | '//=') | |
38 | /* For normal assignments, additional restrictions enforced by the interpreter */ | |
39 | del_stmt::= 'del' exprlist | |
40 | pass_stmt::= 'pass' | |
41 | flow_stmt::= break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt | |
42 | break_stmt::= 'break' | |
43 | continue_stmt::= 'continue' | |
44 | return_stmt::= 'return' (testlist)? | |
45 | yield_stmt::= yield_expr | |
46 | raise_stmt::= 'raise' (test ('from' test)?)? | |
47 | import_stmt::= import_name | import_from | |
48 | import_name::= 'import' dotted_as_names | |
49 | /* note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSIS */ | |
50 | import_from::= ('from' (('.' | '...')* dotted_name | ('.' | '...')+) | |
51 | 'import' ('*' | '(' import_as_names ')' | import_as_names)) | |
52 | import_as_name::= NAME ('as' NAME)? | |
53 | dotted_as_name::= dotted_name ('as' NAME)? | |
54 | import_as_names::= import_as_name (',' import_as_name)* (',')? | |
55 | dotted_as_names::= dotted_as_name (',' dotted_as_name)* | |
56 | dotted_name::= NAME ('.' NAME)* | |
57 | global_stmt::= 'global' NAME (',' NAME)* | |
58 | nonlocal_stmt::= 'nonlocal' NAME (',' NAME)* | |
59 | assert_stmt::= 'assert' test (',' test)? | |
60 | ||
61 | compound_stmt::= if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated | |
62 | if_stmt::= 'if' test ':' suite ('elif' test ':' suite)* ('else' ':' suite)? | |
63 | while_stmt::= 'while' test ':' suite ('else' ':' suite)? | |
64 | for_stmt::= 'for' exprlist 'in' testlist ':' suite ('else' ':' suite)? | |
65 | try_stmt::= ('try' ':' suite | |
66 | ((except_clause ':' suite)+ | |
67 | ('else' ':' suite)? | |
68 | ('finally' ':' suite)? | | |
69 | 'finally' ':' suite)) | |
70 | with_stmt::= 'with' with_item (',' with_item)* ':' suite | |
71 | with_item::= test ('as' expr)? | |
72 | /* NB compile.c makes sure that the default except clause is last */ | |
73 | except_clause::= 'except' (test ('as' NAME)?)? | |
74 | suite::= simple_stmt | NEWLINE INDENT stmt+ DEDENT | |
75 | ||
76 | test::= or_test ('if' or_test 'else' test)? | lambdef | |
77 | test_nocond::= or_test | lambdef_nocond | |
78 | lambdef::= 'lambda' (varargslist)? ':' test | |
79 | lambdef_nocond::= 'lambda' (varargslist)? ':' test_nocond | |
80 | or_test::= and_test ('or' and_test)* | |
81 | and_test::= not_test ('and' not_test)* | |
82 | not_test::= 'not' not_test | comparison | |
83 | comparison::= expr (comp_op expr)* | |
84 | /* <> isn't actually a valid comparison operator in Python. It's here for the | |
85 | - | # sake of a __future__ import described in PEP 401 */ |
85 | + | sake of a __future__ import described in PEP 401 */ |
86 | comp_op::= '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' | |
87 | star_expr::= '*' expr | |
88 | expr::= xor_expr ('|' xor_expr)* | |
89 | xor_expr::= and_expr ('^' and_expr)* | |
90 | and_expr::= shift_expr ('&' shift_expr)* | |
91 | shift_expr::= arith_expr (('<<'|'>>') arith_expr)* | |
92 | arith_expr::= term (('+'|'-') term)* | |
93 | term::= factor (('*'|'/'|'%'|'//') factor)* | |
94 | factor::= ('+'|'-'|'~') factor | power | |
95 | power::= atom trailer* ('**' factor)? | |
96 | atom::= ('(' (yield_expr|testlist_comp)? ')' | | |
97 | '(' (testlist_comp)? ')?' | | |
98 | '{' (dictorsetmaker)? '}' | | |
99 | NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False') | |
100 | testlist_comp::= (test|star_expr) ( comp_for | (',' (test|star_expr))* (',')? ) | |
101 | trailer::= '(' (arglist)? ')' | '(' subscriptlist ')?' | '.' NAME | |
102 | subscriptlist::= subscript (',' subscript)* (',')? | |
103 | subscript::= test | (test)? ':' (test)? (sliceop)? | |
104 | sliceop::= ':' (test)? | |
105 | exprlist::= (expr|star_expr) (',' (expr|star_expr))* (',')? | |
106 | testlist::= test (',' test)* (',')? | |
107 | dictorsetmaker::= ( (test ':' test (comp_for | (',' test ':' test)* (',')?)) | | |
108 | (test (comp_for | (',' test)* (',')?)) ) | |
109 | ||
110 | classdef::= 'class' NAME ('(' (arglist)? ')')? ':' suite | |
111 | ||
112 | arglist::= (argument ',')* (argument (',')? | |
113 | |'*' test (',' argument)* (',' '**' test)? | |
114 | |'**' test) | |
115 | /* The reason that keywords are test nodes instead of NAME is that using NAME | |
116 | - | # results in an ambiguity. ast.c makes sure it's a NAME. */ |
116 | + | results in an ambiguity. ast.c makes sure it's a NAME. */ |
117 | argument::= test (comp_for)? | test '=' test | |
118 | /* Really (keyword '=')? test */ | |
119 | ||
120 | comp_iter::= comp_for | comp_if | |
121 | comp_for::= 'for' exprlist 'in' or_test (comp_iter)? | |
122 | comp_if::= 'if' test_nocond (comp_iter)? | |
123 | ||
124 | /* not used in grammar, but may appear in "node" passed from Parser to Compiler */ | |
125 | encoding_decl::= NAME | |
126 | ||
127 | yield_expr::= 'yield' (yield_arg)? | |
128 | yield_arg::= 'from' test | testlist | |
129 | - | NEWLINE::= 'a' |
129 | + | |
130 | - | NAME::= 'b' |
130 | + | NEWLINE::= '\n' |
131 | - | STRING::= 'c' |
131 | + | NAME::= '<name>' |
132 | - | ENDMARKER::= 'd' |
132 | + | STRING::= '"<string>"' |
133 | - | INDENT::= 'e' |
133 | + | INDENT::= '<ident>' |
134 | - | NUMBER::= 'f' |
134 | + | NUMBER::= '<number>' |