#!perl # Copyright 2012 Jeffrey Kegler # This file is part of Marpa::XS. Marpa::XS is free software: you can # redistribute it and/or modify it under the terms of the GNU Lesser # General Public License as published by the Free Software Foundation, # either version 3 of the License, or (at your option) any later version. # # Marpa::XS is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser # General Public License along with Marpa::XS. If not, see # http://www.gnu.org/licenses/. # Two rules which start with nullables, and cycle. use 5.010; use strict; use warnings; use Test::More tests => 10; use lib 'tool/lib'; use Marpa::XS::Test; BEGIN { Test::More::use_ok('Marpa::XS'); } ## no critic (Subroutines::RequireArgUnpacking) sub default_action { shift; my $v_count = scalar @_; return q{} if $v_count <= 0; my @vals = map { $_ // q{-} } @_; return $_[0] if scalar @vals == 1; return '(' . join( q{;}, @vals ) . ')'; } ## end sub default_action ## use critic my $grammar = Marpa::XS::Grammar->new( { start => 'S', strip => 0, rules => [ [ 'S', [qw/p p p n/], ], [ 'p', ['t'], ], [ 'p', [], ], [ 'n', ['t'], ], [ 'n', ['r2'], ], [ 'r2', [qw/a b c d e x/], ], [ 'a', [] ], [ 'b', [] ], [ 'c', [] ], [ 'd', [] ], [ 'e', [] ], [ 'a', ['t'] ], [ 'b', ['t'] ], [ 'c', ['t'] ], [ 'd', ['t'] ], [ 'e', ['t'] ], [ 'x', ['t'], ], ], terminals => ['t'], default_action => 'main::default_action', } ); $grammar->precompute(); # The count of results without an r2 production, the count # is C(n-1,3), when n>=4, 0 otherwise. # The count of results with an r2 productions is C(n-1,8). # Total results is the sum of the results with an # r2 production and those without. my @expected_count; $expected_count[1] = 2; # 1 w/o r2; 1 with an r2 $expected_count[2] = 11; # 3 w/o r2; 8 with an r2 $expected_count[3] = 31; # 3 w/o r2; 28 with an r2 $expected_count[4] = 57; # 1 w/o r2; 56 with an r2 $expected_count[5] = 70; # 0 w/o r2; 70 with an r2 $expected_count[6] = 56; # 0 w/o r2; 70 with an r2 $expected_count[7] = 28; # 0 w/o r2; 28 with an r2 $expected_count[8] = 8; # 0 w/o r2; 8 with an r2 $expected_count[9] = 1; # 0 w/o r2; 1 with an r2 for my $input_length ( 1 .. 9 ) { my $recce = Marpa::XS::Recognizer->new( { grammar => $grammar, max_parses => 100 } ); for ( 1 .. $input_length ) { $recce->read( 't', 't' ); } my $expected = 1; while ( $expected and my $value_ref = $recce->value() ) { $expected = 0; my $value = ${$value_ref}; if ($value =~ m{ \A [(] ((t|[-])[;]){3} (t|[-]) [)] \z }xms ) { $expected = 1; } ## end if ( $value =~ m{ ) (}) elsif ( $value =~ m{ \A [(] ((t|[-])[;]){3} [(] ((t|[-])[;]){5} (t|[-]) [)] [)] \z }xms ) { $expected = 1; } ## end elsif ( $value =~ m{ ) (}) $expected &&= $input_length == ( $value =~ tr/t/t/ ); if ( not $expected ) { Test::More::fail( qq{Unexpected value, length=$input_length, "$value"}); } } ## end while ( $expected and my $value_ref = $recce->value() ) if ($expected) { my $expected_count = $expected_count[$input_length]; my $parse_count = $recce->parse_count(); if ( $parse_count == $expected_count ) { Test::More::pass( qq{Good parse count $parse_count; input length=$input_length} ); } else { Test::More::fail( qq{Bad parse count $parse_count, expected $expected_count; input length=$input_length} ); } } ## end if ($expected) } ## end for my $input_length ( 1 .. 9 ) 1; # In case used as "do" file # Local Variables: # mode: cperl # cperl-indent-level: 4 # fill-column: 100 # End: # vim: expandtab shiftwidth=4: