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