1use strict;
2use warnings;
3
4use lib qw( t/lib );
5
6use Test::More;
7use ANTLR::Runtime::Test;
8
9plan tests => 1;
10
11# The SimpleCalc grammar from the five minutes tutorial.
12g_test_output_is({ grammar => <<'GRAMMAR', test_program => <<'CODE', expected => <<'OUTPUT' });
13grammar Expr;
14options { language = Perl5; }
15@header {}
16
17@members {
18    my %memory;
19}
20
21prog:   stat+ ;
22
23stat:   expr NEWLINE { print "$expr.value\n"; }
24    |   ID '=' expr NEWLINE
25        { $memory{$ID.text} = $expr.value; }
26    |   NEWLINE
27    ;
28
29expr returns [value]
30    :   e=multExpr { $value = $e.value; }
31        (   '+' e=multExpr { $value += $e.value; }
32        |   '-' e=multExpr { $value -= $e.value; }
33        )*
34    ;
35
36multExpr returns [value]
37    :   e=atom { $value = $e.value; } ('*' e=atom { $value *= $e.value; })*
38    ;
39
40atom returns [value]
41    :   INT { $value = $INT.text; }
42    |   ID
43        {
44            my $v = $memory{$ID.text};
45            if (defined $v) {
46                $value = $v;
47            } else {
48                print STDERR "undefined variable $ID.text\n";
49            }
50        }
51    |   '(' expr ')' { $value = $expr.value; }
52    ;
53
54ID  :   ('a'..'z'|'A'..'Z')+ ;
55INT :   '0'..'9'+ ;
56NEWLINE:'\r'? '\n' ;
57WS  :   (' '|'\t')+ { $self->skip(); } ;
58GRAMMAR
59use strict;
60use warnings;
61
62use ANTLR::Runtime::ANTLRStringStream;
63use ANTLR::Runtime::CommonTokenStream;
64use ExprLexer;
65use ExprParser;
66
67my $in = << 'EOT';
681 + 1
698 - 1
70a = 10
71b = 13
722 * a + b + 1
73EOT
74
75my $input = ANTLR::Runtime::ANTLRStringStream->new({ input => $in });
76my $lexer = ExprLexer->new({ input => $input });
77
78my $tokens = ANTLR::Runtime::CommonTokenStream->new({ token_source => $lexer });
79my $parser = ExprParser->new({ input => $tokens });
80$parser->prog();
81CODE
822
837
8434
85OUTPUT
86