1*16467b97STreehugger Robotuse strict; 2*16467b97STreehugger Robotuse warnings; 3*16467b97STreehugger Robot 4*16467b97STreehugger Robotuse lib qw( t/lib ); 5*16467b97STreehugger Robot 6*16467b97STreehugger Robotuse Test::More; 7*16467b97STreehugger Robotuse ANTLR::Runtime::Test; 8*16467b97STreehugger Robot 9*16467b97STreehugger Robotplan tests => 1; 10*16467b97STreehugger Robot 11*16467b97STreehugger Robot# The SimpleCalc grammar from the five minutes tutorial. 12*16467b97STreehugger Robotg_test_output_is({ grammar => <<'GRAMMAR', test_program => <<'CODE', expected => <<'OUTPUT' }); 13*16467b97STreehugger Robotgrammar SimpleCalc; 14*16467b97STreehugger Robotoptions { language = Perl5; } 15*16467b97STreehugger Robot 16*16467b97STreehugger Robottokens { 17*16467b97STreehugger Robot PLUS = '+' ; 18*16467b97STreehugger Robot MINUS = '-' ; 19*16467b97STreehugger Robot MULT = '*' ; 20*16467b97STreehugger Robot DIV = '/' ; 21*16467b97STreehugger Robot} 22*16467b97STreehugger Robot 23*16467b97STreehugger Robot/*------------------------------------------------------------------ 24*16467b97STreehugger Robot * PARSER RULES 25*16467b97STreehugger Robot *------------------------------------------------------------------*/ 26*16467b97STreehugger Robot 27*16467b97STreehugger Robotexpr : term ( ( PLUS | MINUS ) term )* ; 28*16467b97STreehugger Robot 29*16467b97STreehugger Robotterm : factor ( ( MULT | DIV ) factor )* ; 30*16467b97STreehugger Robot 31*16467b97STreehugger Robotfactor : NUMBER ; 32*16467b97STreehugger Robot 33*16467b97STreehugger Robot/*------------------------------------------------------------------ 34*16467b97STreehugger Robot * LEXER RULES 35*16467b97STreehugger Robot *------------------------------------------------------------------*/ 36*16467b97STreehugger Robot 37*16467b97STreehugger RobotNUMBER : (DIGIT)+ ; 38*16467b97STreehugger Robot 39*16467b97STreehugger RobotWHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ { $channel = HIDDEN; } ; 40*16467b97STreehugger Robot 41*16467b97STreehugger Robotfragment DIGIT : '0'..'9' ; 42*16467b97STreehugger RobotGRAMMAR 43*16467b97STreehugger Robotuse strict; 44*16467b97STreehugger Robotuse warnings; 45*16467b97STreehugger Robot 46*16467b97STreehugger Robotuse ANTLR::Runtime::ANTLRStringStream; 47*16467b97STreehugger Robotuse ANTLR::Runtime::CommonTokenStream; 48*16467b97STreehugger Robotuse ANTLR::Runtime::RecognitionException; 49*16467b97STreehugger Robotuse SimpleCalcLexer; 50*16467b97STreehugger Robotuse SimpleCalcParser; 51*16467b97STreehugger Robot 52*16467b97STreehugger Robotmy @examples = ( 53*16467b97STreehugger Robot '1', 54*16467b97STreehugger Robot '1 + 1', 55*16467b97STreehugger Robot '1 +', 56*16467b97STreehugger Robot '1 * 2 + 3', 57*16467b97STreehugger Robot); 58*16467b97STreehugger Robot 59*16467b97STreehugger Robotforeach my $example (@examples) { 60*16467b97STreehugger Robot my $input = ANTLR::Runtime::ANTLRStringStream->new({ input => $example }); 61*16467b97STreehugger Robot my $lexer = SimpleCalcLexer->new({ input => $input }); 62*16467b97STreehugger Robot my $tokens = ANTLR::Runtime::CommonTokenStream->new({ token_source => $lexer }); 63*16467b97STreehugger Robot my $parser = SimpleCalcParser->new({ input => $tokens }); 64*16467b97STreehugger Robot eval { 65*16467b97STreehugger Robot $parser->expr(); 66*16467b97STreehugger Robot if ($parser->get_number_of_syntax_errors() == 0) { 67*16467b97STreehugger Robot print "$example: good\n"; 68*16467b97STreehugger Robot } 69*16467b97STreehugger Robot else { 70*16467b97STreehugger Robot print "$example: bad\n"; 71*16467b97STreehugger Robot } 72*16467b97STreehugger Robot }; 73*16467b97STreehugger Robot if (my $ex = ANTLR::Runtime::RecognitionException->caught()) { 74*16467b97STreehugger Robot print "$example: error\n"; 75*16467b97STreehugger Robot } elsif ($ex = Exception::Class->caught()) { 76*16467b97STreehugger Robot print "$example: error: $ex\n"; 77*16467b97STreehugger Robot ref $ex ? $ex->rethrow() : die $ex; 78*16467b97STreehugger Robot } 79*16467b97STreehugger Robot} 80*16467b97STreehugger RobotCODE 81*16467b97STreehugger Robot1: good 82*16467b97STreehugger Robot1 + 1: good 83*16467b97STreehugger Robot1 +: bad 84*16467b97STreehugger Robot1 * 2 + 3: good 85*16467b97STreehugger RobotOUTPUT 86*16467b97STreehugger Robot 87*16467b97STreehugger Robot__END__ 88