use strict; use warnings; use lib qw( t/lib ); use Test::More; use ANTLR::Runtime::Test; plan tests => 1; # The SimpleCalc grammar from the five minutes tutorial. g_test_output_is({ grammar => <<'GRAMMAR', test_program => <<'CODE', expected => <<'OUTPUT' }); grammar Expr; options { language = Perl5; } @header {} @members { my %memory; } prog: stat+ ; stat: expr NEWLINE { print "$expr.value\n"; } | ID '=' expr NEWLINE { $memory{$ID.text} = $expr.value; } | NEWLINE ; expr returns [value] : e=multExpr { $value = $e.value; } ( '+' e=multExpr { $value += $e.value; } | '-' e=multExpr { $value -= $e.value; } )* ; multExpr returns [value] : e=atom { $value = $e.value; } ('*' e=atom { $value *= $e.value; })* ; atom returns [value] : INT { $value = $INT.text; } | ID { my $v = $memory{$ID.text}; if (defined $v) { $value = $v; } else { print STDERR "undefined variable $ID.text\n"; } } | '(' expr ')' { $value = $expr.value; } ; ID : ('a'..'z'|'A'..'Z')+ ; INT : '0'..'9'+ ; NEWLINE:'\r'? '\n' ; WS : (' '|'\t')+ { $self->skip(); } ; GRAMMAR use strict; use warnings; use ANTLR::Runtime::ANTLRStringStream; use ANTLR::Runtime::CommonTokenStream; use ExprLexer; use ExprParser; my $in = << 'EOT'; 1 + 1 8 - 1 a = 10 b = 13 2 * a + b + 1 EOT my $input = ANTLR::Runtime::ANTLRStringStream->new({ input => $in }); my $lexer = ExprLexer->new({ input => $input }); my $tokens = ANTLR::Runtime::CommonTokenStream->new({ token_source => $lexer }); my $parser = ExprParser->new({ input => $tokens }); $parser->prog(); CODE 2 7 34 OUTPUT