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 )