# Marpa::R3 is Copyright (C) 2018, Jeffrey Kegler.
#
# This module is free software; you can redistribute it and/or modify it
# under the same terms as Perl 5.10.1. For more details, see the full text
# of the licenses in the directory LICENSES.
#
# This program is distributed in the hope that it will be
# useful, but it is provided "as is" and without any express
# or implied warranties. For details, see the full text of
# of the licenses in the directory LICENSES.

=head1 Name

Marpa::R3::Valuer - Valuer objects

=head1 Synopsis

=for Marpa::R3::Display
name: Valuer synopsis
partial: 1
normalize-whitespace: 1

    use Marpa::R3;

    my $dsl = <<'END_OF_DSL';

    Calculator ::= Expression action => ::first

    Factor ::= Number action => ::first
    Term ::=
        Term '*' Factor action => do_multiply
        | Factor action => ::first
    Expression ::=
        Expression '+' Term action => do_add
        | Term action => ::first
    Number ~ digits
    digits ~ [\d]+
    :discard ~ whitespace
    whitespace ~ [\s]+
    END_OF_DSL

    my $grammar = Marpa::R3::Grammar->new(
        {
            semantics_package => 'My_Actions',
            source            => \$dsl
        }
    );
    my $recce       = Marpa::R3::Recognizer->new( { grammar => $grammar } );
    my $input       = '42 * 1 + 7';
    my $length_read = $recce->read( \$input );

    die "Read ended after $length_read of ", length $input, " characters"
        if $length_read != length $input;

    my $valuer = Marpa::R3::Valuer->new( { recognizer => $recce } );
    my $value_ref = $valuer->value();
    my $value = ${$value_ref};

=for Marpa::R3::Display::End

=for Marpa::R3::Display
name: Valuer semantics
partial: 1
normalize-whitespace: 1

    sub My_Actions::do_add {
        my ( undef, $values ) = @_;
        my ( $t1, undef, $t2 ) = @{$values};
        return $t1 + $t2;
    }

    sub My_Actions::do_multiply {
        my ( undef, $values ) = @_;
        my ( $t1, undef, $t2 ) = @{$values};
        return $t1 * $t2;
    }

=for Marpa::R3::Display::End

=head1 About this document

This page is the reference document for the valuer objects
of Marpa's SLIF (Scanless interface).

Many applications,
probably the majority,
will not need the SLIF valuer class or its methods.
Instead, they will find
the L<C<< $recognizer->value() >> method|Marpa::R3::Recognizer/value()> method
sufficient for their needs.

The methods in this document
will be needed by applications
that wish to do one of more of the following:

=over 4

=item *

Treat an ambiguous parse as something other than an error.

=item *

Get more than one of the values from an ambiguous parse.

=item *

Set an end-of-parse location
other than the default.

=item *

Have more than one valuer active at a time.

=item *

Use one of the valuer methods, as described in
this document.

=back

=head1 Valuer settings

The B<valuer settings> are the named arguments
accepted by
the L<valuer's constructor|/"Constructor">
or its
L<C<set()>|/"set()"> method.

=head2 end

Most users will not need this setting.
The L<C<end>|/"end"> setting
specifies the parse end, as a G1 location.
The default is for the parse to end where the input did,
so that the parse returned is of the entire virtual input stream.
The L<C<end>|/"end"> setting is only allowed in
L<a valuer's constructor|/"Constructor">.

=head2 max_parses

If non-zero, causes a fatal error when that number
of parse results is exceeded.
C<max_parses> is useful to
limit CPU usage and output length when testing
and debugging.
Stable and production applications may
prefer to count the number of parses,
and take a less Draconian response when the
count is exceeded.

The value must be an integer.
If it is zero, there will be no
limit on the number of parse results returned.
The default is for
there to be no limit.
The C<max_parses> setting is allowed
by both
the L<valuer's constructor|/"Constructor">
and its
L<C<set()>|/"set()"> method.

=head2 recognizer

The value of the C<recognizer> setting must be
a SLIF recognizer object.
The C<new()> method is required to have
a C<recognizer> setting.
The C<recognizer> setting is only allowed in
L<a valuer's constructor|/"Constructor">.

=head2 trace_values

The value of the C<trace_values> setting is a numeric trace level.
If the
numeric trace level is 1, Marpa prints tracing information as values
are computed in the evaluation stack.  A trace level of 0 turns
value tracing off, which is the default. Traces are written to the
trace file handle.
The C<trace_values> setting is allowed
by both
the L<valuer's constructor|/"Constructor">
and its
L<C<set()>|/"set()"> method.

=head2 trace_file_handle

The value is a file handle.
Trace output and warning messages
go to the trace file handle.
By default, the trace file handle is inherited from the
grammar.
The C<trace_file_handle> setting is allowed
by both
the L<valuer's constructor|/"Constructor">
and its
L<C<set()>|/"set()"> method.

=head1 Constructor

=for Marpa::R3::Display
name: Valuer synopsis
partial: 1
normalize-whitespace: 1

    my $valuer = Marpa::R3::Valuer->new( { recognizer => $recce } );

=for Marpa::R3::Display::End

The C<new()> method is the constructor for SLIF valuers.
The arguments
to the C<new()> constructor must be one or more hashes of named arguments,
where each hash key is a valuers setting.
The L<C<recognizer>|/"recognizer"> valuer setting is required.
All other valuer settings are optional.
For more on valuer settings,
see
L<the section describing them|/"Valuer settings">.

=head1 Mutators

=head2 set()

=for Marpa::R3::Display
name: Valuer set() synopsis
normalize-whitespace: 1

    $valuer->set( { trace_values => 3 } );

=for Marpa::R3::Display::End

This method allows valuer settings to be changed after a SLIF
grammar is created.
The arguments to
C<set()> must be one or more hashes whose key-value pairs
are valuer settings and their values.
The allowed valuer settings are
L<described above|/"Valuer settings">.

B<Return values>:
The return value is reserved for future use.
Failures are always thrown.

=head2 valuer value()

=for Marpa::R3::Display
name: Valuer synopsis
partial: 1
normalize-whitespace: 1

    my $value_ref = $valuer->value();

=for Marpa::R3::Display::End

The C<value()> method allows one optional argument.
Call this argument C<$self>.
If specified, C<$self>
explicitly specifies the per-parse argument for the
parse tree.
The function of the per-parse argument
is detailed in the description
of the L<< C<value()> method of the
recognizer|Marpa::R3::Recognizer/"recognizer value()" >>.

The C<value()> method of the valuer is an iterator.
Each call of C<value()> evaluates the next parse tree
for the valuer object.
C<value()> succeeds if there is a parse tree and it can be
evaluated.
On success, C<value()>
returns a reference to the parse result for that parse tree.
The value of
a successful evaluation of a parse tree can be a Perl C<undef>,
in which case,
and as implied above,
C<value()> returns a reference to Perl C<undef>.

A soft failure occurs
if there are no parse trees left to evaluate,
in which case the C<value()> method returns C<undef>.
All other failures are hard failures.

There will be more than one parse tree if the parse
was ambiguous.
There will be zero parse trees if there was no valid parse
of the input according to the grammar.
If there are zero parse trees, the first call of the C<value()>
method for a valuer will produce a soft failure.

B<Return values>:
On success, returns a reference to the parse result for a parse tree.
If there are no more parse trees, returns a Perl C<undef>.
Hard failures are thrown.

=head1 Accessors

=head2 ambiguity_level()

=for Marpa::R3::Display
name: Valuer ambiguity_level() synopsis

    my $ambiguity_level = $valuer->ambiguity_level();

=for Marpa::R3::Display::End

Succeeds and
returns 1 if there was an unambiguous parse,
in other words if there was exactly one parse tree.
Succeeds and
returns 2 if the parse was ambiguous,
in other words if there was more than one parse tree.
Succeeds and returns 0 if there are zero parse trees,
in other words if no parse was found.
Failures are thrown.

=head2 ambiguous()

=for Marpa::R3::Display
name: Valuer ambiguous() synopsis

    $ambiguity_status = $valuer->ambiguous();
    if ( $ambiguity_status ) {
        chomp $ambiguity_status;
        die "Parse is ambiguous\n", $ambiguity_status;
    }

=for Marpa::R3::Display::End

If there is exactly one parse, returns the empty string.
If there is no parse, returns a non-empty string indicating that fact.
If there are two or more parses,
returns a non-empty string describing the ambiguity.

The non-empty strings are intended only for reading by
humans -- their exact format is subject to change.
Applications can rely on the results of automated tests
of the return value from C<ambiguous()>
only if that test is for
empty versus non-empty.

=head2 g1_pos

=for Marpa::R3::Display
name: Valuer g1_pos() synopsis
normalize-whitespace: 1

    my $end_of_parse = $valuer->g1_pos();

=for Marpa::R3::Display::End

Returns the G1 location of the end of parsing for
this valuer.

=head1 COPYRIGHT AND LICENSE

=for Marpa::R3::Display
ignore: 1

  Marpa::R3 is Copyright (C) 2018, Jeffrey Kegler.

  This module is free software; you can redistribute it and/or modify it
  under the same terms as Perl 5.10.1. For more details, see the full text
  of the licenses in the directory LICENSES.

  This program 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.

=for Marpa::R3::Display::End

=cut

# vim: expandtab shiftwidth=4:
