root/livinglogic.python.xist/src/ll/UL4.g @ 5331:8564b72915cf

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

Remove ** syntax from UL4 dict literals.

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
234dict returns [node]
235    :
236        '{'
237        '}' { $node = ul4c.Dict() }
238    |
239        '{' { $node = ul4c.Dict() }
240        i1=dictitem { $node.items.append($i1.node) }
241        (
242            ','
243            i2=dictitem { $node.items.append($i2.node) }
244        )*
245        ','?
246        '}'
247    ;
248
249dictcomprehension returns [node]
250    @init
251    {
252        _condition = None;
253    }
254    :
255        '{'
256        key=expr1
257        ':'
258        value=expr1
259        'for'
260        n=nestedname
261        'in'
262        container=expr1
263        (
264            'if'
265            condition=expr1 { _condition = $condition.node; }
266        )?
267        '}' { $node = ul4c.DictComp($key.node, $value.node, $n.varname, $container.node, _condition) }
268    ;
269
270generatorexpression returns [node]
271    @init
272    {
273        _condition = None;
274    }
275    :
276        item=expr1
277        'for'
278        n=nestedname
279        'in'
280        container=expr1
281        (
282            'if'
283            condition=expr1 { _condition = $condition.node; }
284        )? { $node = ul4c.GenExpr($item.node, $n.varname, $container.node, _condition) }
285    ;
286
287atom returns [node]
288    : e_literal=literal { $node = $e_literal.node; }
289    | e_list=list { $node = $e_list.node; }
290    | e_listcomp=listcomprehension { $node = $e_listcomp.node; }
291    | e_dict=dict { $node = $e_dict.node; }
292    | e_dictcomp=dictcomprehension { $node = $e_dictcomp.node; }
293    | '(' e_genexpr=generatorexpression ')' { $node = $e_genexpr.node; }
294    | '(' e_bracket=expr1 ')' { $node = $e_bracket.node; }
295    ;
296
297/* For variable unpacking in assignments and for loops */
298nestedname returns [varname]
299    :
300        n=name { $varname = $n.text; }
301    |
302        '(' n0=nestedname ',' ')' { $varname = ($n0.varname,) }
303    |
304        '('
305        n1=nestedname
306        ','
307        n2=nestedname { $varname = ($n1.varname, $n2.varname) }
308        (
309            ','
310            n3=nestedname { $varname += ($n3.varname,) }
311        )*
312        ','?
313        ')'
314    ;
315
316/* Function/method call, attribute access, item access, slice access */
317expr9 returns [node]
318    @init
319    {
320        callmeth = False
321        index1 = None
322        index2 = None
323        slice = False
324    }
325    :
326        e1=atom { $node = $e1.node; }
327        (
328            /* Attribute access */
329            '.'
330            n=name { $node = ul4c.GetAttr($node, $n.text) }
331        |
332            /* Function/method call */
333            '(' { $node = ul4c.CallMeth($node.obj, $node.attrname) if isinstance($node, ul4c.GetAttr) else ul4c.CallFunc($node) }
334            (
335                /* No arguments */
336            |
337                /* "**" argument only */
338                '**' rkwargs=exprarg { $node.remkwargs = $rkwargs.node; }
339                ','?
340            |
341                /* "*" argument only (and maybe **) */
342                '*' rargs=exprarg { $node.remargs = $rargs.node; }
343                (
344                    ','
345                    '**' rkwargs=exprarg { $node.remkwargs = $rkwargs.node; }
346                )?
347                ','?
348            |
349                /* At least one positional argument */
350                a1=exprarg { $node.args.append($a1.node) }
351                (
352                    ','
353                    a2=exprarg { $node.args.append($a2.node) }
354                )*
355                (
356                    ','
357                    an3=name '=' av3=exprarg { $node.kwargs.append(($an3.text, $av3.node)) }
358                )*
359                (
360                    ','
361                    '*' rargs=exprarg { $node.remargs = $rargs.node; }
362                )?
363                (
364                    ','
365                    '**' rkwargs=exprarg { $node.remkwargs = $rkwargs.node; }
366                )?
367                ','?
368            |
369                /* Keyword arguments only */
370                an1=name '=' av1=exprarg { $node.kwargs.append(($an1.text, $av1.node)) }
371                (
372                    ','
373                    an2=name '=' av2=exprarg { $node.kwargs.append(($an2.text, $av2.node)) }
374                )*
375                (
376                    ','
377                    '*' rargs=exprarg { $node.remargs = $rargs.node; }
378                )?
379                (
380                    ','
381                    '**' rkwargs=exprarg { $node.remkwargs = $rkwargs.node; }
382                )?
383                ','?
384            )
385            ')'
386        |
387            /* Item/slice access */
388            '['
389            (
390                ':'
391                (
392                    e2=expr1 { index2 = $e2.node; }
393                )? { $node = ul4c.GetSlice($node, None, index2) }
394            |
395                e2=expr1 { index1 = $e2.node; }
396                (
397                    ':' { slice = True; }
398                    (
399                        e3=expr1 { index2 = $e3.node; }
400                    )?
401                )? { $node = ul4c.GetSlice($node, index1, index2) if slice else ul4c.GetItem($node, index1) }
402            )
403            ']'
404        )*
405    ;
406
407/* Negation */
408expr8 returns [node]
409    @init
410    {
411        count = 0;
412    }
413    :
414        (
415            '-' { count += 1; }
416        )*
417        e=expr9 {
418            $node = $e.node;
419            for i in range(count):
420                $node = ul4c.Neg.make($node);
421        }
422    ;
423
424/* Multiplication, division, modulo */
425expr7 returns [node]
426    :
427        e1=expr8 { $node = $e1.node; }
428        (
429            (
430                '*' { cls = ul4c.Mul; }
431            |
432                '/' { cls = ul4c.TrueDiv; }
433            |
434                '//' { cls = ul4c.FloorDiv; }
435            |
436                '%' { cls = ul4c.Mod; }
437            )
438            e2=expr8 { $node = cls.make($node, $e2.node) }
439        )*
440    ;
441
442/* Addition, substraction */
443expr6 returns [node]
444    :
445        e1=expr7 { $node = $e1.node; }
446        (
447            (
448                '+' { cls = ul4c.Add; }
449            |
450                '-' { cls = ul4c.Sub; }
451            )
452            e2=expr7 { $node = cls.make($node, $e2.node) }
453        )*
454    ;
455
456/* Comparisons */
457expr5 returns [node]
458    :
459        e1=expr6 { $node = $e1.node; }
460        (
461            (
462                '==' { cls = ul4c.EQ; }
463            |
464                '!=' { cls = ul4c.NE; }
465            |
466                '<' { cls = ul4c.LT; }
467            |
468                '<=' { cls = ul4c.LE; }
469            |
470                '>' { cls = ul4c.GT; }
471            |
472                '>=' { cls = ul4c.GE; }
473            )
474            e2=expr6 { $node = cls.make($node, $e2.node) }
475        )*
476    ;
477
478/* "in"/"not in" operator */
479expr4 returns [node]
480    :
481        e1=expr5 { $node = $e1.node; }
482        (
483            { cls = ul4c.Contains; }
484            (
485                'not' { cls = ul4c.NotContains; }
486            )?
487            'in'
488            e2=expr5 { $node = cls.make($node, $e2.node) }
489        )?
490    ;
491
492/* Not operator */
493expr3 returns [node]
494    :
495        'not'
496        e=expr4 { $node = ul4c.Not.make($e.node) }
497    |
498        e=expr4 { $node = $e.node; }
499    ;
500
501
502/* And operator */
503expr2 returns [node]
504    :
505        e1=expr3 { $node = $e1.node; }
506        (
507            'and'
508            e2=expr3 { $node = ul4c.And($node, $e2.node) }
509        )*
510    ;
511
512/* Or operator */
513expr1 returns [node]
514    :
515        e1=expr2 { $node = $e1.node; }
516        (
517            'or'
518            e2=expr2 { $node = ul4c.Or($node, $e2.node) }
519        )*
520    ;
521
522exprarg returns [node]
523    : ege=generatorexpression { $node = $ege.node; }
524    | e1=expr1 { $node = $e1.node; }
525    ;
526
527expression returns [node]
528    : ege=generatorexpression EOF { $node = $ege.node; }
529    | e=expr1 EOF { $node = $e.node; }
530    ;
531
532
533/* Additional rules for "for" tag */
534
535for_ returns [node]
536    :
537        n=nestedname
538        'in'
539        e=expr1 { $node = ul4c.For(self.location, $n.varname, $e.node) }
540        EOF
541    ;
542
543
544/* Additional rules for "code" tag */
545
546statement returns [node]
547    : nn=nestedname '=' e=expr1 EOF { $node = ul4c.StoreVar(self.location, $nn.varname, $e.node) }
548    | n=name '+=' e=expr1 EOF { $node = ul4c.AddVar(self.location, $n.text, $e.node) }
549    | n=name '-=' e=expr1 EOF { $node = ul4c.SubVar(self.location, $n.text, $e.node) }
550    | n=name '*=' e=expr1 EOF { $node = ul4c.MulVar(self.location, $n.text, $e.node) }
551    | n=name '/=' e=expr1 EOF { $node = ul4c.TrueDivVar(self.location, $n.text, $e.node) }
552    | n=name '//=' e=expr1 EOF { $node = ul4c.FloorDivVar(self.location, $n.text, $e.node) }
553    | n=name '%=' e=expr1 EOF { $node = ul4c.ModVar(self.location, $n.text, $e.node) }
554    | e=expression EOF { $node = $e.node }
555    ;
Note: See TracBrowser for help on using the browser.