Parser-LR v20191119 Perl 5 v5.30.0 amd64-freebsd

Status
Fail
From
Nigel Horne
Dist
Parser-LR v20191119
Platform
Perl 5 v5.30.0 amd64-freebsd
Date
2019-11-18 22:59:21
ID
0ec7ceb8-0a57-11ea-80e7-b93663a9c918
This distribution has been tested as part of the CPAN Testers
project, supporting the Perl programming language.  See
http://wiki.cpantesters.org/ for more information or email
questions to cpan-testers-discuss@perl.org


--
Dear Philip R Brenan,

This is a computer-generated report for Parser-LR-20191119
on perl 5.30.0, created by CPAN-Reporter-1.2018.

Thank you for uploading your work to CPAN.  However, there was a problem
testing your distribution.

If you think this report is invalid, please consult the CPAN Testers Wiki
for suggestions on how to avoid getting FAIL reports for missing library
or binary dependencies, unsupported operating systems, and so on:

http://wiki.cpantesters.org/wiki/CPANAuthorNotes

Sections of this report:

    * Tester comments
    * Program output
    * Prerequisites
    * Environment and other context

------------------------------
TESTER COMMENTS
------------------------------

Additional comments from tester:

this report is from an automated smoke testing program
and was not reviewed by a human for accuracy

------------------------------
PROGRAM OUTPUT
------------------------------

Output from './Build test':

You tried to plan twice at (eval 77) line 1.
 at /var/tmp/build/Data-Table-Text-20191110-4/blib/lib/Data/Table/Text.pm line 3576, <DATA> line 506.
	Data::Table::Text::__ANON__("You tried to plan twice at (eval 77) line 1.\x{a}") called at /home/njh/perl5/perlbrew/perls/perl-5.30.0/lib/5.30.0/Test2/EventFacet/Trace.pm line 68
	Test2::EventFacet::Trace::throw(Test2::EventFacet::Trace=HASH(0x24f25c60), "You tried to plan twice") called at /home/njh/perl5/perlbrew/perls/perl-5.30.0/lib/5.30.0/Test2/API/Context.pm line 195
	Test2::API::Context::throw(Test2::API::Context=HASH(0x24f25bd0), "You tried to plan twice") called at /home/njh/perl5/perlbrew/perls/perl-5.30.0/lib/5.30.0/Test/Builder.pm line 460
	Test::Builder::plan(Test::Builder=HASH(0x244abf90), "tests", 24) called at /home/njh/perl5/perlbrew/perls/perl-5.30.0/lib/5.30.0/Test/Builder/Module.pm line 92
	Test::Builder::Module::import("tests", 24) called at (eval 77) line 1
	Parser::LR::BEGIN() called at (eval 77) line 1
	eval {...} called at (eval 77) line 1
	eval 'use Test::More tests => 24;

if (1) {
  my $g = compileGrammar(<<END, nosub=>1);
A  A + B
A  B
B  B * C
B  C
C  n
END

  my sub tlmr(@)
   {my $r = longestMatchingRule($g, @_);
    if ($r)
     {delete $r->{print} if $r;
      my %r = $r->%*;
      #say STDERR nws(dump(\\%r));
      }
    $r
   }

  is_deeply tlmr(qw(n)),     {expandable=>"C", expansion=>["n"],           rule=>4};
  is_deeply tlmr(qw(n + n)), {expandable=>"C", expansion=>["n"],           rule=>4};
  is_deeply tlmr(qw(A + B)), {expandable=>"A", expansion=>["A", "+", "B"], rule=>0};
  ok !tlmr(qw(n +));

  my sub trswr($@)
   {my ($rule, @stack) = @_;
    my @tree = (q()) x @stack;
    my $r = reduceStackWithRule($g->rules->[$rule], \\@stack, \\@tree);
    #say STDERR nws(dump(\\@stack));
    \\@stack
   }

  is_deeply trswr(0, qw(A + B)),   [qw(A)];
  is_deeply trswr(0, qw(n A + B)), [qw(n A)];
  is_deeply trswr(4, qw(B * n)),   [qw(B * C)];
  is_deeply trswr(3, qw(B * n)),   [qw(B * B)];                                 # There is no check that the rule actually applies

  my sub tpm(@)
   {my (@stack) = @_;
    my $r = partialMatch($g, @stack);
    $r
   }

  ok 3 == tpm qw(A + B);
  ok 2 == tpm qw(A +);
  ok 1 == tpm qw(A);
  ok 0 == tpm qw(A -);

  my sub tpwg(@)
   {my (@stack) = @_;
    my $r = parseWithGrammarAndLog($g, @stack) =~ s(\\s+\\Z) (\\n)gsr;;
    owf($logFile, $r);
    $r
   }

  ok tpwg(qw(n)) eq <<END;
Terminal: n, stack: (empty)
  Accept first terminal: n to get stack: n
  Reduced in finals by rule 4, expandable: C, stack: C
  Reduced in finals by rule 3, expandable: B, stack: B
  Reduced in finals by rule 1, expandable: A, stack: A
  Parse tree is:
   Rule  Expandable  Terminal
1     1  A
2     3    B
3     4      C
4                    n
END

  ok tpwg(qw(n + n)) eq <<END;
Terminal: n, stack: (empty)
  Accept first terminal: n to get stack: n
Terminal: +, stack: n
  Reduced by rule 4, expandable: C, stack: C
  Reduced by rule 3, expandable: B, stack: B
  Reduced by rule 1, expandable: A, stack: A
  Accept + after 3 reductions to get: A +
Terminal: n, stack: A +
Accepted terminal: n as is, stack: A + n
  Reduced in finals by rule 4, expandable: C, stack: A + C
  Reduced in finals by rule 3, expandable: B, stack: A + B
  Reduced in finals by rule 0, expandable: A, stack: A
  Parse tree is:
   Rule  Expandable  Terminal
1     0  A
2     1    A
3     3      B
4     4        C
5                    n
6                    +
7     3    B
8     4      C
9                    n
END

  ok tpwg(qw(n * n + n)) eq <<END;
Terminal: n, stack: (empty)
  Accept first terminal: n to get stack: n
Terminal: *, stack: n
  Reduced by rule 4, expandable: C, stack: C
  Reduced by rule 3, expandable: B, stack: B
  Accept * after 2 reductions to get: B *
Terminal: n, stack: B *
Accepted terminal: n as is, stack: B * n
Terminal: +, stack: B * n
  Reduced by rule 4, expandable: C, stack: B * C
  Reduced by rule 2, expandable: B, stack: B
  Reduced by rule 1, expandable: A, stack: A
  Accept + after 3 reductions to get: A +
Terminal: n, stack: A +
Accepted terminal: n as is, stack: A + n
  Reduced in finals by rule 4, expandable: C, stack: A + C
  Reduced in finals by rule 3, expandable: B, stack: A + B
  Reduced in finals by rule 0, expandable: A, stack: A
  Parse tree is:
    Rule  Expandable  Terminal
 1     0  A
 2     1    A
 3     2      B
 4     3        B
 5     4          C
 6                    n
 7                    *
 8     4        C
 9                    n
10                    +
11     3    B
12     4      C
13                    n
END

  ok tpwg(qw(n * n + n * n)) eq <<END;
Terminal: n, stack: (empty)
  Accept first terminal: n to get stack: n
Terminal: *, stack: n
  Reduced by rule 4, expandable: C, stack: C
  Reduced by rule 3, expandable: B, stack: B
  Accept * after 2 reductions to get: B *
Terminal: n, stack: B *
Accepted terminal: n as is, stack: B * n
Terminal: +, stack: B * n
  Reduced by rule 4, expandable: C, stack: B * C
  Reduced by rule 2, expandable: B, stack: B
  Reduced by rule 1, expandable: A, stack: A
  Accept + after 3 reductions to get: A +
Terminal: n, stack: A +
Accepted terminal: n as is, stack: A + n
Terminal: *, stack: A + n
  Reduced by rule 4, expandable: C, stack: A + C
  Reduced by rule 3, expandable: B, stack: A + B
  Accept * after 2 reductions to get: A + B *
Terminal: n, stack: A + B *
Accepted terminal: n as is, stack: A + B * n
  Reduced in finals by rule 4, expandable: C, stack: A + B * C
  Reduced in finals by rule 2, expandable: B, stack: A + B
  Reduced in finals by rule 0, expandable: A, stack: A
  Parse tree is:
    Rule  Expandable  Terminal
 1     0  A
 2     1    A
 3     2      B
 4     3        B
 5     4          C
 6                    n
 7                    *
 8     4        C
 9                    n
10                    +
11     2    B
12     3      B
13     4        C
14                    n
15                    *
16     4      C
17                    n
END

  ok tpwg(qw(n + n * n + n)) eq <<END;
Terminal: n, stack: (empty)
  Accept first terminal: n to get stack: n
Terminal: +, stack: n
  Reduced by rule 4, expandable: C, stack: C
  Reduced by rule 3, expandable: B, stack: B
  Reduced by rule 1, expandable: A, stack: A
  Accept + after 3 reductions to get: A +
Terminal: n, stack: A +
Accepted terminal: n as is, stack: A + n
Terminal: *, stack: A + n
  Reduced by rule 4, expandable: C, stack: A + C
  Reduced by rule 3, expandable: B, stack: A + B
  Accept * after 2 reductions to get: A + B *
Terminal: n, stack: A + B *
Accepted terminal: n as is, stack: A + B * n
Terminal: +, stack: A + B * n
  Reduced by rule 4, expandable: C, stack: A + B * C
  Reduced by rule 2, expandable: B, stack: A + B
  Reduced by rule 0, expandable: A, stack: A
  Accept + after 3 reductions to get: A +
Terminal: n, stack: A +
Accepted terminal: n as is, stack: A + n
  Reduced in finals by rule 4, expandable: C, stack: A + C
  Reduced in finals by rule 3, expandable: B, stack: A + B
  Reduced in finals by rule 0, expandable: A, stack: A
  Parse tree is:
    Rule  Expandable  Terminal
 1     0  A
 2     0    A
 3     1      A
 4     3        B
 5     4          C
 6                    n
 7                    +
 8     2      B
 9     3        B
10     4          C
11                    n
12                    *
13     4        C
14                    n
15                    +
16     3    B
17     4      C
18                    n
END
 }

if (1) {
  my $grammar = compileGrammar(<<END, nosub=>1);
A  A + B
A  B
B  B * C
B  C
C  n
END

  my $tree = parseWithGrammar($grammar, qw(n * n + n * n));
  ok printParseTree($grammar, $tree) eq <<END;
    Rule  Expandable  Terminal
 1     0  A
 2     1    A
 3     2      B
 4     3        B
 5     4          C
 6                    n
 7                    *
 8     4        C
 9                    n
10                    +
11     2    B
12     3      B
13     4        C
14                    n
15                    *
16     4      C
17                    n
END
 }

if (1) {
  my $grammar = compileGrammar(<<END, nosub=>1);
A  A plus B
A  B
B  B times C
B  C
C  value
END

  my $tree = parseWithGrammar($grammar, qw(value times value plus value times value));

  ok printParseTreeAsXml($grammar, $tree) eq <<END;
<A rule="0">
  <A rule="1">
    <B rule="2">
      <B rule="3">
        <C rule="4">
          <value pos="0"/>
        </C>
      </B>
      <times pos="1"/>
      <C rule="4">
        <value pos="2"/>
      </C>
    </B>
  </A>
  <plus pos="3"/>
  <B rule="2">
    <B rule="3">
      <C rule="4">
        <value pos="4"/>
      </C>
    </B>
    <times pos="5"/>
    <C rule="4">
      <value pos="6"/>
    </C>
  </B>
</A>
END
 }

if (1) {
  my $grammar = compileGrammar(<<END, nosub=>1);
A  A + B
A  B
B  B * C
B  C
C  n
C  ( A )
C  [ A ]
END

  my $tree = parseWithGrammar $grammar, qw/ n * ( n + ( n * [ n ] ) )/, subsitute=>0;

  ok printParseTree($grammar, $tree) eq <<END;
    Rule  Expandable               Terminal
 1     1  A
 2     2    B
 3     3      B
 4     4        C
 5                                 n
 6                                 *
 7     5      C
 8                                 (
 9     0        A
10     1          A
11     3            B
12     4              C
13                                 n
14                                 +
15     3          B
16     5            C
17                                 (
18     1              A
19     2                B
20     3                  B
21     4                    C
22                                 n
23                                 *
24     6                  C
25                                 [
26     1                    A
27     3                      B
28     4                        C
29                                 n
30                                 ]
31                                 )
32                                 )
END
 }

if (1) {                                                                        #TcompileGrammar  #TprintGrammar  #TparseWithGrammar #TprintParseTree #TprintParseTreeAsXml
  my $grammar = compileGrammar(<<END);
A  A + B
A  B
B  B * C
B  C
C  n
C  ( A )
C  [ A ]
C  { A }
C  ( )
C  [ ]
C  { }
END

  ok printGrammar($grammar) eq <<END;
    Rule  Symbol  Expansion
 1     0  A       A          +  B
 2     1  A       B
 3     2  B       B          *  n
 4     3  B       B          *  (  A  )
 5     4  B       B          *  [  A  ]
 6     5  B       B          *  {  A  }
 7     6  B       B          *  (  )
 8     7  B       B          *  [  ]
 9     8  B       B          *  {  }
10     9  B       n
11    10  B       (          A  )
12    11  B       [          A  ]
13    12  B       {          A  }
14    13  B       (          )
15    14  B       [          ]
16    15  B       {          }
END

  my $tree = parseWithGrammar($grammar, qw/( [ { }  ]  +  [ { n }  ] ) * [ n + n ]  /);

  ok printParseTree($grammar, $tree) eq <<END;
    Rule  Expandable         Terminal
 1     1  A
 2     4    B
 3    10      B
 4                           (
 5     0        A
 6     1          A
 7    11            B
 8                           [
 9     1              A
10    15                B
11                           {
12                           }
13                           ]
14                           +
15    11          B
16                           [
17     1            A
18    12              B
19                           {
20     1                A
21     9                  B
22                           n
23                           }
24                           ]
25                           )
26                           *
27                           [
28     0      A
29     1        A
30     9          B
31                           n
32                           +
33     9        B
34                           n
35                           ]
END

  ok printParseTreeAsXml($grammar, $tree) eq <<END;
<A rule="1">
  <B rule="4">
    <B rule="10">
      <"(" pos="0"/>
      <A rule="0">
        <A rule="1">
          <B rule="11">
            <"[" pos="1"/>
            <A rule="1">
              <B rule="15">
                <"{" pos="2"/>
                <"}" pos="3"/>
              </B>
            </A>
            <"]" pos="4"/>
          </B>
        </A>
        <"+" pos="5"/>
        <B rule="11">
          <"[" pos="6"/>
          <A rule="1">
            <B rule="12">
              <"{" pos="7"/>
              <A rule="1">
                <B rule="9">
                  <n pos="8"/>
                </B>
              </A>
              <"}" pos="9"/>
            </B>
          </A>
          <"]" pos="10"/>
        </B>
      </A>
      <")" pos="11"/>
    </B>
    <"*" pos="12"/>
    <"[" pos="13"/>
    <A rule="0">
      <A rule="1">
        <B rule="9">
          <n pos="14"/>
        </B>
      </A>
      <"+" pos="15"/>
      <B rule="9">
        <n pos="16"/>
      </B>
    </A>
    <"]" pos="17"/>
  </B>
</A>
END

  ok printGrammarAsXml($grammar) eq <<END
<grammar>
  <A><A/><"+"/><B/></A>
  <A><B/></A>
  <B><B/><"*"/><n/></B>
  <B><B/><"*"/><"("/><A/><")"/></B>
  <B><B/><"*"/><"["/><A/><"]"/></B>
  <B><B/><"*"/><"{"/><A/><"}"/></B>
  <B><B/><"*"/><"("/><")"/></B>
  <B><B/><"*"/><"["/><"]"/></B>
  <B><B/><"*"/><"{"/><"}"/></B>
  <B><n/></B>
  <B><"("/><A/><")"/></B>
  <B><"["/><A/><"]"/></B>
  <B><"{"/><A/><"}"/></B>
  <B><"("/><")"/></B>
  <B><"["/><"]"/></B>
  <B><"{"/><"}"/></B>
</grammar>
END
 }

done_testing;
' called at lib/Parser/LR.pm line 1831
	Parser::LR::test("Parser::LR") called at test.pl line 11
BEGIN failed--compilation aborted at (eval 77) line 1, <DATA> line 506.
 at /var/tmp/build/Data-Table-Text-20191110-4/blib/lib/Data/Table/Text.pm line 3576, <DATA> line 506.
	Data::Table::Text::__ANON__("You tried to plan twice at (eval 77) line 1.\x{a} at /var/tmp/bui"...) called at (eval 77) line 1
	eval 'use Test::More tests => 24;

if (1) {
  my $g = compileGrammar(<<END, nosub=>1);
A  A + B
A  B
B  B * C
B  C
C  n
END

  my sub tlmr(@)
   {my $r = longestMatchingRule($g, @_);
    if ($r)
     {delete $r->{print} if $r;
      my %r = $r->%*;
      #say STDERR nws(dump(\\%r));
      }
    $r
   }

  is_deeply tlmr(qw(n)),     {expandable=>"C", expansion=>["n"],           rule=>4};
  is_deeply tlmr(qw(n + n)), {expandable=>"C", expansion=>["n"],           rule=>4};
  is_deeply tlmr(qw(A + B)), {expandable=>"A", expansion=>["A", "+", "B"], rule=>0};
  ok !tlmr(qw(n +));

  my sub trswr($@)
   {my ($rule, @stack) = @_;
    my @tree = (q()) x @stack;
    my $r = reduceStackWithRule($g->rules->[$rule], \\@stack, \\@tree);
    #say STDERR nws(dump(\\@stack));
    \\@stack
   }

  is_deeply trswr(0, qw(A + B)),   [qw(A)];
  is_deeply trswr(0, qw(n A + B)), [qw(n A)];
  is_deeply trswr(4, qw(B * n)),   [qw(B * C)];
  is_deeply trswr(3, qw(B * n)),   [qw(B * B)];                                 # There is no check that the rule actually applies

  my sub tpm(@)
   {my (@stack) = @_;
    my $r = partialMatch($g, @stack);
    $r
   }

  ok 3 == tpm qw(A + B);
  ok 2 == tpm qw(A +);
  ok 1 == tpm qw(A);
  ok 0 == tpm qw(A -);

  my sub tpwg(@)
   {my (@stack) = @_;
    my $r = parseWithGrammarAndLog($g, @stack) =~ s(\\s+\\Z) (\\n)gsr;;
    owf($logFile, $r);
    $r
   }

  ok tpwg(qw(n)) eq <<END;
Terminal: n, stack: (empty)
  Accept first terminal: n to get stack: n
  Reduced in finals by rule 4, expandable: C, stack: C
  Reduced in finals by rule 3, expandable: B, stack: B
  Reduced in finals by rule 1, expandable: A, stack: A
  Parse tree is:
   Rule  Expandable  Terminal
1     1  A
2     3    B
3     4      C
4                    n
END

  ok tpwg(qw(n + n)) eq <<END;
Terminal: n, stack: (empty)
  Accept first terminal: n to get stack: n
Terminal: +, stack: n
  Reduced by rule 4, expandable: C, stack: C
  Reduced by rule 3, expandable: B, stack: B
  Reduced by rule 1, expandable: A, stack: A
  Accept + after 3 reductions to get: A +
Terminal: n, stack: A +
Accepted terminal: n as is, stack: A + n
  Reduced in finals by rule 4, expandable: C, stack: A + C
  Reduced in finals by rule 3, expandable: B, stack: A + B
  Reduced in finals by rule 0, expandable: A, stack: A
  Parse tree is:
   Rule  Expandable  Terminal
1     0  A
2     1    A
3     3      B
4     4        C
5                    n
6                    +
7     3    B
8     4      C
9                    n
END

  ok tpwg(qw(n * n + n)) eq <<END;
Terminal: n, stack: (empty)
  Accept first terminal: n to get stack: n
Terminal: *, stack: n
  Reduced by rule 4, expandable: C, stack: C
  Reduced by rule 3, expandable: B, stack: B
  Accept * after 2 reductions to get: B *
Terminal: n, stack: B *
Accepted terminal: n as is, stack: B * n
Terminal: +, stack: B * n
  Reduced by rule 4, expandable: C, stack: B * C
  Reduced by rule 2, expandable: B, stack: B
  Reduced by rule 1, expandable: A, stack: A
  Accept + after 3 reductions to get: A +
Terminal: n, stack: A +
Accepted terminal: n as is, stack: A + n
  Reduced in finals by rule 4, expandable: C, stack: A + C
  Reduced in finals by rule 3, expandable: B, stack: A + B
  Reduced in finals by rule 0, expandable: A, stack: A
  Parse tree is:
    Rule  Expandable  Terminal
 1     0  A
 2     1    A
 3     2      B
 4     3        B
 5     4          C
 6                    n
 7                    *
 8     4        C
 9                    n
10                    +
11     3    B
12     4      C
13                    n
END

  ok tpwg(qw(n * n + n * n)) eq <<END;
Terminal: n, stack: (empty)
  Accept first terminal: n to get stack: n
Terminal: *, stack: n
  Reduced by rule 4, expandable: C, stack: C
  Reduced by rule 3, expandable: B, stack: B
  Accept * after 2 reductions to get: B *
Terminal: n, stack: B *
Accepted terminal: n as is, stack: B * n
Terminal: +, stack: B * n
  Reduced by rule 4, expandable: C, stack: B * C
  Reduced by rule 2, expandable: B, stack: B
  Reduced by rule 1, expandable: A, stack: A
  Accept + after 3 reductions to get: A +
Terminal: n, stack: A +
Accepted terminal: n as is, stack: A + n
Terminal: *, stack: A + n
  Reduced by rule 4, expandable: C, stack: A + C
  Reduced by rule 3, expandable: B, stack: A + B
  Accept * after 2 reductions to get: A + B *
Terminal: n, stack: A + B *
Accepted terminal: n as is, stack: A + B * n
  Reduced in finals by rule 4, expandable: C, stack: A + B * C
  Reduced in finals by rule 2, expandable: B, stack: A + B
  Reduced in finals by rule 0, expandable: A, stack: A
  Parse tree is:
    Rule  Expandable  Terminal
 1     0  A
 2     1    A
 3     2      B
 4     3        B
 5     4          C
 6                    n
 7                    *
 8     4        C
 9                    n
10                    +
11     2    B
12     3      B
13     4        C
14                    n
15                    *
16     4      C
17                    n
END

  ok tpwg(qw(n + n * n + n)) eq <<END;
Terminal: n, stack: (empty)
  Accept first terminal: n to get stack: n
Terminal: +, stack: n
  Reduced by rule 4, expandable: C, stack: C
  Reduced by rule 3, expandable: B, stack: B
  Reduced by rule 1, expandable: A, stack: A
  Accept + after 3 reductions to get: A +
Terminal: n, stack: A +
Accepted terminal: n as is, stack: A + n
Terminal: *, stack: A + n
  Reduced by rule 4, expandable: C, stack: A + C
  Reduced by rule 3, expandable: B, stack: A + B
  Accept * after 2 reductions to get: A + B *
Terminal: n, stack: A + B *
Accepted terminal: n as is, stack: A + B * n
Terminal: +, stack: A + B * n
  Reduced by rule 4, expandable: C, stack: A + B * C
  Reduced by rule 2, expandable: B, stack: A + B
  Reduced by rule 0, expandable: A, stack: A
  Accept + after 3 reductions to get: A +
Terminal: n, stack: A +
Accepted terminal: n as is, stack: A + n
  Reduced in finals by rule 4, expandable: C, stack: A + C
  Reduced in finals by rule 3, expandable: B, stack: A + B
  Reduced in finals by rule 0, expandable: A, stack: A
  Parse tree is:
    Rule  Expandable  Terminal
 1     0  A
 2     0    A
 3     1      A
 4     3        B
 5     4          C
 6                    n
 7                    +
 8     2      B
 9     3        B
10     4          C
11                    n
12                    *
13     4        C
14                    n
15                    +
16     3    B
17     4      C
18                    n
END
 }

if (1) {
  my $grammar = compileGrammar(<<END, nosub=>1);
A  A + B
A  B
B  B * C
B  C
C  n
END

  my $tree = parseWithGrammar($grammar, qw(n * n + n * n));
  ok printParseTree($grammar, $tree) eq <<END;
    Rule  Expandable  Terminal
 1     0  A
 2     1    A
 3     2      B
 4     3        B
 5     4          C
 6                    n
 7                    *
 8     4        C
 9                    n
10                    +
11     2    B
12     3      B
13     4        C
14                    n
15                    *
16     4      C
17                    n
END
 }

if (1) {
  my $grammar = compileGrammar(<<END, nosub=>1);
A  A plus B
A  B
B  B times C
B  C
C  value
END

  my $tree = parseWithGrammar($grammar, qw(value times value plus value times value));

  ok printParseTreeAsXml($grammar, $tree) eq <<END;
<A rule="0">
  <A rule="1">
    <B rule="2">
      <B rule="3">
        <C rule="4">
          <value pos="0"/>
        </C>
      </B>
      <times pos="1"/>
      <C rule="4">
        <value pos="2"/>
      </C>
    </B>
  </A>
  <plus pos="3"/>
  <B rule="2">
    <B rule="3">
      <C rule="4">
        <value pos="4"/>
      </C>
    </B>
    <times pos="5"/>
    <C rule="4">
      <value pos="6"/>
    </C>
  </B>
</A>
END
 }

if (1) {
  my $grammar = compileGrammar(<<END, nosub=>1);
A  A + B
A  B
B  B * C
B  C
C  n
C  ( A )
C  [ A ]
END

  my $tree = parseWithGrammar $grammar, qw/ n * ( n + ( n * [ n ] ) )/, subsitute=>0;

  ok printParseTree($grammar, $tree) eq <<END;
    Rule  Expandable               Terminal
 1     1  A
 2     2    B
 3     3      B
 4     4        C
 5                                 n
 6                                 *
 7     5      C
 8                                 (
 9     0        A
10     1          A
11     3            B
12     4              C
13                                 n
14                                 +
15     3          B
16     5            C
17                                 (
18     1              A
19     2                B
20     3                  B
21     4                    C
22                                 n
23                                 *
24     6                  C
25                                 [
26     1                    A
27     3                      B
28     4                        C
29                                 n
30                                 ]
31                                 )
32                                 )
END
 }

if (1) {                                                                        #TcompileGrammar  #TprintGrammar  #TparseWithGrammar #TprintParseTree #TprintParseTreeAsXml
  my $grammar = compileGrammar(<<END);
A  A + B
A  B
B  B * C
B  C
C  n
C  ( A )
C  [ A ]
C  { A }
C  ( )
C  [ ]
C  { }
END

  ok printGrammar($grammar) eq <<END;
    Rule  Symbol  Expansion
 1     0  A       A          +  B
 2     1  A       B
 3     2  B       B          *  n
 4     3  B       B          *  (  A  )
 5     4  B       B          *  [  A  ]
 6     5  B       B          *  {  A  }
 7     6  B       B          *  (  )
 8     7  B       B          *  [  ]
 9     8  B       B          *  {  }
10     9  B       n
11    10  B       (          A  )
12    11  B       [          A  ]
13    12  B       {          A  }
14    13  B       (          )
15    14  B       [          ]
16    15  B       {          }
END

  my $tree = parseWithGrammar($grammar, qw/( [ { }  ]  +  [ { n }  ] ) * [ n + n ]  /);

  ok printParseTree($grammar, $tree) eq <<END;
    Rule  Expandable         Terminal
 1     1  A
 2     4    B
 3    10      B
 4                           (
 5     0        A
 6     1          A
 7    11            B
 8                           [
 9     1              A
10    15                B
11                           {
12                           }
13                           ]
14                           +
15    11          B
16                           [
17     1            A
18    12              B
19                           {
20     1                A
21     9                  B
22                           n
23                           }
24                           ]
25                           )
26                           *
27                           [
28     0      A
29     1        A
30     9          B
31                           n
32                           +
33     9        B
34                           n
35                           ]
END

  ok printParseTreeAsXml($grammar, $tree) eq <<END;
<A rule="1">
  <B rule="4">
    <B rule="10">
      <"(" pos="0"/>
      <A rule="0">
        <A rule="1">
          <B rule="11">
            <"[" pos="1"/>
            <A rule="1">
              <B rule="15">
                <"{" pos="2"/>
                <"}" pos="3"/>
              </B>
            </A>
            <"]" pos="4"/>
          </B>
        </A>
        <"+" pos="5"/>
        <B rule="11">
          <"[" pos="6"/>
          <A rule="1">
            <B rule="12">
              <"{" pos="7"/>
              <A rule="1">
                <B rule="9">
                  <n pos="8"/>
                </B>
              </A>
              <"}" pos="9"/>
            </B>
          </A>
          <"]" pos="10"/>
        </B>
      </A>
      <")" pos="11"/>
    </B>
    <"*" pos="12"/>
    <"[" pos="13"/>
    <A rule="0">
      <A rule="1">
        <B rule="9">
          <n pos="14"/>
        </B>
      </A>
      <"+" pos="15"/>
      <B rule="9">
        <n pos="16"/>
      </B>
    </A>
    <"]" pos="17"/>
  </B>
</A>
END

  ok printGrammarAsXml($grammar) eq <<END
<grammar>
  <A><A/><"+"/><B/></A>
  <A><B/></A>
  <B><B/><"*"/><n/></B>
  <B><B/><"*"/><"("/><A/><")"/></B>
  <B><B/><"*"/><"["/><A/><"]"/></B>
  <B><B/><"*"/><"{"/><A/><"}"/></B>
  <B><B/><"*"/><"("/><")"/></B>
  <B><B/><"*"/><"["/><"]"/></B>
  <B><B/><"*"/><"{"/><"}"/></B>
  <B><n/></B>
  <B><"("/><A/><")"/></B>
  <B><"["/><A/><"]"/></B>
  <B><"{"/><A/><"}"/></B>
  <B><"("/><")"/></B>
  <B><"["/><"]"/></B>
  <B><"{"/><"}"/></B>
</grammar>
END
 }

done_testing;
' called at lib/Parser/LR.pm line 1831
	Parser::LR::test("Parser::LR") called at test.pl line 11
 at /var/tmp/build/Data-Table-Text-20191110-4/blib/lib/Data/Table/Text.pm line 3576, <DATA> line 506.
	Data::Table::Text::__ANON__("You tried to plan twice at (eval 77) line 1.\x{a} at /var/tmp/bui"...) called at lib/Parser/LR.pm line 1832
	Parser::LR::test("Parser::LR") called at test.pl line 11
# Looks like your test exited with 255 just after 30.
test.pl .. 
Dubious, test returned 255 (wstat 65280, 0xff00)
All 30 subtests passed 

Test Summary Report
-------------------
test.pl (Wstat: 65280 Tests: 30 Failed: 0)
  Non-zero exit status: 255
Files=1, Tests=30,  2 wallclock secs ( 0.09 usr  0.05 sys +  0.92 cusr  0.20 csys =  1.27 CPU)
Result: FAIL
Failed 1/1 test programs. 0/30 subtests failed.

------------------------------
PREREQUISITES
------------------------------

Prerequisite modules loaded:

requires:

    Module                   Need     Have    
    ------------------------ -------- --------
    Carp                     0        1.50    
    Data::DFA                20180429 20191111
    Data::Dump               0        1.23    
    Data::NFA                20191110 20191110
    Data::Table::Text        20191110 20191110
    Exporter                 0        5.73    
    Math::Cartesian::Product 1.009    1.009   
    Test2::API               0        1.302162
    Test::More               0        1.302162

configure_requires:

    Module                   Need     Have    
    ------------------------ -------- --------
    Module::Build            0.4224   0.4229  


------------------------------
ENVIRONMENT AND OTHER CONTEXT
------------------------------

Environment variables:

    AUTOMATED_TESTING = 1
    HARNESS_OPTIONS = j2
    NONINTERACTIVE_TESTING = 1
    PATH = /home/njh/perl5/perlbrew/bin:/home/njh/perl5/perlbrew/perls/perl-5.30.0/bin:/home/njh/src/njh/smoker/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
    PERL5LIB = /var/tmp/build/Math-Cartesian-Product-1.009-4/blib/arch:/var/tmp/build/Math-Cartesian-Product-1.009-4/blib/lib:/var/tmp/build/Data-DFA-20191111-5/blib/arch:/var/tmp/build/Data-DFA-20191111-5/blib/lib:/var/tmp/build/Data-NFA-20191110-4/blib/arch:/var/tmp/build/Data-NFA-20191110-4/blib/lib:/var/tmp/build/Data-Table-Text-20191110-4/blib/arch:/var/tmp/build/Data-Table-Text-20191110-4/blib/lib:/var/tmp/build/Data-Dump-1.23-4/blib/arch:/var/tmp/build/Data-Dump-1.23-4/blib/lib
    PERL5OPT = 
    PERL5_CPANPLUS_IS_RUNNING = 33335
    PERL5_CPAN_IS_RUNNING = 33335
    PERL5_CPAN_IS_RUNNING_IN_RECURSION = 32309,33335
    PERLBREW_HOME = /home/njh/.perlbrew
    PERLBREW_MANPATH = /home/njh/perl5/perlbrew/perls/perl-5.30.0/man
    PERLBREW_PATH = /home/njh/perl5/perlbrew/bin:/home/njh/perl5/perlbrew/perls/perl-5.30.0/bin
    PERLBREW_PERL = perl-5.30.0
    PERLBREW_ROOT = /home/njh/perl5/perlbrew
    PERLBREW_SHELLRC_VERSION = 0.87
    PERLBREW_VERSION = 0.87
    PERL_MM_USE_DEFAULT = 1
    PERL_USE_UNSAFE_INC = 1
    SHELL = /bin/sh
    TMPDIR = /tmp/testwrapper.32412

Perl special variables (and OS-specific diagnostics, for MSWin32):

    $^X = /mnt/nas/home/netgate3/njh/perl5/perlbrew/perls/perl-5.30.0/bin/perl5.30.0
    $UID/$EUID = 1000 / 1000
    $GID = 1000 1000 0
    $EGID = 1000 1000 0

Perl module toolchain versions installed:

    Module              Have    
    ------------------- --------
    CPAN                2.27    
    CPAN::Meta          2.150010
    Cwd                 3.78    
    ExtUtils::CBuilder  0.280231
    ExtUtils::Command   7.34    
    ExtUtils::Install   2.14    
    ExtUtils::MakeMaker 7.34    
    ExtUtils::Manifest  1.72    
    ExtUtils::ParseXS   3.40    
    File::Spec          3.78    
    JSON                4.02    
    JSON::PP            4.04    
    Module::Build       0.4229  
    Module::Signature   n/a     
    Parse::CPAN::Meta   2.150010
    Test::Harness       3.42    
    Test::More          1.302162
    YAML                1.29    
    YAML::Syck          1.31    
    version             0.9924  


--

Summary of my perl5 (revision 5 version 30 subversion 0) configuration:
   
  Platform:
    osname=freebsd
    osvers=11.2-release-p9
    archname=amd64-freebsd
    uname='freebsd netgate3 11.2-release-p9 freebsd 11.2-release-p9 #0: tue feb 5 15:30:36 utc 2019 root@amd64-builder.daemonology.net:usrobjusrsrcsysgeneric amd64 '
    config_args='-de -Dprefix=/home/njh/perl5/perlbrew/perls/perl-5.30.0 -Dusedevel -Accflags= -Aeval:scriptdir=/home/njh/perl5/perlbrew/perls/perl-5.30.0/bin'
    hint=recommended
    useposix=true
    d_sigaction=define
    useithreads=undef
    usemultiplicity=undef
    use64bitint=define
    use64bitall=define
    uselongdouble=undef
    usemymalloc=n
    default_inc_excludes_dot=define
    bincompat5005=undef
  Compiler:
    cc='cc'
    ccflags ='-DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_FORTIFY_SOURCE=2'
    optimize='-O2'
    cppflags='-DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'
    ccversion=''
    gccversion='4.2.1 Compatible FreeBSD Clang 6.0.0 (tags/RELEASE_600/final 326565)'
    gccosandvers=''
    intsize=4
    longsize=8
    ptrsize=8
    doublesize=8
    byteorder=12345678
    doublekind=3
    d_longlong=define
    longlongsize=8
    d_longdbl=define
    longdblsize=16
    longdblkind=3
    ivtype='long'
    ivsize=8
    nvtype='double'
    nvsize=8
    Off_t='off_t'
    lseeksize=8
    alignbytes=8
    prototype=define
  Linker and Libraries:
    ld='cc'
    ldflags ='-Wl,-E  -fstack-protector-strong -L/usr/local/lib'
    libpth=/usr/lib /usr/local/lib /usr/lib/clang/6.0.0/lib /usr/lib
    libs=-lpthread -lgdbm -ldl -lm -lcrypt -lutil -lc
    perllibs=-lpthread -ldl -lm -lcrypt -lutil -lc
    libc=
    so=so
    useshrplib=false
    libperl=libperl.a
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs
    dlext=so
    d_dlsymun=undef
    ccdlflags=' '
    cccdlflags='-DPIC -fPIC'
    lddlflags='-shared  -L/usr/local/lib -fstack-protector-strong'


Characteristics of this binary (from libperl): 
  Compile-time options:
    HAS_TIMES
    PERLIO_LAYERS
    PERL_COPY_ON_WRITE
    PERL_DONT_CREATE_GVSV
    PERL_MALLOC_WRAP
    PERL_OP_PARENT
    PERL_PRESERVE_IVUV
    PERL_USE_DEVEL
    USE_64_BIT_ALL
    USE_64_BIT_INT
    USE_LARGE_FILES
    USE_LOCALE
    USE_LOCALE_COLLATE
    USE_LOCALE_CTYPE
    USE_LOCALE_NUMERIC
    USE_LOCALE_TIME
    USE_PERLIO
    USE_PERL_ATOF
  Locally applied patches:
    Devel::PatchPerl 1.52
  Built under freebsd
  Compiled at May 24 2019 00:39:20
  %ENV:
    PERL5LIB="/var/tmp/build/Math-Cartesian-Product-1.009-4/blib/arch:/var/tmp/build/Math-Cartesian-Product-1.009-4/blib/lib:/var/tmp/build/Data-DFA-20191111-5/blib/arch:/var/tmp/build/Data-DFA-20191111-5/blib/lib:/var/tmp/build/Data-NFA-20191110-4/blib/arch:/var/tmp/build/Data-NFA-20191110-4/blib/lib:/var/tmp/build/Data-Table-Text-20191110-4/blib/arch:/var/tmp/build/Data-Table-Text-20191110-4/blib/lib:/var/tmp/build/Data-Dump-1.23-4/blib/arch:/var/tmp/build/Data-Dump-1.23-4/blib/lib"
    PERL5OPT=""
    PERL5_CPANPLUS_IS_RUNNING="33335"
    PERL5_CPAN_IS_RUNNING="33335"
    PERL5_CPAN_IS_RUNNING_IN_RECURSION="32309,33335"
    PERLBREW_HOME="/home/njh/.perlbrew"
    PERLBREW_MANPATH="/home/njh/perl5/perlbrew/perls/perl-5.30.0/man"
    PERLBREW_PATH="/home/njh/perl5/perlbrew/bin:/home/njh/perl5/perlbrew/perls/perl-5.30.0/bin"
    PERLBREW_PERL="perl-5.30.0"
    PERLBREW_ROOT="/home/njh/perl5/perlbrew"
    PERLBREW_SHELLRC_VERSION="0.87"
    PERLBREW_VERSION="0.87"
    PERL_MM_USE_DEFAULT="1"
    PERL_USE_UNSAFE_INC="1"
  @INC:
    /var/tmp/build/Math-Cartesian-Product-1.009-4/blib/arch
    /var/tmp/build/Math-Cartesian-Product-1.009-4/blib/lib
    /var/tmp/build/Data-DFA-20191111-5/blib/arch
    /var/tmp/build/Data-DFA-20191111-5/blib/lib
    /var/tmp/build/Data-NFA-20191110-4/blib/arch
    /var/tmp/build/Data-NFA-20191110-4/blib/lib
    /var/tmp/build/Data-Table-Text-20191110-4/blib/arch
    /var/tmp/build/Data-Table-Text-20191110-4/blib/lib
    /var/tmp/build/Data-Dump-1.23-4/blib/arch
    /var/tmp/build/Data-Dump-1.23-4/blib/lib
    /home/njh/perl5/perlbrew/perls/perl-5.30.0/lib/site_perl/5.30.0/amd64-freebsd
    /home/njh/perl5/perlbrew/perls/perl-5.30.0/lib/site_perl/5.30.0
    /home/njh/perl5/perlbrew/perls/perl-5.30.0/lib/5.30.0/amd64-freebsd
    /home/njh/perl5/perlbrew/perls/perl-5.30.0/lib/5.30.0
    .