1grammar Expr;
2
3options {
4    language = Perl5;
5}
6
7@header {
8}
9
10@members {
11    my %memory;
12}
13
14prog:   stat+ ;
15
16stat:   expr NEWLINE { print "$expr.value\n"; }
17    |   ID '=' expr NEWLINE
18        { $memory{$ID.text} = $expr.value; }
19    |   NEWLINE
20    ;
21
22expr returns [value]
23    :   e=multExpr { $value = $e.value; }
24        (   '+' e=multExpr { $value += $e.value; }
25        |   '-' e=multExpr { $value -= $e.value; }
26        )*
27    ;
28
29multExpr returns [value]
30    :   e=atom { $value = $e.value; } ('*' e=atom { $value *= $e.value; })*
31    ;
32
33atom returns [value]
34    :   INT { $value = $INT.text; }
35    |   ID
36        {
37            my $v = $memory{$ID.text};
38            if (defined $v) {
39                $value = $v;
40            } else {
41                print STDERR "undefined variable $ID.text\n";
42            }
43        }
44    |   '(' expr ')' { $value = $expr.value; }
45    ;
46
47ID  :   ('a'..'z'|'A'..'Z')+ ;
48INT :   '0'..'9'+ ;
49NEWLINE:'\r'? '\n' ;
50WS  :   (' '|'\t')+ { $self->skip(); } ;
51