]> git.madduck.net Git - etc/vim.git/blob - src/blib2to3/Grammar.txt

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Fix merging implicit multiline strings that have inline comments (#3956)
[etc/vim.git] / src / blib2to3 / Grammar.txt
1 # Grammar for 2to3. This grammar supports Python 2.x and 3.x.
2
3 # NOTE WELL: You should also follow all the steps listed at
4 # https://devguide.python.org/grammar/
5
6 # Start symbols for the grammar:
7 #       file_input is a module or sequence of commands read from an input file;
8 #       single_input is a single interactive statement;
9 #       eval_input is the input for the eval() and input() functions.
10 # NB: compound_stmt in single_input is followed by extra NEWLINE!
11 file_input: (NEWLINE | stmt)* ENDMARKER
12 single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
13 eval_input: testlist NEWLINE* ENDMARKER
14
15 typevar: NAME [':' expr]
16 paramspec: '**' NAME
17 typevartuple: '*' NAME
18 typeparam: typevar | paramspec | typevartuple
19 typeparams: '[' typeparam (',' typeparam)* [','] ']'
20
21 decorator: '@' namedexpr_test NEWLINE
22 decorators: decorator+
23 decorated: decorators (classdef | funcdef | async_funcdef)
24 async_funcdef: ASYNC funcdef
25 funcdef: 'def' NAME [typeparams] parameters ['->' test] ':' suite
26 parameters: '(' [typedargslist] ')'
27
28 # The following definition for typedarglist is equivalent to this set of rules:
29 #
30 #     arguments = argument (',' argument)*
31 #     argument = tfpdef ['=' test]
32 #     kwargs = '**' tname [',']
33 #     args = '*' [tname_star]
34 #     kwonly_kwargs = (',' argument)* [',' [kwargs]]
35 #     args_kwonly_kwargs = args kwonly_kwargs | kwargs
36 #     poskeyword_args_kwonly_kwargs = arguments [',' [args_kwonly_kwargs]]
37 #     typedargslist_no_posonly  = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs
38 #     typedarglist = arguments ',' '/' [',' [typedargslist_no_posonly]])|(typedargslist_no_posonly)"
39 #
40 # It needs to be fully expanded to allow our LL(1) parser to work on it.
41
42 typedargslist: tfpdef ['=' test] (',' tfpdef ['=' test])* ',' '/' [
43                      ',' [((tfpdef ['=' test] ',')* ('*' [tname_star] (',' tname ['=' test])*
44                             [',' ['**' tname [',']]] | '**' tname [','])
45                      | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])]
46                 ] | ((tfpdef ['=' test] ',')* ('*' [tname_star] (',' tname ['=' test])*
47                      [',' ['**' tname [',']]] | '**' tname [','])
48                      | tfpdef ['=' test] (',' tfpdef ['=' test])* [','])
49
50 tname: NAME [':' test]
51 tname_star: NAME [':' (test|star_expr)]
52 tfpdef: tname | '(' tfplist ')'
53 tfplist: tfpdef (',' tfpdef)* [',']
54
55 # The following definition for varargslist is equivalent to this set of rules:
56 #
57 #     arguments = argument (',' argument )*
58 #     argument = vfpdef ['=' test]
59 #     kwargs = '**' vname [',']
60 #     args = '*' [vname]
61 #     kwonly_kwargs = (',' argument )* [',' [kwargs]]
62 #     args_kwonly_kwargs = args kwonly_kwargs | kwargs
63 #     poskeyword_args_kwonly_kwargs = arguments [',' [args_kwonly_kwargs]]
64 #     vararglist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs
65 #     varargslist = arguments ',' '/' [','[(vararglist_no_posonly)]] | (vararglist_no_posonly)
66 #
67 # It needs to be fully expanded to allow our LL(1) parser to work on it.
68
69 varargslist: vfpdef ['=' test ](',' vfpdef ['=' test])* ',' '/' [',' [
70                      ((vfpdef ['=' test] ',')* ('*' [vname] (',' vname ['=' test])*
71                             [',' ['**' vname [',']]] | '**' vname [','])
72                             | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
73                      ]] | ((vfpdef ['=' test] ',')*
74                      ('*' [vname] (',' vname ['=' test])*  [',' ['**' vname [',']]]| '**' vname [','])
75                      | vfpdef ['=' test] (',' vfpdef ['=' test])* [','])
76
77 vname: NAME
78 vfpdef: vname | '(' vfplist ')'
79 vfplist: vfpdef (',' vfpdef)* [',']
80
81 stmt: simple_stmt | compound_stmt
82 simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
83 small_stmt: (type_stmt | expr_stmt | del_stmt | pass_stmt | flow_stmt |
84              import_stmt | global_stmt | assert_stmt)
85 expr_stmt: testlist_star_expr (annassign | augassign (yield_expr|testlist) |
86                      ('=' (yield_expr|testlist_star_expr))*)
87 annassign: ':' test ['=' (yield_expr|testlist_star_expr)]
88 testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
89 augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' |
90             '<<=' | '>>=' | '**=' | '//=')
91 # For normal and annotated assignments, additional restrictions enforced by the interpreter
92 del_stmt: 'del' exprlist
93 pass_stmt: 'pass'
94 flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt
95 break_stmt: 'break'
96 continue_stmt: 'continue'
97 return_stmt: 'return' [testlist_star_expr]
98 yield_stmt: yield_expr
99 raise_stmt: 'raise' [test ['from' test | ',' test [',' test]]]
100 import_stmt: import_name | import_from
101 import_name: 'import' dotted_as_names
102 import_from: ('from' ('.'* dotted_name | '.'+)
103               'import' ('*' | '(' import_as_names ')' | import_as_names))
104 import_as_name: NAME ['as' NAME]
105 dotted_as_name: dotted_name ['as' NAME]
106 import_as_names: import_as_name (',' import_as_name)* [',']
107 dotted_as_names: dotted_as_name (',' dotted_as_name)*
108 dotted_name: NAME ('.' NAME)*
109 global_stmt: ('global' | 'nonlocal') NAME (',' NAME)*
110 assert_stmt: 'assert' test [',' test]
111 type_stmt: "type" NAME [typeparams] '=' test
112
113 compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated | async_stmt | match_stmt
114 async_stmt: ASYNC (funcdef | with_stmt | for_stmt)
115 if_stmt: 'if' namedexpr_test ':' suite ('elif' namedexpr_test ':' suite)* ['else' ':' suite]
116 while_stmt: 'while' namedexpr_test ':' suite ['else' ':' suite]
117 for_stmt: 'for' exprlist 'in' testlist_star_expr ':' suite ['else' ':' suite]
118 try_stmt: ('try' ':' suite
119            ((except_clause ':' suite)+
120             ['else' ':' suite]
121             ['finally' ':' suite] |
122            'finally' ':' suite))
123 with_stmt: 'with' asexpr_test (',' asexpr_test)*  ':' suite
124
125 # NB compile.c makes sure that the default except clause is last
126 except_clause: 'except' ['*'] [test [(',' | 'as') test]]
127 suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
128
129 # Backward compatibility cruft to support:
130 # [ x for x in lambda: True, lambda: False if x() ]
131 # even while also allowing:
132 # lambda x: 5 if x else 2
133 # (But not a mix of the two)
134 testlist_safe: old_test [(',' old_test)+ [',']]
135 old_test: or_test | old_lambdef
136 old_lambdef: 'lambda' [varargslist] ':' old_test
137
138 namedexpr_test: asexpr_test [':=' asexpr_test]
139
140 # This is actually not a real rule, though since the parser is very
141 # limited in terms of the strategy about match/case rules, we are inserting
142 # a virtual case (<expr> as <expr>) as a valid expression. Unless a better
143 # approach is thought, the only side effect of this seem to be just allowing
144 # more stuff to be parser (which would fail on the ast).
145 asexpr_test: test ['as' test]
146
147 test: or_test ['if' or_test 'else' test] | lambdef
148 or_test: and_test ('or' and_test)*
149 and_test: not_test ('and' not_test)*
150 not_test: 'not' not_test | comparison
151 comparison: expr (comp_op expr)*
152 comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
153 star_expr: '*' expr
154 expr: xor_expr ('|' xor_expr)*
155 xor_expr: and_expr ('^' and_expr)*
156 and_expr: shift_expr ('&' shift_expr)*
157 shift_expr: arith_expr (('<<'|'>>') arith_expr)*
158 arith_expr: term (('+'|'-') term)*
159 term: factor (('*'|'@'|'/'|'%'|'//') factor)*
160 factor: ('+'|'-'|'~') factor | power
161 power: [AWAIT] atom trailer* ['**' factor]
162 atom: ('(' [yield_expr|testlist_gexp] ')' |
163        '[' [listmaker] ']' |
164        '{' [dictsetmaker] '}' |
165        '`' testlist1 '`' |
166        NAME | NUMBER | STRING+ | '.' '.' '.')
167 listmaker: (namedexpr_test|star_expr) ( old_comp_for | (',' (namedexpr_test|star_expr))* [','] )
168 testlist_gexp: (namedexpr_test|star_expr) ( old_comp_for | (',' (namedexpr_test|star_expr))* [','] )
169 lambdef: 'lambda' [varargslist] ':' test
170 trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
171 subscriptlist: (subscript|star_expr) (',' (subscript|star_expr))* [',']
172 subscript: test [':=' test] | [test] ':' [test] [sliceop]
173 sliceop: ':' [test]
174 exprlist: (expr|star_expr) (',' (expr|star_expr))* [',']
175 testlist: test (',' test)* [',']
176 dictsetmaker: ( ((test ':' asexpr_test | '**' expr)
177                  (comp_for | (',' (test ':' asexpr_test | '**' expr))* [','])) |
178                 ((test [':=' test] | star_expr)
179                  (comp_for | (',' (test [':=' test] | star_expr))* [','])) )
180
181 classdef: 'class' NAME [typeparams] ['(' [arglist] ')'] ':' suite
182
183 arglist: argument (',' argument)* [',']
184
185 # "test '=' test" is really "keyword '=' test", but we have no such token.
186 # These need to be in a single rule to avoid grammar that is ambiguous
187 # to our LL(1) parser. Even though 'test' includes '*expr' in star_expr,
188 # we explicitly match '*' here, too, to give it proper precedence.
189 # Illegal combinations and orderings are blocked in ast.c:
190 # multiple (test comp_for) arguments are blocked; keyword unpackings
191 # that precede iterable unpackings are blocked; etc.
192 argument: ( test [comp_for] |
193             test ':=' test [comp_for] |
194             test 'as' test |
195             test '=' asexpr_test |
196             '**' test |
197             '*' test )
198
199 comp_iter: comp_for | comp_if
200 comp_for: [ASYNC] 'for' exprlist 'in' or_test [comp_iter]
201 comp_if: 'if' old_test [comp_iter]
202
203 # As noted above, testlist_safe extends the syntax allowed in list
204 # comprehensions and generators. We can't use it indiscriminately in all
205 # derivations using a comp_for-like pattern because the testlist_safe derivation
206 # contains comma which clashes with trailing comma in arglist.
207 #
208 # This was an issue because the parser would not follow the correct derivation
209 # when parsing syntactically valid Python code. Since testlist_safe was created
210 # specifically to handle list comprehensions and generator expressions enclosed
211 # with parentheses, it's safe to only use it in those. That avoids the issue; we
212 # can parse code like set(x for x in [],).
213 #
214 # The syntax supported by this set of rules is not a valid Python 3 syntax,
215 # hence the prefix "old".
216 #
217 # See https://bugs.python.org/issue27494
218 old_comp_iter: old_comp_for | old_comp_if
219 old_comp_for: [ASYNC] 'for' exprlist 'in' testlist_safe [old_comp_iter]
220 old_comp_if: 'if' old_test [old_comp_iter]
221
222 testlist1: test (',' test)*
223
224 # not used in grammar, but may appear in "node" passed from Parser to Compiler
225 encoding_decl: NAME
226
227 yield_expr: 'yield' [yield_arg]
228 yield_arg: 'from' test | testlist_star_expr
229
230
231 # 3.10 match statement definition
232
233 # PS: normally the grammar is much much more restricted, but
234 # at this moment for not trying to bother much with encoding the
235 # exact same DSL in a LL(1) parser, we will just accept an expression
236 # and let the ast.parse() step of the safe mode to reject invalid
237 # grammar.
238
239 # The reason why it is more restricted is that, patterns are some
240 # sort of a DSL (more advanced than our LHS on assignments, but
241 # still in a very limited python subset). They are not really
242 # expressions, but who cares. If we can parse them, that is enough
243 # to reformat them.
244
245 match_stmt: "match" subject_expr ':' NEWLINE INDENT case_block+ DEDENT
246
247 # This is more permissive than the actual version. For example it
248 # accepts `match *something:`, even though single-item starred expressions
249 # are forbidden.
250 subject_expr: (namedexpr_test|star_expr) (',' (namedexpr_test|star_expr))* [',']
251
252 # cases
253 case_block: "case" patterns [guard] ':' suite
254 guard: 'if' namedexpr_test
255 patterns: pattern (',' pattern)* [',']
256 pattern: (expr|star_expr) ['as' expr]