root/livinglogic.python.xist/src/ll/UL4.g @ 5284:b6f2162b594d

Revision 5284:b6f2162b594d, 10.1 KB (checked in by Walter Doerwald <walter@…>, 7 years ago)

Make UL4 functions (and methods) real objects.

Line 
1grammar UL4;
2
3options
4{
5    language=Python;
6    backtrack=true;
7}
8
9@lexer::header
10{
11    from ll import ul4c
12}
13
14@header
15{
16    import datetime, ast
17    from ll import ul4c, color
18}
19
20@lexer::members {
21def reportError(self, e):
22   raise e
23}
24
25@members {
26def mismatch(self, input, ttype, follow):
27    raise MismatchedTokenException(ttype, input)
28
29def recoverFromMismatchedSet(self, input, e, follow):
30    raise e
31}
32
33@rulecatch {
34except RecognitionException as e:
35    raise
36}
37
38NONE
39    : 'None'
40    ;
41
42TRUE
43    : 'True'
44    ;
45
46FALSE
47    : 'False'
48    ;
49
50NAME
51    : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
52    ;
53
54fragment
55DIGIT
56    : '0'..'9'
57    ;
58
59fragment
60BIN_DIGIT
61    : ('0'|'1')
62    ;
63
64fragment
65OCT_DIGIT
66    : '0'..'7'
67    ;
68
69fragment
70HEX_DIGIT
71    : ('0'..'9'|'a'..'f'|'A'..'F')
72    ;
73
74/* We don't have negative ints (as this would lex "1-2" wrong) */
75INT
76    : DIGIT+
77    | '0' ('b'|'B') BIN_DIGIT+
78    | '0' ('o'|'O') OCT_DIGIT+
79    | '0' ('x'|'X') HEX_DIGIT+
80    ;
81
82fragment
83EXPONENT
84    : ('e'|'E') ('+'|'-')? DIGIT+
85    ;
86
87FLOAT
88    : DIGIT+ '.' DIGIT* EXPONENT?
89    | '.' DIGIT+ EXPONENT?
90    | DIGIT+ EXPONENT
91    ;
92
93fragment
94TIME
95    : DIGIT DIGIT ':' DIGIT DIGIT ( ':' DIGIT DIGIT ( '.' DIGIT DIGIT DIGIT DIGIT DIGIT DIGIT)?)?;
96
97DATE
98    : '@' '(' DIGIT DIGIT DIGIT DIGIT '-' DIGIT DIGIT '-' DIGIT DIGIT ('T' TIME?)? ')';
99
100COLOR
101    : '#' HEX_DIGIT HEX_DIGIT HEX_DIGIT
102    | '#' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
103    | '#' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
104    | '#' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
105    ;
106
107WS
108    : (' '|'\t'|'\r'|'\n') { $channel=HIDDEN; }
109    ;
110
111STRING
112    : '"' ( ESC_SEQ | ~('\\'|'"'|'\r'|'\n') )* '"'
113    | '\'' ( ESC_SEQ | ~('\\'|'\''|'\r'|'\n') )* '\''
114    ;
115
116fragment
117ESC_SEQ
118    : '\\' ('a'|'b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
119    | UNICODE1_ESC
120    | UNICODE2_ESC
121    | UNICODE4_ESC
122    ;
123
124fragment
125UNICODE1_ESC
126    : '\\' 'x' HEX_DIGIT HEX_DIGIT
127    ;
128
129fragment
130UNICODE2_ESC
131    : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
132    ;
133
134fragment
135UNICODE4_ESC
136    : '\\' 'U' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
137    ;
138
139
140/* Rules common to all tags */
141
142none returns [node]
143    : NONE { $node = ul4c.Const(None); }
144    ;
145
146true_ returns [node]
147    : TRUE { $node = ul4c.Const(True); }
148    ;
149
150false_ returns [node]
151    : FALSE { $node = ul4c.Const(False); }
152    ;
153
154int_ returns [node]
155    : INT { $node = ul4c.Const(int($INT.text, 0)); }
156    ;
157
158float_ returns [node]
159    : FLOAT { $node = ul4c.Const(float($FLOAT.text)); }
160    ;
161
162string returns [node]
163    : STRING { $node = ul4c.Const(ast.literal_eval($STRING.text)); }
164    ;
165
166date returns [node]
167    : DATE { $node = ul4c.Const(datetime.datetime(*map(int, [f for f in ul4c.datesplitter.split($DATE.text[2:-1]) if f]))); }
168    ;
169
170color returns [node]
171    : COLOR { $node = ul4c.Const(color.Color.fromrepr($COLOR.text)); }
172    ;
173
174name returns [node]
175    : NAME { $node = ul4c.Var($NAME.text); }
176    ;
177
178literal returns [node]
179    : e_none=none { $node = $e_none.node; }
180    | e_false=false_ { $node = $e_false.node; }
181    | e_true=true_ { $node = $e_true.node; }
182    | e_int=int_ { $node = $e_int.node; }
183    | e_float=float_ { $node = $e_float.node; }
184    | e_string=string { $node = $e_string.node; }
185    | e_date=date { $node = $e_date.node; }
186    | e_color=color { $node = $e_color.node; }
187    | e_name=name { $node = $e_name.node; }
188    ;
189
190/* List literals */
191list returns [node]
192    :
193        '['
194        ']' { $node = ul4c.List(); }
195    |
196        '[' {$node = ul4c.List(); }
197        e1=expr1 { $node.items.append($e1.node); }
198        (
199            ','
200            e2=expr1 { $node.items.append($e2.node); }
201        )*
202        ','?
203        ']'
204    ;
205
206listcomprehension returns [node]
207    @init
208    {
209        _condition = None;
210    }
211    :
212        '['
213        item=expr1
214        'for'
215        n=nestedname
216        'in'
217        container=expr1
218        (
219            'if'
220            condition=expr1 { _condition = $condition.node; }
221        )?
222        ']' { $node = ul4c.ListComp($item.node, $n.varname, $container.node, _condition); }
223    ;
224
225/* Dict literal */
226fragment
227dictitem returns [node]
228    :
229        k=expr1
230        ':'
231        v=expr1 { $node = ($k.node, $v.node); }
232    |
233        '**'
234        d=expr1 { $node = ($d.node,); }
235    ;
236
237dict returns [node]
238    :
239        '{'
240        '}' { $node = ul4c.Dict(); }
241    |
242        '{' { $node = ul4c.Dict(); }
243        i1=dictitem { $node.items.append($i1.node); }
244        (
245            ','
246            i2=dictitem { $node.items.append($i2.node); }
247        )*
248        ','?
249        '}'
250    ;
251
252dictcomprehension returns [node]
253    @init
254    {
255        _condition = None;
256    }
257    :
258        '{'
259        key=expr1
260        ':'
261        value=expr1
262        'for'
263        n=nestedname
264        'in'
265        container=expr1
266        (
267            'if'
268            condition=expr1 { _condition = $condition.node; }
269        )?
270        '}' { $node = ul4c.DictComp($key.node, $value.node, $n.varname, $container.node, _condition); }
271    ;
272
273generatorexpression returns [node]
274    @init
275    {
276        _condition = None;
277    }
278    :
279        item=expr1
280        'for'
281        n=nestedname
282        'in'
283        container=expr1
284        (
285            'if'
286            condition=expr1 { _condition = $condition.node; }
287        )? { $node = ul4c.GenExpr($item.node, $n.varname, $container.node, _condition); }
288    ;
289
290atom returns [node]
291    : e_literal=literal { $node = $e_literal.node; }
292    | e_list=list { $node = $e_list.node; }
293    | e_listcomp=listcomprehension { $node = $e_listcomp.node; }
294    | e_dict=dict { $node = $e_dict.node; }
295    | e_dictcomp=dictcomprehension { $node = $e_dictcomp.node; }
296    | '(' e_genexpr=generatorexpression ')' { $node = $e_genexpr.node; }
297    | '(' e_bracket=expr1 ')' { $node = $e_bracket.node; }
298    ;
299
300/* For variable unpacking in assignments and for loops */
301nestedname returns [varname]
302    :
303        n=name { $varname = $n.text; }
304    |
305        '(' n0=nestedname ',' ')' { $varname = ($n0.varname,); }
306    |
307        '('
308        n1=nestedname
309        ','
310        n2=nestedname { $varname = ($n1.varname, $n2.varname); }
311        (
312            ','
313            n3=nestedname { $varname += ($n3.varname,); }
314        )*
315        ','?
316        ')'
317    ;
318
319/* Function/method call, attribute access, item access, slice access */
320expr9 returns [node]
321    @init
322    {
323        callmeth = False
324        index1 = None
325        index2 = None
326        slice = False
327    }
328    :
329        e1=atom { $node = $e1.node; }
330        (
331            /* Attribute access */
332            '.'
333            n=name { $node = ul4c.GetAttr($node, $n.text); }
334        |
335            /* Function/method call */
336            '(' { $node = ul4c.CallMeth($node.obj, $node.attrname) if isinstance($node, ul4c.GetAttr) else ul4c.CallFunc($node); }
337            (
338                /* No arguments */
339            |
340                /* "**" argument only */
341                '**' rkwargs=exprarg { $node.remkwargs = $rkwargs.node; }
342                ','?
343            |
344                /* "*" argument only (and maybe **) */
345                '*' rargs=exprarg { $node.remargs = $rargs.node; }
346                (
347                    ','
348                    '**' rkwargs=exprarg { $node.remkwargs = $rkwargs.node; }
349                )?
350                ','?
351            |
352                /* At least one positional argument */
353                a1=exprarg { $node.args.append($a1.node); }
354                (
355                    ','
356                    a2=exprarg { $node.args.append($a2.node); }
357                )*
358                (
359                    ','
360                    an3=name '=' av3=exprarg { $node.kwargs.append(($an3.text, $av3.node)); }
361                )*
362                (
363                    ','
364                    '*' rargs=exprarg { $node.remargs = $rargs.node; }
365                )?
366                (
367                    ','
368                    '**' rkwargs=exprarg { $node.remkwargs = $rkwargs.node; }
369                )?
370                ','?
371            |
372                /* Keyword arguments only */
373                an1=name '=' av1=exprarg { $node.kwargs.append(($an1.text, $av1.node)); }
374                (
375                    ','
376                    an2=name '=' av2=exprarg { $node.kwargs.append(($an2.text, $av2.node)); }
377                )*
378                (
379                    ','
380                    '*' rargs=exprarg { $node.remargs = $rargs.node; }
381                )?
382                (
383                    ','
384                    '**' rkwargs=exprarg { $node.remkwargs = $rkwargs.node; }
385                )?
386                ','?
387            )
388            ')'
389        |
390            /* Item/slice access */
391            '['
392            (
393                ':'
394                (
395                    e2=expr1 { index2 = $e2.node; }
396                )? { $node = ul4c.GetSlice($node, None, index2); }
397            |
398                e2=expr1 { index1 = $e2.node; }
399                (
400                    ':' { slice = True; }
401                    (
402                        e3=expr1 { index2 = $e3.node; }
403                    )?
404                )? { $node = ul4c.GetSlice($node, index1, index2) if slice else ul4c.GetItem($node, index1); }
405            )
406            ']'
407        )*
408    ;
409
410/* Negation */
411expr8 returns [node]
412    @init
413    {
414        count = 0;
415    }
416    :
417        (
418            '-' { count += 1; }
419        )*
420        e=expr9 {
421            $node = $e.node;
422            for i in range(count):
423                $node = ul4c.Neg.make($node);
424        }
425    ;
426
427/* Multiplication, division, modulo */
428expr7 returns [node]
429    :
430        e1=expr8 { $node = $e1.node; }
431        (
432            (
433                '*' { cls = ul4c.Mul; }
434            |
435                '/' { cls = ul4c.TrueDiv; }
436            |
437                '//' { cls = ul4c.FloorDiv; }
438            |
439                '%' { cls = ul4c.Mod; }
440            )
441            e2=expr8 { $node = cls.make($node, $e2.node); }
442        )*
443    ;
444
445/* Addition, substraction */
446expr6 returns [node]
447    :
448        e1=expr7 { $node = $e1.node; }
449        (
450            (
451                '+' { cls = ul4c.Add; }
452            |
453                '-' { cls = ul4c.Sub; }
454            )
455            e2=expr7 { $node = cls.make($node, $e2.node) }
456        )*
457    ;
458
459/* Comparisons */
460expr5 returns [node]
461    :
462        e1=expr6 { $node = $e1.node; }
463        (
464            (
465                '==' { cls = ul4c.EQ; }
466            |
467                '!=' { cls = ul4c.NE; }
468            |
469                '<' { cls = ul4c.LT; }
470            |
471                '<=' { cls = ul4c.LE; }
472            |
473                '>' { cls = ul4c.GT; }
474            |
475                '>=' { cls = ul4c.GE; }
476            )
477            e2=expr6 { $node = cls.make($node, $e2.node); }
478        )*
479    ;
480
481/* "in"/"not in" operator */
482expr4 returns [node]
483    :
484        e1=expr5 { $node = $e1.node; }
485        (
486            { cls = ul4c.Contains; }
487            (
488                'not' { cls = ul4c.NotContains; }
489            )?
490            'in'
491            e2=expr5 { $node = cls.make($node, $e2.node); }
492        )?
493    ;
494
495/* Not operator */
496expr3 returns [node]
497    :
498        'not'
499        e=expr4 { $node = ul4c.Not.make($e.node); }
500    |
501        e=expr4 { $node = $e.node; }
502    ;
503
504
505/* And operator */
506expr2 returns [node]
507    :
508        e1=expr3 { $node = $e1.node; }
509        (
510            'and'
511            e2=expr3 { $node = ul4c.And.make($node, $e2.node); }
512        )*
513    ;
514
515/* Or operator */
516expr1 returns [node]
517    :
518        e1=expr2 { $node = $e1.node; }
519        (
520            'or'
521            e2=expr2 { $node = ul4c.Or.make($node, $e2.node); }
522        )*
523    ;
524
525exprarg returns [node]
526    : ege=generatorexpression { $node = $ege.node; }
527    | e1=expr1 { $node = $e1.node; }
528    ;
529
530expression returns [node]
531    : ege=generatorexpression EOF { $node = $ege.node; }
532    | e=expr1 EOF { $node = $e.node; }
533    ;
534
535
536/* Additional rules for "for" tag */
537
538for_ returns [node]
539    :
540        n=nestedname
541        'in'
542        e=expr1 { $node = ul4c.For(self.location, $n.varname, $e.node); }
543        EOF
544    ;
545
546
547/* Additional rules for "code" tag */
548
549statement returns [node]
550    : nn=nestedname '=' e=expr1 EOF { $node = ul4c.StoreVar(self.location, $nn.varname, $e.node); }
551    | n=name '+=' e=expr1 EOF { $node = ul4c.AddVar(self.location, $n.text, $e.node); }
552    | n=name '-=' e=expr1 EOF { $node = ul4c.SubVar(self.location, $n.text, $e.node); }
553    | n=name '*=' e=expr1 EOF { $node = ul4c.MulVar(self.location, $n.text, $e.node); }
554    | n=name '/=' e=expr1 EOF { $node = ul4c.TrueDivVar(self.location, $n.text, $e.node); }
555    | n=name '//=' e=expr1 EOF { $node = ul4c.FloorDivVar(self.location, $n.text, $e.node); }
556    | n=name '%=' e=expr1 EOF { $node = ul4c.ModVar(self.location, $n.text, $e.node); }
557    ;
Note: See TracBrowser for help on using the browser.