1
- // TODO
1
+ /*
2
+ * To change this template, choose Tools | Templates
3
+ * and open the template in the editor.
4
+ */
5
+
6
+ grammar PyPde2;
7
+
8
+ // some black magic
9
+ @lexer::members {
10
+ int bracket_nesting_level = 0 ;
11
+ int parenth_nesting_level = 0 ;
12
+ int curlybr_nesting_level = 0 ;
13
+
14
+ int previous_indent_level = 0 ;
15
+ int current_indent_level = 0 ;
16
+ }
17
+
18
+
19
+ script : (NEWLINE | statement)*;
20
+
21
+
22
+ // lexer!
23
+ // strings first, so they'll gobble things up first
24
+
25
+ STRING : STRINGPREFIX ? (SHORTSTRING | LONGSTRING );
26
+ fragment SHORTSTRING : ' \' ' (~(' \\ ' |' \n ' |' \' ' )|' \\ ' .)* ' \' '
27
+ | ' "' (~(' \\ ' |' \n ' |' "' )|' \\ ' .)* ' "' ;
28
+ fragment LONGSTRING : ' """' (~' \\ ' |' \\ ' .)* ' """'
29
+ | ' \'\'\' ' (~' \\ ' |' \\ ' .)* ' \'\'\' ' ;
30
+ fragment STRINGPREFIX : ' r' | ' u' | ' ur' | ' R' | ' U' | ' UR' | ' Ur' | ' uR'
31
+ | ' b' | ' B' | ' br' | ' Br' | ' bR' | ' BR' ;
32
+
33
+ // numbers!
34
+ IMAGINARY : (FLOAT | [0-9]+) [jJ];
35
+
36
+ FLOAT : POINTFLOAT | EXPFLOAT ;
37
+ fragment POINTFLOAT : [0-9]* (' .' [0-9]+) | [0-9]+ ' .' ;
38
+ fragment EXPFLOAT : (POINTFLOAT | [0-9]+) [eE] [+-] [0-9]+;
39
+
40
+ INTEGER : (DEC | OCT | HEX | BIN ) [lL]?; // not distinguishing between ints and longs, no need
41
+ fragment DEC : [1-9][0-9]* | ' 0' ;
42
+ fragment OCT : ' 0' [oO] [0-7]+ | ' 0' [0-7]+;
43
+ fragment HEX : ' 0' [xX] [0-9A-Fa-f]+;
44
+ fragment BIN : ' 0' [bB] [01]+;
45
+
46
+
47
+
48
+ // keywords!
49
+ AND : ' and' ;
50
+ DEL : ' del' ;
51
+ FROM : ' from' ;
52
+ NOT : ' not' ;
53
+ WHILE : ' while' ;
54
+ AS : ' as' ;
55
+ ELIF : ' elif' ;
56
+ GLOBAL : ' global' ;
57
+ OR : ' or' ;
58
+ WITH : ' with' ;
59
+ ASSERT : ' assert' ;
60
+ ELSE : ' else' ;
61
+ IF : ' if' ;
62
+ PASS : ' pass' ;
63
+ YIELD : ' yield' ;
64
+ BREAK : ' break' ;
65
+ EXCEPT : ' except' ;
66
+ IMPORT : ' import' ;
67
+ PRINT : ' print' ;
68
+ CLASS : ' class' ;
69
+ EXEC : ' exec' ;
70
+ IN : ' in' ;
71
+ RAISE : ' raise' ;
72
+ CONTINUE : ' continue' ;
73
+ FINALLY : ' finally' ;
74
+ IS : ' is' ;
75
+ RETURN : ' return' ;
76
+ DEF : ' def' ;
77
+ FOR : ' for' ;
78
+ LAMBDA : ' lambda' ;
79
+ TRY : ' try' ;
80
+
81
+
82
+
83
+ IDENTIFIER : [a-zA-Z_ ] [a-zA-Z0 -9_]*;
84
+
85
+ // logical vs. physical line nonsense
86
+ LPAREN : ' (' {parenth_nesting_level++;} ;
87
+ RPAREN : ' )' {parenth_nesting_level--;} ;
88
+ LCURLY : ' {' {curlybr_nesting_level++;} ;
89
+ RCURLY : ' }' {curlybr_nesting_level--;} ;
90
+ LBRACKET : ' [' {bracket_nesting_level++;} ;
91
+ RBRACKET : ' [' {bracket_nesting_level--;} ;
92
+
93
+ // we're inside a grouping, newlines don't count
94
+ IMPLICIT_ESCAPE_NEWLINE : {parenth_nesting_level > 0 ||
95
+ curlybr_nesting_level > 0 ||
96
+ bracket_nesting_level > 0 } ? (' \n ' | ' \r\n ' ) -> skip;
97
+ EXPLICIT_ESCAPE_NEWLINE : (' \\\n ' | ' \\\r\n ' ) -> skip; // explicit line joins
98
+
99
+
100
+ NEWLINE : (' \n ' | ' \r\n ' ) {current_indent_level = 0 ;} ; // above not true; these newlines count
101
+
102
+ COMMENT : ' #' (~' \n ' )* -> skip; // no need to keep these
103
+
104
+
105
+ WS : ' ' + -> skip;
106
+
107
+ // onto the parser
108
+ // atomic values: identifiers and literals (including enclodure literals
109
+ atom : identifier | literal | enclosure;
110
+
111
+ literal : STRING | INTEGER | IMAGINARY | FLOAT ;
112
+ identifier : IDENTIFIER ;
113
+ enclosure : parenth_form | generator_expression
114
+ | list_display | dict_display | set_display
115
+ | string_conversion | yield_atom;
116
+
117
+ parenth_form : ' (' expression_list ' )' ; // tuples
118
+
119
+ generator_expression : ' (' expression comp_for ' )' ;
120
+
121
+ list_display : ' [' (expression_list | list_comprehension)? ' ]' ; // lists; lotsa backwards compatibility cruft tho
122
+ list_comprehension : expression list_for;
123
+ list_for : FOR target_list IN old_expression_list (list_iter)?;
124
+ old_expression_list : old_expression ((' ,' old_expression)+ ' ,' ?)?;
125
+ old_expression : or_test | old_lambda_form;
126
+ list_iter : list_for | list_if;
127
+ list_if : IF old_expression list_iter?;
128
+
129
+ dict_display : ' {' (key_datum_list | dict_comprehension)? ' }' ; // dictionary
130
+ key_datum_list : key_datum (' ,' key_datum)* ' ,' ?;
131
+ key_datum : expression ' :' expression;
132
+ dict_comprehension : expression ' :' expression comp_for;
133
+
134
+ set_display : ' {' (expression_list | comprehension) ' }' ; // set
135
+
136
+ comprehension : expression comp_for; // elements of set and dictionary comprehensions
137
+ comp_for : FOR target_list IN or_test comp_iter?;
138
+ comp_iter : comp_for | comp_if;
139
+ comp_if : IF expression comp_iter?;
140
+
141
+ string_conversion : ' `' expression_list ' `' ;
142
+
143
+ yield_atom : ' (' yield_expression ' )' ;
144
+ yield_expression : YIELD expression_list?;
145
+
146
+
147
+ // primaries: most tightly bound operations
148
+
149
+ primary : primary ' .' identifier # AttributeRef
150
+ | primary ' [' expression_list ' ]' # Subscription
151
+ | primary ' [' short_slice ' ]' # ShortSlicing
152
+ | primary ' [' slice_list ' ]' # Slicing
153
+ | primary ' (' (argument_list ' ,' ? | expression comp_for)? ' )' # Call
154
+ | atom # PrimaryAtom
155
+ ;
156
+
157
+ // attributeref : primary '.' identifier;
158
+
159
+ // subscription : primary '[' expression_list ']'; //BLAH
160
+
161
+ // slicing : simple_slicing | extended_slicing;
162
+ // simple_slicing : primary '[' short_slice ']';
163
+ // extended_slicing : primary '[' slice_list ']';
164
+ slice_list : slice_item (' ,' slice_item)* ' ,' ?;
165
+ slice_item : expression | proper_slice | ' ...' ;
166
+ proper_slice : short_slice | long_slice;
167
+ short_slice : (expression)? ' :' (expression)?;
168
+ long_slice : short_slice ' :' (expression)?;
169
+
170
+ // call : primary '(' (argument_list ','? | expression comp_for)? ')';
171
+
172
+
173
+ argument_list : positional_arguments (' ,' keyword_arguments)?
174
+ (' ,' ' *' expression)? (' ,' keyword_arguments)?
175
+ (' ,' ' **' expression)?
176
+ | keyword_arguments (' ,' ' *' expression)?
177
+ (' ,' ' **' expression)?
178
+ | ' *' expression (' ,' ' *' expression)? (' ,' ' **' expression)?
179
+ | ' **' expression;
180
+ positional_arguments : expression (' ,' expression)*;
181
+ keyword_arguments : keyword_item (' ,' keyword_item)*;
182
+ keyword_item : identifier ' =' expression;
183
+
184
+
185
+
186
+ // operations
187
+ power : primary (' **' u_expr)?;
188
+ u_expr : power | ' -' u_expr | ' +' u_expr | ' ~' u_expr;
189
+ m_expr : u_expr | m_expr ' *' u_expr | m_expr ' //' u_expr | m_expr ' /' u_expr | m_expr ' %' u_expr;
190
+ a_expr : m_expr | a_expr ' +' m_expr | a_expr ' -' m_expr;
191
+ shift_expr : a_expr | shift_expr ( ' <<' | ' >>' ) a_expr;
192
+ and_expr : shift_expr | and_expr ' &' shift_expr;
193
+ xor_expr : and_expr | xor_expr ' ^' and_expr;
194
+ or_expr : xor_expr | or_expr ' |' xor_expr;
195
+ comparison : or_expr ( comp_operator or_expr )*;
196
+ comp_operator : ' <' | ' >' | ' ==' | ' >=' | ' <=' | ' <>' | ' !=' | IS (NOT )? | (NOT )? IN ;
197
+ or_test : and_test | or_test OR and_test;
198
+ and_test : not_test | and_test AND not_test;
199
+ not_test : comparison | NOT not_test;
200
+ conditional_expression : or_test (IF or_test ELSE expression)?;
201
+ lambda_form : LAMBDA (parameter_list)? ' :' expression;
202
+ old_lambda_form : LAMBDA (parameter_list)? ' :' old_expression;
203
+
204
+
205
+ // top level of expressions
206
+ expression : conditional_expression | lambda_form;
207
+
208
+ // handy
209
+ expression_list : expression ( ' ,' expression )* (' ,' )?;
210
+
211
+ // STATEMENTS
212
+ // simple statements
213
+ simple_stmt : expression_stmt
214
+ | assert_stmt
215
+ | assignment_stmt
216
+ | augmented_assignment_stmt
217
+ | pass_stmt
218
+ | del_stmt
219
+ | print_stmt
220
+ | return_stmt
221
+ | yield_stmt
222
+ | raise_stmt
223
+ | break_stmt
224
+ | continue_stmt
225
+ | import_stmt
226
+ | global_stmt
227
+ | exec_stmt;
228
+
229
+ expression_stmt : expression_list;
230
+
231
+ assignment_stmt : (target_list ' =' )+ expression_list | yield_expression;
232
+ target_list : target (' ,' target)* ' ,' ?;
233
+ target : identifier #TargetIdentifier // essentially a primary, but without atoms
234
+ | ' (' target_list ' )' #TargetTuple
235
+ | ' [' target_list ' ]' #TargetList
236
+ | target ' .' identifier # TargetAttributeRef
237
+ | target ' [' expression_list ' ]' # TargetSubscription
238
+ | target ' [' short_slice ' ]' #TargetShortSlicing
239
+ | target ' [' slice_list ' ]' # TargetLongSlicing
240
+ ;
241
+ // | attributeref
242
+ // | subscription
243
+ // | slicing ;
244
+
245
+ augmented_assignment_stmt : augtarget augop (expression_list | yield_expression);
246
+ augtarget : identifier # AugTargetIdentifier
247
+ | primary ' .' identifier # AugTargetAttributeRef
248
+ | primary ' [' expression_list ' ]' # AugTargetSubscription
249
+ | primary ' [' short_slice ' ]' #AugTargetShortSlicing
250
+ | primary ' [' slice_list ' ]' # AugTargetLongSlicing
251
+ ;
252
+ augop : ' +=' | ' -=' | ' *=' | ' /=' | ' //=' | ' %=' | ' **=' | ' >>=' | ' <<=' | ' &=' | ' ^=' | ' |=' ;
253
+
254
+
255
+ assert_stmt : ASSERT expression (' ,' expression)?;
256
+
257
+
258
+ pass_stmt : PASS ; // complicated stuff
259
+
260
+ del_stmt : DEL target_list;
261
+
262
+ print_stmt : PRINT ((expression (' ,' expression)* (' ,' )?)?
263
+ | ' >>' expression ((' ,' expression)+ (' ,' )?)?); // not sure what this is
264
+
265
+ return_stmt : RETURN expression_list?;
266
+
267
+ yield_stmt : YIELD yield_expression;
268
+
269
+ raise_stmt : RAISE (expression (expression (expression)?)?)?; // silly raise statement
270
+
271
+ break_stmt : BREAK ;
272
+
273
+ continue_stmt : CONTINUE ;
274
+
275
+ import_stmt : IMPORT module (AS name)? ( ' ,' module (AS name)? )*
276
+ | FROM relative_module IMPORT identifier (AS name)? ( ' ,' identifier (AS name)? )*
277
+ | FROM relative_module IMPORT ' (' identifier (AS name)? ( ' ,' identifier (AS name)? )* ' ,' ? ' )'
278
+ | FROM module IMPORT ' *' ;
279
+ module : (identifier ' .' )* identifier;
280
+ relative_module : ' .' * module | ' .' +;
281
+ name : identifier;
282
+
283
+ global_stmt : GLOBAL identifier (' ,' identifier)*;
284
+
285
+ exec_stmt : EXEC or_expr (IN expression (' ,' expression)?)?; // or_expr because expressions with lower precedence than '|' aren't allowed
286
+
287
+
288
+
289
+ // full statements
290
+ statement : (stmt_list NEWLINE | compound_stmt);
291
+ stmt_list : simple_stmt (' ;' simple_stmt)* ' ;' ?;
292
+
293
+
294
+
295
+ // compound statements
296
+ compound_stmt : if_stmt
297
+ | while_stmt
298
+ | for_stmt
299
+ | try_stmt
300
+ | with_stmt
301
+ | funcdef
302
+ | classdef
303
+ | decorated;
304
+
305
+ suite : stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT ;
306
+
307
+ if_stmt : IF expression ' :' suite
308
+ (ELIF expression ' :' suite)*
309
+ (ELSE ' :' suite)?;
310
+
311
+ while_stmt : WHILE expression ' :' suite
312
+ (ELSE ' :' suite)?;
313
+
314
+ for_stmt : FOR target_list IN expression_list ' :' suite
315
+ (ELSE ' :' suite)?;
316
+
317
+ try_stmt : ((TRY ' :' suite
318
+ (EXCEPT (expression ((AS | ' ,' ) target)? )? ' :' suite)+
319
+ (ELSE ' :' suite)?
320
+ (FINALLY ' :' suite)? )
321
+ |(TRY ' :' suite
322
+ FINALLY ' :' suite));
323
+
324
+ with_stmt : WITH with_item (' ,' with_item)* ' :' suite;
325
+ with_item : expression (AS target)?;
326
+
327
+ funcdef : DEF identifier ' (' parameter_list ' )' ' :' suite;
328
+ parameter_list : (defparameter ' ,' )*
329
+ (' *' identifier (' ,' ' **' identifier)?
330
+ |' **' identifier
331
+ |defparameter ' ,' ?);
332
+ defparameter : parameter (' =' expression)?;
333
+ parameter : identifier | ' (' parameter (' ,' parameter)* ' ,' ? ' )' ; // sublist
334
+
335
+ classdef : CLASS identifier (' (' expression_list ' )' )? ' :' suite;
336
+
337
+ decorated : decorator+ (classdef | funcdef);
338
+ decorator : ' @' identifier (' .' identifier)* (' (' (argument_list ' ,' ? )? ' )' )? NEWLINE ;
339
+
340
+
341
+
342
+
343
+
344
+
0 commit comments