88 lines
2.0 KiB
Perl
88 lines
2.0 KiB
Perl
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 SimpleCalc;
|
|
options { language = Perl5; }
|
|
|
|
tokens {
|
|
PLUS = '+' ;
|
|
MINUS = '-' ;
|
|
MULT = '*' ;
|
|
DIV = '/' ;
|
|
}
|
|
|
|
/*------------------------------------------------------------------
|
|
* PARSER RULES
|
|
*------------------------------------------------------------------*/
|
|
|
|
expr : term ( ( PLUS | MINUS ) term )* ;
|
|
|
|
term : factor ( ( MULT | DIV ) factor )* ;
|
|
|
|
factor : NUMBER ;
|
|
|
|
/*------------------------------------------------------------------
|
|
* LEXER RULES
|
|
*------------------------------------------------------------------*/
|
|
|
|
NUMBER : (DIGIT)+ ;
|
|
|
|
WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ { $channel = HIDDEN; } ;
|
|
|
|
fragment DIGIT : '0'..'9' ;
|
|
GRAMMAR
|
|
use strict;
|
|
use warnings;
|
|
|
|
use ANTLR::Runtime::ANTLRStringStream;
|
|
use ANTLR::Runtime::CommonTokenStream;
|
|
use ANTLR::Runtime::RecognitionException;
|
|
use SimpleCalcLexer;
|
|
use SimpleCalcParser;
|
|
|
|
my @examples = (
|
|
'1',
|
|
'1 + 1',
|
|
'1 +',
|
|
'1 * 2 + 3',
|
|
);
|
|
|
|
foreach my $example (@examples) {
|
|
my $input = ANTLR::Runtime::ANTLRStringStream->new({ input => $example });
|
|
my $lexer = SimpleCalcLexer->new({ input => $input });
|
|
my $tokens = ANTLR::Runtime::CommonTokenStream->new({ token_source => $lexer });
|
|
my $parser = SimpleCalcParser->new({ input => $tokens });
|
|
eval {
|
|
$parser->expr();
|
|
if ($parser->get_number_of_syntax_errors() == 0) {
|
|
print "$example: good\n";
|
|
}
|
|
else {
|
|
print "$example: bad\n";
|
|
}
|
|
};
|
|
if (my $ex = ANTLR::Runtime::RecognitionException->caught()) {
|
|
print "$example: error\n";
|
|
} elsif ($ex = Exception::Class->caught()) {
|
|
print "$example: error: $ex\n";
|
|
ref $ex ? $ex->rethrow() : die $ex;
|
|
}
|
|
}
|
|
CODE
|
|
1: good
|
|
1 + 1: good
|
|
1 +: bad
|
|
1 * 2 + 3: good
|
|
OUTPUT
|
|
|
|
__END__
|