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