Skip to content

Commit 3b34a8a

Browse files
committed
Working on a grammar
1 parent d70d7d4 commit 3b34a8a

File tree

1 file changed

+344
-1
lines changed
  • src/info/sansgills/mode/python/preproc

1 file changed

+344
-1
lines changed
Lines changed: 344 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,344 @@
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

Comments
 (0)