MarpaX-ESLIF
view release on metacpan or search on metacpan
lib/MarpaX/ESLIF.pm view on Meta::CPAN
sub getResult { my ($self) = @_; $self->{result} }
sub setResult { my ($self, $result) = @_; $self->{result} = $result }
#
# Here the actions are writen in Perl, they all belong to the valuator namespace 'MyValue'
#
sub tonumber { shift; $_[0] }
sub e { shift; $_[1] }
sub power { shift; $_[0] ** $_[1] }
sub mul { shift; $_[0] * $_[1] }
sub div { shift; $_[0] / $_[1] }
sub plus { shift; $_[0] + $_[1] }
sub minus { shift; $_[0] - $_[1] }
1;
package main;
use Log::Any qw/$log/, default_adapter => qw/Stdout/;
use MarpaX::ESLIF;
use Test::More;
my %tests = (
1 => [ '1', 1 ],
2 => [ '1/2', 0.5 ],
3 => [ 'x', undef ],
4 => [ '(1*(2+3)/4**5)', 0.0048828125 ]
);
my $eslif = MarpaX::ESLIF->new($log);
my $g = MarpaX::ESLIF::Grammar->new($eslif, do { local $/; <DATA> });
foreach (sort { $a <=> $b} keys %tests) {
my ($input, $value) = @{$tests{$_}};
my $r = MyRecognizer->new($input);
my $v = MyValue::Perl->new();
if (defined($value)) {
ok($g->parse($r, $v), "'$input' parse is ok");
ok($v->getResult == $value, "'$input' value is $value");
} else {
ok(!$g->parse($r, $v), "'$input' parse is ko");
}
}
done_testing();
=head1 DESCRIPTION
ESLIF is derived from perl's L<Marpa::R2>, and has its own BNF, documented in L<MarpaX::ESLIF::BNF>.
The main features of this BNF are:
=over
=item Embedded Lua language
Actions can be writen directly in the grammar.
=item Regular expressions
Matching supports natively regular expression using the L<PCRE2|http://www.pcre.org/> library.
=item Streaming
Native support of streaming input.
=item Sub-grammars
The number of sub grammars is unlimited.
=back
Beginners might want to look at L<MarpaX::ESLIF::Introduction>.
=for test_synopsis BEGIN { die "SKIP: skip this pod, this is output from previous code\n"; }
In both cases, the output will be:
ok 1 - '1' parse is ok
ok 2 - '1' value is 1
ok 3 - '1/2' parse is ok
ok 4 - '1/2' value is 0.5
--------------------------------------------
Recognizer progress (grammar level 0 (Grammar level 0)):
[P1@0..0] exp ::= . exp[0]
[P2@0..0] exp[0] ::= . exp[1]
[P3@0..0] exp[1] ::= . exp[2]
[P4@0..0] exp[2] ::= . exp[3]
[P10@0..0] exp[3] ::= . /[\d]+/
[P11@0..0] exp[3] ::= . "("
[P11@0..0] exp[0]
[P11@0..0] ")"
[P13@0..0] exp[2] ::= . exp[3]
[P13@0..0] Internal[5]
[P13@0..0] exp[2]
[P15@0..0] exp[1] ::= . exp[1]
[P15@0..0] Internal[6]
[P15@0..0] exp[2]
[P17@0..0] exp[1] ::= . exp[1]
[P17@0..0] Internal[7]
[P17@0..0] exp[2]
[P19@0..0] exp[0] ::= . exp[0]
[P19@0..0] Internal[8]
[P19@0..0] exp[1]
[P21@0..0] exp[0] ::= . exp[0]
[P21@0..0] Internal[9]
[P21@0..0] exp[1]
Expected symbol: /[\d]+/ (symbol No 7)
Expected symbol: "(" (symbol No 8)
<<<<<< FAILURE AT LINE No 1 COLUMN No 1, HERE: >>>>>>
UTF-8 converted data after the failure (1 bytes) at 1:1:
0x000000: 78 x
--------------------------------------------
ok 5 - 'x' parse is ko
ok 6 - '(1*(2+3)/4**5)' parse is ok
ok 7 - '(1*(2+3)/4**5)' value is 0.0048828125
1..7
MarpaX::ESLIF also provide native JSON encoder/decoder:
use Log::Any qw/$log/, default_adapter => qw/Stdout/;
use MarpaX::ESLIF;
my $eslif = MarpaX::ESLIF->new($log);
my $json = MarpaX::ESLIF::JSON->new($eslif);
( run in 0.501 second using v1.01-cache-2.11-cpan-6aa56a78535 )